/**
    \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;
}
Beispiel #2
0
void TimeSpinBox::reportChange() {
    kDebug() << i18n( "Reporting new timestep value: " ) << timeScale();
    emit scaleChanged( timeScale() );
}