mux复用 demux解复用

保存音频包:

直接输出解复用之后的的音频数据码流。只需要在每次调用av_read_frame()之后将得到的音频的AVPacket存为本地文件即可。

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

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

复用格式是FLV,MP4等,直接存储后的文件是不能播放的。

因为FLV,MP4这些属于“特殊容器”。经过仔细对比后发现,调用av_read_frame()后得到的AVPacket里面的内容是AAC纯数据,就是那种不包含ADTS文件头的AAC数据。(存储AAC数据的AVPacket的data字段中的数据是不包含7字节ADTS文件头的数据)因此如果想要得到可以播放的AAC文件,需要在每个AVPacket前面加上7字节ADTS文件头。

demux分离时,h264需要h264_mp4toannexb,音频aac好像没有用到

mux时,h264也需要h264_mp4toannexb,aac用到aac_adtstoasc

mux时对于某些封装格式(例如MP4/FLV/MKV等)中的AAC,需要用到名称为“aac_adtstoasc”的bitstream filter。

============================================================

保存视频包:

分离某些封装格式(例如MP4/FLV/MKV等)中的H.264的时候,需要首先写入SPS和PPS

例如flv格式时,从av_read_frame中读出的包也是不包含video tag header的裸视频数据。

FLV,MP4这些“特殊容器”,需要经过以下2步处理才能得到可播放的H.264码流:

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

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

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

具体代码如下:

代码片段A

  1. unsigned char *dummy=NULL;   //输入的指针  
  2. int dummy_len;  
  3. AVBitStreamFilterContext* bsfc =  av_bitstream_filter_init("h264_mp4toannexb");    
  4. av_bitstream_filter_filter(bsfc, pCodecCtx, NULL, &dummy, &dummy_len, NULL, 0, 0);  
  5. fwrite(pCodecCtx->extradata,pCodecCtx-->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数据。

具体代码如下:

代码片段B

  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); 

  1. char nal_start[]={0,0,0,1};  
  2. memcpy(packet->data,nal_start,4); 

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

====================================================

其它处理方式:

(1)使用bitstream filter处理每个AVPacket(简单)

把每个AVPacket中的数据(data字段)经过bitstream filter“过滤”一遍。关键函数是av_bitstream_filter_filter()。示例代码如下。

  1. AVBitStreamFilterContext* h264bsfc =  av_bitstream_filter_init("h264_mp4toannexb");   
  2. while(av_read_frame(ifmt_ctx, &pkt)>=0){  
  3.     if(pkt.stream_index==videoindex){  
  4.         av_bitstream_filter_filter(h264bsfc, ifmt_ctx->streams[videoindex]->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);  
  5.         fwrite(pkt.data,1,pkt.size,fp_video);  
  6.         //...  
  7.     }  
  8.     av_free_packet(&pkt);  
  9. }  
  10. av_bitstream_filter_close(h264bsfc);  

代码中,把av_bitstream_filter_filter()的输入数据和输出数据(分别对应第4,5,6,7个参数)都设置成AVPacket的data字段就可以了。

经过上述代码处理之后,AVPacket中的数据有如下变化:

*每个AVPacket的data添加了H.264的NALU的起始码{0,0,0,1}

*每个IDR帧数据前面添加了SPS和PPS

(2)手工添加SPS,PPS(稍微复杂)

将AVCodecContext的extradata数据经过bitstream filter处理之后得到SPS、PPS,拷贝至每个IDR帧之前。“代码片段A”示例了写入SPS、PPS的过程。

然后修改AVPacket的data。把前4个字节改为起始码。参见:代码片段B

参考:

视音频分离器(demuxer):ts->h264+aac
利用
av_interleaved_write_frame

视音频复用器(muxer):h264+aac->mkv,用到av_interleaved_write_frame

分离多媒体文件中的音频码流

分离多媒体文件中的H.264码流

视音频分离器简化版(demuxer-simple):flv->h264+aac

时间: 2024-09-28 04:50:19

mux复用 demux解复用的相关文章

视频播放的基本原理

视频播放的基本原理 VLC是一个功能强大的玩意,能做很多有意思的事情. 最简单的,从界面打开一个文件播放,也可以在命令行下使用,如 C:/Program Files/VideoLAN/VLC>vlc.exe test.ts 获取内置的帮助,会写到vlc-help.txt C:/Program Files/VideoLAN/VLC>vlc.exe -h 获取更详细的帮助,有大量的选项介绍 C:/Program Files/VideoLAN/VLC>vlc.exe -H 在线使用帮助 htt

密集波分复用光网络关键技术

