[FFmpeg-cvslog] Merge commit 'ca2f19b9cc37be509d85f05c8f902860475905f8'
Hendrik Leppkes
git at videolan.org
Sat May 7 22:22:52 CEST 2016
ffmpeg | branch: master | Hendrik Leppkes <h.leppkes at gmail.com> | Sat May 7 10:31:13 2016 +0200| [772ad7142dff590c7bb30370acf5d3c9a8fb512b] | committer: Derek Buitenhuis
Merge commit 'ca2f19b9cc37be509d85f05c8f902860475905f8'
* commit 'ca2f19b9cc37be509d85f05c8f902860475905f8':
h264: switch to h2645_parse for NAL parsing
Merged-by: Hendrik Leppkes <h.leppkes at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=772ad7142dff590c7bb30370acf5d3c9a8fb512b
---
libavcodec/Makefile | 4 +-
libavcodec/h264.c | 500 ++++++++++++++++++++-------------------------------
libavcodec/h264.h | 3 +
3 files changed, 200 insertions(+), 307 deletions(-)
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 8ac2272..cc59498 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -308,7 +308,9 @@ OBJS-$(CONFIG_H263_ENCODER) += mpeg4videoenc.o mpeg4video.o \
OBJS-$(CONFIG_H264_DECODER) += h264.o h264_cabac.o h264_cavlc.o \
h264_direct.o h264_loopfilter.o \
h264_mb.o h264_picture.o h264_ps.o \
- h264_refs.o h264_sei.o h264_slice.o h264data.o h264_parse.o
+ h264_refs.o h264_sei.o \
+ h264_slice.o h264data.o h264_parse.o \
+ h2645_parse.o
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec_h264.o
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 7784026..e022028 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)
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 5bf6b70..33a73ba 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -34,6 +34,7 @@
#include "error_resilience.h"
#include "get_bits.h"
#include "h264_parse.h"
+#include "h2645_parse.h"
#include "h264chroma.h"
#include "h264dsp.h"
#include "h264pred.h"
@@ -527,6 +528,8 @@ typedef struct H264Context {
H264SliceContext *slice_ctx;
int nb_slice_ctx;
+ H2645Packet pkt;
+
int pixel_shift; ///< 0 for 8-bit H264, 1 for high-bit-depth H264
/* coded dimensions -- 16 * mb w/h */
======================================================================
diff --cc libavcodec/Makefile
index 8ac2272,0026b1f..cc59498
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@@ -308,10 -251,11 +308,12 @@@ OBJS-$(CONFIG_H263_ENCODER)
OBJS-$(CONFIG_H264_DECODER) += h264.o h264_cabac.o h264_cavlc.o \
h264_direct.o h264_loopfilter.o \
h264_mb.o h264_picture.o h264_ps.o \
- h264_refs.o h264_sei.o h264_slice.o h264data.o h264_parse.o
+ h264_refs.o h264_sei.o \
+ h264_slice.o h264data.o h264_parse.o \
+ h2645_parse.o
+OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec_h264.o
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
-OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o
+OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o
OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
diff --cc libavcodec/h264.c
index 7784026,94fe1a8..e022028
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@@ -1179,65 -1125,14 +1161,19 @@@ int ff_set_ref_count(H264Context *h, H2
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
@@@ -1251,13 -1146,9 +1187,13 @@@
case NAL_DPA:
case NAL_IDR_SLICE:
case NAL_SLICE:
- init_get_bits(&gb, ptr, bit_length);
- init_get_bits(&gb, nal->data + 1, (nal->size - 1) * 8);
- if (!get_ue_golomb(&gb))
++ 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,19 -1159,10 +1204,15 @@@ static int decode_nal_units(H264Contex
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;
+
+ if(!h->slice_context_count)
+ h->slice_context_count= 1;
h->max_contexts = h->slice_context_count;
if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS)) {
h->current_slice = 0;
@@@ -1289,269 -1171,157 +1221,223 @@@
ff_h264_reset_sei(h);
}
+ if (h->nal_length_size == 4) {
+ if (buf_size > 8 && AV_RB32(buf) == 1 && AV_RB32(buf+5) > (unsigned)buf_size) {
+ h->is_avc = 0;
+ }else if(buf_size > 3 && AV_RB32(buf) > 1 && AV_RB32(buf) <= (unsigned)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 every NAL unit type except PPS and SPS during extradata
++ /* Ignore per frame NAL unit type during extradata
+ * parsing. Decoding slices is not possible in codec init
+ * with frame-mt */
- if (parse_extradata && HAVE_THREADS &&
- (h->avctx->active_thread_type & FF_THREAD_FRAME) &&
- (nal->type != NAL_PPS && nal->type != NAL_SPS)) {
- if (nal->type < NAL_AUD || nal->type > NAL_AUXILIARY_SLICE)
- av_log(avctx, AV_LOG_INFO,
- "Ignoring NAL unit %d during extradata parsing\n",
++ 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);
- nal->type = NAL_FF_IGNORE;
++ // 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;
+ }
- idr(h); // FIXME ensure we don't lose some frames if there is reordering
++ 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 && h->recovery_frame < 0) {
- h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) &
- ((1 << h->sps.log2_max_frame_num) - 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) || (h->sei_recovery_frame_cnt >= 0);
++ 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) {
++ 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, NULL, 0)) < 0)
- return ret;
++ (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 &&
- (avctx->skip_frame < AVDISCARD_NONREF || nal->ref_idc) &&
- (avctx->skip_frame < AVDISCARD_BIDIR ||
- sl->slice_type_nos != AV_PICTURE_TYPE_B) &&
- (avctx->skip_frame < AVDISCARD_NONKEY ||
- h->cur_pic_ptr->f->key_frame) &&
- avctx->skip_frame < AVDISCARD_ALL) {
++ if (sl->redundant_pic_count == 0) {
+ if (avctx->hwaccel) {
- ret = avctx->hwaccel->decode_slice(avctx, nal->raw_data, nal->raw_size);
++ ret = avctx->hwaccel->decode_slice(avctx,
++ nal->raw_data,
++ nal->raw_size);
+ if (ret < 0)
- return ret;
++ 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");
- ret = AVERROR(ENOSYS);
- goto end;
+ 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;
- ret = ff_h264_decode_seq_parameter_set(h);
- if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
- goto end;
++ 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) {
- av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");
++ 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 == 1) {
++ } 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) {
@@@ -1562,47 -1332,6 +1448,47 @@@
ret = 0;
end:
+
+#if CONFIG_ERROR_RESILIENCE
- sl = h->slice_ctx;
+ /*
+ * FIXME: Error handling code does not seem to support interlaced
+ * when slices span multiple rows
+ * The ff_er_add_slice calls don't work right for bottom
+ * fields; they cause massive erroneous error concealing
+ * Error marking covers both fields (top and bottom).
+ * This causes a mismatched s->error_count
+ * and a bad error table. Further, the error count goes to
+ * INT_MAX when called for bottom field, because mb_y is
+ * past end by one (callers fault) and resync_mb_y != 0
+ * 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);
+
+ if (use_last_pic) {
+ ff_h264_set_erpic(&sl->er.last_pic, &h->last_pic_for_ec);
+ sl->ref_list[0][0].parent = &h->last_pic_for_ec;
+ memcpy(sl->ref_list[0][0].data, h->last_pic_for_ec.f->data, sizeof(sl->ref_list[0][0].data));
+ memcpy(sl->ref_list[0][0].linesize, h->last_pic_for_ec.f->linesize, sizeof(sl->ref_list[0][0].linesize));
+ sl->ref_list[0][0].reference = h->last_pic_for_ec.reference;
+ } else if (sl->ref_count[0]) {
+ ff_h264_set_erpic(&sl->er.last_pic, sl->ref_list[0][0].parent);
+ } else
+ ff_h264_set_erpic(&sl->er.last_pic, NULL);
+
+ if (sl->ref_count[1])
+ ff_h264_set_erpic(&sl->er.next_pic, sl->ref_list[1][0].parent);
+
+ sl->er.ref_count = sl->ref_count[0];
+
+ ff_er_frame_end(&sl->er);
+ if (use_last_pic)
+ memset(&sl->ref_list[0][0], 0, sizeof(sl->ref_list[0][0]));
+ }
+#endif /* CONFIG_ERROR_RESILIENCE */
/* clean up */
if (h->cur_pic_ptr && !h->droppable) {
ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
More information about the ffmpeg-cvslog
mailing list