attached clip markers to footage markers
This commit is contained in:
+38
-22
@@ -185,34 +185,34 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
int folder = 0;
|
||||
|
||||
Media* item = new Media(0);
|
||||
Footage* m = new Footage();
|
||||
Footage* f = new Footage();
|
||||
|
||||
m->using_inout = false;
|
||||
f->using_inout = false;
|
||||
|
||||
for (int j=0;j<stream.attributes().size();j++) {
|
||||
const QXmlStreamAttribute& attr = stream.attributes().at(j);
|
||||
if (attr.name() == "id") {
|
||||
m->save_id = attr.value().toInt();
|
||||
f->save_id = attr.value().toInt();
|
||||
} else if (attr.name() == "folder") {
|
||||
folder = attr.value().toInt();
|
||||
} else if (attr.name() == "name") {
|
||||
m->name = attr.value().toString();
|
||||
f->name = attr.value().toString();
|
||||
} else if (attr.name() == "url") {
|
||||
m->url = attr.value().toString();
|
||||
f->url = attr.value().toString();
|
||||
|
||||
if (!QFileInfo::exists(m->url)) { // if path is not absolute
|
||||
QString proj_dir_test = proj_dir.absoluteFilePath(m->url);
|
||||
QString internal_proj_dir_test = internal_proj_dir.absoluteFilePath(m->url);
|
||||
if (!QFileInfo::exists(f->url)) { // if path is not absolute
|
||||
QString proj_dir_test = proj_dir.absoluteFilePath(f->url);
|
||||
QString internal_proj_dir_test = internal_proj_dir.absoluteFilePath(f->url);
|
||||
|
||||
if (QFileInfo::exists(proj_dir_test)) { // if path is relative to the project's current dir
|
||||
m->url = proj_dir_test;
|
||||
f->url = proj_dir_test;
|
||||
qInfo() << "Matched" << attr.value().toString() << "relative to project's current directory";
|
||||
} else if (QFileInfo::exists(internal_proj_dir_test)) { // if path is relative to the last directory the project was saved in
|
||||
m->url = internal_proj_dir_test;
|
||||
f->url = internal_proj_dir_test;
|
||||
qInfo() << "Matched" << attr.value().toString() << "relative to project's internal directory";
|
||||
} else if (m->url.contains('%')) {
|
||||
} else if (f->url.contains('%')) {
|
||||
// hack for image sequences (qt won't be able to find the URL with %, but ffmpeg may)
|
||||
m->url = internal_proj_dir_test;
|
||||
f->url = internal_proj_dir_test;
|
||||
qInfo() << "Guess image sequence" << attr.value().toString() << "path to project's internal directory";
|
||||
} else {
|
||||
qInfo() << "Failed to match" << attr.value().toString() << "to file";
|
||||
@@ -221,25 +221,41 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
qInfo() << "Matched" << attr.value().toString() << "with absolute path";
|
||||
}
|
||||
} else if (attr.name() == "duration") {
|
||||
m->length = attr.value().toLongLong();
|
||||
f->length = attr.value().toLongLong();
|
||||
} else if (attr.name() == "using_inout") {
|
||||
m->using_inout = (attr.value() == "1");
|
||||
f->using_inout = (attr.value() == "1");
|
||||
} else if (attr.name() == "in") {
|
||||
m->in = attr.value().toLong();
|
||||
f->in = attr.value().toLong();
|
||||
} else if (attr.name() == "out") {
|
||||
m->out = attr.value().toLong();
|
||||
f->out = attr.value().toLong();
|
||||
} else if (attr.name() == "speed") {
|
||||
m->speed = attr.value().toDouble();
|
||||
f->speed = attr.value().toDouble();
|
||||
} else if (attr.name() == "alphapremul") {
|
||||
m->alpha_is_premultiplied = (attr.value() == "1");
|
||||
f->alpha_is_premultiplied = (attr.value() == "1");
|
||||
} else if (attr.name() == "proxy") {
|
||||
m->proxy = (attr.value() == "1");
|
||||
f->proxy = (attr.value() == "1");
|
||||
} else if (attr.name() == "proxypath") {
|
||||
m->proxy_path = attr.value().toString();
|
||||
f->proxy_path = attr.value().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item->set_footage(m);
|
||||
while (!cancelled && !(stream.name() == child_search && stream.isEndElement()) && !stream.atEnd()) {
|
||||
read_next_start_element(stream);
|
||||
if (stream.name() == "marker" && stream.isStartElement()) {
|
||||
Marker m;
|
||||
for (int j=0;j<stream.attributes().size();j++) {
|
||||
const QXmlStreamAttribute& attr = stream.attributes().at(j);
|
||||
if (attr.name() == "frame") {
|
||||
m.frame = attr.value().toLong();
|
||||
} else if (attr.name() == "name") {
|
||||
m.name = attr.value().toString();
|
||||
}
|
||||
}
|
||||
f->markers.append(m);
|
||||
}
|
||||
}
|
||||
|
||||
item->set_footage(f);
|
||||
|
||||
if (folder == 0) {
|
||||
project_model.appendChild(nullptr, item);
|
||||
|
||||
+15
-6
@@ -970,6 +970,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
stream.writeAttribute("proxy", QString::number(f->proxy));
|
||||
stream.writeAttribute("proxypath", f->proxy_path);
|
||||
|
||||
// save video stream metadata
|
||||
for (int j=0;j<f->video_tracks.size();j++) {
|
||||
const FootageStream& ms = f->video_tracks.at(j);
|
||||
stream.writeStartElement("video");
|
||||
@@ -978,8 +979,10 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
stream.writeAttribute("height", QString::number(ms.video_height));
|
||||
stream.writeAttribute("framerate", QString::number(ms.video_frame_rate, 'f', 10));
|
||||
stream.writeAttribute("infinite", QString::number(ms.infinite_length));
|
||||
stream.writeEndElement();
|
||||
stream.writeEndElement(); // video
|
||||
}
|
||||
|
||||
// save audio stream metadata
|
||||
for (int j=0;j<f->audio_tracks.size();j++) {
|
||||
const FootageStream& ms = f->audio_tracks.at(j);
|
||||
stream.writeStartElement("audio");
|
||||
@@ -987,9 +990,15 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
stream.writeAttribute("channels", QString::number(ms.audio_channels));
|
||||
stream.writeAttribute("layout", QString::number(ms.audio_layout));
|
||||
stream.writeAttribute("frequency", QString::number(ms.audio_frequency));
|
||||
stream.writeEndElement();
|
||||
stream.writeEndElement(); // audio
|
||||
}
|
||||
stream.writeEndElement();
|
||||
|
||||
// save footage markers
|
||||
for (int j=0;j<f->markers.size();j++) {
|
||||
save_marker(stream, f->markers.at(j));
|
||||
}
|
||||
|
||||
stream.writeEndElement(); // footage
|
||||
media_id++;
|
||||
} else if (type == MEDIA_TYPE_SEQUENCE) {
|
||||
Sequence* s = m->to_sequence();
|
||||
@@ -1062,8 +1071,8 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
}
|
||||
|
||||
// save markers
|
||||
// unnecessary for nested sequences since sequences have their own marker saving
|
||||
if (c->media == nullptr || c->media->get_type() != MEDIA_TYPE_SEQUENCE) {
|
||||
// only necessary for null media clips, since media has its own markers
|
||||
if (c->media == nullptr) {
|
||||
for (int k=0;k<c->get_markers().size();k++) {
|
||||
save_marker(stream, c->get_markers().at(k));
|
||||
}
|
||||
@@ -1087,7 +1096,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
stream.writeEndElement(); // clip
|
||||
}
|
||||
}
|
||||
for (int j=0;j<s->markers.size();j++) {
|
||||
for (int j=0;j<s->markers.size();j++) {
|
||||
save_marker(stream, s->markers.at(j));
|
||||
}
|
||||
stream.writeEndElement();
|
||||
|
||||
+2
-2
@@ -151,8 +151,8 @@ void Clip::queue_remove_earliest() {
|
||||
}
|
||||
|
||||
QVector<Marker> &Clip::get_markers() {
|
||||
if (media != nullptr && media->get_type() == MEDIA_TYPE_SEQUENCE) {
|
||||
return media->to_sequence()->markers;
|
||||
if (media != nullptr) {
|
||||
return media->get_markers();
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <QPixmap>
|
||||
#include <QIcon>
|
||||
|
||||
#include "project/marker.h"
|
||||
|
||||
enum VideoInterlacingMode {
|
||||
VIDEO_PROGRESSIVE,
|
||||
VIDEO_TOP_FIELD_FIRST,
|
||||
@@ -45,6 +47,7 @@ struct Footage {
|
||||
Footage();
|
||||
~Footage();
|
||||
|
||||
// footage metadata
|
||||
QString url;
|
||||
QString name;
|
||||
int64_t length;
|
||||
@@ -60,13 +63,19 @@ struct Footage {
|
||||
bool proxy;
|
||||
QString proxy_path;
|
||||
|
||||
// thumbnail/waveform generation
|
||||
PreviewGenerator* preview_gen;
|
||||
QMutex ready_lock;
|
||||
|
||||
// in/out points
|
||||
bool using_inout;
|
||||
long in;
|
||||
long out;
|
||||
|
||||
// markers
|
||||
QVector<Marker> markers;
|
||||
|
||||
// functions
|
||||
long get_length_in_frames(double frame_rate);
|
||||
FootageStream *get_stream_from_file_index(bool video, int index);
|
||||
void reset();
|
||||
|
||||
+14
-1
@@ -329,5 +329,18 @@ Media *Media::parentItem() {
|
||||
}
|
||||
|
||||
void Media::removeChild(int i) {
|
||||
children.removeAt(i);
|
||||
children.removeAt(i);
|
||||
}
|
||||
|
||||
QVector<Marker> &Media::get_markers() {
|
||||
// returns the marker array from the internal object
|
||||
//
|
||||
// NOTE: if this media object is not footage or a sequence, the result is
|
||||
// undefined - most likely a crash
|
||||
|
||||
if (get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
return to_footage()->markers;
|
||||
} else {
|
||||
return to_sequence()->markers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
|
||||
#include "project/marker.h"
|
||||
|
||||
#define MEDIA_TYPE_FOOTAGE 0
|
||||
#define MEDIA_TYPE_SEQUENCE 1
|
||||
#define MEDIA_TYPE_FOLDER 2
|
||||
@@ -46,6 +48,9 @@ public:
|
||||
Media *parentItem();
|
||||
void removeChild(int i);
|
||||
|
||||
// get markers from internal object
|
||||
QVector<Marker>& get_markers();
|
||||
|
||||
bool root;
|
||||
int temp_id;
|
||||
int temp_id2;
|
||||
|
||||
@@ -41,10 +41,11 @@ bool ProjectFilter::filterAcceptsRow(int source_row, const QModelIndex &source_p
|
||||
// search markers if media is a sequene
|
||||
bool marker_contains_search = false;
|
||||
|
||||
if (media->get_type() == MEDIA_TYPE_SEQUENCE) {
|
||||
Sequence* s = media->to_sequence();
|
||||
for (int i=0;i<s->markers.size();i++) {
|
||||
if (s->markers.at(i).name.contains(search_filter, Qt::CaseInsensitive)) {
|
||||
if (media->get_type() == MEDIA_TYPE_SEQUENCE
|
||||
|| media->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
QVector<Marker>& markers = media->get_markers();
|
||||
for (int i=0;i<markers.size();i++) {
|
||||
if (markers.at(i).name.contains(search_filter, Qt::CaseInsensitive)) {
|
||||
marker_contains_search = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user