summaryrefslogtreecommitdiff
path: root/libavcodec/h264dec.c
diff options
context:
space:
mode:
authorClément Bœsch <u@pkh.me>2017-01-17 15:26:38 +0100
committerClément Bœsch <u@pkh.me>2017-01-24 16:13:03 +0100
commit744801989099df26e90b00062c645969c5347533 (patch)
tree776f86b3709a4355e967712065866fb89297be19 /libavcodec/h264dec.c
parent1033f56b074d0aaf95fe2a0c356cd63cbb7f31aa (diff)
parent38efff92f1ef81f3de20ff0460ec7b70c253d714 (diff)
Merge commit '38efff92f1ef81f3de20ff0460ec7b70c253d714'
* commit '38efff92f1ef81f3de20ff0460ec7b70c253d714': FATE: add a test for H.264 with two fields per packet h264: fix decoding multiple fields per packet with slice threads This merge includes two commits because the FATE test was useful in order to make proper testing. The merge gets rid of the now unused: - SLICE_SINGLETHREAD and SLICE_SKIPED macros - max_contexts - "again" label in decode_nal_units() This commit also includes the fix from d3e4d406b. Thanks to wm4 and Michael Niedermayer for their testing. Merged-by: Clément Bœsch <u@pkh.me> Merged-by: Matthieu Bouron <matthieu.bouron@gmail.com>
Diffstat (limited to 'libavcodec/h264dec.c')
-rw-r--r--libavcodec/h264dec.c67
1 files changed, 22 insertions, 45 deletions
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 41e6ce458c..31db1db076 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -602,7 +602,6 @@ static void debug_green_metadata(const H264SEIGreenMetaData *gm, void *logctx)
static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
{
AVCodecContext *const avctx = h->avctx;
- unsigned context_count = 0;
int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts
int idr_cleared=0;
int i, ret = 0;
@@ -610,7 +609,6 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
h->has_slice = 0;
h->nal_unit_type= 0;
- h->max_contexts = h->nb_slice_ctx;
if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS)) {
h->current_slice = 0;
if (!h->first_field)
@@ -640,14 +638,12 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
for (i = 0; i < h->pkt.nb_nals; i++) {
H2645NAL *nal = &h->pkt.nals[i];
- H264SliceContext *sl = &h->slice_ctx[context_count];
- int err;
+ int max_slice_ctx, err;
if (avctx->skip_frame >= AVDISCARD_NONREF &&
nal->ref_idc == 0 && nal->type != H264_NAL_SEI)
continue;
-again:
// FIXME these should stop being context-global variables
h->nal_ref_idc = nal->ref_idc;
h->nal_unit_type = nal->type;
@@ -672,13 +668,9 @@ again:
idr_cleared = 1;
h->has_recovery_point = 1;
case H264_NAL_SLICE:
- sl->gb = nal->gb;
h->has_slice = 1;
- if ((err = ff_h264_decode_slice_header(h, sl, nal)))
- break;
-
- if (sl->redundant_pic_count > 0)
+ if ((err = ff_h264_queue_decode_slice(h, nal)))
break;
if (h->current_slice == 1) {
@@ -698,14 +690,14 @@ again:
#endif
}
- if (avctx->hwaccel) {
- ret = avctx->hwaccel->decode_slice(avctx,
- nal->raw_data,
- nal->raw_size);
- if (ret < 0)
- goto end;
+ max_slice_ctx = avctx->hwaccel ? 1 : h->nb_slice_ctx;
+ if (h->nb_slice_ctx_queued == max_slice_ctx) {
+ if (h->avctx->hwaccel) {
+ ret = avctx->hwaccel->decode_slice(avctx, nal->raw_data, nal->raw_size);
+ h->nb_slice_ctx_queued = 0;
+ } else
#if FF_API_CAP_VDPAU
- } else if (CONFIG_H264_VDPAU_DECODER &&
+ 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,
@@ -713,9 +705,13 @@ again:
ff_vdpau_add_data_chunk(h->cur_pic_ptr->f->data[0],
nal->raw_data,
nal->raw_size);
-#endif
+ ret = 0;
} else
- context_count++;
+#endif
+ ret = ff_h264_execute_decode_slices(h);
+ if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
+ goto end;
+ }
break;
case H264_NAL_DPA:
case H264_NAL_DPB:
@@ -765,34 +761,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
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 (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 > 0) {
- ret = ff_h264_execute_decode_slices(h, context_count);
- if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
- goto end;
- context_count = 0;
- }
- /* Slice could not be decoded in parallel mode, restart. */
- sl = &h->slice_ctx[0];
- goto again;
+ if (err < 0) {
+ av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");
}
}
- if (context_count) {
- ret = ff_h264_execute_decode_slices(h, context_count);
- if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
- goto end;
- }
+
+ ret = ff_h264_execute_decode_slices(h);
+ if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
+ goto end;
ret = 0;
end:
@@ -1013,6 +989,7 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data,
h->flags = avctx->flags;
h->setup_finished = 0;
+ h->nb_slice_ctx_queued = 0;
if (h->backup_width != -1) {
avctx->width = h->backup_width;