*/
#include "libavutil/avassert.h"
+#include "libavutil/display.h"
#include "libavutil/imgutils.h"
+#include "libavutil/stereo3d.h"
#include "libavutil/timer.h"
#include "internal.h"
#include "cabac.h"
#include "error_resilience.h"
#include "avcodec.h"
#include "h264.h"
+#include "h264dec.h"
#include "h264data.h"
#include "h264chroma.h"
#include "h264_mvpred.h"
+#include "h264_ps.h"
#include "golomb.h"
#include "mathops.h"
#include "mpegutils.h"
return err;
}
}
+
/* copy block_offset since frame_start may not be called */
memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
}
h->coded_picture_number = h1->coded_picture_number;
h->first_field = h1->first_field;
h->picture_structure = h1->picture_structure;
+ h->mb_aff_frame = h1->mb_aff_frame;
h->droppable = h1->droppable;
h->backup_width = h1->backup_width;
h->backup_height = h1->backup_height;
memcpy(&h->poc, &h1->poc, sizeof(h->poc));
- h->curr_pic_num = h1->curr_pic_num;
- h->max_pic_num = h1->max_pic_num;
-
memcpy(h->default_ref, h1->default_ref, sizeof(h->default_ref));
memcpy(h->short_ref, h1->short_ref, sizeof(h->short_ref));
memcpy(h->long_ref, h1->long_ref, sizeof(h->long_ref));
h->postpone_filter = 0;
+ h->mb_aff_frame = h->ps.sps->mb_aff && (h->picture_structure == PICT_FRAME);
+
assert(h->cur_pic_ptr->long_ref == 0);
return 0;
}
}
+static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_slice)
+{
+ const SPS *sps;
+ int needs_reinit = 0, must_reinit, ret;
+
+ if (first_slice) {
+ av_buffer_unref(&h->ps.pps_ref);
+ h->ps.pps = NULL;
+ h->ps.pps_ref = av_buffer_ref(h->ps.pps_list[sl->pps_id]);
+ if (!h->ps.pps_ref)
+ return AVERROR(ENOMEM);
+ h->ps.pps = (const PPS*)h->ps.pps_ref->data;
+ }
+
+ if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
+ av_buffer_unref(&h->ps.sps_ref);
+ h->ps.sps = NULL;
+ h->ps.sps_ref = av_buffer_ref(h->ps.sps_list[h->ps.pps->sps_id]);
+ if (!h->ps.sps_ref)
+ return AVERROR(ENOMEM);
+ h->ps.sps = (const SPS*)h->ps.sps_ref->data;
+
+ if (h->mb_width != h->ps.sps->mb_width ||
+ h->mb_height != h->ps.sps->mb_height * (2 - h->ps.sps->frame_mbs_only_flag) ||
+ h->cur_bit_depth_luma != h->ps.sps->bit_depth_luma ||
+ h->cur_chroma_format_idc != h->ps.sps->chroma_format_idc
+ )
+ needs_reinit = 1;
+
+ if (h->bit_depth_luma != h->ps.sps->bit_depth_luma ||
+ h->chroma_format_idc != h->ps.sps->chroma_format_idc)
+ needs_reinit = 1;
+ }
+ sps = h->ps.sps;
+
+ must_reinit = (h->context_initialized &&
+ ( 16*sps->mb_width != h->avctx->coded_width
+ || 16*sps->mb_height * (2 - sps->frame_mbs_only_flag) != h->avctx->coded_height
+ || h->cur_bit_depth_luma != sps->bit_depth_luma
+ || h->cur_chroma_format_idc != sps->chroma_format_idc
+ || h->mb_width != sps->mb_width
+ || h->mb_height != sps->mb_height * (2 - sps->frame_mbs_only_flag)
+ ));
+ if (h->avctx->pix_fmt == AV_PIX_FMT_NONE
+ || (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0))))
+ must_reinit = 1;
+
+ if (first_slice && av_cmp_q(sps->sar, h->avctx->sample_aspect_ratio))
+ must_reinit = 1;
+
+ if (!h->setup_finished) {
+ h->avctx->profile = ff_h264_get_profile(sps);
+ h->avctx->level = sps->level_idc;
+ h->avctx->refs = sps->ref_frame_count;
+
+ h->mb_width = sps->mb_width;
+ h->mb_height = sps->mb_height * (2 - sps->frame_mbs_only_flag);
+ h->mb_num = h->mb_width * h->mb_height;
+ h->mb_stride = h->mb_width + 1;
+
+ h->b_stride = h->mb_width * 4;
+
+ h->chroma_y_shift = sps->chroma_format_idc <= 1; // 400 uses yuv420p
+
+ h->width = 16 * h->mb_width;
+ h->height = 16 * h->mb_height;
+
+ ret = init_dimensions(h);
+ if (ret < 0)
+ return ret;
+
+ if (sps->video_signal_type_present_flag) {
+ h->avctx->color_range = sps->full_range > 0 ? AVCOL_RANGE_JPEG
+ : AVCOL_RANGE_MPEG;
+ if (sps->colour_description_present_flag) {
+ if (h->avctx->colorspace != sps->colorspace)
+ needs_reinit = 1;
+ h->avctx->color_primaries = sps->color_primaries;
+ h->avctx->color_trc = sps->color_trc;
+ h->avctx->colorspace = sps->colorspace;
+ }
+ }
+ }
+
+ if (!h->context_initialized || must_reinit || needs_reinit) {
+ int flush_changes = h->context_initialized;
+ h->context_initialized = 0;
+ if (sl != h->slice_ctx) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "changing width %d -> %d / height %d -> %d on "
+ "slice %d\n",
+ h->width, h->avctx->coded_width,
+ h->height, h->avctx->coded_height,
+ h->current_slice + 1);
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_assert1(first_slice);
+
+ if (flush_changes)
+ ff_h264_flush_change(h);
+
+ if ((ret = get_pixel_format(h, 1)) < 0)
+ return ret;
+ h->avctx->pix_fmt = ret;
+
+ av_log(h->avctx, AV_LOG_VERBOSE, "Reinit context to %dx%d, "
+ "pix_fmt: %s\n", h->width, h->height, av_get_pix_fmt_name(h->avctx->pix_fmt));
+
+ if ((ret = h264_slice_header_init(h)) < 0) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "h264_slice_header_init() failed\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int h264_export_frame_props(H264Context *h)
+{
+ const SPS *sps = h->ps.sps;
+ H264Picture *cur = h->cur_pic_ptr;
+
+ cur->f->interlaced_frame = 0;
+ cur->f->repeat_pict = 0;
+
+ /* Signal interlacing information externally. */
+ /* Prioritize picture timing SEI information over used
+ * decoding process if it exists. */
+
+ if (sps->pic_struct_present_flag) {
+ H264SEIPictureTiming *pt = &h->sei.picture_timing;
+ switch (pt->pic_struct) {
+ case SEI_PIC_STRUCT_FRAME:
+ break;
+ case SEI_PIC_STRUCT_TOP_FIELD:
+ case SEI_PIC_STRUCT_BOTTOM_FIELD:
+ cur->f->interlaced_frame = 1;
+ break;
+ case SEI_PIC_STRUCT_TOP_BOTTOM:
+ case SEI_PIC_STRUCT_BOTTOM_TOP:
+ if (FIELD_OR_MBAFF_PICTURE(h))
+ cur->f->interlaced_frame = 1;
+ else
+ // try to flag soft telecine progressive
+ cur->f->interlaced_frame = h->prev_interlaced_frame;
+ break;
+ case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
+ case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
+ /* Signal the possibility of telecined film externally
+ * (pic_struct 5,6). From these hints, let the applications
+ * decide if they apply deinterlacing. */
+ cur->f->repeat_pict = 1;
+ break;
+ case SEI_PIC_STRUCT_FRAME_DOUBLING:
+ cur->f->repeat_pict = 2;
+ break;
+ case SEI_PIC_STRUCT_FRAME_TRIPLING:
+ cur->f->repeat_pict = 4;
+ break;
+ }
+
+ if ((pt->ct_type & 3) &&
+ pt->pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP)
+ cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0;
+ } else {
+ /* Derive interlacing flag from used decoding process. */
+ cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
+ }
+ h->prev_interlaced_frame = cur->f->interlaced_frame;
+
+ if (cur->field_poc[0] != cur->field_poc[1]) {
+ /* Derive top_field_first from field pocs. */
+ cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1];
+ } else {
+ if (sps->pic_struct_present_flag) {
+ /* Use picture timing SEI information. Even if it is a
+ * information of a past frame, better than nothing. */
+ if (h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM ||
+ h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
+ cur->f->top_field_first = 1;
+ else
+ cur->f->top_field_first = 0;
+ } else if (cur->f->interlaced_frame) {
+ /* Default to top field first when pic_struct_present_flag
+ * is not set but interlaced frame detected */
+ cur->f->top_field_first = 1;
+ } else {
+ /* Most likely progressive */
+ cur->f->top_field_first = 0;
+ }
+ }
+
+ if (h->sei.frame_packing.present &&
+ h->sei.frame_packing.frame_packing_arrangement_type <= 6 &&
+ h->sei.frame_packing.content_interpretation_type > 0 &&
+ h->sei.frame_packing.content_interpretation_type < 3) {
+ H264SEIFramePacking *fp = &h->sei.frame_packing;
+ AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f);
+ if (stereo) {
+ switch (fp->frame_packing_arrangement_type) {
+ case 0:
+ stereo->type = AV_STEREO3D_CHECKERBOARD;
+ break;
+ case 1:
+ stereo->type = AV_STEREO3D_COLUMNS;
+ break;
+ case 2:
+ stereo->type = AV_STEREO3D_LINES;
+ break;
+ case 3:
+ if (fp->quincunx_sampling_flag)
+ stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+ else
+ stereo->type = AV_STEREO3D_SIDEBYSIDE;
+ break;
+ case 4:
+ stereo->type = AV_STEREO3D_TOPBOTTOM;
+ break;
+ case 5:
+ stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+ break;
+ case 6:
+ stereo->type = AV_STEREO3D_2D;
+ break;
+ }
+
+ if (fp->content_interpretation_type == 2)
+ stereo->flags = AV_STEREO3D_FLAG_INVERT;
+ }
+ }
+
+ if (h->sei.display_orientation.present &&
+ (h->sei.display_orientation.anticlockwise_rotation ||
+ h->sei.display_orientation.hflip ||
+ h->sei.display_orientation.vflip)) {
+ H264SEIDisplayOrientation *o = &h->sei.display_orientation;
+ double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16);
+ AVFrameSideData *rotation = av_frame_new_side_data(cur->f,
+ AV_FRAME_DATA_DISPLAYMATRIX,
+ sizeof(int32_t) * 9);
+ if (rotation) {
+ av_display_rotation_set((int32_t *)rotation->data, angle);
+ av_display_matrix_flip((int32_t *)rotation->data,
+ o->hflip, o->vflip);
+ }
+ }
+
+ if (h->sei.afd.present) {
+ AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD,
+ sizeof(uint8_t));
+
+ if (sd) {
+ *sd->data = h->sei.afd.active_format_description;
+ h->sei.afd.present = 0;
+ }
+ }
+
+ if (h->sei.a53_caption.a53_caption) {
+ H264SEIA53Caption *a53 = &h->sei.a53_caption;
+ AVFrameSideData *sd = av_frame_new_side_data(cur->f,
+ AV_FRAME_DATA_A53_CC,
+ a53->a53_caption_size);
+ if (sd)
+ memcpy(sd->data, a53->a53_caption, a53->a53_caption_size);
+ av_freep(&a53->a53_caption);
+ a53->a53_caption_size = 0;
+ h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+ }
+
+ return 0;
+}
+
/* This function is called right after decoding the slice header for a first
* slice in a field (or a frame). It decides whether we are decoding a new frame
* or a second field in a pair and does the necessary setup.
*/
-static int h264_field_start(H264Context *h, const H264SliceContext *sl)
+static int h264_field_start(H264Context *h, const H264SliceContext *sl,
+ const H2645NAL *nal, int first_slice)
{
int i;
- const SPS *sps = h->ps.sps;
+ const SPS *sps;
int last_pic_structure, last_pic_droppable, ret;
+ ret = h264_init_ps(h, sl, first_slice);
+ if (ret < 0)
+ return ret;
+
+ sps = h->ps.sps;
+
last_pic_droppable = h->droppable;
last_pic_structure = h->picture_structure;
- h->droppable = (h->nal_ref_idc == 0);
+ h->droppable = (nal->ref_idc == 0);
h->picture_structure = sl->picture_structure;
+ h->poc.frame_num = sl->frame_num;
+ h->poc.poc_lsb = sl->poc_lsb;
+ h->poc.delta_poc_bottom = sl->delta_poc_bottom;
+ h->poc.delta_poc[0] = sl->delta_poc[0];
+ h->poc.delta_poc[1] = sl->delta_poc[1];
+
/* Shorten frame num gaps so we don't have to allocate reference
* frames just to throw them away */
if (h->poc.frame_num != h->poc.prev_frame_num) {
(h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
}
+ ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc,
+ h->ps.sps, &h->poc, h->picture_structure, nal->ref_idc);
+
+ memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco));
+ h->nb_mmco = sl->nb_mmco;
+ h->explicit_ref_marking = sl->explicit_ref_marking;
+
+ h->picture_idr = nal->type == H264_NAL_IDR_SLICE;
+
+ if (h->sei.recovery_point.recovery_frame_cnt >= 0) {
+ const int sei_recovery_frame_cnt = h->sei.recovery_point.recovery_frame_cnt;
+
+ if (h->poc.frame_num != sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I)
+ h->valid_recovery_point = 1;
+
+ if ( h->recovery_frame < 0
+ || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > sei_recovery_frame_cnt) {
+ h->recovery_frame = av_mod_uintp2(h->poc.frame_num + sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num);
+
+ if (!h->valid_recovery_point)
+ h->recovery_frame = h->poc.frame_num;
+ }
+ }
+
+ h->cur_pic_ptr->f->key_frame |= (nal->type == H264_NAL_IDR_SLICE);
+
+ if (nal->type == H264_NAL_IDR_SLICE ||
+ (h->recovery_frame == h->poc.frame_num && nal->ref_idc)) {
+ h->recovery_frame = -1;
+ h->cur_pic_ptr->recovered = 1;
+ }
+ // If we have an IDR, all frames after it in decoded order are
+ // "recovered".
+ if (nal->type == H264_NAL_IDR_SLICE)
+ h->frame_recovered |= FRAME_RECOVERED_IDR;
+#if 1
+ h->cur_pic_ptr->recovered |= h->frame_recovered;
+#else
+ h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR);
+#endif
+
+ /* Set the frame properties/side data. Only done for the second field in
+ * field coded frames, since some SEI information is present for each field
+ * and is merged by the SEI parsing code. */
+ if (!FIELD_PICTURE(h) || !h->first_field) {
+ ret = h264_export_frame_props(h);
+ if (ret < 0)
+ return ret;
+ }
+
return 0;
}
-static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
+static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
+ const H2645NAL *nal)
{
const SPS *sps;
const PPS *pps;
- unsigned int pps_id;
int ret;
unsigned int slice_type, tmp, i;
- int must_reinit;
- int needs_reinit = 0;
int field_pic_flag, bottom_field_flag;
int first_slice = sl == h->slice_ctx && !h->current_slice;
- int frame_num, droppable, picture_structure;
- int mb_aff_frame, last_mb_aff_frame;
+ int picture_structure;
if (first_slice)
av_assert0(!h->setup_finished);
sl->first_mb_addr = get_ue_golomb_long(&sl->gb);
- if (sl->first_mb_addr == 0) { // FIXME better field boundary detection
- if (h->current_slice) {
- if (h->setup_finished) {
- av_log(h->avctx, AV_LOG_ERROR, "Too many fields\n");
- return AVERROR_INVALIDDATA;
- }
- if (h->max_contexts > 1) {
- if (!h->single_decode_warning) {
- av_log(h->avctx, AV_LOG_WARNING, "Cannot decode multiple access units as slice threads\n");
- h->single_decode_warning = 1;
- }
- h->max_contexts = 1;
- return SLICE_SINGLETHREAD;
- }
-
- if (h->cur_pic_ptr && FIELD_PICTURE(h) && h->first_field) {
- ret = ff_h264_field_end(h, h->slice_ctx, 1);
- h->current_slice = 0;
- if (ret < 0)
- return ret;
- } else if (h->cur_pic_ptr && !FIELD_PICTURE(h) && !h->first_field && h->nal_unit_type == NAL_IDR_SLICE) {
- av_log(h, AV_LOG_WARNING, "Broken frame packetizing\n");
- ret = ff_h264_field_end(h, h->slice_ctx, 1);
- h->current_slice = 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);
- h->cur_pic_ptr = NULL;
- if (ret < 0)
- return ret;
- } else
- return AVERROR_INVALIDDATA;
- }
-
- if (!h->first_field) {
- if (h->cur_pic_ptr && !h->droppable) {
- ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
- h->picture_structure == PICT_BOTTOM_FIELD);
- }
- h->cur_pic_ptr = NULL;
- }
- }
-
- if (!h->current_slice)
- av_assert0(sl == h->slice_ctx);
-
slice_type = get_ue_golomb_31(&sl->gb);
if (slice_type > 9) {
av_log(h->avctx, AV_LOG_ERROR,
sl->slice_type = slice_type;
sl->slice_type_nos = slice_type & 3;
- if (h->nal_unit_type == NAL_IDR_SLICE &&
+ if (nal->type == H264_NAL_IDR_SLICE &&
sl->slice_type_nos != AV_PICTURE_TYPE_I) {
av_log(h->avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n");
return AVERROR_INVALIDDATA;
}
- if (h->current_slice == 0 && !h->first_field) {
- if (
- (h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) ||
- (h->avctx->skip_frame >= AVDISCARD_BIDIR && sl->slice_type_nos == AV_PICTURE_TYPE_B) ||
- (h->avctx->skip_frame >= AVDISCARD_NONINTRA && sl->slice_type_nos != AV_PICTURE_TYPE_I) ||
- (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != NAL_IDR_SLICE && h->sei.recovery_point.recovery_frame_cnt < 0) ||
- h->avctx->skip_frame >= AVDISCARD_ALL) {
- return SLICE_SKIPED;
- }
- }
-
- pps_id = get_ue_golomb(&sl->gb);
- if (pps_id >= MAX_PPS_COUNT) {
- av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id);
+ sl->pps_id = get_ue_golomb(&sl->gb);
+ if (sl->pps_id >= MAX_PPS_COUNT) {
+ av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", sl->pps_id);
return AVERROR_INVALIDDATA;
}
- if (!h->ps.pps_list[pps_id]) {
+ if (!h->ps.pps_list[sl->pps_id]) {
av_log(h->avctx, AV_LOG_ERROR,
"non-existing PPS %u referenced\n",
- pps_id);
+ sl->pps_id);
return AVERROR_INVALIDDATA;
}
-
- pps = (const PPS*)h->ps.pps_list[pps_id]->data;
+ pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data;
if (!h->ps.sps_list[pps->sps_id]) {
av_log(h->avctx, AV_LOG_ERROR,
- "non-existing SPS %u referenced\n",
- pps->sps_id);
+ "non-existing SPS %u referenced\n", pps->sps_id);
return AVERROR_INVALIDDATA;
}
+ sps = (const SPS*)h->ps.sps_list[pps->sps_id]->data;
- if (first_slice) {
- av_buffer_unref(&h->ps.pps_ref);
- h->ps.pps = NULL;
- h->ps.pps_ref = av_buffer_ref(h->ps.pps_list[pps_id]);
- if (!h->ps.pps_ref)
- return AVERROR(ENOMEM);
- h->ps.pps = (const PPS*)h->ps.pps_ref->data;
- } else {
- if (h->ps.pps->sps_id != pps->sps_id ||
- h->ps.pps->transform_8x8_mode != pps->transform_8x8_mode /*||
- (h->setup_finished && h->ps.pps != pps)*/) {
- av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
- if (!first_slice) {
- av_log(h->avctx, AV_LOG_ERROR,
- "SPS changed in the middle of the frame\n");
- return AVERROR_INVALIDDATA;
- }
-
- av_buffer_unref(&h->ps.sps_ref);
- h->ps.sps = NULL;
- h->ps.sps_ref = av_buffer_ref(h->ps.sps_list[h->ps.pps->sps_id]);
- if (!h->ps.sps_ref)
- return AVERROR(ENOMEM);
- h->ps.sps = (const SPS*)h->ps.sps_ref->data;
-
- if (h->mb_width != h->ps.sps->mb_width ||
- h->mb_height != h->ps.sps->mb_height * (2 - h->ps.sps->frame_mbs_only_flag) ||
- h->cur_bit_depth_luma != h->ps.sps->bit_depth_luma ||
- h->cur_chroma_format_idc != h->ps.sps->chroma_format_idc
- )
- needs_reinit = 1;
-
- if (h->bit_depth_luma != h->ps.sps->bit_depth_luma ||
- h->chroma_format_idc != h->ps.sps->chroma_format_idc)
- needs_reinit = 1;
- }
-
- pps = h->ps.pps;
- sps = h->ps.sps;
-
- must_reinit = (h->context_initialized &&
- ( 16*sps->mb_width != h->avctx->coded_width
- || 16*sps->mb_height * (2 - sps->frame_mbs_only_flag) != h->avctx->coded_height
- || h->cur_bit_depth_luma != sps->bit_depth_luma
- || h->cur_chroma_format_idc != sps->chroma_format_idc
- || h->mb_width != sps->mb_width
- || h->mb_height != sps->mb_height * (2 - sps->frame_mbs_only_flag)
- ));
- if (h->avctx->pix_fmt == AV_PIX_FMT_NONE
- || (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0))))
- must_reinit = 1;
-
- if (first_slice && av_cmp_q(sps->sar, h->avctx->sample_aspect_ratio))
- must_reinit = 1;
-
- if (!h->setup_finished) {
- h->avctx->profile = ff_h264_get_profile(sps);
- h->avctx->level = sps->level_idc;
- h->avctx->refs = sps->ref_frame_count;
-
- h->mb_width = sps->mb_width;
- h->mb_height = sps->mb_height * (2 - sps->frame_mbs_only_flag);
- h->mb_num = h->mb_width * h->mb_height;
- h->mb_stride = h->mb_width + 1;
-
- h->b_stride = h->mb_width * 4;
-
- h->chroma_y_shift = sps->chroma_format_idc <= 1; // 400 uses yuv420p
-
- h->width = 16 * h->mb_width;
- h->height = 16 * h->mb_height;
-
- ret = init_dimensions(h);
- if (ret < 0)
- return ret;
-
- if (sps->video_signal_type_present_flag) {
- h->avctx->color_range = sps->full_range > 0 ? AVCOL_RANGE_JPEG
- : AVCOL_RANGE_MPEG;
- if (sps->colour_description_present_flag) {
- if (h->avctx->colorspace != sps->colorspace)
- needs_reinit = 1;
- h->avctx->color_primaries = sps->color_primaries;
- h->avctx->color_trc = sps->color_trc;
- h->avctx->colorspace = sps->colorspace;
- }
- }
- }
-
- if (!h->context_initialized || must_reinit || needs_reinit) {
- int flush_changes = h->context_initialized;
- h->context_initialized = 0;
- if (sl != h->slice_ctx) {
- av_log(h->avctx, AV_LOG_ERROR,
- "changing width %d -> %d / height %d -> %d on "
- "slice %d\n",
- h->width, h->avctx->coded_width,
- h->height, h->avctx->coded_height,
- h->current_slice + 1);
- return AVERROR_INVALIDDATA;
- }
-
- av_assert1(first_slice);
-
- if(flush_changes)
- ff_h264_flush_change(h);
-
- if ((ret = get_pixel_format(h, 1)) < 0)
- return ret;
- h->avctx->pix_fmt = ret;
-
- av_log(h->avctx, AV_LOG_VERBOSE, "Reinit context to %dx%d, "
- "pix_fmt: %s\n", h->width, h->height, av_get_pix_fmt_name(h->avctx->pix_fmt));
-
- if ((ret = h264_slice_header_init(h)) < 0) {
- av_log(h->avctx, AV_LOG_ERROR,
- "h264_slice_header_init() failed\n");
- return ret;
- }
- }
-
- frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);
+ sl->frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);
if (!first_slice) {
- if (h->poc.frame_num != frame_num) {
+ if (h->poc.frame_num != sl->frame_num) {
av_log(h->avctx, AV_LOG_ERROR, "Frame num change from %d to %d\n",
- h->poc.frame_num, frame_num);
+ h->poc.frame_num, sl->frame_num);
return AVERROR_INVALIDDATA;
}
}
- if (!h->setup_finished)
- h->poc.frame_num = frame_num;
-
sl->mb_mbaff = 0;
- mb_aff_frame = 0;
- last_mb_aff_frame = h->mb_aff_frame;
- droppable = h->nal_ref_idc == 0;
if (sps->frame_mbs_only_flag) {
picture_structure = PICT_FRAME;
} else {
return -1;
}
field_pic_flag = get_bits1(&sl->gb);
-
if (field_pic_flag) {
bottom_field_flag = get_bits1(&sl->gb);
picture_structure = PICT_TOP_FIELD + bottom_field_flag;
} else {
picture_structure = PICT_FRAME;
- mb_aff_frame = sps->mb_aff;
- }
- }
-
- if (h->current_slice) {
- if (h->picture_structure != picture_structure ||
- h->droppable != droppable ||
- last_mb_aff_frame != mb_aff_frame) {
- av_log(h->avctx, AV_LOG_ERROR,
- "Changing field mode (%d -> %d) between slices is not allowed\n",
- h->picture_structure, picture_structure);
- return AVERROR_INVALIDDATA;
- } else if (!h->cur_pic_ptr) {
- av_log(h->avctx, AV_LOG_ERROR,
- "unset cur_pic_ptr on slice %d\n",
- h->current_slice + 1);
- return AVERROR_INVALIDDATA;
}
}
-
- if (!h->setup_finished) {
- h->mb_aff_frame = mb_aff_frame;
- }
sl->picture_structure = picture_structure;
sl->mb_field_decoding_flag = picture_structure != PICT_FRAME;
if (picture_structure == PICT_FRAME) {
- h->curr_pic_num = h->poc.frame_num;
- h->max_pic_num = 1 << sps->log2_max_frame_num;
+ sl->curr_pic_num = sl->frame_num;
+ sl->max_pic_num = 1 << sps->log2_max_frame_num;
} else {
- h->curr_pic_num = 2 * h->poc.frame_num + 1;
- h->max_pic_num = 1 << (sps->log2_max_frame_num + 1);
+ sl->curr_pic_num = 2 * sl->frame_num + 1;
+ sl->max_pic_num = 1 << (sps->log2_max_frame_num + 1);
}
- if (h->nal_unit_type == NAL_IDR_SLICE)
+ if (nal->type == H264_NAL_IDR_SLICE)
get_ue_golomb_long(&sl->gb); /* idr_pic_id */
if (sps->poc_type == 0) {
- int poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb);
+ sl->poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb);
- if (!h->setup_finished)
- h->poc.poc_lsb = poc_lsb;
-
- if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME) {
- int delta_poc_bottom = get_se_golomb(&sl->gb);
- if (!h->setup_finished)
- h->poc.delta_poc_bottom = delta_poc_bottom;
- }
+ if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME)
+ sl->delta_poc_bottom = get_se_golomb(&sl->gb);
}
if (sps->poc_type == 1 && !sps->delta_pic_order_always_zero_flag) {
- int delta_poc = get_se_golomb(&sl->gb);
+ sl->delta_poc[0] = get_se_golomb(&sl->gb);
- if (!h->setup_finished)
- h->poc.delta_poc[0] = delta_poc;
-
- if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME) {
- delta_poc = get_se_golomb(&sl->gb);
-
- if (!h->setup_finished)
- h->poc.delta_poc[1] = delta_poc;
- }
+ if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME)
+ sl->delta_poc[1] = get_se_golomb(&sl->gb);
}
+ sl->redundant_pic_count = 0;
if (pps->redundant_pic_cnt_present)
sl->redundant_pic_count = get_ue_golomb(&sl->gb);
return ret;
if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
- ret = ff_h264_decode_ref_pic_list_reordering(h, sl);
+ ret = ff_h264_decode_ref_pic_list_reordering(sl, h->avctx);
if (ret < 0) {
sl->ref_count[1] = sl->ref_count[0] = 0;
return ret;
sl->slice_type_nos, &sl->pwt, h->avctx);
sl->explicit_ref_marking = 0;
- if (h->nal_ref_idc) {
- ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb);
+ if (nal->ref_idc) {
+ ret = ff_h264_decode_ref_pic_marking(sl, &sl->gb, nal, h->avctx);
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
return AVERROR_INVALIDDATA;
}
*
* @return 0 if okay, <0 if an error occurred
*/
-int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
+int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl,
+ const H2645NAL *nal)
{
int i, j, ret = 0;
+ int first_slice = sl == h->slice_ctx && !h->current_slice;
- ret = h264_slice_header_parse(h, sl);
- if (ret) // can not be ret<0 because of SLICE_SKIPED, SLICE_SINGLETHREAD, ...
+ ret = h264_slice_header_parse(h, sl, nal);
+ if (ret < 0)
return ret;
+ // discard redundant pictures
+ if (sl->redundant_pic_count > 0)
+ return 0;
+
+ if (sl->first_mb_addr == 0 || !h->current_slice) {
+ if (h->setup_finished) {
+ av_log(h->avctx, AV_LOG_ERROR, "Too many fields\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (sl->first_mb_addr == 0) { // FIXME better field boundary detection
+ if (h->current_slice) {
+ if (h->max_contexts > 1) {
+ if (!h->single_decode_warning) {
+ av_log(h->avctx, AV_LOG_WARNING, "Cannot decode multiple access units as slice threads\n");
+ h->single_decode_warning = 1;
+ }
+ h->max_contexts = 1;
+ return SLICE_SINGLETHREAD;
+ }
+
+ if (h->cur_pic_ptr && FIELD_PICTURE(h) && h->first_field) {
+ ret = ff_h264_field_end(h, h->slice_ctx, 1);
+ h->current_slice = 0;
+ if (ret < 0)
+ return ret;
+ } else if (h->cur_pic_ptr && !FIELD_PICTURE(h) && !h->first_field && h->nal_unit_type == H264_NAL_IDR_SLICE) {
+ av_log(h, AV_LOG_WARNING, "Broken frame packetizing\n");
+ ret = ff_h264_field_end(h, h->slice_ctx, 1);
+ h->current_slice = 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);
+ h->cur_pic_ptr = NULL;
+ if (ret < 0)
+ return ret;
+ } else
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!h->first_field) {
+ if (h->cur_pic_ptr && !h->droppable) {
+ ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
+ h->picture_structure == PICT_BOTTOM_FIELD);
+ }
+ h->cur_pic_ptr = NULL;
+ }
+ }
+
+ if (!h->current_slice)
+ av_assert0(sl == h->slice_ctx);
+
+ if (h->current_slice == 0 && !h->first_field) {
+ if (
+ (h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) ||
+ (h->avctx->skip_frame >= AVDISCARD_BIDIR && sl->slice_type_nos == AV_PICTURE_TYPE_B) ||
+ (h->avctx->skip_frame >= AVDISCARD_NONINTRA && sl->slice_type_nos != AV_PICTURE_TYPE_I) ||
+ (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != H264_NAL_IDR_SLICE && h->sei.recovery_point.recovery_frame_cnt < 0) ||
+ h->avctx->skip_frame >= AVDISCARD_ALL) {
+ return SLICE_SKIPED;
+ }
+ }
+
+ if (!first_slice) {
+ const PPS *pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data;
+
+ if (h->ps.pps->sps_id != pps->sps_id ||
+ h->ps.pps->transform_8x8_mode != pps->transform_8x8_mode /*||
+ (h->setup_finished && h->ps.pps != pps)*/) {
+ av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "SPS changed in the middle of the frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
if (h->current_slice == 0) {
- ret = h264_field_start(h, sl);
+ ret = h264_field_start(h, sl, nal, first_slice);
if (ret < 0)
return ret;
+ } else {
+ if (h->picture_structure != sl->picture_structure ||
+ h->droppable != (nal->ref_idc == 0)) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "Changing field mode (%d -> %d) between slices is not allowed\n",
+ h->picture_structure, sl->picture_structure);
+ return AVERROR_INVALIDDATA;
+ } else if (!h->cur_pic_ptr) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "unset cur_pic_ptr on slice %d\n",
+ h->current_slice + 1);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (h->picture_idr && nal->type != H264_NAL_IDR_SLICE) {
+ av_log(h->avctx, AV_LOG_ERROR, "Invalid mix of IDR and non-IDR slices\n");
+ return AVERROR_INVALIDDATA;
}
av_assert1(h->mb_num == h->mb_width * h->mb_height);
sl->resync_mb_y = sl->mb_y = sl->mb_y + 1;
av_assert1(sl->mb_y < h->mb_height);
- if (!h->setup_finished) {
- ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc,
- h->ps.sps, &h->poc, h->picture_structure, h->nal_ref_idc);
-
- memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco));
- h->nb_mmco = sl->nb_mmco;
- h->explicit_ref_marking = sl->explicit_ref_marking;
- }
-
ret = ff_h264_build_ref_list(h, sl);
if (ret < 0)
return ret;
if (h->avctx->skip_loop_filter >= AVDISCARD_ALL ||
(h->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&
- h->nal_unit_type != NAL_IDR_SLICE) ||
+ h->nal_unit_type != H264_NAL_IDR_SLICE) ||
(h->avctx->skip_loop_filter >= AVDISCARD_NONINTRA &&
sl->slice_type_nos != AV_PICTURE_TYPE_I) ||
(h->avctx->skip_loop_filter >= AVDISCARD_BIDIR &&
sl->slice_type_nos == AV_PICTURE_TYPE_B) ||
(h->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
- h->nal_ref_idc == 0))
+ nal->ref_idc == 0))
sl->deblocking_filter = 0;
if (sl->deblocking_filter == 1 && h->max_contexts > 1) {
sl->mb_y * h->mb_width + sl->mb_x,
av_get_picture_type_char(sl->slice_type),
sl->slice_type_fixed ? " fix" : "",
- h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",
+ nal->type == H264_NAL_IDR_SLICE ? " IDR" : "",
h->poc.frame_num,
h->cur_pic_ptr->field_poc[0],
h->cur_pic_ptr->field_poc[1],
if (USES_LIST(top_type, list)) {
const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride;
const int b8_xy = 4 * top_xy + 2;
- const int *ref2frm = h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][list] + (MB_MBAFF(sl) ? 20 : 2);
+ const int *ref2frm = &h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][list][(MB_MBAFF(sl) ? 20 : 2)];
AV_COPY128(mv_dst - 1 * 8, h->cur_pic.motion_val[list][b_xy + 0]);
ref_cache[0 - 1 * 8] =
ref_cache[1 - 1 * 8] = ref2frm[h->cur_pic.ref_index[list][b8_xy + 0]];
if (USES_LIST(left_type[LTOP], list)) {
const int b_xy = h->mb2b_xy[left_xy[LTOP]] + 3;
const int b8_xy = 4 * left_xy[LTOP] + 1;
- const int *ref2frm = h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][list] + (MB_MBAFF(sl) ? 20 : 2);
+ const int *ref2frm = &h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][list][(MB_MBAFF(sl) ? 20 : 2)];
AV_COPY32(mv_dst - 1 + 0, h->cur_pic.motion_val[list][b_xy + b_stride * 0]);
AV_COPY32(mv_dst - 1 + 8, h->cur_pic.motion_val[list][b_xy + b_stride * 1]);
AV_COPY32(mv_dst - 1 + 16, h->cur_pic.motion_val[list][b_xy + b_stride * 2]);
{
int8_t *ref = &h->cur_pic.ref_index[list][4 * mb_xy];
- const int *ref2frm = h->ref2frm[sl->slice_num & (MAX_SLICES - 1)][list] + (MB_MBAFF(sl) ? 20 : 2);
+ const int *ref2frm = &h->ref2frm[sl->slice_num & (MAX_SLICES - 1)][list][(MB_MBAFF(sl) ? 20 : 2)];
uint32_t ref01 = (pack16to32(ref2frm[ref[0]], ref2frm[ref[1]]) & 0x00FF00FF) * 0x0101;
uint32_t ref23 = (pack16to32(ref2frm[ref[2]], ref2frm[ref[3]]) & 0x00FF00FF) * 0x0101;
AV_WN32A(&ref_cache[0 * 8], ref01);
sl->deblocking_filter = 0;
sl->is_complex = FRAME_MBAFF(h) || h->picture_structure != PICT_FRAME ||
- avctx->codec_id != AV_CODEC_ID_H264 ||
(CONFIG_GRAY && (h->flags & AV_CODEC_FLAG_GRAY));
if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && h->slice_ctx[0].er.error_status_table) {