From 998e1b8f521b73e1ed3a13caaabcf79eb401cf0d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 18 Jun 2014 20:42:13 +0200 Subject: lavc: add codec parameters API This API is intended to allow passing around codec parameters without using full AVCodecContext (which also contains codec options and encoder/decoder state). --- doc/APIchanges | 3 + libavcodec/avcodec.h | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/utils.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/version.h | 2 +- 4 files changed, 319 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index b84fa4e4f5..9e11ccc570 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - lavc 57.14.0 - avcodec.h + xxxxxxx - Add AVCodecParameters and its related API. + 2016-xx-xx - xxxxxxx - lavf 57.4.0 - avformat.h Add AVFormatContext.protocol_whitelist and protocol_blacklist. Add 'protocol_whitelist' and 'protocol_blacklist' private options for diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 3deefb04df..4d6b2d0cb2 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3335,6 +3335,127 @@ typedef struct AVSubtitle { int64_t pts; ///< Same as packet pts, in AV_TIME_BASE } AVSubtitle; +/** + * This struct describes the properties of an encoded stream. + * + * sizeof(AVCodecParameters) is not a part of the public ABI, this struct must + * be allocated with avcodec_parameters_alloc() and freed with + * avcodec_parameters_free(). + */ +typedef struct AVCodecParameters { + /** + * General type of the encoded data. + */ + enum AVMediaType codec_type; + /** + * Specific type of the encoded data (the codec used). + */ + enum AVCodecID codec_id; + /** + * Additional information about the codec (corresponds to the AVI FOURCC). + */ + uint32_t codec_tag; + + /** + * Extra binary data needed for initializing the decoder, codec-dependent. + * + * Must be allocated with av_malloc() and will be freed by + * avcodec_parameters_free(). The allocated size of extradata must be at + * least extradata_size + AV_INPUT_BUFFER_PADDING_SIZE, with the padding + * bytes zeroed. + */ + uint8_t *extradata; + /** + * Size of the extradata content in bytes. + */ + int extradata_size; + + /** + * - video: the pixel format, the value corresponds to enum AVPixelFormat. + * - audio: the sample format, the value corresponds to enum AVSampleFormat. + */ + int format; + + /** + * The average bitrate of the encoded data (in bits per second). + */ + int bit_rate; + + int bits_per_coded_sample; + + /** + * Codec-specific bitstream restrictions that the stream conforms to. + */ + int profile; + int level; + + /** + * Video only. The dimensions of the video frame in pixels. + */ + int width; + int height; + + /** + * Video only. The aspect ratio (width / height) which a single pixel + * should have when displayed. + * + * When the aspect ratio is unknown / undefined, the numerator should be + * set to 0 (the denominator may have any value). + */ + AVRational sample_aspect_ratio; + + /** + * Video only. The order of the fields in interlaced video. + */ + enum AVFieldOrder field_order; + + /** + * Video only. Additional colorspace characteristics. + */ + enum AVColorRange color_range; + enum AVColorPrimaries color_primaries; + enum AVColorTransferCharacteristic color_trc; + enum AVColorSpace color_space; + enum AVChromaLocation chroma_location; + + /** + * Audio only. The channel layout bitmask. May be 0 if the channel layout is + * unknown or unspecified, otherwise the number of bits set must be equal to + * the channels field. + */ + uint64_t channel_layout; + /** + * Audio only. The number of audio channels. + */ + int channels; + /** + * Audio only. The number of audio samples per second. + */ + int sample_rate; + /** + * Audio only. The number of bytes per coded audio frame, required by some + * formats. + * + * Corresponds to nBlockAlign in WAVEFORMATEX. + */ + int block_align; + + /** + * Audio only. The amount of padding (in samples) inserted by the encoder at + * the beginning of the audio. I.e. this number of leading decoded samples + * must be discarded by the caller to get the original audio without leading + * padding. + */ + int initial_padding; + /** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + */ + int trailing_padding; +} AVCodecParameters; + /** * If c is NULL, returns the first registered codec, * if c is non-NULL, returns the next registered codec after c, @@ -3433,6 +3554,48 @@ const AVClass *avcodec_get_class(void); */ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); +/** + * Allocate a new AVCodecParameters and set its fields to default values + * (unknown/invalid/0). The returned struct must be freed with + * avcodec_parameters_free(). + */ +AVCodecParameters *avcodec_parameters_alloc(void); + +/** + * Free an AVCodecParameters instance and everything associated with it and + * write NULL to the supplied pointer. + */ +void avcodec_parameters_free(AVCodecParameters **par); + +/** + * Copy the contents of src to dst. Any allocated fields in dst are freed and + * replaced with newly allocated duplicates of the corresponding fields in src. + * + * @return >= 0 on success, a negative AVERROR code on failure. + */ +int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src); + +/** + * Fill the parameters struct based on the values from the supplied codec + * context. Any allocated fields in par are freed and replaced with duplicates + * of the corresponding fields in codec. + * + * @return >= 0 on success, a negative AVERROR code on failure + */ +int avcodec_parameters_from_context(AVCodecParameters *par, + const AVCodecContext *codec); + +/** + * Fill the codec context based on the values from the supplied codec + * parameters. Any allocated fields in codec that have a corresponding field in + * par are freed and replaced with duplicates of the corresponding field in par. + * Fields in codec that do not have a counterpart in par are not touched. + * + * @return >= 0 on success, a negative AVERROR code on failure. + */ +int avcodec_parameters_to_context(AVCodecContext *codec, + const AVCodecParameters *par); + /** * Initialize the AVCodecContext to use the given AVCodec. Prior to using this * function the context has to be allocated with avcodec_alloc_context3(). diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 94ec1e8047..86a67e1672 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -2440,3 +2440,155 @@ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx) return props; } + +static void codec_parameters_reset(AVCodecParameters *par) +{ + av_freep(&par->extradata); + + memset(par, 0, sizeof(*par)); + + par->codec_type = AVMEDIA_TYPE_UNKNOWN; + par->codec_id = AV_CODEC_ID_NONE; + par->format = -1; + par->field_order = AV_FIELD_UNKNOWN; + par->color_range = AVCOL_RANGE_UNSPECIFIED; + par->color_primaries = AVCOL_PRI_UNSPECIFIED; + par->color_trc = AVCOL_TRC_UNSPECIFIED; + par->color_space = AVCOL_SPC_UNSPECIFIED; + par->chroma_location = AVCHROMA_LOC_UNSPECIFIED; + par->sample_aspect_ratio = (AVRational){ 0, 1 }; +} + +AVCodecParameters *avcodec_parameters_alloc(void) +{ + AVCodecParameters *par = av_mallocz(sizeof(*par)); + + if (!par) + return NULL; + codec_parameters_reset(par); + return par; +} + +void avcodec_parameters_free(AVCodecParameters **ppar) +{ + AVCodecParameters *par = *ppar; + + if (!par) + return; + codec_parameters_reset(par); + + av_freep(ppar); +} + +int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src) +{ + codec_parameters_reset(dst); + memcpy(dst, src, sizeof(*dst)); + + dst->extradata = NULL; + dst->extradata_size = 0; + if (src->extradata) { + dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!dst->extradata) + return AVERROR(ENOMEM); + memcpy(dst->extradata, src->extradata, src->extradata_size); + dst->extradata_size = src->extradata_size; + } + + return 0; +} + +int avcodec_parameters_from_context(AVCodecParameters *par, + const AVCodecContext *codec) +{ + codec_parameters_reset(par); + + par->codec_type = codec->codec_type; + par->codec_id = codec->codec_id; + par->codec_tag = codec->codec_tag; + + par->bit_rate = codec->bit_rate; + par->bits_per_coded_sample = codec->bits_per_coded_sample; + par->profile = codec->profile; + par->level = codec->level; + + switch (par->codec_type) { + case AVMEDIA_TYPE_VIDEO: + par->format = codec->pix_fmt; + par->width = codec->width; + par->height = codec->height; + par->field_order = codec->field_order; + par->color_range = codec->color_range; + par->color_primaries = codec->color_primaries; + par->color_trc = codec->color_trc; + par->color_space = codec->colorspace; + par->chroma_location = codec->chroma_sample_location; + par->sample_aspect_ratio = codec->sample_aspect_ratio; + break; + case AVMEDIA_TYPE_AUDIO: + par->format = codec->sample_fmt; + par->channel_layout = codec->channel_layout; + par->channels = codec->channels; + par->sample_rate = codec->sample_rate; + par->block_align = codec->block_align; + par->initial_padding = codec->initial_padding; + break; + } + + if (codec->extradata) { + par->extradata = av_mallocz(codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!par->extradata) + return AVERROR(ENOMEM); + memcpy(par->extradata, codec->extradata, codec->extradata_size); + par->extradata_size = codec->extradata_size; + } + + return 0; +} + +int avcodec_parameters_to_context(AVCodecContext *codec, + const AVCodecParameters *par) +{ + codec->codec_type = par->codec_type; + codec->codec_id = par->codec_id; + codec->codec_tag = par->codec_tag; + + codec->bit_rate = par->bit_rate; + codec->bits_per_coded_sample = par->bits_per_coded_sample; + codec->profile = par->profile; + codec->level = par->level; + + switch (par->codec_type) { + case AVMEDIA_TYPE_VIDEO: + codec->pix_fmt = par->format; + codec->width = par->width; + codec->height = par->height; + codec->field_order = par->field_order; + codec->color_range = par->color_range; + codec->color_primaries = par->color_primaries; + codec->color_trc = par->color_trc; + codec->colorspace = par->color_space; + codec->chroma_sample_location = par->chroma_location; + codec->sample_aspect_ratio = par->sample_aspect_ratio; + break; + case AVMEDIA_TYPE_AUDIO: + codec->sample_fmt = par->format; + codec->channel_layout = par->channel_layout; + codec->channels = par->channels; + codec->sample_rate = par->sample_rate; + codec->block_align = par->block_align; + codec->initial_padding = par->initial_padding; + break; + } + + if (par->extradata) { + av_freep(&codec->extradata); + codec->extradata = av_mallocz(par->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!codec->extradata) + return AVERROR(ENOMEM); + memcpy(codec->extradata, par->extradata, par->extradata_size); + codec->extradata_size = par->extradata_size; + } + + return 0; +} diff --git a/libavcodec/version.h b/libavcodec/version.h index 2cdad5af15..d247c098ce 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 13 +#define LIBAVCODEC_VERSION_MINOR 14 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ -- cgit v1.2.3