diff options
author | Paul Gilbert | 2016-09-10 09:00:24 -0400 |
---|---|---|
committer | Paul Gilbert | 2016-09-10 10:08:22 -0400 |
commit | 4e9933d3c99d6367b04f07d2bd7499f1de999b57 (patch) | |
tree | 896219bc6b6b78acaab54e70fa2664a91455b2c2 | |
parent | 0910e642a229d8f477f35943c6845f3b5a4dea42 (diff) | |
download | scummvm-rg350-4e9933d3c99d6367b04f07d2bd7499f1de999b57.tar.gz scummvm-rg350-4e9933d3c99d6367b04f07d2bd7499f1de999b57.tar.bz2 scummvm-rg350-4e9933d3c99d6367b04f07d2bd7499f1de999b57.zip |
IMAGE: Indeo4 decoder is now working
-rw-r--r-- | image/codecs/indeo/indeo.cpp | 68 | ||||
-rw-r--r-- | image/codecs/indeo/indeo.h | 46 |
2 files changed, 76 insertions, 38 deletions
diff --git a/image/codecs/indeo/indeo.cpp b/image/codecs/indeo/indeo.cpp index 31e8e9864a..d6fdfd189d 100644 --- a/image/codecs/indeo/indeo.cpp +++ b/image/codecs/indeo/indeo.cpp @@ -32,6 +32,7 @@ #include "image/codecs/indeo/indeo.h" #include "image/codecs/indeo/indeo_dsp.h" #include "image/codecs/indeo/mem.h" +#include "graphics/yuv_to_rgb.h" #include "common/system.h" #include "common/algorithm.h" #include "common/textconsole.h" @@ -410,8 +411,31 @@ void IVIPlaneDesc::ivi_free_buffers(IVIPlaneDesc *planes) { /*------------------------------------------------------------------------*/ AVFrame::AVFrame() { - Common::fill(&data[0], &data[AV_NUM_DATA_POINTERS], (uint8 *)nullptr); - Common::fill(&linesize[0], &linesize[AV_NUM_DATA_POINTERS], 0); + Common::fill(&_data[0], &_data[AV_NUM_DATA_POINTERS], (uint8 *)nullptr); + Common::fill(&_linesize[0], &_linesize[AV_NUM_DATA_POINTERS], 0); +} + +int AVFrame::ff_set_dimensions(uint16 width, uint16 height) { + _width = width; + _height = height; + _linesize[0] = _linesize[1] = _linesize[2] = width; + + return 0; +} + +int AVFrame::ff_get_buffer(int flags) { + av_frame_free(); + _data[0] = (uint8 *)av_mallocz(_width * _height); + _data[1] = (uint8 *)av_mallocz(_width * _height); + _data[2] = (uint8 *)av_mallocz(_width * _height); + + return 0; +} + +void AVFrame::av_frame_free() { + av_freep(&_data[0]); + av_freep(&_data[1]); + av_freep(&_data[2]); } /*------------------------------------------------------------------------*/ @@ -444,8 +468,10 @@ IVI45DecContext::IVI45DecContext() : gb(nullptr), frame_num(0), frame_type(0), IndeoDecoderBase::IndeoDecoderBase(uint16 width, uint16 height) : Codec() { _pixelFormat = g_system->getScreenFormat(); + assert(_pixelFormat.bytesPerPixel > 1); _surface = new Graphics::ManagedSurface(); _surface->create(width, height, _pixelFormat); + _surface->fillRect(Common::Rect(0, 0, width, height), 0); _ctx.b_ref_buf = 3; // buffer 2 is used for scalability mode } @@ -518,24 +544,25 @@ int IndeoDecoderBase::decodeIndeoFrame() { if (!is_nonnull_frame()) return 0; - result = ff_set_dimensions(_ctx.planes[0].width, _ctx.planes[0].height); + assert(_ctx.planes[0].width <= _surface->w && _ctx.planes[0].height <= _surface->h); + result = frame->ff_set_dimensions(_ctx.planes[0].width, _ctx.planes[0].height); if (result < 0) return result; - if ((result = ff_get_buffer(frame, 0)) < 0) + if ((result = frame->ff_get_buffer(0)) < 0) return result; if (_ctx.is_scalable) { if (_ctx.is_indeo4) - ff_ivi_recompose_haar(&_ctx.planes[0], frame->data[0], frame->linesize[0]); + ff_ivi_recompose_haar(&_ctx.planes[0], frame->_data[0], frame->_linesize[0]); else - ff_ivi_recompose53(&_ctx.planes[0], frame->data[0], frame->linesize[0]); + ff_ivi_recompose53(&_ctx.planes[0], frame->_data[0], frame->_linesize[0]); } else { - ivi_output_plane(&_ctx.planes[0], frame->data[0], frame->linesize[0]); + ivi_output_plane(&_ctx.planes[0], frame->_data[0], frame->_linesize[0]); } - ivi_output_plane(&_ctx.planes[2], frame->data[1], frame->linesize[1]); - ivi_output_plane(&_ctx.planes[1], frame->data[2], frame->linesize[2]); + ivi_output_plane(&_ctx.planes[2], frame->_data[1], frame->_linesize[1]); + ivi_output_plane(&_ctx.planes[1], frame->_data[2], frame->_linesize[2]); // If the bidirectional mode is enabled, next I and the following P // frame will be sent together. Unfortunately the approach below seems @@ -557,6 +584,15 @@ int IndeoDecoderBase::decodeIndeoFrame() { } } + // Merge the planes into the final surface + Graphics::Surface s = _surface->getSubArea(Common::Rect(0, 0, _surface->w, _surface->h)); + YUVToRGBMan.convert410(&s, Graphics::YUVToRGBManager::kScaleITU, + frame->_data[0], frame->_data[1], frame->_data[2], frame->_width, frame->_height, + frame->_width, frame->_width); + + // Free the now un-needed frame data + frame->av_frame_free(); + return 0; } @@ -667,20 +703,6 @@ int IndeoDecoderBase::decode_band(IVIBandDesc *band) { return result; } -int IndeoDecoderBase::ff_set_dimensions(uint16 width, uint16 height) { - if (_surface->w != width || _surface->h != height) - _surface->create(width, height); - - return 0; -} - -int IndeoDecoderBase::ff_get_buffer(AVFrame *frame, int flags) { - frame->data[0] = (uint8 *)_surface->getBasePtr(0, 0); - frame->linesize[0] = _surface->pitch; - - return 0; -} - void IndeoDecoderBase::ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8 *dst, const int dst_pitch) { int x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3; diff --git a/image/codecs/indeo/indeo.h b/image/codecs/indeo/indeo.h index cd6920d26c..d9801202b4 100644 --- a/image/codecs/indeo/indeo.h +++ b/image/codecs/indeo/indeo.h @@ -277,7 +277,12 @@ struct IVIPlaneDesc { }; struct AVFrame { -#define AV_NUM_DATA_POINTERS 8 + /** + * Dimensions + */ + int _width, _height; + +#define AV_NUM_DATA_POINTERS 3 /** * pointer to the picture/channel planes. * This might be different from the first allocated byte @@ -290,7 +295,7 @@ struct AVFrame { * NOTE: Except for hwaccel formats, pointers not needed by the format * MUST be set to NULL. */ - uint8 *data[AV_NUM_DATA_POINTERS]; + uint8 *_data[AV_NUM_DATA_POINTERS]; /** * For video, size in bytes of each picture line. @@ -307,9 +312,32 @@ struct AVFrame { * @note The linesize may be larger than the size of usable data -- there * may be extra padding present for performance reasons. */ - int linesize[AV_NUM_DATA_POINTERS]; + int _linesize[AV_NUM_DATA_POINTERS]; + /** + * Constructor + */ AVFrame(); + + /** + * Destructor + */ + ~AVFrame() { av_frame_free(); } + + /** + * Sets the frame dimensions + */ + int ff_set_dimensions(uint16 width, uint16 height); + + /** + * Get a buffer for a frame + */ + int ff_get_buffer(int flags); + + /** + * Frees any data loaded for the frame + */ + void av_frame_free(); }; struct IVI45DecContext { @@ -389,18 +417,6 @@ private: int decode_band(IVIBandDesc *band); /** - * Sets the frame dimensions - */ - int ff_set_dimensions(uint16 width, uint16 height); - - /** - * Get a buffer for a frame. This is a wrapper around - * AVCodecContext.get_buffer() and should be used instead calling get_buffer() - * directly. - */ - int ff_get_buffer(AVFrame *frame, int flags); - - /** * Haar wavelet recomposition filter for Indeo 4 * * @param[in] plane pointer to the descriptor of the plane being processed |