X264编码器API

时间:2014-04-16 04:54:48

标签: c video encoding h.264 x264

我正在研究用于编码图像的X264 API。

到目前为止,我已经构建了X264库,以下代码片段显示了我的目标:

  int frame_size;
  x264_t* encoder;
  x264_picture_t pic_in, pic_out;
  x264_param_t x264Param;
  int fps = 20;
  int width = 1280;
  int height = 720;
  x264_nal_t* nals;
  int i_nals;

  x264_param_default_preset(&x264Param, "veryfast", "zerolatency");
  x264Param.i_threads = 1;
  x264Param.i_width = 1280;
  x264Param.i_height = 720;
  x264Param.i_fps_num = fps;
  x264Param.i_fps_den = 1;
  x264Param.i_keyint_max = fps;
  x264Param.b_intra_refresh = 1;
  x264Param.rc.i_rc_method = X264_RC_CRF;
  x264Param.rc.f_rf_constant = 25;
  x264Param.rc.f_rf_constant_max = 35;
  x264Param.b_repeat_headers = 1;
  x264Param.b_annexb = 1;
  x264_param_apply_profile(&x264Param, "baseline");

  encoder = x264_encoder_open(&x264Param);

  x264_picture_alloc(&pic_in, X264_CSP_BGR, width, height);

  /* How to fill in bitmap data? */

  frame_size = x264_encoder_encode(encoder, &nals, &i_nals, &pic_in, &pic_out);
  if (frame_size >= 0)
  {
      printf("OK\n");
  }

所以我试图编码24位BGR位图图像。但是,x264头文件没有显示用于将位图图像写入编码器的任何API函数。这是怎么做到的?

修改

此代码段似乎有效。我将很感激审查和一些评论。感谢。

  int frame_size;
  int accum_frame_size;
  x264_t* encoder;
  x264_picture_t pic_in, pic_out;
  x264_param_t x264Param;
  int fps = 20;
  int width = 1280;
  int height = 720;
  x264_nal_t* nals;
  int i_nals;
  int64_t frameCount = 0;
  int k;

  for (k = 0; k < (1280*3*720); k++)
  {
     bgr[k] = rand();
  }

  x264_param_default_preset(&x264Param, "veryfast", "zerolatency");
  x264Param.i_threads = 1;
  x264Param.i_width = 1280;
  x264Param.i_height = 720;
  x264Param.i_fps_num = fps;
  x264Param.i_fps_den = 1;
  x264Param.i_keyint_max = fps;
  x264Param.b_intra_refresh = 1;
  x264Param.rc.i_rc_method = X264_RC_CRF;
  x264Param.i_csp = X264_CSP_BGR;
  x264Param.rc.f_rf_constant = 25;
  x264Param.rc.f_rf_constant_max = 35;
  x264Param.b_repeat_headers = 1;
  x264Param.b_annexb = 1;
  x264_param_apply_profile(&x264Param, "baseline");

  encoder = x264_encoder_open(&x264Param);

  x264_picture_alloc(&pic_in, X264_CSP_BGR, width, height);

  /* Load 24-bit BGR bitmap */
  pic_in.img.i_csp = X264_CSP_BGR;
  pic_in.img.i_plane = 1;
  pic_in.img.i_stride[0] = 3 * 1280;
  pic_in.img.plane[0] = bgr;
  pic_in.i_pts = frameCount;
  pic_in.i_type = X264_TYPE_AUTO;
  pic_out.i_pts = frameCount;

  /* Returns a frame size of 912 for first frame in this case */
  frame_size = x264_encoder_encode(encoder, &nals, &i_nals, &pic_in, &pic_out);

  printf("Decoder returned frame size = %d \n", frame_size);
  printf("Decoder returned %d NAL units \n", i_nals);
  if (frame_size >= 0)
  {
     int i;
     int j;


     accum_frame_size = 0;
     for (i = 0; i < i_nals; i++)
     {
        printf("******************* NAL %d (%d bytes) *******************\n", i, nals[i].i_payload);
        for (j = 0; j < nals[i].i_payload; j++)
        {
           if (j == 0) printf("First 10 bytes: ");
           if (j < 10) printf("%02X |", nals[i].p_payload[j]);
           accum_frame_size++;
        }
        printf("\n");

     }
  }

  printf("Verified frame size = %d \n", accum_frame_size);

编辑#2 编码器输出:

     x264 [error]: baseline profile doesn't support 4:4:4
     x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
     x264 [info]: profile High 4:4:4 Predictive, level 3.1, 4:4:4 8-bit
     Decoder returned frame size = 1467194
     Decoder returned 4 NAL units
     ******************* NAL 0 (31 bytes) *******************
     First 10 bytes: 00 |00 |00 |01 |67 |F4 |00 |1F |91 |89 |
     ******************* NAL 1 (8 bytes) *******************
     First 10 bytes: 00 |00 |00 |01 |68 |EF |1F |2C |
     ******************* NAL 2 (595 bytes) *******************
     First 10 bytes: 00 |00 |01 |06 |05 |FF |FF |4C |DC |45 |
     ******************* NAL 3 (1466560 bytes) *******************
     First 10 bytes: 00 |00 |01 |65 |88 |82 |0A |FF |F5 |B0 |
     Verified frame size = 1467194

不是每个NAL单元都应该以0x00 0x00 0x00 0x01开头吗?

szatmary :感谢您的宝贵意见。所以你说每个NAL单元不一定以0,0,0,1开头。但是,我对你的答案有点不清楚。您是否暗示使用某种配置时,NAL单元以0,0,0,1开头?如果是这样,那是哪种配置?我需要确保我在网络上传输到远程接收器的每个NAL单元都以0,0,0,1开头。在探索x264库之前,我使用了x264 exe和管道BMP数据,并从x264进程中编码出数据。然后,我解析了编码器输出,并通过查找0,0,0,1来查找NAL单位。如何使用x264库完成相同的操作?

关于libswscale:

我下载了ffmpeg源并在MINGW中运行configure和make。在完成该过程后,我找不到除了许多.exe文件之外的任何内容。如何构建可在Visual Studio项目中使用的实际静态库(.lib)?

1 个答案:

答案 0 :(得分:1)

x264无法编码BGR。您必须将图像转换为YUV 4:2:0p。我建议使用ffmpeg项目中的libswscale来执行此操作。

编辑#2

不,起始码至少有两个0x00字节,后跟一个0x01。但它可以有任何数字(但通常是两个或三个空字节)4字节版本用于检测串行传输中的字节相关,通常在SPS和PPS NALU之前。