if (list0 && list1) {
/* don't optimize for luma-only case, since B-frames usually
* use implicit weights => chroma too. */
- uint8_t *tmp_cb = s->obmc_scratchpad;
- uint8_t *tmp_cr = s->obmc_scratchpad + (16 << pixel_shift);
- uint8_t *tmp_y = s->obmc_scratchpad + 16 * h->mb_uvlinesize;
+ uint8_t *tmp_cb = h->bipred_scratchpad;
+ uint8_t *tmp_cr = h->bipred_scratchpad + (16 << pixel_shift);
+ uint8_t *tmp_y = h->bipred_scratchpad + 16 * h->mb_uvlinesize;
int refn0 = h->ref_cache[0][scan8[n]];
int refn1 = h->ref_cache[1][scan8[n]];
continue;
av_freep(&hx->top_borders[1]);
av_freep(&hx->top_borders[0]);
- av_freep(&hx->s.obmc_scratchpad);
+ av_freep(&hx->bipred_scratchpad);
if (free_rbsp) {
av_freep(&hx->rbsp_buffer[1]);
av_freep(&hx->rbsp_buffer[0]);
h->mb2br_xy[mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * s->mb_stride)));
}
- s->obmc_scratchpad = NULL;
-
if (!h->dequant4_coeff[0])
init_dequant_tables(h);
dst->mvd_table[1] = src->mvd_table[1] + i * 8 * 2 * s->mb_stride;
dst->direct_table = src->direct_table;
dst->list_counts = src->list_counts;
- dst->s.obmc_scratchpad = NULL;
+ dst->bipred_scratchpad = NULL;
ff_h264_pred_init(&dst->hpc, src->s.codec_id, src->sps.bit_depth_luma,
src->sps.chroma_format_idc);
}
return -1; // free_tables will clean up for us
}
-static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size);
+static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
+ int parse_extradata);
static av_cold void common_init(H264Context *h)
{
memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
}
-static int ff_h264_decode_extradata_internal(H264Context *h, const uint8_t *buf, int size)
+int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
{
AVCodecContext *avctx = h->s.avctx;
nalsize = AV_RB16(p) + 2;
if(nalsize > size - (p-buf))
return -1;
- if (decode_nal_units(h, p, nalsize) < 0) {
+ if (decode_nal_units(h, p, nalsize, 1) < 0) {
av_log(avctx, AV_LOG_ERROR,
"Decoding sps %d from avcC failed\n", i);
return -1;
nalsize = AV_RB16(p) + 2;
if(nalsize > size - (p-buf))
return -1;
- if (decode_nal_units(h, p, nalsize) < 0) {
+ if (decode_nal_units(h, p, nalsize, 1) < 0) {
av_log(avctx, AV_LOG_ERROR,
"Decoding pps %d from avcC failed\n", i);
return -1;
h->nal_length_size = (buf[4] & 0x03) + 1;
} else {
h->is_avc = 0;
- if (decode_nal_units(h, buf, size) < 0)
+ if (decode_nal_units(h, buf, size, 1) < 0)
return -1;
}
return size;
}
-int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
-{
- int ret;
- h->decoding_extradata = 1;
- ret = ff_h264_decode_extradata_internal(h, buf, size);
- h->decoding_extradata = 0;
- return ret;
-}
-
av_cold int ff_h264_decode_init(AVCodecContext *avctx)
{
H264Context *h = avctx->priv_data;
memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
+ h->s.context_initialized = 0;
+
return 0;
}
memcpy(&to->start_field, &from->start_field, \
(char *)&to->end_field - (char *)&to->start_field)
+static int h264_slice_header_init(H264Context *, int);
+
+static int h264_set_parameter_from_sps(H264Context *h);
+
static int decode_update_thread_context(AVCodecContext *dst,
const AVCodecContext *src)
{
if (dst == src)
return 0;
+ if (inited &&
+ (s->width != s1->width ||
+ s->height != s1->height ||
+ s->mb_width != s1->mb_width ||
+ s->mb_height != s1->mb_height ||
+ h->sps.bit_depth_luma != h1->sps.bit_depth_luma ||
+ h->sps.chroma_format_idc != h1->sps.chroma_format_idc ||
+ h->sps.colorspace != h1->sps.colorspace)) {
+
+ av_freep(&h->bipred_scratchpad);
+
+ s->width = s1->width;
+ s->height = s1->height;
+ s->mb_height = s1->mb_height;
+ h->b_stride = h1->b_stride;
+ // SPS/PPS
+ copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers,
+ MAX_SPS_COUNT, sizeof(SPS));
+ h->sps = h1->sps;
+ copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers,
+ MAX_PPS_COUNT, sizeof(PPS));
+ h->pps = h1->pps;
+
+ if ((err = h264_slice_header_init(h, 1)) < 0) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");
+ return err;
+ }
+ h->context_reinitialized = 1;
+
+ /* update linesize on resize for h264. The h264 decoder doesn't
+ * necessarily call ff_MPV_frame_start in the new thread */
+ s->linesize = s1->linesize;
+ s->uvlinesize = s1->uvlinesize;
+
+ /* copy block_offset since frame_start may not be called */
+ memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
+ h264_set_parameter_from_sps(h);
+ }
+
err = ff_mpeg_update_thread_context(dst, src);
if (err)
return err;
- // FIXME handle width/height changing
if (!inited) {
for (i = 0; i < MAX_SPS_COUNT; i++)
av_freep(h->sps_buffers + i);
}
context_init(h);
- /* frame_start may not be called for the next thread (if it's decoding
- * a bottom field) so this has to be allocated here */
- h->s.obmc_scratchpad = av_malloc(16 * 6 * s->linesize);
}
for (i = 0; i < 2; i++) {
h->rbsp_buffer[i] = NULL;
h->rbsp_buffer_size[i] = 0;
}
+ h->bipred_scratchpad = NULL;
h->thread_context[0] = h;
s->dsp.clear_blocks(h->mb + (24 * 16 << h->pixel_shift));
}
+ /* frame_start may not be called for the next thread (if it's decoding
+ * a bottom field) so this has to be allocated here */
+ if (!h->bipred_scratchpad && s->linesize)
+ h->bipred_scratchpad = av_malloc(16 * 6 * s->linesize);
+
// extradata/NAL handling
h->is_avc = h1->is_avc;
if (!s->current_picture_ptr)
return 0;
- if (!s->dropable) {
+ if (!s->droppable) {
err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
h->prev_poc_msb = h->poc_msb;
h->prev_poc_lsb = h->poc_lsb;
/* can't be in alloc_tables because linesize isn't known there.
* FIXME: redo bipred weight to not require extra buffer? */
for (i = 0; i < s->slice_context_count; i++)
- if (h->thread_context[i] && !h->thread_context[i]->s.obmc_scratchpad)
- h->thread_context[i]->s.obmc_scratchpad = av_malloc(16 * 6 * s->linesize);
+ if (h->thread_context[i] && !h->thread_context[i]->bipred_scratchpad)
+ h->thread_context[i]->bipred_scratchpad = av_malloc(16 * 6 * s->linesize);
/* Some macroblocks can be accessed before they're available in case
* of lost slices, MBAFF or threading. */
}
/* forget old pics after a seek */
-static void flush_dpb(AVCodecContext *avctx)
+static void flush_change(H264Context *h)
{
- H264Context *h = avctx->priv_data;
- int i;
- for (i=0; i<=MAX_DELAYED_PIC_COUNT; i++) {
- if (h->delayed_pic[i])
- h->delayed_pic[i]->f.reference = 0;
- h->delayed_pic[i] = NULL;
- }
h->outputed_poc = h->next_outputed_poc = INT_MIN;
h->prev_interlaced_frame = 1;
idr(h);
if (h->s.current_picture_ptr)
h->s.current_picture_ptr->f.reference = 0;
h->s.first_field = 0;
+ memset(h->ref_list[0], 0, sizeof(h->ref_list[0]));
+ memset(h->ref_list[1], 0, sizeof(h->ref_list[1]));
+ memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));
+ memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1]));
ff_h264_reset_sei(h);
- ff_mpeg_flush(avctx);
h->recovery_frame= -1;
h->sync= 0;
+ h->list_count = 0;
+ h->current_slice = 0;
+}
+
+/* forget old pics after a seek */
+static void flush_dpb(AVCodecContext *avctx)
+{
+ H264Context *h = avctx->priv_data;
+ int i;
+
+ for (i = 0; i <= MAX_DELAYED_PIC_COUNT; i++) {
+ if (h->delayed_pic[i])
+ h->delayed_pic[i]->f.reference = 0;
+ h->delayed_pic[i] = NULL;
+ }
+
+ flush_change(h);
+ ff_mpeg_flush(avctx);
}
static int init_poc(H264Context *h)
int err = 0;
s->mb_y = 0;
- if (!in_setup && !s->dropable)
+ if (!in_setup && !s->droppable)
ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
s->picture_structure == PICT_BOTTOM_FIELD);
ff_vdpau_h264_set_reference_frames(s);
if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {
- if (!s->dropable) {
+ if (!s->droppable) {
err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
h->prev_poc_msb = h->poc_msb;
h->prev_poc_lsb = h->poc_lsb;
/**
* Replicate H264 "master" context to thread contexts.
*/
-static void clone_slice(H264Context *dst, H264Context *src)
+static int clone_slice(H264Context *dst, H264Context *src)
{
+ int ret;
+
memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset));
dst->s.current_picture_ptr = src->s.current_picture_ptr;
dst->s.current_picture = src->s.current_picture;
dst->s.uvlinesize = src->s.uvlinesize;
dst->s.first_field = src->s.first_field;
+ if (!dst->s.edge_emu_buffer &&
+ (ret = ff_mpv_frame_size_alloc(&dst->s, dst->s.linesize))) {
+ av_log(dst->s.avctx, AV_LOG_ERROR,
+ "Failed to allocate scratch buffers\n");
+ return ret;
+ }
+
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;
memcpy(dst->dequant4_coeff, src->dequant4_coeff, sizeof(src->dequant4_coeff));
memcpy(dst->dequant8_coeff, src->dequant8_coeff, sizeof(src->dequant8_coeff));
+
+ return 0;
}
/**
return profile;
}
+static int h264_set_parameter_from_sps(H264Context *h)
+{
+ MpegEncContext *s = &h->s;
+
+ if (s->flags & CODEC_FLAG_LOW_DELAY ||
+ (h->sps.bitstream_restriction_flag &&
+ !h->sps.num_reorder_frames)) {
+ if (s->avctx->has_b_frames > 1 || h->delayed_pic[0])
+ av_log(h->s.avctx, AV_LOG_WARNING, "Delayed frames seen. "
+ "Reenabling low delay requires a codec flush.\n");
+ else
+ s->low_delay = 1;
+ }
+
+ if (s->avctx->has_b_frames < 2)
+ s->avctx->has_b_frames = !s->low_delay;
+
+ if (s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
+ h->cur_chroma_format_idc != h->sps.chroma_format_idc) {
+ if (s->avctx->codec &&
+ s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU &&
+ (h->sps.bit_depth_luma != 8 || h->sps.chroma_format_idc > 1)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "VDPAU decoding does not support video colorspace.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 14 &&
+ h->sps.bit_depth_luma != 11 && h->sps.bit_depth_luma != 13 &&
+ (h->sps.bit_depth_luma != 9 || !CHROMA422)) {
+ s->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
+ h->cur_chroma_format_idc = h->sps.chroma_format_idc;
+ h->pixel_shift = h->sps.bit_depth_luma > 8;
+
+ ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma,
+ h->sps.chroma_format_idc);
+ ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma,
+ h->sps.chroma_format_idc);
+ s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
+ ff_dsputil_init(&s->dsp, s->avctx);
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
+ h->sps.bit_depth_luma);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ return 0;
+}
+
+static enum PixelFormat get_pixel_format(H264Context *h)
+{
+ MpegEncContext *const s = &h->s;
+ switch (h->sps.bit_depth_luma) {
+ case 9:
+ if (CHROMA444) {
+ if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+ return AV_PIX_FMT_GBRP9;
+ } else
+ return AV_PIX_FMT_YUV444P9;
+ } else if (CHROMA422)
+ return AV_PIX_FMT_YUV422P9;
+ else
+ return AV_PIX_FMT_YUV420P9;
+ break;
+ case 10:
+ if (CHROMA444) {
+ if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+ return AV_PIX_FMT_GBRP10;
+ } else
+ return AV_PIX_FMT_YUV444P10;
+ } else if (CHROMA422)
+ return AV_PIX_FMT_YUV422P10;
+ else
+ return AV_PIX_FMT_YUV420P10;
+ break;
+ case 12:
+ if (CHROMA444) {
+ if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+ return AV_PIX_FMT_GBRP12;
+ } else
+ return AV_PIX_FMT_YUV444P12;
+ } else if (CHROMA422)
+ return AV_PIX_FMT_YUV422P12;
+ else
+ return AV_PIX_FMT_YUV420P12;
+ break;
+ case 14:
+ if (CHROMA444) {
+ if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+ return AV_PIX_FMT_GBRP14;
+ } else
+ return AV_PIX_FMT_YUV444P14;
+ } else if (CHROMA422)
+ return AV_PIX_FMT_YUV422P14;
+ else
+ return AV_PIX_FMT_YUV420P14;
+ break;
+ case 8:
+ if (CHROMA444) {
+ if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+ av_log(h->s.avctx, AV_LOG_DEBUG, "Detected GBR colorspace.\n");
+ return AV_PIX_FMT_GBR24P;
+ } else if (s->avctx->colorspace == AVCOL_SPC_YCGCO) {
+ av_log(h->s.avctx, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n");
+ }
+ return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
+ : AV_PIX_FMT_YUV444P;
+ } else if (CHROMA422) {
+ return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
+ : AV_PIX_FMT_YUV422P;
+ } else {
+ return s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts ?
+ s->avctx->codec->pix_fmts :
+ s->avctx->color_range == AVCOL_RANGE_JPEG ?
+ hwaccel_pixfmt_list_h264_jpeg_420 :
+ ff_hwaccel_pixfmt_list_420);
+ }
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
+ return AVERROR_INVALIDDATA;
+ }
+}
+
+static int h264_slice_header_init(H264Context *h, int reinit)
+{
+ MpegEncContext *const s = &h->s;
+ int i, ret;
+
+ if( FFALIGN(s->avctx->width , 16 ) == s->width
+ && FFALIGN(s->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == s->height
+ && !h->sps.crop_right && !h->sps.crop_bottom
+ && (s->avctx->width != s->width || s->avctx->height && s->height)
+ ) {
+ av_log(h->s.avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n");
+ s->avctx->coded_width = s->width;
+ s->avctx->coded_height = s->height;
+ } else{
+ avcodec_set_dimensions(s->avctx, s->width, s->height);
+ s->avctx->width -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
+ s->avctx->height -= (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
+ }
+
+ s->avctx->sample_aspect_ratio = h->sps.sar;
+ av_assert0(s->avctx->sample_aspect_ratio.den);
+
+ if (h->sps.timing_info_present_flag) {
+ int64_t den = h->sps.time_scale;
+ if (h->x264_build < 44U)
+ den *= 2;
+ av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
+ h->sps.num_units_in_tick, den, 1 << 30);
+ }
+
+ s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt);
+
+ if (reinit) {
+ free_tables(h, 0);
+ if ((ret = ff_MPV_common_frame_size_change(s)) < 0) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_frame_size_change() failed.\n");
+ return ret;
+ }
+ } else {
+ if ((ret = ff_MPV_common_init(s) < 0)) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_init() failed.\n");
+ return ret;
+ }
+ }
+ s->first_field = 0;
+ h->prev_interlaced_frame = 1;
+
+ init_scan_tables(h);
+ if (ff_h264_alloc_tables(h) < 0) {
+ av_log(h->s.avctx, AV_LOG_ERROR,
+ "Could not allocate memory for h264\n");
+ return AVERROR(ENOMEM);
+ }
+
+ if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_SLICE)) {
+ if (context_init(h) < 0) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
+ return -1;
+ }
+ } else {
+ for (i = 1; i < s->slice_context_count; i++) {
+ H264Context *c;
+ c = h->thread_context[i] = av_malloc(sizeof(H264Context));
+ memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext));
+ memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));
+ c->h264dsp = h->h264dsp;
+ c->sps = h->sps;
+ c->pps = h->pps;
+ c->pixel_shift = h->pixel_shift;
+ c->cur_chroma_format_idc = h->cur_chroma_format_idc;
+ init_scan_tables(c);
+ clone_tables(c, h, i);
+ }
+
+ for (i = 0; i < s->slice_context_count; i++)
+ if (context_init(h->thread_context[i]) < 0) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/**
* Decode a slice header.
* This will also call ff_MPV_common_init() and frame_start() as needed.
MpegEncContext *const s0 = &h0->s;
unsigned int first_mb_in_slice;
unsigned int pps_id;
- int num_ref_idx_active_override_flag;
+ int num_ref_idx_active_override_flag, ret;
unsigned int slice_type, tmp, i, j;
int default_ref_list_done = 0;
- int last_pic_structure, last_pic_dropable;
+ int last_pic_structure, last_pic_droppable;
int must_reinit;
+ int needs_reinit = 0;
+ enum AVPixelFormat pix_fmt;
/* FIXME: 2tap qpel isn't implemented for high bit depth. */
if ((s->avctx->flags2 & CODEC_FLAG2_FAST) &&
h0->current_slice = 0;
if (!s0->first_field) {
- if (s->current_picture_ptr && !s->dropable &&
+ if (s->current_picture_ptr && !s->droppable &&
s->current_picture_ptr->owner2 == s) {
ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
s->picture_structure == PICT_BOTTOM_FIELD);
h->pps.sps_id);
return -1;
}
- h->sps = *h0->sps_buffers[h->pps.sps_id];
+
+ if (h->pps.sps_id != h->current_sps_id ||
+ h->context_reinitialized ||
+ h0->sps_buffers[h->pps.sps_id]->new) {
+ h0->sps_buffers[h->pps.sps_id]->new = 0;
+
+ h->current_sps_id = h->pps.sps_id;
+ h->sps = *h0->sps_buffers[h->pps.sps_id];
+
+ if (s->mb_width != h->sps.mb_width ||
+ s->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) ||
+ s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
+ h->cur_chroma_format_idc != h->sps.chroma_format_idc
+ )
+ needs_reinit = 1;
+
+ if ((ret = h264_set_parameter_from_sps(h)) < 0)
+ return ret;
+ }
s->avctx->profile = ff_h264_get_profile(&h->sps);
s->avctx->level = h->sps.level_idc;
|| h->cur_chroma_format_idc != h->sps.chroma_format_idc
|| av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio)));
- if(must_reinit && (h != h0 || (s->avctx->active_thread_type & FF_THREAD_FRAME))) {
- av_log_missing_feature(s->avctx,
- "Width/height/bit depth/chroma idc changing with threads", 0);
- return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding
- }
s->mb_width = h->sps.mb_width;
s->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
s->width = 16 * s->mb_width;
s->height = 16 * s->mb_height;
- if(must_reinit) {
- free_tables(h, 0);
- flush_dpb(s->avctx);
- ff_MPV_common_end(s);
- h->list_count = 0;
- h->current_slice = 0;
- }
- if (!s->context_initialized) {
- if (h != h0) {
- av_log(h->s.avctx, AV_LOG_ERROR,
- "Cannot (re-)initialize context during parallel decoding.\n");
- return -1;
- }
- if( FFALIGN(s->avctx->width , 16 ) == s->width
- && FFALIGN(s->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == s->height
- && !h->sps.crop_right && !h->sps.crop_bottom
- && (s->avctx->width != s->width || s->avctx->height && s->height)
- ) {
- av_log(h->s.avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n");
- s->avctx->coded_width = s->width;
- s->avctx->coded_height = s->height;
- } else{
- avcodec_set_dimensions(s->avctx, s->width, s->height);
- s->avctx->width -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
- s->avctx->height -= (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
- }
- s->avctx->sample_aspect_ratio = h->sps.sar;
- av_assert0(s->avctx->sample_aspect_ratio.den);
-
- if (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU
- && (h->sps.bit_depth_luma != 8 ||
- h->sps.chroma_format_idc > 1)) {
- av_log(s->avctx, AV_LOG_ERROR,
- "VDPAU decoding does not support video "
- "colorspace\n");
- return -1;
+ if (h->sps.video_signal_type_present_flag) {
+ s->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG
+ : AVCOL_RANGE_MPEG;
+ if (h->sps.colour_description_present_flag) {
+ s->avctx->color_primaries = h->sps.color_primaries;
+ s->avctx->color_trc = h->sps.color_trc;
+ s->avctx->colorspace = h->sps.colorspace;
}
+ }
- if (s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
- h->cur_chroma_format_idc != h->sps.chroma_format_idc) {
- if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 14 && h->sps.bit_depth_luma != 11 && h->sps.bit_depth_luma != 13 &&
- (h->sps.bit_depth_luma != 9 || !CHROMA422)) {
- s->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
- h->cur_chroma_format_idc = h->sps.chroma_format_idc;
- h->pixel_shift = h->sps.bit_depth_luma > 8;
-
- ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma, h->sps.chroma_format_idc);
- ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma, h->sps.chroma_format_idc);
- s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
- ff_dsputil_init(&s->dsp, s->avctx);
- } else {
- av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d chroma_idc: %d\n",
- h->sps.bit_depth_luma, h->sps.chroma_format_idc);
- return -1;
- }
- }
- if (h->sps.video_signal_type_present_flag) {
- s->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG
- : AVCOL_RANGE_MPEG;
- if (h->sps.colour_description_present_flag) {
- s->avctx->color_primaries = h->sps.color_primaries;
- s->avctx->color_trc = h->sps.color_trc;
- s->avctx->colorspace = h->sps.colorspace;
- }
- }
+ ret = get_pixel_format(h);
+ if (ret < 0)
+ return ret;
+ else
+ pix_fmt = ret;
+ if (s->avctx->pix_fmt == PIX_FMT_NONE)
+ s->avctx->pix_fmt = pix_fmt;
- if (h->sps.timing_info_present_flag) {
- int64_t den = h->sps.time_scale;
- if (h->x264_build < 44U)
- den *= 2;
- av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
- h->sps.num_units_in_tick, den, 1 << 30);
- }
+ if (s->context_initialized &&
+ (
+ needs_reinit ||
+ must_reinit)) {
- switch (h->sps.bit_depth_luma) {
- case 9:
- if (CHROMA444) {
- if (s->avctx->colorspace == AVCOL_SPC_RGB) {
- s->avctx->pix_fmt = AV_PIX_FMT_GBRP9;
- } else
- s->avctx->pix_fmt = AV_PIX_FMT_YUV444P9;
- } else if (CHROMA422)
- s->avctx->pix_fmt = AV_PIX_FMT_YUV422P9;
- else
- s->avctx->pix_fmt = AV_PIX_FMT_YUV420P9;
- break;
- case 10:
- if (CHROMA444) {
- if (s->avctx->colorspace == AVCOL_SPC_RGB) {
- s->avctx->pix_fmt = AV_PIX_FMT_GBRP10;
- } else
- s->avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
- } else if (CHROMA422)
- s->avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
- else
- s->avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
- break;
- case 12:
- if (CHROMA444) {
- if (s->avctx->colorspace == AVCOL_SPC_RGB) {
- s->avctx->pix_fmt = AV_PIX_FMT_GBRP12;
- } else
- s->avctx->pix_fmt = AV_PIX_FMT_YUV444P12;
- } else if (CHROMA422)
- s->avctx->pix_fmt = AV_PIX_FMT_YUV422P12;
- else
- s->avctx->pix_fmt = AV_PIX_FMT_YUV420P12;
- break;
- case 14:
- if (CHROMA444) {
- if (s->avctx->colorspace == AVCOL_SPC_RGB) {
- s->avctx->pix_fmt = AV_PIX_FMT_GBRP14;
- } else
- s->avctx->pix_fmt = AV_PIX_FMT_YUV444P14;
- } else if (CHROMA422)
- s->avctx->pix_fmt = AV_PIX_FMT_YUV422P14;
- else
- s->avctx->pix_fmt = AV_PIX_FMT_YUV420P14;
- break;
- case 8:
- if (CHROMA444) {
- s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
- : AV_PIX_FMT_YUV444P;
- if (s->avctx->colorspace == AVCOL_SPC_RGB) {
- s->avctx->pix_fmt = AV_PIX_FMT_GBR24P;
- av_log(h->s.avctx, AV_LOG_DEBUG, "Detected GBR colorspace.\n");
- } else if (s->avctx->colorspace == AVCOL_SPC_YCGCO) {
- av_log(h->s.avctx, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n");
- }
- } else if (CHROMA422) {
- s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
- : AV_PIX_FMT_YUV422P;
- } else {
- s->avctx->pix_fmt = s->avctx->get_format(s->avctx,
- s->avctx->codec->pix_fmts ?
- s->avctx->codec->pix_fmts :
- s->avctx->color_range == AVCOL_RANGE_JPEG ?
- hwaccel_pixfmt_list_h264_jpeg_420 :
- ff_hwaccel_pixfmt_list_420);
- }
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR,
- "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
+ if (h != h0) {
+ av_log(s->avctx, AV_LOG_ERROR, "changing width/height on "
+ "slice %d\n", h0->current_slice + 1);
return AVERROR_INVALIDDATA;
}
- s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id,
- s->avctx->pix_fmt);
+ av_log(h->s.avctx, AV_LOG_INFO, "Reinit context to %dx%d, "
+ "pix_fmt: %d\n", s->width, s->height, pix_fmt);
- if (ff_MPV_common_init(s) < 0) {
- av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_init() failed.\n");
- return -1;
- }
- s->first_field = 0;
- h->prev_interlaced_frame = 1;
+ flush_change(h);
- init_scan_tables(h);
- if (ff_h264_alloc_tables(h) < 0) {
+ s->avctx->pix_fmt = pix_fmt;
+
+ if ((ret = h264_slice_header_init(h, 1)) < 0) {
av_log(h->s.avctx, AV_LOG_ERROR,
- "Could not allocate memory for h264\n");
- return AVERROR(ENOMEM);
+ "h264_slice_header_init() failed\n");
+ return ret;
}
-
- if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_SLICE)) {
- if (context_init(h) < 0) {
- av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
- return -1;
- }
- } else {
- for (i = 1; i < s->slice_context_count; i++) {
- H264Context *c;
- c = h->thread_context[i] = av_malloc(sizeof(H264Context));
- memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext));
- memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));
- c->h264dsp = h->h264dsp;
- c->sps = h->sps;
- c->pps = h->pps;
- c->pixel_shift = h->pixel_shift;
- c->cur_chroma_format_idc = h->cur_chroma_format_idc;
- init_scan_tables(c);
- clone_tables(c, h, i);
- }
-
- for (i = 0; i < s->slice_context_count; i++)
- if (context_init(h->thread_context[i]) < 0) {
- av_log(h->s.avctx, AV_LOG_ERROR,
- "context_init() failed.\n");
- return -1;
- }
+ h->context_reinitialized = 1;
+ }
+ if (!s->context_initialized) {
+ if (h != h0) {
+ av_log(h->s.avctx, AV_LOG_ERROR,
+ "Cannot (re-)initialize context during parallel decoding.\n");
+ return -1;
+ }
+ if ((ret = h264_slice_header_init(h, 0)) < 0) {
+ av_log(h->s.avctx, AV_LOG_ERROR,
+ "h264_slice_header_init() failed\n");
+ return ret;
}
}
h->mb_mbaff = 0;
h->mb_aff_frame = 0;
last_pic_structure = s0->picture_structure;
- last_pic_dropable = s->dropable;
- s->dropable = h->nal_ref_idc == 0;
+ last_pic_droppable = s0->droppable;
+ s->droppable = h->nal_ref_idc == 0;
if (h->sps.frame_mbs_only_flag) {
s->picture_structure = PICT_FRAME;
} else {
if (h0->current_slice != 0) {
if (last_pic_structure != s->picture_structure ||
- last_pic_dropable != s->dropable) {
+ last_pic_droppable != s->droppable) {
av_log(h->s.avctx, AV_LOG_ERROR,
"Changing field mode (%d -> %d) between slices is not allowed\n",
last_pic_structure, s->picture_structure);
s->picture_structure = last_pic_structure;
- s->dropable = last_pic_dropable;
+ s->droppable = last_pic_droppable;
return AVERROR_INVALIDDATA;
- } else if (!s->current_picture_ptr) {
+ } else if (!s0->current_picture_ptr) {
av_log(s->avctx, AV_LOG_ERROR,
"unset current_picture_ptr on %d. slice\n",
h0->current_slice + 1);
assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
/* Mark old field/frame as completed */
- if (!last_pic_dropable && s0->current_picture_ptr->owner2 == s0) {
+ if (!last_pic_droppable && s0->current_picture_ptr->owner2 == s0) {
ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
last_pic_structure == PICT_BOTTOM_FIELD);
}
if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
/* Previous field is unmatched. Don't display it, but let it
* remain for reference if marked as such. */
- if (!last_pic_dropable && last_pic_structure != PICT_FRAME) {
+ if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
last_pic_structure == PICT_TOP_FIELD);
}
* different frame_nums. Consider this field first in
* pair. Throw away previous field except for reference
* purposes. */
- if (!last_pic_dropable && last_pic_structure != PICT_FRAME) {
+ if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
last_pic_structure == PICT_TOP_FIELD);
}
"Invalid field mode combination %d/%d\n",
last_pic_structure, s->picture_structure);
s->picture_structure = last_pic_structure;
- s->dropable = last_pic_dropable;
+ s->droppable = last_pic_droppable;
return AVERROR_INVALIDDATA;
- } else if (last_pic_dropable != s->dropable) {
+ } else if (last_pic_droppable != s->droppable) {
av_log(s->avctx, AV_LOG_ERROR,
"Cannot combine reference and non-reference fields in the same frame\n");
av_log_ask_for_sample(s->avctx, NULL);
s->picture_structure = last_pic_structure;
- s->dropable = last_pic_dropable;
+ s->droppable = last_pic_droppable;
return AVERROR_INVALIDDATA;
}
}
}
- while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 &&
+ while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && !s0->first_field &&
h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {
Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
ff_release_unused_pictures(s, 0);
}
}
- if (h != h0)
- clone_slice(h, h0);
+ if (h != h0 && (ret = clone_slice(h, h0)) < 0)
+ return ret;
s->current_picture_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
ff_draw_horiz_band(s, top, height);
- if (s->dropable)
+ if (s->droppable)
return;
ff_thread_report_progress(&s->current_picture_ptr->f, top + height - 1,
hx = h->thread_context[context_count - 1];
s->mb_x = hx->s.mb_x;
s->mb_y = hx->s.mb_y;
- s->dropable = hx->s.dropable;
+ s->droppable = hx->s.droppable;
s->picture_structure = hx->s.picture_structure;
for (i = 1; i < context_count; i++)
h->s.error_count += h->thread_context[i]->s.error_count;
return 0;
}
-static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
+static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
+ int parse_extradata)
{
MpegEncContext *const s = &h->s;
AVCodecContext *const avctx = s->avctx;
int pass = !(avctx->active_thread_type & FF_THREAD_FRAME);
int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts
int nal_index;
+ int idr_cleared=0;
+ int first_slice = 0;
h->nal_unit_type= 0;
case NAL_PPS:
nals_needed = nal_index;
break;
+ case NAL_DPA:
case NAL_IDR_SLICE:
case NAL_SLICE:
init_get_bits(&hx->s.gb, ptr, bit_length);
- if (!get_ue_golomb(&hx->s.gb))
+ if (!get_ue_golomb(&hx->s.gb) || !first_slice)
nals_needed = nal_index;
+ if (!first_slice)
+ first_slice = hx->nal_unit_type;
}
continue;
}
+ if (!first_slice)
+ switch (hx->nal_unit_type) {
+ case NAL_DPA:
+ case NAL_IDR_SLICE:
+ case NAL_SLICE:
+ first_slice = hx->nal_unit_type;
+ }
+
// FIXME do not discard SEI id
if (avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)
continue;
again:
- err = 0;
-
- if (h->decoding_extradata) {
+ /* Ignore per frame NAL unit type during extradata
+ * parsing. Decoding slices is not possible in codec init
+ * with frame-mt */
+ if (parse_extradata) {
switch (hx->nal_unit_type) {
case NAL_IDR_SLICE:
case NAL_SLICE:
case NAL_DPB:
case NAL_DPC:
case NAL_AUXILIARY_SLICE:
- av_log(h->s.avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header\n", hx->nal_unit_type);
- hx->nal_unit_type = NAL_FILLER_DATA;
+ av_log(h->s.avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header/extradata\n", hx->nal_unit_type);
+ hx->nal_unit_type = NAL_FF_IGNORE;
}
}
+ err = 0;
+
switch (hx->nal_unit_type) {
case NAL_IDR_SLICE:
- if (h->nal_unit_type != NAL_IDR_SLICE) {
+ if (first_slice != NAL_IDR_SLICE) {
av_log(h->s.avctx, AV_LOG_ERROR,
"Invalid mix of idr and non-idr slices\n");
buf_index = -1;
goto end;
}
- idr(h); // FIXME ensure we don't lose some frames if there is reordering
+ if(!idr_cleared)
+ idr(h); // FIXME ensure we don't lose some frames if there is reordering
+ idr_cleared = 1;
case NAL_SLICE:
init_get_bits(&hx->s.gb, ptr, bit_length);
hx->intra_gb_ptr =
ff_h264_decode_seq_parameter_set(h);
}
- if (s->flags & CODEC_FLAG_LOW_DELAY ||
- (h->sps.bitstream_restriction_flag &&
- !h->sps.num_reorder_frames)) {
- if (s->avctx->has_b_frames > 1 || h->delayed_pic[0])
- av_log(avctx, AV_LOG_WARNING, "Delayed frames seen "
- "reenabling low delay requires a codec "
- "flush.\n");
- else
- s->low_delay = 1;
- }
-
- if (avctx->has_b_frames < 2)
- avctx->has_b_frames = !s->low_delay;
break;
case NAL_PPS:
init_get_bits(&s->gb, ptr, bit_length);
case NAL_SPS_EXT:
case NAL_AUXILIARY_SLICE:
break;
+ case NAL_FF_IGNORE:
+ break;
default:
av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n",
hx->nal_unit_type, bit_length);
end:
/* clean up */
if (s->current_picture_ptr && s->current_picture_ptr->owner2 == s &&
- !s->dropable) {
+ !s->droppable) {
ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
s->picture_structure == PICT_BOTTOM_FIELD);
}
}
not_extra:
- buf_index = decode_nal_units(h, buf, buf_size);
+ buf_index = decode_nal_units(h, buf, buf_size, 0);
if (buf_index < 0)
return -1;
decode_postinit(h, 1);
field_end(h, 0);
+ h->context_reinitialized = 0;
/* Wait for second field. */
*got_frame = 0;