網(wǎng)站備案信息傳網(wǎng)店推廣聯(lián)盟
libaom
libaom 是 AOMedia(開放媒體聯(lián)盟)開發(fā)的一個開源視頻編解碼器庫,它是 AV1 視頻壓縮格式的參考實(shí)現(xiàn),并被廣泛用于多種生產(chǎn)系統(tǒng)中。libaom 支持多種功能,包括可擴(kuò)展視頻編碼(SVC)、實(shí)時(shí)通信(RTC)優(yōu)化等,并定期進(jìn)行更新以提高壓縮效率和編碼速度 。
libaom 的一些關(guān)鍵特性包括:
- 多空間層和時(shí)間層編碼:通過
aom_svc_layer_id_t
結(jié)構(gòu)體支持空間層和時(shí)間層的ID標(biāo)識,允許視頻在不同的分辨率和幀率下進(jìn)行編碼 。- 編碼參數(shù)配置:通過
aom_svc_params_t
結(jié)構(gòu)體等配置編碼參數(shù),如空間層數(shù)量、時(shí)間層數(shù)量、量化器、縮放因子等 。- 基礎(chǔ)編碼參數(shù):
aom_codec_enc_cfg_t
結(jié)構(gòu)體用于配置編碼器的基礎(chǔ)參數(shù),如使用方式、時(shí)間基準(zhǔn)、編碼通道、幀重采樣等 。- 多遍編碼模式:支持多遍編碼模式,包括單遍、雙遍和多遍編碼,以優(yōu)化編碼效率和質(zhì)量 。
- 幀超分采樣:支持幀超分辨率模式,通過
rc_superres_mode
枚舉值控制放大過程 。- 關(guān)鍵幀放置:支持關(guān)鍵幀放置模式,通過
kf_mode
枚舉值決定是否自動放置關(guān)鍵幀 。- SVC 編碼參數(shù):支持 SVC 編碼的參數(shù)類型配置,如層數(shù)量、量化器、縮放因子等 。
libaom 的更新通常每三個月進(jìn)行一次,最近的更新包括對 SVC 丟幀模式的支持、新的構(gòu)建配置以減小二進(jìn)制文件大小、以及對 RTC 屏幕內(nèi)容壓縮效率的顯著提升 。此外,libaom 還提供了對 AV1 視頻壓縮格式的支持,包括實(shí)時(shí)編碼模式和對不同質(zhì)量控制策略的優(yōu)化 。
twopass_encoder.c 介紹
- 功能:兩遍編碼循環(huán)的 demo 輸入yv12 格式,輸出 ivf 格式。
- 文件位置:libaom/examples/twopass_encoder.c
函數(shù)關(guān)系
結(jié)構(gòu)體
- FILE:文件結(jié)構(gòu)體
- aom_codec_ctx_t:編解碼上下文結(jié)構(gòu)體
- aom_codec_enc_cfg_t:編碼器配置結(jié)構(gòu)體
- aom_image_t:輸入圖像結(jié)構(gòu)體
- aom_codec_err_t:算法返回編碼狀態(tài)碼結(jié)構(gòu)體
- aom_fixed_buf_t:產(chǎn)生固定大小 buffer 結(jié)構(gòu)體
- aom_codec_iface_t:編解碼接口結(jié)構(gòu)體
- AvxVideoInfo:av1 編碼視頻信息結(jié)構(gòu)體
- AvxVideoWriter:視頻信息寫入結(jié)構(gòu)體
2pass 編碼原理
- 數(shù)據(jù)流轉(zhuǎn)圖
- 核心原理:第一遍編碼產(chǎn)生的aom_fixed_buf_t數(shù)據(jù)賦值給aom_codec_enc_cfg_t中的 rc_twopass_stats_in(aom_fixed_buf_t) 供第二遍編碼使用;
- aom_fixed_buf_t 結(jié)構(gòu)體:
/*!\brief Generic fixed size buffer structure** This structure is able to hold a reference to any fixed size buffer.*/
typedef struct aom_fixed_buf {void *buf; /**< Pointer to the data. Does NOT own the data! */size_t sz; /**< Length of the buffer, in chars */
} aom_fixed_buf_t; /**< alias for struct aom_fixed_buf */
- 在 pass0 函數(shù)中的get_frame_stats函數(shù)對aom_fixed_buf_t結(jié)構(gòu)體進(jìn)行賦值;
static int get_frame_stats(aom_codec_ctx_t *ctx, const aom_image_t *img,aom_codec_pts_t pts, unsigned int duration,aom_enc_frame_flags_t flags,aom_fixed_buf_t *stats) {int got_pkts = 0;aom_codec_iter_t iter = NULL;const aom_codec_cx_pkt_t *pkt = NULL;const aom_codec_err_t res = aom_codec_encode(ctx, img, pts, duration, flags);if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to get frame stats.");while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {got_pkts = 1;if (pkt->kind == AOM_CODEC_STATS_PKT) {const uint8_t *const pkt_buf = pkt->data.twopass_stats.buf;const size_t pkt_size = pkt->data.twopass_stats.sz;stats->buf = realloc(stats->buf, stats->sz + pkt_size);if (!stats->buf) die("Failed to allocate frame stats buffer.");memcpy((uint8_t *)stats->buf + stats->sz, pkt_buf, pkt_size);stats->sz += pkt_size;}}return got_pkts;
}
- 在函數(shù) set_encoder_config 中對aom_codec_enc_cfg_t中的 rc_twopass_stats_in(aom_fixed_buf_t) 進(jìn)行應(yīng)用;根據(jù)aom_fixed_buf_t的 sz 大小除以每個包的狀態(tài)大小FIRSTPASS_STATS,作為輸入配置中的 limit 變量的值;
if (cfg->g_pass >= AOM_RC_SECOND_PASS) {const size_t packet_sz = sizeof(FIRSTPASS_STATS);const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);input_cfg->limit = n_packets - 1;} else {input_cfg->limit = cfg->g_limit;}
- 在 validate_config 函數(shù)中對FIRSTPASS_STATS進(jìn)行賦值,用來訪問第一遍編碼的統(tǒng)計(jì)信息。
if (cfg->g_pass >= AOM_RC_SECOND_PASS) {const size_t packet_sz = sizeof(FIRSTPASS_STATS);const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);const FIRSTPASS_STATS *stats;if (cfg->rc_twopass_stats_in.buf == NULL)ERROR("rc_twopass_stats_in.buf not set.");if (cfg->rc_twopass_stats_in.sz % packet_sz)ERROR("rc_twopass_stats_in.sz indicates truncated packet.");if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)ERROR("rc_twopass_stats_in requires at least two packets.");stats =(const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;if ((int)(stats->count + 0.5) != n_packets - 1)ERROR("rc_twopass_stats_in missing EOS stats packet");}
- FIRSTPASS_STATS的定義如下,這個結(jié)構(gòu)體用于在視頻編碼的第一遍(分析遍)中累積幀統(tǒng)計(jì)信息。這些統(tǒng)計(jì)數(shù)據(jù)有助于在第二遍(編碼遍)中優(yōu)化碼率分配和提高編碼質(zhì)量,該結(jié)構(gòu)體包含了幀、權(quán)重、mv 相關(guān)、幀編碼信息等等變量。
/*!* \brief The stucture of acummulated frame stats in the first pass.** Errors (coded_error, intra_error, etc.) and counters (new_mv_count) are* normalized to each MB. MV related stats (MVc, MVr, etc.) are normalized to* the frame width and height. See function normalize_firstpass_stats.*/
typedef struct FIRSTPASS_STATS {/*!* Frame number in display order, if stats are for a single frame.* No real meaning for a collection of frames.*/double frame;/*!* Weight assigned to this frame (or total weight for the collection of* frames) currently based on intra factor and brightness factor. This is used* to distribute bits betweeen easier and harder frames.*/double weight;/*!* Intra prediction error.*/double intra_error;/*!* Average wavelet energy computed using Discrete Wavelet Transform (DWT).*/double frame_avg_wavelet_energy;/*!* Best of intra pred error and inter pred error using last frame as ref.*/double coded_error;/*!* Best of intra pred error and inter pred error using golden frame as ref.*/double sr_coded_error;/*!* Percentage of blocks with inter pred error < intra pred error.*/double pcnt_inter;/*!* Percentage of blocks using (inter prediction and) non-zero motion vectors.*/double pcnt_motion;/*!* Percentage of blocks where golden frame was better than last or intra:* inter pred error using golden frame < inter pred error using last frame and* inter pred error using golden frame < intra pred error*/double pcnt_second_ref;/*!* Percentage of blocks where intra and inter prediction errors were very* close. Note that this is a 'weighted count', that is, the so blocks may be* weighted by how close the two errors were.*/double pcnt_neutral;/*!* Percentage of blocks that have almost no intra error residual* (i.e. are in effect completely flat and untextured in the intra* domain). In natural videos this is uncommon, but it is much more* common in animations, graphics and screen content, so may be used* as a signal to detect these types of content.*/double intra_skip_pct;/*!* Image mask rows top and bottom.*/double inactive_zone_rows;/*!* Image mask columns at left and right edges.*/double inactive_zone_cols;/*!* Average of row motion vectors.*/double MVr;/*!* Mean of absolute value of row motion vectors.*/double mvr_abs;/*!* Mean of column motion vectors.*/double MVc;/*!* Mean of absolute value of column motion vectors.*/double mvc_abs;/*!* Variance of row motion vectors.*/double MVrv;/*!* Variance of column motion vectors.*/double MVcv;/*!* Value in range [-1,1] indicating fraction of row and column motion vectors* that point inwards (negative MV value) or outwards (positive MV value).* For example, value of 1 indicates, all row/column MVs are inwards.*/double mv_in_out_count;/*!* Count of unique non-zero motion vectors.*/double new_mv_count;/*!* Duration of the frame / collection of frames.*/double duration;/*!* 1.0 if stats are for a single frame, OR* Number of frames in this collection for which the stats are accumulated.*/double count;/*!* standard deviation for (0, 0) motion prediction error*/double raw_error_stdev;/*!* Whether the frame contains a flash*/int64_t is_flash;/*!* Estimated noise variance*/double noise_var;/*!* Correlation coefficient with the previous frame*/double cor_coeff;/*!* log of intra_error*/double log_intra_error;/*!* log of coded_error*/double log_coded_error;
} FIRSTPASS_STATS;