InputStream數(shù)據(jù)結(jié)構(gòu)示例解析
正文
struct InputStream 是單個(gè)輸入流的管理器。是由 add_input_stream() 函數(shù)申請(qǐng)內(nèi)存,以及賦值 InputStream 的各個(gè)字段的。
而 input_streams 數(shù)組是一個(gè)全局變量,包含了所有輸入文件里面的所有輸入流。
nputStream **input_streams = NULL; int nb_input_streams = 0;
你在二次開(kāi)發(fā) ffmpeg.exe 的時(shí)候,可以用 input_streams 全局變量來(lái)獲取到所有的輸入流。
struct InputStream數(shù)據(jù)結(jié)構(gòu)定義
typedef struct InputStream {
int file_index;
AVStream *st;
int discard; /* true if stream data should be discarded */
int user_set_discard;
int decoding_needed; /* non zero if the packets must be decoded in 'raw_fifo', see DECODING_FOR_* */
#define DECODING_FOR_OST 1
#define DECODING_FOR_FILTER 2
AVCodecContext *dec_ctx;
const AVCodec *dec;
AVFrame *decoded_frame;
AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */
AVPacket *pkt;
int64_t start; /* time when read started */
/* predicted dts of the next packet read for this stream or (when there are
* several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */
int64_t next_dts;
int64_t dts; ///< dts of the last packet read for this stream (in AV_TIME_BASE units)
int64_t next_pts; ///< synthetic pts for the next decode frame (in AV_TIME_BASE units)
int64_t pts; ///< current pts of the decoded frame (in AV_TIME_BASE units)
int wrap_correction_done;
int64_t filter_in_rescale_delta_last;
int64_t min_pts; /* pts with the smallest value in a current stream */
int64_t max_pts; /* pts with the higher value in a current stream */
// when forcing constant input framerate through -r,
// this contains the pts that will be given to the next decoded frame
int64_t cfr_next_pts;
int64_t nb_samples; /* number of samples in the last decoded audio frame before looping */
double ts_scale;
int saw_first_ts;
AVDictionary *decoder_opts;
AVRational framerate; /* framerate forced with -r */
int top_field_first;
int guess_layout_max;
int autorotate;
...省略字幕相關(guān)字段...
int dr1;
/* decoded data from this stream goes into all those filters
* currently video and audio only */
InputFilter **filters;
int nb_filters;
int reinit_filters;
/* hwaccel options */
...省略硬件解碼相關(guān)字段...
/* hwaccel context */
...省略硬件解碼相關(guān)字段...
/* stats */
// combined size of all the packets read
uint64_t data_size;
/* number of packets successfully read for this stream */
uint64_t nb_packets;
// number of frames/samples retrieved from the decoder
uint64_t frames_decoded;
uint64_t samples_decoded;
int64_t *dts_buffer;
int nb_dts_buffer;
int got_output;
} InputStream;
各個(gè)字段的解析
(省略了字幕相關(guān)的字段):
1, int file_index,input_files 數(shù)組里面的下標(biāo),代表 InputStream 對(duì)應(yīng)的 InputFile。
2, AVStream *st,AVFormatContext 里面的 AVStream 。
3, int discard,如果是 1 會(huì)丟棄讀取到的 AVPacket,剛開(kāi)始的時(shí)候都是 1。例如文件里面有多個(gè)視頻流,會(huì)全部都把 discard 設(shè)置為 1,然后再?gòu)闹羞x出質(zhì)量最好的視頻流,把它的 discard 設(shè)置為 0 。
或者當(dāng)輸出流需要這個(gè)輸入流的時(shí)候,也會(huì)置為 0 ,如下:
if (source_index >= 0) {
ost->sync_ist = input_streams[source_index];
input_streams[source_index]->discard = 0;
input_streams[source_index]->st->discard = input_streams[source_index]->user_set_discard;
}
因此,如果你用 ffmpeg.exe 對(duì)一個(gè)有多個(gè)視頻流的文件進(jìn)行轉(zhuǎn)換,默認(rèn)只會(huì)輸出一個(gè)視頻流。
4, int user_set_discard,命令行選項(xiàng) -discard 的值,默認(rèn)是 AVDISCARD_NONE,可選的值在 AVDiscard 枚舉里面。
enum AVDiscard{
/* We leave some space between them for extensions (drop some
* keyframes for intra-only or drop just some bidir frames). */
AVDISCARD_NONE =-16, ///< discard nothing
AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi
AVDISCARD_NONREF = 8, ///< discard all non reference
AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
AVDISCARD_NONINTRA= 24, ///< discard all non intra frames
AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
AVDISCARD_ALL = 48, ///< discard all
};
5, int decoding_needed,大于 0 代表輸入流需要進(jìn)行解碼操作,有兩個(gè)值,DECODING_FOR_OST ,DECODING_FOR_FILTER
6, AVCodecContext *dec_ctx,解碼器上下文/解碼器實(shí)例,輸入流的 AVPacket 會(huì)丟給解碼實(shí)例進(jìn)行解碼。
7, const AVCodec *dec,解碼器信息
8, AVFrame *decoded_frame,從解碼器上下文 解碼出來(lái)的 AVFrame
9, AVFrame *filter_frame,這個(gè)字段主要是用來(lái)增加引用計(jì)數(shù)的,可能在調(diào)用 av_buffersrc_add_frame_flags() 之后,AVFrame 的引用技術(shù)會(huì)減一,所以需要先復(fù)制一份引用,如下:

