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


            久久精品中文无码资源站| 中文国产成人精品久久不卡| 99久久成人18免费网站| 久久久精品久久久久特色影视| 99久久国产亚洲高清观看2024| 日本精品久久久久中文字幕8| 久久久久久久综合日本亚洲| 国产福利电影一区二区三区,免费久久久久久久精 | 亚洲精品美女久久777777| 亚洲中文字幕无码久久2020| 久久最近最新中文字幕大全| 伊人久久五月天| 东方aⅴ免费观看久久av| 国产精品久久久天天影视香蕉| 久久亚洲高清观看| 97精品依人久久久大香线蕉97| 久久66热人妻偷产精品9| 亚洲成av人片不卡无码久久| 久久精品国产99国产精品澳门| 国产精品久久久久久久午夜片| 伊人久久大香线蕉成人| 91精品无码久久久久久五月天 | 久久精品国产亚洲AV嫖农村妇女| 91精品国产9l久久久久| 亚洲中文字幕无码久久综合网 | 一级女性全黄久久生活片免费| 久久精品中文字幕无码绿巨人| 久久精品一区二区三区中文字幕 | 狠狠狠色丁香婷婷综合久久五月| 午夜精品久久久久成人| 青青青国产精品国产精品久久久久 | 亚洲va久久久噜噜噜久久天堂| 亚洲人成精品久久久久| 久久久久国产精品人妻| 中文字幕久久亚洲一区| 人妻少妇精品久久| 波多野结衣久久一区二区| 久久99国产精品久久99小说| 国产69精品久久久久观看软件| 久久99国产一区二区三区| 久久精品国产亚洲精品|