FLV(一)-解复用器


          FLV(一)-解复用器
FLV的基本结构信息可以参考
http://www.cnblogs.com/chef/archive/2012/07/18/2597279.html
http://www.cnblogs.com/qingquan/archive/2011/08/11/2135531.html
http://blog.youkuaiyun.com/bsplover/article/details/7426511
http://help.adobe.com/en_US/FlashMediaLiveEncoder/3.0/Using/WS5b3ccc516d4fbf351e63e3d11c104ba878-7ff5.html
http://blog.youkuaiyun.com/zengraoli/article/details/7742278
以及 http://download.youkuaiyun.com/detail/zhuweigangzwg/5472729,中的文章,里面包括了官方文档
video_file_format_spec_v10 :这个是对 FLV/F4V的解析,很清楚。
ISOIEC 14496-15                      :这个是对于sps,pps的解析
感谢各位网友的辛勤劳动,这里基本信息就先不讲解了,下面主要讲解在操作中遇到的几个问题
1:
    //•0: 96000 Hz
    //•1: 88200 Hz
    //•2: 64000 Hz
    //•3: 48000 Hz
    //•4: 44100 Hz
    //•5: 32000 Hz
    //•6: 24000 Hz
    //•7: 22050 Hz
    //•8: 16000 Hz
    //•9: 12000 Hz
    //•10: 11025 Hz
    //•11: 8000 Hz
    //•12: 7350 Hz
    //•13: Reserved
    //•14: Reserved
    //•15: frequency is written explictly
samplerate_t = 0x10;        //这里有的地方是 0x1c,但和采样率表对比有问题,对比AAC采样率44100HZ应该是0x10但有的flv中填写的是0x1c,这个需要研究下。

2:
typedef struct Tag_Video_AvcC
{
 unsigned char configurationVersion;
 unsigned char AVCProfileIndication;
 unsigned char profile_compatibility;
 unsigned char AVCLevelIndication;
 unsigned char reserved_1;
 unsigned char lengthSizeMinusOne;
 unsigned char reserved_2;
 unsigned char numOfSequenceParameterSets;  //一般都是一个
 unsigned int sequenceParameterSetLength;
 unsigned char * sequenceParameterSetNALUnit;
 unsigned char numOfPictureParameterSets;   //一般都是一个
 unsigned int  pictureParameterSetLength;
 unsigned char * pictureParameterSetNALUnit;
 unsigned char reserved_3;
 unsigned char chroma_format;
 unsigned char reserved_4;
 unsigned char bit_depth_luma_minus8;
 unsigned char reserved_5;
 unsigned char bit_depth_chroma_minus8;
 unsigned char numOfSequenceParameterSetExt;
 unsigned int sequenceParameterSetExtLength;
 unsigned char * sequenceParameterSetExtNALUnit;
}Video_AvcC;
这个是装 sps,pps的结构体//AVCDecoderConfigurationRecord官方文档有详细介绍,里面的信息名称有解析。

3:
从flv的audio,tag中读取出来的aac音频同样既不是latm,也不是adts,和MP4一样,需要添加7个字节的adts头才能正常播放
video的关键帧(I帧)前面需要添加sps,pps从 AVCDecoderConfigurationRecord可以获取的到,但从video,tag中读取的第一个关键帧(I帧)大部分是有一个SEI和一个I帧,有些不常见的是有多个SEI和一个I帧,这里未作处理,需要注意,
I帧的获取在:Video_Tag中有个参数:
//1: keyframe (for AVC, a seekable frame)
//2: inter frame (for AVC, a nonseekable frame)
//3: disposable inter frame (H.263 only)
//4: generated keyframe (reserved for server use only)
//5: video info/command frame
unsigned char FrameType;                   //帧类型

4:
Script_Tag中是存放了音视频的信息的地方,例如宽高,采样率,样本,是否为立体声等等。
unsigned char Type_1;
unsigned int  StringLength;                //第2-3个字节为UI16类型值,表示字符串的长度,一般总是0x000A(“onMetaData”长度)
unsigned int  ECMAArrayLength;             //一共有多少组数据,即有多少个类似:宽,高,采样率这样的信息
double duration;                           //文件持续时间        
double width;       //文件    宽度        
double height;       //文件    高度        
double videodatarate;             //视频数据速率        
double framerate;             //帧速率              
double videocodecid;      //视频编解码器id      
double audiosamplerate;      //音频采样率          
double audiodatarate;      //音频数据速率        
double audiosamplesize;      //音频样本大小        
int    stereo;       //是否是立体声        
double audiocodecid;      //音频编解码器id      
double filesize;      //文件大小            
double lasttimetamp;      //文件最后时间        
double lastkeyframetimetamp;               //文件最后关键帧时间点
unsigned char * Data;                      //信息剩下的数据,暂时没有解析
double char2double(unsigned char * buf,unsigned int size)
{
 double scr = 0.0;
 unsigned char buf_1[8];
 unsigned char buf_2[8];
 memcpy(buf_1,buf,size);
 //大小端问题
 buf_2[0] = buf_1[7];
 buf_2[1] = buf_1[6];
 buf_2[2] = buf_1[5];
 buf_2[3] = buf_1[4];
 buf_2[4] = buf_1[3];
 buf_2[5] = buf_1[2];
 buf_2[6] = buf_1[1];
 buf_2[7] = buf_1[0];
 scr = *(double *)buf_2;
 return scr;
}

void double2char(unsigned char * buf,double val)
{
 *(double *)buf = val;
}
从char * 中获取的buf,放到 double类型中,需要做一些转换,

“不是直接操作double的内存

而是就得一个临时的int变量后赋值”。这句话要理解下。

同样补习一下:浮点数表示,http://blog.youkuaiyun.com/juanjuan888/article/details/6672517
再有  for (int i = 0 ; i< tag->ECMAArrayLength ; i++)  //一共有多少组数据,即有多少个类似:宽,高,采样率这样的信息
这个循环之后  else if (Arry_InFomation == 0x03) //数组信息的结束
  {
   break;
  }
但Script_Tag的数据还未全完,这个还不知道剩下的数据是什么,下面在网上找下,进行解析,也希望高手指导。
 注:本程序的demo地址:http://download.youkuaiyun.com/detail/zhuweigangzwg/5472767
交流请加QQ:379969650

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值