• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            使用libx264將I420編碼為H.264

            轉載自:http://www.cnblogs.com/fojian/archive/2012/09/01/2666627.html

            libx264 

            libx264是一個自由的H.264編碼庫,是x264項目的一部分,使用廣泛,ffmpeg的H.264實現就是用的libx264。

            代碼

            要把一個I420視頻文件編碼為H264格式。I420是YUV中planar格式的一種,一張I420圖片中有三個plane,分別存放整張圖片的Y、U、V分量;采樣比例為4:2:0,12bpp,Y:U:V的分量長度是4:1:1。

            頭文件

            1 #include <stdint.h>
            2 #include <stdlib.h>
            3 #include <stdio.h>
            4 #include <fcntl.h>
            5 #include <unistd.h>
            6 #include <x264.h>

            變量聲明和參數

            復制代碼
             1 int width = 480;
             2 int height = 360;
             3 int fps = 25;
             4 size_t yuv_size = width * height * 3 / 2;
             5 x264_t *encoder;
             6 x264_picture_t pic_in, pic_out;
             7 int inf, outf;
             8 uint8_t *yuv_buffer;
             9
            10 if (argc != 3) {
            11     printf("usage: %s input output\n", argv[0]);
            12 }
            復制代碼
            • 視頻尺寸是480×360,YUV I420格式,每個像素1.5個字節,所以一張YUV圖片大小是width * height * 1.5
            • encoder就是編碼器,x264_t格式在x264.h文件中只有

              typedef struct x264_t x264_t
                  

              編碼器類型只需要也只能聲明為x264_t的指針類型

            • 每次編碼時,YUV圖片的信息都保存在pic_in中
            • 輸入輸出的文件描述符
            • 從文件讀入的YUV的緩沖區

            初始化encoder

            復制代碼
             1 x264_param_t param;
             2 x264_param_default_preset(&param, "veryfast", "zerolatency");
             3 param.i_threads = 1;
             4 param.i_width = width;
             5 param.i_height = height;
             6 param.i_fps_num = fps;
             7 param.i_fps_den = 1;
             8
             9 param.i_keyint_max = 25;
            10 param.b_intra_refresh = 1;
            11
            12 param.b_annexb = 1;
            13
            14 x264_param_apply_profile(&param, "baseline");
            15 encoder = x264_encoder_open(&param);
            復制代碼

            初始化pic_in

            復制代碼
            1 x264_picture_alloc(&pic_in, X264_CSP_I420, width, height);
            2
            3 yuv_buffer = malloc(yuv_size);
            4
            5 pic_in.img.plane[0] = yuv_buffer;
            6 pic_in.img.plane[1] = pic_in.img.plane[0] + width * height;
            7 pic_in.img.plane[2] = pic_in.img.plane[1] + width * height / 4;
            復制代碼
            • pic_in.img中保存YUV圖片各分量的信息

              typedef struct {
                  int i_csp;
                  int i_plane;
                  int i_stride[4];
                  uint8_t *plane[4];
                  } x264_image_t;

              其中icsp, iplane, istride的值在picin初始化的時候已經被賦值,代碼中只需要將plane數組指向正確的位置

            • 程序中每一幀的圖片都是讀取到yuv_buffer中,所以在這里設置一次就行了

            初始化文件描述符

            復制代碼
            1 inf = open(argv[1], O_RDONLY);
            2 if (inf < 0) {
            3     return -1;
            4 }
            5 outf = open(argv[2], O_CREAT | O_WRONLY, 444);
            6 if (outf < 0) {
            7     return -1;
            8 }
            復制代碼

            編碼

            復制代碼
             1 int64_t i_pts = 0;
             2
             3 x264_nal_t *nals;
             4 int nnal;
             5 while (read(inf, yuv_buffer, yuv_size) > 0) {
             6     pic_in.i_pts = i_pts++;
             7     x264_encoder_encode(encoder, &nals, &nnal, &pic_in, &pic_out);
             8     x264_nal_t *nal;
             9     for (nal = nals; nal < nals + nnal; nal++) {
            10         write(outf, nal->p_payload, nal->i_payload);
            11     }
            12 }
            復制代碼
            • 關于ffmpeg的pts,網上有好多種公式,其實只要步長為1遞增就行了
            • H.264的NAL層是為了適應網絡傳輸的需要,將大的編碼后的幀分成多個塊
            • p_payload就是編碼后的H.264的幀數據,寫入輸出文件

            掃尾

            1 x264_encoder_close(encoder);
            2 close(inf);
            3 close(outf);
            4 free(yuv_buffer);
            5 return 0;

            編譯

            gcc sourcefile -lx264 -Wall -o execfile

             

            這里有一段I420視頻可供測試。

            參考

            1. How does one encode a series of images into H264 using the x264 C API? - Stack Overflow
            2. YUV RGB 常見視頻格式解析 - 一指流砂 - 博客園

            posted on 2013-01-11 11:30 楊粼波 閱讀(4227) 評論(0)  編輯 收藏 引用

            久久最新精品国产| 久久久久国产精品嫩草影院| 久久ww精品w免费人成| 国产精品99久久免费观看| 狠狠色丁香久久婷婷综| 久久久久久亚洲精品不卡| 久久天天躁狠狠躁夜夜2020一| 久久精品中文闷骚内射| 久久伊人精品青青草原日本| 久久久久亚洲精品天堂| 欧美精品丝袜久久久中文字幕| 伊人久久大香线焦AV综合影院 | 久久精品国产99久久久古代 | 国内精品久久国产| 国产精品久久久久天天影视| 久久夜色精品国产噜噜亚洲a | 色综合久久久久无码专区| 精品人妻伦九区久久AAA片69 | 国产精品久久成人影院| 模特私拍国产精品久久| 亚洲国产精品久久久久网站| 久久亚洲日韩看片无码| 久久免费国产精品| 久久综合狠狠综合久久激情 | 久久久久久九九99精品| 久久热这里只有精品在线观看| 久久国产香蕉一区精品| 国产成人精品久久综合 | 久久亚洲中文字幕精品有坂深雪| 大香网伊人久久综合网2020| 97热久久免费频精品99| 亚洲精品无码专区久久久| 久久久久亚洲精品日久生情| 久久久久久久久66精品片| 欧美色综合久久久久久| 欧美久久久久久午夜精品| 精品久久久久中文字| 精品久久久久久久久久久久久久久| 久久99国产精品久久久| 久久综合九色综合精品| 国产伊人久久|