QString FileInfo::getDebugInfo() const { const QString str = "\n\tContainer: " + getContainerPath() + "\n\tPath: " + getPath() + "\n\tImageFileName: " + getImageFileName() + "\n\tZipPath: " + getArchiveContainerPath() + "\n\tIsInArchive: " + (isInArchive() ? "true" : "false") + "\n\tContainer Name: " + getContainerName(); return str; }
/** \fn saveLoop */ bool muxerFFmpeg::saveLoop(const char *title) { printf("[FF] Saving\n"); uint32_t bufSize=vStream->getWidth()*vStream->getHeight()*3; uint8_t *buffer=new uint8_t[bufSize]; uint64_t rawDts; uint64_t lastVideoDts=0; uint64_t videoIncrement; int ret; int written=0; bool result=true; int missingPts=0; float f=(float)vStream->getAvgFps1000(); f=1000./f; f*=1000000; videoIncrement=(uint64_t)f; ADM_info("avg fps=%u\n",vStream->getAvgFps1000()); uint64_t videoDuration=vStream->getVideoDuration(); initUI(QT_TRANSLATE_NOOP("adm","Saving")); encoding->setContainer(getContainerName()); MuxAudioPacket *audioPackets=new MuxAudioPacket[nbAStreams]; ADMBitstream out(bufSize); out.data=buffer; while(true==vStream->getPacket(&out)) { AVPacket pkt; encoding->refresh(); if(!encoding->isAlive()) { result=false; break; } int64_t xpts=(int64_t)out.pts; int64_t xdts=(int64_t)out.dts; if(out.pts==ADM_NO_PTS) xpts=-1; if(out.dts==ADM_NO_PTS) xdts=-1; aprintf("[FF:V] Pts: %"PRId64" DTS:%"PRId64" ms\n",xpts/1000,xdts/1000); aprintf("[FF:V] LastDts:%08"PRIu64" Dts:%08"PRIu64" (%04"PRIu64") Delta : %"PRIu64"\n", lastVideoDts,out.dts,out.dts/1000000,out.dts-lastVideoDts); rawDts=out.dts; if(rawDts==ADM_NO_PTS) { lastVideoDts+=videoIncrement; }else { lastVideoDts=out.dts; } if(out.pts==ADM_NO_PTS) { ADM_warning("No PTS information for frame %"PRIu32"\n",written); missingPts++; out.pts=lastVideoDts; } encoding->pushVideoFrame(out.len,out.out_quantizer,lastVideoDts); muxerRescaleVideoTimeDts(&(out.dts),lastVideoDts); muxerRescaleVideoTime(&(out.pts)); aprintf("[FF:V] RawDts:%lu Scaled Dts:%lu\n",rawDts,out.dts); aprintf("[FF:V] Rescaled: Len : %d flags:%x Pts:%"PRIu64" Dts:%"PRIu64"\n",out.len,out.flags,out.pts,out.dts); av_init_packet(&pkt); pkt.dts=out.dts; if(vStream->providePts()==true) { pkt.pts=out.pts; }else { pkt.pts=pkt.dts; } pkt.stream_index=0; pkt.data= buffer; pkt.size= out.len; if(out.flags & 0x10) // FIXME AVI_KEY_FRAME pkt.flags |= AV_PKT_FLAG_KEY; ret =writePacket( &pkt); aprintf("[FF]Frame:%u, DTS=%08lu PTS=%08lu\n",written,out.dts,out.pts); if(false==ret) { printf("[FF]Error writing video packet\n"); break; } written++; // Now send audio until they all have DTS > lastVideoDts+increment for(int audio=0;audio<nbAStreams;audio++) { MuxAudioPacket *audioTrack=&(audioPackets[audio]); ADM_audioStream*a=aStreams[audio]; uint32_t fq=a->getInfo()->frequency; while(1) { if(audioTrack->eof==true) break; // no more packet for this track if(audioTrack->present==false) { if(false==a->getPacket(audioTrack->buffer, &(audioTrack->size), AUDIO_BUFFER_SIZE, &(audioTrack->samples), &(audioTrack->dts))) { audioTrack->eof=true; ADM_info("No more audio packets for audio track %d\n",audio); break; } // printf("Track %d , new audio packet DTS=%"PRId64" size=%"PRIu32"\n",audioTrack->dts,audioTrack->size); audioTrack->present=true; // Delay audio by the delay induce by encoder if(audioTrack->dts!=ADM_NO_PTS) audioTrack->dts+=audioDelay; } if(audioTrack->dts!=ADM_NO_PTS) { //printf("Audio PTS:%"PRId64", limit=%"PRId64"\n",audioTrack->dts,lastVideoDts+videoIncrement); if(audioTrack->dts>lastVideoDts+videoIncrement) break; // This packet is in the future } // Write... AVPacket pkt; uint64_t rescaledDts; rescaledDts=audioTrack->dts; encoding->pushAudioFrame(audioTrack->size); muxerRescaleAudioTime(audio,&rescaledDts,a->getInfo()->frequency); //printf("[FF] A: Video frame %d, audio Dts :%"PRIu64" size :%"PRIu32" nbSample : %"PRIu32" rescaled:%"PRIu64"\n", // written,audioTrack->dts,audioTrack->size,audioTrack->samples,rescaledDts); av_init_packet(&pkt); pkt.dts=rescaledDts; pkt.pts=rescaledDts; pkt.stream_index=1+audio; pkt.data= audioTrack->buffer; pkt.size= audioTrack->size; pkt.flags |= AV_PKT_FLAG_KEY; // Assume all audio are keyframe, which is slightly wrong ret =writePacket( &pkt); audioTrack->present=false; // consumed if(false==ret) { ADM_warning("[FF]Error writing audio packet\n"); break; } // printf("[FF] A:%"PRIu32" ms vs V: %"PRIu32" ms\n",(uint32_t)audioTrack->dts/1000,(uint32_t)(lastVideoDts+videoIncrement)/1000); } //if(!nb) printf("[FF] A: No audio for video frame %d\n",written); } } delete [] buffer; if((videoDuration *4)/5 > lastVideoDts) { GUI_Error_HIG("Too short","The video has been saved but seems to be incomplete."); result=false; } ADM_info("[FF] Wrote %d frames, nb audio streams %d\n",written,nbAStreams); ADM_info("[FF] Found %d missing PTS / %d total frames\n",missingPts,written); delete [] audioPackets; audioPackets=NULL; return result; }
Path MediaConvert::getOutputFilePath(){ return Path(destination.getPath(), (fileName + "." + getContainerName())); }