//rmvb格式相关文档
#include <iostream>
#include <fstream>
using namespace std;
uint8_t RM[]=".RMF";
uint8_t DATA[]="DATA";
int rm_probe(uint8_t * data, uint32_t size)
{
return 0;
}
int rm_audio_decode_init(uint8_t * data, uint32_t size)
{
return 0;
}
int rm_get_audio_packet(uint8_t * data, uint32_t size)
{
return 0;
}
unsigned char* get_str(unsigned char *buf,unsigned char* s,int buf_size)
{
unsigned char * tmp = buf;
if(tmp == NULL || buf_size < 0)
return NULL;
for(int i=0; i<buf_size; i++)
{
*buf++ = *s++;
}
return tmp;
}
uint16_t get_le16(unsigned char *s)
{
unsigned int val=0;
for(int i=0; i<2; ++i)
{
val <<= 8;
val += *s++;
}
return val;
}
uint32_t get_le32(unsigned char *s)
{
uint32_t val=0;
for(int i=0; i<4; ++i)
{
val <<= 8;
val += *s++;
}
return val;
}
void mdpr_chunk_handle(ifstream &rmfile,long size,long seek)
{
unsigned char *buf = new unsigned char[size];
rmfile.seekg(seek, ios::beg);
rmfile.read((char*)buf,size);
int my_size = get_le32(buf+4);
cout<<"--data size :"<<my_size<<endl;
cout<<"--stream num:"<<get_le16(&buf[10])<<endl;
char name_size = buf[40];
char mime_size = buf[41+name_size];
int special_size = get_le32(buf+mime_size+name_size+42);
buf[41+name_size] = '\0';
buf[name_size+mime_size+42] = '\0';
cout<<"--stream name:"<<buf+41<<endl;
cout<<"--mime_type :"<<buf+name_size+42<<endl;
char audio_tag[] ={'.','r','a',0xFD}; //warning : version 3 not handled
if(strncmp(audio_tag,(char*)buf+46+name_size+mime_size,4)==0)
{
short version = get_le16(buf+50+name_size+mime_size);
if(version == 3)
{/*
st->codec->sample_rate = 8000;
st->codec->channels = 1;
st->codec->codec_type = CODEC_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_RA_144;
*/
cout<<"-------------version 3-----------"<<endl;
}
uint32_t sampleRate;
uint16_t sampleSize;
uint16_t numChannels;
uint16_t frame_size;
uint16_t block_align;
uint16_t interleave;
int codecdata_length;
unsigned char codec_buf[255]={'\0'};
//{cook CODEC_ID_COOK} {sipr CODEC_ID_SIPR} {atrc CODEC_ID_ATRAC3}
//{dnet CODEC_ID_AC3} {28_8 CODEC_ID_RA_288} {raac racp CODEC_ID_AAC}
interleave = get_le16(buf+name_size+mime_size+46+40);
frame_size = get_le16(buf+name_size+mime_size+46+42);
block_align = get_le16(buf+name_size+mime_size+46+44);
cout<<"--interleave:"<<interleave<<endl;
cout<<"--frame_size:"<<frame_size<<endl;
cout<<"--block_align:"<<block_align<<endl;
if(version==5)
{
sampleRate = get_le16(buf+name_size+mime_size+46+54);//54
sampleSize = get_le32(buf+name_size+mime_size+46+56);//4*13
numChannels= get_le16(buf+name_size+mime_size+46+60);//
get_str(codec_buf,buf+name_size+mime_size+46+66,4);
cout<<"--codec name:"<<codec_buf<<endl;
//skip 4byte
codecdata_length = (int)get_le32(buf+name_size+mime_size+46+70);
cout<<"--codec_extra_data_length:"<<codecdata_length<<endl;
}
else
{
sampleRate = get_le16(buf+name_size+mime_size+46+48);//48
sampleSize = get_le32(buf+name_size+mime_size+46+50);//4*13
numChannels= get_le16(buf+name_size+mime_size+46+54);//
char len = buf[name_size+mime_size+46+56];
get_str(codec_buf,buf+name_size+mime_size+46+57,len);
cout<<"--codec name:"<<codec_buf<<endl;
char len2 = buf[name_size+mime_size+46+len+57];
get_str(codec_buf,buf+name_size+mime_size+46+len+58,len2);
cout<<"--codec name2:"<<codec_buf<<endl;
//skip 2byte
codecdata_length = (int)get_le32(buf+name_size+mime_size+46+len+58+len2+3);
cout<<"--codec_extra_data_length:"<<codecdata_length<<endl;
}
cout<<"--audio version:"<<version<<endl;
cout<<"--sampleRate:"<<sampleRate<<endl;
cout<<"--sampleSize:"<<sampleSize<<endl;
cout<<"--Channels :"<<numChannels<<endl;
}
cout<<"--special size :"<<special_size<<", data:";
/*hex(cout);
for(int i = 0; i
cout<<(int)buf[46+name_size+mime_size+i]<<" ";
cout<
dec(cout);
*/
delete buf;
system("pause");
}
void data_chunk_handle(ifstream &rmfile,long size,long seek)
{
unsigned char buf[16];
rmfile.seekg(seek, ios::beg);
rmfile.read((char*)buf,16);
int packet_num = get_le32(&buf[10]);
short version = get_le16(&buf[8]);
cout<<"--data size :"<<get_le32(&buf[4])<<endl;
cout<<"--packet num:"<<packet_num<<endl;
cout<<"--version :"<<version<<endl;
int my_size = 0;
int packet = 0;
int my_seek = seek+18;
while(packet < packet_num)
{
system("pause");
rmfile.clear();
rmfile.seekg(my_seek, ios::beg);
rmfile.read((char*)buf,16);
packet ++;
int pktsize = get_le16(buf+2);
version = get_le16(buf);
cout<<hex<<my_seek;
cout<<dec;
cout<<"{ v: "<<version\
<<", s: "<<pktsize<<", sn: "\
<<get_le16(buf+4)<<", ts: "<<get_le32(buf+6)<<" }";
//cout<<", groupnum:"<<(int)buf[10]<<", flag:"<<(int)buf[11];
hex(cout);
if(version==0)
{
cout<<", data {"<<(int)buf[12]<<","<<(int)buf[13]<<","<<(int)buf[14]<<","<<(int)buf[15]<<"} }"<<endl;
}
else if(version==1)
{
cout<<", data {"<<(int)buf[13]<<","<<(int)buf[14]<<","<<(int)buf[15]<<","<<(int)buf[16]<<"} }"<<endl;
}
else
{
cout<<endl;
}
dec(cout);
if(version >3 ||version < 0||get_le16(buf+4)>32)
break;
my_seek += pktsize;
}
}
int main(int argc, char* argv[])
{
//rmfile.open("G:\\rmff\\rmff\\rminfo\\02.rm",ifstream::binary|ifstream::in);//need "\\"
//horrible use | please!
ifstream rmlist("F:\\real\\rmlist.txt");
locale::global(std::locale("")); //or setlocale(LC_ALL,"Chinese-simplified");
unsigned char buf[8];
char rmname[255] = "11858095759904908288_421.rmvb";
//while(!rmlist.eof())
//{
//rmlist.getline(rmname,255);
ifstream rmfile;
rmfile.open(rmname,ifstream::binary|ifstream::in);
//rmfile.open("G:\\rmff\\rmff\\rminfo\\03.rm",ifstream::binary|ifstream::in);
cout<<rmname<<endl;
if(rmfile.is_open())
{
long seekpos = 0;
rmfile.seekg(0, ios::end);
long length = rmfile.tellg();
rmfile.seekg (0, ios::beg);
while(!rmfile.eof())
{
rmfile.read((char*)buf,8);
uint32_t size =0;
for(int i=4; i<8; ++i)
{
size <<= 8;
size += buf[i];//需要无符号才行
}
cout<<"find:"<<buf[0]<<buf[1]<<buf[2]<<buf[3]<<" size:"<<size<<" pos:"<<seekpos<<endl;
if(size == 0)
break;
if(strncmp("DATA",(char*)buf,4)==0)
{
data_chunk_handle(rmfile,size,seekpos);
}
else if(strncmp("MDPR",(char*)buf,4)==0)
{
mdpr_chunk_handle(rmfile,size,seekpos);
}
seekpos += size;
rmfile.seekg(seekpos, ios::beg);
cout<<endl;
if(seekpos<0)
break;
//
}
rmfile.close();
system("pause");
}
//}
system("pause");
return 0;
}
|