【问题标题】:encode x264(libx264) raw yuv frame data编码 x264(libx264) 原始 yuv 帧数据
【发布时间】:2015-03-31 18:57:09
【问题描述】:

我正在尝试使用原始 YUV 帧数据对 MP4 视频进行编码,但我不确定如何填充平面数据(最好不使用 ffmpeg 等其他库)

帧数据已经I420编码,不需要转换。

这是我想要做的:

const char *frameData = /* Raw frame data */;

x264_t *encoder = x264_encoder_open(&param);
x264_picture_t imgInput, imgOutput;
x264_picture_alloc(&imgInput, X264_CSP_I420, width, height);

// how can I fill the struct data of imgInput

x264_nal_t *nals;
int i_nals;
int frameSize = x264_encoder_encode(encoder, &nals, &i_nals, &imgInput, &imgOutput);

我找到的等效命令行是:

 x264 --output video.mp4 --fps 15 --input-res 1280x800 imgdata_01.raw 

但我无法弄清楚应用程序是如何做到的。

谢谢。

【问题讨论】:

  • @mpromonet 我已经检查了这个问题,但示例使用的是swscale,并且也没有提供将现有 YUV 数据映射到 x264_picture_t 的方法。谢谢

标签: c++ c x264 libx264


【解决方案1】:

为了完成上面的答案,这是一个填充x264_picture_t 图像的示例。

int fillImage(uint8_t* buffer, int width, int height, x264_picture_t*pic){
    int ret = x264_picture_alloc(pic, X264_CSP_I420, width, height);
    if (ret < 0) return ret;
    pic->img.i_plane = 3; // Y, U and V
    pic->img.i_stride[0] = width;
    // U and V planes are half the size of Y plane
    pic->img.i_stride[1] = width / 2;
    pic->img.i_stride[2] = width / 2;
    int uvsize = ((width + 1) >> 1) * ((height + 1) >> 1);
    pic->img.plane[0] = buffer; // Y Plane pointer
    pic->img.plane[1] = buffer + (width * height); // U Plane pointer
    pic->img.plane[2] = pic->img.plane[1] + uvsize; // V Plane pointer
    return ret;
}

【讨论】:

  • 这里使用 x264_picture_alloc 是错误的,因为:1)您不需要它,应该使用 x264_picture_init 代替; 2)您的示例中没有 pic_in 的定义; 3) x264_picture_alloc 返回 int(错误代码)。
【解决方案2】:

查看 libx264 API 使用情况example。此示例使用 fread() 使用来自标准输入的实际 i420 数据填充由 x264_picture_alloc() 分配的帧。如果您在内存中已经有 i420 数据并且想要跳过 memcpy 步骤而不是它,您可以:

  1. 使用 x264_picture_init() 代替 x264_picture_alloc() 和 x264_picture_clean()。因为您不需要在堆上为帧数据分配内存。
  2. 填充 x264_picture_t.img 结构字段:
    • i_csp = X264_CSP_I420;
    • i_plane = 3;
    • plane[0] = 指向 Y 平面的指针;
    • i_stride[0] = Y 平面的步幅(以字节为单位);
    • plane[1] = 指向 U 平面的指针;
    • i_stride[1] = U 平面的步幅(以字节为单位);
    • plane[2] = 指向 V 平面的指针;
    • i_stride[2] = V 平面的步幅(以字节为单位);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-22
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多