diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 7a5e6a6b3..c00e686a1 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -324,7 +324,7 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode, const int &divid // Convert frame to RGB/A for the rest of the pipeline uint8_t* output_data = reinterpret_cast(copy->data()); - int output_linesize = copy->width() * PixelFormat::BytesPerPixel(native_pix_fmt_); + int output_linesize = copy->linesize_bytes(); sws_scale(scale_ctx_, input_data, diff --git a/app/codec/ffmpeg/ffmpegencoder.cpp b/app/codec/ffmpeg/ffmpegencoder.cpp index 441a678e1..7146a0941 100644 --- a/app/codec/ffmpeg/ffmpegencoder.cpp +++ b/app/codec/ffmpeg/ffmpegencoder.cpp @@ -254,7 +254,7 @@ void FFmpegEncoder::WriteInternal(FramePtr frame) // Use swscale context to convert formats/linesizes input_data = frame->const_data(); - input_linesize = frame->width() * PixelFormat::BytesPerPixel(video_conversion_fmt_); + input_linesize = frame->linesize_bytes(); error_code = sws_scale(video_scale_ctx_, reinterpret_cast(&input_data), &input_linesize, diff --git a/app/codec/frame.cpp b/app/codec/frame.cpp index d428ac31a..bb18ace05 100644 --- a/app/codec/frame.cpp +++ b/app/codec/frame.cpp @@ -50,11 +50,16 @@ void Frame::set_video_params(const VideoRenderingParams ¶ms) linesize_ = qCeil(static_cast(params.width()) / 16.0) * 16; } -int Frame::linesize() const +int Frame::linesize_pixels() const { return linesize_; } +int Frame::linesize_bytes() const +{ + return linesize_pixels() * PixelFormat::BytesPerPixel(params_.format()); +} + const int &Frame::width() const { return params_.width(); @@ -76,7 +81,7 @@ Color Frame::get_pixel(int x, int y) const return Color(); } - int pixel_index = y * width() + x; + int pixel_index = y * linesize_pixels() + x; int byte_offset = PixelFormat::GetBufferSize(video_params().format(), pixel_index, 1); @@ -118,11 +123,6 @@ void Frame::set_native_timestamp(const int64_t ×tamp) native_timestamp_ = timestamp; } -QByteArray Frame::ToByteArray() const -{ - return data_; -} - char *Frame::data() { return data_.data(); diff --git a/app/codec/frame.h b/app/codec/frame.h index 014a261ba..a7160016a 100644 --- a/app/codec/frame.h +++ b/app/codec/frame.h @@ -47,7 +47,8 @@ public: const VideoRenderingParams& video_params() const; void set_video_params(const VideoRenderingParams& params); - int linesize() const; + int linesize_pixels() const; + int linesize_bytes() const; const int& width() const; const int& height() const; const PixelFormat::Format& format() const; @@ -69,13 +70,6 @@ public: const int64_t& native_timestamp(); void set_native_timestamp(const int64_t& timestamp); - /** - * @brief Returns a copy of the data in this frame as a QByteArray - * - * Will always do a deep copy. If you want to affect the data directly, use data() instead. - */ - QByteArray ToByteArray() const; - /** * @brief Get the data buffer of this frame */ diff --git a/app/render/backend/opengl/openglproxy.cpp b/app/render/backend/opengl/openglproxy.cpp index eb7e86d6f..2b12a54e2 100644 --- a/app/render/backend/opengl/openglproxy.cpp +++ b/app/render/backend/opengl/openglproxy.cpp @@ -132,7 +132,7 @@ void OpenGLProxy::FrameToValue(FramePtr frame, StreamPtr stream, NodeValueTable* VideoRenderingParams footage_params(frame->width(), frame->height(), frame->format()); - footage_tex_ref = texture_cache_.Get(ctx_, footage_params, frame->data()); + footage_tex_ref = texture_cache_.Get(ctx_, footage_params, frame->data(), frame->linesize_pixels()); if (ocio_method == ColorManager::kOCIOFast) { if (!color_processor->IsEnabled()) { @@ -426,7 +426,7 @@ void OpenGLProxy::RunNodeAccelerated(const Node *node, const TimeRange &range, N output_params.Push(NodeParam::kTexture, QVariant::fromValue(output_tex)); } -void OpenGLProxy::TextureToBuffer(const QVariant &tex_in, void *buffer) +void OpenGLProxy::TextureToBuffer(const QVariant &tex_in, void *buffer, int linesize) { OpenGLTextureCache::ReferencePtr texture = tex_in.value(); @@ -438,6 +438,8 @@ void OpenGLProxy::TextureToBuffer(const QVariant &tex_in, void *buffer) buffer_.Attach(texture->texture()); buffer_.Bind(); + f->glPixelStorei(GL_PACK_ROW_LENGTH, linesize); + f->glReadPixels(0, 0, video_params_.effective_width(), @@ -446,6 +448,8 @@ void OpenGLProxy::TextureToBuffer(const QVariant &tex_in, void *buffer) OpenGLRenderFunctions::GetPixelType(video_params_.format()), buffer); + f->glPixelStorei(GL_PACK_ROW_LENGTH, 0); + buffer_.Release(); buffer_.Detach(); } diff --git a/app/render/backend/opengl/openglproxy.h b/app/render/backend/opengl/openglproxy.h index f30943670..753615e6e 100644 --- a/app/render/backend/opengl/openglproxy.h +++ b/app/render/backend/opengl/openglproxy.h @@ -67,7 +67,7 @@ public: void RunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable& output_params); - void TextureToBuffer(const QVariant& texture, void *buffer); + void TextureToBuffer(const QVariant& texture, void *buffer, int linesize); void SetParameters(const VideoRenderingParams& params); diff --git a/app/render/backend/opengl/opengltexture.cpp b/app/render/backend/opengl/opengltexture.cpp index 3586bf5e4..c0c1621ea 100644 --- a/app/render/backend/opengl/opengltexture.cpp +++ b/app/render/backend/opengl/opengltexture.cpp @@ -75,7 +75,7 @@ void OpenGLTexture::Create(QOpenGLContext *ctx, int width, int height, const Pix void OpenGLTexture::Create(QOpenGLContext *ctx, FramePtr frame) { - Create(ctx, frame->width(), frame->height(), frame->format(), frame->data(), frame->linesize()); + Create(ctx, frame->width(), frame->height(), frame->format(), frame->data(), frame->linesize_pixels()); } void OpenGLTexture::Destroy() diff --git a/app/render/backend/opengl/opengltexturecache.cpp b/app/render/backend/opengl/opengltexturecache.cpp index 450fb962b..95e0638ee 100644 --- a/app/render/backend/opengl/opengltexturecache.cpp +++ b/app/render/backend/opengl/opengltexturecache.cpp @@ -29,7 +29,7 @@ OpenGLTextureCache::~OpenGLTextureCache() } } -OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext* ctx, const VideoRenderingParams ¶ms, const void *data) +OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext* ctx, const VideoRenderingParams ¶ms, const void *data, int linesize) { OpenGLTexturePtr texture = nullptr; @@ -60,12 +60,17 @@ OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext* ctx, co lock_.unlock(); if (data) { - texture->Upload(data); + texture->Upload(data, linesize); } return ref; } +OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext *ctx, const VideoRenderingParams ¶ms) +{ + return Get(ctx, params, nullptr, 0); +} + void OpenGLTextureCache::Relinquish(OpenGLTextureCache::Reference *ref) { OpenGLTexturePtr tex = ref->texture(); diff --git a/app/render/backend/opengl/opengltexturecache.h b/app/render/backend/opengl/opengltexturecache.h index 151a12d2d..7be07bfbb 100644 --- a/app/render/backend/opengl/opengltexturecache.h +++ b/app/render/backend/opengl/opengltexturecache.h @@ -57,7 +57,8 @@ public: DISABLE_COPY_MOVE(OpenGLTextureCache) - ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, const void *data = nullptr); + ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, const void *data, int linesize); + ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params); private: void Relinquish(Reference* ref); diff --git a/app/render/backend/opengl/openglworker.cpp b/app/render/backend/opengl/openglworker.cpp index be7937e50..bee22d266 100644 --- a/app/render/backend/opengl/openglworker.cpp +++ b/app/render/backend/opengl/openglworker.cpp @@ -50,9 +50,9 @@ void OpenGLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, emit RequestRunNodeAccelerated(node, range, input_params, output_params); } -void OpenGLWorker::TextureToBuffer(const QVariant &tex_in, void *buffer) +void OpenGLWorker::TextureToBuffer(const QVariant &tex_in, void *buffer, int linesize) { - emit RequestTextureToBuffer(tex_in, buffer); + emit RequestTextureToBuffer(tex_in, buffer, linesize); } OLIVE_NAMESPACE_EXIT diff --git a/app/render/backend/opengl/openglworker.h b/app/render/backend/opengl/openglworker.h index 6bc90b4c2..1f0330c7d 100644 --- a/app/render/backend/opengl/openglworker.h +++ b/app/render/backend/opengl/openglworker.h @@ -42,14 +42,14 @@ signals: void RequestRunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable& output_params); - void RequestTextureToBuffer(const QVariant& texture, void *buffer); + void RequestTextureToBuffer(const QVariant& texture, void *buffer, int linesize); protected: virtual void FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeRange &range, NodeValueTable* table) override; virtual void RunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable& output_params) override; - virtual void TextureToBuffer(const QVariant& texture, void *buffer) override; + virtual void TextureToBuffer(const QVariant& texture, void *buffer, int linesize) override; }; diff --git a/app/render/backend/videorenderworker.cpp b/app/render/backend/videorenderworker.cpp index b78edb42a..4a39b9797 100644 --- a/app/render/backend/videorenderworker.cpp +++ b/app/render/backend/videorenderworker.cpp @@ -253,7 +253,7 @@ void VideoRenderWorker::Download(const rational& time, QVariant texture, QString { if (operating_mode_ & kDownloadOnly) { - TextureToBuffer(texture, download_buffer_.data()); + TextureToBuffer(texture, download_buffer_.data(), 0); switch (video_params().format()) { case PixelFormat::PIX_FMT_RGB8: @@ -342,7 +342,7 @@ void VideoRenderWorker::Download(const rational& time, QVariant texture, QString frame->set_video_params(video_params()); frame->allocate(); - TextureToBuffer(texture, frame->data()); + TextureToBuffer(texture, frame->data(), frame->linesize_pixels()); emit GeneratedFrame(time, frame); diff --git a/app/render/backend/videorenderworker.h b/app/render/backend/videorenderworker.h index 4a69f060c..96959bde1 100644 --- a/app/render/backend/videorenderworker.h +++ b/app/render/backend/videorenderworker.h @@ -89,7 +89,7 @@ protected: virtual void ParametersChangedEvent(){} - virtual void TextureToBuffer(const QVariant& texture, void *buffer) = 0; + virtual void TextureToBuffer(const QVariant& texture, void *buffer, int linesize) = 0; virtual NodeValueTable RenderInternal(const NodeDependency& CurrentPath, const qint64& job_time) override; diff --git a/app/render/colorprocessor.cpp b/app/render/colorprocessor.cpp index 47773bac5..1188b7270 100644 --- a/app/render/colorprocessor.cpp +++ b/app/render/colorprocessor.cpp @@ -68,7 +68,13 @@ ColorProcessor::ColorProcessor(ColorManager *config, void ColorProcessor::ConvertFrame(Frame *f) { - OCIO::PackedImageDesc img(reinterpret_cast(f->data()), f->width(), f->height(), PixelFormat::ChannelCount(f->format())); + OCIO::PackedImageDesc img(reinterpret_cast(f->data()), + f->width(), + f->height(), + PixelFormat::ChannelCount(f->format()), + OCIO::AutoStride, + OCIO::AutoStride, + f->linesize_bytes()); processor_->apply(img); } diff --git a/app/widget/viewer/viewerglwidget.cpp b/app/widget/viewer/viewerglwidget.cpp index 6d731cbfc..cc39ac71d 100644 --- a/app/widget/viewer/viewerglwidget.cpp +++ b/app/widget/viewer/viewerglwidget.cpp @@ -114,12 +114,12 @@ void ViewerGLWidget::SetImage(const QString &fn) texture_.Create(context(), input->spec().width, input->spec().height, image_format); } - input->read_image(input->spec().format, load_buffer_.data()); + input->read_image(input->spec().format, load_buffer_.data(), OIIO::AutoStride, load_buffer_.linesize_bytes()); input->close(); emit LoadedBuffer(&load_buffer_); - texture_.Upload(load_buffer_.data()); + texture_.Upload(load_buffer_.data(), load_buffer_.linesize_pixels()); emit LoadedTexture(&texture_); @@ -162,9 +162,9 @@ void ViewerGLWidget::SetImageFromLoadBuffer(Frame *in_buffer) || texture_.width() != in_buffer->width() || texture_.height() != in_buffer->height() || texture_.format() != in_buffer->format()) { - texture_.Create(context(), in_buffer->width(), in_buffer->height(), in_buffer->format(), in_buffer->data()); + texture_.Create(context(), in_buffer->width(), in_buffer->height(), in_buffer->format(), in_buffer->data(), load_buffer_.linesize_pixels()); } else { - texture_.Upload(in_buffer->data()); + texture_.Upload(in_buffer->data(), load_buffer_.linesize_pixels()); } doneCurrent();