Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-10-30 13:13:23 +0400
committerMichael Niedermayer <michaelni@gmx.at>2013-10-30 13:23:24 +0400
commit558784f113f1436a48f34db2612c3b6460e6c734 (patch)
tree2b0ed3468b3a15e232f71697a46bb758161b6f85
parent4427fe7e4bf652856e4ee4101fae3c361fc8637f (diff)
parentb9589f5a770ec2357ab7920a5fabe8510b8601f9 (diff)
Merge commit 'b9589f5a770ec2357ab7920a5fabe8510b8601f9'
* commit 'b9589f5a770ec2357ab7920a5fabe8510b8601f9': lavc: add error checking to apply_param_change. Conflicts: libavcodec/utils.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/utils.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 186993dc02..7ea0084dc8 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -1954,46 +1954,59 @@ static int64_t guess_correct_pts(AVCodecContext *ctx,
return pts;
}
-static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt)
+static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt)
{
int size = 0;
const uint8_t *data;
uint32_t flags;
- if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE))
- return;
-
data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size);
- if (!data || size < 4)
- return;
+ if (!data)
+ return 0;
+
+ if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) {
+ av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter "
+ "changes, but PARAM_CHANGE side data was sent to it.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (size < 4)
+ goto fail;
+
flags = bytestream_get_le32(&data);
size -= 4;
- if (size < 4) /* Required for any of the changes */
- return;
+
if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) {
+ if (size < 4)
+ goto fail;
avctx->channels = bytestream_get_le32(&data);
size -= 4;
}
if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) {
if (size < 8)
- return;
+ goto fail;
avctx->channel_layout = bytestream_get_le64(&data);
size -= 8;
}
- if (size < 4)
- return;
if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) {
+ if (size < 4)
+ goto fail;
avctx->sample_rate = bytestream_get_le32(&data);
size -= 4;
}
if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) {
if (size < 8)
- return;
+ goto fail;
avctx->width = bytestream_get_le32(&data);
avctx->height = bytestream_get_le32(&data);
avcodec_set_dimensions(avctx, avctx->width, avctx->height);
size -= 8;
}
+
+ return 0;
+fail:
+ av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n");
+ return AVERROR_INVALIDDATA;
}
static int add_metadata_from_side_data(AVCodecContext *avctx, AVFrame *frame)
@@ -2053,7 +2066,13 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
int did_split = av_packet_split_side_data(&tmp);
- apply_param_change(avctx, &tmp);
+ ret = apply_param_change(avctx, &tmp);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ goto fail;
+ }
+
avctx->pkt = &tmp;
if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr,
@@ -2077,6 +2096,7 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
}
add_metadata_from_side_data(avctx, picture);
+fail:
emms_c(); //needed to avoid an emms_c() call before every return;
avctx->pkt = NULL;
@@ -2195,7 +2215,12 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
// copy to ensure we do not change avpkt
AVPacket tmp = *avpkt;
int did_split = av_packet_split_side_data(&tmp);
- apply_param_change(avctx, &tmp);
+ ret = apply_param_change(avctx, &tmp);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ goto fail;
+ }
avctx->pkt = &tmp;
if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
@@ -2275,7 +2300,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
frame->nb_samples -= discard_padding;
}
}
-
+fail:
avctx->pkt = NULL;
if (did_split) {
av_packet_free_side_data(&tmp);