diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2016-05-07 10:31:13 +0200 |
---|---|---|
committer | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2016-05-07 21:13:44 +0100 |
commit | 772ad7142dff590c7bb30370acf5d3c9a8fb512b (patch) | |
tree | b0ea5c118dc93a404728bbb62ce12c9591ceb87a /libavcodec/h264.c | |
parent | 9cc1ab63ac0fa524ad9b6c8ef600dc4fc69e2b31 (diff) | |
parent | ca2f19b9cc37be509d85f05c8f902860475905f8 (diff) | |
download | ffmpeg-772ad7142dff590c7bb30370acf5d3c9a8fb512b.tar.gz |
Merge commit 'ca2f19b9cc37be509d85f05c8f902860475905f8'
* commit 'ca2f19b9cc37be509d85f05c8f902860475905f8':
h264: switch to h2645_parse for NAL parsing
Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 500 |
1 files changed, 194 insertions, 306 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 7784026afb..e02202840b 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -40,6 +40,7 @@ #include "error_resilience.h" #include "avcodec.h" #include "h264.h" +#include "h2645_parse.h" #include "h264data.h" #include "h264chroma.h" #include "h264_mvpred.h" @@ -243,25 +244,6 @@ nsc: return dst; } -/** - * Identify the exact end of the bitstream - * @return the length of the trailing, or 0 if damaged - */ -static int decode_rbsp_trailing(H264Context *h, const uint8_t *src) -{ - int v = *src; - int r; - - ff_tlog(h->avctx, "rbsp trailing %X\n", v); - - for (r = 1; r < 9; r++) { - if (v & 1) - return r; - v >>= 1; - } - return 0; -} - void ff_h264_free_tables(H264Context *h) { int i; @@ -1179,85 +1161,39 @@ int ff_set_ref_count(H264Context *h, H264SliceContext *sl) return 0; } +#if FF_API_CAP_VDPAU static const uint8_t start_code[] = { 0x00, 0x00, 0x01 }; +#endif -static int get_bit_length(H264Context *h, const uint8_t *buf, - const uint8_t *ptr, int dst_length, - int i, int next_avc) -{ - if ((h->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc && - buf[i] == 0x00 && buf[i + 1] == 0x00 && - buf[i + 2] == 0x01 && buf[i + 3] == 0xE0) - h->workaround_bugs |= FF_BUG_TRUNCATED; - - if (!(h->workaround_bugs & FF_BUG_TRUNCATED)) - while (dst_length > 0 && ptr[dst_length - 1] == 0) - dst_length--; - - if (!dst_length) - return 0; - - return 8 * dst_length - decode_rbsp_trailing(h, ptr + dst_length - 1); -} - -static int get_last_needed_nal(H264Context *h, const uint8_t *buf, int buf_size) +static int get_last_needed_nal(H264Context *h) { - int next_avc = h->is_avc ? 0 : buf_size; - int nal_index = 0; - int buf_index = 0; int nals_needed = 0; int first_slice = 0; + int i; - while(1) { + for (i = 0; i < h->pkt.nb_nals; i++) { + H2645NAL *nal = &h->pkt.nals[i]; GetBitContext gb; - int nalsize = 0; - int dst_length, bit_length, consumed; - const uint8_t *ptr; - - if (buf_index >= next_avc) { - nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index); - if (nalsize < 0) - break; - next_avc = buf_index + nalsize; - } else { - buf_index = find_start_code(buf, buf_size, buf_index, next_avc); - if (buf_index >= buf_size) - break; - if (buf_index >= next_avc) - continue; - } - - ptr = ff_h264_decode_nal(h, &h->slice_ctx[0], buf + buf_index, &dst_length, &consumed, - next_avc - buf_index); - - if (!ptr || dst_length < 0) - return AVERROR_INVALIDDATA; - - buf_index += consumed; - - bit_length = get_bit_length(h, buf, ptr, dst_length, - buf_index, next_avc); - nal_index++; /* packets can sometimes contain multiple PPS/SPS, * e.g. two PAFF field pictures in one packet, or a demuxer * which splits NALs strangely if so, when frame threading we * can't start the next thread until we've read all of them */ - switch (h->nal_unit_type) { + switch (nal->type) { case NAL_SPS: case NAL_PPS: - nals_needed = nal_index; + nals_needed = i; break; case NAL_DPA: case NAL_IDR_SLICE: case NAL_SLICE: - init_get_bits(&gb, ptr, bit_length); + init_get_bits8(&gb, nal->data + 1, (nal->size - 1)); if (!get_ue_golomb_long(&gb) || // first_mb_in_slice !first_slice || - first_slice != h->nal_unit_type) - nals_needed = nal_index; + first_slice != nal->type) + nals_needed = i; if (!first_slice) - first_slice = h->nal_unit_type; + first_slice = nal->type; } } @@ -1268,14 +1204,10 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, int parse_extradata) { AVCodecContext *const avctx = h->avctx; - H264SliceContext *sl; - int buf_index; - unsigned context_count; - int next_avc; + unsigned context_count = 0; int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts - int nal_index; int idr_cleared=0; - int ret = 0; + int i, ret = 0; h->nal_unit_type= 0; @@ -1296,262 +1228,216 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, h->is_avc = 1; } - if (avctx->active_thread_type & FF_THREAD_FRAME) - nals_needed = get_last_needed_nal(h, buf, buf_size); - - { - buf_index = 0; - context_count = 0; - next_avc = h->is_avc ? 0 : buf_size; - nal_index = 0; - for (;;) { - int consumed; - int dst_length; - int bit_length; - const uint8_t *ptr; - int nalsize = 0; - int err; - - if (buf_index >= next_avc) { - nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index); - if (nalsize < 0) - break; - next_avc = buf_index + nalsize; - } else { - buf_index = find_start_code(buf, buf_size, buf_index, next_avc); - if (buf_index >= buf_size) - break; - if (buf_index >= next_avc) - continue; - } - - sl = &h->slice_ctx[context_count]; - - ptr = ff_h264_decode_nal(h, sl, buf + buf_index, &dst_length, - &consumed, next_avc - buf_index); - if (!ptr || dst_length < 0) { - ret = -1; - goto end; - } - - bit_length = get_bit_length(h, buf, ptr, dst_length, - buf_index + consumed, next_avc); - - if (h->avctx->debug & FF_DEBUG_STARTCODE) - av_log(h->avctx, AV_LOG_DEBUG, - "NAL %d/%d at %d/%d length %d\n", - h->nal_unit_type, h->nal_ref_idc, buf_index, buf_size, dst_length); + ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc, + h->nal_length_size, avctx->codec_id); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Error splitting the input into NAL units.\n"); + return ret; + } - if (h->is_avc && (nalsize != consumed) && nalsize) - av_log(h->avctx, AV_LOG_DEBUG, - "AVC: Consumed only %d bytes instead of %d\n", - consumed, nalsize); + if (avctx->active_thread_type & FF_THREAD_FRAME) + nals_needed = get_last_needed_nal(h); - buf_index += consumed; - nal_index++; + for (i = 0; i < h->pkt.nb_nals; i++) { + H2645NAL *nal = &h->pkt.nals[i]; + H264SliceContext *sl = &h->slice_ctx[context_count]; + int err; - if (avctx->skip_frame >= AVDISCARD_NONREF && - h->nal_ref_idc == 0 && - h->nal_unit_type != NAL_SEI) - continue; + if (avctx->skip_frame >= AVDISCARD_NONREF && + nal->ref_idc == 0 && nal->type != NAL_SEI) + continue; again: - /* Ignore per frame NAL unit type during extradata - * parsing. Decoding slices is not possible in codec init - * with frame-mt */ - if (parse_extradata) { - switch (h->nal_unit_type) { - case NAL_IDR_SLICE: - case NAL_SLICE: - case NAL_DPA: - case NAL_DPB: - case NAL_DPC: - av_log(h->avctx, AV_LOG_WARNING, - "Ignoring NAL %d in global header/extradata\n", - h->nal_unit_type); - // fall through to next case - case NAL_AUXILIARY_SLICE: - h->nal_unit_type = NAL_FF_IGNORE; - } + /* Ignore per frame NAL unit type during extradata + * parsing. Decoding slices is not possible in codec init + * with frame-mt */ + if (parse_extradata) { + switch (nal->type) { + case NAL_IDR_SLICE: + case NAL_SLICE: + case NAL_DPA: + case NAL_DPB: + case NAL_DPC: + av_log(h->avctx, AV_LOG_WARNING, + "Ignoring NAL %d in global header/extradata\n", + nal->type); + // fall through to next case + case NAL_AUXILIARY_SLICE: + nal->type = NAL_FF_IGNORE; } + } - err = 0; + // FIXME these should stop being context-global variables + h->nal_ref_idc = nal->ref_idc; + h->nal_unit_type = nal->type; - switch (h->nal_unit_type) { - case NAL_IDR_SLICE: - if ((ptr[0] & 0xFC) == 0x98) { - av_log(h->avctx, AV_LOG_ERROR, "Invalid inter IDR frame\n"); - h->next_outputed_poc = INT_MIN; - ret = -1; - goto end; - } - if (h->nal_unit_type != NAL_IDR_SLICE) { - av_log(h->avctx, AV_LOG_ERROR, - "Invalid mix of idr and non-idr slices\n"); - ret = -1; + err = 0; + switch (nal->type) { + case NAL_IDR_SLICE: + if ((nal->data[1] & 0xFC) == 0x98) { + av_log(h->avctx, AV_LOG_ERROR, "Invalid inter IDR frame\n"); + h->next_outputed_poc = INT_MIN; + ret = -1; + goto end; + } + if (nal->type != NAL_IDR_SLICE) { + av_log(h->avctx, AV_LOG_ERROR, + "Invalid mix of idr and non-idr slices\n"); + ret = -1; + goto end; + } + if(!idr_cleared) { + if (h->current_slice && (avctx->active_thread_type & FF_THREAD_SLICE)) { + av_log(h, AV_LOG_ERROR, "invalid mixed IDR / non IDR frames cannot be decoded in slice multithreading mode\n"); + ret = AVERROR_INVALIDDATA; goto end; } - if(!idr_cleared) { - if (h->current_slice && (avctx->active_thread_type & FF_THREAD_SLICE)) { - av_log(h, AV_LOG_ERROR, "invalid mixed IDR / non IDR frames cannot be decoded in slice multithreading mode\n"); - ret = AVERROR_INVALIDDATA; - goto end; - } - idr(h); // FIXME ensure we don't lose some frames if there is reordering - } - idr_cleared = 1; - h->has_recovery_point = 1; - case NAL_SLICE: - init_get_bits(&sl->gb, ptr, bit_length); - - if ( nals_needed >= nal_index - || (!(avctx->active_thread_type & FF_THREAD_FRAME) && !context_count)) - h->au_pps_id = -1; + idr(h); // FIXME ensure we don't lose some frames if there is reordering + } + idr_cleared = 1; + h->has_recovery_point = 1; + case NAL_SLICE: + sl->gb = nal->gb; + if ( nals_needed >= i + || (!(avctx->active_thread_type & FF_THREAD_FRAME) && !context_count)) + h->au_pps_id = -1; - if ((err = ff_h264_decode_slice_header(h, sl))) - break; + if ((err = ff_h264_decode_slice_header(h, sl))) + break; - if (h->sei_recovery_frame_cnt >= 0) { - if (h->frame_num != h->sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I) - h->valid_recovery_point = 1; + if (h->sei_recovery_frame_cnt >= 0) { + if (h->frame_num != h->sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I) + h->valid_recovery_point = 1; - if ( h->recovery_frame < 0 - || av_mod_uintp2(h->recovery_frame - h->frame_num, h->sps.log2_max_frame_num) > h->sei_recovery_frame_cnt) { - h->recovery_frame = av_mod_uintp2(h->frame_num + h->sei_recovery_frame_cnt, h->sps.log2_max_frame_num); + if ( h->recovery_frame < 0 + || av_mod_uintp2(h->recovery_frame - h->frame_num, h->sps.log2_max_frame_num) > h->sei_recovery_frame_cnt) { + h->recovery_frame = av_mod_uintp2(h->frame_num + h->sei_recovery_frame_cnt, h->sps.log2_max_frame_num); - if (!h->valid_recovery_point) - h->recovery_frame = h->frame_num; - } + if (!h->valid_recovery_point) + h->recovery_frame = h->frame_num; } + } - h->cur_pic_ptr->f->key_frame |= - (h->nal_unit_type == NAL_IDR_SLICE); + h->cur_pic_ptr->f->key_frame |= (nal->type == NAL_IDR_SLICE); - if (h->nal_unit_type == NAL_IDR_SLICE || - (h->recovery_frame == h->frame_num && h->nal_ref_idc)) { - h->recovery_frame = -1; - h->cur_pic_ptr->recovered = 1; - } - // If we have an IDR, all frames after it in decoded order are - // "recovered". - if (h->nal_unit_type == NAL_IDR_SLICE) - h->frame_recovered |= FRAME_RECOVERED_IDR; + if (nal->type == NAL_IDR_SLICE || + (h->recovery_frame == h->frame_num && nal->ref_idc)) { + h->recovery_frame = -1; + h->cur_pic_ptr->recovered = 1; + } + // If we have an IDR, all frames after it in decoded order are + // "recovered". + if (nal->type == NAL_IDR_SLICE) + h->frame_recovered |= FRAME_RECOVERED_IDR; #if 1 - h->cur_pic_ptr->recovered |= h->frame_recovered; + h->cur_pic_ptr->recovered |= h->frame_recovered; #else - h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR); + h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR); #endif - if (h->current_slice == 1) { - if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS)) - decode_postinit(h, nal_index >= nals_needed); + if (h->current_slice == 1) { + if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS)) + decode_postinit(h, i >= nals_needed); - if (h->avctx->hwaccel && - (ret = h->avctx->hwaccel->start_frame(h->avctx, buf, buf_size)) < 0) - goto end; + if (h->avctx->hwaccel && + (ret = h->avctx->hwaccel->start_frame(h->avctx, buf, buf_size)) < 0) + goto end; #if FF_API_CAP_VDPAU - if (CONFIG_H264_VDPAU_DECODER && - h->avctx->codec->capabilities & AV_CODEC_CAP_HWACCEL_VDPAU) - ff_vdpau_h264_picture_start(h); + if (CONFIG_H264_VDPAU_DECODER && + h->avctx->codec->capabilities & AV_CODEC_CAP_HWACCEL_VDPAU) + ff_vdpau_h264_picture_start(h); #endif - } + } - if (sl->redundant_pic_count == 0) { - if (avctx->hwaccel) { - ret = avctx->hwaccel->decode_slice(avctx, - &buf[buf_index - consumed], - consumed); - if (ret < 0) - goto end; + if (sl->redundant_pic_count == 0) { + if (avctx->hwaccel) { + ret = avctx->hwaccel->decode_slice(avctx, + nal->raw_data, + nal->raw_size); + if (ret < 0) + goto end; #if FF_API_CAP_VDPAU - } else if (CONFIG_H264_VDPAU_DECODER && - h->avctx->codec->capabilities & AV_CODEC_CAP_HWACCEL_VDPAU) { - ff_vdpau_add_data_chunk(h->cur_pic_ptr->f->data[0], - start_code, - sizeof(start_code)); - ff_vdpau_add_data_chunk(h->cur_pic_ptr->f->data[0], - &buf[buf_index - consumed], - consumed); + } else if (CONFIG_H264_VDPAU_DECODER && + h->avctx->codec->capabilities & AV_CODEC_CAP_HWACCEL_VDPAU) { + ff_vdpau_add_data_chunk(h->cur_pic_ptr->f->data[0], + start_code, + sizeof(start_code)); + ff_vdpau_add_data_chunk(h->cur_pic_ptr->f->data[0], + nal->raw_data, + nal->raw_size); #endif - } else - context_count++; - } - break; - case NAL_DPA: - case NAL_DPB: - case NAL_DPC: - avpriv_request_sample(avctx, "data partitioning"); + } else + context_count++; + } + break; + case NAL_DPA: + case NAL_DPB: + case NAL_DPC: + avpriv_request_sample(avctx, "data partitioning"); + break; + case NAL_SEI: + h->gb = nal->gb; + ret = ff_h264_decode_sei(h); + if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) + goto end; + break; + case NAL_SPS: + h->gb = nal->gb; + if (ff_h264_decode_seq_parameter_set(h, 0) >= 0) break; - case NAL_SEI: - init_get_bits(&h->gb, ptr, bit_length); - ret = ff_h264_decode_sei(h); - if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) - goto end; + av_log(h->avctx, AV_LOG_DEBUG, + "SPS decoding failure, trying again with the complete NAL\n"); + init_get_bits8(&h->gb, nal->raw_data + 1, nal->raw_size - 1); + if (ff_h264_decode_seq_parameter_set(h, 0) >= 0) break; - case NAL_SPS: - init_get_bits(&h->gb, ptr, bit_length); - if (ff_h264_decode_seq_parameter_set(h, 0) >= 0) - break; - if (h->is_avc ? nalsize : 1) { - av_log(h->avctx, AV_LOG_DEBUG, - "SPS decoding failure, trying again with the complete NAL\n"); - if (h->is_avc) - av_assert0(next_avc - buf_index + consumed == nalsize); - if ((next_avc - buf_index + consumed - 1) >= INT_MAX/8) - break; - init_get_bits(&h->gb, &buf[buf_index + 1 - consumed], - 8*(next_avc - buf_index + consumed - 1)); - if (ff_h264_decode_seq_parameter_set(h, 0) >= 0) - break; - } - init_get_bits(&h->gb, ptr, bit_length); - ff_h264_decode_seq_parameter_set(h, 1); + h->gb = nal->gb; + ff_h264_decode_seq_parameter_set(h, 1); - break; - case NAL_PPS: - init_get_bits(&h->gb, ptr, bit_length); - ret = ff_h264_decode_picture_parameter_set(h, bit_length); - if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) - goto end; - break; - case NAL_AUD: - case NAL_END_SEQUENCE: - case NAL_END_STREAM: - case NAL_FILLER_DATA: - case NAL_SPS_EXT: - case NAL_AUXILIARY_SLICE: - break; - case NAL_FF_IGNORE: - break; - default: - av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n", - h->nal_unit_type, bit_length); - } + break; + case NAL_PPS: + h->gb = nal->gb; + ret = ff_h264_decode_picture_parameter_set(h, nal->size_bits); + if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) + goto end; + break; + case NAL_AUD: + case NAL_END_SEQUENCE: + case NAL_END_STREAM: + case NAL_FILLER_DATA: + case NAL_SPS_EXT: + case NAL_AUXILIARY_SLICE: + break; + case NAL_FF_IGNORE: + break; + default: + av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n", + nal->type, nal->size_bits); + } + + if (context_count == h->max_contexts) { + ret = ff_h264_execute_decode_slices(h, context_count); + if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) + goto end; + context_count = 0; + } - if (context_count == h->max_contexts) { - ret = ff_h264_execute_decode_slices(h, context_count); + if (err < 0 || err == SLICE_SKIPED) { + if (err < 0) + av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n"); + sl->ref_count[0] = sl->ref_count[1] = sl->list_count = 0; + } else if (err == SLICE_SINGLETHREAD) { + if (context_count > 1) { + ret = ff_h264_execute_decode_slices(h, context_count - 1); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) goto end; context_count = 0; } - - if (err < 0 || err == SLICE_SKIPED) { - if (err < 0) - av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n"); - sl->ref_count[0] = sl->ref_count[1] = sl->list_count = 0; - } else if (err == SLICE_SINGLETHREAD) { - if (context_count > 1) { - ret = ff_h264_execute_decode_slices(h, context_count - 1); - if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) - goto end; - context_count = 0; - } - /* Slice could not be decoded in parallel mode, restart. Note - * that rbsp_buffer is not transferred, but since we no longer - * run in parallel mode this should not be an issue. */ - sl = &h->slice_ctx[0]; - goto again; - } + /* Slice could not be decoded in parallel mode, restart. Note + * that rbsp_buffer is not transferred, but since we no longer + * run in parallel mode this should not be an issue. */ + sl = &h->slice_ctx[0]; + goto again; } } if (context_count) { @@ -1564,7 +1450,6 @@ again: end: #if CONFIG_ERROR_RESILIENCE - sl = h->slice_ctx; /* * FIXME: Error handling code does not seem to support interlaced * when slices span multiple rows @@ -1578,6 +1463,7 @@ end: * causes problems for the first MB line, too. */ if (!FIELD_PICTURE(h) && h->current_slice && !h->sps.new && h->enable_er) { + H264SliceContext *sl = h->slice_ctx; int use_last_pic = h->last_pic_for_ec.f->buf[0] && !sl->ref_count[0]; ff_h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr); @@ -1609,7 +1495,7 @@ end: h->picture_structure == PICT_BOTTOM_FIELD); } - return (ret < 0) ? ret : buf_index; + return (ret < 0) ? ret : buf_size; } /** @@ -1860,6 +1746,8 @@ av_cold void ff_h264_free_context(H264Context *h) for (i = 0; i < MAX_PPS_COUNT; i++) av_freep(h->pps_buffers + i); + + ff_h2645_packet_uninit(&h->pkt); } static av_cold int h264_decode_end(AVCodecContext *avctx) |