Skip to content

Commit

Permalink
lavc: add codec parameters API
Browse files Browse the repository at this point in the history
This API is intended to allow passing around codec parameters without
using full AVCodecContext (which also contains codec options and
encoder/decoder state).
  • Loading branch information
elenril committed Feb 23, 2016
1 parent 257b30a commit 998e1b8
Show file tree
Hide file tree
Showing 4 changed files with 319 additions and 1 deletion.
3 changes: 3 additions & 0 deletions doc/APIchanges
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
163 changes: 163 additions & 0 deletions libavcodec/avcodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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().
Expand Down
152 changes: 152 additions & 0 deletions libavcodec/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion libavcodec/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand Down

0 comments on commit 998e1b8

Please sign in to comment.