- int clipIndex = trackPlaylist.get_clip_index_at((int) info.startPos.frames(m_fps));
- Mlt::Producer clip(trackPlaylist.get_clip(clipIndex));
- QString serv = clip.parent().get("mlt_service");
- QString id = clip.parent().get("id");
- kDebug() << "CLIP SERVICE: " << clip.parent().get("mlt_service");
- if (serv == "avformat" && speed != 1.0) {
- mlt_service_lock(service.get_service());
- QString url = clip.parent().get("resource");
- url.append("?" + QString::number(speed));
- Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
- if (!slowprod || slowprod->get_producer() == NULL) {
- char *tmp = decodedString(url);
- slowprod = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp);
- delete[] tmp;
- QString producerid = "slowmotion:" + id + ":" + QString::number(speed);
- tmp = decodedString(producerid);
- slowprod->set("id", tmp);
- delete[] tmp;
- m_slowmotionProducers.insert(url, slowprod);
- }
- Mlt::Producer *cut = slowprod->cut(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps) - 1);
- newLength = cut->get_length();
- trackPlaylist.replace_with_blank(clipIndex);
- trackPlaylist.consolidate_blanks(0);
- trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *cut, 1);
- mlt_service_unlock(service.get_service());
- } else if (speed == 1.0) {
- mlt_service_lock(service.get_service());
- Mlt::Producer *cut = prod->cut(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps) - 1);
- trackPlaylist.replace_with_blank(clipIndex);
- newLength = cut->get_length();
- trackPlaylist.consolidate_blanks(0);
- trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *cut, 1);
- mlt_service_unlock(service.get_service());
- } else if (serv == "framebuffer") {
- mlt_service_lock(service.get_service());
- QString url = clip.parent().get("resource");
- url = url.section("?", 0, 0);
- url.append("?" + QString::number(speed));
- Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
+ int clipIndex = trackPlaylist.get_clip_index_at(insertPos);
+ if (!trackPlaylist.is_blank(clipIndex)) return -1;
+ if (fromBlankStart) return trackPlaylist.clip_length(clipIndex);
+ return trackPlaylist.clip_length(clipIndex) + trackPlaylist.clip_start(clipIndex) - insertPos;
+}
+
+
+void Render::mltInsertSpace(QMap <int, int> trackClipStartList, QMap <int, int> trackTransitionStartList, int track, const GenTime duration, const GenTime timeOffset) {
+ if (!m_mltProducer) {
+ kDebug() << "PLAYLIST NOT INITIALISED //////";
+ return;
+ }
+ Mlt::Producer parentProd(m_mltProducer->parent());
+ if (parentProd.get_producer() == NULL) {
+ kDebug() << "PLAYLIST BROKEN, CANNOT INSERT CLIP //////";
+ return;
+ }
+ //kDebug()<<"// CLP STRT LST: "<<trackClipStartList;
+ //kDebug()<<"// TRA STRT LST: "<<trackTransitionStartList;
+
+ Mlt::Service service(parentProd.get_service());
+ Mlt::Tractor tractor(service);
+ mlt_service_lock(service.get_service());
+ int diff = duration.frames(m_fps);
+ int offset = timeOffset.frames(m_fps);
+ int insertPos;
+
+ if (track != -1) {
+ // insert space in one track only
+ Mlt::Producer trackProducer(tractor.track(track));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+ insertPos = trackClipStartList.value(track);
+ if (insertPos != -1) {
+ insertPos += offset;
+ int clipIndex = trackPlaylist.get_clip_index_at(insertPos);
+ if (diff > 0) trackPlaylist.insert_blank(clipIndex, diff - 1);
+ else {
+ if (!trackPlaylist.is_blank(clipIndex)) clipIndex --;
+ if (!trackPlaylist.is_blank(clipIndex)) kDebug() << "//// ERROR TRYING TO DELETE SPACE FROM " << insertPos;
+ int position = trackPlaylist.clip_start(clipIndex);
+ trackPlaylist.remove_region(position, - diff - 1);
+ }
+ trackPlaylist.consolidate_blanks(0);
+ }
+ // now move transitions
+ mlt_service serv = m_mltProducer->parent().get_service();
+ mlt_service nextservice = mlt_service_get_producer(serv);
+ mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
+ QString mlt_type = mlt_properties_get(properties, "mlt_type");
+ QString resource = mlt_properties_get(properties, "mlt_service");
+
+ while (mlt_type == "transition") {
+ mlt_transition tr = (mlt_transition) nextservice;
+ int currentTrack = mlt_transition_get_b_track(tr);
+ int currentIn = (int) mlt_transition_get_in(tr);
+ int currentOut = (int) mlt_transition_get_out(tr);
+ insertPos = trackTransitionStartList.value(track);
+ if (insertPos != -1) {
+ insertPos += offset;
+ if (track == currentTrack && currentOut > insertPos && resource != "mix") {
+ mlt_transition_set_in_and_out(tr, currentIn + diff, currentOut + diff);
+ }
+ }
+ nextservice = mlt_service_producer(nextservice);
+ if (nextservice == NULL) break;
+ properties = MLT_SERVICE_PROPERTIES(nextservice);
+ mlt_type = mlt_properties_get(properties, "mlt_type");
+ resource = mlt_properties_get(properties, "mlt_service");
+ }
+ } else {
+ int trackNb = tractor.count();
+ while (trackNb > 1) {
+ Mlt::Producer trackProducer(tractor.track(trackNb - 1));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+
+
+ int clipNb = trackPlaylist.count();
+ insertPos = trackClipStartList.value(trackNb - 1);
+ if (insertPos != -1) {
+ insertPos += offset;
+
+ /* kDebug()<<"-------------\nTRACK "<<trackNb<<" HAS "<<clipNb<<" CLPIS";
+ kDebug() << "INSERT SPACE AT: "<<insertPos<<", DIFF: "<<diff<<", TK: "<<trackNb;
+ for (int i = 0; i < clipNb; i++) {
+ kDebug()<<"CLIP "<<i<<", START: "<<trackPlaylist.clip_start(i)<<", END: "<<trackPlaylist.clip_start(i) + trackPlaylist.clip_length(i);
+ if (trackPlaylist.is_blank(i)) kDebug()<<"++ BLANK ++ ";
+ kDebug()<<"-------------";
+ }
+ kDebug()<<"END-------------";*/
+
+
+ int clipIndex = trackPlaylist.get_clip_index_at(insertPos);
+ if (diff > 0) trackPlaylist.insert_blank(clipIndex, diff - 1);
+ else {
+ if (!trackPlaylist.is_blank(clipIndex)) clipIndex --;
+ if (!trackPlaylist.is_blank(clipIndex)) kDebug() << "//// ERROR TRYING TO DELETE SPACE FROM " << insertPos;
+ int position = trackPlaylist.clip_start(clipIndex);
+ trackPlaylist.remove_region(position, - diff - 1);
+ }
+ trackPlaylist.consolidate_blanks(0);
+ }
+ trackNb--;
+ }
+ // now move transitions
+ mlt_service serv = m_mltProducer->parent().get_service();
+ mlt_service nextservice = mlt_service_get_producer(serv);
+ mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
+ QString mlt_type = mlt_properties_get(properties, "mlt_type");
+ QString resource = mlt_properties_get(properties, "mlt_service");
+
+ while (mlt_type == "transition") {
+ mlt_transition tr = (mlt_transition) nextservice;
+ int currentIn = (int) mlt_transition_get_in(tr);
+ int currentOut = (int) mlt_transition_get_out(tr);
+ int currentTrack = mlt_transition_get_b_track(tr);
+ insertPos = trackTransitionStartList.value(currentTrack);
+ if (insertPos != -1) {
+ insertPos += offset;
+ if (currentOut > insertPos && resource != "mix") {
+ mlt_transition_set_in_and_out(tr, currentIn + diff, currentOut + diff);
+ }
+ }
+ nextservice = mlt_service_producer(nextservice);
+ if (nextservice == NULL) break;
+ properties = MLT_SERVICE_PROPERTIES(nextservice);
+ mlt_type = mlt_properties_get(properties, "mlt_type");
+ resource = mlt_properties_get(properties, "mlt_service");
+ }
+ }
+ mlt_service_unlock(service.get_service());
+ mltCheckLength();
+ m_mltConsumer->set("refresh", 1);
+}
+
+int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod) {
+ m_isBlocked = true;
+ int newLength = 0;
+ Mlt::Service service(m_mltProducer->parent().get_service());
+ if (service.type() != tractor_type) kWarning() << "// TRACTOR PROBLEM";
+ kDebug() << "Changing clip speed, set in and out: " << info.cropStart.frames(m_fps) << " to " << (info.endPos - info.startPos).frames(m_fps) - 1;
+ Mlt::Tractor tractor(service);
+ Mlt::Producer trackProducer(tractor.track(info.track));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+ int startPos = info.startPos.frames(m_fps);
+ int clipIndex = trackPlaylist.get_clip_index_at(startPos);
+ int clipLength = trackPlaylist.clip_length(clipIndex);
+
+ Mlt::Producer clip(trackPlaylist.get_clip(clipIndex));
+ QString serv = clip.parent().get("mlt_service");
+ QString id = clip.parent().get("id");
+ kDebug() << "CLIP SERVICE: " << clip.parent().get("mlt_service");
+ if (serv == "avformat" && speed != 1.0) {
+ mlt_service_lock(service.get_service());
+ QString url = clip.parent().get("resource");
+ url.append("?" + QString::number(speed));
+ Mlt::Producer *slowprod = m_slowmotionProducers.value(url);
+ if (!slowprod || slowprod->get_producer() == NULL) {
+ char *tmp = decodedString(url);
+ slowprod = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp);
+ delete[] tmp;
+ QString producerid = "slowmotion:" + id + ":" + QString::number(speed);
+ tmp = decodedString(producerid);
+ slowprod->set("id", tmp);
+ delete[] tmp;
+ m_slowmotionProducers.insert(url, slowprod);
+ }
+ trackPlaylist.replace_with_blank(clipIndex);
+ trackPlaylist.consolidate_blanks(0);
+ // Check that the blank space is long enough for our new duration
+ clipIndex = trackPlaylist.get_clip_index_at(startPos);
+ int blankEnd = trackPlaylist.clip_start(clipIndex) + trackPlaylist.clip_length(clipIndex);
+ Mlt::Producer *cut;
+ if (clipIndex + 1 < trackPlaylist.count() && (startPos + clipLength / speed > blankEnd)) {
+ GenTime maxLength = GenTime(blankEnd, m_fps) - info.startPos;
+ cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)(info.cropStart.frames(m_fps) / speed + maxLength.frames(m_fps) - 1));
+ } else cut = slowprod->cut((int)(info.cropStart.frames(m_fps) / speed), (int)((info.cropStart.frames(m_fps) + clipLength) / speed - 1));
+ trackPlaylist.insert_at(startPos, *cut, 1);
+ clipIndex = trackPlaylist.get_clip_index_at(startPos);
+ newLength = trackPlaylist.clip_length(clipIndex);
+ mlt_service_unlock(service.get_service());
+ } else if (speed == 1.0) {
+ mlt_service_lock(service.get_service());
+
+ trackPlaylist.replace_with_blank(clipIndex);
+ trackPlaylist.consolidate_blanks(0);
+
+ // Check that the blank space is long enough for our new duration
+ clipIndex = trackPlaylist.get_clip_index_at(startPos);
+ int blankEnd = trackPlaylist.clip_start(clipIndex) + trackPlaylist.clip_length(clipIndex);
+
+ Mlt::Producer *cut;
+ GenTime oldDuration = GenTime(clipLength, m_fps);
+ GenTime newDuration = oldDuration * oldspeed;
+ if (clipIndex + 1 < trackPlaylist.count() && (info.startPos + newDuration).frames(m_fps) > blankEnd) {
+ GenTime maxLength = GenTime(blankEnd, m_fps) - info.startPos;
+ cut = prod->cut((int)(info.cropStart.frames(m_fps)), (int)(info.cropStart.frames(m_fps) + maxLength.frames(m_fps) - 1));
+ } else cut = prod->cut((int)(info.cropStart.frames(m_fps)), (int)((info.cropStart + newDuration).frames(m_fps)) - 1);
+ trackPlaylist.insert_at(startPos, *cut, 1);
+ clipIndex = trackPlaylist.get_clip_index_at(startPos);
+ newLength = trackPlaylist.clip_length(clipIndex);
+ mlt_service_unlock(service.get_service());
+
+ } else if (serv == "framebuffer") {
+ mlt_service_lock(service.get_service());
+ QString url = clip.parent().get("resource");
+ url = url.section("?", 0, 0);
+ url.append("?" + QString::number(speed));
+ Mlt::Producer *slowprod = m_slowmotionProducers.value(url);