aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2016-09-10 09:00:24 -0400
committerPaul Gilbert2016-09-10 10:08:22 -0400
commit4e9933d3c99d6367b04f07d2bd7499f1de999b57 (patch)
tree896219bc6b6b78acaab54e70fa2664a91455b2c2
parent0910e642a229d8f477f35943c6845f3b5a4dea42 (diff)
downloadscummvm-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.cpp68
-rw-r--r--image/codecs/indeo/indeo.h46
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