1. 程式人生 > >FFMPEG結構體分析:AVFormatContext

FFMPEG結構體分析:AVFormatContext

注:寫了一系列的結構體的分析的文章,在這裡列一個列表:

FFMPEG有幾個最重要的結構體,包含了解協議,解封裝,解碼操作,此前已經進行過分析:

在此不再詳述,其中AVFormatContext是包含碼流引數較多的結構體。本文將會詳細分析一下該結構體裡每個變數的含義和作用。

首先看一下結構體的定義(位於avformat.h):

/* 雷霄驊
 * 中國傳媒大學/數字電視技術
 * [email protected]
 *
 */
/**
 * Format I/O context.
 * New fields can be added to the end with minor version bumps.
 * Removal, reordering and changes to existing fields require a major
 * version bump.
 * sizeof(AVFormatContext) must not be used outside libav*, use
 * avformat_alloc_context() to create an AVFormatContext.
 */
typedef struct AVFormatContext {
    /**
     * A class for logging and AVOptions. Set by avformat_alloc_context().
     * Exports (de)muxer private options if they exist.
     */
    const AVClass *av_class;

    /**
     * Can only be iformat or oformat, not both at the same time.
     *
     * decoding: set by avformat_open_input().
     * encoding: set by the user.
     */
    struct AVInputFormat *iformat;
    struct AVOutputFormat *oformat;

    /**
     * Format private data. This is an AVOptions-enabled struct
     * if and only if iformat/oformat.priv_class is not NULL.
     */
    void *priv_data;

    /*
     * I/O context.
     *
     * decoding: either set by the user before avformat_open_input() (then
     * the user must close it manually) or set by avformat_open_input().
     * encoding: set by the user.
     *
     * Do NOT set this field if AVFMT_NOFILE flag is set in
     * iformat/oformat.flags. In such a case, the (de)muxer will handle
     * I/O in some other way and this field will be NULL.
     */
    AVIOContext *pb;

    /* stream info */
    int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */

    /**
     * A list of all streams in the file. New streams are created with
     * avformat_new_stream().
     *
     * decoding: streams are created by libavformat in avformat_open_input().
     * If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also
     * appear in av_read_frame().
     * encoding: streams are created by the user before avformat_write_header().
     */
    unsigned int nb_streams;
    AVStream **streams;

    char filename[1024]; /**< input or output filename */

    /**
     * Decoding: position of the first frame of the component, in
     * AV_TIME_BASE fractional seconds. NEVER set this value directly:
     * It is deduced from the AVStream values.
     */
    int64_t start_time;

    /**
     * Decoding: duration of the stream, in AV_TIME_BASE fractional
     * seconds. Only set this value if you know none of the individual stream
     * durations and also do not set any of them. This is deduced from the
     * AVStream values if not set.
     */
    int64_t duration;

    /**
     * Decoding: total stream bitrate in bit/s, 0 if not
     * available. Never set it directly if the file_size and the
     * duration are known as FFmpeg can compute it automatically.
     */
    int bit_rate;

    unsigned int packet_size;
    int max_delay;

    int flags;
#define AVFMT_FLAG_GENPTS       0x0001 ///< Generate missing pts even if it requires parsing future frames.
#define AVFMT_FLAG_IGNIDX       0x0002 ///< Ignore index.
#define AVFMT_FLAG_NONBLOCK     0x0004 ///< Do not block when reading packets from input.
#define AVFMT_FLAG_IGNDTS       0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
#define AVFMT_FLAG_NOFILLIN     0x0010 ///< Do not infer any values from other values, just return what is stored in the container
#define AVFMT_FLAG_NOPARSE      0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
#define AVFMT_FLAG_CUSTOM_IO    0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
#define AVFMT_FLAG_DISCARD_CORRUPT  0x0100 ///< Discard frames marked corrupted
#define AVFMT_FLAG_MP4A_LATM    0x8000 ///< Enable RTP MP4A-LATM payload
#define AVFMT_FLAG_SORT_DTS    0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
#define AVFMT_FLAG_PRIV_OPT    0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Dont merge side data but keep it separate.

    /**
     * decoding: size of data to probe; encoding: unused.
     */
    unsigned int probesize;

    /**
     * decoding: maximum time (in AV_TIME_BASE units) during which the input should
     * be analyzed in avformat_find_stream_info().
     */
    int max_analyze_duration;

    const uint8_t *key;
    int keylen;

    unsigned int nb_programs;
    AVProgram **programs;

    /**
     * Forced video codec_id.
     * Demuxing: Set by user.
     */
    enum CodecID video_codec_id;

    /**
     * Forced audio codec_id.
     * Demuxing: Set by user.
     */
    enum CodecID audio_codec_id;

    /**
     * Forced subtitle codec_id.
     * Demuxing: Set by user.
     */
    enum CodecID subtitle_codec_id;

    /**
     * Maximum amount of memory in bytes to use for the index of each stream.
     * If the index exceeds this size, entries will be discarded as
     * needed to maintain a smaller size. This can lead to slower or less
     * accurate seeking (depends on demuxer).
     * Demuxers for which a full in-memory index is mandatory will ignore
     * this.
     * muxing  : unused
     * demuxing: set by user
     */
    unsigned int max_index_size;

    /**
     * Maximum amount of memory in bytes to use for buffering frames
     * obtained from realtime capture devices.
     */
    unsigned int max_picture_buffer;

    unsigned int nb_chapters;
    AVChapter **chapters;

    AVDictionary *metadata;

    /**
     * Start time of the stream in real world time, in microseconds
     * since the unix epoch (00:00 1st January 1970). That is, pts=0
     * in the stream was captured at this real world time.
     * - encoding: Set by user.
     * - decoding: Unused.
     */
    int64_t start_time_realtime;

    /**
     * decoding: number of frames used to probe fps
     */
    int fps_probe_size;

    /**
     * Error recognition; higher values will detect more errors but may
     * misdetect some more or less valid parts as errors.
     * - encoding: unused
     * - decoding: Set by user.
     */
    int error_recognition;

    /**
     * Custom interrupt callbacks for the I/O layer.
     *
     * decoding: set by the user before avformat_open_input().
     * encoding: set by the user before avformat_write_header()
     * (mainly useful for AVFMT_NOFILE formats). The callback
     * should also be passed to avio_open2() if it's used to
     * open the file.
     */
    AVIOInterruptCB interrupt_callback;

    /**
     * Flags to enable debugging.
     */
    int debug;
#define FF_FDEBUG_TS        0x0001

    /**
     * Transport stream id.
     * This will be moved into demuxer private options. Thus no API/ABI compatibility
     */
    int ts_id;

    /**
     * Audio preload in microseconds.
     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
     * - encoding: Set by user via AVOptions (NO direct access)
     * - decoding: unused
     */
    int audio_preload;

    /**
     * Max chunk time in microseconds.
     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
     * - encoding: Set by user via AVOptions (NO direct access)
     * - decoding: unused
     */
    int max_chunk_duration;

    /**
     * Max chunk size in bytes
     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
     * - encoding: Set by user via AVOptions (NO direct access)
     * - decoding: unused
     */
    int max_chunk_size;

    /*****************************************************************
     * All fields below this line are not part of the public API. They
     * may not be used outside of libavformat and can be changed and
     * removed at will.
     * New public fields should be added right above.
     *****************************************************************
     */

    /**
     * This buffer is only needed when packets were already buffered but
     * not decoded, for example to get the codec parameters in MPEG
     * streams.
     */
    struct AVPacketList *packet_buffer;
    struct AVPacketList *packet_buffer_end;

    /* av_seek_frame() support */
    int64_t data_offset; /**< offset of the first packet */

    /**
     * Raw packets from the demuxer, prior to parsing and decoding.
     * This buffer is used for buffering packets until the codec can
     * be identified, as parsing cannot be done without knowing the
     * codec.
     */
    struct AVPacketList *raw_packet_buffer;
    struct AVPacketList *raw_packet_buffer_end;
    /**
     * Packets split by the parser get queued here.
     */
    struct AVPacketList *parse_queue;
    struct AVPacketList *parse_queue_end;
    /**
     * Remaining size available for raw_packet_buffer, in bytes.
     */
#define RAW_PACKET_BUFFER_SIZE 2500000
    int raw_packet_buffer_remaining_size;
} AVFormatContext;

