return out_i;
}
- int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl)
+static int mismatches_ref(H264Context *h, H264Picture *pic)
+{
+ AVFrame *f = pic->f;
+ return (h->cur_pic_ptr->f->width != f->width ||
+ h->cur_pic_ptr->f->height != f->height ||
+ h->cur_pic_ptr->f->format != f->format);
+}
+
+ static void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl)
{
int i, len;
+ int j;
if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
H264Picture *sorted[32];
for (list = 0; list < 2; list++) {
len = add_sorted(sorted, h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);
len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);
- assert(len <= 32);
+ av_assert0(len <= 32);
- len = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]),
+ len = build_def_list(sl->ref_list[list], FF_ARRAY_ELEMS(sl->ref_list[0]),
sorted, len, 0, h->picture_structure);
- len += build_def_list(h->default_ref_list[list] + len,
- FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
+ len += build_def_list(sl->ref_list[list] + len,
+ FF_ARRAY_ELEMS(sl->ref_list[0]) - len,
h->long_ref, 16, 1, h->picture_structure);
+ av_assert0(len <= 32);
if (len < sl->ref_count[list])
- memset(&h->default_ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len));
+ memset(&sl->ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len));
lens[list] = len;
}
}
}
} else {
- len = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]),
+ len = build_def_list(sl->ref_list[0], FF_ARRAY_ELEMS(sl->ref_list[0]),
h->short_ref, h->short_ref_count, 0, h->picture_structure);
- len += build_def_list(h->default_ref_list[0] + len,
- FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
+ len += build_def_list(sl->ref_list[0] + len,
+ FF_ARRAY_ELEMS(sl->ref_list[0]) - len,
h-> long_ref, 16, 1, h->picture_structure);
+ av_assert0(len <= 32);
if (len < sl->ref_count[0])
- memset(&h->default_ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len));
+ memset(&sl->ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len));
}
#ifdef TRACE
for (i = 0; i < sl->ref_count[0]; i++) {
}
}
#endif
- if (h->default_ref_list[j][i].parent) {
- if (mismatches_ref(h, h->default_ref_list[j][i].parent)) {
+
+ for (j = 0; j<1+(sl->slice_type_nos == AV_PICTURE_TYPE_B); j++) {
+ for (i = 0; i < sl->ref_count[j]; i++) {
- memset(&h->default_ref_list[j][i], 0, sizeof(h->default_ref_list[j][i]));
++ if (sl->ref_list[j][i].parent) {
++ if (mismatches_ref(h, sl->ref_list[j][i].parent)) {
+ av_log(h->avctx, AV_LOG_ERROR, "Discarding mismatching reference\n");
-
- return 0;
++ memset(&sl->ref_list[j][i], 0, sizeof(sl->ref_list[j][i]));
+ }
+ }
+ }
+ }
}
static void print_short_term(H264Context *h);
}
for (list = 0; list < sl->list_count; list++) {
for (index = 0; index < sl->ref_count[list]; index++) {
- if (!sl->ref_list[list][index].parent) {
+ if ( !sl->ref_list[list][index].parent
+ || (!FIELD_PICTURE(h) && (sl->ref_list[list][index].reference&3) != 3)) {
+ int i;
- av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc);
+ av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n");
+ for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++)
+ h->last_pocs[i] = INT_MIN;
- if (h->default_ref_list[list][0].parent
- && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3))
- sl->ref_list[list][index] = h->default_ref_list[list][0];
- else
- return -1;
+ return -1;
}
+ av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f->buf[0]) > 0);
}
}
h->short_ref[i] = NULL;
}
h->short_ref_count = 0;
- memset(h->default_ref_list, 0, sizeof(h->default_ref_list));
+
+ 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));
+ }
}
/**
} else {
release_unused_pictures(h, 0);
}
- h->last_slice_type = -1;
+ /* Some macroblocks can be accessed before they're available in case
+ * of lost slices, MBAFF or threading. */
+ if (FIELD_PICTURE(h)) {
+ for(i = (h->picture_structure == PICT_BOTTOM_FIELD); i<h->mb_height; i++)
+ memset(h->slice_table + i*h->mb_stride, -1, (h->mb_stride - (i+1==h->mb_height)) * sizeof(*h->slice_table));
+ } else {
+ memset(h->slice_table, -1,
+ (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
+ }
}
if (!h->setup_finished)
h->pps.chroma_qp_index_offset[1]) +
6 * (h->sps.bit_depth_luma - 8);
- h->last_slice_type = slice_type;
- memcpy(h->last_ref_count, sl->ref_count, sizeof(h->last_ref_count));
sl->slice_num = ++h->current_slice;
- if (sl->slice_num >= MAX_SLICES) {
- av_log(h->avctx, AV_LOG_ERROR,
- "Too many slices, increase MAX_SLICES and recompile\n");
+
+ if (sl->slice_num)
+ h->slice_row[(sl->slice_num-1)&(MAX_SLICES-1)]= sl->resync_mb_y;
+ if ( h->slice_row[sl->slice_num&(MAX_SLICES-1)] + 3 >= sl->resync_mb_y
+ && h->slice_row[sl->slice_num&(MAX_SLICES-1)] <= sl->resync_mb_y
+ && 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
+ 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);
}
for (j = 0; j < 2; j++) {