10, AVPacket *pkt,從 av_read_frame() 里面讀出來(lái)的 AVPacket,只是復(fù)制了一下引用。

11, int64_t start,記錄此流是什么時(shí)候開(kāi)始處理的,主要是給 -re 選項(xiàng)使用的,模擬幀率速度,錄制視頻模擬直播用的。
12, int64_t next_dts,下一幀的 解碼時(shí)間,這是通過(guò)計(jì)算得到的預(yù)估值,如果讀取出來(lái)的 AVPacket 沒(méi)有 dts ,會(huì)用這個(gè)值代替。
13, int64_t dts,最近一次從 av_read_frame() 讀出來(lái)的 AVPacket 的 dts
14, int64_t next_pts,下一個(gè) AVFrame 的 pts,通過(guò)當(dāng)前 AVFrame 的 pts 加上 duration 計(jì)算出來(lái)的,應(yīng)該是給一些沒(méi)有 pts 值的 AVFrame 用的。
15, int64_t pts,最近一次從解碼器里面解碼出來(lái)的 AVFrame 的 pts,記錄這個(gè)值主要是給 send_filter_eof() 用的,防止回滾。

15, int64_t wrap_correction_done,在一些流格式,例如 TS,會(huì)有時(shí)間戳環(huán)回的問(wèn)題,int64 是有大小限制的,超過(guò)這個(gè)大小會(huì)環(huán)回,ffmpeg.exe 需要處理環(huán)回的邏輯。
16, int64_t filter_in_rescale_delta_last,專門給音頻幀轉(zhuǎn)換時(shí)間基用的,因?yàn)橐纛l的連續(xù)性太強(qiáng),如果有些許誤差需要保存下來(lái),在下次轉(zhuǎn)換的時(shí)候進(jìn)行補(bǔ)償。

17, int64_t min_pts, 從 av_read_frame() 讀出來(lái)的 AVPacket 的最小 pts ,不一定是第一幀的 pts,因?yàn)槊钚袇?shù)通過(guò) -ss 選項(xiàng),指定從哪里開(kāi)始處理。
18, int64_t max_pts,從 av_read_frame() 讀出來(lái)的 AVPacket 的最大 pts ,不一定是最后一幀的 pts,因?yàn)槊钚袇?shù)通過(guò) -t 選項(xiàng),指定只處理多久的時(shí)長(zhǎng)。
19, int64_t cfr_next_pts,給 -r 選項(xiàng)用的。
20, int64_t nb_samples,記錄的是最近一次解碼出來(lái)的 AVFrame 里面的 nb_samples。用途我也不清楚,后面補(bǔ)充。
21, double ts_scale,默認(rèn)值是 1.0,可通過(guò)命令行選項(xiàng) -itsscale 進(jìn)行改變,主要作用是將 pts ,dts 進(jìn)行放大,放大的方法是乘以 ts_scale。
22, int saw_first_ts,標(biāo)記是不是已經(jīng)讀取到屬于該流的第一個(gè) AVPacket
23, AVDictionary *decoder_opts,從 OptionsContext 里面轉(zhuǎn)移過(guò)來(lái)的解碼器參數(shù)。

