int SoundGen2GS::readBuffer(int16 *buffer, const int numSamples) { fillAudio(buffer, numSamples / 2); return numSamples; }
/** \fn save */ bool muxerAvi::save(void) { printf("[AviMuxer] Saving\n"); uint32_t bufSize=vStream->getWidth()*vStream->getHeight()*3; bool result=true; uint64_t rawDts; uint64_t lastVideoDts=0; int ret; int written=0; audioPackets=new aviAudioPacket[nbAStreams]; videoBuffer=new uint8_t[bufSize]; ADM_info("[AviMuxer]avg fps=%u\n",vStream->getAvgFps1000()); ADMBitstream in(bufSize); in.data=videoBuffer; uint64_t aviTime=0; if(in.dts==ADM_NO_PTS) in.dts=0; lastVideoDts=in.dts; initUI("Saving Avi"); encoding->setContainer("AVI/OpenDML"); if(false==vStream->getPacket(&in)) { ADM_error("Cannot get first video frame\n"); goto abt; } while(1) { if(in.dts>aviTime+videoIncrement) { writter.saveVideoFrame( 0, 0,videoBuffer); // Insert dummy video frame encoding->pushVideoFrame(0,0,in.dts); }else { if(!writter.saveVideoFrame( in.len, in.flags,videoBuffer)) // Put our real video { ADM_warning("[AviMuxer] Error writting video frame\n"); result=false; goto abt; } encoding->pushVideoFrame(in.len,in.out_quantizer,in.dts); if(false==vStream->getPacket(&in)) goto abt; if(in.dts==ADM_NO_PTS) { in.dts=lastVideoDts+videoIncrement; } lastVideoDts=in.dts; } fillAudio(aviTime+videoIncrement); // and matching audio if(updateUI()==false) { result=false; goto abt; } written++; aviTime+=videoIncrement; } abt: closeUI(); writter.setEnd(); delete [] videoBuffer; videoBuffer=NULL; delete [] audioPackets; audioPackets=NULL; ADM_info("[AviMuxer] Wrote %d frames, nb audio streams %d\n",written,nbAStreams); return result; }
/** \fn save */ bool muxerMp4v2::save(void) { bool result=true; int nbFrame=0; printf("[Mp4v2Muxer] Saving\n"); initUI("Saving MP4V2"); encoding->setContainer("MP4 (libmp4v2)"); uint64_t lastSentDts=0; while(loadNextVideoFrame((&(in[nextWrite])))) { bool kf=false; int other=!nextWrite; if(in[other].flags & AVI_KEY_FRAME) kf=true; ADM_assert(in[nextWrite].dts!=ADM_NO_PTS) ADM_assert(in[nextWrite].dts!=ADM_NO_PTS) if(in[other].pts==ADM_NO_PTS || in[other].pts==ADM_NO_PTS) { GUI_Error_HIG("Video","Video does not have enough timing information. Are you copying from AVI ?"); goto theEnd; } uint64_t nextDts=in[nextWrite].dts; // Delta between dts=duration of the frame (sort of) uint64_t myDts=in[other].dts; uint64_t myPts=in[other].pts; cprintf(">>next DTS=%"PRIu64", last DTS=%"PRIu64"delta=%"PRIu64"\n",nextDts,lastSentDts,nextDts-lastSentDts); encoding->pushVideoFrame(in[other].len,in[other].out_quantizer,myDts); uint64_t delta=myPts-lastSentDts; // composition time... delta=timeScale(delta); uint64_t duration=nextDts-lastSentDts; uint64_t scaled_duration=timeScale(duration); duration=inverseTimeScale(scaled_duration); // handle rounding error nbFrame++; cprintf("Sending frame duration=%"PRIu64", pts/dts=%"PRIu64"\n",lastSentDts,delta); if(false==MP4WriteSample(handle,videoTrackId,in[other].data,in[other].len, scaled_duration, // duration delta, // pts/dts offset kf // Sync Sample )) { ADM_error("Cannot write video sample\n"); result=false; goto theEnd; } // update lastSentDts lastSentDts+=duration; // beginning of next frame... // cprintf("lastSendDts=%"PRIu64", next Dts=%"PRIu64", skew=%"PRId64"\n",lastSentDts,nextDts, (int64_t)nextDts-(int64_t)lastSentDts); // fillAudio(lastSentDts); // toggle nextWrite=other; if(updateUI()==false) { result=false; break; } } // Write last frame nextWrite=!nextWrite; int scale; if(videoIncrement>5000) scale=(1000000.0/videoIncrement); else scale=100; // 10 ms MP4WriteSample(handle,videoTrackId,in[nextWrite].data,in[nextWrite].len, (MP4Duration)90000/scale, 0, // pts/dts offset 0 // Sync Sample ); theEnd: close(); if(muxerConfig.optimize && result==true) { encoding->setPhasis("Optimizing"); string tmpTargetFileName=targetFileName+string(".tmp"); if(!ADM_renameFile(targetFileName.c_str(),tmpTargetFileName.c_str())) { GUI_Error_HIG("","Cannot rename file (optimize)"); return false; } // Optimize ADM_info("Optimizing...\n"); MP4Optimize( tmpTargetFileName.c_str(), targetFileName.c_str() ); // delete unlink(tmpTargetFileName.c_str()); } closeUI(); return result; }