在使用FFMPEG進行開發的時候,AVFormatContext是一個貫穿始終的資料結構,很多函式都要用到它作為引數。它是FFMPEG解封裝(flv,mp4,rmvb,avi)功能的結構體。下面看幾個主要變數的作用(在這裡考慮解碼的情況):

struct AVInputFormat *iformat:輸入資料的封裝格式

AVIOContext *pb:輸入資料的快取

unsigned int nb_streams:視音訊流的個數

AVStream **streams:視音訊流

char filename[1024]:檔名

int64_t duration:時長(單位:微秒us,轉換為秒需要除以1000000)

int bit_rate:位元率(單位bps,轉換為kbps需要除以1000)

AVDictionary *metadata:元資料

視訊的時長可以轉換成HH:MM:SS的形式,示例程式碼如下:

AVFormatContext *pFormatCtx;
CString timelong;
...
//duration是以微秒為單位
//轉換成hh:mm:ss形式
int tns, thh, tmm, tss;
tns  = (pFormatCtx->duration)/1000000;
thh  = tns / 3600;
tmm  = (tns % 3600) / 60;
tss  = (tns % 60);
timelong.Format("%02d:%02d:%02d",thh,tmm,tss);


視訊的原資料(metadata)資訊可以通過AVDictionary獲取。元資料儲存在AVDictionaryEntry結構體中,如下所示