24, AVRational framerate,命令行選項(xiàng) -r 的值。
25, int top_field_first,命令行選項(xiàng) -top 的值,好像是給隔行掃描視頻用的。
26, int guess_layout_max,命令行選項(xiàng) -guess_layout_max 的值,猜測(cè)的最大的聲道布局。
27, int autorotate,命令行選項(xiàng) -autorotate 的值,是否插入糾正旋轉(zhuǎn)的 filter 濾鏡,有些視頻的畫(huà)面中途會(huì)上下旋轉(zhuǎn),設(shè)置這個(gè)選項(xiàng)可以自動(dòng)糾正旋轉(zhuǎn),不會(huì)上下顛倒。
28, int dr1,用 Find Useage 找不到使用這個(gè)字段的代碼,所以是沒(méi)用的字段。
29, InputFilter **filters 跟 int nb_filters,輸入流綁定的 入口濾鏡,可以是綁定多個(gè)入口濾鏡的,輸入流解碼出來(lái)的 AVFrame 會(huì)往多個(gè)入口濾鏡發(fā)送。
30, int reinit_filters,命令行選項(xiàng) -reinit_filter 的值,0 代表輸入信息如果產(chǎn)生變化也不重新初始化 FilterGraph,輸入信息產(chǎn)生變化是指 解碼出來(lái)的 AVFrame 的寬高中途變大或者變小之類的。reinit_filters 默認(rèn)是 -1,就是會(huì)重新初始化 FilterGraph。
下面這些都是統(tǒng)計(jì)相關(guān)的字段。
31, uint64_t data_size,從 av_read_frame() 讀出來(lái)的 AVPacket 的 size 的總和。也就是統(tǒng)計(jì)當(dāng)前流一共讀出出來(lái)了多少字節(jié)的數(shù)據(jù)。
32, uint64_t nb_packets,從 av_read_frame() 讀出來(lái)的 AVPacket 數(shù)量的總和。
33, uint64_t frames_decoded,uint64_t samples_decoded,從解碼器解碼出來(lái)的 AVFrame 的數(shù)量。
34, int64_t *dts_buffer,int nb_dts_buffer,我沒(méi)看懂這兩個(gè)字段干什么的,可能是舊代碼沒(méi)有刪除。
35, int got_output,只要解碼器已經(jīng)解碼出一幀 AVFrame,這個(gè)字段就會(huì)置為 1。
以上就是InputStream數(shù)據(jù)結(jié)構(gòu)示例解析的詳細(xì)內(nèi)容,更多關(guān)于InputStream 數(shù)據(jù)結(jié)構(gòu)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java設(shè)計(jì)模式——工廠設(shè)計(jì)模式詳解
這篇文章主要介紹了Java設(shè)計(jì)模式——工廠設(shè)計(jì)模式詳解,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
JAVA 日常開(kāi)發(fā)中Websocket示例詳解
JAVA |日常開(kāi)發(fā)中Websocket詳解,WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議,它在Web應(yīng)用中實(shí)現(xiàn)了客戶端與服務(wù)器之間的實(shí)時(shí)數(shù)據(jù)傳輸,本文將詳細(xì)介紹Java開(kāi)發(fā)中WebSocket的使用,包括基本概念、Java API、使用示例以及注意事項(xiàng),感興趣的朋友一起看看吧2024-12-12
Java對(duì)MySQL數(shù)據(jù)庫(kù)進(jìn)行連接、查詢和修改操作方法
這篇文章主要介紹了Java對(duì)MySQL數(shù)據(jù)庫(kù)進(jìn)行連接、查詢和修改操作方法,需要的朋友可以參考下2017-07-07
java ant 配置及構(gòu)建項(xiàng)目圖文教程
以下是對(duì)java ant配置及構(gòu)建項(xiàng)目進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-08-08
springboot2.3.1替換為其他的嵌入式servlet容器的詳細(xì)方法
這篇文章主要介紹了springboot2.3.1替換為其他的嵌入式servlet容器的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07

