summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2019-04-30 13:38:44 +0200
committerGitHub <noreply@github.com>2019-04-30 13:38:44 +0200
commit12cc760538fbec37199dcc24098d942ac1d623b8 (patch)
tree055ea7e21718ef7bd430b43eebf4738f03f56618
parentb5deb1dc72d8c4c92c9850379522926e60ddf7d0 (diff)
parentb1f5cee7d9a1f509ef8990f3b8405c74e83a20cc (diff)
Merge pull request #26051 from 20kdc/videofix
webm/theora/yuv2rgb/libsimplewebm: Fix colour issues I could find.
-rw-r--r--modules/theora/video_stream_theora.cpp6
-rw-r--r--modules/webm/video_stream_webm.cpp27
-rw-r--r--thirdparty/README.md11
-rw-r--r--thirdparty/libsimplewebm/OpusVorbisDecoder.cpp2
-rw-r--r--thirdparty/libsimplewebm/OpusVorbisDecoder.hpp4
-rw-r--r--thirdparty/libsimplewebm/VPXDecoder.cpp14
-rw-r--r--thirdparty/libsimplewebm/VPXDecoder.hpp6
-rw-r--r--thirdparty/misc/yuv2rgb.h121
8 files changed, 96 insertions, 95 deletions
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 8db0799b47..ae542713ea 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -94,15 +94,15 @@ void VideoStreamPlaybackTheora::video_write(void) {
if (px_fmt == TH_PF_444) {
- yuv444_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2, 0);
+ yuv444_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2);
} else if (px_fmt == TH_PF_422) {
- yuv422_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2, 0);
+ yuv422_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2);
} else if (px_fmt == TH_PF_420) {
- yuv420_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[2].data, (uint8_t *)yuv[1].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2, 0);
+ yuv420_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2);
};
format = Image::FORMAT_RGBA8;
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index f2497eeec1..f6397483e8 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -32,6 +32,7 @@
#include "OpusVorbisDecoder.hpp"
#include "VPXDecoder.hpp"
+#include <vpx/vpx_image.h>
#include "mkvparser/mkvparser.h"
@@ -314,19 +315,37 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
PoolVector<uint8_t>::Write w = frame_data.write();
bool converted = false;
- if (image.chromaShiftW == 1 && image.chromaShiftH == 1) {
+ if (image.chromaShiftW == 0 && image.chromaShiftH == 0 && image.cs == VPX_CS_SRGB) {
+
+ uint8_t *wp = w.ptr();
+ unsigned char *rRow = image.planes[2];
+ unsigned char *gRow = image.planes[0];
+ unsigned char *bRow = image.planes[1];
+ for (size_t i = 0; i < image.h; i++) {
+ for (size_t j = 0; j < image.w; j++) {
+ *wp++ = rRow[j];
+ *wp++ = gRow[j];
+ *wp++ = bRow[j];
+ *wp++ = 255;
+ }
+ rRow += image.linesize[2];
+ gRow += image.linesize[0];
+ bRow += image.linesize[1];
+ }
+ converted = true;
+ } else if (image.chromaShiftW == 1 && image.chromaShiftH == 1) {
- yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
+ yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
// libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) {
- yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
+ yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
// libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) {
- yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
+ yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
// libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) {
diff --git a/thirdparty/README.md b/thirdparty/README.md
index e2c2334c0f..b4a9b83331 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -185,18 +185,21 @@ Files extracted from upstream source:
## libsimplewebm
- Upstream: https://github.com/zaps166/libsimplewebm
-- Version: git (05cfdc2, 2016)
-- License: MIT, BSD-3-Clause
+- Version: git (fe57fd3, 2019)
+- License: MIT (main), BSD-3-Clause (libwebm)
+
+This contains libwebm, but the version in use is updated from the one used by libsimplewebm,
+and may have *unmarked* alterations from that.
Files extracted from upstream source:
-TODO.
+- all the .cpp, .hpp files in the main folder except `example.cpp`
+- LICENSE
Important: Some files have Godot-made changes.
They are marked with `// -- GODOT start --` and `// -- GODOT end --`
comments.
-
## libtheora
- Upstream: https://www.theora.org
diff --git a/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp b/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp
index c9e71eb733..b5824b17be 100644
--- a/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp
+++ b/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp
@@ -122,6 +122,7 @@ bool OpusVorbisDecoder::getPCMS16(WebMFrame &frame, short *buffer, int &numOutSa
return false;
}
+// -- GODOT begin --
bool OpusVorbisDecoder::getPCMF(WebMFrame &frame, float *buffer, int &numOutSamples) {
if (m_vorbis) {
m_vorbis->op.packet = frame.buffer;
@@ -158,6 +159,7 @@ bool OpusVorbisDecoder::getPCMF(WebMFrame &frame, float *buffer, int &numOutSamp
}
return false;
}
+// -- GODOT end --
bool OpusVorbisDecoder::openVorbis(const WebMDemuxer &demuxer)
{
diff --git a/thirdparty/libsimplewebm/OpusVorbisDecoder.hpp b/thirdparty/libsimplewebm/OpusVorbisDecoder.hpp
index b7619d6a25..f285b3fbd6 100644
--- a/thirdparty/libsimplewebm/OpusVorbisDecoder.hpp
+++ b/thirdparty/libsimplewebm/OpusVorbisDecoder.hpp
@@ -44,8 +44,10 @@ public:
{
return m_numSamples;
}
- bool getPCMF(WebMFrame &frame, float *buffer, int &numOutSamples);
bool getPCMS16(WebMFrame &frame, short *buffer, int &numOutSamples);
+// -- GODOT begin --
+ bool getPCMF(WebMFrame &frame, float *buffer, int &numOutSamples);
+// -- GODOT end --
private:
bool openVorbis(const WebMDemuxer &demuxer);
diff --git a/thirdparty/libsimplewebm/VPXDecoder.cpp b/thirdparty/libsimplewebm/VPXDecoder.cpp
index 3f77b8f5cd..e2606f83ba 100644
--- a/thirdparty/libsimplewebm/VPXDecoder.cpp
+++ b/thirdparty/libsimplewebm/VPXDecoder.cpp
@@ -33,7 +33,8 @@
VPXDecoder::VPXDecoder(const WebMDemuxer &demuxer, unsigned threads) :
m_ctx(NULL),
m_iter(NULL),
- m_delay(0)
+ m_delay(0),
+ m_last_space(VPX_CS_UNKNOWN)
{
if (threads > 8)
threads = 8;
@@ -86,6 +87,11 @@ VPXDecoder::IMAGE_ERROR VPXDecoder::getImage(Image &image)
IMAGE_ERROR err = NO_FRAME;
if (vpx_image_t *img = vpx_codec_get_frame(m_ctx, &m_iter))
{
+ // It seems to be a common problem that UNKNOWN comes up a lot, yet FFMPEG is somehow getting accurate colour-space information.
+ // After checking FFMPEG code, *they're* getting colour-space information, so I'm assuming something like this is going on.
+ // It appears to work, at least.
+ if (img->cs != VPX_CS_UNKNOWN)
+ m_last_space = img->cs;
if ((img->fmt & VPX_IMG_FMT_PLANAR) && !(img->fmt & (VPX_IMG_FMT_HAS_ALPHA | VPX_IMG_FMT_HIGHBITDEPTH)))
{
if (img->stride[0] && img->stride[1] && img->stride[2])
@@ -95,6 +101,7 @@ VPXDecoder::IMAGE_ERROR VPXDecoder::getImage(Image &image)
image.w = img->d_w;
image.h = img->d_h;
+ image.cs = m_last_space;
image.chromaShiftW = img->x_chroma_shift;
image.chromaShiftH = img->y_chroma_shift;
@@ -119,7 +126,9 @@ VPXDecoder::IMAGE_ERROR VPXDecoder::getImage(Image &image)
/**/
+// -- GODOT begin --
#if 0
+// -- GODOT end --
static inline int ceilRshift(int val, int shift)
{
@@ -139,4 +148,7 @@ int VPXDecoder::Image::getHeight(int plane) const
return ceilRshift(h, chromaShiftH);
}
+// -- GODOT begin --
#endif
+// -- GODOT end --
+
diff --git a/thirdparty/libsimplewebm/VPXDecoder.hpp b/thirdparty/libsimplewebm/VPXDecoder.hpp
index 6108395871..5071b069cb 100644
--- a/thirdparty/libsimplewebm/VPXDecoder.hpp
+++ b/thirdparty/libsimplewebm/VPXDecoder.hpp
@@ -37,12 +37,17 @@ public:
class Image
{
public:
+// -- GODOT begin --
#if 0
+// -- GODOT end --
int getWidth(int plane) const;
int getHeight(int plane) const;
+// -- GODOT begin --
#endif
+// -- GODOT end --
int w, h;
+ int cs;
int chromaShiftW, chromaShiftH;
unsigned char *planes[3];
int linesize[3];
@@ -75,6 +80,7 @@ private:
vpx_codec_ctx *m_ctx;
const void *m_iter;
int m_delay;
+ int m_last_space;
};
#endif // VPXDECODER_HPP
diff --git a/thirdparty/misc/yuv2rgb.h b/thirdparty/misc/yuv2rgb.h
index 3ec8388246..d8f7fd6de2 100644
--- a/thirdparty/misc/yuv2rgb.h
+++ b/thirdparty/misc/yuv2rgb.h
@@ -24,6 +24,14 @@ does not infringe any patents that apply in your area before you
ship it.
*/
+/*
+ * Please note that this version has been modified for various reasons:
+ * 1. Using the Godot core typedefs
+ * 2. At some point or another the code relied on the byte order of a uint32_t, this has been fixed
+ * 3. Output has been reordered to struct { uint8_t r, g, b, a; } precisely in accordance with the function names
+ * 4. Removing unused 'dither' parameter
+ */
+
#ifndef YUV2RGB_H
#define YUV2RGB_H
@@ -803,6 +811,8 @@ static const uint32_t tables[256*3] = {
0xE6365800U
};
+/* -- Common -- */
+
#define FLAGS 0x40080100
#define READUV(U,V) (tables[256 + (U)] + tables[512 + (V)])
#define READY(Y) tables[Y]
@@ -820,12 +830,14 @@ do { \
#define STORE(Y,DSTPTR) \
do { \
- *(DSTPTR)++ = (Y); \
- *(DSTPTR)++ = (Y)>>22; \
*(DSTPTR)++ = (Y)>>11; \
- *(DSTPTR)++ = 255; \
+ *(DSTPTR)++ = (Y)>>22; \
+ *(DSTPTR)++ = (Y); \
+ *(DSTPTR)++ = 255; \
} while (0 == 1)
+/* -- End Common -- */
+
static void yuv422_2_rgb8888(uint8_t *dst_ptr,
const uint8_t *y_ptr,
const uint8_t *u_ptr,
@@ -834,8 +846,7 @@ static void yuv422_2_rgb8888(uint8_t *dst_ptr,
int32_t height,
int32_t y_span,
int32_t uv_span,
- int32_t dst_span,
- int32_t dither)
+ int32_t dst_span)
{
height -= 1;
while (height > 0)
@@ -909,35 +920,7 @@ static void yuv422_2_rgb8888(uint8_t *dst_ptr,
}
}
-
-#undef FLAGS
-#undef READUV
-#undef READY
-#undef FIXUP
-#undef STORE
-
-
-#define FLAGS 0x40080100
-#define READUV(U,V) (tables[256 + (U)] + tables[512 + (V)])
-#define READY(Y) tables[Y]
-#define FIXUP(Y) \
-do { \
- int tmp = (Y) & FLAGS; \
- if (tmp != 0) \
- { \
- tmp -= tmp>>8; \
- (Y) |= tmp; \
- tmp = FLAGS & ~(Y>>1); \
- (Y) += tmp>>8; \
- } \
-} while (0 == 1)
-
-#define STORE(Y,DSTPTR) \
-do { \
- (DSTPTR) = 0xFF000000 | (Y & 0xFF) | (0xFF00 & (Y>>14)) | (0xFF0000 & (Y<<5));\
-} while (0 == 1)
-
-static void yuv420_2_rgb8888(uint8_t *dst_ptr_,
+static void yuv420_2_rgb8888(uint8_t *dst_ptr,
const uint8_t *y_ptr,
const uint8_t *u_ptr,
const uint8_t *v_ptr,
@@ -945,12 +928,9 @@ static void yuv420_2_rgb8888(uint8_t *dst_ptr_,
int32_t height,
int32_t y_span,
int32_t uv_span,
- int32_t dst_span,
- int32_t dither)
+ int32_t dst_span)
{
- uint32_t *dst_ptr = (uint32_t *)(void *)dst_ptr_;
- dst_span >>= 2;
-
+ /* The 'dst_ptr as uint32_t' thing is not endianness-aware, so that's been removed. */
height -= 1;
while (height > 0)
{
@@ -960,36 +940,38 @@ static void yuv420_2_rgb8888(uint8_t *dst_ptr_,
{
/* Do 2 column pairs */
uint32_t uv, y0, y1;
+ uint8_t * dst_ptr_1span = dst_ptr + dst_span;
uv = READUV(*u_ptr++,*v_ptr++);
y1 = uv + READY(y_ptr[y_span]);
y0 = uv + READY(*y_ptr++);
FIXUP(y1);
FIXUP(y0);
- STORE(y1, dst_ptr[dst_span]);
- STORE(y0, *dst_ptr++);
+ STORE(y1, dst_ptr_1span);
+ STORE(y0, dst_ptr);
y1 = uv + READY(y_ptr[y_span]);
y0 = uv + READY(*y_ptr++);
FIXUP(y1);
FIXUP(y0);
- STORE(y1, dst_ptr[dst_span]);
- STORE(y0, *dst_ptr++);
+ STORE(y1, dst_ptr_1span);
+ STORE(y0, dst_ptr);
height += (2<<16);
}
if ((height>>16) == 0)
{
/* Trailing column pair */
uint32_t uv, y0, y1;
+ uint8_t * dst_ptr_1span = dst_ptr + dst_span;
uv = READUV(*u_ptr,*v_ptr);
y1 = uv + READY(y_ptr[y_span]);
y0 = uv + READY(*y_ptr++);
FIXUP(y1);
FIXUP(y0);
- STORE(y0, dst_ptr[dst_span]);
- STORE(y1, *dst_ptr++);
+ STORE(y0, dst_ptr_1span);
+ STORE(y1, dst_ptr);
}
- dst_ptr += dst_span*2-width;
+ dst_ptr += (dst_span * 2) - (width * 4);
y_ptr += y_span*2-width;
u_ptr += uv_span-(width>>1);
v_ptr += uv_span-(width>>1);
@@ -1011,8 +993,8 @@ static void yuv420_2_rgb8888(uint8_t *dst_ptr_,
y0 = uv + READY(*y_ptr++);
FIXUP(y1);
FIXUP(y0);
- STORE(y1, *dst_ptr++);
- STORE(y0, *dst_ptr++);
+ STORE(y1, dst_ptr);
+ STORE(y0, dst_ptr);
height += (2<<16);
}
if ((height>>16) == 0)
@@ -1023,42 +1005,11 @@ static void yuv420_2_rgb8888(uint8_t *dst_ptr_,
uv = READUV(*u_ptr++,*v_ptr++);
y0 = uv + READY(*y_ptr++);
FIXUP(y0);
- STORE(y0, *dst_ptr++);
+ STORE(y0, dst_ptr);
}
}
}
-
-
-#undef FLAGS
-#undef READUV
-#undef READY
-#undef FIXUP
-#undef STORE
-
-#define FLAGS 0x40080100
-#define READUV(U,V) (tables[256 + (U)] + tables[512 + (V)])
-#define READY(Y) tables[Y]
-#define FIXUP(Y) \
-do { \
- int tmp = (Y) & FLAGS; \
- if (tmp != 0) \
- { \
- tmp -= tmp>>8; \
- (Y) |= tmp; \
- tmp = FLAGS & ~(Y>>1); \
- (Y) += tmp>>8; \
- } \
-} while (0 == 1)
-
-#define STORE(Y,DSTPTR) \
-do { \
- *(DSTPTR)++ = (Y); \
- *(DSTPTR)++ = (Y)>>22; \
- *(DSTPTR)++ = (Y)>>11; \
- *(DSTPTR)++ = 255; \
-} while (0 == 1)
-
static void yuv444_2_rgb8888(uint8_t *dst_ptr,
const uint8_t *y_ptr,
const uint8_t *u_ptr,
@@ -1067,8 +1018,7 @@ static void yuv444_2_rgb8888(uint8_t *dst_ptr,
int32_t height,
int32_t y_span,
int32_t uv_span,
- int32_t dst_span,
- int32_t dither)
+ int32_t dst_span)
{
height -= 1;
while (height > 0)
@@ -1143,4 +1093,11 @@ static void yuv444_2_rgb8888(uint8_t *dst_ptr,
height -= 1;
}
}
+
+#undef FLAGS
+#undef READUV
+#undef READY
+#undef FIXUP
+#undef STORE
+
#endif // YUV2RGB_H