enforce v1 api for now
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
#include <QSpinBox>
|
||||
#ifndef NO_OCIO
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE;
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
#endif
|
||||
|
||||
#include "project/footage.h"
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <QSpinBox>
|
||||
#ifndef NO_OCIO
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE;
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
#endif
|
||||
|
||||
#include "timeline/sequence.h"
|
||||
|
||||
@@ -270,6 +270,9 @@ void SourcesCommon::dropEvent(QWidget* parent,
|
||||
const QModelIndexList& items) {
|
||||
const QMimeData* mimeData = event->mimeData();
|
||||
MediaPtr m = project_parent->item_to_media_ptr(drop_item);
|
||||
if (m == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (mimeData->hasUrls()) {
|
||||
// drag files in from outside
|
||||
QList<QUrl> urls = mimeData->urls();
|
||||
|
||||
+67
-32
@@ -116,7 +116,7 @@ void Cacher::CacheAudioWorker() {
|
||||
long target_frame = audio_target_frame;
|
||||
|
||||
bool temp_reverse = (playback_speed_ < 0);
|
||||
bool reverse_audio = (clip->reversed() != temp_reverse);
|
||||
bool reverse_audio = IsReversed();
|
||||
|
||||
long frame_skip = 0;
|
||||
double last_fr = clip->sequence->frame_rate;
|
||||
@@ -461,6 +461,12 @@ void Cacher::CacheAudioWorker() {
|
||||
QMetaObject::invokeMethod(panel_sequence_viewer, "play_wake", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
bool Cacher::IsReversed()
|
||||
{
|
||||
// Here, the Clip reverse and reversed playback speed cancel each other out to produce normal playback
|
||||
return (clip->reversed() != playback_speed_ < 0);
|
||||
}
|
||||
|
||||
void Cacher::CacheVideoWorker() {
|
||||
|
||||
// is this media a still image?
|
||||
@@ -495,6 +501,9 @@ void Cacher::CacheVideoWorker() {
|
||||
// main thread waits until cacher starts fully, wake it up here
|
||||
WakeMainThread();
|
||||
|
||||
// determine if this media is reversed, which will affect how the queue is constructed
|
||||
bool reversed = IsReversed();
|
||||
|
||||
// get the timestamp we want in terms of the media's timebase
|
||||
int64_t target_pts = seconds_to_timestamp(clip, playhead_to_clip_seconds(clip, playhead_));
|
||||
|
||||
@@ -572,39 +581,55 @@ void Cacher::CacheVideoWorker() {
|
||||
// for FRAME_QUEUE_TYPE_FRAMES, this is used to store the maximum number of frames that can be added
|
||||
int64_t minimum_ts;
|
||||
|
||||
if (olive::CurrentConfig.previous_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) {
|
||||
// get the maximum number of previous frames that can be in the queue
|
||||
minimum_ts = qCeil(olive::CurrentConfig.previous_queue_size);
|
||||
} else {
|
||||
// get the minimum frame timestamp that can be added to the queue
|
||||
minimum_ts = target_pts - seconds_to_timestamp(clip, olive::CurrentConfig.previous_queue_size);
|
||||
}
|
||||
|
||||
// check if we can add more frames to this queue or not
|
||||
|
||||
// for FRAME_QUEUE_TYPE_SECONDS, this is used to store the maximum timestamp
|
||||
// for FRAME_QUEUE_TYPE_FRAMES, this is used to store the maximum number of frames that can be added
|
||||
int64_t maximum_ts;
|
||||
|
||||
bool start_loop = true;
|
||||
// Get queue configuration
|
||||
int previous_queue_type, upcoming_queue_type;
|
||||
double previous_queue_size, upcoming_queue_size;
|
||||
|
||||
if (olive::CurrentConfig.upcoming_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) {
|
||||
maximum_ts = qCeil(olive::CurrentConfig.upcoming_queue_size);
|
||||
// For reversed playback, we flip the queue stats as "upcoming" frames are going to be played before the "previous"
|
||||
// frames now
|
||||
if (reversed) {
|
||||
previous_queue_type = olive::CurrentConfig.upcoming_queue_type;
|
||||
previous_queue_size = olive::CurrentConfig.upcoming_queue_size;
|
||||
upcoming_queue_type = olive::CurrentConfig.previous_queue_type;
|
||||
upcoming_queue_size = olive::CurrentConfig.previous_queue_size;
|
||||
} else {
|
||||
previous_queue_type = olive::CurrentConfig.previous_queue_type;
|
||||
previous_queue_size = olive::CurrentConfig.previous_queue_size;
|
||||
upcoming_queue_type = olive::CurrentConfig.upcoming_queue_type;
|
||||
upcoming_queue_size = olive::CurrentConfig.upcoming_queue_size;
|
||||
}
|
||||
|
||||
// if we already have the maximum number of upcoming frames, don't bother running the below loop at all
|
||||
if (frames_greater_than_target >= maximum_ts) {
|
||||
start_loop = false;
|
||||
}
|
||||
// Determine "previous" queue statistics
|
||||
if (previous_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) {
|
||||
// get the maximum number of previous frames that can be in the queue
|
||||
minimum_ts = qCeil(previous_queue_size);
|
||||
} else {
|
||||
// get the minimum frame timestamp that can be added to the queue
|
||||
minimum_ts = qRound(target_pts - second_pts * previous_queue_size);
|
||||
}
|
||||
|
||||
// Determine "upcoming" queue statistics
|
||||
if (upcoming_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) {
|
||||
maximum_ts = qCeil(upcoming_queue_size);
|
||||
} else {
|
||||
// get the maximum frame timestamp that can be added to the queue
|
||||
maximum_ts = target_pts + seconds_to_timestamp(clip, olive::CurrentConfig.upcoming_queue_size);
|
||||
|
||||
// if the latest frame is already past the maximum queue seconds
|
||||
if (latest_pts > maximum_ts) {
|
||||
start_loop = false;
|
||||
}
|
||||
maximum_ts = qRound(target_pts + second_pts * upcoming_queue_size);
|
||||
}
|
||||
|
||||
// if we already have the maximum number of upcoming frames, don't bother running the retrieving any frames at all
|
||||
bool start_loop = true;
|
||||
if ((upcoming_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES && frames_greater_than_target >= maximum_ts)
|
||||
|| (upcoming_queue_type == olive::FRAME_QUEUE_TYPE_SECONDS && latest_pts > maximum_ts)) {
|
||||
start_loop = false;
|
||||
}
|
||||
|
||||
|
||||
if (start_loop) {
|
||||
|
||||
interrupt_ = false;
|
||||
@@ -630,7 +655,7 @@ void Cacher::CacheVideoWorker() {
|
||||
} else if (decoded_frame->pts != AV_NOPTS_VALUE) {
|
||||
|
||||
// check if this frame exceeds the minimum timestamp
|
||||
if (olive::CurrentConfig.previous_queue_type == olive::FRAME_QUEUE_TYPE_SECONDS
|
||||
if (previous_queue_type == olive::FRAME_QUEUE_TYPE_SECONDS
|
||||
&& decoded_frame->pts < minimum_ts) {
|
||||
|
||||
// if so, we don't need it
|
||||
@@ -640,16 +665,26 @@ void Cacher::CacheVideoWorker() {
|
||||
|
||||
if (retrieved_frame == nullptr) {
|
||||
if (decoded_frame->pts == target_pts) {
|
||||
SetRetrievedFrame(decoded_frame);
|
||||
} else if (seeked_to_zero) {
|
||||
|
||||
// If this flag is set, it means this was somehow the earliest frame we could get for this timestamp
|
||||
// We retrieved the exact frame we're looking for
|
||||
|
||||
SetRetrievedFrame(decoded_frame);
|
||||
seeked_to_zero = false;
|
||||
|
||||
} else if (decoded_frame->pts > target_pts) {
|
||||
|
||||
if (queue_.size() > 0) {
|
||||
|
||||
SetRetrievedFrame(queue_.last());
|
||||
|
||||
} else if (seeked_to_zero) {
|
||||
|
||||
// If this flag is set but we still got a frame after the target timestamp, it means this was somehow
|
||||
// the earliest frame we could get
|
||||
SetRetrievedFrame(decoded_frame);
|
||||
seeked_to_zero = false;
|
||||
|
||||
}
|
||||
|
||||
} else if (decoded_frame->pts > target_pts
|
||||
&& queue_.size() > 0) {
|
||||
SetRetrievedFrame(queue_.last());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,7 +695,7 @@ void Cacher::CacheVideoWorker() {
|
||||
|
||||
// check the amount of previous frames in the queue by using the current queue size for if we need to
|
||||
// remove any old entries (assumes the queue is chronological)
|
||||
if (olive::CurrentConfig.previous_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) {
|
||||
if (previous_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) {
|
||||
|
||||
int previous_frame_count = 0;
|
||||
|
||||
@@ -692,7 +727,7 @@ void Cacher::CacheVideoWorker() {
|
||||
}
|
||||
|
||||
// check if the queue is full according to olive::CurrentConfig
|
||||
if (olive::CurrentConfig.upcoming_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) {
|
||||
if (upcoming_queue_type == olive::FRAME_QUEUE_TYPE_FRAMES) {
|
||||
|
||||
// if this frame is later than the target, it's an "upcoming" frame
|
||||
if (decoded_frame->pts > target_pts) {
|
||||
|
||||
@@ -570,6 +570,11 @@ private:
|
||||
* audio to the audio buffer which will later be sent to the audio output device.
|
||||
*/
|
||||
void CacheAudioWorker();
|
||||
|
||||
/**
|
||||
* @brief Internal function using the Cacher's known information to determine whether this media is playing in reverse
|
||||
*/
|
||||
bool IsReversed();
|
||||
};
|
||||
|
||||
#endif // CACHER_H
|
||||
|
||||
@@ -390,7 +390,7 @@ void ExportThread::run() {
|
||||
if (params.video_enabled) {
|
||||
do {
|
||||
// TODO optimize by rendering the next frame while encoding the last
|
||||
renderer->start_render(nullptr, olive::ActiveSequence.get(), nullptr, video_frame->data[0], video_frame->linesize[0]/4);
|
||||
renderer->start_render(nullptr, olive::ActiveSequence.get(), 1, nullptr, video_frame->data[0], video_frame->linesize[0]/4);
|
||||
waitCond.wait(&mutex);
|
||||
if (!continueEncode) break;
|
||||
} while (renderer->did_texture_fail());
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <QOpenGLShaderProgram>
|
||||
#ifndef NO_OCIO
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE;
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
#endif
|
||||
|
||||
#include "timeline/sequence.h"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#ifndef NO_OCIO
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE;
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
#endif
|
||||
|
||||
#include "timeline/sequence.h"
|
||||
@@ -220,7 +220,7 @@ void RenderThread::paint() {
|
||||
params.video = true;
|
||||
params.texture_failed = false;
|
||||
params.wait_for_mutexes = true;
|
||||
params.playback_speed = 1;
|
||||
params.playback_speed = playback_speed_;
|
||||
params.blend_mode_program = blend_mode_program.get();
|
||||
params.pipeline = pipeline_program.get();
|
||||
params.backend_buffer1 = &back_buffer_1;
|
||||
@@ -315,6 +315,7 @@ void RenderThread::paint() {
|
||||
|
||||
void RenderThread::start_render(QOpenGLContext *share,
|
||||
Sequence* s,
|
||||
int playback_speed,
|
||||
const QString& save,
|
||||
GLvoid* pixels,
|
||||
int pixel_linesize,
|
||||
@@ -323,6 +324,8 @@ void RenderThread::start_render(QOpenGLContext *share,
|
||||
|
||||
seq = s;
|
||||
|
||||
playback_speed_ = playback_speed;
|
||||
|
||||
// stall any dependent actions
|
||||
texture_failed = true;
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
void paint();
|
||||
void start_render(QOpenGLContext* share,
|
||||
Sequence *s,
|
||||
int playback_speed,
|
||||
const QString &save = nullptr,
|
||||
GLvoid *pixels = nullptr,
|
||||
int pixel_linesize = 0,
|
||||
@@ -104,6 +105,7 @@ private:
|
||||
|
||||
Sequence* seq;
|
||||
|
||||
int playback_speed_;
|
||||
int divider;
|
||||
int tex_width;
|
||||
int tex_height;
|
||||
|
||||
+3
-3
@@ -169,7 +169,7 @@ void ViewerWidget::save_frame() {
|
||||
fn += selected_ext;
|
||||
}
|
||||
|
||||
renderer.start_render(context(), viewer->seq.get(), fn);
|
||||
renderer.start_render(context(), viewer->seq.get(), 1, fn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ void ViewerWidget::frame_update() {
|
||||
update();
|
||||
} else {
|
||||
doneCurrent();
|
||||
renderer.start_render(context(), viewer->seq.get());
|
||||
renderer.start_render(context(), viewer->seq.get(), viewer->get_playback_speed());
|
||||
}
|
||||
|
||||
// render the audio
|
||||
@@ -767,7 +767,7 @@ void ViewerWidget::paintGL() {
|
||||
|
||||
if (renderer.did_texture_fail() && !viewer->playing) {
|
||||
doneCurrent();
|
||||
renderer.start_render(context(), viewer->seq.get());
|
||||
renderer.start_render(context(), viewer->seq.get(), viewer->get_playback_speed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user