xoreos  0.0.5
xmvwmv2.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 /* Based on the WMV2 implementation in FFmpeg (<https://ffmpeg.org/)>,
26  * which is released under the terms of version 2 or later of the GNU
27  * Lesser General Public License.
28  *
29  * The original copyright notes in the file libavcodec/wmv2dec.c reads as follows:
30  *
31  * Copyright (c) 2002 The FFmpeg Project
32  *
33  * This file is part of FFmpeg.
34  *
35  * FFmpeg is free software; you can redistribute it and/or
36  * modify it under the terms of the GNU Lesser General Public
37  * License as published by the Free Software Foundation; either
38  * version 2.1 of the License, or (at your option) any later version.
39  *
40  * FFmpeg is distributed in the hope that it will be useful,
41  * but WITHOUT ANY WARRANTY; without even the implied warranty of
42  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
43  * Lesser General Public License for more details.
44  *
45  * You should have received a copy of the GNU Lesser General Public
46  * License along with FFmpeg; if not, write to the Free Software
47  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
48  */
49 
50 #include <cassert>
51 #include <cstring>
52 
53 #include "src/common/util.h"
54 #include "src/common/error.h"
55 #include "src/common/readstream.h"
56 #include "src/common/bitstream.h"
57 #include "src/common/huffman.h"
58 
60 
62 
65 
66 // Disable the "unused variable" warnings while most stuff is still stubbed
68 
69 namespace Video {
70 
71 static const uint32 kEscapeCodeLuma = 119;
72 static const uint32 kEscapeCodeChroma = 119;
73 
74 static const uint8 kSkipTypeNone = 0;
75 static const uint8 kSkipTypeMPEG = 1;
76 static const uint8 kSkipTypeRow = 2;
77 static const uint8 kSkipTypeCol = 3;
78 
79 
81  decode(cbp);
82 }
83 
85  _cbp = 0;
86 }
87 
89  return _cbp == 0;
90 }
91 
92 bool XMVWMV2Codec::CBP::isSet(int block) const {
93  assert((block >= 0) && (block < 6));
94 
95  return (_cbp & (1 << (5 - block))) != 0;
96 }
97 
98 void XMVWMV2Codec::CBP::set(int block, bool coded) {
99  _cbp &= ~( 1 << (5 - block));
100  _cbp |= coded << (5 - block);
101 }
102 
104  _cbp = cbp & 0x3F;
105 }
106 
107 void XMVWMV2Codec::CBP::decode(uint32 cbp, const CBP &topLeft, const CBP &top,
108  const CBP &left) {
109  const CBP x(cbp);
110 
111  set(0, ((topLeft.isSet(3) == top.isSet(2)) ? left.isSet(1) : top.isSet(2)) ^ x.isSet(0));
112  set(1, ((top .isSet(2) == top.isSet(3)) ? isSet(0) : top.isSet(3)) ^ x.isSet(1));
113  set(2, ((left .isSet(1) == isSet(0)) ? left.isSet(3) : isSet(0)) ^ x.isSet(2));
114  set(3, (( isSet(0) == isSet(1)) ? isSet(2) : isSet(1)) ^ x.isSet(3));
115  set(4, x.isSet(4));
116  set(5, x.isSet(5));
117 }
118 
119 
121  hasACPerMacroBlock(false), hasACPrediction(false),
122  acRLERunLength(0), acRLELevelLength(0) {
123 
124  decoderAC[0] = decoderAC[1] = 0;
125  huffDC [0] = huffDC [1] = 0;
126 
127  for (int i = 0; i < 4; i++) {
128  block[i].acQuantLeft = acQuantLeft[i >> 1];
129 
130  block[i].dcTopLeft = &dcTopLeft[i >> 1];
131 
132  block[i].decoderAC = &decoderAC[0];
133  block[i].huffDC = &huffDC [0];
134 
136 
137  block[i].hasACCoeffs = false;
138  }
139 
140  for (int i = 4; i < 6; i++) {
141  block[i].acQuantLeft = acQuantLeft[i - 2];
142 
143  block[i].dcTopLeft = &dcTopLeft[i - 2];
144 
145  block[i].decoderAC = &decoderAC[1];
146  block[i].huffDC = &huffDC [1];
147 
149 
150  block[i].hasACCoeffs = false;
151  }
152 }
153 
155  qScale = qS;
156 
157  dcStepSize = 8;
158  if (qScale > 4)
159  dcStepSize = qScale / 2 + 6;
160 
161  defaultPredictor = (1024 + (dcStepSize / 2)) / dcStepSize;
162 
163  if (acQuantTop[0] && acQuantTop[1] && acQuantTop[2]) {
164  std::memset(acQuantTop[0], 0, sizeof(int32) * block[0].planePitch);
165  std::memset(acQuantTop[1], 0, sizeof(int32) * block[4].planePitch);
166  std::memset(acQuantTop[2], 0, sizeof(int32) * block[5].planePitch);
167 
168  for (uint32 x = 0; x < (block[0].planePitch / block[0].blockPitch); x++) {
169  acQuantTop[0][x * block[0].blockPitch + block[4].blockPitch] = defaultPredictor;
170  acQuantTop[0][x * block[0].blockPitch ] = defaultPredictor;
171 
172  acQuantTop[1][x * block[4].blockPitch] = defaultPredictor;
173  acQuantTop[2][x * block[5].blockPitch] = defaultPredictor;
174  }
175  }
176 }
177 
179  for (int i = 0; i < 4; i++)
180  block[i].acQuantTop = acQuantTop[0] + kBlockSize * (i & 1);
181 
182  for (int i = 4; i < 6; i++)
183  block[i].acQuantTop = acQuantTop[i - 3];
184 
185  std::memset(acQuantLeft, 0, sizeof(int32) * kBlockSize * 4);
186 
187  acQuantLeft[0][0] = defaultPredictor;
188  acQuantLeft[1][0] = defaultPredictor;
189  acQuantLeft[2][0] = defaultPredictor;
190  acQuantLeft[3][0] = defaultPredictor;
191 
192  dcTopLeft[0] = defaultPredictor;
193  dcTopLeft[1] = 0;
194  dcTopLeft[2] = defaultPredictor;
195  dcTopLeft[3] = defaultPredictor;
196 
197  curCBP = rowCBP;
198 
199  cbpTopLeft.clear();
200 }
201 
203  for (int i = 0; i < 6; i++) {
204  block[i].refPlane += block[i].planePitch * (block[i].blockPitch - 1);
205  block[i].curPlane += block[i].planePitch * (block[i].blockPitch - 1);
206  }
207 }
208 
210  cbpTop = curCBP[0];
211 
212  curCBP[0].decode(cbp, cbpTopLeft, cbpTop, curCBP[-1]);
213 
214  cbpTopLeft = cbpTop;
215 }
216 
218  for (int i = 0; i < 6; i++) {
219  block[i].refPlane += block[i].blockPitch;
220  block[i].curPlane += block[i].blockPitch;
221  block[i].acQuantTop += block[i].blockPitch;
222  }
223 
224  curCBP++;
225 }
226 
227 
229  Common::SeekableReadStream &extraData) :
230  _width(width), _height(height), _currentFrame(0) {
231 
232  init();
233 
234  parseExtraData(extraData);
235 }
236 
238 }
239 
241  // Dimensions
244 
247 
248  _chromaWidth = _lumaWidth / 2;
250 
251 
252  // Color planes
259 
260  std::memset(_curPlanes[0].get(), 0, _lumaWidth * _lumaHeight );
261  std::memset(_curPlanes[1].get(), 0, _chromaWidth * _chromaHeight);
262  std::memset(_curPlanes[2].get(), 0, _chromaWidth * _chromaHeight);
263  std::memset(_oldPlanes[0].get(), 0, _lumaWidth * _lumaHeight );
264  std::memset(_oldPlanes[1].get(), 0, _chromaWidth * _chromaHeight);
265  std::memset(_oldPlanes[2].get(), 0, _chromaWidth * _chromaHeight);
266 
267 
268  // Coded block pattern
269  _cbp.reset(new CBP[_mbCountWidth + 1]); // +1 border for the start of the row
270 
275 
276 
277  // DC Huffman decoders
278  _huffDC[0][0].reset(new Common::Huffman(wmv2HuffmanDC[0][0]));
279  _huffDC[0][1].reset(new Common::Huffman(wmv2HuffmanDC[0][1]));
280  _huffDC[1][0].reset(new Common::Huffman(wmv2HuffmanDC[1][0]));
281  _huffDC[1][1].reset(new Common::Huffman(wmv2HuffmanDC[1][1]));
282 
283 
284  // AC predictors
285  _predAC[0].reset(new int32[_lumaWidth]);
286  _predAC[1].reset(new int32[_chromaWidth]);
287  _predAC[2].reset(new int32[_chromaWidth]);
288 
289 
290  // AC decoders
291  for (int i = 0; i < 2; i++) {
292  for (int j = 0; j < 3; j++) {
293  const WMV2ACCoefficientTable *params = &wmv2AC[i][j];
294 
295  _decoderAC[i][j].parameters = params;
296  _decoderAC[i][j].huffman.reset(new Common::Huffman(params->huffman));
297  }
298  }
299 
300  // Motion vectors
301  for (int i = 0; i < 2; i++) {
302  const WMV2MVTable *params = &wmv2MV[i];
303 
304  _decoderMV[i].parameters = params;
306  }
307 }
308 
310  Common::SeekableReadStream &dataStream) {
311 
312  Common::BitStream32LEMSB bits(dataStream);
313  DecodeContext ctx(bits);
314 
315  initDecodeContext(ctx);
316 
317  // Is this a P-frame?
318  bool isPFrame = ctx.bits.getBit() != 0;
319 
320  // "buffer-fullness", apparently not needed
321  if (!isPFrame)
322  ctx.bits.skip(7);
323 
324  // Quantizer scale
325  int32 qScale = ctx.bits.getBits(5);
326 
327  ctx.setQScale(qScale);
328 
329  // Is this a J-Frame?
330  bool isJFrame = false;
331  if (!isPFrame && _hasJFrames)
332  isJFrame = ctx.bits.getBit() != 0;
333 
334  // Decode the frame
335  if ( isJFrame)
336  decodeJFrame(ctx);
337  else if (!isPFrame)
338  decodeIFrame(ctx);
339  else
340  decodePFrame(ctx);
341 
342  // Convert the YUV data we have to BGRA
344  surface.getData(), surface.getWidth() * 4,
345  _curPlanes[0].get(), _curPlanes[1].get(), _curPlanes[2].get(),
347 
348  // And swap the planes with the reference planes
349  for (int i = 0; i < 3; i++)
350  _oldPlanes[i].swap(_curPlanes[i]);
351 
352  _currentFrame++;
353 }
354 
356  if (extraData.size() < 4)
357  throw Common::Exception("XMVWMV2Codec::parseExtraData(): Extra data too small");
358 
359  uint32 data = extraData.readUint32LE();
360 
361  // Read the various decoder flags
362 
363  _hasMixedPelMC = ( data & 1) != 0;
364  _hasLoopFilter = ((data >> 1) & 1) != 0;
365  _hasVarSizeTrans = ((data >> 2) & 1) != 0;
366  _hasJFrames = ((data >> 3) & 1) != 0;
367  _hasHybridMV = ((data >> 4) & 1) != 0;
368  _hasACPerMacroBlock = ((data >> 5) & 1) != 0;
369 
370  // Not used in I-Frames
371  _sliceCount = (data >> 6) & 7;
372  if (_sliceCount == 0)
373  throw Common::Exception("XMVWMV2Codec::parseExtraData(): _sliceCount == 0");
374 
375  // Yet unsupported features
376  if (_hasLoopFilter)
377  warning("TODO: XMVWMV2 Loop filter");
378 }
379 
381  ctx.acQuantTop[0] = _predAC[0].get();
382  ctx.acQuantTop[1] = _predAC[1].get();
383  ctx.acQuantTop[2] = _predAC[2].get();
384 
385  for (int i = 0; i < 4; i++) {
386  const uint32 offset = kBlockSize * (i & 1) + kBlockSize * _lumaWidth * (i >> 1);
387 
388  ctx.block[i].refPlane = _oldPlanes[0].get() + offset;
389  ctx.block[i].curPlane = _curPlanes[0].get() + offset;
390 
391  ctx.block[i].planePitch = _lumaWidth;
393  }
394 
395  for (int i = 4; i < 6; i++) {
396  ctx.block[i].refPlane = _oldPlanes[i - 3].get();
397  ctx.block[i].curPlane = _curPlanes[i - 3].get();
398 
399  ctx.block[i].planePitch = _chromaWidth;
400  ctx.block[i].blockPitch = kBlockSize;
401  }
402 
403  for (size_t i = 0; i < (_mbCountWidth + 1); i++)
404  _cbp[i].clear();
405 
406  ctx.rowCBP = _cbp.get() + 1;
407 }
408 
410  // Coefficients decoders
411 
412  // Do we have the AC Huffman table indices per macro block?
414  ctx.hasACPerMacroBlock = ctx.bits.getBit() != 0;
415 
416  // If not, read them now
417  if (!ctx.hasACPerMacroBlock) {
418  ctx.decoderAC[1] = &_decoderAC[1][getTrit(ctx.bits)];
419  ctx.decoderAC[0] = &_decoderAC[0][getTrit(ctx.bits)];
420  }
421 
422  // DC Huffman table index
423  uint8 dcTableIndex = ctx.bits.getBit();
424 
425  ctx.huffDC[0] = _huffDC[0][dcTableIndex].get();
426  ctx.huffDC[1] = _huffDC[1][dcTableIndex].get();
427 
428 
429  // Decode the macro blocks, row-major order
430  for (uint32 y = 0; y < _mbCountHeight; y++) {
431 
432  ctx.startRow();
433 
434  // Decode all macro blocks on the current row
435  for (uint32 x = 0; x < _mbCountWidth; x++) {
436 
437  // CBP
438 
439  uint32 cbp = _huffCBP[0]->getSymbol(ctx.bits);
440 
441  ctx.startMacroBlock(cbp);
442 
443  // AC Coefficients
444 
445  ctx.hasACPrediction = ctx.bits.getBit() != 0;
446 
447  // Read the AC Huffman table indices for this macro block
448  if (ctx.hasACPerMacroBlock && !ctx.curCBP[0].empty()) {
449  uint32 index = getTrit(ctx.bits);
450 
451  ctx.decoderAC[0] = &_decoderAC[0][index];
452  ctx.decoderAC[1] = &_decoderAC[1][index];
453  }
454 
455  // Decode this macro block
456  decodeIMacroBlock(ctx);
457 
458  ctx.finishMacroBlock();
459  }
460 
461  ctx.finishRow();
462  }
463 
464 
465  // Loop filter
466  if (_hasLoopFilter) {
467  // TODO: Loop filter
468  }
469 }
470 
472  warning("XMV: J-Frame %d", _currentFrame);
473 
474  // Just copy the reference planes for now
475  std::memcpy(_curPlanes[0].get(), _oldPlanes[0].get(), _lumaWidth * _lumaHeight );
476  std::memcpy(_curPlanes[1].get(), _oldPlanes[1].get(), _chromaWidth * _chromaHeight);
477  std::memcpy(_curPlanes[2].get(), _oldPlanes[2].get(), _chromaWidth * _chromaHeight);
478 }
479 
481  // Just copy the reference planes for now
482  std::memcpy(_curPlanes[0].get(), _oldPlanes[0].get(), _lumaWidth * _lumaHeight );
483  std::memcpy(_curPlanes[1].get(), _oldPlanes[1].get(), _chromaWidth * _chromaHeight);
484  std::memcpy(_curPlanes[2].get(), _oldPlanes[2].get(), _chromaWidth * _chromaHeight);
485 }
486 
488  int32 dcTopLeftNext = ctx.block[1].acQuantTop[0];
489 
490  *ctx.block[3].dcTopLeft = ctx.block[0].acQuantLeft[0];
491 
492  for (int i = 0; i < 6; i++) {
493  BlockContext &block = ctx.block[i];
494 
495  block.hasACCoeffs = ctx.curCBP[0].isSet(i);
496 
497  int32 dcTop = block.acQuantTop[0];
498 
499  decodeIBlock(ctx, block);
500 
501  *block.dcTopLeft = dcTop;
502  }
503 
504  *ctx.block[0].dcTopLeft = dcTopLeftNext;
505 }
506 
508  // Check which predictor we're using
509  bool isPredictedLeft = abs(*block.dcTopLeft - block.acQuantTop [0]) <=
510  abs(*block.dcTopLeft - block.acQuantLeft[0]);
511  int32 dcPredictor = isPredictedLeft ? block.acQuantLeft[0] : block.acQuantTop[0];
512 
513  // Decode the DC differential
514  int32 dcDiff = (*block.huffDC)->getSymbol(ctx.bits);
515  assert(dcDiff >= 0);
516 
517  if (((uint32) dcDiff) == block.dcEscapeCode) {
518  // Escaped value, directly encoded
519 
520  dcDiff = ctx.bits.getBits(8);
521  if (dcDiff == 0)
522  throw Common::Exception("XMVWMV2Codec::decodeIBlock(): Broken DC Magnitude");
523  }
524 
525  // Read the DC diff sign
526  if (dcDiff && ctx.bits.getBit())
527  dcDiff = -dcDiff;
528 
529  // Init AC coefficient prediction
530  const uint8 *zigZag = 0;
531  if (ctx.hasACPrediction) {
532 
533  if (isPredictedLeft) {
534  std::memset(block.acQuantTop, 0, sizeof(int32) * kBlockSize);
535 
536  zigZag = wmv2ZigZagVertical;
537  } else {
538  std::memset(block.acQuantLeft, 0, sizeof(int32) * kBlockSize);
539 
540  zigZag = wmv2ZigZagHorizontal;
541  }
542 
543  } else {
544  std::memset(block.acQuantTop , 0, sizeof(int32) * kBlockSize);
545  std::memset(block.acQuantLeft, 0, sizeof(int32) * kBlockSize);
546 
547  zigZag = wmv2ZigZagNormal;
548  }
549 
550  int32 dcQuantCoeff = dcPredictor + dcDiff;
551 
552  block.acQuantTop [0] = dcQuantCoeff;
553  block.acQuantLeft[0] = dcQuantCoeff;
554 
555  int32 acReconCoeffs[kBlockSize * kBlockSize];
556  std::memset(acReconCoeffs, 0, sizeof(acReconCoeffs));
557 
558  acReconCoeffs[0] = dcQuantCoeff * ctx.dcStepSize;
559 
560  int32 qScaleOdd = (ctx.qScale & 1) ? ctx.qScale : (ctx.qScale - 1);
561  int32 qScale2 = ctx.qScale * 2;
562 
563 
564  // Decode AC coefficients (using run level encoding)
565  if (block.hasACCoeffs) {
566  assert(block.decoderAC && *block.decoderAC);
567  assert((*block.decoderAC)->huffman && (*block.decoderAC)->parameters);
568 
569  Common::Huffman &acHuff = *(*block.decoderAC)->huffman;
570  const WMV2ACCoefficientTable &acTable = *(*block.decoderAC)->parameters;
571 
572  uint32 coeffCount = 1;
573 
574  bool done = false;
575  while (!done) {
576  uint32 run = 0;
577  int32 level = 0;
578 
579  // Read the run and level table index
580  uint32 index = acHuff.getSymbol(ctx.bits);
581  if (index > acTable.escapeCode)
582  throw Common::Exception("XMVWMV2Codec::decodeIBlock(): Broken AC index");
583 
584  // Read the run and level values, and determine if this is the last run
585  if (index != acTable.escapeCode) {
586  // Run and level from table
587 
588  run = acTable.runTable [index];
589  level = acTable.levelTable[index];
590 
591  done = index >= acTable.lastRunIndex;
592 
593  if (ctx.bits.getBit())
594  level = -level;
595 
596  } else if (ctx.bits.getBit()) {
597  // Escape + 1: run and level from table + level delta
598 
599  index = acHuff.getSymbol(ctx.bits);
600 
601  run = acTable.runTable [index];
602  level = acTable.levelTable[index];
603 
604  done = index >= acTable.lastRunIndex;
605 
606  if (done)
607  level += acTable.levelDeltaTableLast[run];
608  else
609  level += acTable.levelDeltaTable [run];
610 
611  if (ctx.bits.getBit())
612  level = -level;
613 
614  } else if (ctx.bits.getBit()) {
615  // Escape + 01: run and level from table + run delta
616 
617  index = acHuff.getSymbol(ctx.bits);
618 
619  run = acTable.runTable [index];
620  level = acTable.levelTable[index];
621 
622  done = index >= acTable.lastRunIndex;
623 
624  if (done)
625  run += acTable.runDeltaTableLast[level] + 1;
626  else
627  run += acTable.runDeltaTable [level] + 1;
628 
629  if (ctx.bits.getBit())
630  level = -level;
631 
632  } else {
633  // Escape + 00: run and level directly encoded
634 
635  done = ctx.bits.getBit() != 0;
636 
637  if (ctx.acRLERunLength == 0) {
638 
639  if (ctx.qScale >= 8) {
640  int length = 0;
641  bool end = false;
642 
643  while (length < 6 && !end) {
644  end = ctx.bits.getBit() != 0;
645  length++;
646  }
647 
648  ctx.acRLELevelLength = end ? (length + 1) : 8;
649 
650  } else {
651 
652  ctx.acRLELevelLength = ctx.bits.getBits(3);
653  if (!ctx.acRLELevelLength)
654  ctx.acRLELevelLength = 8 + ctx.bits.getBit();
655  }
656 
657  ctx.acRLERunLength = 3 + ctx.bits.getBits(2);
658  }
659 
660  bool levelSign;
661 
662  run = ctx.bits.getBits(ctx.acRLERunLength);
663  levelSign = ctx.bits.getBit() != 0;
664  level = ctx.bits.getBits(ctx.acRLELevelLength);
665 
666  if (levelSign)
667  level = -level;
668  }
669 
670  // Skip the run of 0s
671  coeffCount += run;
672  if (coeffCount >= (kBlockSize * kBlockSize))
673  throw Common::Exception("XMVWMV2Codec::parseExtraData(): "
674  "Overrun while deRLEing AC coefficients");
675 
676  // deZigZag the current coefficient position
677  uint32 coeffIndex = zigZag[coeffCount];
678 
679  if ((coeffIndex / kBlockSize) == 0) {
680  // This is the first row
681 
682  block.acQuantTop[coeffIndex] += level;
683 
684  } else if ((coeffIndex % kBlockSize) == 0) {
685  // This is the first column
686 
687  block.acQuantLeft[coeffIndex / kBlockSize] += level;
688 
689  } else {
690  // Not first row/column
691 
692  if (level > 0)
693  acReconCoeffs[coeffIndex] = qScale2 * level + qScaleOdd;
694  else
695  acReconCoeffs[coeffIndex] = qScale2 * level - qScaleOdd;
696  }
697 
698  coeffCount++;
699  }
700  }
701 
702  // deQuantize and propagate the first row and column
703  for (uint32 i = 1; i < kBlockSize; i++) {
704  int32 acQuantCoeff = block.acQuantLeft[i];
705 
706  if (acQuantCoeff == 0)
707  acReconCoeffs[i * kBlockSize] = 0;
708  else if (acQuantCoeff > 0)
709  acReconCoeffs[i * kBlockSize] = qScale2 * acQuantCoeff + qScaleOdd;
710  else
711  acReconCoeffs[i * kBlockSize] = qScale2 * acQuantCoeff - qScaleOdd;
712 
713  acQuantCoeff = block.acQuantTop[i];
714 
715  if (acQuantCoeff == 0)
716  acReconCoeffs[i] = 0;
717  else if (acQuantCoeff > 0)
718  acReconCoeffs[i] = qScale2 * acQuantCoeff + qScaleOdd;
719  else
720  acReconCoeffs[i] = qScale2 * acQuantCoeff - qScaleOdd;
721  }
722 
723  // And run the IDCT over the block
724  IDCTPut(block.curPlane, acReconCoeffs, block.planePitch);
725 }
726 
727 void XMVWMV2Codec::IDCTPut(byte *dest, int32 *block, uint32 pitch) {
728  IDCT(block);
729 
730  for (uint32 i = 0; i < 8; i++, dest += pitch, block += 8)
731  for (uint32 j = 0; j < 8; j++)
732  dest[j] = CLIP(block[j], 0, 255);
733 }
734 
735 void XMVWMV2Codec::IDCT(int32 *block) {
736  for (int i = 0; i < 64; i += 8)
737  IDCTRow(block + i);
738 
739  for (int i = 0; i < 8; i++)
740  IDCTCol(block + i);
741 }
742 
743 #define W0 2048
744 #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
745 #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
746 #define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
747 #define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
748 #define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
749 #define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
750 #define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
751 
753  // Step 1
754  int a1 = (W1 * b[1]) + (W7 * b[7]);
755  int a7 = (W7 * b[1]) - (W1 * b[7]);
756  int a5 = (W5 * b[5]) + (W3 * b[3]);
757  int a3 = (W3 * b[5]) - (W5 * b[3]);
758  int a2 = (W2 * b[2]) + (W6 * b[6]);
759  int a6 = (W6 * b[2]) - (W2 * b[6]);
760  int a0 = (W0 * b[0]) + (W0 * b[4]);
761  int a4 = (W0 * b[0]) - (W0 * b[4]);
762 
763  // Step 2
764  int s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8; // 1, 3, 5, 7,
765  int s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
766 
767  // Step 3
768  b[0] = (a0 + a2 + a1 + a5 + (1 << 7)) >> 8;
769  b[1] = (a4 + a6 + s1 + (1 << 7)) >> 8;
770  b[2] = (a4 - a6 + s2 + (1 << 7)) >> 8;
771  b[3] = (a0 - a2 + a7 + a3 + (1 << 7)) >> 8;
772  b[4] = (a0 - a2 - a7 - a3 + (1 << 7)) >> 8;
773  b[5] = (a4 - a6 - s2 + (1 << 7)) >> 8;
774  b[6] = (a4 + a6 - s1 + (1 << 7)) >> 8;
775  b[7] = (a0 + a2 - a1 - a5 + (1 << 7)) >> 8;
776 }
777 
779  // Step 1, with extended precision
780  int a1 = ((W1 * b[8 * 1]) + (W7 * b[8 * 7]) + 4) >> 3;
781  int a7 = ((W7 * b[8 * 1]) - (W1 * b[8 * 7]) + 4) >> 3;
782  int a5 = ((W5 * b[8 * 5]) + (W3 * b[8 * 3]) + 4) >> 3;
783  int a3 = ((W3 * b[8 * 5]) - (W5 * b[8 * 3]) + 4) >> 3;
784  int a2 = ((W2 * b[8 * 2]) + (W6 * b[8 * 6]) + 4) >> 3;
785  int a6 = ((W6 * b[8 * 2]) - (W2 * b[8 * 6]) + 4) >> 3;
786  int a0 = ((W0 * b[8 * 0]) + (W0 * b[8 * 4]) ) >> 3;
787  int a4 = ((W0 * b[8 * 0]) - (W0 * b[8 * 4]) ) >> 3;
788 
789  // Step 2
790  int s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8;
791  int s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
792 
793  // Step 3
794  b[8 * 0] = (a0 + a2 + a1 + a5 + (1 << 13)) >> 14;
795  b[8 * 1] = (a4 + a6 + s1 + (1 << 13)) >> 14;
796  b[8 * 2] = (a4 - a6 + s2 + (1 << 13)) >> 14;
797  b[8 * 3] = (a0 - a2 + a7 + a3 + (1 << 13)) >> 14;
798 
799  b[8 * 4] = (a0 - a2 - a7 - a3 + (1 << 13)) >> 14;
800  b[8 * 5] = (a4 - a6 - s2 + (1 << 13)) >> 14;
801  b[8 * 6] = (a4 + a6 - s1 + (1 << 13)) >> 14;
802  b[8 * 7] = (a0 + a2 - a1 - a5 + (1 << 13)) >> 14;
803 }
804 
806  // 0 -> 0; 10 -> 1; 11 -> 2
807 
808  uint8 n = bits.getBit();
809  if (n == 0)
810  return n;
811 
812  return bits.getBit() + 1;
813 }
814 
815 } // End of namespace Video
const uint8 * runDeltaTableLast
Table for run delta values, last run.
Definition: wmv2data.h:71
const WMV2ACCoefficientTable wmv2AC[2][3]
DCT AC cofficients [luma/chroma][low motion/high motion/MPEG4].
Definition: wmv2data.cpp:2364
const WMV2MVTable wmv2MV[2]
Motion vectors [low/high motion].
Definition: wmv2data.cpp:2450
void decodeIMacroBlock(DecodeContext &ctx)
Decode an I-Frame (intra frame) macro block.
Definition: xmvwmv2.cpp:487
const Common::HuffmanTable & huffman
Huffman decoder for the motion vectors.
Definition: wmv2data.h:84
static const uint8 kSkipTypeNone
Definition: xmvwmv2.cpp:74
byte * getData()
Definition: surface.cpp:61
Parameters for decoding the motion vectors.
Definition: wmv2data.h:80
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
Common::ScopedPtr< Common::Huffman > _huffDC[2][2]
Huffman code for DCT DC coefficients, [luma/chroma][low/high motion].
Definition: xmvwmv2.h:213
uint32 _lumaHeight
Height of the luma portion of a decoded frame.
Definition: xmvwmv2.h:181
Common::ScopedPtr< Common::Huffman > _huffCBP[4]
Huffman codes for coded block pattern.
Definition: xmvwmv2.h:208
Luminance values range from [0, 255].
Definition: yuv_to_rgb.h:42
bool _hasLoopFilter
Does the video use the loop filter?
Definition: xmvwmv2.h:197
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
uint32 _height
Height of a frame.
Definition: xmvwmv2.h:178
Common::Huffman * huffDC[2]
Definition: xmvwmv2.h:145
const Common::HuffmanTable wmv2HuffmanPMB[3]
P-Frame macroblock block pattern [high/mid/low rate].
Definition: wmv2data.cpp:2252
uint8_t uint8
Definition: types.h:200
void decodePFrame(DecodeContext &ctx)
Decode a P-Frame (inter frame).
Definition: xmvwmv2.cpp:480
Parameters for decoding the DCT AC coefficients.
Definition: wmv2data.h:59
bool isSet(int block) const
Definition: xmvwmv2.cpp:92
static const uint32 kMacroBlockSize
Size of a macro block.
Definition: xmvwmv2.h:76
const WMV2ACCoefficientTable * parameters
Definition: xmvwmv2.h:101
Which block pattern are coded?
Definition: xmvwmv2.h:80
uint32 _lumaWidth
Width of the luma portion of a decoded frame.
Definition: xmvwmv2.h:180
void initDecodeContext(DecodeContext &ctx)
Definition: xmvwmv2.cpp:380
static const uint32 kEscapeCodeChroma
Definition: xmvwmv2.cpp:72
#define W3
Definition: xmvwmv2.cpp:746
bool empty() const
Definition: xmvwmv2.cpp:88
#define IGNORE_UNUSED_VARIABLES
Definition: system.h:423
void set(int block, bool coded)
Definition: xmvwmv2.cpp:98
Common::ScopedPtr< Common::Huffman > huffman
Definition: xmvwmv2.h:106
Exception that provides a stack of explanations.
Definition: error.h:36
const Common::HuffmanTable wmv2HuffmanDC[2][2]
DCT DC coefficients [luma/chroma][low/high motion].
Definition: wmv2data.cpp:2208
bool _hasJFrames
Does the video have j-frames (IntraX8)?
Definition: xmvwmv2.h:199
#define W2
Definition: xmvwmv2.cpp:745
static uint8 getTrit(Common::BitStream &bits)
Decode a "tri-state".
Definition: xmvwmv2.cpp:805
static const uint8 kSkipTypeCol
Definition: xmvwmv2.cpp:77
uint32 getSymbol(BitStream &bits) const
Return the next symbol in the bitstream.
Definition: huffman.cpp:85
MVDecoder _decoderMV[2]
Huffman code for the motion vectors [low/high motion].
Definition: xmvwmv2.h:225
#define W6
Definition: xmvwmv2.cpp:749
Common::Huffman ** huffDC
Definition: xmvwmv2.h:121
Basic exceptions to throw.
int getWidth() const
Definition: surface.cpp:53
uint32 lastRunIndex
Index of the last run/level pair.
Definition: wmv2data.h:66
int32 acQuantLeft[4][kBlockSize]
Definition: xmvwmv2.h:140
#define UNUSED(x)
Definition: system.h:170
Common::BitStream & bits
Definition: xmvwmv2.h:133
Utility templates and functions.
void decodeIBlock(DecodeContext &ctx, BlockContext &block)
Decode an I-Frame (intra frame) block.
Definition: xmvwmv2.cpp:507
void setQScale(int32 qS)
Set the quantizer scale and calculate the DC step size and default predictor.
Definition: xmvwmv2.cpp:154
static const uint32 kEscapeCodeLuma
Definition: xmvwmv2.cpp:71
void IDCT(int32 *block)
Definition: xmvwmv2.cpp:735
void startMacroBlock(uint32 cbp)
Definition: xmvwmv2.cpp:209
Decode a Huffman&#39;d bitstream.
Definition: huffman.h:47
virtual uint32 getBit()=0
Read a bit from the bit stream.
Common::ScopedArray< int32 > _predAC[3]
AC predictors, previous row.
Definition: xmvwmv2.h:217
void decodeIFrame(DecodeContext &ctx)
Decode an I-Frame (intra frame).
Definition: xmvwmv2.cpp:409
const uint8 wmv2ZigZagNormal[64]
I-Frame coefficient zig-zag scantable, normal.
Definition: wmv2data.cpp:2159
uint32 _width
Width of a frame.
Definition: xmvwmv2.h:177
#define W1
Definition: xmvwmv2.cpp:744
const uint8 * levelDeltaTableLast
Table for level delta values, last level.
Definition: wmv2data.h:76
XMVWMV2Codec(uint32 width, uint32 height, Common::SeekableReadStream &extraData)
Definition: xmvwmv2.cpp:228
const uint8 * runDeltaTable
Table for run delta values.
Definition: wmv2data.h:70
Context for decoding a block.
Definition: xmvwmv2.h:111
CBP(uint32 cbp=0)
Definition: xmvwmv2.cpp:80
#define YUVToRGBMan
Definition: yuv_to_rgb.h:91
StackException Exception
Definition: error.h:59
Efficient YUV to RGB conversion.
void parseExtraData(Common::SeekableReadStream &extraData)
Parse the extra data containing video encoding properties.
Definition: xmvwmv2.cpp:355
const uint8 * levelDeltaTable
Table for level delta values.
Definition: wmv2data.h:75
void warning(const char *s,...)
Definition: util.cpp:33
virtual size_t size() const =0
Obtains the total size of the stream, measured in bytes.
const Common::HuffmanTable wmv2HuffmanIMB
I-Frame macroblock block pattern.
Definition: wmv2data.cpp:2199
Basic reading stream interfaces.
Common::ScopedArray< CBP > _cbp
Coded block pattern, previous row.
Definition: xmvwmv2.h:207
bool _hasACPerMacroBlock
Are the AC selected per macro block instead of per frame?
Definition: xmvwmv2.h:201
DecodeContext(Common::BitStream &b)
Definition: xmvwmv2.cpp:120
void decodeJFrame(DecodeContext &ctx)
Decode a J-Frame (intra X8 frame).
Definition: xmvwmv2.cpp:471
Common::ScopedArray< byte > _curPlanes[3]
The 3 color planes, YUV, current frame.
Definition: xmvwmv2.h:191
A bit stream.
ACDecoder _decoderAC[2][3]
Decoders for DCT AC coefficients [luma/chroma][low motion/high motion/MPEG4].
Definition: xmvwmv2.h:220
uint32 _mbCountWidth
Width of a frame in macro blocks.
Definition: xmvwmv2.h:186
#define W0
Definition: xmvwmv2.cpp:743
const Common::HuffmanTable & huffman
Huffman decoder for the AC coefficients.
Definition: wmv2data.h:61
void decode(uint32 cbp)
Definition: xmvwmv2.cpp:103
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
static const uint8 kSkipTypeMPEG
Definition: xmvwmv2.cpp:75
An image surface, in BGRA format.
Common::ScopedArray< byte > _oldPlanes[3]
The 3 color planes, YUV, last frame.
Definition: xmvwmv2.h:192
bool _hasVarSizeTrans
Does the video have variable sized transforms?
Definition: xmvwmv2.h:198
uint32 _chromaHeight
Height of the chroma portion of a decoded frame.
Definition: xmvwmv2.h:184
Decompressing Huffman codes.
virtual void skip(size_t n)=0
Skip the specified amount of bits.
bool _hasHybridMV
Does the video have hybrid motion vectors?
Definition: xmvwmv2.h:200
uint32_t uint32
Definition: types.h:204
void decodeFrame(Graphics::Surface &surface, Common::SeekableReadStream &dataStream)
Definition: xmvwmv2.cpp:309
#define W7
Definition: xmvwmv2.cpp:750
Context for decoding a frame.
Definition: xmvwmv2.h:132
const uint8 * levelTable
Table for level values.
Definition: wmv2data.h:74
void IDCTCol(int32 *b)
Definition: xmvwmv2.cpp:778
bool _hasMixedPelMC
Does the video have mixed pel motion compensation?
Definition: xmvwmv2.h:196
const uint8 wmv2ZigZagVertical[64]
I-Frame coefficient zig-zag scantable, vertical.
Definition: wmv2data.cpp:2147
virtual uint32 getBits(size_t n)=0
Read a multi-bit value from the bit stream.
uint32 _mbCountHeight
Height of a frame in macro blocks.
Definition: xmvwmv2.h:187
const WMV2MVTable * parameters
Definition: xmvwmv2.h:107
Static data used for decoding WMV2 videos.
A template implementing a bit stream for different data memory layouts.
Definition: bitstream.h:85
void IDCTRow(int32 *b)
Definition: xmvwmv2.cpp:752
#define W5
Definition: xmvwmv2.cpp:748
WMV2 video codec, XMV variant.
uint32 escapeCode
Escape code that signifies a special run level encoding.
Definition: wmv2data.h:63
T CLIP(T v, T amin, T amax)
Definition: util.h:72
static const uint32 kBlockSize
Size of a block.
Definition: xmvwmv2.h:77
void init()
Init the decoder.
Definition: xmvwmv2.cpp:240
static const uint8 kSkipTypeRow
Definition: xmvwmv2.cpp:76
uint32 _currentFrame
Definition: xmvwmv2.h:227
Interface for a seekable & readable data stream.
Definition: readstream.h:265
const uint8 * runTable
Table for run values.
Definition: wmv2data.h:69
Common::ScopedPtr< Common::Huffman > huffman
Definition: xmvwmv2.h:100
uint32 _chromaWidth
Width of the chroma portion of a decoded frame.
Definition: xmvwmv2.h:183
A bit stream.
Definition: bitstream.h:40
uint8 byte
Definition: types.h:209
void IDCTPut(byte *dest, int32 *block, uint32 pitch)
Definition: xmvwmv2.cpp:727
int32_t int32
Definition: types.h:203
uint8 _sliceCount
Number of slices per frame.
Definition: xmvwmv2.h:203
const uint8 wmv2ZigZagHorizontal[64]
I-Frame coefficient zig-zag scantable, horizontal.
Definition: wmv2data.cpp:2135