#include "internal.h"
#include "avcodec.h"
#include "h264.h"
+#include "h264dec.h"
#include "golomb.h"
#include "mpegutils.h"
h264_initialise_ref_list(h, sl);
for (list = 0; list < sl->list_count; list++) {
- int pred = h->curr_pic_num;
+ int pred = sl->curr_pic_num;
for (index = 0; index < sl->nb_ref_modifications[list]; index++) {
unsigned int modification_of_pic_nums_idc = sl->ref_modifications[list][index].op;
const unsigned int abs_diff_pic_num = val + 1;
int frame_num;
- if (abs_diff_pic_num > h->max_pic_num) {
+ if (abs_diff_pic_num > sl->max_pic_num) {
av_log(h->avctx, AV_LOG_ERROR,
"abs_diff_pic_num overflow\n");
return AVERROR_INVALIDDATA;
pred -= abs_diff_pic_num;
else
pred += abs_diff_pic_num;
- pred &= h->max_pic_num - 1;
+ pred &= sl->max_pic_num - 1;
frame_num = pic_num_extract(h, pred, &pic_structure);
}
break;
}
+ default:
+ av_assert0(0);
}
if (i < 0) {
return 0;
}
-int ff_h264_decode_ref_pic_list_reordering(const H264Context *h, H264SliceContext *sl)
+int ff_h264_decode_ref_pic_list_reordering(H264SliceContext *sl, void *logctx)
{
int list, index;
break;
if (index >= sl->ref_count[list]) {
- av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
+ av_log(logctx, AV_LOG_ERROR, "reference count overflow\n");
return AVERROR_INVALIDDATA;
} else if (op > 2) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(logctx, AV_LOG_ERROR,
"illegal modification_of_pic_nums_idc %u\n",
op);
return AVERROR_INVALIDDATA;
h->short_ref_count = 0;
memset(h->default_ref, 0, sizeof(h->default_ref));
- for (i = 0; i < h->nb_slice_ctx; i++) {
- H264SliceContext *sl = &h->slice_ctx[i];
- sl->list_count = sl->ref_count[0] = sl->ref_count[1] = 0;
- memset(sl->ref_list, 0, sizeof(sl->ref_list));
- }
-}
-
-static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos)
-{
- int i;
-
- for (i = 0; i < n_mmcos; i++) {
- if (mmco1[i].opcode != mmco2[i].opcode) {
- av_log(NULL, AV_LOG_ERROR, "MMCO opcode [%d, %d] at %d mismatches between slices\n",
- mmco1[i].opcode, mmco2[i].opcode, i);
- return -1;
- }
- }
-
- return 0;
}
-int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
+static void generate_sliding_window_mmcos(H264Context *h)
{
- MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
- int mmco_index = 0, i = 0;
+ MMCO *mmco = h->mmco;
+ int nb_mmco = 0;
if (h->short_ref_count &&
h->long_ref_count + h->short_ref_count >= h->ps.sps->ref_frame_count &&
!(FIELD_PICTURE(h) && !h->first_field && h->cur_pic_ptr->reference)) {
mmco[0].opcode = MMCO_SHORT2UNUSED;
mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num;
- mmco_index = 1;
+ nb_mmco = 1;
if (FIELD_PICTURE(h)) {
mmco[0].short_pic_num *= 2;
mmco[1].opcode = MMCO_SHORT2UNUSED;
mmco[1].short_pic_num = mmco[0].short_pic_num + 1;
- mmco_index = 2;
+ nb_mmco = 2;
}
}
- if (first_slice) {
- h->mmco_index = mmco_index;
- } else if (!first_slice && mmco_index >= 0 &&
- (mmco_index != h->mmco_index ||
- (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) {
- av_log(h->avctx, AV_LOG_ERROR,
- "Inconsistent MMCO state between slices [%d, %d]\n",
- mmco_index, h->mmco_index);
- return AVERROR_INVALIDDATA;
- }
- return 0;
+ h->nb_mmco = nb_mmco;
}
-int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
+int ff_h264_execute_ref_pic_marking(H264Context *h)
{
+ MMCO *mmco = h->mmco;
+ int mmco_count;
int i, av_uninit(j);
int pps_ref_count[2] = {0};
int current_ref_assigned = 0, err = 0;
H264Picture *av_uninit(pic);
+ if (!h->explicit_ref_marking)
+ generate_sliding_window_mmcos(h);
+ mmco_count = h->nb_mmco;
+
if ((h->avctx->debug & FF_DEBUG_MMCO) && mmco_count == 0)
av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n");
return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
}
-int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
- int first_slice)
+int ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb,
+ const H2645NAL *nal, void *logctx)
{
- int i, ret;
- MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp;
- int mmco_index = 0;
+ int i;
+ MMCO *mmco = sl->mmco;
+ int nb_mmco = 0;
- if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields
+ if (nal->type == H264_NAL_IDR_SLICE) { // FIXME fields
skip_bits1(gb); // broken_link
if (get_bits1(gb)) {
mmco[0].opcode = MMCO_LONG;
mmco[0].long_arg = 0;
- mmco_index = 1;
+ nb_mmco = 1;
}
+ sl->explicit_ref_marking = 1;
} else {
- if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag
+ sl->explicit_ref_marking = get_bits1(gb);
+ if (sl->explicit_ref_marking) {
for (i = 0; i < MAX_MMCO_COUNT; i++) {
MMCOOpcode opcode = get_ue_golomb_31(gb);
mmco[i].opcode = opcode;
if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) {
mmco[i].short_pic_num =
- (h->curr_pic_num - get_ue_golomb_long(gb) - 1) &
- (h->max_pic_num - 1);
+ (sl->curr_pic_num - get_ue_golomb_long(gb) - 1) &
+ (sl->max_pic_num - 1);
#if 0
if (mmco[i].short_pic_num >= h->short_ref_count ||
!h->short_ref[mmco[i].short_pic_num]) {
if (long_arg >= 32 ||
(long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG &&
long_arg == 16) &&
- !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(h)))) {
- av_log(h->avctx, AV_LOG_ERROR,
+ !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(sl)))) {
+ av_log(logctx, AV_LOG_ERROR,
"illegal long ref in memory management control "
"operation %d\n", opcode);
return -1;
}
if (opcode > (unsigned) MMCO_LONG) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(logctx, AV_LOG_ERROR,
"illegal memory management control operation %d\n",
opcode);
return -1;
if (opcode == MMCO_END)
break;
}
- mmco_index = i;
- } else {
- if (first_slice) {
- ret = ff_generate_sliding_window_mmcos(h, first_slice);
- if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
- return ret;
- }
- mmco_index = -1;
+ nb_mmco = i;
}
}
- if (first_slice && mmco_index != -1) {
- memcpy(h->mmco, mmco_temp, sizeof(h->mmco));
- h->mmco_index = mmco_index;
- } else if (!first_slice && mmco_index >= 0 &&
- (mmco_index != h->mmco_index ||
- check_opcodes(h->mmco, mmco_temp, mmco_index))) {
- av_log(h->avctx, AV_LOG_ERROR,
- "Inconsistent MMCO state between slices [%d, %d]\n",
- mmco_index, h->mmco_index);
- return AVERROR_INVALIDDATA;
- }
+ sl->nb_mmco = nb_mmco;
return 0;
}