]> git.sesse.net Git - nageru/blobdiff - clip_list.cpp
Move Y'CbCr conversion into a common utility class.
[nageru] / clip_list.cpp
index 3c9637258f60c8b002cee6b23321a318f9734972..2f805756003264470a37b25682e12db736c1ac3f 100644 (file)
@@ -5,14 +5,14 @@
 #include <vector>
 
 #include "clip_list.h"
+#include "timebase.h"
 #include "ui_mainwindow.h"
 
 using namespace std;
 
 string pts_to_string(int64_t pts)
 {
-       // FIXME: This depends on a fixed timebase.
-       int64_t t = lrint((pts / 12800.0) * 1e3);  // In milliseconds.
+       int64_t t = lrint((pts / double(TIMEBASE)) * 1e3);  // In milliseconds.
        int ms = t % 1000;
        t /= 1000;
        int sec = t % 60;
@@ -28,8 +28,7 @@ string pts_to_string(int64_t pts)
 
 string duration_to_string(int64_t pts_diff)
 {
-       // FIXME: This depends on a fixed timebase.
-       int64_t t = lrint((pts_diff / 12800.0) * 1e3);  // In milliseconds.
+       int64_t t = lrint((pts_diff / double(TIMEBASE)) * 1e3);  // In milliseconds.
        int ms = t % 1000;
        t /= 1000;
        int sec = t % 60;
@@ -79,7 +78,7 @@ QVariant ClipList::data(const QModelIndex &parent, int role) const {
                }
        }
 
-       if (role != Qt::DisplayRole)
+       if (role != Qt::DisplayRole && role != Qt::EditRole)
                return QVariant();
 
        switch (Column(column)) {
@@ -130,8 +129,27 @@ QVariant PlayList::data(const QModelIndex &parent, int role) const {
                        return Qt::AlignLeft + Qt::AlignVCenter;
                }
        }
+       if (role == Qt::BackgroundRole) {
+               if (Column(column) == Column::PLAYING) {
+                       if (row == currently_playing_index) {
+                               // This only really works well for the first column, for whatever odd Qt reason.
+                               QLinearGradient grad(QPointF(0, 0), QPointF(1, 0));
+                               grad.setCoordinateMode(grad.QGradient::ObjectBoundingMode);
+                               grad.setColorAt(0.0f, QColor::fromRgbF(0.0f, 0.0f, 1.0f, 0.2f));
+                               grad.setColorAt(play_progress, QColor::fromRgbF(0.0f, 0.0f, 1.0f, 0.2f));
+                               if (play_progress + 0.01f <= 1.0f) {
+                                       grad.setColorAt(play_progress + 0.01f, QColor::fromRgbF(0.0f, 0.0f, 1.0f, 0.0f));
+                               }
+                               return QBrush(grad);
+                       } else {
+                               return QVariant();
+                       }
+               } else {
+                       return QVariant();
+               }
+       }
 
-       if (role != Qt::DisplayRole)
+       if (role != Qt::DisplayRole && role != Qt::EditRole)
                return QVariant();
 
        switch (Column(column)) {
@@ -307,6 +325,7 @@ void ClipList::add_clip(const Clip &clip)
        beginInsertRows(QModelIndex(), clips.size(), clips.size());
        clips.push_back(clip);
        endInsertRows();
+       emit any_content_changed();
 }
 
 void PlayList::add_clip(const Clip &clip)
@@ -314,6 +333,7 @@ void PlayList::add_clip(const Clip &clip)
        beginInsertRows(QModelIndex(), clips.size(), clips.size());
        clips.push_back(clip);
        endInsertRows();
+       emit any_content_changed();
 }
 
 void PlayList::duplicate_clips(size_t first, size_t last)
@@ -321,6 +341,7 @@ void PlayList::duplicate_clips(size_t first, size_t last)
        beginInsertRows(QModelIndex(), first, last);
        clips.insert(clips.begin() + first, clips.begin() + first, clips.begin() + last + 1);
        endInsertRows();
+       emit any_content_changed();
 }
 
 void PlayList::erase_clips(size_t first, size_t last)
@@ -328,6 +349,7 @@ void PlayList::erase_clips(size_t first, size_t last)
        beginRemoveRows(QModelIndex(), first, last);
        clips.erase(clips.begin() + first, clips.begin() + last + 1);
        endRemoveRows();
+       emit any_content_changed();
 }
 
 void PlayList::move_clips(size_t first, size_t last, int delta)
@@ -342,28 +364,94 @@ void PlayList::move_clips(size_t first, size_t last, int delta)
                rotate(clips.rbegin() + last - 1, clips.rbegin() + last, clips.rbegin() + first + 1);
        }
        endMoveRows();
+       emit any_content_changed();
 }
 
 void ClipList::emit_data_changed(size_t row)
 {
        emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS)));
+       emit any_content_changed();
 }
 
 void PlayList::emit_data_changed(size_t row)
 {
        emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS)));
+       emit any_content_changed();
 }
 
-void PlayList::set_currently_playing(int index)
+void PlayList::set_currently_playing(int index, double progress)
 {
        int old_index = currently_playing_index;
+       int column = int(Column::PLAYING);
        if (index != old_index) {
                currently_playing_index = index;
+               play_progress = progress;
                if (old_index != -1) {
-                       emit_data_changed(old_index);
+                       emit dataChanged(this->index(old_index, column), this->index(old_index, column));
                }
                if (index != -1) {
-                       emit_data_changed(index);
+                       emit dataChanged(this->index(index, column), this->index(index, column));
                }
+       } else if (index != -1 && fabs(progress - play_progress) > 1e-3) {
+               play_progress = progress;
+               emit dataChanged(this->index(index, column), this->index(index, column));
+       }
+}
+
+namespace {
+
+Clip deserialize_clip(const ClipProto &clip_proto)
+{
+       Clip clip;
+       clip.pts_in = clip_proto.pts_in();
+       clip.pts_out = clip_proto.pts_out();
+       for (int camera_idx = 0; camera_idx < min(clip_proto.description_size(), NUM_CAMERAS); ++camera_idx) {
+               clip.descriptions[camera_idx] = clip_proto.description(camera_idx);
+       }
+       clip.stream_idx = clip_proto.stream_idx();
+       return clip;
+}
+
+void serialize_clip(const Clip &clip, ClipProto *clip_proto)
+{
+       clip_proto->set_pts_in(clip.pts_in);
+       clip_proto->set_pts_out(clip.pts_out);
+       for (int camera_idx = 0; camera_idx < NUM_CAMERAS; ++camera_idx) {
+               *clip_proto->add_description() = clip.descriptions[camera_idx];
+       }
+       clip_proto->set_stream_idx(clip.stream_idx);
+}
+
+}  // namespace
+
+ClipList::ClipList(const ClipListProto &serialized)
+{
+       for (const ClipProto &clip_proto : serialized.clip()) {
+               clips.push_back(deserialize_clip(clip_proto));
+       }
+}
+
+ClipListProto ClipList::serialize() const
+{
+       ClipListProto ret;
+       for (const Clip &clip : clips) {
+               serialize_clip(clip, ret.add_clip());
+       }
+       return ret;
+}
+
+PlayList::PlayList(const ClipListProto &serialized)
+{
+       for (const ClipProto &clip_proto : serialized.clip()) {
+               clips.push_back(deserialize_clip(clip_proto));
+       }
+}
+
+ClipListProto PlayList::serialize() const
+{
+       ClipListProto ret;
+       for (const Clip &clip : clips) {
+               serialize_clip(clip, ret.add_clip());
        }
+       return ret;
 }