typedef struct AVDictionaryEntry {
    char *key;
    char *value;
} AVDictionaryEntry;
每一條元資料分為key和value兩個屬性。

在ffmpeg中通過av_dict_get()函式獲得視訊的原資料。

下列程式碼顯示了獲取元資料並存入meta字串變數的過程,注意每一條key和value之間有一個"\t:",value之後有一個"\r\n"

//MetaData------------------------------------------------------------
//從AVDictionary獲得
//需要用到AVDictionaryEntry物件
//CString author,copyright,description;
CString meta=NULL,key,value;
AVDictionaryEntry *m = NULL;
//不用一個一個找出來
/*	m=av_dict_get(pFormatCtx->metadata,"author",m,0);
author.Format("作者:%s",m->value);
m=av_dict_get(pFormatCtx->metadata,"copyright",m,0);
copyright.Format("版權:%s",m->value);
m=av_dict_get(pFormatCtx->metadata,"description",m,0);
description.Format("描述:%s",m->value);
*/
//使用迴圈讀出
//(需要讀取的資料,欄位名稱,前一條欄位(迴圈時使用),引數)
while(m=av_dict_get(pFormatCtx->metadata,"",m,AV_DICT_IGNORE_SUFFIX)){
	key.Format(m->key);
	value.Format(m->value);
	meta+=key+"\t:"+value+"\r\n" ;
}



相關推薦

FFMPEG結構分析AVFormatContext

注:寫了一系列的結構體的分析的文章,在這裡列一個列表:FFMPEG有幾個最重要的結構體,包含了解協議,解封裝,解碼操作,此前已經進行過分析:在此不再詳述,其中AVFormatContext是包含碼流引數較多的結構體。本文將會詳細分析一下該結構體裡每個變數的含義和作用。首先看一

