aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-06-03 02:45:10 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-06-03 02:45:10 +0200
commit952738d0af74041c9ad8ac17f6d848a6d69fb3f1 (patch)
tree724022064017b561853e030dee3d3cf1f5aaea86
parentd499685d8020b919f0953fd358f2e8dc9a206783 (diff)
parent6f4404b24bcf59ab29cd4b57995d374a578f51a7 (diff)
downloadffmpeg-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.c6
-rw-r--r--libavcodec/h264.c76
-rw-r--r--libavcodec/h264.h2
-rw-r--r--libavcodec/h264_ps.c7
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);