Message ID | 1324044883-78833-2-git-send-email-martin@martin.st |
---|---|
State | Committed |
Commit | f13db94d0aadc4f27aea715383a18df461ed9b5d |
Headers | show |
On 12/16/2011 09:14 AM, Martin Storsjö wrote: > --- > libavcodec/utils.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 44 insertions(+), 0 deletions(-) > > diff --git a/libavcodec/utils.c b/libavcodec/utils.c > index 68fc525..bdff919 100644 > --- a/libavcodec/utils.c > +++ b/libavcodec/utils.c > @@ -40,6 +40,7 @@ > #include "thread.h" > #include "audioconvert.h" > #include "internal.h" > +#include "bytestream.h" > #include <stdlib.h> > #include <stdarg.h> > #include <limits.h> > @@ -924,6 +925,47 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa > } > #endif > > +static void 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; > + 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) { > + avctx->channels = bytestream_get_le32(&data); > + size -= 4; > + } > + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { > + if (size < 8) > + return; > + avctx->channel_layout = bytestream_get_le64(&data); > + size -= 8; > + } > + if (size < 4) > + return; > + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { > + avctx->sample_rate = bytestream_get_le32(&data); > + size -= 4; > + } > + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { > + if (size < 8) > + return; > + avctx->width = bytestream_get_le32(&data); > + avctx->height = bytestream_get_le32(&data); > + size -= 8; > + } > +} The fields are defined as unsigned in the side data, but they're being read to signed fields (except channel_layout). Maybe we should just define the side data as signed for those fields. -Justin
On Mon, 19 Dec 2011, Justin Ruggles wrote: > On 12/16/2011 09:14 AM, Martin Storsjö wrote: > >> --- >> libavcodec/utils.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ >> 1 files changed, 44 insertions(+), 0 deletions(-) >> >> diff --git a/libavcodec/utils.c b/libavcodec/utils.c >> index 68fc525..bdff919 100644 >> --- a/libavcodec/utils.c >> +++ b/libavcodec/utils.c >> @@ -40,6 +40,7 @@ >> #include "thread.h" >> #include "audioconvert.h" >> #include "internal.h" >> +#include "bytestream.h" >> #include <stdlib.h> >> #include <stdarg.h> >> #include <limits.h> >> @@ -924,6 +925,47 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa >> } >> #endif >> >> +static void 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; >> + 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) { >> + avctx->channels = bytestream_get_le32(&data); >> + size -= 4; >> + } >> + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { >> + if (size < 8) >> + return; >> + avctx->channel_layout = bytestream_get_le64(&data); >> + size -= 8; >> + } >> + if (size < 4) >> + return; >> + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { >> + avctx->sample_rate = bytestream_get_le32(&data); >> + size -= 4; >> + } >> + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { >> + if (size < 8) >> + return; >> + avctx->width = bytestream_get_le32(&data); >> + avctx->height = bytestream_get_le32(&data); >> + size -= 8; >> + } >> +} > > > The fields are defined as unsigned in the side data, but they're being > read to signed fields (except channel_layout). Maybe we should just > define the side data as signed for those fields. Changed the definition in patch #4 locally, and the parameters in the utility function in patch #5. Any more opinions on this patchset, Luca? // Martin
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 68fc525..bdff919 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -40,6 +40,7 @@ #include "thread.h" #include "audioconvert.h" #include "internal.h" +#include "bytestream.h" #include <stdlib.h> #include <stdarg.h> #include <limits.h> @@ -924,6 +925,47 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa } #endif +static void 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; + 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) { + avctx->channels = bytestream_get_le32(&data); + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { + if (size < 8) + return; + avctx->channel_layout = bytestream_get_le64(&data); + size -= 8; + } + if (size < 4) + return; + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + avctx->sample_rate = bytestream_get_le32(&data); + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { + if (size < 8) + return; + avctx->width = bytestream_get_le32(&data); + avctx->height = bytestream_get_le32(&data); + size -= 8; + } +} + int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, @@ -940,6 +982,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, return AVERROR(EINVAL); } + apply_param_change(avctx, avpkt); + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt); if (ret >= 0 && *got_frame_ptr) {