diff options
-rw-r--r-- | modules/theora/video_stream_theora.cpp | 6 | ||||
-rw-r--r-- | modules/webm/video_stream_webm.cpp | 27 | ||||
-rw-r--r-- | thirdparty/README.md | 11 | ||||
-rw-r--r-- | thirdparty/libsimplewebm/OpusVorbisDecoder.cpp | 2 | ||||
-rw-r--r-- | thirdparty/libsimplewebm/OpusVorbisDecoder.hpp | 4 | ||||
-rw-r--r-- | thirdparty/libsimplewebm/VPXDecoder.cpp | 14 | ||||
-rw-r--r-- | thirdparty/libsimplewebm/VPXDecoder.hpp | 6 | ||||
-rw-r--r-- | thirdparty/misc/yuv2rgb.h | 121 |
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 |