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<special_size; i++)
         cout<<(int)buf[46+name_size+mime_size+i]<<" ";
    cout<<endl;
     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  > | | 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 ;
}

猜你喜欢

转载自blog.csdn.net/kemengli/article/details/48395173
今日推荐