/** \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 seektoFrame \brief Seek to frame with timestamp given as arg */ bool ADM_Composer::seektoTime(uint32_t ref,uint64_t timeToSeek,bool dontdecode) { _VIDEOS *vid=_segments.getRefVideo(ref); vidHeader *demuxer=vid->_aviheader; EditorCache *cache =vid->_videoCache; ADM_assert(cache); bool found=false; // Search the previous keyframe for segment.... uint64_t seekTime; if(_segments.isKeyFrameByTime(ref,timeToSeek)) { seekTime=timeToSeek; ADM_info("First frame of the new segment is a keyframe at %"PRIu32"ms\n",seekTime/1000); found=true; }else { if(false==searchPreviousKeyFrameInRef(ref,timeToSeek,&seekTime)) { ADM_warning("Cannot identify the keyframe before %"PRIu64" ms\n",seekTime/1000); return false; } } uint32_t frame=_segments.intraTimeToFrame(ref,seekTime); if(dontdecode==true) { vid->lastSentFrame=frame; ADM_info("Seek to time without decoding ok\n"); return true; } // ok now seek... if(false==DecodePictureUpToIntra(ref,frame)) { ADM_warning("Cannot decode up to intra %"PRIu64" at %"PRIu64" ms\n",frame,seekTime/1000); return false; } if(found==true) return true; // Now forward... while(nextPictureInternal(ref,NULL)==true) { uint64_t pts=vid->lastDecodedPts; if(pts==ADM_NO_PTS) { ADM_warning("No PTS out of decoder\n"); continue; } vid->lastReadPts=pts; if(pts==timeToSeek) { ADM_info("Image found, pts=%"PRIu64" ms\n",pts/1000); return true; } if(pts>timeToSeek) { ADM_info("Image not found,searching %"PRIu64" ms, got pts=%"PRIu64" ms\n",timeToSeek/1000,pts/1000); return false; } } ADM_warning("seekToFrame failed for frame at PTS= %"PRIu64" ms, next image failed\n",timeToSeek/1000); return false; }