1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

Merge commit '51d8725a6e4c7f989d6f0f38b59cb54a2d72846c'

* commit '51d8725a6e4c7f989d6f0f38b59cb54a2d72846c':
  h264: use the main H264Context as the parent for all slice contexts

Conflicts:
	libavcodec/h264.c
	libavcodec/h264.h
	libavcodec/h264_slice.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2015-03-21 21:33:27 +01:00
commit 8bdcec3111
3 changed files with 89 additions and 132 deletions

View File

@ -685,7 +685,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
h->thread_context[0] = h; h->thread_context[0] = h;
for (i = 0; i < h->nb_slice_ctx; i++) for (i = 0; i < h->nb_slice_ctx; i++)
h->slice_ctx[i].h264 = h->thread_context[0]; h->slice_ctx[i].h264 = h;
h->outputed_poc = h->next_outputed_poc = INT_MIN; h->outputed_poc = h->next_outputed_poc = INT_MIN;
for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
@ -1433,7 +1433,6 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
int parse_extradata) int parse_extradata)
{ {
AVCodecContext *const avctx = h->avctx; AVCodecContext *const avctx = h->avctx;
H264Context *hx; ///< thread context
H264SliceContext *sl; H264SliceContext *sl;
int buf_index; int buf_index;
unsigned context_count; unsigned context_count;
@ -1491,10 +1490,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
continue; continue;
} }
hx = h->thread_context[context_count];
sl = &h->slice_ctx[context_count]; sl = &h->slice_ctx[context_count];
ptr = ff_h264_decode_nal(hx, sl, buf + buf_index, &dst_length, ptr = ff_h264_decode_nal(h, sl, buf + buf_index, &dst_length,
&consumed, next_avc - buf_index); &consumed, next_avc - buf_index);
if (!ptr || dst_length < 0) { if (!ptr || dst_length < 0) {
ret = -1; ret = -1;
@ -1507,7 +1505,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
if (h->avctx->debug & FF_DEBUG_STARTCODE) if (h->avctx->debug & FF_DEBUG_STARTCODE)
av_log(h->avctx, AV_LOG_DEBUG, av_log(h->avctx, AV_LOG_DEBUG,
"NAL %d/%d at %d/%d length %d\n", "NAL %d/%d at %d/%d length %d\n",
hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length); h->nal_unit_type, h->nal_ref_idc, buf_index, buf_size, dst_length);
if (h->is_avc && (nalsize != consumed) && nalsize) if (h->is_avc && (nalsize != consumed) && nalsize)
av_log(h->avctx, AV_LOG_DEBUG, av_log(h->avctx, AV_LOG_DEBUG,
@ -1530,7 +1528,7 @@ again:
* parsing. Decoding slices is not possible in codec init * parsing. Decoding slices is not possible in codec init
* with frame-mt */ * with frame-mt */
if (parse_extradata) { if (parse_extradata) {
switch (hx->nal_unit_type) { switch (h->nal_unit_type) {
case NAL_IDR_SLICE: case NAL_IDR_SLICE:
case NAL_SLICE: case NAL_SLICE:
case NAL_DPA: case NAL_DPA:
@ -1538,16 +1536,16 @@ again:
case NAL_DPC: case NAL_DPC:
av_log(h->avctx, AV_LOG_WARNING, av_log(h->avctx, AV_LOG_WARNING,
"Ignoring NAL %d in global header/extradata\n", "Ignoring NAL %d in global header/extradata\n",
hx->nal_unit_type); h->nal_unit_type);
// fall through to next case // fall through to next case
case NAL_AUXILIARY_SLICE: case NAL_AUXILIARY_SLICE:
hx->nal_unit_type = NAL_FF_IGNORE; h->nal_unit_type = NAL_FF_IGNORE;
} }
} }
err = 0; err = 0;
switch (hx->nal_unit_type) { switch (h->nal_unit_type) {
case NAL_IDR_SLICE: case NAL_IDR_SLICE:
if ((ptr[0] & 0xFC) == 0x98) { if ((ptr[0] & 0xFC) == 0x98) {
av_log(h->avctx, AV_LOG_ERROR, "Invalid inter IDR frame\n"); av_log(h->avctx, AV_LOG_ERROR, "Invalid inter IDR frame\n");
@ -1568,7 +1566,7 @@ again:
case NAL_SLICE: case NAL_SLICE:
init_get_bits(&sl->gb, ptr, bit_length); init_get_bits(&sl->gb, ptr, bit_length);
if ((err = ff_h264_decode_slice_header(hx, sl, h))) if ((err = ff_h264_decode_slice_header(h, sl)))
break; break;
if (h->sei_recovery_frame_cnt >= 0) { if (h->sei_recovery_frame_cnt >= 0) {
@ -1586,16 +1584,16 @@ again:
} }
h->cur_pic_ptr->f.key_frame |= h->cur_pic_ptr->f.key_frame |=
(hx->nal_unit_type == NAL_IDR_SLICE); (h->nal_unit_type == NAL_IDR_SLICE);
if (hx->nal_unit_type == NAL_IDR_SLICE || if (h->nal_unit_type == NAL_IDR_SLICE ||
h->recovery_frame == h->frame_num) { h->recovery_frame == h->frame_num) {
h->recovery_frame = -1; h->recovery_frame = -1;
h->cur_pic_ptr->recovered = 1; h->cur_pic_ptr->recovered = 1;
} }
// If we have an IDR, all frames after it in decoded order are // If we have an IDR, all frames after it in decoded order are
// "recovered". // "recovered".
if (hx->nal_unit_type == NAL_IDR_SLICE) if (h->nal_unit_type == NAL_IDR_SLICE)
h->frame_recovered |= FRAME_RECOVERED_IDR; h->frame_recovered |= FRAME_RECOVERED_IDR;
h->frame_recovered |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL); h->frame_recovered |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL);
h->frame_recovered |= 3*!!(avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT); h->frame_recovered |= 3*!!(avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT);
@ -1681,7 +1679,7 @@ again:
break; break;
default: default:
av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n", av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n",
hx->nal_unit_type, bit_length); h->nal_unit_type, bit_length);
} }
if (context_count == h->max_contexts) { if (context_count == h->max_contexts) {
@ -1696,13 +1694,9 @@ again:
av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n"); av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");
sl->ref_count[0] = sl->ref_count[1] = sl->list_count = 0; sl->ref_count[0] = sl->ref_count[1] = sl->list_count = 0;
} else if (err == SLICE_SINGLETHREAD) { } else if (err == SLICE_SINGLETHREAD) {
/* Slice could not be decoded in parallel mode, copy down /* Slice could not be decoded in parallel mode, restart. Note
* NAL unit stuff to context 0 and restart. Note that * that rbsp_buffer is not transferred, but since we no longer
* rbsp_buffer is not transferred, but since we no longer
* run in parallel mode this should not be an issue. */ * run in parallel mode this should not be an issue. */
h->nal_unit_type = hx->nal_unit_type;
h->nal_ref_idc = hx->nal_ref_idc;
hx = h;
sl = &h->slice_ctx[0]; sl = &h->slice_ctx[0];
goto again; goto again;
} }

View File

@ -1171,7 +1171,7 @@ int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc);
int ff_pred_weight_table(H264Context *h, H264SliceContext *sl); int ff_pred_weight_table(H264Context *h, H264SliceContext *sl);
int ff_set_ref_count(H264Context *h, H264SliceContext *sl); int ff_set_ref_count(H264Context *h, H264SliceContext *sl);
int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Context *h0); int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl);
#define SLICE_SINGLETHREAD 1 #define SLICE_SINGLETHREAD 1
#define SLICE_SKIPED 2 #define SLICE_SKIPED 2

