• <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>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            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

            轉(zhuǎn)載自:http://www.cnblogs.com/fojian/archive/2012/09/01/2666627.html

            libx264 

            libx264是一個(gè)自由的H.264編碼庫,是x264項(xiàng)目的一部分,使用廣泛,ffmpeg的H.264實(shí)現(xiàn)就是用的libx264。

            代碼

            要把一個(gè)I420視頻文件編碼為H264格式。I420是YUV中planar格式的一種,一張I420圖片中有三個(gè)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>

            變量聲明和參數(shù)

            復(fù)制代碼
             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 }
            復(fù)制代碼
            • 視頻尺寸是480×360,YUV I420格式,每個(gè)像素1.5個(gè)字節(jié),所以一張YUV圖片大小是width * height * 1.5
            • encoder就是編碼器,x264_t格式在x264.h文件中只有

              typedef struct x264_t x264_t
                  

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

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

            初始化encoder

            復(fù)制代碼
             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);
            復(fù)制代碼

            初始化pic_in

            復(fù)制代碼
            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;
            復(fù)制代碼
            • 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初始化的時(shí)候已經(jīng)被賦值,代碼中只需要將plane數(shù)組指向正確的位置

            • 程序中每一幀的圖片都是讀取到y(tǒng)uv_buffer中,所以在這里設(shè)置一次就行了

            初始化文件描述符

            復(fù)制代碼
            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 }
            復(fù)制代碼

            編碼

            復(fù)制代碼
             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 }
            復(fù)制代碼
            • 關(guān)于ffmpeg的pts,網(wǎng)上有好多種公式,其實(shí)只要步長為1遞增就行了
            • H.264的NAL層是為了適應(yīng)網(wǎng)絡(luò)傳輸?shù)男枰瑢⒋蟮木幋a后的幀分成多個(gè)塊
            • p_payload就是編碼后的H.264的幀數(shù)據(jù),寫入輸出文件

            掃尾

            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 楊粼波 閱讀(4238) 評(píng)論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            18禁黄久久久AAA片| 狠狠88综合久久久久综合网| 99久久精品费精品国产一区二区| 天天爽天天狠久久久综合麻豆| 午夜精品久久久久久久久| 九九精品99久久久香蕉| 久久精品国产清自在天天线| 国内精品伊人久久久影院| av无码久久久久久不卡网站| 久久婷婷五月综合97色直播| 久久久无码人妻精品无码| 久久久久人妻精品一区三寸蜜桃| 久久SE精品一区二区| 国产2021久久精品| 久久婷婷国产剧情内射白浆| 亚洲伊人久久大香线蕉苏妲己| 国产精品久久久久久久app| 久久久久夜夜夜精品国产| 久久久久久精品久久久久| 国内精品伊人久久久久影院对白| 伊人久久精品无码二区麻豆| 久久亚洲AV无码西西人体| 99久久久精品免费观看国产| 精产国品久久一二三产区区别| 国产成人综合久久精品尤物| 亚洲精品美女久久久久99| 久久无码人妻精品一区二区三区| 俺来也俺去啦久久综合网| 久久人人爽人人爽人人片av高请 | 一本大道久久东京热无码AV | 久久久久久久尹人综合网亚洲| 中文字幕乱码人妻无码久久| 一本色道久久88综合日韩精品| 久久精品二区| 久久综合色区| 免费精品国产日韩热久久| 午夜精品久久久久久久无码| 久久久久亚洲爆乳少妇无| 久久夜色精品国产| 性做久久久久久久久老女人| 欧美久久久久久|