/** \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; }
/** * \fn copyToClipBoard * \Brief copy the section between startTime and endTime to clipboard * @param startTime * @param endTime * @return */ bool ADM_EditorSegment::copyToClipBoard(uint64_t startTime, uint64_t endTime) { ADM_info("Copy to clipboard from %s",ADM_us2plain(startTime)); ADM_info("to %s\n",ADM_us2plain(endTime)); uint32_t startSeg,endSeg; uint64_t startSegTime,endSegTime; convertLinearTimeToSeg( startTime, &startSeg,&startSegTime); convertLinearTimeToSeg( endTime, &endSeg,&endSegTime); dump(); clipboard.clear(); for(int seg=startSeg;seg<=endSeg;seg++) { _SEGMENT s=segments[seg]; aprintf("Adding segment %d to clipboard\n",seg); if(s._startTimeUs<=startTime && (s._startTimeUs+s._durationUs)>startTime) { // need to refine 1st seg uint64_t offset=startTime-s._startTimeUs; s._refStartTimeUs+=offset; s._durationUs-=offset; // take into account the part we chopped aprintf("Marker A is here offset=%d\n",(int)offset); } if(s._startTimeUs<=endTime && (s._startTimeUs+s._durationUs)>endTime) { // need to refine last seg uint64_t offset=endTime-s._startTimeUs; s._durationUs=offset; aprintf("Marker B is here offset=%d\n",(int)offset); } // TODO refine timing for 1st/last/duration/... clipboard.push_back(s); } dumpClipBoard(); return false; }
/** * \fn pasteFromClipBoard * \brief instert clipboard at currentTime position * @param currentTime * @return */ bool ADM_EditorSegment::pasteFromClipBoard(uint64_t currentTime) { if(clipboardEmpty()) { ADM_info("The clipboard is empty, nothing to do\n"); return true; } ADM_info("Pasting from clipboard to %s\n",ADM_us2plain(currentTime)); uint32_t startSeg; uint64_t startSegTime; convertLinearTimeToSeg( currentTime, &startSeg,&startSegTime); ListOfSegments tmp=segments; ListOfSegments newSegs; int n=segments.size(); for(int i=0;i<n;i++) { _SEGMENT s=segments[i]; if(i==startSeg) { // insert clipboard // Do we need to split it ? if(currentTime==s._startTimeUs) { // nope for(int j=0;j<clipboard.size();j++) newSegs.push_back(clipboard[j]); }else { _SEGMENT pre=s,post=s; uint64_t offset=currentTime-s._startTimeUs; pre._durationUs=offset; post._refStartTimeUs+=offset; post._durationUs-=offset; newSegs.push_back(pre); for(int j=0;j<clipboard.size();j++) newSegs.push_back(clipboard[j]); newSegs.push_back(post); continue; } } newSegs.push_back(s); } segments=newSegs; // If a video doesn't start at zero and we paste to its first frame, // we end up with an empty segment at the beginning. Remove it. removeEmptySegments(); updateStartTime(); dump(); return true; }
/** \fn getRefFromTime \brief Return the ref video where xtime is */ bool ADM_EditorSegment::getRefFromTime(uint64_t xtime,uint32_t *refVideo) { // What segments does it belong to ? uint32_t seg; uint64_t segTime; if(false== convertLinearTimeToSeg( xtime, &seg, &segTime)) { ADM_warning("Cannot identify segment for time %"PRIu64" ms\n",xtime/1000); return false; } _SEGMENT *s=getSegment(seg); ADM_assert(s); *refVideo=s->_reference; return true; }
/** * \fn pasteFromClipBoard * \brief instert clipboard at currentTime position * @param currentTime * @return */ bool ADM_EditorSegment::pasteFromClipBoard(uint64_t currentTime) { ADM_info("Pasting from clipboard to %s\n",ADM_us2plain(currentTime)); uint32_t startSeg; uint64_t startSegTime; convertLinearTimeToSeg( currentTime, &startSeg,&startSegTime); ListOfSegments newSegs; int n=segments.size(); for(int i=0;i<n;i++) { _SEGMENT s=segments[i]; if(i==startSeg) { // insert clipboard // Do we need to split it ? if(currentTime==s._startTimeUs) { // nope for(int j=0;j<clipboard.size();j++) newSegs.push_back(clipboard[j]); }else { _SEGMENT pre=s,post=s; uint64_t offset=currentTime-s._startTimeUs; pre._durationUs=offset; post._refStartTimeUs+=offset; post._durationUs-=offset; newSegs.push_back(pre); for(int j=0;j<clipboard.size();j++) newSegs.push_back(clipboard[j]); newSegs.push_back(post); continue; } } newSegs.push_back(s); } segments=newSegs; updateStartTime(); return true; }
/** \fn truncateVideo \brief Remove a part of the video from the given time to the end */ bool ADM_EditorSegment::truncateVideo(uint64_t from) { uint32_t startSeg; uint64_t startOffset; ADM_info("Truncating from %" PRIu64" ms\n",from/1000); dump(); if(false==convertLinearTimeToSeg(from,&startSeg,&startOffset)) { ADM_warning("Cannot get starting point for linear time %" PRIu64" ms\n",from/1000); return false; } ADM_info("Start in segment %" PRIu32" at offset :%" PRIu64" ms\n",startSeg,startOffset); ListOfSegments tmp=segments; _SEGMENT *first=getSegment(startSeg); _VIDEOS *vid=getRefVideo(first->_reference); uint64_t padding=vid->timeIncrementInUs/2; // shorten the start segment first->_durationUs=startOffset+padding; // remove following segments int n=segments.size(); for(int i=startSeg+1;i<n;i++) { segments.erase(segments.begin()+startSeg+1); } removeEmptySegments(); updateStartTime(); 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; } dump(); return true; }