ijkplayer框架簡析 — FFmpeg中重要結構體
A complete, cross-platform solution to record, convert and stream audio and video.
FFmpeg 是一個多媒體框架,能夠處理解編碼、轉碼、mux、demux、流、濾鏡和播放。它支援很多格式,且具有高度的移植性。
類庫
libavformat
- 用於解析和生成音視訊格式
libavcodec
- 編解碼音視訊
libavutil
- 工具庫
libswscale
- 提供比例縮放、色彩對映轉換、影象顏色空間或格式轉換的功能
libswresample
- 音訊重取樣,取樣格式轉換和混合等
libavfilter
-濾波器,如寬高比裁剪、格式化、非格式化、伸縮
libpostproc
- 後期效果處理,如影象的去塊效應等
libavdevice
-硬體採集、加速、顯示
結構體之間關係
-
協議(http, rtsp, rtmp, mms)
AVIOContext,URLProtocol,URLContext 主要儲存視音訊使用的協議的型別以及狀態。URLProtocol 儲存輸入視音訊使用的封裝格式;每種協議都對應一個URLProtocol結構(注意:FFMPEG中檔案也被當做一種協議 “file” )
-
封裝(flv, avi, rmvb, mp4)
AVFormatContext 主要儲存視音訊封裝格式中包含的資訊;AVInputFormat 儲存輸入視音訊使用的封裝格式。每種視音訊封裝格式都對應一個 AVInputFormat 結構
-
編解碼(h264, mpeg2, aac, mp3)
每個 AVStream 儲存一個視訊/音訊流的相關資料;每個 AVStream 對應一個 AVCodecContext,儲存該視訊 / 音訊流使用解碼方式的相關資料;每個 AVCodecContext 中對應一個 AVCodec,包含該視訊/音訊對應的解碼器。每種解碼器都對應一個 AVCodec 結構
-
資料
視訊的話,每個結構一般是存一幀(音訊可能有好幾幀)
解碼前資料:AVPacket;解碼後資料:AVFrame
結構體
網路協議
AVIOContext
管理輸入輸出資料的結構體,
在avformat_open_input()
中進行初始化
typedef struct AVIOContext{ const AVClass *av_class; unsigned char *buffer;/**< Start of the buffer. */ int buffer_size;/**< Maximum buffer size */ unsigned char *buf_ptr; /**< Current position in the buffer */ unsigned char *buf_end; /**< End of the data */ int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); int64_t (*seek)(void *opaque, int64_t offset, int whence); int64_t pos;/**< position in the file of the current buffer */ int must_flush;/**< true if the next seek should flush */ int eof_reached;/**< true if eof reached */ int write_flag;/**< true if open for writing */ int max_packet_size; unsigned long checksum; unsigned char *checksum_ptr; unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); int error;/**< contains the error code or 0 if no error happened */ int (*read_pause)(void *opaque, int pause); int64_t (*read_seek)(void *opaque, int stream_index, int64_t timestamp, int flags); int seekable; int64_t maxsize; int direct; int64_t bytes_read; int seek_count; int writeout_count; int orig_buffer_size; int short_seek_threshold; }
- unsigned char *buffer : 快取開始位置
- int buffer_size : 快取大小(預設32768)
- unsigned char *buf_ptr : 當前指標讀取到的位置
- unsigned char *buf_end : 快取結束的位置
- void *opaque : URLContext 結構體
在解碼的情況下,buffer 用於儲存 ffmpeg 讀入的資料。例如開啟一個視訊檔案的時候,先把資料從硬碟讀入buffer,然後在送給解碼器用於解碼。
URLProtocol
述了音視訊資料傳輸所使用的協議,每種傳輸協議 (例如 HTTP、RTMP) 等,都會對應一個 URLProtocol 結構
typedef struct URLProtocol { const char *name; int (*url_open)(URLContext *h, const char *url, int flags); int (*url_read)(URLContext *h, unsigned char *buf, int size); int (*url_write)(URLContext *h, const unsigned char *buf, int size); int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); int (*url_close)(URLContext *h); struct URLProtocol *next; int (*url_read_pause)(URLContext *h, int pause); int64_t (*url_read_seek)(URLContext *h, int stream_index, int64_t timestamp, int flags); int (*url_get_file_handle)(URLContext *h); int priv_data_size; const AVClass *priv_data_class; int flags; int (*url_check)(URLContext *h, int mask); }
-
const char *name : 儲存協議的名稱,每一種輸入協議都對應這樣一個結構體
URLProtocol ff_rtmp_protocol = { .name= "rtmp", .url_open= rtmp_open, .url_read= rtmp_read, .url_write= rtmp_write, .url_close= rtmp_close, .url_read_pause= rtmp_read_pause, .url_read_seek= rtmp_read_seek, .url_get_file_handle = rtmp_get_file_handle, .priv_data_size= sizeof(RTMP), .flags= URL_PROTOCOL_FLAG_NETWORK, };
等號右邊的函式是完成具體讀寫功能的函式。可以看一下 file 協議的幾個函式(file.c)
static int file_read(URLContext *h, unsigned char *buf, int size) { int fd = (intptr_t) h->priv_data; int r = read(fd, buf, size); return (-1 == r)?AVERROR(errno):r; } static int file_write(URLContext *h, const unsigned char *buf, int size) { int fd = (intptr_t) h->priv_data; int r = write(fd, buf, size); return (-1 == r)?AVERROR(errno):r; } static int file_get_handle(URLContext *h) { return (intptr_t) h->priv_data; } static int file_check(URLContext *h, int mask) { struct stat st; int ret = stat(h->filename, &st); if (ret < 0) return AVERROR(errno); ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ: 0; ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0; return ret; } #if CONFIG_FILE_PROTOCOL static int file_open(URLContext *h, const char *filename, int flags) { int access; int fd; av_strstart(filename, "file:", &filename); if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) { access = O_CREAT | O_TRUNC | O_RDWR; } else if (flags & AVIO_FLAG_WRITE) { access = O_CREAT | O_TRUNC | O_WRONLY; } else { access = O_RDONLY; } #ifdef O_BINARY access |= O_BINARY; #endif fd = open(filename, access, 0666); if (fd == -1) return AVERROR(errno); h->priv_data = (void *) (intptr_t) fd; return 0; } /* XXX: use llseek */ static int64_t file_seek(URLContext *h, int64_t pos, int whence) { int fd = (intptr_t) h->priv_data; if (whence == AVSEEK_SIZE) { struct stat st; int ret = fstat(fd, &st); return ret < 0 ? AVERROR(errno) : st.st_size; } return lseek(fd, pos, whence); } static int file_close(URLContext *h) { int fd = (intptr_t) h->priv_data; return close(fd); }
URLContext
封裝了協議物件及協議操作物件
封裝格式
AVFormatContext
描述了媒體檔案的構成及基本資訊,是統領全域性的基本結構體,貫穿程式始終,很多函式都要用它作為引數
typedef struct AVFormatContext { const AVClass *av_class; struct AVInputFormat *iformat; struct AVOutputFormat *oformat; void *priv_data; AVIOContext *pb; int ctx_flags; unsigned int nb_streams; AVStream **streams; char filename[1024]; int64_t start_time; int64_t duration; int bit_rate; unsigned int packet_size; int max_delay; int flags; const uint8_t *key; int keylen; unsigned int nb_programs; AVProgram **programs; enum AVCodecID video_codec_id; enum AVCodecID audio_codec_id; enum AVCodecID subtitle_codec_id; unsigned int max_index_size; unsigned int max_picture_buffer; unsigned int nb_chapters; AVChapter **chapters; AVDictionary *metadata; int64_t start_time_realtime; int fps_probe_size; int error_recognition; AVIOInterruptCB interrupt_callback; int64_t max_interleave_delta; int strict_std_compliance; int event_flags; int max_ts_probe; int avoid_negative_ts; int ts_id; int audio_preload; int max_chunk_duration; int max_chunk_size; int use_wallclock_as_timestamps; int avio_flags; enum AVDurationEstimationMethod duration_estimation_method; int64_t skip_initial_bytes; unsigned int correct_ts_overflow; int seek2any; int probe_score; int format_probesize; char *codec_whitelist; char *format_whitelist; AVFormatInternal *internal; int io_repositioned; AVCodec *video_codec; AVCodec *audio_codec; AVCodec *subtitle_codec; AVCodec *data_codec; int metadata_header_padding; void *opaque; av_format_control_message control_message_cb; int64_t output_ts_offset; uint8_t *dump_separator; enum AVCodecID data_codec_id; int (*open_cb)(struct AVFormatContext *s, AVIOContext **p, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options); }
-
struct AVInputFormat *iformat : 輸入資料的封裝格式,由
avformat_open_input
設定,僅僅在 Demuxing 使用。 -
struct AVOutputFormat *oformat : 輸出資料的封裝格式,必須由使用者在
avformat_write_header
前設定,由 Muxing 使用 -
priv_data : 在 muxing 中,由
avformat_write_header
設定;在 demuxing 中,由avformat_open_input
設定 -
AVIOContext *pb : 輸入資料的快取。如 果
iformat/oformat.flags
設定為AVFMT_NOFILE
的話,該欄位不需要設定。對於 Demuxing ,需要在avformat_open_input
前設定,或由avformat_open_input
設定;對於 Muxing,在avformat_write_header
前設定 -
ctx_flags : 碼流的資訊,表明碼流屬性的的訊號。由
libavformat
設定,例如AVFMTCTX_NOHEADER
-
nb_streams : 指
AVFormatContext.streams
的數量,必須由avformat_new_stream
設定 -
AVStream **streams : 檔案中所有碼流的列表,新的碼流建立使用
avformat_new_stream
函式。Demuxing 中,碼流由avformat_open_input
建立。 如果AVFMTCTX_NOHEADER
被設定,新的碼流可以出現在av_read_frame
中。Muxing 中,碼流在avformat_write_header
之前由使用者建立,它的釋放是由avformat_free_context
完成的 -
filename : 輸入或輸出的檔名,Demuxing 中由
avformat_open_input
設定,Muxing 中在使用avformat_write_header
前由呼叫者設定 - int64_t duration : 碼流的時長
- bit_rate : 位元率
-
AVDictionary *metadata : 元資料,適用於整個檔案。通過
av_dict_get()
函式獲得視訊的原資料
AVInputFormat
解複用器物件,每種作為輸入的封裝格式 (例如FLV 、MP4 、TS 等) 對應一個該結構體
AVOutputFormat
複用器物件,每種作為輸出的封裝格式(例如FLV ,MP4 、TS 等)對應一個該結構體
AVStream
用於描述一個視訊 / 音訊流的相關資料資訊
編解碼
AVCodecContext
描述編解碼器上下文的資料結構,包含了眾多編解碼器需要的引數資訊
typedef struct AVCodecContext{ const AVClass *av_class; int log_level_offset; enum AVMediaType codec_type; const struct AVCodec *codec; enum AVCodecIDcodec_id; unsigned int codec_tag; void *priv_data; struct AVCodecInternal *internal; void *opaque; int bit_rate; int bit_rate_tolerance; int global_quality; int compression_level; int flags; int flags2; uint8_t *extradata; int extradata_size; AVRational time_base; int ticks_per_frame; int delay; int width, height; int coded_width, coded_height; int gop_size; enum AVPixelFormat pix_fmt; void (*draw_horiz_band)(struct AVCodecContext *s, const AVFrame *src, int offset[AV_NUM_DATA_POINTERS], int y, int type, int height); enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt); int max_b_frames; float b_quant_factor; int b_frame_strategy; float b_quant_offset; int has_b_frames; int mpeg_quant; /*decoding: unused*/ float i_quant_factor; /*decoding: unused*/ float i_quant_offset; /*decoding: unused*/ float lumi_masking;/*decoding: unused*/ float temporal_cplx_masking; /*decoding: unused*/ float spatial_cplx_masking;/*decoding: unused*/ float p_masking;/*decoding: unused*/ float dark_masking;/*decoding: unused*/ int slice_count; int prediction_method;/*decoding: unused*/ int *slice_offset; AVRational sample_aspect_ratio; int me_cmp;/*decoding: unused*/ int me_sub_cmp;/*decoding: unused*/ int mb_cmp;/*decoding: unused*/ ... }AVCodecContext;
- AVMediaType codec_type : 編解碼器的型別,如音訊、視訊、字幕
- AVCdec *codec : 採用的解碼器 AVCodec
- int bit_rate : 平均位元率
- uint8_t *extradata; int extradata_size : 針對特定編碼器包含的附加資訊(例如對於H.264解碼器來說,儲存SPS,PPS等)
- AVRational time_base : 根據該引數,可以把PTS轉化為實際的時間(單位為秒s)
- int width, height : 視訊的寬高
- int refs : 運動估計參考幀的個數
- int sample_rate : 取樣率
- int channels : 聲道數
- enum AVSampleFormat sample_fmt : 取樣格式
- int profile : 型(H.264裡面就有,其他編碼標準應該也有)
- int level : 級(和profile差不太多)
AVCodecContext 使用 avcodec_alloc_context3 分配,該函式除了分配 AVCodecContext 外,還會初始化預設的欄位。分配的記憶體必須通過 avcodec_free_context 釋放。AVCodecContext 中很多的引數是編碼的時候使用的,而不是解碼的時候使用的
avcodec_register_all(); ... codec = avcodec_find_decoder(AV_CODEC_ID_H264); if(!codec) exit(1); context = avcodec_alloc_context3(codec); if(avcodec_open2(context, codec, opts) < 0) exit(1);
codec_type(編解碼器型別)
enum AVMediaType { AVMEDIA_TYPE_UNKNOWN = -1,///< Usually treated as AVMEDIA_TYPE_DATA AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA,///< Opaque data information usually continuous AVMEDIA_TYPE_SUBTITLE, AVMEDIA_TYPE_ATTACHMENT,///< Opaque data information usually sparse AVMEDIA_TYPE_NB };
sample_fmt(音訊取樣格式)
enum AVSampleFormat { AV_SAMPLE_FMT_NONE = -1, AV_SAMPLE_FMT_U8,///< unsigned 8 bits AV_SAMPLE_FMT_S16,///< signed 16 bits AV_SAMPLE_FMT_S32,///< signed 32 bits AV_SAMPLE_FMT_FLT,///< float AV_SAMPLE_FMT_DBL,///< double AV_SAMPLE_FMT_U8P,///< unsigned 8 bits, planar AV_SAMPLE_FMT_S16P,///< signed 16 bits, planar AV_SAMPLE_FMT_S32P,///< signed 32 bits, planar AV_SAMPLE_FMT_FLTP,///< float, planar AV_SAMPLE_FMT_DBLP,///< double, planar AV_SAMPLE_FMT_NB///< Number of sample formats. DO NOT USE if linking dynamically };
profile
#define FF_PROFILE_UNKNOWN -99 #define FF_PROFILE_RESERVED -100 #define FF_PROFILE_AAC_MAIN 0 #define FF_PROFILE_AAC_LOW1 #define FF_PROFILE_AAC_SSR2 #define FF_PROFILE_AAC_LTP3 #define FF_PROFILE_AAC_HE4 #define FF_PROFILE_AAC_HE_V2 28 #define FF_PROFILE_AAC_LD22 #define FF_PROFILE_AAC_ELD38 #define FF_PROFILE_DTS20 #define FF_PROFILE_DTS_ES30 #define FF_PROFILE_DTS_96_2440 #define FF_PROFILE_DTS_HD_HRA50 #define FF_PROFILE_DTS_HD_MA60 #define FF_PROFILE_MPEG2_4220 #define FF_PROFILE_MPEG2_HIGH1 #define FF_PROFILE_MPEG2_SS2 #define FF_PROFILE_MPEG2_SNR_SCALABLE3 #define FF_PROFILE_MPEG2_MAIN4 #define FF_PROFILE_MPEG2_SIMPLE 5 #define FF_PROFILE_H264_CONSTRAINED(1<<9)// 8+1; constraint_set1_flag #define FF_PROFILE_H264_INTRA(1<<11) // 8+3; constraint_set3_flag #define FF_PROFILE_H264_BASELINE66 #define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED) #define FF_PROFILE_H264_MAIN77 #define FF_PROFILE_H264_EXTENDED88 #define FF_PROFILE_H264_HIGH100 #define FF_PROFILE_H264_HIGH_10110 #define FF_PROFILE_H264_HIGH_10_INTRA(110|FF_PROFILE_H264_INTRA) #define FF_PROFILE_H264_HIGH_422122 #define FF_PROFILE_H264_HIGH_422_INTRA(122|FF_PROFILE_H264_INTRA) #define FF_PROFILE_H264_HIGH_444144 #define FF_PROFILE_H264_HIGH_444_PREDICTIVE244 #define FF_PROFILE_H264_HIGH_444_INTRA(244|FF_PROFILE_H264_INTRA) #define FF_PROFILE_H264_CAVLC_44444 #define FF_PROFILE_VC1_SIMPLE0 #define FF_PROFILE_VC1_MAIN1 #define FF_PROFILE_VC1_COMPLEX2 #define FF_PROFILE_VC1_ADVANCED 3 #define FF_PROFILE_MPEG4_SIMPLE0 #define FF_PROFILE_MPEG4_SIMPLE_SCALABLE1 #define FF_PROFILE_MPEG4_CORE2 #define FF_PROFILE_MPEG4_MAIN3 #define FF_PROFILE_MPEG4_N_BIT4 #define FF_PROFILE_MPEG4_SCALABLE_TEXTURE5 #define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION6 #define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE7 #define FF_PROFILE_MPEG4_HYBRID8 #define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME9 #define FF_PROFILE_MPEG4_CORE_SCALABLE10 #define FF_PROFILE_MPEG4_ADVANCED_CODING11 #define FF_PROFILE_MPEG4_ADVANCED_CORE12 #define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13 #define FF_PROFILE_MPEG4_SIMPLE_STUDIO14 #define FF_PROFILE_MPEG4_ADVANCED_SIMPLE15
AVCodec
編解碼器物件,每種編解碼格式 (例如 H.264、AAC 等)對應一個該結構體;每個 AVCodecContext 中含有一個 AVCodec
typedef struct AVCodec{ const char *name; const char *long_name; enum AVMediaType type; enum AVCodecID id; int capabilities; const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} const enum AVPixelFormat *pix_fmts;///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 const int *supported_samplerates;///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 const uint64_t *channel_layouts;///< array of support channel layouts, or NULL if unknown. array is terminated by 0 uint8_t max_lowres;///< maximum value for lowres supported by the decoder, no direct access, use av_codec_get_max_lowres() const AVClass *priv_class;///< AVClass for the private context const AVProfile *profiles;///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} int priv_data_size; struct AVCodec *next; int (*init_thread_copy)(AVCodecContext *); int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src); const AVCodecDefault *defaults; void (*init_static_data)(struct AVCodec *codec); int (*init)(AVCodecContext *); int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size, int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr); int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); int (*close)(AVCodecContext *); void (*flush)(AVCodecContext *); int caps_internal; }
- name : 具體的 CODEC 的名稱的簡短描述,比如 “HEVC”/“H264” 等
- long_name : CODEC 名稱的詳細描述,比如 “HEVC (High Efficiency Video Coding)”
- type : 媒體型別的欄位,它是 enum 型的,表示視訊、音訊、字幕等,比如AVMEDIA_TYPE_VIDEO、AVMEIDA_TYPE_AUDIO
- id : 唯一標識的 CODEC 型別,比如 AV_CODEC_ID_HEVC
- supported_framerates : 支援的視訊幀率的陣列,以{0,0}作為結束
- pix_fmts : 編解碼器支援的影象格式的陣列,以 -1 作為結束
- profiles : 編解碼器支援的 Profile,以 HEVC 為例,包含 “Main” / “Main10” / “Main Still Picture”
- supported_samplerates : 支援的音訊取樣率
- sample_fmts : 支援的音訊取樣格式
- channel_layouts : 支援的音訊聲道數
- priv_data_size : 私有資料的大小
enum AVMediaType type
enum AVMediaType { AVMEDIA_TYPE_UNKNOWN = -1,///< Usually treated as AVMEDIA_TYPE_DATA AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA,///< Opaque data information usually continuous AVMEDIA_TYPE_SUBTITLE, AVMEDIA_TYPE_ATTACHMENT,///< Opaque data information usually sparse AVMEDIA_TYPE_NB }
enum AVCodecID id
enum AVCodecID { AV_CODEC_ID_NONE, /* video codecs */ AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding AV_CODEC_ID_MPEG2VIDEO_XVMC, AV_CODEC_ID_H261, AV_CODEC_ID_H263, AV_CODEC_ID_RV10, AV_CODEC_ID_RV20, AV_CODEC_ID_MJPEG, AV_CODEC_ID_MJPEGB, AV_CODEC_ID_LJPEG, AV_CODEC_ID_SP5X, AV_CODEC_ID_JPEGLS, AV_CODEC_ID_MPEG4, AV_CODEC_ID_RAWVIDEO, AV_CODEC_ID_MSMPEG4V1, AV_CODEC_ID_MSMPEG4V2, AV_CODEC_ID_MSMPEG4V3, AV_CODEC_ID_WMV1, AV_CODEC_ID_WMV2, AV_CODEC_ID_H263P, AV_CODEC_ID_H263I, AV_CODEC_ID_FLV1, AV_CODEC_ID_SVQ1, AV_CODEC_ID_SVQ3, AV_CODEC_ID_DVVIDEO, AV_CODEC_ID_HUFFYUV, AV_CODEC_ID_CYUV, AV_CODEC_ID_H264, ... }
const enum AVPixelFormat *pix_fmts
enum AVPixelFormat { AV_PIX_FMT_NONE = -1, AV_PIX_FMT_YUV420P,///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) AV_PIX_FMT_YUYV422,///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr AV_PIX_FMT_RGB24,///< packed RGB 8:8:8, 24bpp, RGBRGB... AV_PIX_FMT_BGR24,///< packed RGB 8:8:8, 24bpp, BGRBGR... AV_PIX_FMT_YUV422P,///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) AV_PIX_FMT_YUV444P,///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) AV_PIX_FMT_YUV410P,///< planar YUV 4:1:0,9bpp, (1 Cr & Cb sample per 4x4 Y samples) AV_PIX_FMT_YUV411P,///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) AV_PIX_FMT_GRAY8,///<Y,8bpp AV_PIX_FMT_MONOWHITE, ///<Y,1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb AV_PIX_FMT_MONOBLACK, ///<Y,1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb AV_PIX_FMT_PAL8,///< 8 bit with PIX_FMT_RGB32 palette AV_PIX_FMT_YUVJ420P,///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range AV_PIX_FMT_YUVJ422P,///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range AV_PIX_FMT_YUVJ444P,///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing AV_PIX_FMT_XVMC_MPEG2_IDCT, ... }
const enum AVSampleFormat *sample_fmts
enum AVSampleFormat { AV_SAMPLE_FMT_NONE = -1, AV_SAMPLE_FMT_U8,///< unsigned 8 bits AV_SAMPLE_FMT_S16,///< signed 16 bits AV_SAMPLE_FMT_S32,///< signed 32 bits AV_SAMPLE_FMT_FLT,///< float AV_SAMPLE_FMT_DBL,///< double AV_SAMPLE_FMT_U8P,///< unsigned 8 bits, planar AV_SAMPLE_FMT_S16P,///< signed 16 bits, planar AV_SAMPLE_FMT_S32P,///< signed 32 bits, planar AV_SAMPLE_FMT_FLTP,///< float, planar AV_SAMPLE_FMT_DBLP,///< double, planar AV_SAMPLE_FMT_NB///< Number of sample formats. DO NOT USE if linking dynamically };
每一個編解碼器對應一個 AVCodec 該結構體
AVCodec ff_h264_decoder = { .name= "h264", .type= AVMEDIA_TYPE_VIDEO, .id= CODEC_ID_H264, .priv_data_size = sizeof(H264Context), .init= ff_h264_decode_init, .close= ff_h264_decode_end, .decode= decode_frame, .capabilities= /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS, .flush= flush_dpb, .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .init_thread_copy= ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context), .profiles = NULL_IF_CONFIG_SMALL(profiles), .priv_class= &h264_class, };
AVCodecParameters
編解碼引數,每個 AVStream 中都含有一個 AVCodecParameters,用來存放當前流的編解碼引數
資料
AVPacket
存放編碼後、解碼前的壓縮資料,即 ES 資料
typedef struct AVPacket{ AVBufferRef *buf; int64_tpts; int64_tdts; uint8_t*data; intsize; int stream_index; intflags; AVPacketSideData *side_data; int side_data_elems; intduration; int64_t pos; int64_t convergence_duration; }
- pts: 顯示時間戳,它的單位是 AVStream->time_base;如果在檔案中沒有儲存這個值,它被設定為 AV_NOPTS_VALUE。由於影象顯示不可能早於影象解壓,因此 PTS 必須比 DTS(解碼時間戳)大或者相等。某些檔案格式中可能會使用 PTS/DTS 表示其他含義,此時時間戳必須轉為真正的時間戳才能儲存到 AVPacket 結構中
- dts : 解碼時間戳,它的單位是 AVStream->time_base,表示壓縮視訊解碼的時間,如果檔案中沒有儲存該值,它被設定為 AV_NOPTS_VALUE
- data : 指向真正的壓縮編碼的資料
- size : 表示該 AVPacket 結構中 data 欄位所指向的壓縮資料的大小
- stream_index : 標識該 AVPacket 結構所屬的視訊流或音訊流
- duration : 該 AVPacket 包以 AVStream->time_base 為單位,所持續的時間,0 表示未知,或者為顯示時間戳的差值(next_pts - this pts)
- pos : 表示該 AVPacket 資料在媒體中的位置,即位元組偏移量
AVFrame
存放編碼前、解碼後的原始資料,如 YUV 格式的視訊資料或 PCM 格式的音訊資料等
AVFrame 結構體必須使用av_frame_alloc()
分配,注意該函式只是分配了 AVFrame 結構本身,它的 data 區域要用其他方式管理;該結構體的釋放要用av_frame_free()
。
AVFrame 結構體通常只需分配一次,之後即可通過儲存不同的資料來重複多次使用,比如一個 AVFrame 結構可以儲存從解碼器中解碼出的多幀資料。此時,就可以使用av_frame_unref()
釋放任何由 Frame 儲存的參考幀並還原回最原始的狀態。
typedef struct AVFrame{ uint8_t *data[AV_NUM_DATA_POINTERS]; int linesize[AV_NUM_DATA_POINTERS]; uint8_t **extended_data; int width, height; int nb_samples; /* number of audio samples(per channel) described by this frame */ int format; int key_frame; /* 1->keyframe, 0->not*/ enum AVPictureType pict_type; AVRational sample_aspect_ratio; int64_t pts; int64_t pkt_pts; int64_t pkt_dts; int coded_picture_number; int display_picture_number; int quality; void *opaque; /* for some private data of the user */ uint64_t error[AV_NUM_DATA_POINTERS]; int repeat_pict; int interlaced_frame; int top_field_first;/* If the content is interlaced, is top field displayed first */ int palette_has_changed; int64_t reordered_opaque; int sample_rate;/*Sample rate of the audio data*/ uint64_t channel_layout; /*channel layout of the audio data*/ AVBufferRef *buf[AV_NUM_DATA_POINTERS]; AVBufferRef **extended_buf; int nb_exteneded_buf; AVFrameSideData **side_data; int nb_side_data; int flags; enum AVColorRange color_range; enum AVColorPrimaries color_primaries; enum AVColorTransferCharacteristic color_trc; enum AVColorSpace colorspace; enum AVChromaLocation chroma_location; int64_t best_effort_timestamp; int64_t pkt_pos; int64_t pkt_duration; AVDictionary *metadata; int decode _error_flags; int channels; int pkt_size; AVBufferRef *qp_table_buf; }
avcodec_align_dimensions2()
pict_type
enum AVPictureType { AV_PICTURE_TYPE_NONE = 0, ///< Undefined AV_PICTURE_TYPE_I,///< Intra AV_PICTURE_TYPE_P,///< Predicted AV_PICTURE_TYPE_B,///< Bi-dir predicted AV_PICTURE_TYPE_S,///< S(GMC)-VOP MPEG4 AV_PICTURE_TYPE_SI,///< Switching Intra AV_PICTURE_TYPE_SP,///< Switching Predicted AV_PICTURE_TYPE_BI,///< BI type };