diff --git a/libavformat/internal.h b/libavformat/internal.h index 45736687d3..559e710014 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -299,4 +299,12 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den); +/** + * Add side data to a packet for changing parameters to the given values. + * Parameters set to 0 aren't included in the change. + */ +int ff_add_param_change(AVPacket *pkt, int32_t channels, + uint64_t channel_layout, int32_t sample_rate, + int32_t width, int32_t height); + #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/utils.c b/libavformat/utils.c index bc5b7e02da..aa2c276b90 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -25,6 +25,7 @@ #include "avio_internal.h" #include "internal.h" #include "libavcodec/internal.h" +#include "libavcodec/bytestream.h" #include "libavutil/opt.h" #include "libavutil/dict.h" #include "libavutil/pixdesc.h" @@ -4017,3 +4018,45 @@ int avformat_network_deinit(void) #endif return 0; } + +int ff_add_param_change(AVPacket *pkt, int32_t channels, + uint64_t channel_layout, int32_t sample_rate, + int32_t width, int32_t height) +{ + uint32_t flags = 0; + int size = 4; + uint8_t *data; + if (!pkt) + return AVERROR(EINVAL); + if (channels) { + size += 4; + flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT; + } + if (channel_layout) { + size += 8; + flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT; + } + if (sample_rate) { + size += 4; + flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE; + } + if (width || height) { + size += 8; + flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS; + } + data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size); + if (!data) + return AVERROR(ENOMEM); + bytestream_put_le32(&data, flags); + if (channels) + bytestream_put_le32(&data, channels); + if (channel_layout) + bytestream_put_le64(&data, channel_layout); + if (sample_rate) + bytestream_put_le32(&data, sample_rate); + if (width || height) { + bytestream_put_le32(&data, width); + bytestream_put_le32(&data, height); + } + return 0; +}