/** \fn switchToSegment \brief Switch to the segment given as argument */ bool ADM_Composer::switchToSegment(uint32_t s,bool dontdecode) { if(s+1>_segments.getNbSegments()) { ADM_warning("Cannot switch to segment:%"PRIu32"\n",s); return false; } _SEGMENT *seg=_segments.getSegment(s); ADM_assert(seg); ADM_info("Trying to switch to seg %"PRIu32" with startTime in reference pic= %"PRIu32" ms\n",s,seg->_refStartTimeUs/1000); // If the refStartTime is 0, it is the first image // But the fist image might not be = 0 _VIDEOS *vid=_segments.getRefVideo(seg->_reference); vidHeader *demuxer=vid->_aviheader; ADM_assert(vid); uint64_t from=seg->_refStartTimeUs; uint64_t pts,dts; if(!from) from=vid->firstFramePts; if(false==seektoTime(seg->_reference,from,dontdecode)) { ADM_warning("Cannot seek to beginning of segment %"PRIu32" at %"PRIu64" ms\n",s,from/1000); return false; } _currentSegment=s; ADM_info("Switched ok to segment %"PRIu32" (dontdecode=%d)\n",s,dontdecode); return true; }
bool ADM_Composer::addToUndoQueue(void) { // truncate the dead branch first if we add a new element to the undo queue after _cnt-1 undo steps if(_cnt>1 && undoQueue.size()>1) { for(uint32_t i=0;i<_cnt;i++) { undoQueue.pop_back(); } ADM_info("Deleted last %d elements from the undo queue\n",_cnt); } // now populate the new element... undoQueueElem rec; uint64_t a=getMarkerAPts(); uint64_t b=getMarkerBPts(); rec.segm=_segments.getSegments(); rec.markerA=a; rec.markerB=b; // ...do some housekeeping... uint32_t m=maxUndoSteps; if(m<10) m=10; // less than 10 undo steps is a bad idea, ignore the limit then uint32_t nb=undoQueue.size(); if(nb>m) { // erase the oldest records if the limit is exceeded and create space for a new one undoQueue.erase(undoQueue.begin(),undoQueue.begin()+nb-m+1); } // ...and store the new element in the queue undoQueue.push_back(rec); ADM_info("The undo queue has now %d element(s)\n",undoQueue.size()); _cnt=0; // redo should not be available after a new undo-able action has been performed return true; }
/** \fn setupAudio \brief create the audio streams we will use (copy/process) */ bool admSaver::setupAudio() { bool r=true; ADM_info("Setting up %d audio track(s)\n",nbAudioTracks); for(int i=0;i<nbAudioTracks;i++) { EditableAudioTrack *ed=video_body->getEditableAudioTrackAt(i); ADM_audioStream *access=NULL; if(ed->encoderIndex) // encode { // Access.. ADM_info("[audioTrack %d] Creating audio encoding stream, starttime %s(encoding with encoder=%d)\n",i,ADM_us2plain(startAudioTime),ed->encoderIndex); access=audioCreateEncodingStream(ed,muxer->useGlobalHeader(),startAudioTime); // FIXME LEAK FIXME }else // copy mode... { ADM_info("[audioTrack %d] Creating audio encoding stream, starttime %s(copy)\n",i,ADM_us2plain(startAudioTime)); int32_t shift=0; if(ed->audioEncodingConfig.shiftEnabled) { shift=ed->audioEncodingConfig.shiftInMs; ADM_info("Using shift of %d ms\n",(int)shift); } access=audioCreateCopyStream(startAudioTime,shift,ed->edTrack,!muxer->canDealWithTimeStamps()); } if(!access) { GUI_Error_HIG("Audio","Cannot setup audio encoder, make sure your stream is compatible with audio encoder (number of channels, bitrate, format)"); return false; } audioAccess[i]=access; } return r; }
/** \fn GoToIntraTime \brief Go to an intra at time time (exact) \return true on success, false on error */ bool ADM_Composer::goToIntraTimeVideo(uint64_t time) { uint32_t frame; if(false==GoToIntraTime_noDecoding(time,&frame)) { ADM_warning("Seek failed.\n"); return false; } _SEGMENT *seg=_segments.getSegment(_currentSegment); // Ok, we have switched to a new segment // Flush the cache _VIDEOS *vid= _segments.getRefVideo(seg->_reference); if(false== DecodePictureUpToIntra(seg->_reference,frame)) { return false; } // Get the last decoded PTS and it is our current PTS uint64_t newPts=vid->lastDecodedPts+seg->_startTimeUs; newPts-=seg->_refStartTimeUs; SET_CURRENT_PTS(newPts); #if 0 ADM_info("decodec DTS=%"PRIu64" ms\n",vid->lastDecodedPts/1000); ADM_info("startTime DTS=%"PRIu64" ms\n",seg->_startTimeUs/1000); ADM_info("refstart DTS=%"PRIu64" ms\n",seg->_refStartTimeUs/1000); ADM_info("Current DTS=%"PRIu64" ms\n",_currentPts/1000); #endif return true; }
/** \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 startNewRiffIfNeeded */ bool aviIndexOdml::startNewRiffIfNeeded(int trackNo,int len) { bool breakNeeded=false; // Case 1: we exceed riff boundary (4 GB) uint64_t currentPosition=LMovie->Tell(); uint64_t start=_masterList->TellBegin(); uint64_t riffSize=currentPosition-start; uint64_t limit=((1LL<<31)-10*(1LL<<20)); // 2GB per riff chunk riffSize+=len; if(!riffCount) // take into account legacy index { for(int i=0;i<1+nbAudioTrack;i++) limit-=4*4*indexes[i].listOfChunks.size(); } if(riffSize> limit) { ADM_info("Riff is now %" PRIu64" bytes, break needed\n",riffSize); breakNeeded=true; } // Case 2 : the current index is full int available=(AVI_REGULAR_INDEX_CHUNK_SIZE-64)/8; // nb index entry if(indexes[trackNo].listOfChunks.size()>=available) { ADM_info("Index for track %d is full\n",trackNo); breakNeeded=true; } if(breakNeeded) startNewRiff(); return true; }
void qtRegisterDialog(QWidget *dialog) { if (widgetStack.count()) { Qt::WindowFlags flags = dialog->windowFlags(); bool reparent = false; bool isDialog = false; if (dialog->parentWidget() != widgetStack.top()) reparent = true; if (flags & Qt::Dialog) isDialog = true; #if defined(__APPLE__) && QT_VERSION == QT_VERSION_CHECK(5,10,1) if (reparent || isDialog) { ADM_info("Working around Qt bug introduced in 5.10.1 resulting in non-resizable dialogs with Cocoa\n"); dialog->setWindowFlag(Qt::Dialog, false); dialog->setParent(widgetStack.top(), Qt::Window); dialog->setWindowModality(Qt::ApplicationModal); dialog->show(); } #else if (reparent || !isDialog) { ADM_info("reparenting widget %s\n",dialog->objectName().toUtf8().constData()); dialog->setParent(widgetStack.top(), Qt::Dialog); dialog->show(); // reparenting makes the widget invisible } #endif } widgetStack.push(dialog); }
/** \fn detectTs \brief returns true if the file seems to be mpeg PS */ bool detectTs(const char *file) { uint8_t buffer[PROBE_SIZE]; uint32_t bufferSize; uint32_t nbPacket,nbMatch=0; FILE *f=ADM_fopen(file,"rb"); if(!f) return false; bufferSize=fread(buffer,1,PROBE_SIZE,f); fclose(f); // Do a simple check by checking we have 0x47....0x47 several time in a raw if(true==checkMarker(buffer,bufferSize,TS_PACKET_LEN)) { ADM_info("[TS Demuxer] 188 bytes packet detected\n"); return true; } // Do a simple check by checking we have 0x47....0x47 several time in a raw if(true==checkMarker(buffer,bufferSize,TS_PACKET_LEN+4)) { ADM_info("[TS Demuxer] 192 bytes packet detected\n"); return true; } ADM_info("[TS Demuxer] Not a TS file\n"); return false; }
uint8_t asfHeader::open(const char *name) { _fd=ADM_fopen(name,"rb"); if(!_fd) { GUI_Error_HIG("File Error.","Cannot open file\n"); return 0; } myName=ADM_strdup(name); if(!getHeaders()) { return 0; } ADM_info("Stream Video: index=%d, sid=%d\n",(int)_videoIndex,(int)_videoStreamId); for(int i=0;i<_nbAudioTrack;i++) ADM_info("Stream Audio: index=%d, sid=%d\n", (int)_allAudioTracks[i].streamIndex,(int)_allAudioTracks[i].streamIndex); buildIndex(); fseeko(_fd,_dataStartOffset,SEEK_SET); _packet=new asfPacket(_fd,_nbPackets,_packetSize,&readQueue,&storageQueue,_dataStartOffset); curSeq=1; for(int i=0;i<_nbAudioTrack;i++) { _audioAccess[i]=new asfAudioAccess(this,i); _audioStreams[i]=ADM_audioCreateStream(&(_allAudioTracks[i].wavHeader), _audioAccess[i]); } if(!nbImage) { ADM_error("No image found \n"); return 0; } return 1; }
/** * \fn compute the minimum us delta = maximum fps * \brief average fps is not good enough, it might be too high * @return */ bool MP4Header::refineFps(void) { int n=VDEO.nbIndex; uint64_t minDelta=60*1000*1000; for(int i=0;i<n-1;i++) { MP4Index *dex=&(_tracks[0].index[i]); MP4Index *next=&(_tracks[0].index[i+1]); if(dex->dts==ADM_NO_PTS) continue; if(next->dts==ADM_NO_PTS) continue; uint64_t delta=next->dts-dex->dts; if(delta<minDelta) minDelta=delta; } if(minDelta>1000) { double f=1000000./(double)minDelta; f*=1000.; ADM_info("MinDelta=%d us\n",(int)minDelta); ADM_info("Computed fps1000=%d\n",(int)f); uint32_t fps1000=floor(f+0.49); if(fps1000> _videostream.dwRate) { ADM_info("Adjusting fps, the computed is higher than average, dropped frames ?\n"); _videostream.dwRate=fps1000; _mainaviheader.dwMicroSecPerFrame=ADM_UsecFromFps1000(_videostream.dwRate); } } }
bool AUDMEncoder_DcaEnc::initialize (void) { int chan_config=0; switch(wavheader.channels) { case 1: chan_config=DCAENC_CHANNELS_MONO;break; case 2: chan_config=DCAENC_CHANNELS_STEREO;break; case 6: chan_config=DCAENC_CHANNELS_3FRONT_2REAR_1OV;break; case 5: chan_config=DCAENC_CHANNELS_3FRONT_2REAR;break; default: ADM_warning("Unsupported channel configuration \n"); break; } wavheader.byterate=(config.bitrate*1000)>>3; ADM_info("Starting dcaenc with channels=%d, bitrate=%d\n",wavheader.channels,config.bitrate); context=dcaenc_create(wavheader.frequency,chan_config,config.bitrate*1000,DCAENC_FLAG_BIGENDIAN ); if(!context) { ADM_warning("Cannot create dcaenc context \n"); return false; } inputSize=dcaenc_input_size(context); outputSize=dcaenc_output_size(context); ADM_info("Converting %d samples to %d bytes\n",inputSize,outputSize); return true; }
/** \fn convertLinearTimeToSeg \brief convert linear time to a segment+ offset in the segment */ bool ADM_EditorSegment::convertLinearTimeToSeg( uint64_t frameTime, uint32_t *seg, uint64_t *segTime) { if(!frameTime && segments.size()) // pick the first one { ADM_info("Frame time=0, taking first segment \n"); *seg=0; *segTime=0; // ?? return true; } for(int i=0;i<segments.size();i++) { if(segments[i]._startTimeUs<=frameTime && segments[i]._startTimeUs+segments[i]._durationUs>frameTime) { *seg=i; *segTime=frameTime-segments[i]._startTimeUs; return true; } } int max=segments.size(); if(max) { _SEGMENT *last=&(segments[max-1]); if(frameTime==last->_startTimeUs+last->_durationUs) { ADM_info("End of last segment\n"); *seg=max-1; *segTime=frameTime-last->_startTimeUs; return true; } } ADM_warning("Cannot find segment matching time %"PRIu64"ms \n",frameTime/1000); dump(); return false; }
/** \fn resetVdpau */ bool vdpauVideoFilterDeint::setupVdpau(void) { scaler=NULL; secondField=false; nextFrame=0; if(!admVdpau::isOperationnal()) { ADM_warning("Vdpau not operationnal\n"); return false; } if(VDP_STATUS_OK!=admVdpau::outputSurfaceCreate(VDP_RGBA_FORMAT_B8G8R8A8, info.width,info.height,&outputSurface)) { ADM_error("Cannot create outputSurface0\n"); return false; } for(int i=0;i<ADM_NB_SURFACES;i++) surfacePool[i]=VDP_INVALID_HANDLE; for(int i=0;i<ADM_NB_SURFACES;i++) { if(VDP_STATUS_OK!=admVdpau::surfaceCreate( previousFilter->getInfo()->width, previousFilter->getInfo()->height, &(surfacePool[i]))) { ADM_error("Cannot create input Surface %d\n",i); goto badInit; } aprintf("Created surface %d\n",(int)surfacePool[i]); } // allocate our (dummy) images for(int i=0;i<3;i++) xslots[i].image=new ADMImageDefault( previousFilter->getInfo()->width, previousFilter->getInfo()->height); if(VDP_STATUS_OK!=admVdpau::mixerCreate(previousFilter->getInfo()->width, previousFilter->getInfo()->height,&mixer,true)) { ADM_error("Cannot create mixer\n"); goto badInit; } tempBuffer=new uint8_t[info.width*info.height*4]; scaler=new ADMColorScalerSimple( info.width,info.height, ADM_COLOR_BGR32A,ADM_COLOR_YV12); freeSurface.clear(); for(int i=0;i<ADM_NB_SURFACES;i++) freeSurface.push_back(surfacePool[i]); ADM_info("VDPAU setup ok\n"); if(initGl()==false) { ADM_error("Cannot setup openGL\n"); goto badInit; } ADM_info("VDPAU setup ok\n"); return true; badInit: cleanupVdpau(); passThrough=true; return false; }
void loadTranslator(void) { char *lang=NULL; bool autoSelect=true; if(prefs->get(DEFAULT_LANGUAGE,&lang)) { if(lang && strlen(lang)>0 && strcmp(lang,"auto")) autoSelect=false; } if(autoSelect) { ADM_info("Using system language\n"); lang=ADM_strdup(QLocale::system().name().toUtf8().constData()); }else { ADM_info("Language forced \n"); } ADM_info("Initializing language %s\n",lang); #ifdef __APPLE__ QString appdir = QCoreApplication::applicationDirPath() + "/../share/avidemux6/i18n/"; #elif defined(_WIN32) QString appdir = QCoreApplication::applicationDirPath() + "/i18n/"; #else QString appdir = ADM_getInstallRelativePath("share","avidemux6","i18n"); #endif QString languageFile=QString(lang); int nbLoaded=0; nbLoaded+=loadTranslation(&qtTranslator, appdir + "qt_" + languageFile); nbLoaded+=loadTranslation(&avidemuxTranslator, appdir + "avidemux_" + languageFile); translatorLoaded = true; if(!nbLoaded) // Nothing to translate.. return; ADM_info("Updating translations...\n"); // Re-translate existing map (to take care of global strings already allocated) if(!map) map = new QMap<QString, char*>; QMapIterator<QString, char*> mapIterator(*map); while (mapIterator.hasNext()) { mapIterator.next(); QByteArray translatedMessage = QApplication::translate("", mapIterator.key().toAscii().constData()).toUtf8(); char *buffer = mapIterator.value(); int copyLength = translatedMessage.length() + 1; if (copyLength > MAX_UNLOADED_MSG_LENGTH + 1) { copyLength = MAX_UNLOADED_MSG_LENGTH; buffer[MAX_UNLOADED_MSG_LENGTH] = '\0'; } memcpy(buffer, translatedMessage.constData(), copyLength); } ADM_info("[Locale] Test: &Edit -> %s\n\n", HIDE_STRING_FROM_QT("MainWindow", "&Edit").toUtf8().data()); }
bool aviIndexOdml::writeIndex() { if(!riffCount) prepareLegacyIndex(); // super index needed ? ADM_info("Writting openDml chunk\n"); writeOdmlChunk(); ADM_info("Writting type 2 Avi index\n"); for(int i=0;i<1+nbAudioTrack;i++) writeRegularIndex(i); ADM_info("Writting type 2 Avi SuperIndex\n"); writeSuperIndex(); LMovie->End(); if(!riffCount) { ADM_info("Writting legacy index\n"); writeLegacyIndex(); } delete LMovie; LMovie=NULL; _masterList->End(); delete _masterList; _masterList=NULL; return true; }
/** * * @param avctx * @param fmt * @param outputFormat * @return */ bool ADM_hwAccelEntryLibVA::canSupportThis(struct AVCodecContext *avctx, const enum AVPixelFormat *fmt,enum AVPixelFormat &outputFormat) { bool enabled=false; prefs->get(FEATURES_LIBVA,&enabled); if(!enabled) { ADM_info("LibVA not enabled\n"); return false; } enum AVPixelFormat ofmt=ADM_LIBVA_getFormat(avctx,fmt); if(ofmt==AV_PIX_FMT_NONE) return false; outputFormat=ofmt; ADM_info("This is maybe supported by LIBVA\n"); VAProfile profile=VAProfileNone; switch(avctx->codec_id) { case AV_CODEC_ID_H264: profile= VAProfileH264High;break; #ifdef LIBVA_HEVC_DEC case AV_CODEC_ID_H265: profile= VAProfileHEVCMain;break;; #endif case AV_CODEC_ID_VC1: profile= VAProfileVC1Advanced;break; #ifdef LIBVA_VP9_DEC case AV_CODEC_ID_VP9: profile= VAProfileVP9Profile3;break; #endif default: return false; } if(!admLibVA::supported(profile)) { ADM_warning("Not supported by libVA\n"); return false; } return true; }
/** \fn removeChunk \brief */ bool ADM_EditorSegment::removeChunk(uint64_t from, uint64_t to) { uint32_t startSeg,endSeg; uint64_t startOffset,endOffset; ADM_info("Cutting from %"PRIu64" to %"PRIu64" ms\n",from/1000,to/1000); dump(); if(false==convertLinearTimeToSeg( from,&startSeg,&startOffset)) { ADM_warning("Cannot get starting point (%"PRIu64" ms\n",from/1000); return false; } if(false==convertLinearTimeToSeg( to,&endSeg,&endOffset)) { ADM_warning("Cannot get starting point (%"PRIu64" ms\n",from/1000); return false; } ADM_info("Start, seg %"PRIu32" Offset :%"PRIu64" ms\n",startSeg,startOffset); ADM_info("End , seg %"PRIu32" Offset :%"PRIu64" ms\n",endSeg,endOffset); ListOfSegments tmp=segments; if(startSeg==endSeg) { // Split the seg int two.. segments.insert(segments.begin()+startSeg+1,*getSegment(startSeg)); endSeg=startSeg+1; } _SEGMENT *first=getSegment(startSeg); // Span over several seg... // 1- shorten the start segment.. first->_durationUs=startOffset; // 3- Shorten last segment _SEGMENT *last=getSegment(endSeg); last->_refStartTimeUs+=endOffset; last->_durationUs-=endOffset; // 2- Kill the segment in between for(int i=startSeg+1;i<endSeg;i++) { segments.erase(segments.begin()+startSeg+1); } updateStartTime(); removeEmptySegments(); if(isEmpty()) { GUI_Error_HIG(QT_TRANSLATE_NOOP("adm","Error"),QT_TRANSLATE_NOOP("adm","You cannot remove *all* the video\n")); segments=tmp; updateStartTime(); return false; } undoSegments.push_back(tmp); dump(); return true; }
bool ADM_Composer::addAudioTrack(int poolIndex) { ADM_info("** Adding active track from pool **\n"); activeAudioTracks.addTrack(poolIndex,audioTrackPool.at(poolIndex)); ADM_info("Adding track %d\n",poolIndex); activeAudioTracks.dump(); return true; }
/** * \fn uncompress * \brief * @param in * @param out * @return */ bool decoderFFLIBVA::uncompress (ADMCompressedImage * in, ADMImage * out) { aprintf("==> uncompress %s\n",_context->codec->long_name); if(out->refType==ADM_HW_LIBVA) { ADM_vaSurface *img=(ADM_vaSurface *)out->refDescriptor.refHwImage; markSurfaceUnused(img); out->refType=ADM_HW_NONE; } if (!in->dataLength ) // Null frame, silently skipped { out->_noPicture = 1; out->Pts=ADM_COMPRESSED_NO_PTS; out->refType=ADM_HW_NONE; ADM_info("[LibVa] Nothing to decode -> no Picture\n"); return false; } // Put a safe value.... out->Pts=in->demuxerPts; _context->reordered_opaque=in->demuxerPts; int got_picture; AVPacket pkt; av_init_packet(&pkt); pkt.data=in->data; pkt.size=in->dataLength; if(in->flags&AVI_KEY_FRAME) pkt.flags=AV_PKT_FLAG_KEY; else pkt.flags=0; AVFrame *frame=_parent->getFramePointer(); ADM_assert(frame); int ret = avcodec_decode_video2 (_context, frame, &got_picture, &pkt); if(ret<0) { char er[2048]={0}; av_make_error_string(er, sizeof(er)-1, ret); ADM_warning("Error %d in lavcodec (%s)\n",ret,er); out->refType=ADM_HW_NONE; return false; } if(frame->pict_type==AV_PICTURE_TYPE_NONE) { out->_noPicture=true; out->refType=ADM_HW_NONE; out->Pts= (uint64_t)(frame->reordered_opaque); ADM_info("[LIBVA] No picture \n"); return false; } return readBackBuffer(frame,in,out); }
/** \fn setDtsFromPts \brief For mpeg4 SP/ASP, recompute PTS DTS using the simple I/P/B frame reordering Works also for mpeg1/2 It absolutely NEEDS to have the proper frame type set (PTS/DTS/...) */ bool setPtsFromDts(vidHeader *hdr,uint64_t timeIncrementUs,uint64_t *delay) { int last=0; int nbFrames; int nbBframe=0; int maxBframe=0; uint32_t flags; uint64_t pts,dts; ADM_info("computing pts...\n"); aviInfo info; hdr->getVideoInfo(&info); nbFrames=info.nb_frames; for(int i=1;i<nbFrames;i++) { hdr->getFlags(i,&flags); if(true!=hdr->getPtsDts(i,&pts,&dts)) { ADM_warning("Cannot get PTS/DTS\n"); return false; } if(flags & AVI_B_FRAME) nbBframe++; else { if(nbBframe>maxBframe) maxBframe=nbBframe; nbBframe=0; } } ADM_info("max bframe = %d\n",maxBframe); nbBframe=0; // We have now maxBframe = max number of Bframes in sequence for(int i=1;i<nbFrames;i++) { hdr->getFlags(i,&flags); hdr->getPtsDts(i,&pts,&dts); if(flags & AVI_B_FRAME) { pts=dts; hdr->setPtsDts(i,pts,dts); nbBframe++; } else { uint64_t oldPts,oldDts; uint64_t fwdPts,fwdDts; hdr->getPtsDts(last,&oldPts,&oldDts); hdr->getPtsDts(i,&fwdPts,&fwdDts); oldPts=fwdDts; hdr->setPtsDts(last,oldPts,oldDts); last=i; } } return 1; }
/** \fn encode \brief Get an encoded dca packet @param dest [in] Where to write datas @param len [out] Length of encoded datas in bytes @param samples [out] Number of samples @return true on success, false on error */ bool AUDMEncoder_DcaEnc::encode(uint8_t *dest, uint32_t *len, uint32_t *samples) { int32_t nbout; int neededSamples=inputSize*wavheader.channels; *samples = inputSize; //FIXME *len = 0; if(AudioEncoderStopped==_state) return false; refillBuffer (neededSamples); if(AudioEncoderNoInput==_state) { int left=tmptail-tmphead; if (left < neededSamples) { if(left) { nbout=send(left,dest); tmphead=tmptail; ADM_info("[dcaenc]Sending last packet\n"); goto cont; } // Flush _state=AudioEncoderStopped; // flush pad with 0n todo if(nbout<0) { ADM_warning("Error while flushing dcaenc\n"); return false; } *len=nbout; *samples=inputSize; ADM_info("[dcaenc] Flushing, last block is %d bytes\n",nbout); return true; } } nbout=send(neededSamples,dest); tmphead += neededSamples; cont: if (nbout < 0) { printf ("[dcaenc] Error !!! : %"PRIi32"\n", nbout); return false; } *len = nbout; if (!*len) *samples =0; else *samples=inputSize; return true; }
/** \fn encode \brief Get an encoded mp3 packet @param dest [in] Where to write datas @param len [out] Length of encoded datas in bytes @param samples [out] Number of samples @return true on success, false on error */ bool AUDMEncoder_Lame::encode(uint8_t *dest, uint32_t *len, uint32_t *samples) { int32_t nbout; *samples = BLOCK_SIZE; //FIXME *len = 0; if(AudioEncoderStopped==_state) return false; refillBuffer (_chunk); if(AudioEncoderNoInput==_state) { int left=tmptail-tmphead; if (left < _chunk) { if(left) { nbout=send(left,dest); tmphead=tmptail; ADM_info("[lame]Sending last packet\n"); goto cont; } // Flush _state=AudioEncoderStopped; nbout=lame_encode_flush(MYFLAGS,dest,16*1024); if(nbout<0) { ADM_warning("Error while flushing lame\n"); return false; } *len=nbout; *samples=BLOCK_SIZE; ADM_info("[Lame] Flushing, last block is %d bytes\n",nbout); return true; } } nbout=send(_chunk,dest); tmphead += _chunk; cont: if (nbout < 0) { printf ("[Lame] Error !!! : %"PRIi32"\n", nbout); return false; } *len = nbout; if (!*len) *samples = 0; else *samples=BLOCK_SIZE; return true; }
/** \fn setup */ bool ADM_ffVAEncHEVC::setup(void) { if(false== ADM_coreVideoEncoderFFmpeg::setupByName("hevc_vaapi")) { ADM_info("[ffMpeg] Setup failed\n"); return false; } ADM_info("[ffMpeg] Setup ok\n"); return true; }
/** \fn dxvaRender */ dxvaRender::~dxvaRender() { if(videoWidget) { videoWidget->useExternalRedraw(false); // reactivate Qt double buffering videoWidget->setDrawer(NULL); videoWidget=NULL; } ADM_info("dxva2/D3D clean up\n"); cleanup(); ADM_info("dxva2/D3D cleaned up\n"); }
bool spawnProcess(const char *processName, int argc, const string argv[]) { ADM_info("Starting <%s>\n",processName); string command=string(processName); for(int i=0;i<argc;i++) { ADM_info("%d : %s\n",i,argv[i].c_str()); command+=string(" ")+argv[i]; } ADM_info("=>%s\n",command.c_str()); ADM_info("==================== Start of spawner process job ================\n"); #ifdef _WIN32 STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); // utf8 -> utf16 const char *c=command.c_str(); int size=utf8StringToWideChar(c,strlen(c),NULL); wchar_t* w = new wchar_t[size+1]; utf8StringToWideChar(c,strlen(c),w); // Start the child process. if( !CreateProcessW( NULL, // No module name (use command line) w, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { delete [] w; ADM_error("Cannot spawn process! (%s)\n",c); return false; } delete [] w; #else system(command.c_str()); #endif ADM_info("==================== End of spawner process job ================\n"); return true; }
/** * * @param avctx * @return */ static bool probeCuda() { ADM_info( "Probing cuda\n"); if(!loadCuda()) { ADM_warning("Cannot load cuda\n"); return false; } ADM_warning("Cuda loaded, probing..\n"); if(!cudaCall(init(0))) return false; int deviceCount=0; if(!cudaCall(getDeviceCount(&deviceCount))) return false; if (!deviceCount) { ADM_warning( "No Cuda device available\n"); return false; } ADM_info( "found %d CUDA devices \n", deviceCount); for (int i = 0; i < deviceCount; ++i) { CUdevice dev; char chipName[128]; int major,minor,ver; cudaAbortOnFail(getDevice(&dev,i)); cudaAbortOnFail(getDeviceName(chipName,sizeof(chipName),dev)); cudaAbortOnFail(getDeviceCapabilities(&major,&minor,dev)); ver = (major << 4) | minor; ADM_info("Found chip, GPU %s, SM %d.d",chipName,major,minor); if(ver>=0x30) { ADM_info(" this chip has nvenc"); if(!nvEncAvailable) { nvEncAvailable=true; selectedDevice=dev; } } } return nvEncAvailable; abortCudaProbe: return false; }
/** \fn stop */ bool sdlRenderImpl::stop( void) { ADM_info("[SDL] Stopping\n"); cleanup(); if(sdl_running) { ADM_info("[SDL] Video subsystem closed\n"); SDL_QuitSubSystem(SDL_INIT_VIDEO); sdl_running=0; } return true; }
static int loadTranslation(QTranslator *qTranslator, QString translation) { ADM_info("[Locale] Loading language file %s ", translation.toUtf8().constData()); if (qTranslator->load(translation)) { QApplication::installTranslator(qTranslator); ADM_info("succeeded\n"); return 1; } ADM_warning("FAILED\n"); return 0; }
/** \fn listOfPsAudioTracks \brief returns a list of audio track found, null if none found */ listOfPsAudioTracks *psProbeAudio(const char *fileName) { uint32_t size; uint64_t dts,pts,startAt; uint8_t buffer[PACKET_PROBE_SIZE]; uint64_t fileSize; listOfPsAudioTracks *tracks=new listOfPsAudioTracks; psPacketLinearTracker *packet=new psPacketLinearTracker(0xE0); printf("[MpegPS] Probing audio for %s\n",fileName); if(!packet->open(fileName,FP_APPEND)) goto end; fileSize=packet->getSize(); packet->setPos(fileSize/2); // Jump in the middle of the stream while(packet->getPacketOfType(0xE0,PACKET_PROBE_SIZE,&size,&dts,&pts,buffer,&startAt)) { packetStats *stat=packet->getStat(0xE0); if(stat->count > PROBE_PACKET_VIDEO_COUNT) break; } // Now synthetize for(int i=0x0;i<0xFF;i++) { packetStats *stat=packet->getStat(i); if(stat->count) { ADM_info("[PsProbeAudo] Pid:%x count:%" PRIx32" size:%" PRIi32"\n",i,stat->count,stat->size); if(stat->count>=PROBE_MIN_PACKET && stat->size>PROBE_MIN_SIZE) { packet->setPos(fileSize/2); addAudioTrack(i,tracks,packet); }else ADM_info("[PsProbeAudo] Not enough samples\n"); } } end: ADM_info("[PsDemux] Audio probe done, found %d tracks\n",(int)tracks->size()); delete packet; if(tracks->size()==0) { delete tracks; return NULL; } return tracks; }