diff --git a/io/media.cpp b/io/media.cpp index 04c1bb2fe..3ca621a85 100644 --- a/io/media.cpp +++ b/io/media.cpp @@ -25,6 +25,20 @@ long Media::get_length_in_frames(float frame_rate) { return ceil((float) length / (float) AV_TIME_BASE * frame_rate); } +MediaStream* Media::get_stream_from_file_index(int index) { + for (int i=0;ifile_index == index) { + return video_tracks.at(i); + } + } + for (int i=0;ifile_index == index) { + return audio_tracks.at(i); + } + } + return NULL; +} + int guess_layout_from_channels(int channel_count) { if (channel_count == 1) { return AV_CH_LAYOUT_MONO; diff --git a/io/media.h b/io/media.h index 3d6b2caf4..929bdee6b 100644 --- a/io/media.h +++ b/io/media.h @@ -38,6 +38,7 @@ struct Media Sequence* sequence; int save_id; long get_length_in_frames(float frame_rate); + MediaStream* get_stream_from_file_index(int index); }; int guess_layout_from_channels(int channel_count); diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index dae02d0dd..333e952d4 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -23,20 +23,6 @@ PreviewGenerator::PreviewGenerator(QObject* parent) : QThread(parent) { fmt_ctx = NULL; } -MediaStream* PreviewGenerator::get_stream_from_file_index(int index) { - for (int i=0;ivideo_tracks.size();i++) { - if (media->video_tracks.at(i)->file_index == index) { - return media->video_tracks.at(i); - } - } - for (int i=0;iaudio_tracks.size();i++) { - if (media->audio_tracks.at(i)->file_index == index) { - return media->audio_tracks.at(i); - } - } - return NULL; -} - #define WAVEFORM_RESOLUTION 64 void PreviewGenerator::run() { @@ -82,7 +68,7 @@ void PreviewGenerator::run() { } } if (!end_of_file) { - MediaStream* s = get_stream_from_file_index(packet.stream_index); + MediaStream* s = media->get_stream_from_file_index(packet.stream_index); if (s != NULL && !s->preview_done) { if (fmt_ctx->streams[packet.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { int dstH = 120; diff --git a/io/previewgenerator.h b/io/previewgenerator.h index 7d7d23717..35ffc3b5d 100644 --- a/io/previewgenerator.h +++ b/io/previewgenerator.h @@ -12,7 +12,6 @@ class PreviewGenerator : public QThread public: PreviewGenerator(QObject* parent = 0); void run(); - MediaStream* get_stream_from_file_index(int index); Media* media; AVFormatContext* fmt_ctx; }; diff --git a/olive.pro.user b/olive.pro.user index caffec19e..372d7ad90 100644 --- a/olive.pro.user +++ b/olive.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/panels/project.cpp b/panels/project.cpp index af51eea99..dad10f437 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -245,6 +245,7 @@ void Project::new_project() { #define LOAD_STATE_CLIP 5 #define LOAD_STATE_CLIP_EFFECTS 6 #define LOAD_STATE_EFFECT 7 +#define LOAD_STATE_CLIP_LINKS 8 void Project::load_project() { new_project(); @@ -304,6 +305,14 @@ void Project::load_project() { break; case LOAD_STATE_SEQUENCE: if (stream.isEndElement() && stream.name() == "sequence") { + // convert link ids to pointers + for (int i=0;iclip_count();i++) { + Clip* c = temp_seq->get_clip(i); + for (int j=0;jlink_ids.size();j++) { + c->linked.append(temp_seq->get_clip(c->link_ids.at(j))); + } + } + new_sequence(temp_seq); state = LOAD_STATE_IDLE; } else if (stream.isStartElement()) { @@ -373,28 +382,14 @@ void Project::load_project() { } } } else if (stream.name() == "stream") { - // TODO very unintelligent code - i hate this + stream.readNext(); int stream_index = stream.text().toInt(); - bool found = false; - for (int i=0;imedia->video_tracks.size();i++) { - if (temp_clip->media->video_tracks.at(i)->file_index == stream_index) { - temp_clip->media_stream = temp_clip->media->video_tracks[i]; - found = true; - break; - } - } - if (!found) { - for (int i=0;imedia->audio_tracks.size();i++) { - if (temp_clip->media->audio_tracks.at(i)->file_index == stream_index) { - temp_clip->media_stream = temp_clip->media->audio_tracks[i]; - found = true; - break; - } - } - } - if (!found) { + temp_clip->media_stream = temp_clip->media->get_stream_from_file_index(stream_index); + if (temp_clip->media_stream == NULL) { qDebug() << "[WARNING] Could not load media stream - project file seems corrupt"; } + } else if (stream.name() == "linked") { + state = LOAD_STATE_CLIP_LINKS; } else if (stream.name() == "effect") { int effect_id = -1; for (int j=0;jload(&stream); temp_clip->effects.append(e); - state = LOAD_STATE_CLIP; } } } break; + case LOAD_STATE_CLIP_LINKS: + if (stream.name() == "linked" && stream.isEndElement()) { + state = LOAD_STATE_CLIP; + } else if (stream.isStartElement() && stream.name() == "link") { + stream.readNext(); + temp_clip->link_ids.append(stream.text().toInt()); + } + break; } } if (stream.hasError()) { @@ -466,6 +468,12 @@ void Project::save_project() { stream.writeTextElement("afreq", QString::number(s->audio_frequency)); stream.writeTextElement("alayout", QString::number(s->audio_layout)); stream.writeStartElement("clips"); + + // give clips IDs for links + for (int i=0;iclip_count();i++) { + s->get_clip(i)->save_id = i; + } + for (int i=0;iclip_count();i++) { Clip* c = s->get_clip(i); @@ -482,6 +490,11 @@ void Project::save_project() { stream.writeEndElement(); stream.writeTextElement("media", QString::number(c->media->save_id)); stream.writeTextElement("stream", QString::number(c->media_stream->file_index)); + stream.writeStartElement("linked"); + for (int j=0;jlinked.size();j++) { + stream.writeTextElement("link", QString::number(c->linked.at(j)->save_id)); + } + stream.writeEndElement(); stream.writeStartElement("effects"); for (int j=0;jeffects.size();j++) { stream.writeStartElement("effect"); diff --git a/playback/cacher.cpp b/playback/cacher.cpp index c79564d69..37c1462d5 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -50,7 +50,6 @@ void cache_audio_worker(Clip* c) { } else { c->frame_sample_index = av_samples_get_buffer_size(NULL, av_get_channel_layout_nb_channels(c->sequence->audio_layout), nb_samples, AV_SAMPLE_FMT_S16, 1); } - qDebug() << target_sts << frame_sts << nb_samples << c->frame_sample_index; c->audio_just_reset = false; } else { c->frame_sample_index = 0; diff --git a/project/clip.h b/project/clip.h index 3a5b0a911..dbfa60b6c 100644 --- a/project/clip.h +++ b/project/clip.h @@ -93,6 +93,10 @@ struct Clip bool reset_audio; bool audio_just_reset; long audio_target_frame; + + // only used for saving/loading + int save_id; + QVector link_ids; }; #endif // CLIP_H diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 77804092d..3813ff7b3 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -374,7 +374,7 @@ void TimelineWidget::init_ghosts() { } bool subvalidate_snapping(Ghost& g, long* frame_diff, long snap_point) { - int snap_range = 15; + int snap_range = panel_timeline->getFrameFromScreenPoint(10); long in_validator = g.old_in + *frame_diff - snap_point; long out_validator = g.old_out + *frame_diff - snap_point;