예제 #1
0
/**
    \fn TsIndexer
*/
TsIndexer::TsIndexer(listOfTsAudioTracks *trk)
{
    memset(&spsInfo,0,sizeof(spsInfo));
    index=NULL;
    pkt=NULL;
    audioTracks=NULL;
    beginConsuming=0;
    ui=createWorking ("Indexing");
    audioTracks=trk;
    ticktock.reset();
}
예제 #2
0
/**
    \fn rederiveFrameType
    \brief 
*/
bool        ADM_Composer::rederiveFrameType(vidHeader *demuxer)
{
    uint32_t flags,flagsDecoded;
    uint8_t *buffer;
    aviInfo info;

    demuxer->getVideoInfo (&info);
    frameIdentifier id=ADM_getFrameIdentifier(info.fcc);
    if(!id)
    {
        printf("[Editor]Cannot get identifer for this fourcc\n");
        return true;
    }
    uint32_t size=demuxer->getMainHeader()->dwWidth;
    size*=demuxer->getMainHeader()->dwHeight*3;
    buffer=new uint8_t[size];

    ADMCompressedImage img;
    img.data=buffer;

    int max=100;
    if(max>info.nb_frames)max=info.nb_frames;

    int nbOk=0,nbKo=0;

    for(int i=0;i<max;i++)
    {
        demuxer->getFlags(i,&flags);
        demuxer->getFrame(i,&img);
        flagsDecoded=id(img.dataLength,img.data);
        if(flagsDecoded==flags) nbOk++;
            else nbKo++;
    }
    printf("[Editor] Muxer has %d frames right, %d frames wrong\n",nbOk,nbKo);
    if(!nbKo)  
    {
        delete [] buffer;
        buffer=NULL;
        return true;
    }
    // Demuxer is wrong, rederive all frames...
    DIA_workingBase *work=createWorking(QT_TRANSLATE_NOOP("adm","Updating frametype"));
    for(int i=0;i<info.nb_frames;i++)
    {
        work->update(i,info.nb_frames);
        demuxer->getFrame(i,&img);
        flagsDecoded=id(img.dataLength,img.data);
        demuxer->setFlag(i,flagsDecoded);
    }
    delete [] buffer;
    buffer=NULL;
    delete work;
    return false;
}
예제 #3
0
/*
	Unpack all frames without displaying them to check for error

*/
void A_videoCheck( void)
{
#if 0
uint32_t nb=0;
//uint32_t buf[720*576*2];
uint32_t error=0;
ADMImage *aImage;
DIA_workingBase *work;

	nb = avifileinfo->nb_frames;
	work=createWorking(QT_TRANSLATE_NOOP("adm","Checking video"));
	aImage=new ADMImage(avifileinfo->width,avifileinfo->height);
  for(uint32_t i=0;i<nb;i++)
  {
	work->update(i, nb);
      	if(!work->isAlive()) break;
	if(!GUI_getFrameContent (aImage,i))
	{
		error ++;
		printf("Frame %u has error\n",i);
	}

    };
  delete work;
  delete aImage;
  if(error==0)
    GUI_Info_HIG(ADM_LOG_IMPORTANT,QT_TRANSLATE_NOOP("adm","No error found"), NULL);
else
	{
		char str[400];
                sprintf(str,QT_TRANSLATE_NOOP("adm","Errors found in %u frames"),error);
		GUI_Info_HIG(ADM_LOG_IMPORTANT,str, NULL);

	}
	GUI_GoToFrame(0);
#endif
}
예제 #4
0
/**
    \fn handleFirstPass
*/
ADM_coreVideoEncoder *admSaver::handleFirstPass(ADM_coreVideoEncoder *pass1)
{
#define BUFFER_SIZE 1920*1800*3
ADM_coreVideoFilter  *last;
                int sze=chain->size();
                ADM_assert(sze);
                last=(*chain)[sze-1]; // Grab last filter


uint64_t videoDuration=last->getInfo()->totalDuration;



                if(videoDuration<5000) videoDuration=5000;
                printf("[Save] Performing Pass one,using %s as log file\n",logFileName.c_str());
                pass1->setPassAndLogFile(1,logFileName.c_str());
                if(false==pass1->setup())
                {
                    printf("[Save] setup failed for pass1 encoder\n");
                    delete pass1;
                    return NULL;
                }
                ADMBitstream bitstream;

                uint8_t *buffer=new uint8_t[BUFFER_SIZE];
                bitstream.data=buffer;
                bitstream.bufferSize=BUFFER_SIZE;
                DIA_workingBase  *encoding=createWorking("Pass1");
                int nbFrames=0;
                while(pass1->encode(&bitstream))
                {
                    if(bitstream.pts!=ADM_NO_PTS)
                    {
                        float f=100;
                        f/=videoDuration;
                        f*=bitstream.pts;
                        uint32_t percent=(uint32_t)f;
                        encoding->update(percent);
                    }
                    nbFrames++;
                }
                delete encoding;
                delete [] buffer;
                delete pass1;
                encoding=NULL;
                buffer=NULL;
                pass1=NULL;

                printf("[Save] Pass 1 done, encoded %d frames, restarting for pass 2\n",nbFrames);
                // Destroy filter chain & create the new encoder
                destroyVideoFilterChain(chain);
                chain=NULL;
                chain=createVideoFilterChain(markerA,markerB);

                if(!chain)
                {
                    printf("[Save] Cannot recreate video filter chain\n");
                    return NULL;
                }
                int sz=chain->size();
                ADM_assert(sz);
                last=(*chain)[sz-1]; // Grab last filter
                ADM_coreVideoEncoder *pass2=createVideoEncoderFromIndex(last,videoEncoderIndex,muxer->useGlobalHeader()); 
                if(!pass2)
                {
                    printf("[Save] Cannot create encoder for pass 2\n");
                    return NULL;
                }
                pass2->setPassAndLogFile(2,logFileName.c_str());
#if 0
                buffer=new uint8_t[BUFFER_SIZE];
                pass2->setup();
                nbFrames=0;
                bitstream.data=buffer;
                encoding=createWorking("Pass2");
                while(pass2->encode(&bitstream))
                {
                    if(bitstream.pts!=ADM_NO_PTS)
                    {
                        float f=100;
                        f/=videoDuration;
                        f*=bitstream.pts;
                        uint32_t percent=(uint32_t)f;
                        encoding->update(percent);
                    }
                    nbFrames++;
                }
                printf(": Pass2 done : %d frames this time\n",nbFrames);
                delete [] buffer;
                delete encoding;

#endif
    return pass2;
}
예제 #5
0
uint8_t asfHeader::loadVideo(asfChunk *s)
{
  uint32_t w,h,x;
            printf("--\n");
            w=s->read32();
            h=s->read32();
            s->read8();
            x=s->read16();
            _isvideopresent=1;

            memset(&_mainaviheader,0,sizeof(_mainaviheader));
            _mainaviheader.dwWidth=w;
            _mainaviheader.dwHeight=h;
            _video_bih.biWidth=w;
            _video_bih.biHeight=h;
            printf("Pic Width  %04d\n",w);
            printf("Pic Height %04d\n",h);
            printf(" BMP size  %04d (%04d)\n",x,(int)sizeof(ADM_BITMAPINFOHEADER));
            s->read((uint8_t *)&_video_bih,sizeof(ADM_BITMAPINFOHEADER));

		#ifdef ADM_BIG_ENDIAN
			Endian_BitMapInfo(&_video_bih);
		#endif


            _videostream.fccHandler=_video_bih.biCompression;
            printf("Codec : <%s> (%04x)\n",
                    fourCC::tostring(_video_bih.biCompression),_video_bih.biCompression);
            if(fourCC::check(_video_bih.biCompression,(uint8_t *)"DVR "))
            {
              // It is MS DVR, fail so that the mpeg2 indexer can take it from here
              _videostream.fccHandler=_video_bih.biCompression=fourCC::get((uint8_t *)"MPEG");
              printf("This is MSDVR, not ASF\n");
              return 0; 
            }
            printBih(&_video_bih);
#if 1
            if(_video_bih.biSize>sizeof(ADM_BITMAPINFOHEADER))
            {
                    x=_video_bih.biSize;
#else
            if(x>sizeof(ADM_BITMAPINFOHEADER))
            {
#endif
              _videoExtraLen=x-sizeof(ADM_BITMAPINFOHEADER);
              _videoExtraData=new uint8_t[_videoExtraLen];
              s->read(_videoExtraData,_videoExtraLen);
              ADM_info("We have %d bytes of extra data for video.\n",(int)_videoExtraLen);
            }else
            {
                ADM_info("No extra data for video\n");
            }
            uint64_t l=ftello(_fd);
            printf("Bytes left : %d\n",(int)(s->endPos()-l));
            return 1;
}
/**
    \fn      buildIndex
    \brief   Scan the file to build an index
    
    Header Chunk
            Chunk
            Chunk
            Chunk
            
    Data chunk
            Chunk
            Chunk
            
    We skip the 1st one, and just read the header of the 2nd one
    
*/
uint8_t asfHeader::buildIndex(void)
{
  uint32_t fSize;
  const chunky *id;
  uint32_t chunkFound;
  uint32_t r=5;
  uint32_t len;
  
  fseeko(_fd,0,SEEK_END);
  fSize=ftello(_fd);
  fseeko(_fd,0,SEEK_SET);
  
  asfChunk h(_fd);
  printf("[ASF] ********** Building index **********\n");
  printf("[ASF] Searching data\n");
  while(r--)
  {
    h.nextChunk();    // Skip headers
    id=h.chunkId();
    h.dump();
    if(id->id==ADM_CHUNK_DATA_CHUNK) break;
    h.skipChunk();
  }
  if(id->id!=ADM_CHUNK_DATA_CHUNK) return 0;
  // Remove leftover from DATA_chunk
 // Unknown	GUID	16
//       Number of packets	UINT64	8
//       Unknown	UINT8	1
//       Unknown	UINT8	1
//   
  h.read32();
  h.read32();
  h.read32();
  h.read32();
  _nbPackets=(uint32_t) h.read64();
  h.read16();
  
  len=h.chunkLen-16-8-2-24;
  
  printf("[ASF] nbPacket  : %u\n",_nbPackets);
  printf("[ASF] len to go : %u\n",len);
  printf("[ASF] scanning data\n");
  _dataStartOffset=ftello(_fd);
  
  // Here we go
  asfPacket *aPacket=new asfPacket(_fd,_nbPackets,_packetSize,
                                   &readQueue,&storageQueue,_dataStartOffset);
  uint32_t packet=0;
#define MAXIMAGE (_nbPackets)
  uint32_t sequence=0;
  uint32_t ceilImage=MAXIMAGE;

  nbImage=0;
  
  len=0;
  asfIndex indexEntry;
  memset(&indexEntry,0,sizeof(indexEntry));
  bool first=true;
  DIA_workingBase *progressBar=createWorking("Indexing");
  uint32_t fileSizeMB=(uint32_t)(fSize>>10);

  uint64_t lastDts[ASF_MAX_AUDIO_TRACK];
  for(int i=0;i<ASF_MAX_AUDIO_TRACK;i++)
  {
        lastDts[i]=0;
  }


  while(packet<_nbPackets)
  {
    while(readQueue.size())
    {
      asfBit *bit=NULL;

      // update UI
      uint32_t curPos=(uint32_t)(ftello(_fd)>>10);
      progressBar->update(curPos,fileSizeMB);

      bit=readQueue.front();
      readQueue.pop_front();

      // --
      uint64_t dts=bit->dts;
      uint64_t pts=bit->pts;
        aprintf("** DTS=%s\n",ADM_us2plain(dts));
        aprintf("** PDTS=%s\n",ADM_us2plain(pts));
      if(bit->stream==_videoStreamId)
      {
          aprintf(">found video packet of size=%d off=%d seq %d, while curseq =%d, dts=%s",
                        bit->len,bit->offset,  bit->sequence,curSeq, ADM_us2plain(dts));
          aprintf(" pts=%s\n",ADM_us2plain(pts));
          if(bit->sequence!=sequence || first==true)
          {
            if(first==false)
            {
                indexEntry.frameLen=len;
                aprintf("Pushing video frame index=%d seq=%d pts=%s \n",
                        _index.size(),
                        indexEntry.segNb,ADM_us2plain(indexEntry.pts));
                aprintf("dts=%s\n",ADM_us2plain(indexEntry.dts));
                _index.append(indexEntry);
            }
            
            aprintf("New sequence\n");
            if( ((sequence+1)&0xff)!=(bit->sequence&0xff))
            {
                ADM_warning("!!!!!!!!!!!! non continuous sequence %u %u\n",sequence,bit->sequence); 
            }
            
            
            indexEntry.frameLen=0;
            indexEntry.segNb=bit->sequence;
            indexEntry.packetNb=bit->packet;
            indexEntry.flags=bit->flags;
            indexEntry.dts=dts;
            indexEntry.pts=pts;
            if(first==false)
            {
                sequence=bit->sequence;
                readQueue.push_front(bit); // reuse it next time
                len=0;
                continue;

            }else
            {
                sequence=bit->sequence;
                first=false; // first packet
            }
            
          }
          len+=bit->len;
      } // End of video stream Id
      else  // Audio ?
      {
        int found=0;
        for(int i=0;i<_nbAudioTrack && !found;i++)
        {
          if(bit->stream == _allAudioTracks[i].streamIndex)
          {
            if(bit->pts!=ADM_NO_PTS)
            {
                if(!lastDts[i] || (bit->pts>lastDts[i]+500000L)) // seek point every 500 ms
                {
                    asfAudioSeekPoint seek;
                        seek.pts=bit->pts;
                        seek.packetNb=bit->packet;
                        (audioSeekPoints[i]).append(seek);
      
#if 1
                        if(!lastDts[i])
                            printf("Adding seek point for track %d at %s (packet=%d)\n",
                            i,ADM_us2plain(bit->pts),(int)seek.packetNb);
#endif
                        lastDts[i]=bit->pts;
                        aprintf("Adding seek point for track %d at %s (packet=%d)\n",
                            i,ADM_us2plain(bit->pts),(int)seek.packetNb);
                }
            }
            found=1;
          }
        }
        if(!found) 
        {
          printf("Unmapped stream %u\n",bit->stream); 
        }
      }
      delete [] bit->data;
      bit->data=NULL;
      storageQueue.push_back(bit);
    }
    //working->update(packet,_nbPackets);

    packet++;
    aPacket->nextPacket(0xff); // All packets
    aPacket->skipPacket();
  }
  delete progressBar;
  delete aPacket;
  //delete working;
  /* Compact index */
  
  fseeko(_fd,_dataStartOffset,SEEK_SET);
  printf("[ASF] %u images found\n",nbImage);
  printf("[ASF] ******** End of buildindex *******\n");

  nbImage=_index.size();;
  if(!nbImage) return 0;
  
  uint64_t shift=60*1000*1000;
  bool canShift=false;
  uint64_t tPts;
  tPts=_index[0].pts;
    ADM_info("First image pts: %s, dts: %s\n",ADM_us2plain(tPts), ADM_us2plain(_index[0].dts));
   if(tPts != ADM_NO_PTS)
    {
        shift=tPts;
        ADM_info("Video shift = %s\n",ADM_us2plain(tPts));
        canShift=true;
    }else
        canShift=false;
    for(int i=0;i<_nbAudioTrack;i++)
    {
        if(!audioSeekPoints[i].size())
        {
            ADM_info("audio track : %d, no seek\n",i);
            canShift=false;
            continue;
        }
        tPts=audioSeekPoints[i][0].pts;
        ADM_info("audio track : %d, %s\n",i,ADM_us2plain(tPts));
        if(tPts<shift) shift=tPts;
    }
    if(canShift)
    {
            ADM_info("Shifting a/v raw=%s\n",ADM_us2plain(shift));
    }else
    {
            ADM_info("Can t shift\n");
            shift=0;
    }
  _videostream.dwLength=_mainaviheader.dwTotalFrames=nbImage;
  
  _index[0].flags=AVI_KEY_FRAME;
  if(_index[0].pts==ADM_NO_PTS) _index[0].pts=_index[0].dts;
  // Update fps
  // In fact it is an average fps
  //
    _videostream.dwScale=1000;
    // check if we have a duration per frame for video...
    int n=frameDurationMapping.size();
    int dex=-1;
    for(int i=0;i<n;i++)
    {
        if(frameDurationMapping[i].streamNb==_videoStreamId)
            dex=i;
    }
    if(dex!=-1)
    {
        ADM_info("Average fps provided\n");
        setFps(frameDurationMapping[dex].usPerFrame);
    }
    else
    {
      ADM_info("Fps not provided, guessing it from nbFrame and duration\n");
      uint32_t avgFps;
      if(_index[nbImage-1].pts!=ADM_NO_PTS && _index[0].pts!=ADM_NO_PTS)
      {
          float f=(_index[nbImage-1].pts-_index[0].pts);
            f/=nbImage; // average duration of 1 image in us
            setFps((uint64_t) f);
      }else
        {
            printf("[Asf] No pts, setting 30 fps hardcoded\n");
            _videostream.dwRate=(uint32_t)30000;;
        }
    }
    if(shift)
    {
        double frames3=_videostream.dwScale;
                frames3/=_videostream.dwRate;
                frames3*=3*1000*1000; // 
            ADM_info("3 frames time = %s\n",ADM_us2plain((uint64_t)frames3));
        uint64_t frame64=(uint64_t)frames3;
        if(frame64<shift) shift=shift-frame64;
        else shift=0;

        shiftAudioVideoBy(shift);
    }
    return 1;
  
}
예제 #6
0
/**
    \fn DIA_working
    \brief Constructor
*/
DIA_working::DIA_working( const char *title )
{
    son=NULL;
    son=createWorking(title);
}