h264bitstream (read and write H.264 video bitstreams)

1、编译安装参考源码包自带的说明文档

h264bitstream-0.2.0/README.md

 

sudo apt-get install build-essential libtool
autoreconf -i
./configure --prefix=$(pwd)/_install
make
make install

 

2、例子太啰嗦,精简了一下

h264_analyze.c

/* 
 * h264bitstream - a library for reading and writing H.264 video
 * Copyright (C) 2005-2007 Auroras Entertainment, LLC
 * 
 * Written by Alex Izvorski <aizvorski@gmail.com>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "h264_stream.h"

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define BUFSIZE 32*1024*1024

int main(int argc, char *argv[])
{
    FILE* infile;

    uint8_t* buf = (uint8_t*)malloc( BUFSIZE );

    h264_stream_t* h = h264_new();

    if (argc < 2) { return EXIT_FAILURE; }

    int opt_verbose = 1;
    int opt_probe = 0;

    infile = fopen(argv[1], "rb");


    if (infile == NULL) { fprintf( stderr, "!! Error: could not open file: %s \n", strerror(errno)); exit(EXIT_FAILURE); }

    if (h264_dbgfile == NULL) { h264_dbgfile = stdout; }
    

    size_t rsz = 0;
    size_t sz = 0;
    int64_t off = 0;
    uint8_t* p = buf;

    int nal_start, nal_end;

    while (1)
    {
        rsz = fread(buf + sz, 1, BUFSIZE - sz, infile);
        if (rsz == 0)
        {
            if (ferror(infile)) { fprintf( stderr, "!! Error: read failed: %s \n", strerror(errno)); break; }
            break;  // if (feof(infile)) 
        }

        sz += rsz;

        while (find_nal_unit(p, sz, &nal_start, &nal_end) > 0)
        {
            if ( opt_verbose > 0 )
            {
               fprintf( h264_dbgfile, "!! Found NAL at offset %lld , size %lld  \n",
                      (long long int)(off + (p - buf) + nal_start),
                      (long long int)(nal_end - nal_start) );
            }

            p += nal_start;
            read_debug_nal_unit(h, p, nal_end - nal_start);

            if ( opt_probe && h->nal->nal_unit_type == NAL_UNIT_TYPE_SPS )
            {
                // print codec parameter, per RFC 6381.
                int constraint_byte = h->sps->constraint_set0_flag << 7;
                constraint_byte = h->sps->constraint_set1_flag << 6;
                constraint_byte = h->sps->constraint_set2_flag << 5;
                constraint_byte = h->sps->constraint_set3_flag << 4;
                constraint_byte = h->sps->constraint_set4_flag << 3;
                constraint_byte = h->sps->constraint_set4_flag << 3;

                fprintf( h264_dbgfile, "codec: avc1.%02X%02X%02X\n",h->sps->profile_idc, constraint_byte, h->sps->level_idc );

                // TODO: add more, move to h264_stream (?)
                break; // we've seen enough, bailing out.
            }

            if ( opt_verbose > 0 )
            {

            }

            p += (nal_end - nal_start);
            sz -= nal_end;
        }

        // if no NALs found in buffer, discard it
        if (p == buf) 
        {
            fprintf( stderr, "!! Did not find any NALs between offset %lld , size %lld , discarding \n",
                   (long long int)off, 
                   (long long int)off + sz);

            p = buf + sz;
            sz = 0;
        }

        memmove(buf, p, sz);
        off += p - buf;
        p = buf;
    }

    h264_free(h);
    free(buf);

    fclose(h264_dbgfile);
    fclose(infile);

    return 0;
}

编译

gcc h264_analyze.c -o h264_analyze -I $(pwd)/h264bitstream/include/h264bitstream -L $(pwd)/h264bitstream/lib -lh264bitstream

添加库文件环境变量

export LD_LIBRARY_PATH=$(pwd)/h264bitstream/lib:$LD_LIBRARY_PATH

运行

./h264_analyze JM_cqm_cabac.264

 

3、封装了个函数,方便集成

int get_h264_nalu(uint8_t* buf, size_t sz)

main.c

/* 
 * h264bitstream - a library for reading and writing H.264 video
 * Copyright (C) 2005-2007 Auroras Entertainment, LLC
 * 
 * Written by Alex Izvorski <aizvorski@gmail.com>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "h264_stream.h"

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define BUFSIZE 1024*1024

void h264_nalu_cb(uint8_t* p,size_t sz)
{
    printf("h264 payload %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4]);
}

int get_h264_nalu(uint8_t* buf, size_t sz)
{    
    h264_stream_t* h = h264_new();
   
    uint8_t* p = buf;

    int nal_start, nal_end;

    int n = 0;

    while (find_nal_unit(p, sz, &nal_start, &nal_end) > 0)
    {

        printf("!! Found NAL at offset %lld , size %lld  \n",
              (long long int)((p - buf) + nal_start),
              (long long int)(nal_end - nal_start) );  

        //export nalu data
        //printf("h264 payload %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4]);
        char str[32];
        sprintf(str,"./h264_nalu_frame/test%d.264",n);         
        FILE *fp = fopen(str, "a+b");
        if(fp)
        {
         fwrite(p, nal_end, 1, fp);
         fclose(fp);
         fp = NULL;
        }
        n++;
        h264_nalu_cb(p, nal_end);      


        //debug
        p += nal_start;
        //read_debug_nal_unit(h, p, nal_end - nal_start);

        //next frame
        p += (nal_end - nal_start);
        sz -= nal_end;
    }

    h264_free(h);
    
    return 0;
}

int main(int argc, char *argv[])
{   
    uint8_t* buf = (uint8_t*)malloc( BUFSIZE );
    FILE* infile = fopen("test0.264", "rb");
    fread(buf,1,BUFSIZE,infile);
    get_h264_nalu(buf, BUFSIZE);
    fclose(infile);
    free(buf);
    return 0;
}

还是三步走

gcc main.c -o main -I $(pwd)/h264bitstream/include/h264bitstream -L $(pwd)/h264bitstream/lib -lh264bitstream

export LD_LIBRARY_PATH=$(pwd)/h264bitstream/lib:$LD_LIBRARY_PATH

./main

解析个 sps + pps + i + p*n

dong@ubuntu:~/doing/h264bitstream_demo$ ./build.sh
dong@ubuntu:~/doing/h264bitstream_demo$ ./main
!! Found NAL at offset 4 , size 15  
h264 payload 0 0 0 1 67
!! Found NAL at offset 23 , size 4  
h264 payload 0 0 0 1 68
!! Found NAL at offset 31 , size 23637  
h264 payload 0 0 0 1 65
!! Found NAL at offset 23672 , size 6052  
h264 payload 0 0 0 1 41
!! Found NAL at offset 29728 , size 15796  
h264 payload 0 0 0 1 41
!! Found NAL at offset 45528 , size 16669  
h264 payload 0 0 0 1 41
!! Found NAL at offset 62201 , size 14952  
h264 payload 0 0 0 1 41
!! Found NAL at offset 77157 , size 14291  
h264 payload 0 0 0 1 41
!! Found NAL at offset 91452 , size 14913  
h264 payload 0 0 0 1 41
!! Found NAL at offset 106369 , size 14420  
h264 payload 0 0 0 1 41
!! Found NAL at offset 120793 , size 14316  
h264 payload 0 0 0 1 41
!! Found NAL at offset 135113 , size 16304  
h264 payload 0 0 0 1 41
!! Found NAL at offset 151421 , size 14216  
h264 payload 0 0 0 1 41
!! Found NAL at offset 165641 , size 16108  
h264 payload 0 0 0 1 41
!! Found NAL at offset 181753 , size 14348  
h264 payload 0 0 0 1 41
!! Found NAL at offset 196105 , size 16092  
h264 payload 0 0 0 1 41
!! Found NAL at offset 212201 , size 14529  
h264 payload 0 0 0 1 41
!! Found NAL at offset 226734 , size 16852  
h264 payload 0 0 0 1 41
!! Found NAL at offset 243590 , size 14098  
h264 payload 0 0 0 1 41
!! Found NAL at offset 257692 , size 16018  
h264 payload 0 0 0 1 41
!! Found NAL at offset 273714 , size 14647  
h264 payload 0 0 0 1 41
!! Found NAL at offset 288365 , size 14792  
h264 payload 0 0 0 1 41
!! Found NAL at offset 303161 , size 13929  
h264 payload 0 0 0 1 41
!! Found NAL at offset 317094 , size 19153  
h264 payload 0 0 0 1 41
!! Found NAL at offset 336251 , size 13545  
h264 payload 0 0 0 1 41
!! Found NAL at offset 349800 , size 19024  
h264 payload 0 0 0 1 41
!! Found NAL at offset 368828 , size 14569  
h264 payload 0 0 0 1 41
!! Found NAL at offset 383401 , size 13160  
h264 payload 0 0 0 1 41
!! Found NAL at offset 396565 , size 19309  
h264 payload 0 0 0 1 41
!! Found NAL at offset 415878 , size 13847  
h264 payload 0 0 0 1 41
!! Found NAL at offset 429729 , size 13841  
h264 payload 0 0 0 1 41
!! Found NAL at offset 443574 , size 20354  
h264 payload 0 0 0 1 41
dong@ubuntu:~/doing/h264bitstream_demo$

 

4、去掉起始码

main.c

/* 
 * h264bitstream - a library for reading and writing H.264 video
 * Copyright (C) 2005-2007 Auroras Entertainment, LLC
 * 
 * Written by Alex Izvorski <aizvorski@gmail.com>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "h264_stream.h"

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define BUFSIZE 1024*1024

void h264_nalu_cb(uint8_t* p,size_t sz)
{
    printf("h264 payload %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4]);
}

int get_h264_nalu(uint8_t* buf, size_t sz)
{    
    h264_stream_t* h = h264_new();
   
    uint8_t* p = buf;

    int nal_start, nal_end;

    int n = 0;

    while (find_nal_unit(p, sz, &nal_start, &nal_end) > 0)
    {

        printf("!! Found NAL at offset %lld , size %lld  \n",
              (long long int)((p - buf) + nal_start),
              (long long int)(nal_end - nal_start) );  

        //printf("h264 payload %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4]);


        //debug
        p += nal_start;
        //read_debug_nal_unit(h, p, nal_end - nal_start);

        //export nalu data
        char str[32];
        sprintf(str,"./h264_nalu_frame/test%d.264",n);         
        FILE *fp = fopen(str, "a+b");
        if(fp)
        {
         fwrite(p, nal_end - nal_start, 1, fp);
         fclose(fp);
         fp = NULL;
        }
        n++;
        h264_nalu_cb(p, nal_end - nal_start);

        //next frame
        p += (nal_end - nal_start);
        sz -= nal_end;
    }

    h264_free(h);
    
    return 0;
}

int main(int argc, char *argv[])
{   
    uint8_t* buf = (uint8_t*)malloc( BUFSIZE );
    FILE* infile = fopen("test0.264", "rb");
    fread(buf,1,BUFSIZE,infile);
    get_h264_nalu(buf, BUFSIZE);
    fclose(infile);
    free(buf);
    return 0;
}

 

demo附件包下载

https://files.cnblogs.com/files/dong1/h264bitstream_demo.zip

 

转载于:https://www.cnblogs.com/dong1/p/11457760.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值