mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-22 08:52:20 +08:00
AI automatically translates all comments in the code into English (#3917)
This commit is contained in:
@@ -19,7 +19,8 @@ namespace mediakit {
|
||||
H264Encoder::H264Encoder() {}
|
||||
|
||||
H264Encoder::~H264Encoder() {
|
||||
//* 清除图像区域
|
||||
// * 清除图像区域 [AUTO-TRANSLATED:6b316309]
|
||||
// * Clear image area
|
||||
if (_pPicIn) {
|
||||
delete _pPicIn;
|
||||
_pPicIn = nullptr;
|
||||
@@ -29,7 +30,8 @@ H264Encoder::~H264Encoder() {
|
||||
_pPicOut = nullptr;
|
||||
}
|
||||
|
||||
//* 关闭编码器句柄
|
||||
// * 关闭编码器句柄 [AUTO-TRANSLATED:bf4a14e5]
|
||||
// * Close encoder handle
|
||||
if (_pX264Handle) {
|
||||
x264_encoder_close(_pX264Handle);
|
||||
_pX264Handle = nullptr;
|
||||
@@ -206,6 +208,178 @@ Value的值就是fps。
|
||||
* i.e. when an x264_param_t is passed to x264_t in an x264_picture_t or in zones.
|
||||
* Not used when x264_encoder_reconfig is called directly.
|
||||
void (*param_free)( void* );
|
||||
/*typedef struct x264_param_t
|
||||
{
|
||||
CPU flag bit
|
||||
unsigned int cpu;
|
||||
int i_threads; Parallel encoding of multiple frames
|
||||
int b_deterministic; Whether to allow non-deterministic thread optimization
|
||||
int i_sync_lookahead; Thread pre-buffering
|
||||
|
||||
Video attributes
|
||||
int i_width; Width
|
||||
int i_height; Height
|
||||
int i_csp; CSP of the encoded bitstream, only supports i420, color space setting
|
||||
int i_level_idc; Setting of the level value
|
||||
int i_frame_total; Total number of encoded frames, default 0
|
||||
Vui parameter set video availability information video standardization options
|
||||
struct
|
||||
{
|
||||
they will be reduced to be 0 < x <= 65535 and prime
|
||||
int i_sar_height;
|
||||
int i_sar_width; Set aspect ratio
|
||||
|
||||
int i_overscan; 0=undef, 1=no overscan, 2=overscan Overscan lines, default "undef" (not set), options: show (watch) / crop (remove)
|
||||
|
||||
See the following value h264 appendix E
|
||||
Int i_vidformat; Video format, default "undef", component/pal/ntsc/secam/mac/undef
|
||||
int b_fullrange; Specify full range samples setting, default "off", options: off/on
|
||||
int i_colorprim; Original chroma format, default "undef", options: undef/bt709/bt470m/bt470bg, smpte170m/smpte240m/film
|
||||
int i_transfer; Conversion method, default "undef", options: undef/bt709/bt470m/bt470bg/linear,log100/log316/smpte170m/smpte240m
|
||||
int i_colmatrix; Chroma matrix setting, default "undef", undef/bt709/fcc/bt470bg, smpte170m/smpte240m/GBR/YCgCo
|
||||
int i_chroma_loc; both top & bottom chroma samples specified, range 0~5, default 0
|
||||
} vui;
|
||||
|
||||
int i_fps_num;
|
||||
int i_fps_den;
|
||||
These two parameters are determined by the fps frame rate, the assignment process is as follows:
|
||||
{ float fps;
|
||||
if( sscanf( value, "%d/%d", &p->i_fps_num, &p->i_fps_den ) == 2 )
|
||||
;
|
||||
else if( sscanf( value, "%f", &fps ) )
|
||||
{
|
||||
p->i_fps_num = (int)(fps * 1000 + .5);
|
||||
p->i_fps_den = 1000;
|
||||
}
|
||||
else
|
||||
b_error = 1;
|
||||
}
|
||||
The value of Value is fps.
|
||||
|
||||
Stream parameters
|
||||
int i_frame_reference; Maximum number of reference frames
|
||||
int i_keyint_max; Set IDR keyframe at this interval
|
||||
int i_keyint_min; Scene switching less than this value encodes as I, not IDR.
|
||||
int i_scenecut_threshold; How actively to insert additional I frames
|
||||
int i_bframe; Number of P frames between two related images
|
||||
int i_bframe_adaptive; Adaptive B frame determination
|
||||
int i_bframe_bias; Control the insertion of B frame determination, range -100~+100, the higher the easier it is to insert B frame, default 0
|
||||
int b_bframe_pyramid; Allow some B to be reference frames
|
||||
Parameters required for deblocking filter
|
||||
int b_deblocking_filter;
|
||||
int i_deblocking_filter_alphac0; [-6, 6] -6 light filter, 6 strong
|
||||
int i_deblocking_filter_beta; [-6, 6] idem
|
||||
Entropy coding
|
||||
int b_cabac;
|
||||
int i_cabac_init_idc;
|
||||
|
||||
int b_interlaced; Interlaced scanning
|
||||
Quantization
|
||||
int i_cqm_preset; Custom quantization matrix (CQM), initialize quantization mode to flat
|
||||
char *psz_cqm_file; JM format reads external quantization matrix file in JM format, automatically ignores other —cqm options
|
||||
uint8_t cqm_4iy[16]; used only if i_cqm_preset == X264_CQM_CUSTOM
|
||||
uint8_t cqm_4ic[16];
|
||||
uint8_t cqm_4py[16];
|
||||
uint8_t cqm_4pc[16];
|
||||
uint8_t cqm_8iy[64];
|
||||
uint8_t cqm_8py[64];
|
||||
|
||||
Log
|
||||
void (*pf_log)( void *, int i_level, const char *psz, va_list );
|
||||
void *p_log_private;
|
||||
int i_log_level;
|
||||
int b_visualize;
|
||||
char *psz_dump_yuv; Name of the reconstructed frame
|
||||
|
||||
Encoding analysis parameters
|
||||
struct
|
||||
{
|
||||
unsigned int intra; Inter-frame partition
|
||||
unsigned int inter; Intra-frame partition
|
||||
|
||||
int b_transform_8x8; Inter-frame partition
|
||||
int b_weighted_bipred; Implicit weighting for b frames
|
||||
int i_direct_mv_pred; Time-space motion prediction
|
||||
int i_chroma_qp_offset; Chroma quantization step offset
|
||||
|
||||
int i_me_method; Motion estimation algorithm (X264_ME_*)
|
||||
int i_me_range; Integer pixel motion estimation search range (from predicted mv)
|
||||
int i_mv_range; Maximum length of motion vector (in pixels). -1 = auto, based on level
|
||||
int i_mv_range_thread; Minimum space between threads. -1 = auto, based on number of threads.
|
||||
int i_subpel_refine; Sub-pixel motion estimation quality
|
||||
int b_chroma_me; Sub-pixel chroma motion estimation and mode selection for P frames
|
||||
int b_mixed_references; Allow each macroblock partition in the P frame to have its own reference number
|
||||
int i_trellis; Trellis quantization, find the appropriate quantization value for each 8x8 block, requires CABAC, default 0 0: off 1: use only at the end of encoding 2: always use
|
||||
int b_fast_pskip; Fast P frame skip detection
|
||||
int b_dct_decimate; Transform parameter domain in P-frames
|
||||
int i_noise_reduction; Adaptive pseudo-blind area
|
||||
float f_psy_rd; Psy RD strength
|
||||
float f_psy_trellis; Psy trellis strength
|
||||
int b_psy; Toggle all psy optimizations
|
||||
|
||||
, the size of the invalid area used in luminance quantization
|
||||
int i_luma_deadzone[2]; {Inter-frame, Intra-frame}
|
||||
|
||||
int b_psnr; Calculate and print PSNR information
|
||||
int b_ssim; Calculate and print SSIM information
|
||||
} analyse;
|
||||
|
||||
Bitrate control parameters
|
||||
struct
|
||||
{
|
||||
int i_rc_method; X264_RC_*
|
||||
|
||||
int i_qp_constant; 0-51
|
||||
int i_qp_min; Minimum quantization value allowed
|
||||
int i_qp_max; Maximum quantization value allowed
|
||||
int i_qp_step; Maximum quantization step between frames
|
||||
|
||||
int i_bitrate; Set average bitrate
|
||||
float f_rf_constant; 1pass VBR, nominal QP
|
||||
float f_rate_tolerance;
|
||||
int i_vbv_max_bitrate; In average bitrate mode, the maximum instantaneous bitrate, default 0 (same as -B setting)
|
||||
int i_vbv_buffer_size; Size of the bitrate control buffer, unit kbit, default 0
|
||||
float f_vbv_buffer_init; <=1: fraction of buffer_size. >1: kbit bitrate control buffer data retention maximum data amount ratio to buffer size, range 0~1.0, default 0.9
|
||||
float f_ip_factor;
|
||||
float f_pb_factor;
|
||||
|
||||
int i_aq_mode; psy adaptive QP. (X264_AQ_*)
|
||||
float f_aq_strength;
|
||||
int b_mb_tree; Macroblock-tree ratecontrol.
|
||||
int i_lookahead;
|
||||
|
||||
2pass multiple compression bitrate control
|
||||
int b_stat_write; Enable stat writing in psz_stat_out
|
||||
char *psz_stat_out;
|
||||
int b_stat_read; Read stat from psz_stat_in and use it
|
||||
char *psz_stat_in;
|
||||
|
||||
2pass params (same as ffmpeg ones)
|
||||
float f_qcompress; 0.0 => cbr, 1.0 => constant qp
|
||||
float f_qblur; Quantization blur over time
|
||||
float f_complexity_blur; Complexity blur over time
|
||||
x264_zone_t *zones; Bitrate control coverage
|
||||
int i_zones; number of zone_t's
|
||||
char *psz_zones; Another way to specify the zone
|
||||
} rc;
|
||||
|
||||
Muxing parameters
|
||||
int b_aud; Generate access unit delimiter
|
||||
int b_repeat_headers; Place SPS/PPS before each keyframe
|
||||
int i_sps_id; SPS and PPS id number
|
||||
|
||||
Slice (like strip) parameters
|
||||
int i_slice_max_size; Maximum number of bytes per slice, including expected NAL overhead.
|
||||
int i_slice_max_mbs; Maximum number of macroblocks per slice, overwrite i_slice_count
|
||||
int i_slice_count; Number of strips per frame: Set rectangular strips.
|
||||
|
||||
Optional callback for freeing this x264_param_t when it is done being used.
|
||||
* Only used when the x264_param_t sits in memory for an indefinite period of time,
|
||||
* i.e. when an x264_param_t is passed to x264_t in an x264_picture_t or in zones.
|
||||
* Not used when x264_encoder_reconfig is called directly.
|
||||
void (*param_free)( void* );
|
||||
} x264_param_t;
|
||||
* [AUTO-TRANSLATED:b730fe72]
|
||||
} x264_param_t;*/
|
||||
|
||||
bool H264Encoder::init(int iWidth, int iHeight, int iFps, int iBitRate) {
|
||||
@@ -213,8 +387,10 @@ bool H264Encoder::init(int iWidth, int iHeight, int iFps, int iBitRate) {
|
||||
return true;
|
||||
}
|
||||
x264_param_t X264Param, *pX264Param = &X264Param;
|
||||
//* 配置参数
|
||||
//* 使用默认参数
|
||||
// * 配置参数 [AUTO-TRANSLATED:1629898c]
|
||||
// * Configure parameters
|
||||
// * 使用默认参数 [AUTO-TRANSLATED:db7658e2]
|
||||
// * Use default parameters
|
||||
x264_param_default_preset(pX264Param, "ultrafast", "zerolatency");
|
||||
|
||||
//* cpuFlags
|
||||
@@ -233,13 +409,18 @@ bool H264Encoder::init(int iWidth, int iHeight, int iFps, int iBitRate) {
|
||||
pX264Param->rc.f_qcompress = 0.6;//ffmpeg:qcompress 量化器压缩比率0-1.越小则比特率越区域固定,但是越高越使量化器参数越固定
|
||||
pX264Param->analyse.i_me_range = 16; //ffmpeg:me_range 运动侦测的半径
|
||||
pX264Param->i_frame_reference = 3; //ffmpeg:refsB和P帧向前预测参考的帧数。取值范围1-16。
|
||||
//该值不影响解码的速度,但是越大解码
|
||||
//所需的内存越大。这个值在一般情况下
|
||||
//越大效果越好,但是超过6以后效果就
|
||||
//不明显了。
|
||||
// 该值不影响解码的速度,但是越大解码 [AUTO-TRANSLATED:23eb12ae]
|
||||
// This value does not affect the decoding speed, but the larger the decoding
|
||||
// 所需的内存越大。这个值在一般情况下 [AUTO-TRANSLATED:3ff4f036]
|
||||
// The more memory required. This value is generally
|
||||
// 越大效果越好,但是超过6以后效果就 [AUTO-TRANSLATED:3252f33a]
|
||||
// The better the effect, but the effect is not obvious after 6
|
||||
// 不明显了。 [AUTO-TRANSLATED:d654ba67]
|
||||
// It's not obvious.
|
||||
|
||||
pX264Param->analyse.i_trellis = 1; //ffmpeg:trellis
|
||||
//pX264Param->analyse.i_me_method=X264_ME_DIA;//ffmpeg:me_method ME_ZERO 运动侦测的方式
|
||||
// pX264Param->analyse.i_me_method=X264_ME_DIA;//ffmpeg:me_method ME_ZERO 运动侦测的方式 [AUTO-TRANSLATED:24c6240d]
|
||||
// pX264Param->analyse.i_me_method=X264_ME_DIA;//ffmpeg:me_method ME_ZERO Motion detection method
|
||||
pX264Param->rc.f_qblur = 0.5; //ffmpeg:qblur
|
||||
|
||||
//* bitstream parameters
|
||||
@@ -262,6 +443,27 @@ bool H264Encoder::init(int iWidth, int iHeight, int iFps, int iBitRate) {
|
||||
如果一个GOP的最后一帧(上例中是第5帧)设置为B帧,
|
||||
这个码流就是open-GOP,设置为P帧就是close-GOP。
|
||||
由于B帧压缩性能好于P帧,因此open-GOP在编码性能上稍微优于close-GOP,
|
||||
/*open-GOP
|
||||
open-GOP only appears when the bitstream contains B frames.
|
||||
A frame in a GOP needs to rely on some frames in the previous GOP when decoding,
|
||||
This GOP is called open-GOP.
|
||||
Some decoders do not fully support open-GOP bitstreams,
|
||||
For example, Blu-ray decoders, so open-GOP is disabled by default in x264.
|
||||
For the decoding end, if the received bitstream is as follows: I0 B0 B1 P0 B2 B3... This is an open-GOP bitstream (I frame followed by B frame).
|
||||
Therefore, the decoding of B0 B1 needs to use the data of the GOP before I0, and the dts of B0 B1 is less than that of I0.
|
||||
If the bitstream is as follows: I0 P0 B0 B1 P1 B2 B3... This is a close-GOP bitstream,
|
||||
The decoding of all frames after I0 does not depend on the frames before I0, and the dts of all frames after I0 is greater than that of I0.
|
||||
If the bitstream is IDR0 B0 B1 P0 B2 B3... then this GOP is close-GOP, although the dst of B0, B1 is smaller than that of IDR0,
|
||||
But both the encoder and decoder refresh the reference buffer, B0, B1 cannot refer to the forward GOP frame.
|
||||
For the encoding end, if the encoding frame type is determined as follows: ...P0 B1 B2 P3 B4 B5 I6 This will output an open-Gop bitstream (P0 P3 B1 B2 I6 B4 B5...),
|
||||
The decoding of B4 B5 depends on P3.
|
||||
If the encoding frame type is determined as follows...P0 B1 B2 P3 B4 P5 I6, then this will not output an open-GOP bitstream (P0 P3 B1 B2 P5 B4 I6...).
|
||||
The difference between the two is whether the 5th frame before I6 is set to B frame or P frame,
|
||||
If the last frame of a GOP (the 5th frame in the example above) is set to B frame,
|
||||
This bitstream is open-GOP, and setting it to P frame is close-GOP.
|
||||
Since B frames have better compression performance than P frames, open-GOP performs slightly better than close-GOP in terms of encoding performance,
|
||||
But for compatibility and less trouble, it's better to turn off opne-GOP.
|
||||
* [AUTO-TRANSLATED:6ccfc922]
|
||||
但为了兼容性和少一些麻烦,还是把opne-GOP关闭的好。*/
|
||||
pX264Param->b_open_gop = 0;
|
||||
pX264Param->i_bframe = 0; //最大B帧数.
|
||||
@@ -282,11 +484,14 @@ bool H264Encoder::init(int iWidth, int iHeight, int iFps, int iBitRate) {
|
||||
pX264Param->b_annexb = 1; //1前面为0x00000001,0为nal长度
|
||||
pX264Param->b_repeat_headers = 1; //关键帧前面是否放sps跟pps帧,0 否 1,放
|
||||
|
||||
//* 设置Profile.使用baseline
|
||||
// * 设置Profile.使用baseline [AUTO-TRANSLATED:c451b8a5]
|
||||
// * Set Profile. Use baseline
|
||||
x264_param_apply_profile(pX264Param, "high");
|
||||
|
||||
//* 打开编码器句柄,通过x264_encoder_parameters得到设置给X264
|
||||
//* 的参数.通过x264_encoder_reconfig更新X264的参数
|
||||
// * 打开编码器句柄,通过x264_encoder_parameters得到设置给X264 [AUTO-TRANSLATED:e52faa11]
|
||||
// * Open encoder handle, get the settings for X264 through x264_encoder_parameters
|
||||
// * 的参数.通过x264_encoder_reconfig更新X264的参数 [AUTO-TRANSLATED:83b929df]
|
||||
// * Parameters. Update the parameters of X264 through x264_encoder_reconfig
|
||||
_pX264Handle = x264_encoder_open(pX264Param);
|
||||
if (!_pX264Handle) {
|
||||
return false;
|
||||
|
||||
@@ -88,7 +88,8 @@ static bool checkIfSupportedNvidia_l() {
|
||||
bool find_driver = false;
|
||||
File::scanDir("/dev", [&](const string &path, bool is_dir) {
|
||||
if (!is_dir && start_with(path, "/dev/nvidia")) {
|
||||
//找到nvidia的驱动
|
||||
// 找到nvidia的驱动 [AUTO-TRANSLATED:5b87bf81]
|
||||
// Find the Nvidia driver
|
||||
find_driver = true;
|
||||
return false;
|
||||
}
|
||||
@@ -403,7 +404,8 @@ FFmpegDecoder::FFmpegDecoder(const Track::Ptr &track, int thread_num, const std:
|
||||
throw std::runtime_error("创建解码器失败");
|
||||
}
|
||||
|
||||
//保存AVFrame的引用
|
||||
// 保存AVFrame的引用 [AUTO-TRANSLATED:2df53d07]
|
||||
// Save the AVFrame reference
|
||||
#ifdef FF_API_OLD_ENCDEC
|
||||
_context->refcounted_frames = 1;
|
||||
#endif
|
||||
@@ -441,7 +443,8 @@ FFmpegDecoder::FFmpegDecoder(const Track::Ptr &track, int thread_num, const std:
|
||||
_context->flags |= AV_CODEC_FLAG_TRUNCATED;
|
||||
_do_merger = false;
|
||||
} else {
|
||||
// 此时业务层应该需要合帧
|
||||
// 此时业务层应该需要合帧 [AUTO-TRANSLATED:8dea0fff]
|
||||
// The business layer should need to merge frames at this time
|
||||
_do_merger = true;
|
||||
}
|
||||
#endif
|
||||
@@ -449,13 +452,15 @@ FFmpegDecoder::FFmpegDecoder(const Track::Ptr &track, int thread_num, const std:
|
||||
int ret = avcodec_open2(_context.get(), codec, &dict);
|
||||
av_dict_free(&dict);
|
||||
if (ret >= 0) {
|
||||
//成功
|
||||
// 成功 [AUTO-TRANSLATED:7d878ca9]
|
||||
// Success
|
||||
InfoL << "打开解码器成功:" << codec->name;
|
||||
break;
|
||||
}
|
||||
|
||||
if (codec_default && codec_default != codec) {
|
||||
//硬件编解码器打开失败,尝试软件的
|
||||
// 硬件编解码器打开失败,尝试软件的 [AUTO-TRANSLATED:060200f4]
|
||||
// Hardware codec failed to open, try software codec
|
||||
WarnL << "打开解码器" << codec->name << "失败,原因是:" << ffmpeg_err(ret) << ", 再尝试打开解码器" << codec_default->name;
|
||||
codec = codec_default;
|
||||
continue;
|
||||
@@ -507,7 +512,8 @@ bool FFmpegDecoder::inputFrame_l(const Frame::Ptr &frame, bool live, bool enable
|
||||
|
||||
bool FFmpegDecoder::inputFrame(const Frame::Ptr &frame, bool live, bool async, bool enable_merge) {
|
||||
if (async && !TaskManager::isEnabled() && getContext()->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
//开启异步编码,且为视频,尝试启动异步解码线程
|
||||
// 开启异步编码,且为视频,尝试启动异步解码线程 [AUTO-TRANSLATED:17a68fc6]
|
||||
// Enable asynchronous encoding, and it is video, try to start asynchronous decoding thread
|
||||
startThread("decoder thread");
|
||||
}
|
||||
|
||||
@@ -518,7 +524,8 @@ bool FFmpegDecoder::inputFrame(const Frame::Ptr &frame, bool live, bool async, b
|
||||
auto frame_cache = Frame::getCacheAbleFrame(frame);
|
||||
return addDecodeTask(frame->keyFrame(), [this, live, frame_cache, enable_merge]() {
|
||||
inputFrame_l(frame_cache, live, enable_merge);
|
||||
//此处模拟解码太慢导致的主动丢帧
|
||||
// 此处模拟解码太慢导致的主动丢帧 [AUTO-TRANSLATED:fc8bea8a]
|
||||
// Here simulates decoding too slow, resulting in active frame dropping
|
||||
//usleep(100 * 1000);
|
||||
});
|
||||
}
|
||||
@@ -554,7 +561,8 @@ bool FFmpegDecoder::decodeFrame(const char *data, size_t size, uint64_t dts, uin
|
||||
break;
|
||||
}
|
||||
if (live && pts - out_frame->get()->pts > MAX_DELAY_SECOND * 1000 && _ticker.createdTime() > 10 * 1000) {
|
||||
//后面的帧才忽略,防止Track无法ready
|
||||
// 后面的帧才忽略,防止Track无法ready [AUTO-TRANSLATED:23f1a7c9]
|
||||
// The following frames are ignored to prevent the Track from being ready
|
||||
WarnL << "解码时,忽略" << MAX_DELAY_SECOND << "秒前的数据:" << pts << " " << out_frame->get()->pts;
|
||||
continue;
|
||||
}
|
||||
@@ -593,7 +601,8 @@ FFmpegFrame::Ptr FFmpegSwr::inputFrame(const FFmpegFrame::Ptr &frame) {
|
||||
frame->get()->channels == _target_channels &&
|
||||
frame->get()->channel_layout == (uint64_t)_target_channel_layout &&
|
||||
frame->get()->sample_rate == _target_samplerate) {
|
||||
//不转格式
|
||||
// 不转格式 [AUTO-TRANSLATED:31dc6ae1]
|
||||
// Do not convert format
|
||||
return frame;
|
||||
}
|
||||
if (!_ctx) {
|
||||
@@ -655,11 +664,13 @@ FFmpegFrame::Ptr FFmpegSws::inputFrame(const FFmpegFrame::Ptr &frame, int &ret,
|
||||
auto target_width = _target_width ? _target_width : frame->get()->width;
|
||||
auto target_height = _target_height ? _target_height : frame->get()->height;
|
||||
if (frame->get()->format == _target_format && frame->get()->width == target_width && frame->get()->height == target_height) {
|
||||
//不转格式
|
||||
// 不转格式 [AUTO-TRANSLATED:31dc6ae1]
|
||||
// Do not convert format
|
||||
return frame;
|
||||
}
|
||||
if (_ctx && (_src_width != frame->get()->width || _src_height != frame->get()->height || _src_format != (enum AVPixelFormat) frame->get()->format)) {
|
||||
//输入分辨率发生变化了
|
||||
// 输入分辨率发生变化了 [AUTO-TRANSLATED:0e4ea2e8]
|
||||
// Input resolution has changed
|
||||
sws_freeContext(_ctx);
|
||||
_ctx = nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user