xoreos  0.0.5
h263.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <cstring>
26 
27 #include <xvid.h>
28 
29 #include "src/common/scopedptr.h"
30 #include "src/common/util.h"
31 #include "src/common/readstream.h"
32 #include "src/common/types.h"
33 
35 
37 
38 #include "src/video/codecs/codec.h"
39 #include "src/video/codecs/h263.h"
40 
41 namespace Video {
42 
43 namespace {
44 
45 class H263Codec : public Codec {
46 public:
47  H263Codec(uint32 width, uint32 height, Common::SeekableReadStream &extraData);
48  ~H263Codec();
49 
50  void decodeFrame(Graphics::Surface &surface, Common::SeekableReadStream &dataStream);
51 
52 private:
55 
56  void *_decHandle;
57 
61  void decodeInternal(Common::SeekableReadStream &dataStream, Graphics::Surface *surface = 0);
62 };
63 
64 H263Codec::H263Codec(uint32 width, uint32 height, Common::SeekableReadStream &extraData) : _width(width), _height(height) {
65  xvid_gbl_init_t xvid_gbl_init;
66  std::memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t));
67  xvid_gbl_init.version = XVID_VERSION;
68  xvid_gbl_init.debug = 0;//XVID_DEBUG_ERROR | XVID_DEBUG_HEADER | XVID_DEBUG_STARTCODE;
69  xvid_global(0, XVID_GBL_INIT, &xvid_gbl_init, 0);
70 
71  xvid_dec_create_t xvid_dec_create;
72  std::memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t));
73  xvid_dec_create.version = XVID_VERSION;
74  xvid_dec_create.width = width;
75  xvid_dec_create.height = height;
76 
77  int result = xvid_decore(0, XVID_DEC_CREATE, &xvid_dec_create, 0);
78  if (result != 0)
79  throw Common::Exception("H263Codec::H263Codec(): Failed to create the decore context: %d", result);
80 
81  _decHandle = xvid_dec_create.handle;
82 
83  // Run the first extra data through the frame decoder, but don't bother
84  // decoding to a surface.
85  extraData.seek(0);
86  decodeInternal(extraData);
87 }
88 
89 H263Codec::~H263Codec() {
90  xvid_decore(_decHandle, XVID_DEC_DESTROY, 0, 0);
91 }
92 
93 void H263Codec::decodeInternal(Common::SeekableReadStream &dataStream, Graphics::Surface *surface) {
94  // NOTE: When asking libxvidcore to decode the video into BGRA, it fills the alpha
95  // values with 0x00, rendering the output invisible (!).
96  // Since we, surprise, actually want to see the video, we would have to pass
97  // over the whole video data and fix-up the alpha values ourselves. Or
98  // alternatively do the YUV->BGRA conversion ourselves. We chose the latter.
99 
100  size_t dataSize = dataStream.size();
101  Common::ScopedArray<byte> data(new byte[dataSize]);
102  dataStream.read(data.get(), dataSize);
103 
104  xvid_dec_frame_t xvid_dec_frame;
105  std::memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t));
106  xvid_dec_frame.version = XVID_VERSION;
107  xvid_dec_frame.general = XVID_DEBLOCKY | XVID_DEBLOCKUV | XVID_DERINGY | XVID_DERINGUV;
108  xvid_dec_frame.bitstream = data.get();
109  xvid_dec_frame.length = dataSize;
110  xvid_dec_frame.output.csp = XVID_CSP_INTERNAL;
111 
112  xvid_dec_stats_t xvid_dec_stats;
113  std::memset(&xvid_dec_stats, 0, sizeof(xvid_dec_stats_t));
114  xvid_dec_stats.version = XVID_VERSION;
115 
116  int result = xvid_decore(_decHandle, XVID_DEC_DECODE, &xvid_dec_frame, &xvid_dec_stats);
117  if (result < 0)
118  throw Common::Exception("H263Codec::decodeFrame(): Failed to decode frame: %d", result);
119 
120  if (surface &&
121  xvid_dec_frame.output.plane[0] &&
122  xvid_dec_frame.output.plane[1] &&
123  xvid_dec_frame.output.plane[2])
125  surface->getData(), surface->getWidth() * 4,
126  static_cast<const byte *>(xvid_dec_frame.output.plane[0]),
127  static_cast<const byte *>(xvid_dec_frame.output.plane[1]),
128  static_cast<const byte *>(xvid_dec_frame.output.plane[2]), _width, _height,
129  xvid_dec_frame.output.stride[0], xvid_dec_frame.output.stride[1]);
130 }
131 
132 void H263Codec::decodeFrame(Graphics::Surface &surface, Common::SeekableReadStream &dataStream) {
133  decodeInternal(dataStream, &surface);
134 }
135 
136 } // End of anonymous namespace
137 
138 Codec *makeH263Codec(int width, int height, Common::SeekableReadStream &extraData) {
139  return new H263Codec(width, height, extraData);
140 }
141 
142 } // End of namespace Video
byte * getData()
Definition: surface.cpp:61
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
Video codec base class.
A simple scoped smart pointer template.
int getWidth() const
Definition: surface.cpp:53
Utility templates and functions.
h.263 video codec.
virtual size_t read(void *dataPtr, size_t dataSize)=0
Read data from the stream.
Low-level type definitions to handle fixed width types portably.
#define YUVToRGBMan
Definition: yuv_to_rgb.h:91
StackException Exception
Definition: error.h:59
Efficient YUV to RGB conversion.
virtual size_t size() const =0
Obtains the total size of the stream, measured in bytes.
Basic reading stream interfaces.
An image surface, in BGRA format.
uint32 _height
Definition: h263.cpp:54
uint32_t uint32
Definition: types.h:204
Codec * makeH263Codec(int width, int height, Common::SeekableReadStream &extraData)
Create a Codec capable of decoding h.263 frames.
Definition: h263.cpp:138
uint32 _width
Definition: h263.cpp:53
Interface for a seekable & readable data stream.
Definition: readstream.h:265
uint8 byte
Definition: types.h:209
void * _decHandle
Definition: h263.cpp:56