예제 #1
0
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;
}
예제 #3
0
Path MediaConvert::getOutputFilePath(){
	return Path(destination.getPath(), (fileName + "." + getContainerName()));
}