libyuv API MJPGToI420()

时间:2018-07-25 01:49:45

标签: image-processing jpeg yuv mjpeg libyuv

我正在尝试使用libyuv API,更具体地说是MJPGToI420()

我想首先将jpeg图像作为MJPGToI420()的输入,其签名如下:

int MJPGToI420(const uint8_t* sample,
               size_t sample_size,
               uint8_t* dst_y,
               int dst_stride_y,
               uint8_t* dst_u,
               int dst_stride_u,
               uint8_t* dst_v,
               int dst_stride_v,
               int src_width,
               int src_height,
               int dst_width,
               int dst_height);

然后,我想为dst_ydst_udst_v指针分配空间。但是,我不知道要为它们分配多少空间。对于步幅应该是什么,也就是参数dst_stride_ydst_stride_udst_stride_v应该是什么,我也感到困惑。

真的很感谢任何朝着正确方向提出的建议。

编辑:这是来自libyuvunit tests的使用此功能的代码段。但是,测试返回1,这是功能的失败,是预期的行为。该测试还只对数据使用零,而不是实际的MJPG文件。

TEST_F(LibYUVConvertTest, MJPGToI420) {
  const int kOff = 10;
  const int kMinJpeg = 64;
  const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg
                             ? benchmark_width_ * benchmark_height_
                             : kMinJpeg;
  const int kSize = kImageSize + kOff;
  align_buffer_page_end(orig_pixels, kSize);
  align_buffer_page_end(dst_y_opt, benchmark_width_ * benchmark_height_);
  align_buffer_page_end(dst_u_opt, SUBSAMPLE(benchmark_width_, 2) *
                                       SUBSAMPLE(benchmark_height_, 2));
  align_buffer_page_end(dst_v_opt, SUBSAMPLE(benchmark_width_, 2) *
                                       SUBSAMPLE(benchmark_height_, 2));

  // EOI, SOI to make MJPG appear valid.
  memset(orig_pixels, 0, kSize);
  orig_pixels[0] = 0xff;
  orig_pixels[1] = 0xd8;  // SOI.
  orig_pixels[kSize - kOff + 0] = 0xff;
  orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.

  for (int times = 0; times < benchmark_iterations_; ++times) {
    int ret =
        MJPGToI420(orig_pixels, kSize, dst_y_opt, benchmark_width_, dst_u_opt,
                   SUBSAMPLE(benchmark_width_, 2), dst_v_opt,
                   SUBSAMPLE(benchmark_width_, 2), benchmark_width_,
                   benchmark_height_, benchmark_width_, benchmark_height_);
    // Expect failure because image is not really valid.
    EXPECT_EQ(1, ret);
  }

  free_aligned_buffer_page_end(dst_y_opt);
  free_aligned_buffer_page_end(dst_u_opt);
  free_aligned_buffer_page_end(dst_v_opt);
  free_aligned_buffer_page_end(orig_pixels);
}

编辑2:此外,这是我尝试过的方法,但是,最终yuv文件甚至无法在yuv查看器中查看(使用缓冲区dst_u_opt和{{ 1}}),这使我相信该函数可能有些混乱:

dst_y_opt

1 个答案:

答案 0 :(得分:1)

您需要知道jpeg的宽度和高度。

I420是420个子采样的YUV。 Y平面是宽度*高度(以字节为单位)。 dst_stride_y的值是width 例如

char* dst_y = malloc(width * height);

U和V平面是宽度和高度的一半。要处理奇数大小,您应该四舍五入。

dst_stride_u = (width + 1) / 2;
dst_stride_v = (width + 1) / 2;

u和v平面为((宽度+ 1)/ 2)*((高度+ 1)/ 2)字节。

char* dst_u = malloc(((width + 1) / 2) * ((height + 1) / 2));
char* dst_y = malloc(((width + 1) / 2) * ((height + 1) / 2));

如果您要提交问题,包括更好的文档,请在此处发布: https://bugs.chromium.org/p/libyuv/issues/list