diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-06-03 02:45:10 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-06-03 02:45:10 +0200 |
commit | 952738d0af74041c9ad8ac17f6d848a6d69fb3f1 (patch) | |
tree | 724022064017b561853e030dee3d3cf1f5aaea86 | |
parent | d499685d8020b919f0953fd358f2e8dc9a206783 (diff) | |
parent | 6f4404b24bcf59ab29cd4b57995d374a578f51a7 (diff) | |
download | ffmpeg-952738d0af74041c9ad8ac17f6d848a6d69fb3f1.tar.gz |
Merge commit '6f4404b24bcf59ab29cd4b57995d374a578f51a7' into release/0.10
* commit '6f4404b24bcf59ab29cd4b57995d374a578f51a7':
h264: set parameters from SPS whenever it changes
alac: Limit max_samples_per_frame
Conflicts:
libavcodec/h264.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/alac.c | 6 | ||||
-rw-r--r-- | libavcodec/h264.c | 76 | ||||
-rw-r--r-- | libavcodec/h264.h | 2 | ||||
-rw-r--r-- | libavcodec/h264_ps.c | 7 |
4 files changed, 74 insertions, 17 deletions
diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 0e6c549dd5..f87313d202 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -615,6 +615,12 @@ static int alac_set_info(ALACContext *alac) /* buffer size / 2 ? */ alac->setinfo_max_samples_per_frame = bytestream_get_be32(&ptr); + if (!alac->setinfo_max_samples_per_frame || + alac->setinfo_max_samples_per_frame > INT_MAX / sizeof(int32_t)) { + av_log(alac->avctx, AV_LOG_ERROR, "max samples per frame invalid: %u\n", + alac->setinfo_max_samples_per_frame); + return AVERROR_INVALIDDATA; + } ptr++; /* compatible version */ alac->setinfo_sample_size = *ptr++; alac->setinfo_rice_historymult = *ptr++; diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 1ec3f77e8f..981adb48a4 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2607,6 +2607,52 @@ int ff_h264_get_profile(SPS *sps) 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 <= 10) { + 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; + 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; +} + /** * Decode a slice header. * This will also call MPV_common_init() and frame_start() as needed. @@ -2624,7 +2670,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ int num_ref_idx_active_override_flag; 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_dropable, ret; /* FIXME: 2tap qpel isn't implemented for high bit depth. */ if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc && !h->pixel_shift){ @@ -2696,7 +2742,17 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h->pps.sps_id); return -1; } - h->sps = *h0->sps_buffers[h->pps.sps_id]; + + if (h->pps.sps_id != h->current_sps_id || + 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 ((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; @@ -4103,20 +4159,10 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ 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 (h264_set_parameter_from_sps(h) < 0) { + buf_index = -1; + goto end; } - - 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); diff --git a/libavcodec/h264.h b/libavcodec/h264.h index d0dfca3442..0a645f4e45 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -206,6 +206,7 @@ typedef struct SPS{ int bit_depth_chroma; ///< bit_depth_chroma_minus8 + 8 int residual_color_transform_flag; ///< residual_colour_transform_flag int constraint_set_flags; ///< constraint_set[0-3]_flag + int new; ///< flag to keep track if the decoder context needs re-init due to changed SPS }SPS; /** @@ -332,6 +333,7 @@ typedef struct H264Context{ int emu_edge_width; int emu_edge_height; + unsigned current_sps_id; ///< id of the current SPS SPS sps; ///< current sps /** diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index d8229e3c55..4d4ff22bc1 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -494,10 +494,13 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->bit_depth_luma ); } + sps->new = 1; av_free(h->sps_buffers[sps_id]); - h->sps_buffers[sps_id]= sps; - h->sps = *sps; + h->sps_buffers[sps_id] = sps; + h->sps = *sps; + h->current_sps_id = sps_id; + return 0; fail: av_free(sps); |