Commit c8dcff0c authored by Anton Khirnov's avatar Anton Khirnov

h264: factor out calculating the POC count into a separate file

This will allow decoupling the parser from the decoder.
parent 113aeee6
...@@ -143,7 +143,7 @@ static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext * ...@@ -143,7 +143,7 @@ static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *
pp->num_ref_idx_l0_active_minus1 = pps->ref_count[0] - 1; pp->num_ref_idx_l0_active_minus1 = pps->ref_count[0] - 1;
pp->num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1; pp->num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1;
pp->Reserved8BitsA = 0; pp->Reserved8BitsA = 0;
pp->frame_num = h->frame_num; pp->frame_num = h->poc.frame_num;
pp->log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4; pp->log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4;
pp->pic_order_cnt_type = sps->poc_type; pp->pic_order_cnt_type = sps->poc_type;
if (sps->poc_type == 0) if (sps->poc_type == 0)
......
...@@ -399,7 +399,7 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) ...@@ -399,7 +399,7 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
h->slice_context_count = 1; h->slice_context_count = 1;
h->workaround_bugs = avctx->workaround_bugs; h->workaround_bugs = avctx->workaround_bugs;
h->flags = avctx->flags; h->flags = avctx->flags;
h->prev_poc_msb = 1 << 16; h->poc.prev_poc_msb = 1 << 16;
h->x264_build = -1; h->x264_build = -1;
h->recovery_frame = -1; h->recovery_frame = -1;
h->frame_recovered = 0; h->frame_recovered = 0;
...@@ -813,10 +813,10 @@ static void decode_postinit(H264Context *h, int setup_finished) ...@@ -813,10 +813,10 @@ static void decode_postinit(H264Context *h, int setup_finished)
static void idr(H264Context *h) static void idr(H264Context *h)
{ {
ff_h264_remove_all_refs(h); ff_h264_remove_all_refs(h);
h->prev_frame_num = h->poc.prev_frame_num =
h->prev_frame_num_offset = h->poc.prev_frame_num_offset =
h->prev_poc_msb = h->poc.prev_poc_msb =
h->prev_poc_lsb = 0; h->poc.prev_poc_lsb = 0;
} }
/* forget old pics after a seek */ /* forget old pics after a seek */
...@@ -857,85 +857,6 @@ static void flush_dpb(AVCodecContext *avctx) ...@@ -857,85 +857,6 @@ static void flush_dpb(AVCodecContext *avctx)
h->context_initialized = 0; h->context_initialized = 0;
} }
int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc)
{
const SPS *sps = h->ps.sps;
const int max_frame_num = 1 << sps->log2_max_frame_num;
int field_poc[2];
h->frame_num_offset = h->prev_frame_num_offset;
if (h->frame_num < h->prev_frame_num)
h->frame_num_offset += max_frame_num;
if (sps->poc_type == 0) {
const int max_poc_lsb = 1 << sps->log2_max_poc_lsb;
if (h->poc_lsb < h->prev_poc_lsb &&
h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2)
h->poc_msb = h->prev_poc_msb + max_poc_lsb;
else if (h->poc_lsb > h->prev_poc_lsb &&
h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2)
h->poc_msb = h->prev_poc_msb - max_poc_lsb;
else
h->poc_msb = h->prev_poc_msb;
field_poc[0] =
field_poc[1] = h->poc_msb + h->poc_lsb;
if (h->picture_structure == PICT_FRAME)
field_poc[1] += h->delta_poc_bottom;
} else if (sps->poc_type == 1) {
int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc;
int i;
if (sps->poc_cycle_length != 0)
abs_frame_num = h->frame_num_offset + h->frame_num;
else
abs_frame_num = 0;
if (h->nal_ref_idc == 0 && abs_frame_num > 0)
abs_frame_num--;
expected_delta_per_poc_cycle = 0;
for (i = 0; i < sps->poc_cycle_length; i++)
// FIXME integrate during sps parse
expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
if (abs_frame_num > 0) {
int poc_cycle_cnt = (abs_frame_num - 1) / sps->poc_cycle_length;
int frame_num_in_poc_cycle = (abs_frame_num - 1) % sps->poc_cycle_length;
expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle;
for (i = 0; i <= frame_num_in_poc_cycle; i++)
expectedpoc = expectedpoc + sps->offset_for_ref_frame[i];
} else
expectedpoc = 0;
if (h->nal_ref_idc == 0)
expectedpoc = expectedpoc + sps->offset_for_non_ref_pic;
field_poc[0] = expectedpoc + h->delta_poc[0];
field_poc[1] = field_poc[0] + sps->offset_for_top_to_bottom_field;
if (h->picture_structure == PICT_FRAME)
field_poc[1] += h->delta_poc[1];
} else {
int poc = 2 * (h->frame_num_offset + h->frame_num);
if (!h->nal_ref_idc)
poc--;
field_poc[0] = poc;
field_poc[1] = poc;
}
if (h->picture_structure != PICT_BOTTOM_FIELD)
pic_field_poc[0] = field_poc[0];
if (h->picture_structure != PICT_TOP_FIELD)
pic_field_poc[1] = field_poc[1];
*pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]);
return 0;
}
/** /**
* Compute profile from profile_idc and constraint_set?_flags. * Compute profile from profile_idc and constraint_set?_flags.
* *
...@@ -1064,14 +985,14 @@ again: ...@@ -1064,14 +985,14 @@ again:
break; break;
if (h->sei_recovery_frame_cnt >= 0 && h->recovery_frame < 0) { if (h->sei_recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) & h->recovery_frame = (h->poc.frame_num + h->sei_recovery_frame_cnt) &
((1 << h->ps.sps->log2_max_frame_num) - 1); ((1 << h->ps.sps->log2_max_frame_num) - 1);
} }
h->cur_pic_ptr->f->key_frame |= h->cur_pic_ptr->f->key_frame |=
(nal->type == NAL_IDR_SLICE) || (h->sei_recovery_frame_cnt >= 0); (nal->type == NAL_IDR_SLICE) || (h->sei_recovery_frame_cnt >= 0);
if (nal->type == NAL_IDR_SLICE || h->recovery_frame == h->frame_num) { if (nal->type == NAL_IDR_SLICE || h->recovery_frame == h->poc.frame_num) {
h->recovery_frame = -1; h->recovery_frame = -1;
h->cur_pic_ptr->recovered = 1; h->cur_pic_ptr->recovered = 1;
} }
......
...@@ -577,17 +577,7 @@ typedef struct H264Context { ...@@ -577,17 +577,7 @@ typedef struct H264Context {
uint16_t *slice_table_base; uint16_t *slice_table_base;
// POC stuff H264POCContext poc;
int poc_lsb;
int poc_msb;
int delta_poc_bottom;
int delta_poc[2];
int frame_num;
int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0
int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0
int frame_num_offset; ///< for POC type 2
int prev_frame_num_offset; ///< for POC type 2
int prev_frame_num; ///< frame_num of the last pic for POC type 1/2
/** /**
* frame_num for frames or 2 * frame_num + 1 for field pics. * frame_num for frames or 2 * frame_num + 1 for field pics.
...@@ -1059,7 +1049,6 @@ void ff_h264_unref_picture(H264Context *h, H264Picture *pic); ...@@ -1059,7 +1049,6 @@ void ff_h264_unref_picture(H264Context *h, H264Picture *pic);
int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl); int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl);
void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height); void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height);
int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc);
int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl); int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl);
int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count); int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count);
......
...@@ -225,3 +225,83 @@ fail: ...@@ -225,3 +225,83 @@ fail:
ref_count[1] = 0; ref_count[1] = 0;
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
int ff_h264_init_poc(int pic_field_poc[2], int *pic_poc,
const SPS *sps, H264POCContext *pc,
int picture_structure, int nal_ref_idc)
{
const int max_frame_num = 1 << sps->log2_max_frame_num;
int field_poc[2];
pc->frame_num_offset = pc->prev_frame_num_offset;
if (pc->frame_num < pc->prev_frame_num)
pc->frame_num_offset += max_frame_num;
if (sps->poc_type == 0) {
const int max_poc_lsb = 1 << sps->log2_max_poc_lsb;
if (pc->poc_lsb < pc->prev_poc_lsb &&
pc->prev_poc_lsb - pc->poc_lsb >= max_poc_lsb / 2)
pc->poc_msb = pc->prev_poc_msb + max_poc_lsb;
else if (pc->poc_lsb > pc->prev_poc_lsb &&
pc->prev_poc_lsb - pc->poc_lsb < -max_poc_lsb / 2)
pc->poc_msb = pc->prev_poc_msb - max_poc_lsb;
else
pc->poc_msb = pc->prev_poc_msb;
field_poc[0] =
field_poc[1] = pc->poc_msb + pc->poc_lsb;
if (picture_structure == PICT_FRAME)
field_poc[1] += pc->delta_poc_bottom;
} else if (sps->poc_type == 1) {
int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc;
int i;
if (sps->poc_cycle_length != 0)
abs_frame_num = pc->frame_num_offset + pc->frame_num;
else
abs_frame_num = 0;
if (nal_ref_idc == 0 && abs_frame_num > 0)
abs_frame_num--;
expected_delta_per_poc_cycle = 0;
for (i = 0; i < sps->poc_cycle_length; i++)
// FIXME integrate during sps parse
expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
if (abs_frame_num > 0) {
int poc_cycle_cnt = (abs_frame_num - 1) / sps->poc_cycle_length;
int frame_num_in_poc_cycle = (abs_frame_num - 1) % sps->poc_cycle_length;
expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle;
for (i = 0; i <= frame_num_in_poc_cycle; i++)
expectedpoc = expectedpoc + sps->offset_for_ref_frame[i];
} else
expectedpoc = 0;
if (nal_ref_idc == 0)
expectedpoc = expectedpoc + sps->offset_for_non_ref_pic;
field_poc[0] = expectedpoc + pc->delta_poc[0];
field_poc[1] = field_poc[0] + sps->offset_for_top_to_bottom_field;
if (picture_structure == PICT_FRAME)
field_poc[1] += pc->delta_poc[1];
} else {
int poc = 2 * (pc->frame_num_offset + pc->frame_num);
if (!nal_ref_idc)
poc--;
field_poc[0] = poc;
field_poc[1] = poc;
}
if (picture_structure != PICT_BOTTOM_FIELD)
pic_field_poc[0] = field_poc[0];
if (picture_structure != PICT_TOP_FIELD)
pic_field_poc[1] = field_poc[1];
*pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]);
return 0;
}
...@@ -39,6 +39,19 @@ typedef struct H264PredWeightTable { ...@@ -39,6 +39,19 @@ typedef struct H264PredWeightTable {
int implicit_weight[48][48][2]; int implicit_weight[48][48][2];
} H264PredWeightTable; } H264PredWeightTable;
typedef struct H264POCContext {
int poc_lsb;
int poc_msb;
int delta_poc_bottom;
int delta_poc[2];
int frame_num;
int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0
int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0
int frame_num_offset; ///< for POC type 2
int prev_frame_num_offset; ///< for POC type 2
int prev_frame_num; ///< frame_num of the last pic for POC type 1/2
} H264POCContext;
struct SPS; struct SPS;
struct PPS; struct PPS;
...@@ -65,4 +78,8 @@ int ff_h264_parse_ref_count(int *plist_count, int ref_count[2], ...@@ -65,4 +78,8 @@ int ff_h264_parse_ref_count(int *plist_count, int ref_count[2],
GetBitContext *gb, const struct PPS *pps, GetBitContext *gb, const struct PPS *pps,
int slice_type_nos, int picture_structure); int slice_type_nos, int picture_structure);
int ff_h264_init_poc(int pic_field_poc[2], int *pic_poc,
const struct SPS *sps, H264POCContext *poc,
int picture_structure, int nal_ref_idc);
#endif /* AVCODEC_H264_PARSE_H */ #endif /* AVCODEC_H264_PARSE_H */
...@@ -47,6 +47,7 @@ typedef struct H264ParseContext { ...@@ -47,6 +47,7 @@ typedef struct H264ParseContext {
ParseContext pc; ParseContext pc;
H264ParamSets ps; H264ParamSets ps;
H264DSPContext h264dsp; H264DSPContext h264dsp;
H264POCContext poc;
int got_first; int got_first;
} H264ParseContext; } H264ParseContext;
...@@ -274,10 +275,10 @@ static inline int parse_nal_units(AVCodecParserContext *s, ...@@ -274,10 +275,10 @@ static inline int parse_nal_units(AVCodecParserContext *s,
case NAL_IDR_SLICE: case NAL_IDR_SLICE:
s->key_frame = 1; s->key_frame = 1;
h->prev_frame_num = 0; p->poc.prev_frame_num = 0;
h->prev_frame_num_offset = 0; p->poc.prev_frame_num_offset = 0;
h->prev_poc_msb = p->poc.prev_poc_msb =
h->prev_poc_lsb = 0; p->poc.prev_poc_lsb = 0;
/* fall through */ /* fall through */
case NAL_SLICE: case NAL_SLICE:
get_ue_golomb(&nal.gb); // skip first_mb_in_slice get_ue_golomb(&nal.gb); // skip first_mb_in_slice
...@@ -310,7 +311,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, ...@@ -310,7 +311,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
h->ps.pps = p->ps.pps; h->ps.pps = p->ps.pps;
sps = p->ps.sps; sps = p->ps.sps;
h->frame_num = get_bits(&nal.gb, sps->log2_max_frame_num); p->poc.frame_num = get_bits(&nal.gb, sps->log2_max_frame_num);
s->coded_width = 16 * sps->mb_width; s->coded_width = 16 * sps->mb_width;
s->coded_height = 16 * sps->mb_height; s->coded_height = 16 * sps->mb_height;
...@@ -357,26 +358,27 @@ static inline int parse_nal_units(AVCodecParserContext *s, ...@@ -357,26 +358,27 @@ static inline int parse_nal_units(AVCodecParserContext *s,
if (h->nal_unit_type == NAL_IDR_SLICE) if (h->nal_unit_type == NAL_IDR_SLICE)
get_ue_golomb(&nal.gb); /* idr_pic_id */ get_ue_golomb(&nal.gb); /* idr_pic_id */
if (sps->poc_type == 0) { if (sps->poc_type == 0) {
h->poc_lsb = get_bits(&nal.gb, sps->log2_max_poc_lsb); p->poc.poc_lsb = get_bits(&nal.gb, sps->log2_max_poc_lsb);
if (p->ps.pps->pic_order_present == 1 && if (p->ps.pps->pic_order_present == 1 &&
h->picture_structure == PICT_FRAME) h->picture_structure == PICT_FRAME)
h->delta_poc_bottom = get_se_golomb(&nal.gb); p->poc.delta_poc_bottom = get_se_golomb(&nal.gb);
} }
if (sps->poc_type == 1 && if (sps->poc_type == 1 &&
!sps->delta_pic_order_always_zero_flag) { !sps->delta_pic_order_always_zero_flag) {
h->delta_poc[0] = get_se_golomb(&nal.gb); p->poc.delta_poc[0] = get_se_golomb(&nal.gb);
if (p->ps.pps->pic_order_present == 1 && if (p->ps.pps->pic_order_present == 1 &&
h->picture_structure == PICT_FRAME) h->picture_structure == PICT_FRAME)
h->delta_poc[1] = get_se_golomb(&nal.gb); p->poc.delta_poc[1] = get_se_golomb(&nal.gb);
} }
/* Decode POC of this picture. /* Decode POC of this picture.
* The prev_ values needed for decoding POC of the next picture are not set here. */ * The prev_ values needed for decoding POC of the next picture are not set here. */
field_poc[0] = field_poc[1] = INT_MAX; field_poc[0] = field_poc[1] = INT_MAX;
ff_init_poc(h, field_poc, &s->output_picture_number); ff_h264_init_poc(field_poc, &s->output_picture_number, sps,
&p->poc, h->picture_structure, nal.ref_idc);
/* Continue parsing to check if MMCO_RESET is present. /* Continue parsing to check if MMCO_RESET is present.
* FIXME: MMCO_RESET could appear in non-first slice. * FIXME: MMCO_RESET could appear in non-first slice.
...@@ -389,15 +391,15 @@ static inline int parse_nal_units(AVCodecParserContext *s, ...@@ -389,15 +391,15 @@ static inline int parse_nal_units(AVCodecParserContext *s,
} }
/* Set up the prev_ values for decoding POC of the next picture. */ /* Set up the prev_ values for decoding POC of the next picture. */
h->prev_frame_num = got_reset ? 0 : h->frame_num; p->poc.prev_frame_num = got_reset ? 0 : p->poc.frame_num;
h->prev_frame_num_offset = got_reset ? 0 : h->frame_num_offset; p->poc.prev_frame_num_offset = got_reset ? 0 : p->poc.frame_num_offset;
if (h->nal_ref_idc != 0) { if (h->nal_ref_idc != 0) {
if (!got_reset) { if (!got_reset) {
h->prev_poc_msb = h->poc_msb; p->poc.prev_poc_msb = p->poc.poc_msb;
h->prev_poc_lsb = h->poc_lsb; p->poc.prev_poc_lsb = p->poc.poc_lsb;
} else { } else {
h->prev_poc_msb = 0; p->poc.prev_poc_msb = 0;
h->prev_poc_lsb = p->poc.prev_poc_lsb =
h->picture_structure == PICT_BOTTOM_FIELD ? 0 : field_poc[0]; h->picture_structure == PICT_BOTTOM_FIELD ? 0 : field_poc[0];
} }
} }
......
...@@ -156,11 +156,11 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup) ...@@ -156,11 +156,11 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup)
if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) { if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {
if (!h->droppable) { if (!h->droppable) {
err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
h->prev_poc_msb = h->poc_msb; h->poc.prev_poc_msb = h->poc.poc_msb;
h->prev_poc_lsb = h->poc_lsb; h->poc.prev_poc_lsb = h->poc.poc_lsb;
} }
h->prev_frame_num_offset = h->frame_num_offset; h->poc.prev_frame_num_offset = h->poc.frame_num_offset;
h->prev_frame_num = h->frame_num; h->poc.prev_frame_num = h->poc.frame_num;
} }
if (avctx->hwaccel) { if (avctx->hwaccel) {
......
...@@ -656,7 +656,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) ...@@ -656,7 +656,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
remove_long(h, j, 0); remove_long(h, j, 0);
} }
h->frame_num = h->cur_pic_ptr->frame_num = 0; h->poc.frame_num = h->cur_pic_ptr->frame_num = 0;
h->mmco_reset = 1; h->mmco_reset = 1;
h->cur_pic_ptr->mmco_reset = 1; h->cur_pic_ptr->mmco_reset = 1;
break; break;
......
...@@ -409,7 +409,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, ...@@ -409,7 +409,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
h->nal_length_size = h1->nal_length_size; h->nal_length_size = h1->nal_length_size;
// POC timing // POC timing
copy_fields(h, h1, poc_lsb, current_slice); copy_fields(h, h1, poc, current_slice);
copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1); copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1);
copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1); copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1);
...@@ -421,11 +421,11 @@ int ff_h264_update_thread_context(AVCodecContext *dst, ...@@ -421,11 +421,11 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
if (!h->droppable) { if (!h->droppable) {
err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
h->prev_poc_msb = h->poc_msb; h->poc.prev_poc_msb = h->poc.poc_msb;
h->prev_poc_lsb = h->poc_lsb; h->poc.prev_poc_lsb = h->poc.poc_lsb;
} }
h->prev_frame_num_offset = h->frame_num_offset; h->poc.prev_frame_num_offset = h->poc.frame_num_offset;
h->prev_frame_num = h->frame_num; h->poc.prev_frame_num = h->poc.frame_num;
h->recovery_frame = h1->recovery_frame; h->recovery_frame = h1->recovery_frame;
h->frame_recovered = h1->frame_recovered; h->frame_recovered = h1->frame_recovered;
...@@ -447,7 +447,7 @@ static int h264_frame_start(H264Context *h) ...@@ -447,7 +447,7 @@ static int h264_frame_start(H264Context *h)
pic->reference = h->droppable ? 0 : h->picture_structure; pic->reference = h->droppable ? 0 : h->picture_structure;
pic->f->coded_picture_number = h->coded_picture_number++; pic->f->coded_picture_number = h->coded_picture_number++;
pic->field_picture = h->picture_structure != PICT_FRAME; pic->field_picture = h->picture_structure != PICT_FRAME;
pic->frame_num = h->frame_num; pic->frame_num = h->poc.frame_num;
/* /*
* Zero key_frame here; IDR markings per slice in frame or fields are ORed * Zero key_frame here; IDR markings per slice in frame or fields are ORed
* in later. * in later.
...@@ -1106,7 +1106,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1106,7 +1106,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
frame_num = get_bits(&sl->gb, sps->log2_max_frame_num); frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);
if (!h->setup_finished) if (!h->setup_finished)
h->frame_num = frame_num; h->poc.frame_num = frame_num;
sl->mb_mbaff = 0; sl->mb_mbaff = 0;
...@@ -1149,19 +1149,19 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1149,19 +1149,19 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
} else { } else {
/* 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->poc.frame_num != h->poc.prev_frame_num) {
int unwrap_prev_frame_num = h->prev_frame_num; int unwrap_prev_frame_num = h->poc.prev_frame_num;
int max_frame_num = 1 << sps->log2_max_frame_num; int max_frame_num = 1 << sps->log2_max_frame_num;
if (unwrap_prev_frame_num > h->frame_num) if (unwrap_prev_frame_num > h->poc.frame_num)
unwrap_prev_frame_num -= max_frame_num; unwrap_prev_frame_num -= max_frame_num;
if ((h->frame_num - unwrap_prev_frame_num) > sps->ref_frame_count) { if ((h->poc.frame_num - unwrap_prev_frame_num) > sps->ref_frame_count) {
unwrap_prev_frame_num = (h->frame_num - sps->ref_frame_count) - 1; unwrap_prev_frame_num = (h->poc.frame_num - sps->ref_frame_count) - 1;
if (unwrap_prev_frame_num < 0) if (unwrap_prev_frame_num < 0)
unwrap_prev_frame_num += max_frame_num; unwrap_prev_frame_num += max_frame_num;
h->prev_frame_num = unwrap_prev_frame_num; h->poc.prev_frame_num = unwrap_prev_frame_num;
} }
} }
...@@ -1184,7 +1184,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1184,7 +1184,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
last_pic_structure == PICT_TOP_FIELD); last_pic_structure == PICT_TOP_FIELD);
} }
} else { } else {
if (h->cur_pic_ptr->frame_num != h->frame_num) { if (h->cur_pic_ptr->frame_num != h->poc.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
...@@ -1216,20 +1216,20 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1216,20 +1216,20 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
} }
} }
while (h->frame_num != h->prev_frame_num && while (h->poc.frame_num != h->poc.prev_frame_num &&
h->frame_num != (h->prev_frame_num + 1) % (1 << sps->log2_max_frame_num)) { h->poc.frame_num != (h->poc.prev_frame_num + 1) % (1 << 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",
h->frame_num, h->prev_frame_num); h->poc.frame_num, h->poc.prev_frame_num);
ret = initialize_cur_frame(h); ret = initialize_cur_frame(h);
if (ret < 0) { if (ret < 0) {
h->first_field = 0; h->first_field = 0;
return ret; return ret;
} }
h->prev_frame_num++; h->poc.prev_frame_num++;
h->prev_frame_num %= 1 << sps->log2_max_frame_num; h->poc.prev_frame_num %= 1 << sps->log2_max_frame_num;
h->cur_pic_ptr->frame_num = h->prev_frame_num; h->cur_pic_ptr->frame_num = h->poc.prev_frame_num;
ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0); ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1); ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
ret = ff_generate_sliding_window_mmcos(h, 1); ret = ff_generate_sliding_window_mmcos(h, 1);
...@@ -1259,7 +1259,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1259,7 +1259,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
h->mb_height * 16); h->mb_height * 16);
h->short_ref[0]->poc = prev->poc + 2; h->short_ref[0]->poc = prev->poc + 2;
} }
h->short_ref[0]->frame_num = h->prev_frame_num; h->short_ref[0]->frame_num = h->poc.prev_frame_num;
} }
} }
...@@ -1278,7 +1278,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1278,7 +1278,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
h->cur_pic_ptr = NULL; h->cur_pic_ptr = NULL;
h->first_field = FIELD_PICTURE(h); h->first_field = FIELD_PICTURE(h);
} else { } else {
if (h->cur_pic_ptr->frame_num != h->frame_num) { if (h->cur_pic_ptr->frame_num != h->poc.frame_num) {
/* 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. */
...@@ -1318,10 +1318,10 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1318,10 +1318,10 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
assert(sl->mb_y < h->mb_height); assert(sl->mb_y < h->mb_height);
if (h->picture_structure == PICT_FRAME) { if (h->picture_structure == PICT_FRAME) {
h->curr_pic_num = h->frame_num; h->curr_pic_num = h->poc.frame_num;
h->max_pic_num = 1 << sps->log2_max_frame_num; h->max_pic_num = 1 << sps->log2_max_frame_num;
} else { } else {
h->curr_pic_num = 2 * h->frame_num + 1; h->curr_pic_num = 2 * h->poc.frame_num + 1;
h->max_pic_num = 1 << (sps->log2_max_frame_num + 1); h->max_pic_num = 1 << (sps->log2_max_frame_num + 1);
} }
...@@ -1332,12 +1332,12 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1332,12 +1332,12 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
int poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb); int poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb);
if (!h->setup_finished) if (!h->setup_finished)
h->poc_lsb = poc_lsb; h->poc.poc_lsb = poc_lsb;
if (pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) { if (pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) {
int delta_poc_bottom = get_se_golomb(&sl->gb); int delta_poc_bottom = get_se_golomb(&sl->gb);
if (!h->setup_finished) if (!h->setup_finished)
h->delta_poc_bottom = delta_poc_bottom; h->poc.delta_poc_bottom = delta_poc_bottom;
} }
} }
...@@ -1345,18 +1345,19 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1345,18 +1345,19 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
int delta_poc = get_se_golomb(&sl->gb); int delta_poc = get_se_golomb(&sl->gb);
if (!h->setup_finished) if (!h->setup_finished)
h->delta_poc[0] = delta_poc; h->poc.delta_poc[0] = delta_poc;
if (pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) { if (pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) {
delta_poc = get_se_golomb(&sl->gb); delta_poc = get_se_golomb(&sl->gb);
if (!h->setup_finished) if (!h->setup_finished)
h->delta_poc[1] = delta_poc; h->poc.delta_poc[1] = delta_poc;
} }
} }
if (!h->setup_finished) if (!h->setup_finished)
ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc); ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc,
sps, &h->poc, h->picture_structure, h->nal_ref_idc);
if (pps->redundant_pic_cnt_present) if (pps->redundant_pic_cnt_present)
sl->redundant_pic_count = get_ue_golomb(&sl->gb); sl->redundant_pic_count = get_ue_golomb(&sl->gb);
...@@ -1557,7 +1558,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1557,7 +1558,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
av_get_picture_type_char(sl->slice_type), av_get_picture_type_char(sl->slice_type),
sl->slice_type_fixed ? " fix" : "", sl->slice_type_fixed ? " fix" : "",
h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",
pps_id, h->frame_num, pps_id, h->poc.frame_num,
h->cur_pic_ptr->field_poc[0], h->cur_pic_ptr->field_poc[0],
h->cur_pic_ptr->field_poc[1], h->cur_pic_ptr->field_poc[1],
sl->ref_count[0], sl->ref_count[1], sl->ref_count[0], sl->ref_count[1],
......
...@@ -278,7 +278,7 @@ static int vaapi_h264_start_frame(AVCodecContext *avctx, ...@@ -278,7 +278,7 @@ static int vaapi_h264_start_frame(AVCodecContext *avctx,
pic_param->pic_fields.bits.deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present; pic_param->pic_fields.bits.deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present;
pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present; pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present;
pic_param->pic_fields.bits.reference_pic_flag = h->nal_ref_idc != 0; pic_param->pic_fields.bits.reference_pic_flag = h->nal_ref_idc != 0;
pic_param->frame_num = h->frame_num; pic_param->frame_num = h->poc.frame_num;
/* Fill in VAIQMatrixBufferH264. */ /* Fill in VAIQMatrixBufferH264. */
iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferH264)); iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferH264));
......
...@@ -134,7 +134,7 @@ static int vdpau_h264_start_frame(AVCodecContext *avctx, ...@@ -134,7 +134,7 @@ static int vdpau_h264_start_frame(AVCodecContext *avctx,
info->field_order_cnt[0] = h264_foc(pic->field_poc[0]); info->field_order_cnt[0] = h264_foc(pic->field_poc[0]);
info->field_order_cnt[1] = h264_foc(pic->field_poc[1]); info->field_order_cnt[1] = h264_foc(pic->field_poc[1]);
info->is_reference = h->nal_ref_idc != 0; info->is_reference = h->nal_ref_idc != 0;
info->frame_num = h->frame_num; info->frame_num = h->poc.frame_num;
info->field_pic_flag = h->picture_structure != PICT_FRAME; info->field_pic_flag = h->picture_structure != PICT_FRAME;
info->bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD; info->bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD;
info->num_ref_frames = sps->ref_frame_count; info->num_ref_frames = sps->ref_frame_count;
......
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