• 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 
    ", 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 
    ", 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  
    ",
                          (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
    ",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 
    ",
                       (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
    ",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  
    ",
                  (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
    ",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、去掉起始码

    这两行换个顺序

            h264_nalu_cb(p, nal_end);     
            p += nal_start;

    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
    ",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  
    ",
                  (long long int)((p - buf) + nal_start),
                  (long long int)(nal_end - nal_start) );  
    
            //printf("h264 payload %x %x %x %x %x
    ",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

  • 相关阅读:
    带你进入异步Django+Vue的世界
    xps转换为pdf
    当对函数的返回值有多种需求时(执行是否成功,及业务数据的返回值),可采用的方法
    WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)
    集群、限流、缓存 BAT 大厂无非也就是这么做
    C#简单爬取数据(.NET使用HTML解析器ESoup和正则两种方式匹配数据)
    公共静态函数、属性 的 “关联成员” 的 生命周期
    python 之 Django框架(ORM常用字段和字段参数、关系字段和和字段参数)
    Django文档
    go micro 微服务框架温习
  • 原文地址:https://www.cnblogs.com/dong1/p/10149980.html
Copyright © 2020-2023  润新知