View File

@ -977,34 +977,6 @@ static void init_scan_tables(H264Context *h)
} }
} }
/**
* Replicate H264 "master" context to thread contexts.
*/
static int clone_slice(H264Context *dst, H264Context *src)
{
memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset));
dst->cur_pic_ptr = src->cur_pic_ptr;
dst->cur_pic = src->cur_pic;
dst->linesize = src->linesize;
dst->uvlinesize = src->uvlinesize;
dst->first_field = src->first_field;
dst->prev_poc_msb = src->prev_poc_msb;
dst->prev_poc_lsb = src->prev_poc_lsb;
dst->prev_frame_num_offset = src->prev_frame_num_offset;
dst->prev_frame_num = src->prev_frame_num;
dst->short_ref_count = src->short_ref_count;
memcpy(dst->short_ref, src->short_ref, sizeof(dst->short_ref));
memcpy(dst->long_ref, src->long_ref, sizeof(dst->long_ref));
memcpy(dst->default_ref_list, src->default_ref_list, sizeof(dst->default_ref_list));
memcpy(dst->dequant4_coeff, src->dequant4_coeff, sizeof(src->dequant4_coeff));
memcpy(dst->dequant8_coeff, src->dequant8_coeff, sizeof(src->dequant8_coeff));
return 0;
}
static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
{ {
#define HWACCEL_MAX (CONFIG_H264_DXVA2_HWACCEL + \ #define HWACCEL_MAX (CONFIG_H264_DXVA2_HWACCEL + \
@ -1275,12 +1247,10 @@ static enum AVPixelFormat non_j_pixfmt(enum AVPixelFormat a)
* This will (re)intialize the decoder and call h264_frame_start() as needed. * This will (re)intialize the decoder and call h264_frame_start() as needed.
* *
* @param h h264context * @param h h264context
* @param h0 h264 master context (differs from 'h' when doing sliced based
* parallel decoding)
* *
* @return 0 if okay, <0 if an error occurred, 1 if decoding must not be multithreaded * @return 0 if okay, <0 if an error occurred, 1 if decoding must not be multithreaded
*/ */
int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Context *h0) int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
{ {
unsigned int first_mb_in_slice; unsigned int first_mb_in_slice;
unsigned int pps_id; unsigned int pps_id;
@ -1290,7 +1260,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
int must_reinit; int must_reinit;
int needs_reinit = 0; int needs_reinit = 0;
int field_pic_flag, bottom_field_flag; int field_pic_flag, bottom_field_flag;
int first_slice = h == h0 && !h0->current_slice; int first_slice = sl == h->slice_ctx && !h->current_slice;
int frame_num, picture_structure, droppable; int frame_num, picture_structure, droppable;
PPS *pps; PPS *pps;
@ -1300,12 +1270,12 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
first_mb_in_slice = get_ue_golomb_long(&sl->gb); first_mb_in_slice = get_ue_golomb_long(&sl->gb);
if (first_mb_in_slice == 0) { // FIXME better field boundary detection if (first_mb_in_slice == 0) { // FIXME better field boundary detection
if (h0->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) { if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
ff_h264_field_end(h, sl, 1); ff_h264_field_end(h, sl, 1);
} }
h0->current_slice = 0; h->current_slice = 0;
if (!h0->first_field) { if (!h->first_field) {
if (h->cur_pic_ptr && !h->droppable) { if (h->cur_pic_ptr && !h->droppable) {
ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
h->picture_structure == PICT_BOTTOM_FIELD); h->picture_structure == PICT_BOTTOM_FIELD);
@ -1328,6 +1298,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
sl->slice_type_fixed = 0; sl->slice_type_fixed = 0;
slice_type = golomb_to_pict_type[slice_type]; slice_type = golomb_to_pict_type[slice_type];
sl->slice_type = slice_type; sl->slice_type = slice_type;
sl->slice_type_nos = slice_type & 3; sl->slice_type_nos = slice_type & 3;
@ -1354,33 +1325,33 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id); av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (!h0->pps_buffers[pps_id]) { if (!h->pps_buffers[pps_id]) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
"non-existing PPS %u referenced\n", "non-existing PPS %u referenced\n",
pps_id); pps_id);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (h0->au_pps_id >= 0 && pps_id != h0->au_pps_id) { if (h->au_pps_id >= 0 && pps_id != h->au_pps_id) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
"PPS change from %d to %d forbidden\n", "PPS change from %d to %d forbidden\n",
h0->au_pps_id, pps_id); h->au_pps_id, pps_id);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
pps = h0->pps_buffers[pps_id]; pps = h->pps_buffers[pps_id];
if (!h0->sps_buffers[pps->sps_id]) { if (!h->sps_buffers[pps->sps_id]) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
"non-existing SPS %u referenced\n", "non-existing SPS %u referenced\n",
h->pps.sps_id); h->pps.sps_id);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (first_slice) if (first_slice)
h->pps = *h0->pps_buffers[pps_id]; h->pps = *h->pps_buffers[pps_id];
if (pps->sps_id != h->sps.sps_id || if (pps->sps_id != h->sps.sps_id ||
pps->sps_id != h->current_sps_id || pps->sps_id != h->current_sps_id ||
h0->sps_buffers[pps->sps_id]->new) { h->sps_buffers[pps->sps_id]->new) {
if (!first_slice) { if (!first_slice) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
@ -1388,7 +1359,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
h->sps = *h0->sps_buffers[h->pps.sps_id]; h->sps = *h->sps_buffers[h->pps.sps_id];
if (h->mb_width != h->sps.mb_width || if (h->mb_width != h->sps.mb_width ||
h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) || h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) ||
@ -1419,7 +1390,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
|| h->mb_width != h->sps.mb_width || h->mb_width != h->sps.mb_width
|| h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) || h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag)
)); ));
if (non_j_pixfmt(h0->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h0, 0))) if (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0)))
must_reinit = 1; must_reinit = 1;
if (first_slice && av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio)) if (first_slice && av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio))
@ -1455,13 +1426,13 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
if (h->context_initialized && if (h->context_initialized &&
(must_reinit || needs_reinit)) { (must_reinit || needs_reinit)) {
if (h != h0) { if (sl != h->slice_ctx) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
"changing width %d -> %d / height %d -> %d on " "changing width %d -> %d / height %d -> %d on "
"slice %d\n", "slice %d\n",
h->width, h->avctx->coded_width, h->width, h->avctx->coded_width,
h->height, h->avctx->coded_height, h->height, h->avctx->coded_height,
h0->current_slice + 1); h->current_slice + 1);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
@ -1483,7 +1454,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
} }
} }
if (!h->context_initialized) { if (!h->context_initialized) {
if (h != h0) { if (sl != h->slice_ctx) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
"Cannot (re-)initialize context during parallel decoding.\n"); "Cannot (re-)initialize context during parallel decoding.\n");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
@ -1507,17 +1478,17 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
frame_num = get_bits(&sl->gb, h->sps.log2_max_frame_num); frame_num = get_bits(&sl->gb, h->sps.log2_max_frame_num);
if (!first_slice) { if (!first_slice) {
if (h0->frame_num != frame_num) { if (h->frame_num != frame_num) {
av_log(h->avctx, AV_LOG_ERROR, "Frame num change from %d to %d\n", av_log(h->avctx, AV_LOG_ERROR, "Frame num change from %d to %d\n",
h0->frame_num, frame_num); h->frame_num, frame_num);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
} }
sl->mb_mbaff = 0; sl->mb_mbaff = 0;
h->mb_aff_frame = 0; h->mb_aff_frame = 0;
last_pic_structure = h0->picture_structure; last_pic_structure = h->picture_structure;
last_pic_droppable = h0->droppable; last_pic_droppable = h->droppable;
droppable = h->nal_ref_idc == 0; droppable = h->nal_ref_idc == 0;
if (h->sps.frame_mbs_only_flag) { if (h->sps.frame_mbs_only_flag) {
picture_structure = PICT_FRAME; picture_structure = PICT_FRAME;
@ -1536,17 +1507,17 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
h->mb_aff_frame = h->sps.mb_aff; h->mb_aff_frame = h->sps.mb_aff;
} }
} }
if (h0->current_slice) { if (h->current_slice) {
if (last_pic_structure != picture_structure || if (last_pic_structure != picture_structure ||
last_pic_droppable != droppable) { last_pic_droppable != droppable) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
"Changing field mode (%d -> %d) between slices is not allowed\n", "Changing field mode (%d -> %d) between slices is not allowed\n",
last_pic_structure, h->picture_structure); last_pic_structure, h->picture_structure);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} else if (!h0->cur_pic_ptr) { } else if (!h->cur_pic_ptr) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
"unset cur_pic_ptr on slice %d\n", "unset cur_pic_ptr on slice %d\n",
h0->current_slice + 1); h->current_slice + 1);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
} }
@ -1556,7 +1527,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
h->frame_num = frame_num; h->frame_num = frame_num;
sl->mb_field_decoding_flag = picture_structure != PICT_FRAME; sl->mb_field_decoding_flag = picture_structure != PICT_FRAME;
if (h0->current_slice == 0) { if (h->current_slice == 0) {
/* Shorten frame num gaps so we don't have to allocate reference /* Shorten frame num gaps so we don't have to allocate reference
* frames just to throw them away */ * frames just to throw them away */
if (h->frame_num != h->prev_frame_num) { if (h->frame_num != h->prev_frame_num) {
@ -1580,14 +1551,14 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
* decode frames as "finished". * decode frames as "finished".
* We have to do that before the "dummy" in-between frame allocation, * We have to do that before the "dummy" in-between frame allocation,
* since that can modify h->cur_pic_ptr. */ * since that can modify h->cur_pic_ptr. */
if (h0->first_field) { if (h->first_field) {
assert(h0->cur_pic_ptr); assert(h->cur_pic_ptr);
assert(h0->cur_pic_ptr->f.buf[0]); assert(h->cur_pic_ptr->f.buf[0]);
assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF); assert(h->cur_pic_ptr->reference != DELAYED_PIC_REF);
/* Mark old field/frame as completed */ /* Mark old field/frame as completed */
if (h0->cur_pic_ptr->tf.owner == h0->avctx) { if (h->cur_pic_ptr->tf.owner == h->avctx) {
ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
last_pic_structure == PICT_BOTTOM_FIELD); last_pic_structure == PICT_BOTTOM_FIELD);
} }
@ -1596,17 +1567,17 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
/* Previous field is unmatched. Don't display it, but let it /* Previous field is unmatched. Don't display it, but let it
* remain for reference if marked as such. */ * remain for reference if marked as such. */
if (last_pic_structure != PICT_FRAME) { if (last_pic_structure != PICT_FRAME) {
ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
last_pic_structure == PICT_TOP_FIELD); last_pic_structure == PICT_TOP_FIELD);
} }
} else { } else {
if (h0->cur_pic_ptr->frame_num != h->frame_num) { if (h->cur_pic_ptr->frame_num != h->frame_num) {
/* This and previous field were reference, but had /* This and previous field were reference, but had
* different frame_nums. Consider this field first in * different frame_nums. Consider this field first in
* pair. Throw away previous field except for reference * pair. Throw away previous field except for reference
* purposes. */ * purposes. */
if (last_pic_structure != PICT_FRAME) { if (last_pic_structure != PICT_FRAME) {
ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
last_pic_structure == PICT_TOP_FIELD); last_pic_structure == PICT_TOP_FIELD);
} }
} else { } else {
@ -1632,7 +1603,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
} }
} }
while (h->frame_num != h->prev_frame_num && !h0->first_field && while (h->frame_num != h->prev_frame_num && !h->first_field &&
h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) { h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {
H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL; H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
@ -1642,7 +1613,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
h->last_pocs[i] = INT_MIN; h->last_pocs[i] = INT_MIN;
ret = h264_frame_start(h); ret = h264_frame_start(h);
if (ret < 0) { if (ret < 0) {
h0->first_field = 0; h->first_field = 0;
return ret; return ret;
} }
@ -1683,41 +1654,41 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
/* See if we have a decoded first field looking for a pair... /* See if we have a decoded first field looking for a pair...
* We're using that to see whether to continue decoding in that * We're using that to see whether to continue decoding in that
* frame, or to allocate a new one. */ * frame, or to allocate a new one. */
if (h0->first_field) { if (h->first_field) {
assert(h0->cur_pic_ptr); assert(h->cur_pic_ptr);
assert(h0->cur_pic_ptr->f.buf[0]); assert(h->cur_pic_ptr->f.buf[0]);
assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF); assert(h->cur_pic_ptr->reference != DELAYED_PIC_REF);
/* figure out if we have a complementary field pair */ /* figure out if we have a complementary field pair */
if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) { if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {
/* Previous field is unmatched. Don't display it, but let it /* Previous field is unmatched. Don't display it, but let it
* remain for reference if marked as such. */ * remain for reference if marked as such. */
h0->missing_fields ++; h->missing_fields ++;
h0->cur_pic_ptr = NULL; h->cur_pic_ptr = NULL;
h0->first_field = FIELD_PICTURE(h); h->first_field = FIELD_PICTURE(h);
} else { } else {
h0->missing_fields = 0; h->missing_fields = 0;
if (h0->cur_pic_ptr->frame_num != h->frame_num) { if (h->cur_pic_ptr->frame_num != h->frame_num) {
ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX, ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
h0->picture_structure==PICT_BOTTOM_FIELD); h->picture_structure==PICT_BOTTOM_FIELD);
/* This and the previous field had different frame_nums. /* This and the previous field had different frame_nums.
* Consider this field first in pair. Throw away previous * Consider this field first in pair. Throw away previous
* one except for reference purposes. */ * one except for reference purposes. */
h0->first_field = 1; h->first_field = 1;
h0->cur_pic_ptr = NULL; h->cur_pic_ptr = NULL;
} else { } else {
/* Second field in complementary pair */ /* Second field in complementary pair */
h0->first_field = 0; h->first_field = 0;
} }
} }
} else { } else {
/* Frame or first field in a potentially complementary pair */ /* Frame or first field in a potentially complementary pair */
h0->first_field = FIELD_PICTURE(h); h->first_field = FIELD_PICTURE(h);
} }
if (!FIELD_PICTURE(h) || h0->first_field) { if (!FIELD_PICTURE(h) || h->first_field) {
if (h264_frame_start(h) < 0) { if (h264_frame_start(h) < 0) {
h0->first_field = 0; h->first_field = 0;
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
} else { } else {
@ -1732,10 +1703,8 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
memset(h->slice_table, -1, memset(h->slice_table, -1,
(h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table)); (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
} }
h0->last_slice_type = -1; h->last_slice_type = -1;
} }
if (h != h0 && (ret = clone_slice(h, h0)) < 0)
return ret;
h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
@ -1788,9 +1757,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
return ret; return ret;
if (slice_type != AV_PICTURE_TYPE_I && if (slice_type != AV_PICTURE_TYPE_I &&
(h0->current_slice == 0 || (h->current_slice == 0 ||
slice_type != h0->last_slice_type || slice_type != h->last_slice_type ||
memcmp(h0->last_ref_count, sl->ref_count, sizeof(sl->ref_count)))) { memcmp(h->last_ref_count, sl->ref_count, sizeof(sl->ref_count)))) {
ff_h264_fill_default_ref_list(h, sl); ff_h264_fill_default_ref_list(h, sl);
} }
@ -1824,9 +1793,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
// further down the line. This may break decoding if the first slice is // further down the line. This may break decoding if the first slice is
// corrupt, thus we only do this if frame-mt is enabled. // corrupt, thus we only do this if frame-mt is enabled.
if (h->nal_ref_idc) { if (h->nal_ref_idc) {
ret = ff_h264_decode_ref_pic_marking(h0, &sl->gb, ret = ff_h264_decode_ref_pic_marking(h, &sl->gb,
!(h->avctx->active_thread_type & FF_THREAD_FRAME) || !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||
h0->current_slice == 0); h->current_slice == 0);
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
@ -1909,22 +1878,22 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
h->nal_ref_idc == 0)) h->nal_ref_idc == 0))
sl->deblocking_filter = 0; sl->deblocking_filter = 0;
if (sl->deblocking_filter == 1 && h0->max_contexts > 1) { if (sl->deblocking_filter == 1 && h->max_contexts > 1) {
if (h->avctx->flags2 & CODEC_FLAG2_FAST) { if (h->avctx->flags2 & CODEC_FLAG2_FAST) {
/* Cheat slightly for speed: /* Cheat slightly for speed:
* Do not bother to deblock across slices. */ * Do not bother to deblock across slices. */
sl->deblocking_filter = 2; sl->deblocking_filter = 2;
} else { } else {
h0->max_contexts = 1; h->max_contexts = 1;
if (!h0->single_decode_warning) { if (!h->single_decode_warning) {
av_log(h->avctx, AV_LOG_INFO, av_log(h->avctx, AV_LOG_INFO,
"Cannot parallelize slice decoding with deblocking filter type 1, decoding such frames in sequential order\n" "Cannot parallelize slice decoding with deblocking filter type 1, decoding such frames in sequential order\n"
"To parallelize slice decoding you need video encoded with disable_deblocking_filter_idc set to 2 (deblock only edges that do not cross slices).\n" "To parallelize slice decoding you need video encoded with disable_deblocking_filter_idc set to 2 (deblock only edges that do not cross slices).\n"
"Setting the flags2 libavcodec option to +fast (-flags2 +fast) will disable deblocking across slices and enable parallel slice decoding " "Setting the flags2 libavcodec option to +fast (-flags2 +fast) will disable deblocking across slices and enable parallel slice decoding "
"but will generate non-standard-compliant output.\n"); "but will generate non-standard-compliant output.\n");
h0->single_decode_warning = 1; h->single_decode_warning = 1;
} }
if (h != h0) { if (sl != h->slice_ctx) {
av_log(h->avctx, AV_LOG_ERROR, av_log(h->avctx, AV_LOG_ERROR,
"Deblocking switched inside frame.\n"); "Deblocking switched inside frame.\n");
return SLICE_SINGLETHREAD; return SLICE_SINGLETHREAD;
@ -1938,14 +1907,14 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
h->pps.chroma_qp_index_offset[1]) + h->pps.chroma_qp_index_offset[1]) +
6 * (h->sps.bit_depth_luma - 8); 6 * (h->sps.bit_depth_luma - 8);
h0->last_slice_type = slice_type; h->last_slice_type = slice_type;
memcpy(h0->last_ref_count, sl->ref_count, sizeof(h0->last_ref_count)); memcpy(h->last_ref_count, sl->ref_count, sizeof(h->last_ref_count));
sl->slice_num = ++h0->current_slice; sl->slice_num = ++h->current_slice;
if (sl->slice_num) if (sl->slice_num)
h0->slice_row[(sl->slice_num-1)&(MAX_SLICES-1)]= sl->resync_mb_y; h->slice_row[(sl->slice_num-1)&(MAX_SLICES-1)]= sl->resync_mb_y;
if ( h0->slice_row[sl->slice_num&(MAX_SLICES-1)] + 3 >= sl->resync_mb_y if ( h->slice_row[sl->slice_num&(MAX_SLICES-1)] + 3 >= sl->resync_mb_y
&& h0->slice_row[sl->slice_num&(MAX_SLICES-1)] <= sl->resync_mb_y && h->slice_row[sl->slice_num&(MAX_SLICES-1)] <= sl->resync_mb_y
&& sl->slice_num >= MAX_SLICES) { && sl->slice_num >= MAX_SLICES) {
//in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case //in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case
av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", sl->slice_num, MAX_SLICES); av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", sl->slice_num, MAX_SLICES);
@ -1984,9 +1953,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex
(sl->ref_list[j][i].reference & 3); (sl->ref_list[j][i].reference & 3);
} }
h0->au_pps_id = pps_id; h->au_pps_id = pps_id;
h->sps.new = h->sps.new =
h0->sps_buffers[h->pps.sps_id]->new = 0; h->sps_buffers[h->pps.sps_id]->new = 0;
h->current_sps_id = h->pps.sps_id; h->current_sps_id = h->pps.sps_id;
if (h->avctx->debug & FF_DEBUG_PICT_INFO) { if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
@ -2388,7 +2357,7 @@ static void er_add_slice(H264SliceContext *sl,
static int decode_slice(struct AVCodecContext *avctx, void *arg) static int decode_slice(struct AVCodecContext *avctx, void *arg)
{ {
H264SliceContext *sl = arg; H264SliceContext *sl = arg;
const H264Context *h = sl->h264; const H264Context *h = avctx->priv_data;
int lf_x_start = sl->mb_x; int lf_x_start = sl->mb_x;
int ret; int ret;
@ -2573,7 +2542,6 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count) int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count)
{ {
AVCodecContext *const avctx = h->avctx; AVCodecContext *const avctx = h->avctx;
H264Context *hx;
H264SliceContext *sl; H264SliceContext *sl;
int i; int i;
@ -2589,23 +2557,18 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count)
} else { } else {
av_assert0(context_count > 0); av_assert0(context_count > 0);
for (i = 1; i < context_count; i++) { for (i = 1; i < context_count; i++) {
hx = h->thread_context[i];
sl = &h->slice_ctx[i]; sl = &h->slice_ctx[i];
if (CONFIG_ERROR_RESILIENCE) { if (CONFIG_ERROR_RESILIENCE) {
sl->er.error_count = 0; sl->er.error_count = 0;
} }
hx->x264_build = h->x264_build;
} }
avctx->execute(avctx, decode_slice, h->slice_ctx, avctx->execute(avctx, decode_slice, h->slice_ctx,
NULL, context_count, sizeof(h->slice_ctx[0])); NULL, context_count, sizeof(h->slice_ctx[0]));
/* pull back stuff from slices to master context */ /* pull back stuff from slices to master context */
hx = h->thread_context[context_count - 1];
sl = &h->slice_ctx[context_count - 1]; sl = &h->slice_ctx[context_count - 1];
h->mb_y = sl->mb_y; h->mb_y = sl->mb_y;
h->droppable = hx->droppable;
h->picture_structure = hx->picture_structure;
if (CONFIG_ERROR_RESILIENCE) { if (CONFIG_ERROR_RESILIENCE) {
for (i = 1; i < context_count; i++) for (i = 1; i < context_count; i++)
h->slice_ctx[0].er.error_count += h->slice_ctx[i].er.error_count; h->slice_ctx[0].er.error_count += h->slice_ctx[i].er.error_count;