lavc: add error checking to apply_param_change.

This commit is contained in:
Anton Khirnov 2013-10-27 09:56:00 +01:00
parent 5c0a09839c
commit b9589f5a77

View File

@ -1321,46 +1321,59 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
return ret;
}
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;
}
int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
@ -1375,7 +1388,12 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
return -1;
avctx->pkt = avpkt;
apply_param_change(avctx, avpkt);
ret = apply_param_change(avctx, avpkt);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");
if (avctx->err_recognition & AV_EF_EXPLODE)
return ret;
}
avcodec_get_frame_defaults(picture);
@ -1441,7 +1459,12 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
return AVERROR(EINVAL);
}
apply_param_change(avctx, avpkt);
ret = apply_param_change(avctx, avpkt);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");
if (avctx->err_recognition & AV_EF_EXPLODE)
return ret;
}
avcodec_get_frame_defaults(frame);