Commit 74480198 authored by Clément Bœsch's avatar Clément Bœsch

Merge commit '38efff92'

* commit '38efff92':
  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 d3e4d406.

Thanks to wm4 and Michael Niedermayer for their testing.
Merged-by: 's avatarClément Bœsch <u@pkh.me>
Merged-by: 's avatarMatthieu Bouron <matthieu.bouron@gmail.com>
parents 1033f56b 38efff92
This diff is collapsed.
......@@ -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;
......
......@@ -353,6 +353,7 @@ typedef struct H264Context {
H264SliceContext *slice_ctx;
int nb_slice_ctx;
int nb_slice_ctx_queued;
H2645Packet pkt;
......@@ -491,20 +492,6 @@ typedef struct H264Context {
*/
int current_slice;
/**
* Max number of threads / contexts.
* This is equal to AVCodecContext.thread_count unless
* multithreaded decoding is impossible, in which case it is
* reduced to 1.
*/
int max_contexts;
/**
* 1 if the single thread fallback warning has already been
* displayed, 0 otherwise.
*/
int single_decode_warning;
/** @} */
/**
......@@ -848,10 +835,14 @@ void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y,
int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl,
const H2645NAL *nal);
#define SLICE_SINGLETHREAD 1
#define SLICE_SKIPED 2
int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count);
/**
* Submit a slice for decoding.
*
* Parse the slice header, starting a new field/frame if necessary. If any
* slices are queued for the previous field, they are decoded.
*/
int ff_h264_queue_decode_slice(H264Context *h, const H2645NAL *nal);
int ff_h264_execute_decode_slices(H264Context *h);
int ff_h264_update_thread_context(AVCodecContext *dst,
const AVCodecContext *src);
......
......@@ -215,6 +215,9 @@ FATE_H264-$(call DEMDEC, MOV, H264) += fate-h264-mixed-nal-coding
# this sample has invalid extradata that is not escaped
FATE_H264-$(call DEMDEC, MOV, H264) += fate-h264-unescaped-extradata
# this sample contains field-coded frames, with both fields in a single packet
FATE_H264-$(call DEMDEC, MOV, H264) += fate-h264-twofields-packet
FATE_H264-$(call ALLYES, MOV_DEMUXER H264_MP4TOANNEXB_BSF H264_MUXER) += fate-h264-bsf-mp4toannexb
FATE_H264-$(call DEMDEC, MATROSKA, H264) += fate-h264-direct-bff
FATE_H264-$(call DEMDEC, FLV, H264) += fate-h264-brokensps-2580
......@@ -431,6 +434,7 @@ fate-h264-intra-refresh-recovery: CMD = framecrc -i $(TARGET_SAM
fate-h264-invalid-ref-mod: CMD = framecrc -i $(TARGET_SAMPLES)/h264/h264refframeregression.mp4 -an -frames 10 -pix_fmt yuv420p10le
fate-h264-lossless: CMD = framecrc -i $(TARGET_SAMPLES)/h264/lossless.h264
fate-h264-mixed-nal-coding: CMD = framecrc -i $(TARGET_SAMPLES)/h264/mixed-nal-coding.mp4
fate-h264-twofields-packet: CMD = framecrc -i $(TARGET_SAMPLES)/h264/twofields_packet.mp4 -an -frames 30
fate-h264-unescaped-extradata: CMD = framecrc -i $(TARGET_SAMPLES)/h264/unescaped_extradata.mp4 -an -frames 10
fate-h264-3386: CMD = framecrc -i $(TARGET_SAMPLES)/h264/bbc2.sample.h264
fate-h264-missing-frame: CMD = framecrc -i $(TARGET_SAMPLES)/h264/nondeterministic_cut.h264
......
#tb 0: 1001/30000
#media_type 0: video
#codec_id 0: rawvideo
#dimensions 0: 1920x1080
#sar 0: 1/1
0, 0, 0, 1, 3110400, 0x40d65f69
0, 1, 1, 1, 3110400, 0xdcbc50bf
0, 2, 2, 1, 3110400, 0x73a2276a
0, 3, 3, 1, 3110400, 0x84a2b3c6
0, 4, 4, 1, 3110400, 0x7cf3b570
0, 5, 5, 1, 3110400, 0xa2d1e03a
0, 6, 6, 1, 3110400, 0x03220fb1
0, 7, 7, 1, 3110400, 0x89cd526a
0, 8, 8, 1, 3110400, 0xbb4b7531
0, 9, 9, 1, 3110400, 0x0a69f053
0, 10, 10, 1, 3110400, 0x0187994b
0, 11, 11, 1, 3110400, 0x26ed49fa
0, 12, 12, 1, 3110400, 0xbe8966d4
0, 13, 13, 1, 3110400, 0x248d203c
0, 14, 14, 1, 3110400, 0x3139c754
0, 15, 15, 1, 3110400, 0xf22380c4
0, 16, 16, 1, 3110400, 0x3e00dcc1
0, 17, 17, 1, 3110400, 0x8cbe2483
0, 18, 18, 1, 3110400, 0x6951cd63
0, 19, 19, 1, 3110400, 0x36aca4c5
0, 20, 20, 1, 3110400, 0x4d4f6fbe
0, 21, 21, 1, 3110400, 0x997247aa
0, 22, 22, 1, 3110400, 0x0fd40e06
0, 23, 23, 1, 3110400, 0xa10d2d67
0, 24, 24, 1, 3110400, 0x87c481da
0, 25, 25, 1, 3110400, 0xe3dca3cd
0, 26, 26, 1, 3110400, 0x5f77b078
0, 27, 27, 1, 3110400, 0xf1ddd098
0, 28, 28, 1, 3110400, 0xedcd1754
0, 29, 29, 1, 3110400, 0x14ac7153
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment