本文主要是介绍FFmpeg之AVCodec,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
这一节是最重要的一节,ffmpeg的解码,还是和以前一样,一定是先来一个上下文context,再一个具体的解码器类。
AVCodecContext和
下面是一个解码器定义,三部分组成,第一部分是设置参数,第二部分是基类,第三部分是具体实现。
如果你要实现自己的一个解码器,实现第三部分的那几个回调函数就可以了。
#define OFFSET(x) offsetof(H264Context, x)
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
#define VDX VD | AV_OPT_FLAG_EXPORT
static const AVOption h264_options[] = {{ "is_avc", "is avc", OFFSET(is_avc), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VDX },{ "nal_length_size", "nal_length_size", OFFSET(nal_length_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, VDX },{ "enable_er", "Enable error resilience on damaged frames (unsafe)", OFFSET(enable_er), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD },{ "x264_build", "Assume this x264 version if no x264 version found in any SEI", OFFSET(x264_build), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VD },{ NULL },
};static const AVClass h264_class = {.class_name = "H264 Decoder",.item_name = av_default_item_name,.option = h264_options,.version = LIBAVUTIL_VERSION_INT,
};const AVCodec ff_h264_decoder = {.name = "h264",.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),.type = AVMEDIA_TYPE_VIDEO,.id = AV_CODEC_ID_H264,.priv_data_size = sizeof(H264Context),.init = h264_decode_init,.close = h264_decode_end,.decode = h264_decode_frame,.capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |AV_CODEC_CAP_FRAME_THREADS,}
结构体定义
/*** main external API structure.* New fields can be added to the end with minor version bumps.* Removal, reordering and changes to existing fields require a major* version bump.* You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user* applications.* The name string for AVOptions options matches the associated command line* parameter name and can be found in libavcodec/options_table.h* The AVOption/command line parameter names differ in some cases from the C* structure field names for historic reasons or brevity.* sizeof(AVCodecContext) must not be used outside libav*.*/
typedef struct AVCodecContext {/*** information on struct for av_log* - set by avcodec_alloc_context3*/const AVClass *av_class;int log_level_offset;enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */const struct AVCodec *codec;enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx *//*** fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').* This is used to work around some encoder bugs.* A demuxer should set this to what is stored in the field used to identify the codec.* If there are multiple such fields in a container then the demuxer should choose the one* which maximizes the information about the used codec.* If the codec tag field in a container is larger than 32 bits then the demuxer should* remap the longer ID to 32 bits with a table or other structure. Alternatively a new* extra_codec_tag + size could be added but for this a clear advantage must be demonstrated* first.* - encoding: Set by user, if not then the default based on codec_id will be used.* - decoding: Set by user, will be converted to uppercase by libavcodec during init.*/unsigned int codec_tag;void *priv_data;/*** Private context used for internal data.** Unlike priv_data, this is not codec-specific. It is used in general* libavcodec functions.*/struct AVCodecInternal *internal;/*** Private data of the user, can be used to carry app specific stuff.* - encoding: Set by user.* - decoding: Set by user.*/void *opaque;/*** the average bitrate* - encoding: Set by user; unused for constant quantizer encoding.* - decoding: Set by user, may be overwritten by libavcodec* if this info is available in the stream*/int64_t bit_rate;/*** number of bits the bitstream is allowed to diverge from the reference.* the reference can be CBR (for CBR pass1) or VBR (for pass2)* - encoding: Set by user; unused for constant quantizer encoding.* - decoding: unused*/int bit_rate_tolerance;/*** Global quality for codecs which cannot change it per frame.* This should be proportional to MPEG-1/2/4 qscale.* - encoding: Set by user.* - decoding: unused*/int global_quality;/*** - encoding: Set by user.* - decoding: unused*/int compression_level;
#define FF_COMPRESSION_DEFAULT -1/*** AV_CODEC_FLAG_*.* - encoding: Set by user.* - decoding: Set by user.*/int flags;/*** AV_CODEC_FLAG2_** - encoding: Set by user.* - decoding: Set by user.*/int flags2;/*** some codecs need / can use extradata like Huffman tables.* MJPEG: Huffman tables* rv10: additional flags* MPEG-4: global headers (they can be in the bitstream or here)* The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger* than extradata_size to avoid problems if it is read with the bitstream reader.* The bytewise contents of extradata must not depend on the architecture or CPU endianness.* Must be allocated with the av_malloc() family of functions.* - encoding: Set/allocated/freed by libavcodec.* - decoding: Set/allocated/freed by user.*/uint8_t *extradata;int extradata_size;/*** This is the fundamental unit of time (in seconds) in terms* of which frame timestamps are represented. For fixed-fps content,* timebase should be 1/framerate and timestamp increments should be* identically 1.* This often, but not always is the inverse of the frame rate or field rate* for video. 1/time_base is not the average frame rate if the frame rate is not* constant.** Like containers, elementary streams also can store timestamps, 1/time_base* is the unit in which these timestamps are specified.* As example of such codec time base see ISO/IEC 14496-2:2001(E)* vop_time_increment_resolution and fixed_vop_rate* (fixed_vop_rate == 0 implies that it is different from the framerate)** - encoding: MUST be set by user.* - decoding: the use of this field for decoding is deprecated.* Use framerate instead.*/AVRational time_base;/*** For some codecs, the time base is closer to the field rate than the frame rate.* Most notably, H.264 and MPEG-2 specify time_base as half of frame duration* if no telecine is used ...** Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.*/int ticks_per_frame;/*** Codec delay.** Encoding: Number of frames delay there will be from the encoder input to* the decoder output. (we assume the decoder matches the spec)* Decoding: Number of frames delay in addition to what a standard decoder* as specified in the spec would produce.** Video:* Number of frames the decoded output will be delayed relative to the* encoded input.** Audio:* For encoding, this field is unused (see initial_padding).** For decoding, this is the number of samples the decoder needs to* output before the decoder's output is valid. When seeking, you should* start decoding this many samples prior to your desired seek point.** - encoding: Set by libavcodec.* - decoding: Set by libavcodec.*/int delay;/* video only *//*** picture width / height.** @note Those fields may not match the values of the last* AVFrame output by avcodec_receive_frame() due frame* reordering.** - encoding: MUST be set by user.* - decoding: May be set by the user before opening the decoder if known e.g.* from the container. Some decoders will require the dimensions* to be set by the caller. During decoding, the decoder may* overwrite those values as required while parsing the data.*/int width, height;/*** Bitstream width / height, may be different from width/height e.g. when* the decoded frame is cropped before being output or lowres is enabled.** @note Those field may not match the value of the last* AVFrame output by avcodec_receive_frame() due frame* reordering.** - encoding: unused* - decoding: May be set by the user before opening the decoder if known* e.g. from the container. During decoding, the decoder may* overwrite those values as required while parsing the data.*/int coded_width, coded_height;/*** the number of pictures in a group of pictures, or 0 for intra_only* - encoding: Set by user.* - decoding: unused*/int gop_size;/*** Pixel format, see AV_PIX_FMT_xxx.* May be set by the demuxer if known from headers.* May be overridden by the decoder if it knows better.** @note This field may not match the value of the last* AVFrame output by avcodec_receive_frame() due frame* reordering.** - encoding: Set by user.* - decoding: Set by user if known, overridden by libavcodec while* parsing the data.*/enum AVPixelFormat pix_fmt;/*** If non NULL, 'draw_horiz_band' is called by the libavcodec* decoder to draw a horizontal band. It improves cache usage. Not* all codecs can do that. You must check the codec capabilities* beforehand.* When multithreading is used, it may be called from multiple threads* at the same time; threads might draw different parts of the same AVFrame,* or multiple AVFrames, and there is no guarantee that slices will be drawn* in order.* The function is also used by hardware acceleration APIs.* It is called at least once during frame decoding to pass* the data needed for hardware render.* In that mode instead of pixel data, AVFrame points to* a structure specific to the acceleration API. The application* reads the structure and can change some fields to indicate progress* or mark state.* - encoding: unused* - decoding: Set by user.* @param height the height of the slice* @param y the y position of the slice* @param type 1->top field, 2->bottom field, 3->frame* @param offset offset into the AVFrame.data from which the slice should be read*/void (*draw_horiz_band)(struct AVCodecContext *s,const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],int y, int type, int height);/*** Callback to negotiate the pixel format. Decoding only, may be set by the* caller before avcodec_open2().** Called by some decoders to select the pixel format that will be used for* the output frames. This is mainly used to set up hardware acceleration,* then the provided format list contains the corresponding hwaccel pixel* formats alongside the "software" one. The software pixel format may also* be retrieved from \ref sw_pix_fmt.** This callback will be called when the coded frame properties (such as* resolution, pixel format, etc.) change and more than one output format is* supported for those new properties. If a hardware pixel format is chosen* and initialization for it fails, the callback may be called again* immediately.** This callback may be called from different threads if the decoder is* multi-threaded, but not from more than one thread simultaneously.** @param fmt list of formats which may be used in the current* configuration, terminated by AV_PIX_FMT_NONE.* @warning Behavior is undefined if the callback returns a value other* than one of the formats in fmt or AV_PIX_FMT_NONE.* @return the chosen format or AV_PIX_FMT_NONE*/enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);/*** maximum number of B-frames between non-B-frames* Note: The output will be delayed by max_b_frames+1 relative to the input.* - encoding: Set by user.* - decoding: unused*/int max_b_frames;/*** qscale factor between IP and B-frames* If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).* If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).* - encoding: Set by user.* - decoding: unused*/float b_quant_factor;/*** qscale offset between IP and B-frames* - encoding: Set by user.* - decoding: unused*/float b_quant_offset;/*** Size of the frame reordering buffer in the decoder.* For MPEG-2 it is 1 IPB or 0 low delay IP.* - encoding: Set by libavcodec.* - decoding: Set by libavcodec.*/int has_b_frames;/*** qscale factor between P- and I-frames* If > 0 then the last P-frame quantizer will be used (q = lastp_q * factor + offset).* If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).* - encoding: Set by user.* - decoding: unused*/float i_quant_factor;/*** qscale offset between P and I-frames* - encoding: Set by user.* - decoding: unused*/float i_quant_offset;/*** luminance masking (0-> disabled)* - encoding: Set by user.* - decoding: unused*/float lumi_masking;/*** temporary complexity masking (0-> disabled)* - encoding: Set by user.* - decoding: unused*/float temporal_cplx_masking;/*** spatial complexity masking (0-> disabled)* - encoding: Set by user.* - decoding: unused*/float spatial_cplx_masking;/*** p block masking (0-> disabled)* - encoding: Set by user.* - decoding: unused*/float p_masking;/*** darkness masking (0-> disabled)* - encoding: Set by user.* - decoding: unused*/float dark_masking;/*** slice count* - encoding: Set by libavcodec.* - decoding: Set by user (or 0).*/int slice_count;/*** slice offsets in the frame in bytes* - encoding: Set/allocated by libavcodec.* - decoding: Set/allocated by user (or NULL).*/int *slice_offset;/*** sample aspect ratio (0 if unknown)* That is the width of a pixel divided by the height of the pixel.* Numerator and denominator must be relatively prime and smaller than 256 for some video standards.* - encoding: Set by user.* - decoding: Set by libavcodec.*/AVRational sample_aspect_ratio;/*** motion estimation comparison function* - encoding: Set by user.* - decoding: unused*/int me_cmp;/*** subpixel motion estimation comparison function* - encoding: Set by user.* - decoding: unused*/int me_sub_cmp;/*** macroblock comparison function (not supported yet)* - encoding: Set by user.* - decoding: unused*/int mb_cmp;
函数
函数调用逻辑慢慢补充
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,AVBufferRef *device_ref,enum AVPixelFormat hw_pix_fmt,AVBufferRef **out_frames_ref);
这篇关于FFmpeg之AVCodec的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!