摘要基于IP的数据业务的爆炸式发展带来了对带宽的无限需求,而密集波分复用(DWDM)系统在满足不断增长的带宽需求的同时还具有不可比拟的联网优势.本文对其关键技术进行了探讨. 关键词密集波分复用(DWDM)WDM光网络全光联网关健技术 WDM光网络在不断进步的同时仍有大量问题需要解决,如设备价格昂贵,标准化问题,如何在不同用户间分配波长,如何对用户鉴权以及保留性问题,串扰问题,一体化网络管理机制和互操作问题等.光联网的实现主要取决于关键网元设备的成熟与否.研究或发明可用于WDM的新技术和新器件具有

深入解析OTN光交叉技术实现方式

OTN技术领域中,目前业内较为流行的3种光交叉实现技术分别为波长阻断型光交叉(WB).平面光波导电路型光交叉(PLC)和波长选择型光交叉(WSS).这3种光交叉技术根据其实现原理和实现成本不同,各有相应的应用场景.波长阻断型 所谓波长阻断型,是以任意顺序,在 同一时间对任意数目的波长进行衰减或者阻断.其特性在于它可以独立且并行地处理每一个波长,因此对某一波长进行操作不会影响其他的波长.由于该器件支持远程控制并且能实现完全重新配置,因此可以完成以下功能.a)将输入的复用信号导向相应的输出端,除了

ffmpeg 源代码简单分析 : avcodec_register_all()

原帖地址:http://blog.csdn.net/leixiaohua1020/article/details/12677265: avcodec_register_all()是av_register_all()函数中在注册各种复用.解复用之前调用的函数,用于注册编解码器. 其实注册编解码器和注册复用器解复用器道理是差不多的,重复的内容不再多说. 编码器的注册是: REGISTER_ENCODER (X,x); 例如: REGISTER_ENCODER (LJPEG, ljpeg); 解码器的

全光网络实现关键:光分插复用(OADM)节点技术

光通信具有带宽大.可靠性高.成本低等特点,光通信系统和光网络飞速发展给信息时代带来新的革命.OADM节点在光网络中的应用,使得环内路由操作不受传输信号类型和速率的影响,从而实现本地网的透明,为提供端到端的波长业务奠定基础.也就是说用户可以根据自己的需要将任何形式,任何速率的信息承载在某一个波长上,而网络通过波长标识路由将其传到目的地. 一 概述 WDM光网络简介 随着数据业务以几何级数增长,尤其是Internet的迅速普及,现有网络技术已远远不能适应广大用户对网络速度和带宽的要求.90年代中期后

android中抽象公共类,复用公共方法为多个对象

今天学习如何实现愤怒的小鸟,用到了JBox2D构建物理世界(这个不是这篇文章重点,但是很谢谢这个开源玩意) 一般一个独立的物体的实体类 import org.jbox2d.dynamics.Body; import org.liky.angrybird.util.Globals; import org.liky.angrybird.util.ImageUtils; import android.graphics.Canvas; import android.graphics.Paint; imp

设计模式六大原则--合成/聚合复用原则

       背景        对于很多人来说自己的第一步手机或者曾经用过的手机里一定有诺基亚的身影.记得当年的诺基亚的手机即时使用的系统是相同的也可能不能使用相同的软件,还得看具体的机型.现在想着就麻烦,哪里有电脑上的软件和安卓智能手机上的软件使用起来方便.如果你看了之前的博客,你肯定会知道,今天我们要了解的是合成/聚合复用模式(Composite/Aggregate Reuse Principle,缩写CARP).        定义        尽量使用合成/聚合,尽量不要使用类继承.

软件测试中的测试用例复用技术

摘要:软件测试是确保软件质量的可靠手段,是软件开发过程中必不可少的重要环节.本文提出了面向复用的测试用例设计过程,为测试用例复用提供了实现策略.测试用例的复用对于缩短软件开发周期和降低软件开发成本具有极其重要的意义. 关键词:软件测试:测试用例 1.引言 随着软件工程领域的拓展,在软件产业飞速发展的今天,软件测试成为保证软件质量的重要手段.测试用例的选择对于软件测试的成败起着决定性作用,因此如何设计最少的测试用例实现最大的测试覆盖成为自动化测试领域中的主要研究对象.测试用例是确定一组最有可能发现

Python实现端口复用实例代码_python

本文介绍Python实现端口复用实例如下所示: #coding=utf-8 import socket import sys import select import threading host='192.168.99.100' port=80 class Thread(threading.Thread): def __init__(self,buf,sockfd): threading.Thread.__init__(self) self.buf=buf self.sockfd=sockfd