From 7a06e08ad005ded61a9a2b73b2ea027f841dcc58 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 27 Aug 2013 07:37:19 -0700 Subject: [PATCH] Use ycbcr_converter in YUV4MPEGVideoProvider --- src/video_frame.cpp | 9 +++++++++ src/video_frame.h | 1 + src/video_provider_yuv4mpeg.cpp | 30 ++++++++++++------------------ 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/video_frame.cpp b/src/video_frame.cpp index 91639318a..09c4e9e6d 100644 --- a/src/video_frame.cpp +++ b/src/video_frame.cpp @@ -28,6 +28,15 @@ VideoFrame::VideoFrame(const unsigned char *data, size_t width, size_t height, s { } +VideoFrame::VideoFrame(std::vector&& data, size_t width, size_t height, size_t pitch, bool flipped) +: data(std::move(data)) +, width(width) +, height(height) +, pitch(pitch) +, flipped(flipped) +{ +} + namespace { // We actually have bgr_, not bgra, so we need a custom converter which ignores the alpha channel struct color_converter { diff --git a/src/video_frame.h b/src/video_frame.h index 88055dc33..fc8a67efa 100644 --- a/src/video_frame.h +++ b/src/video_frame.h @@ -26,6 +26,7 @@ struct VideoFrame { bool flipped; VideoFrame(const unsigned char *data, size_t width, size_t height, size_t pitch, bool fipped); + VideoFrame(std::vector&& data, size_t width, size_t height, size_t pitch, bool fipped); }; wxImage GetImage(VideoFrame const& frame); diff --git a/src/video_provider_yuv4mpeg.cpp b/src/video_provider_yuv4mpeg.cpp index 86bcf7c5d..6f0d16845 100644 --- a/src/video_provider_yuv4mpeg.cpp +++ b/src/video_provider_yuv4mpeg.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -130,6 +131,8 @@ class YUV4MPEGVideoProvider final : public VideoProvider { agi::vfr::Framerate fps; + agi::ycbcr_converter conv{agi::ycbcr_matrix::bt601, agi::ycbcr_range::tv}; + /// a list of byte positions detailing where in the file /// each frame header can be found std::vector seek_table; @@ -390,15 +393,6 @@ int YUV4MPEGVideoProvider::IndexFile(uint64_t pos) { return framecount; } -// http://bob.allegronetwork.com/prog/tricks.html#clamp -static FORCEINLINE int clamp(int x) { - x &= (~x) >> 31; - x -= 255; - x &= x >> 31; - x += 255; - return x; -} - std::shared_ptr YUV4MPEGVideoProvider::GetFrame(int n) { n = mid(0, n, num_frames - 1); @@ -422,15 +416,15 @@ std::shared_ptr YUV4MPEGVideoProvider::GetFrame(int n) { for (int py = 0; py < h; ++py) { for (int px = 0; px < w / 2; ++px) { - const int u = *src_u++ - 128; - const int v = *src_v++ - 128; + const uint8_t u = *src_u++; + const uint8_t v = *src_v++; for (unsigned int i = 0; i < 2; ++i) { - const int y = (*src_y++ - 16) * 298; - - *dst++ = clamp((y + 516 * u + 128) >> 8); // Blue - *dst++ = clamp((y - 100 * u - 208 * v + 128) >> 8); // Green - *dst++ = clamp((y + 409 * v + 128) >> 8); // Red - *dst++ = 0; // Alpha + const uint8_t y = *src_y++; + auto rgb = conv.ycbcr_to_rgb({{y, u, v}}); + *dst++ = rgb[2]; + *dst++ = rgb[1]; + *dst++ = rgb[0]; + *dst++ = 0; } } @@ -441,7 +435,7 @@ std::shared_ptr YUV4MPEGVideoProvider::GetFrame(int n) { } } - return std::make_shared(data.data(), w, h, w * 4, false); + return std::make_shared(std::move(data), w, h, w * 4, false); } }