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

            x264編碼得到的文件,在文件頭部的一些東西,有了新發現

            轉載自:http://wmnmtm.blog.163.com/blog/static/38245714201192211245389/

            下載的一個源碼里,實現了把264文件通過RTP發送,但是如果發送實時編碼的怎么辦,序列參數集和圖像參數集得自己發送,因為264文件本身在文件開頭已經存儲了這些了。

            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
            (圖一)這是一個正確編碼得到的xxx.264文件,用UltraEDit打開的文件開始部分
             

            在x264.dsw工程中,找了一下,找到點相關的東西。
            另外,x264.exe在編碼文件時,只有一個地方進行文件的寫入,就是
            int write_nalu_bsf( hnd_t handle, uint8_t *p_nalu, int i_size )
            {
               if (fwrite(p_nalu, i_size, 1, (FILE *)handle) > 0)
            {
                     return i_size;
            }
                return -1;
            }
            如果把函數里的代碼注釋掉,會發現,雖然在不停的編碼,但最終文件大小始終為0,從這一點可以證明只有此處進行文件的寫入操作。

            那么,序列參數集是哪里來的呢,又找到一部分東西,在encoder.c文件的函數:
            int     x264_encoder_encode( x264_t *h,/* 指定編碼器 */
                                         x264_nal_t **pp_nal, /* x264_nal_t * */
             int *pi_nal, /* int */
                                         x264_picture_t *pic_in,
                                         x264_picture_t *pic_out )
            中,有如下代碼:

                /* Write SPS and PPS 寫序列參數集、圖像參數集以及SEI版本信息,并不是寫入文件,而是寫入輸出緩沖區 最后通過p_write_nalu中的fwrite寫入到文件*/
                if( i_nal_type == NAL_SLICE_IDR && h->param.b_repeat_headers )
                {
            printf("encoder.c : Write SPS and PPS");
            system("pause");//暫停,任意鍵繼續

                    if( h->fenc->i_frame == 0 )
                    {
                        /* identify ourself */
                        x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
                        x264_sei_version_write( h, &h->out.bs );
                        x264_nal_end( h );
                    }

                    /* generate sequence parameters */
                    x264_nal_start( h, NAL_SPS, NAL_PRIORITY_HIGHEST );
                    x264_sps_write( &h->out.bs, h->sps );
                    x264_nal_end( h );

                    /* generate picture parameters */
                    x264_nal_start( h, NAL_PPS, NAL_PRIORITY_HIGHEST );
                    x264_pps_write( &h->out.bs, h->pps );
                    x264_nal_end( h );
                }

                /* Write frame 寫入幀,并不是寫入文件,而是寫入輸出緩沖區*/
                i_frame_size = x264_slices_write( h );

            在圖一中,看到有一個網址http://www.videolan.org,在源碼中搜索這個網址,找到唯一的一處,也就是如下的函數:
            void x264_sei_version_write( x264_t *h, bs_t *s )
            {
                int i;
                // random ID number generated according to ISO-11578
                const uint8_t uuid[16] = {
                    0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7,
                    0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef
                };
                char version[1200];
                int length;
                char *opts = x264_param2string( &h->param, 0 );

                sprintf( version, "x264 - core %d%s - H.264/MPEG-4 AVC codec - "
                         "Copyleft 2005 - http://www.videolan.org/x264.html - options: %s",
                         X264_BUILD, X264_VERSION, opts );
                x264_free( opts );
                length = strlen(version)+1+16;

                bs_write( s, 8, 0x5 ); // payload_type = user_data_unregistered
                // payload_size
                for( i = 0; i <= length-255; i += 255 )
                    bs_write( s, 8, 255 );
                bs_write( s, 8, length-i );

                for( i = 0; i < 16; i++ )
                    bs_write( s, 8, uuid[i] );
                for( i = 0; i < length-16; i++ )
                    bs_write( s, 8, version[i] );

                bs_rbsp_trailing( s );
            }

            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
             (圖二)注釋掉x264_sps_write( &h->out.bs, h->sps );的情況


            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
            (圖三)注釋掉x264_pps_write( &h->out.bs, h->pps );的情況


            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲

            (圖四)x264_sei_version_write( h, &h->out.bs );注釋掉,但是播放是一樣的

            既然注釋掉仍能播,說明它不是必須的,僅是個版權聲明
             
             
            猜想:
            如果是實時的話,可以模仿下面的這兩句代碼發送序列參數集和圖像參數集:
            x264_sps_write( &h->out.bs, h->sps );
            x264_pps_write( &h->out.bs, h->pps );

            實際就是要發送h->sps和h->pps

            因為我編碼的文件是可以播放的,所以實際已經產生了sps和pps,直接發送就行了。

            因為h是已知的,h = x264_encoder_open( &param );它的返回值就是x264_t,這樣就可以通過h->sps和h->pps,下面是我將它們單獨寫入文件的截圖:
            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
             sps_1
            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
             sps_2
            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
            sps_3
             
            上面是一個sps(sps1,sps_2,sps_3),看著內容好少啊。寫入代碼是:file1.Write(h->sps,sizeof(x264_sps_t));

            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲 
            pps


            PPS的內容也好少,可能是因為大多數均未指定,采用的是默認參數的原因吧,但是圖像寬度和高度在哪兒了。

            h->x264_param_t    param;
            這個也很關鍵,因為我指定的都是在這個里,
            param.i_width=320;
            param.i_height=240;
            把這個也保一份看看。

            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
            h->PARAM
            param.i_width=320;
            param.i_height=240;
            這兩個數字對應的在哪呢,應該有才對啊,找找。(其實已經有了,只是現在沒找到,看后面)

            后來換了個參數值,又試了一下
            param.i_width=320;
            param.i_height=240;
            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
            這是i_width 為320和100的比較,一直折騰半天,發現0x64能對應上十進制100,但是320怎么也對不上。
            后來又從結構體的存儲上找了半天(我直觀的認為結構體中的變量字段是按順序存在一塊連續空間的,對不對不知道了)

             x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
             
            我分析,在unsigned int 和int共占8字節,那么第9、10、11、12個字節應該就是i_width,但還是對不上。直到ing提到小頭和大頭,也就是主機字節序和網絡字節序時,才驚醒過來。

            原來,前面一直是對的,只是自己看成是錯的了,呵呵。

            0x 64 00  ,實際應該看成 0x 00 64  ,換算成二進制表示: 0000 0000  0110 0100
            0x 40 01  ,實際應該看成 0x 01 40  ,換算成二進制表示: 0000 0001  0100 0000

            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
             
            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
             
            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
             
            x264編碼得到的文件,在文件頭部的一些東西,有了新發現 - 加菲 - 視頻會議 - 加菲
             


            這下就對了。



            小結一下:
            1、結構體的各字段存儲在一段連續的內存中。
            2、主機字節序,用二進制查看器查看到 0x 64 00 ,換算二進制時,要按 0x 00 64這樣反過來。(說法不標準,呵呵)
            3、x264.exe編碼得到的文件,前面有一段版權聲明,是沒用的。
            4、file1.Write(&(h->param),sizeof(x264_param_t));這樣把h->param寫入二進制文件是正確的。
            5、只發送sps和pps可以嗎

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

            2021国内久久精品| 色播久久人人爽人人爽人人片aV| 久久99精品国产麻豆宅宅| 伊人久久大香线蕉综合Av| 国内精品久久久人妻中文字幕| 色综合久久最新中文字幕| 日日狠狠久久偷偷色综合免费| 伊人久久大香线蕉AV一区二区| 色欲综合久久躁天天躁蜜桃| 久久香蕉一级毛片| 日韩欧美亚洲综合久久| 久久国产乱子精品免费女| 97香蕉久久夜色精品国产 | 国内精品伊人久久久久网站| 久久久青草青青国产亚洲免观| 18岁日韩内射颜射午夜久久成人| 色综合久久天天综合| 午夜精品久久久久久久| 亚洲国产成人久久笫一页| 久久青青草原精品影院| www久久久天天com| 中文无码久久精品| 久久综合狠狠综合久久97色| 2021久久国自产拍精品| 亚洲综合精品香蕉久久网| 热综合一本伊人久久精品| 国产精品青草久久久久福利99| 久久人人爽人人爽人人AV东京热| 久久中文字幕视频、最近更新 | 精品国产一区二区三区久久久狼| 久久婷婷五月综合成人D啪| 丁香五月综合久久激情| 69SEX久久精品国产麻豆| 日韩AV无码久久一区二区| 亚洲国产精品无码久久久不卡| 日韩人妻无码一区二区三区久久99| 久久99精品久久久久久噜噜| 久久久久亚洲av毛片大| 亚洲精品99久久久久中文字幕| 欧美激情精品久久久久久| 久久受www免费人成_看片中文|