Exemplo n.º 1
0
/** 
  \fn find
  \brief Search for the tag given and returns the corresponding atom
*/
uint8_t ADM_ebml_file::simplefind(MKV_ELEM_ID  prim,uint64_t *len,uint32_t rewind)
{
  uint64_t id,alen;
  ADM_MKV_TYPE type;
  const char *ss;
  

    vprintf("[MKV] Simple Searching for tag %llx\n",prim);
    if(rewind) seek(_begin);
   
      while(!finished())
      {
          readElemId(&id,&alen);
          if(!ADM_searchMkvTag( (MKV_ELEM_ID)id,&ss,&type))
          {
              vprintf("[MKV] Tag 0x%x not found\n",id);
              skip(alen);
              continue;
           }
          if(!alen)
          {
            printf("[MKV] WARNING ZERO SIZED ATOM %s %llu/%llu\n",ss,tell(),_fileSize);
            continue; 
          }
          vprintf("Found Tag : %x (%s)\n",id,ss);
          if(id==prim)
          {
            *len=alen;
            return 1;
          }else
            skip(alen);
      }
    vprintf("[MKV] Failed to locate %llx\n",prim);
    return 0;
}
Exemplo n.º 2
0
/**
    \fn analyzeTracks
    \brief Read Tracks Info.
*/
uint8_t mkvHeader::analyzeTracks(void *head,uint32_t headlen)
{
  uint64_t id,len;
  ADM_MKV_TYPE type;
  const char *ss;
 ADM_ebml_file father( (ADM_ebml_file *)head,headlen);
 while(!father.finished())
 {
      father.readElemId(&id,&len);
      if(!ADM_searchMkvTag( (MKV_ELEM_ID)id,&ss,&type))
      {
        printf("[MKV] Tag 0x%x not found (len %llu)\n",id,len);
        father.skip(len);
        continue;
      }
      ADM_assert(ss);
      if(id!=MKV_TRACK_ENTRY)
      {
        printf("[MKV] skipping %s\n",ss);
        father.skip(len);
        continue;
      }
      if(!analyzeOneTrack(&father,len)) return 0;
 }
 return 1;
}
Exemplo n.º 3
0
/**
    \fn walk
    \brief Walk a matroska atom and print out what is found.
*/
uint8_t mkvHeader::walk(void *seed)
{
  uint64_t id,len;
  ADM_MKV_TYPE type;
  const char *ss;

   ADM_ebml_file *father=(ADM_ebml_file *)seed;
    while(!father->finished())
   {
      father->readElemId(&id,&len);
      if(!ADM_searchMkvTag( (MKV_ELEM_ID)id,&ss,&type))
      {
        printf("[MKV] Tag 0x%x not found (len %llu)\n",id,len);
        father->skip(len);
        continue;
      }
      ADM_assert(ss);
      switch(type)
      {
        case ADM_MKV_TYPE_CONTAINER:
                  father->skip(len);
                  printf("%s skipped\n",ss);
                  break;
        case ADM_MKV_TYPE_UINTEGER:
                  printf("%s:%llu\n",ss,father->readUnsignedInt(len));
                  break;
        case ADM_MKV_TYPE_INTEGER:
                  printf("%s:%lld\n",ss,father->readSignedInt(len));
                  break;
        case ADM_MKV_TYPE_STRING:
        {
                  char string[len+1];
                  string[0]=0;
                  father->readString(string,len);
                  printf("%s:<%s>\n",ss,string);
                  break;
        }
        default:
                printf("%s skipped\n",ss);
                father->skip(len);
                break;
      }
   }
  return 1;
}
Exemplo n.º 4
0
int main(int argc, char *argv[])
{
  ADM_ebml_file *ebml=new ADM_ebml_file ;
  uint64_t id,len;
  ADM_MKV_TYPE type;
  const char *ss;
  
  if(!ebml->open(argv[1])) ADM_assert(0);
  
  // Read level 1 stuff
  while(!ebml->finished())
  {
      ebml->readElemId(&id,&len);
      if(!ADM_searchMkvTag( (MKV_ELEM_ID)id,&ss,&type))
      {
        printf("[MKV] Tag 0x%x not found\n",id);
        ebml->skip(len);
        continue;
      }
      uint64_t w=ebml->tell();
      printf("Found Tag : %x (%s) at 0x%x size %d end at 0x%x\n",id,ss,w,len,w+len);
      if(type==ADM_MKV_TYPE_CONTAINER)
      {
        ADM_mkvWalk(ebml,len);
        if(ebml->tell() > w+len)
        {
                        printf("*** WARNING INCORRECT CONTAINER SIZE : %d vs real size %d\n",len,ebml->tell()-w);
        }
        else
        {
                printf(">Seeking from 0x%x to  0x%x (size %d)\n",w,w+len,len);
                ebml->seek(w+len);
        }
      }else
        ebml->skip(len);
  }
  return 0;
}
uint8_t             mkvAudio::getPacket(uint8_t *dest, uint32_t *packlen, uint32_t *samples,uint32_t *timecode)
{
  uint64_t fileSize,len,bsize,pos;
  uint32_t alen,vlen;
  uint64_t id;
  ADM_MKV_TYPE type;
  const char *ss;
  vprintf("Enter: Currently at :%llx\n",_clusterParser->tell());
    // Have we still lace to go ?
    if(_currentLace<_maxLace)
    {
      _clusterParser->readBin(dest,_Laces[_currentLace]);
      *packlen= _Laces[_currentLace];
      vprintf("Continuing lacing : %u bytes, lacing %u/%u\n",*packlen,_currentLace,_maxLace);
      _currentLace++;
      *samples=_frameDurationInSample;
      *timecode=_curTimeCode;
      
      return 1;
    }
    while(1)
    {
        vprintf("While: Currently at :%llx\n",_clusterParser->tell());
        // need to switch cluster ?
        if(_clusterParser->finished())
        {
          if(!goToCluster(_currentCluster+1))
          {
            printf("[MKVAUDIO] cannot go to next cluster\n");
            return 0; 
          }
          _currentCluster++;
        }
        // Ok read a new block
        while(!_clusterParser->finished())
        {
          
            _clusterParser->readElemId(&id,&len);
            pos=_clusterParser->tell();
            if(!ADM_searchMkvTag( (MKV_ELEM_ID)id,&ss,&type))
            {
              vprintf("[MKVAUDIO] unknown tag %x\n",id);
              _clusterParser->skip(len);
              continue;
            }
            
            vprintf("[MKVAudio]Found tag %x (%s) at 0x%llx len %u\n",id,ss,_clusterParser->tell(),len);
            
            switch(id)
            {
              default:
              case MKV_TIMECODE:     _clusterParser->skip(len);  break;
              case MKV_BLOCK_GROUP:    break;
              case MKV_SIMPLE_BLOCK: 
              case MKV_BLOCK: 
              {
                  uint32_t tid=_clusterParser->readEBMCode();
                  uint64_t tail=pos+len;
                  uint64_t head=pos;
                  
                  // FIXME WARNING ASSUME TRACK FITS ON 1 BYTE!
                  len--; 
                  vprintf("Tid = %u, my tid=%u\n",tid,_track->streamIndex);
                  if(tid!=_track->streamIndex)
                    {
                      _clusterParser->skip(len); // skip this block
                      break; // not our track
                    }
                    // Skip timecode
                    int tc=_clusterParser->readUnsignedInt(2); // FIXME Should be signed
                    if(tc<0) tc=0;
                    _curTimeCode=(uint32_t )tc;
                    len-=2;
                    *timecode=_curTimeCode;
                    uint8_t flags=_clusterParser->readu8();
                    len--;
                    uint32_t remaining=len;
                    uint32_t lacing=((flags>>1)&3);
                    switch(lacing)
                    {
                      case 0 : // no lacing 
                          
                              vprintf("No lacing :%d bytes\n",remaining);
                              _clusterParser->readBin(dest,remaining);
                              *packlen=remaining; 
                              *samples=_frameDurationInSample;
                              _currentLace=_maxLace=0;
                              
                              return 1;
                      case 1: //Xiph lacing
                        {
                                int nbLaces=_clusterParser->readu8()+1;
                                
                                ADM_assert(nbLaces<MKV_MAX_LACES);
                                for(int i=0;i<nbLaces-1;i++)
                                {
                                  int v=0;
                                  int lce=0;
                                  while(  (v=_clusterParser->readu8())==0xff) lce+=v;
                                  lce+=v;
                                  _Laces[i]=lce;
                                }
                                int64_t d=_clusterParser->tell();
                                
                                d=tail-d;
                                /* We have the remaining size after laces, substract the already known lace size */
                                for(int i=0;i<nbLaces-1;i++)
                                {
                                  d-=_Laces[i]; 
                                }
                                // What is left is the sift of the last lace
                                if(d>0)
                                  _Laces[nbLaces-1]=(uint32_t)d; 
                                else
                                {
                                  printf("[MKVAUDIO] OOps overflow on Xiph\n");
                                  nbLaces--; 
                                }

                                
                                _currentLace=0;
                                _maxLace=nbLaces;
                                return getPacket(dest, packlen, samples);
                              }
                              
                              break;
                      case 2 : // constant size lacing
                              {
                                int nbLaces=_clusterParser->readu8()+1;
                                
                                remaining--;
                                int bsize=remaining/nbLaces;
                                vprintf("NbLaces :%u lacesize:%u\n",nbLaces,bsize);
                                ADM_assert(nbLaces<MKV_MAX_LACES);
                                for(int i=0;i<nbLaces;i++)
                                {
                                  _Laces[i]=bsize; 
                                }
                                _currentLace=0;
                                _maxLace=nbLaces;
                                return getPacket(dest, packlen, samples);
                              }
                              break;
                      case 3: // Ebml lacing
                        {
                                
                                int nbLaces=_clusterParser->readu8()+1;
                                int32_t curSize=_clusterParser->readEBMCode();
                                int32_t delta;
                                
                                vprintf("Ebml nbLaces :%u lacesize(0):%u\n",nbLaces,curSize);
                                
                                _Laces[0]=curSize;
                                ADM_assert(nbLaces<MKV_MAX_LACES);
                                for(int i=1;i<nbLaces-1;i++)
                                {
                                  delta=_clusterParser->readEBMCode_Signed();
                                  vprintf("Ebml delta :%d lacesize[%d]->:%d\n",delta,i,curSize+delta);
                                  curSize+=delta;
                                  ADM_assert(curSize>0);
                                  _Laces[i]=curSize; 
                                 
                                }
                                int64_t d=_clusterParser->tell();
                                
                                d=tail-d;
                                /* We have the remaining size after laces, substract the already known lace size */
                                for(int i=0;i<nbLaces-1;i++)
                                {
                                  d-=_Laces[i]; 
                                }
                                // What is left is the sift of the last lace
                                if(d>0)
                                  _Laces[nbLaces-1]=(uint32_t)d; 
                                else
                                {
                                  printf("[MKVAUDIO] OOps overflow on ebml\n");
                                  nbLaces--; 
                                }
                                _currentLace=0;
                                _maxLace=nbLaces;
                                return getPacket(dest, packlen, samples);
                              }
                              break;
                      default:
                            printf("Unsupported lacing %u\n",lacing);
                            _clusterParser->seek(pos+len);
                    }
                
              }
              break;
            }
        }
  }
  return 0;
}
Exemplo n.º 6
0
void ADM_mkvWalk(ADM_ebml_file *working, uint32_t size)
{
  uint64_t id,len;
  ADM_MKV_TYPE type;
  const char *ss;
  static int recurse=0;
  uint64_t pos; 
  
  recurse++;
   ADM_ebml_file son(working,size);
   while(!son.finished())
   {
      pos=son.tell();
      son.readElemId(&id,&len);
      if(!ADM_searchMkvTag( (MKV_ELEM_ID)id,&ss,&type))
      {
        recTab();printf("[MKV] Tag 0x%x not found\n",id);
        son.skip(len);
        continue;
      }
      recTab();printf("at 0x%llx, Found Tag : %x (%s) type %d (%s) size %d, start at 0x%x end at 0x%x\n",pos,id,ss,type,ADM_mkvTypeAsString(type),len,working->tell(),working->tell()+len);
      uint32_t val;
      switch(type)
      {
        case ADM_MKV_TYPE_CONTAINER:
                  //if(id!=MKV_CLUSTER)
                  if(len)
                    ADM_mkvWalk(&son,len);
                    else
                    {
                                printf("******************************* WARNING ZERO SIZE ******************\n");
                    }

                  //else
                  //    son.skip(len);
                  break;
        case ADM_MKV_TYPE_UINTEGER:
                  val=son.readUnsignedInt(len);
                  recTab();printf("\tval uint: %llu (0x%llx) \n",val,val);
                  break;
        case ADM_MKV_TYPE_UTF8:
        {
                  char string[len+1];
                  string[0]=0;
                  son.readString(string,len);
                  recTab();printf("\tval utf8 as string: <%s> \n",string);
        }
                  break;
                  
        case ADM_MKV_TYPE_FLOAT:
                  recTab();printf("\tval float: %f \n",son.readFloat(len));
                  break;
        case ADM_MKV_TYPE_INTEGER:
                  recTab();printf("\tval int: %lld \n",son.readSignedInt(len));
                  break;
        case ADM_MKV_TYPE_STRING:
        {
                  char string[len+1];
                  string[0]=0;
                  son.readString(string,len);
                  recTab();printf("\tval string: <%s> \n",string);
                  break;
        }
        default:
                if(id==MKV_BLOCK)
                {
                        recTab();printf("\t\tTrack :%u",son.readu8()-128); // Assume 1 byte code
                        //printf(" Timecode:%d",son.reads16());
                        son.skip(2);
                        int lacing=son.readu8();
                        printf(" Lacing :%x ");
                        if(lacing&1) printf(" keyframe ");
                        lacing=(lacing>>1)&3;
                        switch(lacing)
                        {
                                       case 0:printf("No lacing\n");break;
                                       case 1:printf("Xiph lacing\n");break;
                                       case 3:printf("Ebml lacing\n");break;
                                       case 2:printf("Fixed lacing :%u remaining:%u\n",son.readu8()+1,len-5);len--;break;

                        }
                        son.skip(len-4);

                }
                else
                {
                        recTab();printf("Skipping %s\n",ss);
                        son.skip(len);
                }
                break;
      }