FFMPEG結構分析AVFrame

                注:寫了一系列的結構體的分析的文章,在這裡列一個列表:FFMPEG有幾個最重要的結構體,包含了解協議,解封裝,解碼操作,此前已經進行過分析:在此不再詳述,其中AVFrame是包含碼流引數較多的結構體。本文將會詳細分析一下該結構體裡主要變數的含義和作用。首先看一下結構體的定義(位

FFMPEG結構分析AVCodec

const char *name:編解碼器的名字,比較短const char *long_name:編解碼器的名字,全稱,比較長enum AVMediaType type:指明瞭型別,是視訊,音訊,還是

FFMPEG結構分析AVPacket

注:寫了一系列的結構體的分析的文章,在這裡列一個列表: FFMPEG有幾個最重要的結構體,包含了解協議,解封裝,解碼操作,此前已經進行過分析: 在此不再詳述,其中AVPacket是儲存壓縮編碼資料相關資訊的結構體。本文將會詳細分析一下該結構體裡

FFmpegAVFormatContext結構分析

FFmpeg: AVFormatContext結構體解析 AVFormatContext AVFormatContext是API中直接接觸到的結構體,位於avformat.h中,是音視訊資料,也就是音視訊檔案(通常接觸到的mp3/mp4等檔案)的一種抽象

FFmpeg原始碼簡單分析常見結構的初始化和銷燬(AVFormatContext,AVFrame等)

=====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

FFmpeg 結構學習(二) AVStream 分析

rem hid version tin avd none internal hunk terms 在上文FFmpeg 結構體學習(一): AVFormatContext 分析我們學習了AVFormatContext結構體的相關內容。本文,我們將講述一下AVStream。 A

FFmpeg原始碼簡單分析結構成員管理系統-AVClass

=====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

libevent源碼分析1 ----evnet相關結構分析

所有 active 復用 超時 handling 源碼 執行 evb tel 位於代碼event-internal.h中。 event_base類似事件的集合,你創建一個事件,必須將該事件指定一個集合。 struct event_base { 50 const

FFmpeg結構之AVCodec

hat 結構 ranges gray enc add www. fig existing AVCodec字段 AVCodec是存儲編解碼器信息的結構體,主要字段註釋如下: const char *name; //編解碼器名字 const char *long_name;

usb驅動結構分析

1.usb幾個結構體總結 (1)usb_bus_type usb匯流排型別結構體 drivers/usb/core/driver.c struct bus_type usb_bus_type = { .name = "usb", .match = usb_device_match

uart_ops結構分析之amba_pl011_pops

static struct uart_ops amba_pl011_pops = { .tx_empty = pl01x_tx_empty, //串列埠的tx_fifo是否為空 .set_mctrl = pl011_set_mctrl,

結構定義unsigned int type : 2;

1. C語言實現的HTTP協議的解析原始碼中有下面的結構體定義: struct http_parser { unsigned int type : 2; unsigned int flags : 8; unsigned int state : 7;

iOS Class結構分析~詳解

//聯絡人:石虎  QQ: 1224614774暱稱:嗡嘛呢叭咪哄 objc_class結構體 一、類在OC中是objc_class的結構體指標   typedef struct ob

結構定義struct與typedef struct 用法詳解和用法小結

黑體二 三是關鍵 一、typedef的用法 在C/C++語言中,typedef常用來定義一個識別符號及關鍵字的別名,它是語言編譯過程的一部分,但它並不實際分配記憶體空間,例項像: typedef int INT; typedef int ARRAY[10]; type

ffmpeg 原始碼簡單分析 av_read_frame()

此前寫了好幾篇ffmpeg原始碼分析文章,列表如下: ============================ ffmpeg中的av_read_frame()的作用是讀取碼流中的音訊若干幀或者視訊一幀。例如,解碼視訊的時

ffmpeg 原始碼簡單分析 av_register_all()

此前寫了好幾篇ffmpeg原始碼分析文章,列表如下: ============================ 前一陣子看了一下ffmpeg的原始碼,並且做了一些註釋,在此貼出來以作備忘。 本文分析一下ffmpeg註冊

FFmpeg原始碼簡單分析makefile

=====================================================FFmpeg的庫函式原始碼分析文章列表:【架構圖】【通用】【解碼】【編碼】【其它】【指令碼】【H.264】================================

82599網絡卡驅動rx descriptor結構分析

82599 datasheet: 7.1.6  節    大概位於314頁 對驅動的理解關鍵是對資料結構的理解。 The 82599 posts receive packets into data buffers in system memory. The follo

【C++】用結構完成程式設計求出3個學生中某個學生的平均成績

//用結構體完成:程式設計求出3個學生中某個學生的平均成績 #include <iostream> #include <string.h> using namespace st