bool VideoTheoraPlayer::update() {
    _currentTime = _freezeGame ? _gameRef->getLiveTimer()->getTime() : _gameRef->getTimer()->getTime();

    if (!isPlaying()) {
        return STATUS_OK;
    }

    if (_playbackStarted /*&& m_Sound && !m_Sound->IsPlaying()*/) {
        return STATUS_OK;
    }

    if (_playbackStarted && !_freezeGame && _gameRef->_state == GAME_FROZEN) {
        return STATUS_OK;
    }

    if (_theoraDecoder) {
        if (_theoraDecoder->endOfVideo() && _looping) {
            warning("Should loop movie %s, hacked for now", _filename.c_str());
            _theoraDecoder->rewind();
            //HACK: Just reinitialize the same video again:
            return resetStream();
        } else if (_theoraDecoder->endOfVideo() && !_looping) {
            debugC(kWintermuteDebugLog, "Finished movie %s", _filename.c_str());
            _state = THEORA_STATE_FINISHED;
            _playbackStarted = false;
            if (_freezeGame) {
                _gameRef->unfreeze();
            }
        }
        if (_state == THEORA_STATE_PLAYING) {
            if (!_theoraDecoder->endOfVideo() && _theoraDecoder->getTimeToNextFrame() == 0) {
                const Graphics::Surface *decodedFrame = _theoraDecoder->decodeNextFrame();
                if (decodedFrame) {
                    _surface.free();
                    _surface.copyFrom(*decodedFrame);
                    if (_texture) {
                        writeVideo();
                    }
                }
            }
            return STATUS_OK;
        }
    }
    // Skip the busy-loop?
    if ((!_texture || !_videoFrameReady) && _theoraDecoder && !_theoraDecoder->endOfVideo()) {
        // end playback
        if (!_looping) {
            _state = THEORA_STATE_FINISHED;
            if (_freezeGame) {
                _gameRef->unfreeze();
            }
            return STATUS_OK;
        } else {
            resetStream();
            return STATUS_OK;
        }
    }

    return STATUS_OK;
}
Пример #2
0
//_______________________________________________
uint8_t ADM_ogmWrite::save(const char *name)
{

uint8_t *bufr;
uint32_t len,flags;
uint8_t error=0;


		_fd=fopen(name,"wb");
		if(!_fd)
		{
                        GUI_Error_HIG(QT_TR_NOOP("File error"), QT_TR_NOOP("Cannot open \"%s\" for writing."), name);
			return 0;
		}

		videoStream=new ogm_page(_fd,1);
	
		encoding_gui=new DIA_encoding(25000);
                encoding_gui->setContainer("OGM");
		//______________ Write headers..._____________________
		
		if(!initVideo(name))
		{
			fclose(_fd);
			_fd=NULL;
                        GUI_Error_HIG(QT_TR_NOOP("Could not initialize video"), NULL);
			return 0;
		
		}
		if(!initAudio())
		{
			fclose(_fd);
			_fd=NULL;
                        GUI_Error_HIG(QT_TR_NOOP("Could not initialize audio"), NULL);
			return 0;
		
		}

		encoding_gui->setFps(_fps1000);
		encoding_gui->reset();
		// ___________________Then body_______________________
                uint32_t j=0;
		for( j=0;j<_togo && !error;j++)
		{
			if(!encoding_gui->isAlive())
			{
				error=1;
				continue;
			}
			if(!writeVideo(j)) error=1;
			if(!writeAudio(j)) error=1;
		}
                if(abs(j-_togo)<3 && error) error=0; // might be caused by late B frame
		delete encoding_gui;
		encoding_gui=NULL;
		//________________ Flush______________________
		videoStream->flush();
		endAudio();
		//deleteAudioFilters();
		// ____________Close____________________
		fclose(_fd);
		_fd=NULL;

	return !error;
}
/**
    \fn runVC1
    \brief Index VC1 stream
*/
bool TsIndexer::runVC1(const char *file,ADM_TS_TRACK *videoTrac)
{
    uint32_t temporal_ref,val;
    uint8_t buffer[50*1024];
    bool seq_found=false;

    TSVideo video;
    indexerData  data;
    dmxPacketInfo info;

    beginConsuming=0;
    listOfUnits.clear();

    if(!videoTrac) return false;
    if(videoTrac[0].trackType!=ADM_TS_VC1)
    {
        printf("[Ts Indexer] Only VC1 video supported\n");
        return false;
    }
    video.pid=videoTrac[0].trackPid;

    memset(&data,0,sizeof(data));
    data.picStructure=pictureFrame;

    string indexName=string(file);
    indexName=indexName+string(".idx2");
    index=qfopen(indexName,"wt");

    if(!index)
    {
        printf("[PsIndex] Cannot create %s\n",indexName.c_str());
        return false;
    }
    writeSystem(file,false);
    pkt=new tsPacketLinearTracker(videoTrac->trackPid, audioTracks);

    FP_TYPE append=FP_APPEND;
    pkt->open(file,append);
    data.pkt=pkt;
    fullSize=pkt->getSize();
    int startCode;
    decodingImage=false;
#define likely(x) x
#define unlikely(x) x
    while(1)
    {
        startCode=pkt->findStartCode();
        if(!pkt->stillOk()) break;

        switch(startCode)
        {
        case 0x0f: // sequence start

            if(seq_found)
            {
                pkt->getInfo(&thisUnit.packetInfo);
                thisUnit.consumedSoFar=pkt->getConsumed();
                addUnit(data,unitTypeSps,thisUnit,4);
                decodingImage=false;
                break;
            }
            // Verify it is high/advanced profile
            {
                int seqSize=0;
                tsGetBits bits(pkt);
                if(!bits.peekBits(1)) continue; // simple/main profile

                if(!decodeVC1Seq(bits,video)) continue;

                seqSize=bits.getConsumed();
                video.extraDataLength=seqSize+4+1;
                memcpy(video.extraData+4,bits.data,seqSize);
                // Add info so that ffmpeg is happy
                video.extraData[0]=0;
                video.extraData[1]=0;
                video.extraData[2]=1;
                video.extraData[3]=0xf;
                video.extraData[seqSize+4+0]=0;
                seq_found=1;
                // Hi Profile
                printf("[VC1] Found seq start with %d x %d video\n",(int)video.w,(int)video.h);
                printf("[VC1] FPS : %d\n",(int)video.fps);
                printf("[VC1] sequence header is %d bytes\n",(int)seqSize);
                writeVideo(&video,ADM_TS_VC1);
                writeAudio();
                qfprintf(index,"[Data]");

                pkt->getInfo(&thisUnit.packetInfo);
                thisUnit.consumedSoFar=pkt->getConsumed();
                addUnit(data,unitTypeSps,thisUnit,seqSize+4);
                decodingImage=false;

                continue;
            }
            break;
        case 0x0D: //  Picture start
        {
            int type;
            uint8_t buffer[4];
            uint32_t fType,sType;
            if(!seq_found)
            {
                continue;
                printf("[TsIndexer]No sequence start yet, skipping..\n");
            }
            pkt->getInfo(&thisUnit.packetInfo);
            thisUnit.consumedSoFar=pkt->getConsumed();

            tsGetBits bits(pkt);
            if(!decodeVC1Pic(bits,fType,sType)) continue;
            thisUnit.imageType=fType;
            updatePicStructure(video,sType);
            addUnit(data,unitTypePic,thisUnit,4);
            decodingImage=true;
            data.nbPics++;
        }
        break;
        default:
            break;
        }
    }

    printf("\n");
//        Mark(&data,&info,2);
    qfprintf(index,"\n[End]\n");
    qfprintf(index,"\n# Found %"PRIu32" images \n",data.nbPics); // Size
    qfprintf(index,"# Found %"PRIu32" frame pictures\n",video.frameCount); // Size
    qfprintf(index,"# Found %"PRIu32" field pictures\n",video.fieldCount); // Size
    qfclose(index);
    index=NULL;
    audioTracks=NULL;
    delete pkt;
    pkt=NULL;
    return 1;
}
Пример #4
0
/**
    \fn runH264
    \brief Index H264 stream
*/  
bool TsIndexer::runH264(const char *file,ADM_TS_TRACK *videoTrac)
{

bool    seq_found=false;
bool    firstSps=true;

TSVideo video;
indexerData  data;    
dmxPacketInfo tmpInfo;
TS_PESpacket SEI_nal(0);
bool result=false;
bool bAppend=false;

    beginConsuming=0;
    listOfUnits.clear();

    printf("Starting H264 indexer\n");
    if(!videoTrac) return false;
    if(videoTrac[0].trackType!=ADM_TS_H264)
    {
        printf("[Ts Indexer] Only H264 video supported\n");
        return false;
    }
    video.pid=videoTrac[0].trackPid;

    memset(&data,0,sizeof(data));
    data.picStructure=pictureFrame;
    string indexName=string(file);
    indexName=indexName+string(".idx2");
    index=qfopen(indexName,(const char*)"wt");

    if(!index)
    {
        printf("[PsIndex] Cannot create %s\n",indexName.c_str());
        return false;
    }

    
    pkt=new tsPacketLinearTracker(videoTrac->trackPid, audioTracks);
    
    FP_TYPE append=FP_DONT_APPEND;
    if(true==ADM_probeSequencedFile(file))
    {
        if(true==GUI_Question("There are several files with sequential file names. Should they be all loaded ?"))
                bAppend=true;
    }
    if(bAppend==true)
        append=FP_APPEND;
    writeSystem(file,bAppend);
    pkt->open(file,append);
    data.pkt=pkt;
    fullSize=pkt->getSize();
    gui=createProcessing("Indexing",pkt->getSize());
    int lastRefIdc=0;
    bool keepRunning=true;
    //******************
    // 1 search SPS
    //******************
      while(keepRunning)
      {
        int startCode=pkt->findStartCode();

        if(startCode&0x80) continue; // Marker missing
        startCode&=0x1f;
        if(startCode!=NAL_SPS) continue;

          // Got SPS!
          
          uint32_t xA,xR;
          // Get info
          pkt->getInfo(&tmpInfo);
          // Read just enough...
          {
            SEI_nal.empty();
            uint32_t code=0xffff+0xffff0000;
            while(((code&0xffffff)!=1) && pkt->stillOk())
            {
                    uint8_t r=pkt->readi8();
                    code=(code<<8)+r;
                    SEI_nal.pushByte(r);
            }
            if(!pkt->stillOk()) break;;
            pkt->seek(tmpInfo.startAt,tmpInfo.offset-5);
            if (extractSPSInfo(SEI_nal.payload, SEI_nal.payloadSize-4,&spsInfo))
            {
              ADM_info("[TsIndexer] Found video %"PRIu32"x%"PRIu32", fps=%"PRIu32"\n",video.w,video.h,video.fps);
              ADM_info("[TsIndexer] SPS says %"PRIu32"x%"PRIu32"\n",spsInfo.width,spsInfo.height);
              seq_found=1;
              video.w=spsInfo.width;
              video.h=spsInfo.height;
              video.fps=spsInfo.fps1000;
              xA=spsInfo.darNum;
              xR=spsInfo.darDen;
              writeVideo(&video,ADM_TS_H264);
              writeAudio();
              qfprintf(index,"[Data]");
              // Rewind
              
              break;              
          };
        }
      }
      
        if(!seq_found) goto the_end;
        
        decodingImage=false;
    //******************
    // 2 Index
    //******************
        bool fourBytes;
      while(keepRunning)
      {
          fourBytes=false;
        int startCode=pkt->findStartCode2(fourBytes);
resume:
        if(!pkt->stillOk()) break;

        int startCodeLength=4;
        if(fourBytes==true) startCodeLength++;

//  1:0 2:Nal ref idc 5:Nal Type
        if(startCode&0x80) 
        {
            printf("[Ts] Nal Marker missing:%x\n",startCode);
            continue; // Marker missing
        }
        int fullStartCode=startCode;
        int ref=(startCode>>5)&3;

        startCode&=0x1f; // Ignore nal ref IDR
        
        aprintf("[%02x] Nal :0x%x,ref=%d,lastRef=%d at : %d \n",fullStartCode,startCode,ref,lastRefIdc,pkt->getConsumed()-beginConsuming);
        
          // Ignore multiple chunk of the same pic
          if((startCode==NAL_NON_IDR || startCode==NAL_IDR)&&decodingImage )
          {
            aprintf("Still capturing, ignore\n");
            continue;
          }
                
          switch(startCode)
                  {
                  case NAL_AU_DELIMITER:
                        {
                          aprintf("AU DELIMITER\n");
                          decodingImage = false;
                        }
                          break;
                  case NAL_SEI:
                        {
                        // Load the whole NAL
                            SEI_nal.empty();
                            uint32_t code=0xffff+0xffff0000;
                            while(((0xffffff&code)!=1) && pkt->stillOk())
                            {
                                uint8_t r=pkt->readi8();
                                code=(code<<8)+r;
                                SEI_nal.pushByte(r);
                            }
                            if(!pkt->stillOk()) goto resume;
                            aprintf("[SEI] Nal size :%d\n",SEI_nal.payloadSize);
                            if(SEI_nal.payloadSize>=7)
                                decodeSEI(SEI_nal.payloadSize-4,
                                    SEI_nal.payload,&(thisUnit.recoveryCount),&(thisUnit.imageStructure));
                            else 
                                    printf("[SEI] Too short size+4=%d\n",*(SEI_nal.payload));
                            startCode=pkt->readi8();
                            
                            decodingImage=false;
                            pkt->getInfo(&thisUnit.packetInfo);
                            thisUnit.consumedSoFar=pkt->getConsumed();
                            if(!addUnit(data,unitTypeSei,thisUnit,startCodeLength+SEI_nal.payloadSize+1))
                                keepRunning=false;
                            fourBytes=true;
                            goto resume;
                            }
                            break;
                  
                  case NAL_SPS:
                                decodingImage=false;
                                pkt->getInfo(&thisUnit.packetInfo);
                                if(firstSps)
                                {
                                    pkt->setConsumed(startCodeLength); // reset consume counter
                                    firstSps=false;
                                }
                                thisUnit.consumedSoFar=pkt->getConsumed();
                                if(!addUnit(data,unitTypeSps,thisUnit,startCodeLength))
                                    keepRunning=false;
                          break;

                  case NAL_IDR:
                  case NAL_NON_IDR:
                    {
#define NON_IDR_PRE_READ 8
                      aprintf("Pic start last ref:%d cur ref:%d nb=%d\n",lastRefIdc,ref,data.nbPics);
                      lastRefIdc=ref;
                        
                      uint8_t bufr[NON_IDR_PRE_READ+4];
                      uint8_t header[NON_IDR_PRE_READ+4];
                      
                   
                        pkt->read(NON_IDR_PRE_READ,bufr);
                        // unescape...
                        ADM_unescapeH264(NON_IDR_PRE_READ,bufr,header);
                        //
                        getBits bits(NON_IDR_PRE_READ,header);
                        int first_mb_in_slice,slice_type;

                        first_mb_in_slice= bits.getUEG();
                        slice_type= bits.getUEG31();
                        if(slice_type>9) 
                        {
                            printf("[TsIndexer] Bad slice type\n");
                        }
                        if(slice_type>4) slice_type-=5;
                        switch(slice_type)
                        {

                            case 0 : thisUnit.imageType=2;break; // P
                            case 1 : thisUnit.imageType=3;break; // B
                            case 2 : thisUnit.imageType=1;break; // I
                            default : thisUnit.imageType=2;break; // SP/SI
                        }
                      if(startCode==NAL_IDR) thisUnit.imageType=4; // IDR
                      aprintf("[>>>>>>>>] Pic Type %"PRIu32" Recovery %"PRIu32"\n",thisUnit.imageType,recoveryCount);
                      if(thisUnit.imageType==1 && !thisUnit.recoveryCount) 
                                thisUnit.imageType=4; //I  + Recovery=0 = IDR!

                      data.nbPics++;

                      

                      decodingImage=true;
                      pkt->getInfo(&thisUnit.packetInfo);
                      thisUnit.consumedSoFar=pkt->getConsumed();

                      if(!addUnit(data,unitTypePic,thisUnit,startCodeLength+NON_IDR_PRE_READ))
                          keepRunning=false;
                        // reset to default
                      thisUnit.imageStructure=pictureFrame;
                      thisUnit.recoveryCount=0xff;
                      pkt->invalidatePtsDts();
                    }
                  
                    break;
                  default:
                      break;
          }
      } // End while
      result=true;
the_end:
        printf("\n");
        qfprintf(index,"\n[End]\n");
        qfclose(index);
        index=NULL;
        audioTracks=NULL;
        delete pkt;
        pkt=NULL;
        return result; 
}
int main( void ) {

	help();
	
	// func type
	int funcType = 1;
	int processId = 0;

	// paramater
	int layerLimit = 3;
	int widthDeletedDefault = 70;
	int colorDiffThred = 5;
	int elePerTagThred = 300;
	int bandWidthDefault = 50;
	int keyFrameNumLimit = 30;
	int badCutLimit = (int)(0.08 * widthDeletedDefault);
	vector<int> shotArr;

	switch ( funcType ) {

		case 0:{

			bool state;
			state = video2Frames( processId );
			if ( !state ) return -2;

			// shot Cut
			cout << " Shot Cut --ING" << endl;
			segShotCut( shotArr );

			cout << " Convert Process Finished !! " << endl;
		}
		case 1:{

			int globalTime = clock();

			getShotCut( shotArr );

			// resize shot
			for ( int shotId = 1; shotId < (int)shotArr.size(); shotId++ ) {

				int frameStId = shotArr[shotId - 1];
				int frameEdId = shotArr[shotId];

				cout << " Process Shot From " << frameStId << " To " << frameEdId << " --ING" << endl << endl;

				// read frames
				vector<Mat> frames;
				bool state;
				state = readFrameStream( frameStId, frameEdId, frames );
				if ( !state ) return -2;

				// calculate Energy
				vector<Mat> pixelEnergy;
				vector<int> pixelTag;
				int tagNum;
				calcPixelTag( frames, pixelTag, tagNum, colorDiffThred, elePerTagThred, frameStId );
				calcPixelEnergy( frames, pixelTag, tagNum, pixelEnergy, frameStId );

				// temporal compress
				vector<int> keyFrame;
				timeCompress( pixelEnergy, keyFrame, keyFrameNumLimit );
				preserveKeyData( keyFrame, frames, pixelEnergy );

				// resize Video
				int widthDeleted = widthDeletedDefault;
				vector<Mat> edgeProtect;
				for ( int c = 0; c < 2; c++ ) {

					if ( widthDeleted > 0 ) {
						calcEdgeProtect( frames, edgeProtect );
						resizeVideo( keyFrame, frames, pixelEnergy, edgeProtect, layerLimit, widthDeleted, bandWidthDefault, badCutLimit, frameStId, frameEdId, c );
						scaleVideo( keyFrame, frames, pixelEnergy, widthDeleted, frameStId, frameEdId, c );
						rotateVideo( keyFrame, frames, pixelEnergy, frameStId, frameEdId, c );
					} else {
						copyFrame( frameStId, frameEdId );
					}
				}

				cout << endl;

			}
			// finished
			cout << " Shot Finished !! Well done !!" << endl;
			globalTime = clock() - globalTime;
			globalTime = (globalTime + 500) / 1000;
			printf( " Global Time Used : %d min %d sec\n", globalTime / 60, globalTime % 60 );

			break;
		}
		case 2:{

			   // write frame stream
			   writeFrameStream();
		}
		case 3:{
			// write video
			bool state = writeVideo( processId );
			if ( !state ) return -2;
			break;
		}
		default:
			break;
	}

	system( "pause" );

	return 0;
}