/** \fn A_jog \brief Handle jogshuttle widget */ void A_jog(void) { int32_t r; uint32_t a; uint32_t slip; static int jog=0; if(jog) return; jog++; while(r=A_jogRead()) { a=abs(r); printf("%d \n",r); if(a<JOG_THRESH1) slip=JOG_THRESH1_PERIOD; else if(a<JOG_THRESH2) slip=JOG_THRESH2_PERIOD; else slip=JOG_THRESH3_PERIOD; if(r>0) GUI_NextKeyFrame(); else GUI_PreviousKeyFrame(); UI_purge(); for(int i=0;i<slip/REFRESH;i++) { UI_purge(); ADM_usleep(REFRESH); UI_purge(); } } jog--; }
/** \fn stopThread */ bool ADM_threadQueue::stopThread(void) { ADM_info("Destroying threadQueue\n"); mutex->lock(); if(threadState==RunStateRunning) { threadState=RunStateStopOrder; if(cond->iswaiting()) { cond->wakeup(); } mutex->unlock(); int clockDown=10; while(threadState!=RunStateStopped && clockDown) { ADM_usleep(50*1000); clockDown--; }; ADM_info("Thread stopped, continuing dtor\n"); }else { mutex->unlock(); } return true; }
ADM_threadQueue::~ADM_threadQueue() { ADM_info("Killing audio thread and son\n"); // ask the thread to stop if(started) { mutex->lock(); if(threadState==RunStateRunning) { ADM_info("Asking the thread to stop\n"); threadState=RunStateStopOrder; if(cond->iswaiting()) { cond->wakeup(); } mutex->unlock(); int count=100; while(count) { if(threadState==RunStateStopped) break; ADM_usleep(1000*100); // Slep 100 ms } }else mutex->unlock(); void *ret; pthread_join(myThread, &ret); } if(cond) delete cond; if(mutex) delete mutex; cond=NULL; mutex=NULL; }
/** \fn stop \brief stop */ uint8_t audioDeviceThreaded::stop() { uint32_t maxWait=3*1000; // Should be enough to drain ADM_info("[audioDevice]Stopping device..."); if(stopRequest==AUDIO_DEVICE_STARTED) { CHANGE_STATE(AUDIO_DEVICE_STOP_REQ); while(stopRequest==AUDIO_DEVICE_STOP_REQ && maxWait) { ADM_usleep(1000); maxWait--; } } if(!maxWait) { ADM_error("Audio device did not stop cleanly\n"); } localStop(); if(audioBuffer) { delete [] audioBuffer; audioBuffer=NULL; } if(silence) delete [] silence; silence=NULL; CHANGE_STATE(AUDIO_DEVICE_STOPPED); return 1; }
void trampoline(void) { ADM_usleep(100000); // let gtk start gdk_threads_enter(); automation(); gdk_threads_leave(); }
void runDialog(volatile int *lock) { while (!*lock) { while (gtk_events_pending()) gtk_main_iteration(); ADM_usleep( 50000L); // wait 50 ms } }
/** \fn A_jogRead \brief Read an average value of jog */ uint32_t A_jogRead(void) { int32_t sum=0,v; for(int i=0;i<NB_JOG_READ;i++) { v=UI_readJog(); if(abs(v)<10) v=0; sum+=v; ADM_usleep(JOG_READ_PERIOD_US); } return sum/NB_JOG_READ; }
bool coreAudioDevice::localStop(void) { if (_inUse) { verify_noerr(AudioOutputUnitStop(theOutputUnit)); // Clean up verify_noerr(AudioUnitUninitialize(theOutputUnit)); verify_noerr(AudioComponentInstanceDispose(theOutputUnit)); } _inUse=0; ADM_usleep(10*1000); return 1; }
void DIA_StartBusyDialog( void ) { busy=create_dialog1(); gtk_signal_connect(GTK_OBJECT(busy), "delete_event", GTK_SIGNAL_FUNC(on_destroy_abort), (void *) NULL); gtk_register_dialog(busy); gtk_widget_show(busy); UI_purge(); ADM_usleep(500); }
//_________________________________________________________________ // // Set up audio system //_________________________________________________________________ uint8_t GenericAviSave::setupAudio (void) { // 1- Prepare audio filter //__________________________ _audioInBuffer = 0; _audioTarget=_audioCurrent=0; _audioTotal=0; audio_filter=NULL; if(!currentaudiostream) { encoding_gui->setAudioCodec(QT_TR_NOOP("None")); return 1; } printf (" mux mode : %d mux param %d\n", muxMode, muxParam); if (audioProcessMode()) // else Raw copy mode { audio_filter = buildAudioFilter (currentaudiostream,video_body->getTime (frameStart)); if(!audio_filter) return 0; encoding_gui->setAudioCodec(getStrFromAudioCodec(audio_filter->getInfo()->encoding)); } else // copymode { // else prepare the incoming raw stream // audio copy mode here encoding_gui->setAudioCodec(QT_TR_NOOP("Copy")); audio_filter=buildAudioFilter( currentaudiostream,video_body->getTime (frameStart)); if(!audio_filter) return 0; } /* Setup audioQ */ pthread_t audioThread; _pq=new PacketQueue("AVI audioQ",5000,2*1024*1024); memset(&_context,0,sizeof(_context)); _context.audioEncoder=audio_filter; _context.audioTargetSample=0xFFFF0000; ; //FIXME _context.packetQueue=_pq; // start audio thread ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioQueueSlave,&_context)); ADM_usleep(4000); return 1; }
/** \fn startThread */ bool ADM_threadQueue::startThread(void) { ADM_info("Starting thread...\n"); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if(pthread_create(&myThread,&attr, boomerang, this)) { ADM_error("ERROR CREATING THREAD\n"); ADM_assert(0); } while(threadState==RunStateIdle) { ADM_usleep(10000); } ADM_info("Thread created and started\n"); started=true; return true; }
/** \fn sendData \brief Send data to playback */ void ossAudioDevice::sendData(void) { int pack=_channels*_frequency*2; int w; pack/=100; pack&=~3; // Try to send 10 ms chunks mutex.lock(); if(wrIndex-rdIndex<pack) pack=wrIndex-rdIndex; mutex.unlock(); w = write(oss_fd, audioBuffer.at(rdIndex), pack); mutex.lock(); rdIndex+=pack; mutex.unlock(); if(w!=pack) printf("[OSS] Error :%u vs %u\n",w,pack); ADM_usleep(1000); return; }
/** \fn spawnChild \brief Spawn a child to execute a commande */ bool jobWindow::spawnChild(const char *exeName, const string &script, const string &outputFile) { spawnData data; data.script=script; data.outputFile=outputFile; data.exeName=exeName; data.me=this; pthread_t threadId; // Have to spawn a thread that will handle the exec... if( pthread_create(&threadId,NULL, spawnerBoomerang, &data)) { ADM_error("Spawn failed\n"); return false; } // Everything is fine, give process 1 second to use the stack allocated data.... ADM_usleep(1000*1000LL); QApplication::processEvents(); ADM_info("Spawning successfull\n"); return true; }
uint8_t GenericAviSave::cleanupAudio (void) { printf("[AVI] Cleaning audio\n"); if(_pq) { _pq->Abort(); while(!_context.audioDone) { printf("Waiting Audio thread\n"); ADM_usleep(500000); } if(_pq) delete _pq; _pq=NULL; } if(audio_filter) { deleteAudioFilter (audio_filter); audio_filter=NULL; } return 1; }
uint8_t mpeg_passthrough(const char *name,ADM_OUT_FORMAT format ) { uint32_t len, flags; AVDMGenericAudioStream *audio=NULL; uint32_t audiolen; DIA_encoding *work; ADM_MUXER_TYPE mux; double total_wanted=0; uint32_t total_got=0; uint8_t ret=0; ADMMpegMuxer *muxer=NULL; ADMBitstream bitstream(0); printf("Saving as mpg PS to file %s\n",name); // First we check it is mpeg if(!isMpeg12Compatible(avifileinfo->fcc)) { GUI_Error_HIG(QT_TR_NOOP("This is not MPEG compatible"), QT_TR_NOOP("You can't use the Copy codec.")); return 0 ; } if(!currentaudiostream) { GUI_Error_HIG(QT_TR_NOOP("There is no audio track"), NULL); return 0; } ADM_assert (video_body->getFlags (frameStart, &flags)); if(!(flags&AVI_KEY_FRAME)) { GUI_Error_HIG(QT_TR_NOOP("The first frame is not intra frame"), QT_TR_NOOP("Use the << and the >> buttons to move using Intra frames.")); return 0; } audio=mpt_getAudioStream(); // Have to check the type // If it is mpeg2 we use DVD-PS // If it is mpeg1 we use VCD-PS // Later check if it is SVCD if(!audio) { GUI_Error_HIG(QT_TR_NOOP("Audio track is not suitable"), NULL); return 0; } // Check WAVHeader *hdr=audio->getInfo(); uint32_t isMpeg1; uint32_t isLav; if(!prefs->get(FEATURE_USE_LAVCODEC_MPEG2, &isLav)) { isLav=0; } if(!isLav) { decoderMpeg *mpeghdr; mpeghdr=(decoderMpeg *)video_body->rawGetDecoder(0); isMpeg1=mpeghdr->isMpeg1(); } else { // How to know if it is mpeg 1? // Assume it is not /* decoderFFMpeg12 *mpeghdr; mpeghdr=(decoderFFMpeg12 *)video_body->rawGetDecoder(0); isMpeg1=mpeghdr->isMpeg1(); */ isMpeg1=0; } switch(format) { case ADM_PS: if(isMpeg1) { if(hdr->frequency!=44100 || hdr->encoding != WAV_MP2) { GUI_Error_HIG(QT_TR_NOOP("Incompatible audio"), QT_TR_NOOP("For VCD, audio must be 44.1 kHz MP2.")); return 0 ; } mux=MUXER_VCD; printf("PassThrough: Using VCD PS\n"); }else { // Mpeg2 aviInfo info; video_body->getVideoInfo(&info); if(hdr->frequency==44100 && info.width==480&& hdr->encoding == WAV_MP2 ) // SVCD ? { mux=MUXER_SVCD; printf("PassThrough: Using SVCD PS\n"); } else { uint32_t valid=0; if(!prefs->get(FEATURE_MPEG_NO_LIMIT,&valid)) valid=0; // mpeg2, we do only DVD right now if(hdr->frequency==48000) valid=1; if((hdr->encoding != WAV_MP2 && hdr->encoding!=WAV_AC3 && hdr->encoding!=WAV_LPCM && hdr->encoding!=WAV_DTS)) { valid=0; } if(!valid) { deleteAudioFilter(audio); GUI_Error_HIG(("Incompatible audio"),QT_TR_NOOP( "For DVD, audio must be 48 kHz MP2(stereo), AC3, DTS or LPCM (stereo).")); return 0; } mux=MUXER_DVD; printf("PassThrough: Using DVD PS\n"); } } muxer=new mplexMuxer(); break; case ADM_TS: printf("Using TS output format\n"); muxer=new tsMuxer(); //lavMuxer(); mux=MUXER_TS; break; default: ADM_assert(0); break; } if(!muxer) { printf("No muxer ?\n"); return 0; } if(!muxer->open(name,0,mux,avifileinfo,audio->getInfo())) { delete muxer; muxer=NULL; printf("Muxer init failed\n"); return 0; } // In copy mode it is better to recompute the gop timestamp muxer->forceRestamp(); ///____________________________ work=new DIA_encoding(avifileinfo->fps1000); work->setCodec(QT_TR_NOOP("Copy")); work->setAudioCodec(QT_TR_NOOP("---")); work->setPhasis(QT_TR_NOOP("Saving")); if(!audioProcessMode()) work->setAudioCodec(QT_TR_NOOP("Copy")); else work->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding)); switch(mux) { case MUXER_TS: work->setContainer(QT_TR_NOOP("MPEG TS"));break; case MUXER_VCD: work->setContainer(QT_TR_NOOP("MPEG VCD"));break; case MUXER_SVCD: work->setContainer(QT_TR_NOOP("MPEG SVCD"));break; case MUXER_DVD: work->setContainer(QT_TR_NOOP("MPEG DVD"));break; default: ADM_assert(0); } uint32_t cur=0; uint32_t target_sample=0; double target_time; aviInfo info; video_body->getVideoInfo(&info); target_time=frameEnd-frameStart+1; target_time*=1000; target_time/=info.fps1000; // target_time in second target_time*=audio->getInfo()->frequency; target_sample=(uint32_t)floor(target_time); uint8_t *buffer = new uint8_t[avifileinfo->width * avifileinfo->height * 3]; uint8_t *audiobuffer = new uint8_t[4*48000*2]; // 2 sec worth of lpcm uint32_t position; EncoderCopy *copy=NULL; bitstream.data=buffer; bitstream.bufferSize=avifileinfo->width * avifileinfo->height * 3; /*************************** Special case : Multithreaded ***************************/ if(mux==MUXER_VCD || mux==MUXER_SVCD || mux==MUXER_DVD) { pthread_t audioThread,videoThread,muxerThread; copy=new EncoderCopy(NULL); muxerMT context; copy->configure(NULL); // memset(&context,0,sizeof(context)); context.videoEncoder=copy; context.audioEncoder=audio; context.muxer=( mplexMuxer *)muxer; context.nbVideoFrame=copy->getNbFrame(); context.audioTargetSample=target_sample; context.audioBuffer=audiobuffer; context.bitstream=&bitstream; context.opaque=(void *)work; // start audio thread ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioSlave,&context)); ADM_assert(!pthread_create(&videoThread,NULL,(THRINP)copyVideoSlave,&context)); while(1) { accessMutex.lock(); if(context.audioDone==2 || context.videoDone==2 || !work->isAlive()) //ERROR { context.audioAbort=1; context.videoAbort=1; printf("[Copy] aborting\n"); } if(context.audioDone && context.videoDone) { printf("[Copy]Both audio & video done\n"); if(context.audioDone==1 && context.videoDone==1) ret=1; else ret=0; accessMutex.unlock(); goto _abt; } // Update UI work->setAudioSize(context.feedAudio); context.feedVideo=0; accessMutex.unlock(); ADM_usleep(1000*1000); } } /**************************************************************************************/ /* If we get here, it means output is MPEG_TS */ /* We must use the audio packet Queue */ /**************************************************************************************/ ADM_assert(mux==MUXER_TS); { PacketQueue *pq; uint32_t mx,sample; pthread_t audioThread; copy=new EncoderCopy(NULL); audioQueueMT context; uint8_t r; copy->configure(NULL); pq=new PacketQueue("TS audioQ",5000,2*1024*1024); memset(&context,0,sizeof(context)); context.audioEncoder=audio; context.audioTargetSample=target_sample; context.packetQueue=pq; // start audio thread ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioQueueSlave,&context)); // Go! ADM_usleep(4000); mx=copy->getNbFrame(); printf("Writing %u frames\n",mx); for(int frame=0;frame<mx;frame++) { while(muxer->needAudio()) { if(pq->Pop(audiobuffer,&audiolen,&sample)) { if(audiolen) { muxer->writeAudioPacket(audiolen,audiobuffer); //work->feedAudioFrame(audiolen); } }else break; } ADM_assert(copy); bitstream.cleanup(frame); r=copy->encode ( frame, &bitstream); if(!r) { printf("TS:Frame %u error\n",frame); GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL); goto stopit; } muxer->writeVideoPacket( &bitstream); work->setFrame(frame,bitstream.len,bitstream.out_quantizer,mx); // work->feedFrame(bitstream.len); if(!work->isAlive()) { goto stopit; } } ret=1; stopit: context.audioAbort=1; pq->Abort(); // Wait for audio slave to be over while(!context.audioDone) { printf("Waiting Audio thread\n"); ADM_usleep(500000); } delete pq; } // End ts case /************************************** TS End *********************************/ _abt: delete work; muxer->close(); delete muxer; delete [] buffer; delete [] audiobuffer; deleteAudioFilter(audio); if(copy) delete copy; return ret; }
uint8_t oplug_mp4(const char *name, ADM_OUT_FORMAT type) { AVDMGenericVideoStream *_incoming=NULL; AVDMGenericAudioStream *audio=NULL; uint8_t audioBuffer[48000]; uint8_t *videoBuffer=NULL; uint32_t alen;//,flags; uint32_t size; uint8_t ret=0; uint32_t sample_got=0,sample; uint32_t extraDataSize=0; uint8_t *extraData=NULL; lavMuxer *muxer=NULL; aviInfo info; uint32_t width,height; DIA_encoding *encoding_gui=NULL; Encoder *_encode=NULL; char *TwoPassLogFile=NULL; uint32_t total=0; uint32_t videoExtraDataSize=0; uint8_t *videoExtraData=NULL; uint8_t *dummy,err; WAVHeader *audioinfo=NULL; int prefill=0; uint32_t displayFrame=0; ADMBitstream bitstream(0); uint32_t frameWrite=0; ADM_MUXER_TYPE muxerType=MUXER_MP4; uint8_t dualPass=0; uint8_t r=0; uint32_t skipping=1; pthread_t audioThread; audioQueueMT context; PacketQueue *pq;//("MP4 audioQ",50,2*1024*1024); uint32_t totalAudioSize=0; uint32_t sent=0; const char *containerTitle; switch(type) { case ADM_PSP:muxerType=MUXER_PSP;containerTitle="PSP";break; case ADM_MP4:muxerType=MUXER_MP4;containerTitle="MP4";break; case ADM_MATROSKA:muxerType=MUXER_MATROSKA;containerTitle="MKV";break; default: ADM_assert(0); } // Setup video if(videoProcessMode()) { _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart); }else { _incoming = getFirstVideoFilter (frameStart,frameEnd-frameStart); } videoBuffer=new uint8_t[_incoming->getInfo()->width*_incoming->getInfo()->height*3]; // Set global header encoding, needed for H264 _encode = getVideoEncoder (_incoming->getInfo()->width, _incoming->getInfo()->height,1); total= _incoming->getInfo()->nb_frames; encoding_gui=new DIA_encoding(_incoming->getInfo()->fps1000); bitstream.bufferSize=_incoming->getInfo()->width*_incoming->getInfo()->height*3; if (!_encode) { GUI_Error_HIG (QT_TR_NOOP("Cannot initialize the video stream"), NULL); goto stopit; } // init compressor encoding_gui->setContainer(containerTitle); encoding_gui->setAudioCodec("None"); if(!videoProcessMode()) encoding_gui->setCodec("Copy"); else encoding_gui->setCodec(_encode->getDisplayName()); TwoPassLogFile=new char[strlen(name)+6]; strcpy(TwoPassLogFile,name); strcat(TwoPassLogFile,".stat"); _encode->setLogFile(TwoPassLogFile,total); if (!_encode->configure (_incoming)) { GUI_Error_HIG (QT_TR_NOOP("Filter init failed"), NULL); goto stopit; }; dualPass=_encode->isDualPass(); if(dualPass) { if(!prepareDualPass(bitstream.bufferSize,videoBuffer,TwoPassLogFile,encoding_gui,_encode,total)) goto stopit; }else { encoding_gui->setPhasis ("Encoding"); } info.width=_incoming->getInfo()->width; info.height=_incoming->getInfo()->height; info.nb_frames=_incoming->getInfo()->nb_frames; info.fps1000=_incoming->getInfo()->fps1000; info.fcc=*(uint32_t *)_encode->getCodecName(); //FIXME _encode->hasExtraHeaderData( &videoExtraDataSize,&dummy); if(videoExtraDataSize) { printf("We have extradata for video in copy mode (%d)\n",videoExtraDataSize); videoExtraData=new uint8_t[videoExtraDataSize]; memcpy(videoExtraData,dummy,videoExtraDataSize); } // _________________Setup video (cont) _______________ // ___________ Read 1st frame _________________ ADM_assert(_encode); bitstream.data=videoBuffer; preFilling: bitstream.cleanup(0); if(!(err=_encode->encode ( prefill, &bitstream)))//&len, videoBuffer, &flags,&displayFrame)) { printf("MP4:First frame error\n"); GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL); goto stopit; } sent++; if(!bitstream.len) { prefill++; goto preFilling; } printf("Pass 2 prefill : %u\n",prefill); if(!bitstream.flags & AVI_KEY_FRAME) { GUI_Error_HIG (QT_TR_NOOP("KeyFrame error"),QT_TR_NOOP( "The beginning frame is not a key frame.\nPlease move the A marker.")); goto stopit; } //len=bitstream.len; // If needed get VOL header if(isMpeg4Compatible(info.fcc) && !videoExtraDataSize && bitstream.len) { // And put them as extradata for esds atom uint32_t voslen=0; if(extractVolHeader(videoBuffer,bitstream.len,&voslen)) { if(voslen) { videoExtraDataSize=voslen; videoExtraData=new uint8_t[videoExtraDataSize]; memcpy(videoExtraData,videoBuffer,videoExtraDataSize); } } else printf("Oops should be settings data for esds\n"); } // ____________Setup audio__________________ if(currentaudiostream) { audio=mpt_getAudioStream(); if(!audio) { GUI_Error_HIG (QT_TR_NOOP("Cannot initialize the audio stream"), NULL); goto stopit; } } if(audio) { audioinfo=audio->getInfo(); audio->extraData(&extraDataSize,&extraData); if(audioProcessMode()) encoding_gui->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding)); else encoding_gui->setAudioCodec("Copy"); }else { encoding_gui->setAudioCodec("None"); } // ____________Setup Muxer _____________________ muxer= new lavMuxer; if(!muxer->open( name, 2000000, // Muxrate muxerType, &info,videoExtraDataSize,videoExtraData, audioinfo,extraDataSize,extraData)) goto stopit; //_____________ Loop _____________________ encoding_gui->setContainer(containerTitle); if(!videoProcessMode()) encoding_gui->setCodec("Copy"); else encoding_gui->setCodec(_encode->getDisplayName()); // UI_purge(); if(bitstream.len) { muxer->writeVideoPacket( &bitstream); frameWrite++; } //_____________ Start Audio thread _____________________ if(audio) { pq=new PacketQueue("MP4 audioQ",5000,2*1024*1024); memset(&context,0,sizeof(context)); context.audioEncoder=audio; context.audioTargetSample=0xFFFF0000; ; //FIXME context.packetQueue=pq; // start audio thread ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioQueueSlave,&context)); ADM_usleep(4000); } //_____________GO !___________________ for(int frame=1;frame<total;frame++) { while(muxer->needAudio()) { if(pq->Pop(audioBuffer,&alen,&sample)) { if(alen) { muxer->writeAudioPacket(alen,audioBuffer,sample_got); totalAudioSize+=alen; encoding_gui->setAudioSize(totalAudioSize); sample_got+=sample; } }else break; } ADM_assert(_encode); bitstream.cleanup(frameWrite); if(!prefill || frame+prefill<total) { r=_encode->encode ( prefill+frame, &bitstream); } else { r=_encode->encode ( total-1, &bitstream); } if(!r && frame<total-2) { printf("MP4:Frame %u error\n",frame); GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL); goto stopit; } if(!bitstream.len && skipping) { printf("Frame skipped (xvid ?)\n"); continue; } sent++; skipping=0; // printf("Prefill %u FrameWrite :%u Frame %u PtsFrame :%u\n",prefill,frameWrite,frame,bitstream.ptsFrame); frameWrite++; muxer->writeVideoPacket( &bitstream); encoding_gui->setFrame(frame,bitstream.len,bitstream.out_quantizer,total); if(!encoding_gui->isAlive()) { goto stopit; } } ret=1; stopit: printf("2nd pass, sent %u frames\n",sent); // Flush slave Q if(audio) { context.audioAbort=1; pq->Abort(); // Wait for audio slave to be over while(!context.audioDone) { printf("Waiting Audio thread\n"); ADM_usleep(500000); } delete pq; } // if(muxer) muxer->close(); if(encoding_gui) delete encoding_gui; if(TwoPassLogFile) delete [] TwoPassLogFile; if(videoBuffer) delete [] videoBuffer; if(muxer) delete muxer; if(_encode) delete _encode; if(videoExtraData) delete [] videoExtraData; // Cleanup deleteAudioFilter (audio); return ret; }
/** \fn runOneJob */ bool jobWindow::runOneJob( ADMJob &job) { bool r=false; uint32_t version; job.startTime=ADM_getSecondsSinceEpoch(); job.status=ADM_JOB_RUNNING; ADM_commandSocket *runSocket=NULL; ADMJob::jobUpdate(job); refreshList(); ADM_socketMessage msg; uint32_t v; // 1- Start listening to socket // 2- Spawn child string ScriptFullPath; #ifdef _WIN32 #define MKCLI() "avidemux_cli.exe" #define MKQT() "avidemux.exe" string slash=string("\\"); #else #define MKCLI() "avidemux3_cli" #define MKQT() "avidemux3_qt4" string slash=string("/"); #endif ScriptFullPath=string(ADM_getJobDir())+slash+string(job.scriptName); const char *avidemuxVersion=MKCLI(); if(ui.checkBoxUseQt4->isChecked()) { avidemuxVersion=MKQT(); } if(false==spawnChild(avidemuxVersion,ScriptFullPath,job.outputFileName)) { ADM_error("Cannot spawn child\n"); r=false; goto done; } // 3- Wait for connect... runSocket=mySocket.waitForConnect(6*1000); if(!runSocket) { ADM_error("No connect\n"); goto done; } if(!runSocket->handshake()) { popup("Cannot handshake"); goto done; } // 4- wait for complete and/or success message while(1) { if(!runSocket->isAlive()) { ADM_info("Exiting loop\n"); break; } if(runSocket->pollMessage(msg)) { ADM_info("Got a new message %d\n",msg.command); switch(msg.command) { case ADM_socketCommand_End: if(msg.getPayloadAsUint32_t(&v)) { r=(bool)v; ADM_info("Result is %d\n",r); goto done; }else { ADM_error("Can read End payload \n"); } break; case ADM_socketCommand_Progress: if(msg.getPayloadAsUint32_t(&v)) { printf("Progress %d %%\n",(int)v); dialog->setPercent(v); }else { ADM_error("Can read End payload \n"); } break; default: ADM_error("Unknown command\n"); break; } } ADM_assert(dialog); QApplication::processEvents(); ADM_usleep(1000*1000); // Refresh once per sec } ADM_info("** End of slave process **\n"); ADM_info("** End of slave process **\n"); ADM_info("** End of slave process **\n"); // 5-Done, do the cleanup done: if(r) job.status=ADM_JOB_OK; else job.status=ADM_JOB_KO; job.endTime=ADM_getSecondsSinceEpoch(); ADMJob::jobUpdate(job); if(runSocket) delete runSocket; refreshList(); ADM_info("Running job id = %d\n",job.id); return r; }
/** \fn initializeAudio \brief Initialize audio */ bool GUIPlayback::initializeAudio(void) { uint32_t state,latency, preload; uint32_t small_; uint32_t channels,frequency; wavbuf = 0; uint64_t startPts=firstPts; int32_t shift=0; // unit is ms, + => delay audio, -=> advance audio // if audio shift is activated, take it into account // EditableAudioTrack *ed=video_body->getDefaultEditableAudioTrack(); if(ed->audioEncodingConfig.shiftEnabled) shift=ed->audioEncodingConfig.shiftInMs; playbackAudio = createPlaybackFilter(startPts,shift); if(!playbackAudio) { ADM_info("No audio\n"); return false; } channels= playbackAudio->getInfo()->channels; frequency=playbackAudio->getInfo()->frequency; preload= (frequency * channels)/5; // 200 ms preload // 4 sec buffer.. wavbuf = (float *) ADM_alloc((20*sizeof(float)*preload)); // 4 secs buffers ADM_assert(wavbuf); // Read a at least one block to have the proper channel mapping uint32_t fill=0; AUD_Status status; small_ = playbackAudio->fill(channels, wavbuf,&status); fill+=small_; // Call it twice to be sure it is properly setup state = AVDM_AudioSetup(frequency, channels ,playbackAudio->getChannelMapping()); AVDM_AudioClose(); state = AVDM_AudioSetup(frequency, channels ,playbackAudio->getChannelMapping()); latency=AVDM_GetLayencyMs(); printf("[Playback] Latency : %d ms\n",latency); audioLatency=latency; // ms -> us if (!state) { GUI_Error_HIG(QT_TR_NOOP("Trouble initializing audio device"), NULL); cleanupAudio(); return false; } while(fill<preload) { if (!(small_ = playbackAudio->fill(preload-fill, wavbuf+fill,&status))) { break; } fill+=small_; } nbSamplesSent = fill/channels; // In sample AVDM_AudioPlay(wavbuf, fill); // Let audio latency sets in... ticktock.reset(); uint32_t slice=(frequency * channels)/100; // 10 ms // pump data until latency is over updateVu(); #if 0 while(ticktock.getElapsedMS()<latency) { if(AVDM_getMsFullness()<AUDIO_PRELOAD) { if (!(small_ = playbackAudio->fill(slice, wavbuf,&status))) { printf("[Playback] Compensating for latency failed\n"); break; } AVDM_AudioPlay(wavbuf, slice); } ADM_usleep(10*1000); updateVu(); } #endif printf("[Playback] Latency is now %u\n",ticktock.getElapsedMS()); return true; }
//void automation(int argc, char **argv) int automation(void ) { static char **argv; static int argc; static int cur; static int myargc; static three_arg_type three; static two_arg_type two; static int index; argv=global_argv; argc=global_argc; ADM_usleep(100000); // let gtk start gdk_threads_enter(); printf("\n *** Automated : %d entries*************\n",NB_AUTO); // we need to process argc-=1; cur=1; myargc=argc; while(myargc>0) { if(( *argv[cur]!='-') || (*(argv[cur]+1)!='-')) { if(cur==1) { A_openAvi(argv[cur]); } else printf("\n Found garbage %s\n",argv[cur]); cur+=1;myargc-=1; continue; } // else it begins with -- index= searchReactionTable(argv[cur]+2); if(index==-1) // not found { printf("\n Unknown command :%s\n",argv[cur] ); cur+=1;myargc-=1; } else { printf("%s-->%d\n", reaction_table[index].string,reaction_table[index].have_arg); switch( reaction_table[index].have_arg) { case 3: three=( three_arg_type) reaction_table[index].callback; three( argv[cur+1],argv[cur+2],argv[cur+3]); printf("\n arg: %d index %d\n",myargc,index); break; case 2: two=( two_arg_type) reaction_table[index].callback; two( argv[cur+1],argv[cur+2]); break; case 1: reaction_table[index].callback(argv[cur+1]); break; case 0: reaction_table[index].callback(NULL); break; default: ADM_assert(0); break; } cur+=1+reaction_table[index].have_arg; myargc-=1+reaction_table[index].have_arg; } } // end while GUI_Verbose(); printf("\n ********** Automation ended***********\n"); gdk_threads_leave(); return FALSE; // Do not call me anymore }
//_______________________________________ // void ComputePreload(void) //_______________________________________ { uint32_t state,latency, one_sec; uint32_t small_; uint32_t channels; wavbuf = 0; if (!currentaudiostream) // audio ? { return; } // PCM or readable format ? if (currentaudiostream->isCompressed()) { if (!currentaudiostream->isDecompressable()) { audio_available = 0; return; } } double db; // go to the beginning... db = curframe * 1000.; // ms db *= 1000.; // fps is 1000 time too big db /= avifileinfo->fps1000; printf(".. Offset ...%ld ms\n", (uint32_t) floor(db + 0.49)); // currentaudiostream->goToTime( (uint32_t)floor(db+0.49)); playback = buildPlaybackFilter(currentaudiostream,(uint32_t) (db + 0.49), 0xffffffff); channels= playback->getInfo()->channels; one_audio_frame = (one_frame * wavinfo->frequency * channels); // 1000 *nb audio bytes per ms one_audio_frame /= 1000; // In elemtary info (float) printf("1 audio frame = %lu bytes\n", one_audio_frame); // 3 sec buffer.. wavbuf = (float *) ADM_alloc((3 * 2*channels * wavinfo->frequency*wavinfo->channels)); ADM_assert(wavbuf); // Call it twice to be sure it is properly setup state = AVDM_AudioSetup(playback->getInfo()->frequency, channels ); AVDM_AudioClose(); state = AVDM_AudioSetup(playback->getInfo()->frequency, channels ); latency=AVDM_GetLayencyMs(); printf("[Playback] Latency : %d ms\n",latency); if (!state) { GUI_Error_HIG(QT_TR_NOOP("Trouble initializing audio device"), NULL); return; } // compute preload //_________________ // we preload 1/4 a second currentaudiostream->beginDecompress(); one_sec = (wavinfo->frequency * channels) >> 2; one_sec+=(latency*wavinfo->frequency * channels*2)/1000; AUD_Status status; uint32_t fill=0; while(fill<one_sec) { if (!(small_ = playback->fill(one_sec-fill, wavbuf,&status))) { break; } fill+=small_; } dauds += fill/channels; // In sample AVDM_AudioPlay(wavbuf, fill); // Let audio latency sets in... ADM_usleep(latency*1000); audio_available = 1; }
void dummyAudioDevice::sendData(void) {ADM_usleep(5000);}
uint8_t oplug_mpegff(const char *name, ADM_OUT_FORMAT type) { AVDMGenericVideoStream *_incoming; Encoder *encoder=NULL; ADMMpegMuxer *muxer=NULL; FILE *file=NULL; uint8_t audioBuffer[48000]; uint32_t audioLen=0; uint32_t _w,_h,_fps1000,_page,total; AVDMGenericAudioStream *audio=NULL; uint32_t len,flags; uint32_t size; ADM_MUXER_TYPE mux; uint32_t audio_encoding=0; uint32_t real_framenum=0; uint8_t ret=0; uint32_t sample_target=0; uint32_t total_sample=0; ADMBitstream bitstream(0); uint32_t audioSum=0; DIA_encoding *encoding; int reuse = 0; twoPass=new char[strlen(name)+6]; twoFake=new char[strlen(name)+6]; strcpy(twoPass,name); strcat(twoPass,".stat"); strcpy(twoFake,name); strcat(twoFake,".fake"); _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart); _w=_incoming->getInfo()->width; _h=_incoming->getInfo()->height; _fps1000=_incoming->getInfo()->fps1000; _page=_w*_h; _page+=_page>>1; total=_incoming->getInfo()->nb_frames; if(!total) return 0; switch(type) { default: ADM_assert(0); case ADM_ES: // Else open file (if possible) mux=MUXER_NONE; break; case ADM_TS: if(!currentaudiostream) { GUI_Error_HIG(QT_TR_NOOP("There is no audio track"), NULL); goto finishvcdff; } audio=mpt_getAudioStream(); mux=MUXER_TS; break; case ADM_PS: { if(!currentaudiostream) { GUI_Error_HIG(QT_TR_NOOP("There is no audio track"), NULL); goto finishvcdff; } audio=mpt_getAudioStream(); // Have to check the type // If it is mpeg2 we use DVD-PS // If it is mpeg1 we use VCD-PS // Later check if it is SVCD if(!audio) { GUI_Error_HIG(QT_TR_NOOP("Audio track is not suitable"), NULL); goto finishvcdff; } // Check WAVHeader *hdr=audio->getInfo(); audio_encoding=hdr->encoding; if (videoCodecGetType() == CodecXVCD || videoCodecGetType() == CodecVCD) { if(hdr->frequency!=44100 || hdr->encoding != WAV_MP2) { GUI_Error_HIG(("Incompatible audio"),QT_TR_NOOP( "For VCD, audio must be 44.1 kHz MP2.")); goto finishvcdff; } mux=MUXER_VCD; printf("X*CD: Using VCD PS\n"); }else { aviInfo info; video_body->getVideoInfo(&info); if(hdr->frequency==44100 && _w==480&&hdr->encoding == WAV_MP2 ) // SVCD ? { mux=MUXER_SVCD; printf("X*VCD: Using SVCD PS\n"); } else { // mpeg2, we do only DVD right now if(hdr->frequency!=48000 || (hdr->encoding != WAV_MP2 && hdr->encoding!=WAV_AC3 && hdr->encoding!=WAV_LPCM)) { GUI_Error_HIG(QT_TR_NOOP("Incompatible audio"), QT_TR_NOOP("For DVD, audio must be 48 kHz MP2, AC3 or LPCM.")); goto finishvcdff; } mux=MUXER_DVD; printf("X*VCD: Using DVD PS\n"); } } } } // Create muxer switch (videoCodecGetType()) { case CodecXVCD: encoder=new EncoderFFMPEGMpeg1(FF_MPEG1,&ffmpeg1Codec); printf("\n Using ffmpeg mpeg1 encoder\n"); break; case CodecXSVCD: encoder=new EncoderFFMPEGMpeg1(FF_MPEG2,&ffmpeg2SVCDCodec); printf("\n Using ffmpeg mpeg2 encoder\n"); break; case CodecXDVD: encoder=new EncoderFFMPEGMpeg1(FF_MPEG2,&ffmpeg2DVDCodec); printf("\n Using ffmpeg mpeg2 encoder (DVD)\n"); break; case CodecDVD: encoder=new EncoderMpeg2enc(MPEG2ENC_DVD,&DVDCodec); printf("\n Using mpeg2enc encoder (DVD)\n"); break; case CodecRequant: if(!isMpeg12Compatible(avifileinfo->fcc)) { GUI_Error_HIG("Incompatible Input","The input file must be mpeg2 to be able to use requant!"); return 0; // Fixme, do some cleanup } encoder=new EncoderRequant(&RequantCodec); printf("\n Using mpeg2 requant\n"); break; break; case CodecSVCD: encoder=new EncoderMpeg2enc(MPEG2ENC_SVCD,&SVCDCodec); printf("\n Using mpeg2enc encoder (SVCD)\n"); break; case CodecVCD: encoder=new EncoderMpeg2enc(MPEG2ENC_VCD,&VCDCodec); printf("\n Using mpeg2enc encoder (VCD)\n"); break; default: ADM_assert(0); } encoder->setLogFile(twoPass,total); if (encoder->isDualPass()) { printf("Verifying log file\n"); if (encoder->verifyLog(twoPass, total) && GUI_Question(QT_TR_NOOP("Reuse the existing log file?"))) reuse = 1; } if(!encoder->configure(_incoming, reuse)) goto finishvcdff; _buffer=new uint8_t[_page]; // Might overflow if _page only _outbuffer=new uint8_t[_page]; ADM_assert( _buffer); ADM_assert( _outbuffer); encoding =new DIA_encoding(_fps1000); switch (videoCodecGetType()) { case CodecVCD: encoding->setCodec(QT_TR_NOOP("libmpeg2enc VCD")); break; case CodecSVCD: encoding->setCodec(QT_TR_NOOP("libmpeg2enc SVCD")); break; case CodecDVD: encoding->setCodec(QT_TR_NOOP("libmpeg2enc DVD")); break; case CodecXVCD: encoding->setCodec(QT_TR_NOOP("FFmpeg MPEG-1 VBR")); break; case CodecXSVCD: encoding->setCodec(QT_TR_NOOP("FFmpeg MPEG-2 SVCD VBR")); break; case CodecXDVD: encoding->setCodec(QT_TR_NOOP("FFmpeg MPEG-2 DVD VBR")); break; case CodecRequant: encoding->setCodec(QT_TR_NOOP("MPEG Requantizer")); break; default: ADM_assert(0); } switch(mux) { case MUXER_NONE:encoding->setContainer(QT_TR_NOOP("MPEG ES"));break; case MUXER_TS: encoding->setContainer(QT_TR_NOOP("MPEG TS"));break; case MUXER_VCD: encoding->setContainer(QT_TR_NOOP("MPEG VCD"));break; case MUXER_SVCD:encoding->setContainer(QT_TR_NOOP("MPEG SVCD"));break; case MUXER_DVD: encoding->setContainer(QT_TR_NOOP("MPEG DVD"));break; default: ADM_assert(0); } // pass 1 if(encoder->isDualPass()) //Cannot be requant { if(!reuse) { encoding->setPhasis (QT_TR_NOOP("Pass 1/2")); encoder->startPass1(); bitstream.data=_buffer; bitstream.bufferSize=_page; for(uint32_t i=0;i<total;i++) { bitstream.cleanup(i); if(!encoder->encode( i, &bitstream))//&len,(uint8_t *) _buffer,&flags)) { GUI_Error_HIG(QT_TR_NOOP("Error in pass 1"), NULL); } encoding->setFrame(i,bitstream.len,bitstream.out_quantizer,total); if(!encoding->isAlive()) goto finishvcdff; } } encoder->startPass2(); encoding->reset(); } switch(type) { case ADM_PS: muxer=new mplexMuxer; break; case ADM_TS: muxer=new tsMuxer; break; case ADM_ES: break; default: ADM_assert(0); } if(muxer) { if(!muxer->open(name,0,mux,avifileinfo,audio->getInfo())) { printf("Muxer init failed\n"); goto finishvcdff; } double sample_time; sample_time=total; sample_time*=1000; sample_time/=_fps1000; // target_time in second sample_time*=audio->getInfo()->frequency; sample_target=(uint32_t)floor(sample_time); } else { file=fopen(name,"wb"); if(!file) { GUI_Error_HIG(QT_TR_NOOP("File error"), QT_TR_NOOP("Cannot open \"%s\" for writing."), name); goto finishvcdff; } } if(encoder->isDualPass()) encoding->setPhasis (QT_TR_NOOP("Pass 2/2")); else encoding->setPhasis (QT_TR_NOOP("Encoding")); // Set info for audio if any if(muxer) { if(!audioProcessMode()) encoding->setAudioCodec(QT_TR_NOOP("Copy")); else encoding->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding)); } //********************************************************** // In that case we do multithreadedwriting (yes!) //********************************************************** if(mux==MUXER_DVD || mux==MUXER_SVCD || mux==MUXER_VCD) { pthread_t audioThread,videoThread,muxerThread; muxerMT context; // bitstream.data=_outbuffer; bitstream.bufferSize=_page; // memset(&context,0,sizeof(context)); context.videoEncoder=encoder; context.audioEncoder=audio; context.muxer=(mplexMuxer *)muxer; context.nbVideoFrame=total; context.audioTargetSample=sample_target; context.audioBuffer=audioBuffer; context.bitstream=&bitstream; context.opaque=(void *)encoding; // start audio thread ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioSlave,&context)); ADM_assert(!pthread_create(&videoThread,NULL,(THRINP)defaultVideoSlave,&context)); while(1) { accessMutex.lock(); if(!encoding->isAlive()) { context.audioAbort=1; context.videoAbort=1; printf("[mpegFF]Waiting for slaves\n"); accessMutex.unlock(); while(1) { accessMutex.lock(); if(context.audioDone && context.videoDone) { printf("[mpegFF]Both audio & video done\n"); if(context.audioDone==1 && context.videoDone==1) ret=1; accessMutex.unlock(); goto finishvcdff; } accessMutex.unlock(); ADM_usleep(50000); } } if(context.audioDone==2 || context.videoDone==2 ) //ERROR { context.audioAbort=1; context.videoAbort=1; } if(context.audioDone && context.videoDone) { printf("[mpegFF]Both audio & video done\n"); if(context.audioDone==1 && context.videoDone==1) ret=1; accessMutex.unlock(); goto finishvcdff; } accessMutex.unlock(); ADM_usleep(1000*1000); } } //********************************************************** // NOT MULTITHREADED //********************************************************** bitstream.data=_outbuffer; bitstream.bufferSize=_page; for(uint32_t i=0;i<total;i++) { // get frame bitstream.cleanup(i); if(!encoder->encode( i,&bitstream))// &len,(uint8_t *) _outbuffer,&flags)) { GUI_Error_HIG(QT_TR_NOOP("Error in pass 2"), NULL); goto finishvcdff; } if(!bitstream.len) continue; if(file) { fwrite(_outbuffer,bitstream.len,1,file); } else { uint32_t samples; //printf("%lu %lu\n",i,dts); muxer->writeVideoPacket(&bitstream); real_framenum++; // _muxer->writeVideoPacket(len,_buffer_out, //i-MPEG_PREFILL,_codec->getCodedPictureNumber()); if(total_sample<sample_target) { while(muxer->needAudio() && total_sample<sample_target) { if(!audio->getPacket(audioBuffer, &audioLen, &samples)) { break; } if(audioLen) { muxer->writeAudioPacket(audioLen,audioBuffer); total_sample+=samples; audioSum+=audioLen; } } } } encoding->setFrame(i,bitstream.len,bitstream.out_quantizer,total); encoding->setAudioSize(audioSum); if(!encoding->isAlive ()) goto finishvcdff; } ret=1; finishvcdff: printf("[MPEGFF] Finishing..\n"); delete encoding; end(); if(file) { fclose(file); file=NULL; } else if(muxer) { muxer->close(); delete muxer; muxer=NULL; } delete encoder; if (audio) deleteAudioFilter(audio); return ret; }
/* * \fn Oplug_flv \brief Main function to save in flv format. It is very close to oplug_mp4 but somehow simplified as the following assumptions are made : * No b frame * No 2 pass encoding */ uint8_t oplug_flv(const char *name) { AVDMGenericVideoStream *_incoming=NULL; AVDMGenericAudioStream *audio=NULL; uint8_t audioBuffer[48000]; uint8_t *videoBuffer=NULL; uint32_t alen;//,flags; uint32_t size; uint32_t sample_got=0,sample; uint32_t extraDataSize=0; uint8_t *extraData=NULL; lavMuxer *muxer=NULL; aviInfo info; uint32_t width,height; DIA_encoding *encoding_gui=NULL; Encoder *_encode=NULL; uint32_t total=0; uint32_t videoExtraDataSize=0; uint8_t *videoExtraData=NULL; uint8_t *dummy,err; WAVHeader *audioinfo=NULL; int prefill=0; uint32_t displayFrame=0; ADMBitstream bitstream(0); uint8_t r=0; pthread_t audioThread; audioQueueMT context; PacketQueue *pq=NULL;//("MP4 audioQ",50,2*1024*1024); uint32_t totalAudioSize=0; int frameDelay = 0; bool receivedFrame = false; // Setup video if(videoProcessMode()) { _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart); }else { _incoming = getFirstVideoFilter (frameStart,frameEnd-frameStart); } videoBuffer=new uint8_t[_incoming->getInfo()->width*_incoming->getInfo()->height*3]; // Set global header encoding, needed for H264 _encode = getVideoEncoder (_incoming->getInfo()->width, _incoming->getInfo()->height,1); total= _incoming->getInfo()->nb_frames; info.fcc=*(uint32_t *)_encode->getCodecName(); //FIXME // int supported=0; if(isVP6Compatible(info.fcc)) supported=1; if(fourCC::check(info.fcc,(const uint8_t *)"FLV1")) supported=1; if(!supported) { GUI_Error_HIG(QT_TR_NOOP("Unsupported video"),QT_TR_NOOP("Only FLV1 and VP6 video are supported")); goto stopit; } /* Check audio, we support only mp3 right now * 44100, 22050, 11025 only! * */ if(currentaudiostream) { uint32_t audioCodec=0; uint32_t fq=currentaudiostream->getInfo()->frequency; if(audioProcessMode()) { audioCodec=audioFilter_getOuputCodec(); fq=audioFilter_getOuputFrequency(fq); }else { // copy audioCodec=currentaudiostream->getInfo()->encoding; } if(audioCodec!=WAV_MP3 ) { GUI_Error_HIG(QT_TR_NOOP("Unsupported audio"),QT_TR_NOOP("Audio must be mp3 for flv output.")); goto stopit; } if(fq!=44100 && fq!=22050 && fq!=11025) { GUI_Error_HIG(QT_TR_NOOP("Unsupported audio"),QT_TR_NOOP("Frequency must be 44100, 22050 or 11025 Hz.")); goto stopit; } } encoding_gui=new DIA_encoding(_incoming->getInfo()->fps1000); bitstream.bufferSize=_incoming->getInfo()->width*_incoming->getInfo()->height*3; if (!_encode) { GUI_Error_HIG ("[FLV]",QT_TR_NOOP("Cannot initialize the video stream")); goto stopit; } // init compressor encoding_gui->setContainer(QT_TR_NOOP("FLV")); encoding_gui->setAudioCodec(QT_TR_NOOP("None")); if(!videoProcessMode()) encoding_gui->setCodec(QT_TR_NOOP("Copy")); else encoding_gui->setCodec(_encode->getDisplayName()); if (!_encode->configure (_incoming)) { GUI_Error_HIG (QT_TR_NOOP("Filter init failed"), NULL); goto stopit; }; encoding_gui->setPhasis (QT_TR_NOOP("Encoding")); info.width=_incoming->getInfo()->width; info.height=_incoming->getInfo()->height; info.nb_frames=_incoming->getInfo()->nb_frames; info.fps1000=_incoming->getInfo()->fps1000; _encode->hasExtraHeaderData( &videoExtraDataSize,&dummy); if(videoExtraDataSize) { printf("[FLV]We have extradata for video in copy mode (%d)\n",videoExtraDataSize); videoExtraData=new uint8_t[videoExtraDataSize]; memcpy(videoExtraData,dummy,videoExtraDataSize); } ADM_assert(_encode); bitstream.data=videoBuffer; // ____________Setup audio__________________ if(currentaudiostream) { audio=mpt_getAudioStream(); if(!audio) { GUI_Error_HIG ("[FLV]",QT_TR_NOOP("Cannot initialize the audio stream")); goto stopit; } } if(audio) { audioinfo=audio->getInfo(); audio->extraData(&extraDataSize,&extraData); if(audioProcessMode()) encoding_gui->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding)); else encoding_gui->setAudioCodec(QT_TR_NOOP("Copy")); }else { encoding_gui->setAudioCodec(QT_TR_NOOP("None")); } // ____________Setup Muxer _____________________ muxer= new lavMuxer; if(!muxer->open( name, 2000000, // Muxrate MUXER_FLV, &info,videoExtraDataSize,videoExtraData, audioinfo,extraDataSize,extraData)) goto stopit; //_____________ Loop _____________________ encoding_gui->setContainer(QT_TR_NOOP("FLV")); if(!videoProcessMode()) encoding_gui->setCodec(QT_TR_NOOP("Copy")); else encoding_gui->setCodec(_encode->getDisplayName()); // UI_purge(); //_____________ Start Audio thread _____________________ if(audio) { pq=new PacketQueue("[FLV] audioQ",5000,2*1024*1024); memset(&context,0,sizeof(context)); context.audioEncoder=audio; context.audioTargetSample=0xFFFF0000; ; //FIXME context.packetQueue=pq; // start audio thread ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioQueueSlave,&context)); ADM_usleep(4000); } //_____________GO !___________________ for (uint32_t frame = 0; frame < total; frame++) { if (!encoding_gui->isAlive()) { r = 0; break; } while(muxer->needAudio()) { if(pq->Pop(audioBuffer,&alen,&sample)) { if(alen) { muxer->writeAudioPacket(alen,audioBuffer,sample_got); totalAudioSize+=alen; encoding_gui->setAudioSize(totalAudioSize); sample_got+=sample; } } else { r = 0; break; } } for (;;) { bitstream.cleanup(frame); if (frame + frameDelay >= total) { if (_encode->getRequirements() & ADM_ENC_REQ_NULL_FLUSH) r = _encode->encode(UINT32_MAX, &bitstream); else r = 0; } else r = _encode->encode(frame + frameDelay, &bitstream); if (!r) { printf("Encoding of frame %lu failed!\n", frame); GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL); break; } else if (!receivedFrame && bitstream.len > 0) { if (!(bitstream.flags & AVI_KEY_FRAME)) { GUI_Error_HIG (QT_TR_NOOP("KeyFrame error"), QT_TR_NOOP("The beginning frame is not a key frame.\nPlease move the A marker.")); r = 0; break; } else receivedFrame = true; } if (bitstream.len == 0 && (_encode->getRequirements() & ADM_ENC_REQ_NULL_FLUSH)) { printf("skipping frame: %u size: %i\n", frame + frameDelay, bitstream.len); frameDelay++; } else break; } if (!r) break; muxer->writeVideoPacket(&bitstream); encoding_gui->setFrame(frame, bitstream.len, bitstream.out_quantizer, total); } stopit: // Flush slave Q if(audio&& pq) { context.audioAbort=1; pq->Abort(); // Wait for audio slave to be over while(!context.audioDone) { printf("[FLV]Waiting Audio thread\n"); ADM_usleep(500000); } delete pq; } // if(muxer) muxer->close(); if(encoding_gui) delete encoding_gui; if(videoBuffer) delete [] videoBuffer; if(muxer) delete muxer; if(_encode) delete _encode; if(videoExtraData) delete [] videoExtraData; // Cleanup deleteAudioFilter (audio); return r; }
// // Sleep for n ms // void GUI_Sleep(uint32_t ms) { if (ms < 10) return; ADM_usleep(ms*1000); }
/** \fn sendData \brief Do nothing, SDL has its own thread/callback */ void sdlAudioDevice::sendData(void) { ADM_usleep(5*1000); }