x264编码时基计算

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了x264编码时基计算相关的知识,希望对你有一定的参考价值。

我有yuv帧,我正在使用libx264成功转换为h264帧。我知道每帧之间的时差。然后我使用以下ffmpeg命令将h264视频文件转换为mp4:

ffmpeg.exe -i frames.h264 -c:v copy -f mp4 frames.mp4

这有效。但是我无法弄清楚如何正确设置可变帧速率。这部电影播放得太快了。我没有固定的帧速率,否则我会设置它,结果mp4是正确的持续时间。

我有每帧之间的时差,以毫秒为单位。如何设置时基和pts,以便在将h264文件转换为mp4时,它是正确的持续时间。

bool X264Encoder::init(int width, int height, 
AVRational &timebase,  // what should timebase be?
int fps)
{
   x264_param_t param;
    if( x264_param_default_preset( &param, "medium", NULL ) < 0 )
    { return false; }

    /* Configure non-default params */
    param.i_bitdepth = 8;
    param.i_csp = X264_CSP_I420;
    param.i_width  = width;
    param.i_height = height;
    param.b_vfr_input = 0;
    param.b_repeat_headers = 1;
    param.b_annexb = 1;
    if(0) // don't have fixed frame rate, can't use it
    {
        param.b_vfr_input = 0;
        param.i_fps_num = 4;
        param.i_fps_den = 1;
    }
    else
    {
        param.b_vfr_input = 1;
        param.i_timebase_num = timebase.den;
        param.i_timebase_den = timebase.num;
    }

    if( x264_param_apply_profile(&param, "high" ) < 0 )
    { return false; }

    m_pic_in = new x264_picture_t;
    x264_picture_init(m_pic_in);
    m_pic_in->img.i_csp = X264_CSP_I420;
    m_pic_in->img.i_plane = 3;

    m_encoder = x264_encoder_open(&param);

}

//This is called for each frame
void X264Encoder::encode(uint8_t *plane[4], int64_t pts) // what should pts be?
{
    m_pic_in->img.plane[0] = plane[0];  // Y frame
    m_pic_in->img.i_stride[0] = m_width;
    m_pic_in->img.plane[1] = plane[1];  // U frame
    m_pic_in->img.i_stride[1] = m_width;
    m_pic_in->img.plane[2] = plane[2];  // V frame
    m_pic_in->img.i_stride[2] = m_width;

    x264_picture_t pic_out;
    m_pic_in->i_pts = pts;
    int frame_size = x264_encoder_encode(m_encoder, &m_nals, &m_i_nals, m_pic_in, &pic_out);

    if(frame_size <= 0)
    {
        return;
    }

    writeH264Frame(m_nals->p_payload, frame_size); // basically same as fwrite
}
答案

通常,时基是帧时间戳的单位,即如果你的第一帧有超过你设置时基1/1000的增量40ms和33ms,并提供pts = 0,40,73。但是原始的H.264(附件B)格式没有时间戳信息,因此仅保存VFR视频是不够的。转换为mp4时需要提供时间戳文件,或者在编码帧的pts / dts信息时需要直接保存到mp4。

以上是关于x264编码时基计算的主要内容,如果未能解决你的问题,请参考以下文章

x264代码剖析(十五):核心算法之宏块编码中的变换编码

x264代码剖析(十七):核心算法之熵编码(Entropy Encoding)

x264代码剖析:主函数main()解析函数parse()与编码函数encode()

H264编码系列之ffmpeg和x264码率控制分析

x264 编码器选项分析 (x264 Codec Strong and Weak Points) 1

x264代码剖析:encode()函数之x264_encoder_open()函数