diff options
Diffstat (limited to 'thirdparty/libsimplewebm/VPXDecoder.cpp')
-rw-r--r-- | thirdparty/libsimplewebm/VPXDecoder.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/thirdparty/libsimplewebm/VPXDecoder.cpp b/thirdparty/libsimplewebm/VPXDecoder.cpp new file mode 100644 index 0000000000..3f77b8f5cd --- /dev/null +++ b/thirdparty/libsimplewebm/VPXDecoder.cpp @@ -0,0 +1,142 @@ +/* + MIT License + + Copyright (c) 2016 Błażej Szczygieł + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include "VPXDecoder.hpp" + +#include <vpx/vpx_decoder.h> +#include <vpx/vp8dx.h> + +#include <stdlib.h> +#include <string.h> + +VPXDecoder::VPXDecoder(const WebMDemuxer &demuxer, unsigned threads) : + m_ctx(NULL), + m_iter(NULL), + m_delay(0) +{ + if (threads > 8) + threads = 8; + else if (threads < 1) + threads = 1; + + const vpx_codec_dec_cfg_t codecCfg = { + threads, + 0, + 0 + }; + vpx_codec_iface_t *codecIface = NULL; + + switch (demuxer.getVideoCodec()) + { + case WebMDemuxer::VIDEO_VP8: + codecIface = vpx_codec_vp8_dx(); + break; + case WebMDemuxer::VIDEO_VP9: + codecIface = vpx_codec_vp9_dx(); + m_delay = threads - 1; + break; + default: + return; + } + + m_ctx = new vpx_codec_ctx_t; + if (vpx_codec_dec_init(m_ctx, codecIface, &codecCfg, m_delay > 0 ? VPX_CODEC_USE_FRAME_THREADING : 0)) + { + delete m_ctx; + m_ctx = NULL; + } +} +VPXDecoder::~VPXDecoder() +{ + if (m_ctx) + { + vpx_codec_destroy(m_ctx); + delete m_ctx; + } +} + +bool VPXDecoder::decode(const WebMFrame &frame) +{ + m_iter = NULL; + return !vpx_codec_decode(m_ctx, frame.buffer, frame.bufferSize, NULL, 0); +} +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)) + { + 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]) + { + const int uPlane = !!(img->fmt & VPX_IMG_FMT_UV_FLIP) + 1; + const int vPlane = !(img->fmt & VPX_IMG_FMT_UV_FLIP) + 1; + + image.w = img->d_w; + image.h = img->d_h; + image.chromaShiftW = img->x_chroma_shift; + image.chromaShiftH = img->y_chroma_shift; + + image.planes[0] = img->planes[0]; + image.planes[1] = img->planes[uPlane]; + image.planes[2] = img->planes[vPlane]; + + image.linesize[0] = img->stride[0]; + image.linesize[1] = img->stride[uPlane]; + image.linesize[2] = img->stride[vPlane]; + + err = NO_ERROR; + } + } + else + { + err = UNSUPPORTED_FRAME; + } + } + return err; +} + +/**/ + +#if 0 + +static inline int ceilRshift(int val, int shift) +{ + return (val + (1 << shift) - 1) >> shift; +} + +int VPXDecoder::Image::getWidth(int plane) const +{ + if (!plane) + return w; + return ceilRshift(w, chromaShiftW); +} +int VPXDecoder::Image::getHeight(int plane) const +{ + if (!plane) + return h; + return ceilRshift(h, chromaShiftH); +} + +#endif |