zoukankan      html  css  js  c++  java
  • 使用FFMPEG类库分离出多媒体文件中的H.264码流

    在使用FFMPEG的类库进行编程的过程中,可以直接输出解复用之后的的视频数据码流。只需要在每次调用av_read_frame()之后将得到的视频的AVPacket存为本地文件即可。

    经试验,在分离MPEG2码流的时候,直接存储AVPacket即可。

    在分离H.264码流的时候,直接存储AVPacket后的文件可能是不能播放的。

    如果视音频复用格式是TS(MPEG2 Transport Stream),直接存储后的文件是可以播放的。

    复用格式是FLV,MP4则不行。

    经过长时间资料搜索发现,FLV,MP4这些属于“特殊容器”,需要经过以下处理才能得到可播放的H.264码流:

    1.第一次存储AVPacket之前需要在前面加上H.264的SPS和PPS。这些信息存储在AVCodecContext的extradata里面。

    并且需要使用FFMPEG中的名为"h264_mp4toannexb"的bitstream filter 进行处理。

    然后将处理后的extradata存入文件

    具体代码如下:

    1. FILE *fp=fopen("test.264","ab");  
    1. unsigned char *dummy=NULL;   //输入的指针  
    2. int dummy_len;  
    3. AVBitStreamFilterContext* bsfc =  av_bitstream_filter_init("h264_mp4toannexb");    
    4. av_bitstream_filter_filter(bsfc, is->ic->streams[is->video_stream]->codec, NULL, &dummy, &dummy_len, NULL, 0, 0);  
    5. fwrite(is->ic->streams[is->video_stream]->codec->extradata,is->ic->streams[is->video_stream]->codec->extradata_size,1,fp);  
    6. av_bitstream_filter_close(bsfc);    
    7. free(dummy);  

    2.通过查看FFMPEG源代码我们发现,AVPacket中的数据起始处没有分隔符(0x00000001), 也不是0x65、0x67、0x68、0x41等字节,所以可以AVPacket肯定这不是标准的nalu。其实,AVPacket前4个字表示的是nalu的长度,从第5个字节开始才是nalu的数据。所以直接将AVPacket前4个字节替换为0x00000001即可得到标准的nalu数据。

    具体代码如下:

    1. char nal_start[]={0,0,0,1};  
    2. fwrite(nal_start,4,1,fp);  
    3. fwrite(pkt->data+4,pkt->size-4,1,fp);  
    4. fclose(fp);  

    经过以上两步处理之后,我们就得到了可以正常播放的H.264码流

  • 相关阅读:
    「PHP」使用 Homestead 作为 thinkphp5 的开发环境
    「PHP」Homestead 安装 swoole
    「PHP」Homestead
    存储过程
    Windows不能用鼠标双击运行jar文件怎么办?
    spring事务管理
    xml页面开头报错Multiple annotations found at this line
    修行
    jsp页面get和post不同导致的乱码问题
    VC执行Cmd命令,并获取结果
  • 原文地址:https://www.cnblogs.com/leixiaohua1020/p/3902226.html
Copyright © 2011-2022 走看看