Make movies use new plugin system.
[gemrb.git] / gemrb / plugins / BIKPlayer / BIKPlay.cpp
blob49717e3519ab1203f1a9bcdbc09c4e0fc26a8a72
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2009 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * $Id: BIKPlay.cpp 6168 2009-05-28 22:28:33Z mattinm $
23 * code derived from Bink Audio decoder
24 * Copyright (c) 2007-2009 Peter Ross (pross@xvid.org)
25 * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
27 * code derived from Bink video decoder
28 * Copyright (c) 2009 Konstantin Shishkov
31 #include <assert.h>
32 #include <fcntl.h>
33 #include <sys/stat.h>
34 #include <cstdio>
35 #include "../Core/Video.h"
36 #include "../Core/Audio.h"
37 #include "../Core/Variables.h"
38 #include "BIKPlay.h"
39 #include "../../includes/ie_types.h"
40 #include "rational.h"
41 #include "binkdata.h"
43 static Video *video = NULL;
44 static int g_truecolor;
45 static ieDword *cbAtFrame = NULL;
46 static ieDword *strRef = NULL;
48 static const int ff_wma_critical_freqs[25] = {
49 100, 200, 300, 400, 510, 630, 770, 920,
50 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150,
51 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500,
52 24500,
55 static uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, };
57 BIKPlay::BIKPlay(void)
59 int i;
61 video = core->GetVideoDriver();
62 inbuff = NULL;
63 maxRow = 0;
64 rowCount = 0;
65 frameCount = 0;
66 //force initialisation of static tables
67 memset(bink_trees, 0, sizeof(bink_trees));
68 memset(table, 0, sizeof(table));
70 for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i;
71 for(i=0;i<MAX_NEG_CROP;i++) {
72 ff_cropTbl[i] = 0;
73 ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
77 BIKPlay::~BIKPlay(void)
79 av_freep((void **) &inbuff);
82 void BIKPlay::av_set_pts_info(AVRational &time_base, unsigned int pts_num, unsigned int pts_den)
84 //pts_wrap_bits, if needed, is always 64
85 if(av_reduce(time_base.num, time_base.den, pts_num, pts_den, INT_MAX)) {
86 //bla bla, something didn't work
89 if(!time_base.num || !time_base.den)
90 time_base.num = time_base.den = 0;
93 int BIKPlay::ReadHeader()
95 str->Seek(0,GEM_STREAM_START);
96 str->Read( header.signature, BIK_SIGNATURE_LEN );
97 str->ReadDword(&header.filesize);
98 header.filesize += 8;
99 str->ReadDword(&header.framecount);
101 if (header.framecount > 1000000) {
102 return -1;
105 str->ReadDword(&header.maxframesize);
106 if (header.maxframesize > header.filesize) {
107 return -1;
110 str->Seek(4,GEM_CURRENT_POS);
112 str->ReadDword(&header.width);
113 str->ReadDword(&header.height);
115 ieDword fps_num, fps_den;
117 str->ReadDword(&fps_num);
118 str->ReadDword(&fps_den);
120 if (fps_num == 0 || fps_den == 0) {
121 //av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den);
122 return -1;
124 //also sets pts_wrap_bits to 64
125 av_set_pts_info(v_timebase, fps_den, fps_num);
127 str->Seek(4,GEM_CURRENT_POS);
128 str->ReadDword(&header.tracks);
130 //we handle only single tracks, is this a problem with multi language iwd2?
131 if (header.tracks > 1) {
132 return -1;
135 if (header.tracks) {
136 str->Seek(4 * header.tracks,GEM_CURRENT_POS);
137 //make sure we use one track, if more needed, rewrite this part
138 assert(header.tracks==1);
140 str->ReadWord(&header.samplerate);
141 //also sets pts_wrap_bits to 64
142 //av_set_pts_info(s_timebase, 1, header.samplerate); //unused, we simply use header.samplerate
143 str->ReadWord(&header.audioflag);
145 str->Seek(4 * header.tracks,GEM_CURRENT_POS);
148 /* build frame index table */
149 ieDword pos, next_pos;
150 int keyframe;
152 str->ReadDword(&pos);
153 keyframe = pos & 1;
154 pos &= ~1;
156 frames.reserve(header.framecount);
157 for (unsigned int i = 0; i < header.framecount; i++) {
158 if (i == header.framecount - 1) {
159 next_pos = header.filesize;
160 } else {
161 str->ReadDword(&next_pos);
163 if (next_pos <= pos) {
164 // av_log(s, AV_LOG_ERROR, "invalid frame index table\n");
165 return -1;
167 //offset, size, keyframe
168 binkframe frame;
170 //the order of instructions is important here!
171 frame.pos=pos;
172 frame.keyframe=keyframe;
173 pos = next_pos&~1;
174 keyframe = next_pos&1;
175 frame.size=pos-frame.pos;
176 //sanity hack, we might as well just go belly up and refuse playing
177 if (frame.size>header.maxframesize) {
178 frame.size = header.maxframesize;
181 frames.push_back(frame);
184 inbuff = (ieByte *) av_malloc(header.maxframesize);
185 if (!inbuff) {
186 return -2;
189 str->Seek(4, GEM_CURRENT_POS);
190 return 0;
193 bool BIKPlay::Open(DataStream* stream, bool autoFree)
195 validVideo = false;
196 if (!Resource::Open(stream, autoFree))
197 return false;
199 str->Read( &header.signature, BIK_SIGNATURE_LEN );
200 if (memcmp( header.signature, BIK_SIGNATURE_DATA, 4 ) == 0) {
201 validVideo = ReadHeader()==0;
202 return validVideo;
204 return false;
207 void BIKPlay::CallBackAtFrames(ieDword cnt, ieDword *arg, ieDword *arg2 )
209 maxRow = cnt;
210 frameCount = 0;
211 rowCount = 0;
212 cbAtFrame = arg;
213 strRef = arg2;
216 int BIKPlay::Play()
218 if (!validVideo) {
219 return 0;
221 //Start Movie Playback
222 frameCount = 0;
223 int ret = doPlay( );
225 EndAudio();
226 EndVideo();
227 av_freep((void **) &inbuff);
228 return ret;
231 //this code could be in the movieplayer parent class
232 void get_current_time(long &sec, long &usec) {
233 #ifdef _WIN32
234 DWORD time;
235 time = GetTickCount();
237 sec = time / 1000;
238 usec = (time % 1000) * 1000;
239 #else
240 struct timeval tv;
241 gettimeofday(&tv, NULL);
243 sec = tv.tv_sec;
244 usec = tv.tv_usec;
245 #endif
248 void BIKPlay::timer_start()
250 get_current_time(timer_last_sec, timer_last_usec);
253 void BIKPlay::timer_wait()
255 long sec, usec;
256 get_current_time(sec, usec);
258 while (sec > timer_last_sec) {
259 usec += 1000000;
260 timer_last_sec++;
263 //quick hack, we should rather use the rational time base as ffmpeg
264 frame_wait = v_timebase.num*1000000/v_timebase.den;
265 while (usec - timer_last_usec > (long)frame_wait) {
266 usec -= frame_wait;
267 video_frameskip++;
270 long to_sleep = frame_wait - (usec - timer_last_usec);
271 #ifdef _WIN32
272 Sleep(to_sleep / 1000);
273 #else
274 usleep(to_sleep);
275 #endif
277 timer_start();
280 bool BIKPlay::next_frame()
282 if (timer_last_sec) {
283 timer_wait();
285 if(frameCount>=header.framecount) {
286 return false;
288 binkframe frame = frames[frameCount++];
289 //frame.size = fileRead( frame.pos, inbuff, frame.size);
290 //ieDword audframesize = *(ieDword *) inbuff;
291 str->Seek(frame.pos, GEM_STREAM_START);
292 ieDword audframesize;
293 str->ReadDword(&audframesize);
294 frame.size = str->Read( inbuff, frame.size - 4 );
295 if (DecodeAudioFrame(inbuff, audframesize)) {
296 //buggy frame, we stop immediately
297 //return false;
299 if (DecodeVideoFrame(inbuff+audframesize, frame.size-audframesize)) {
300 //buggy frame, we stop immediately
301 return false;
303 if (!timer_last_sec) {
304 timer_start();
306 return true;
309 int BIKPlay::doPlay()
311 int done = 0;
313 //bink is always truecolor
314 g_truecolor = 1;
316 frame_wait = 0;
317 timer_last_sec = 0;
318 video_frameskip = 0;
320 if (sound_init( core->GetAudioDrv()->CanPlay())) {
321 //sound couldn't be initialized
322 return 1;
325 //last parameter is to enable YUV overlay
326 outputwidth = (int) header.width;
327 outputheight= (int) header.height;
328 video->InitMovieScreen(outputwidth,outputheight, true);
330 if (video_init(outputwidth,outputheight)) {
331 return 2;
334 while (!done && next_frame()) {
335 done = video->PollMovieEvents();
338 return 0;
341 unsigned int BIKPlay::fileRead(unsigned int pos, void* buf, unsigned int count)
343 str->Seek(pos, GEM_STREAM_START);
344 return str->Read( buf, count );
347 void BIKPlay::showFrame(unsigned char** buf, unsigned int *strides, unsigned int bufw,
348 unsigned int bufh, unsigned int w, unsigned int h, unsigned int dstx, unsigned int dsty)
350 ieDword titleref = 0;
352 if (cbAtFrame && strRef) {
353 frameCount ++;
354 if ((rowCount<maxRow) && (frameCount >= cbAtFrame[rowCount]) ) {
355 rowCount++;
357 //draw subtitle here
358 if (rowCount) {
359 titleref = strRef[rowCount-1];
362 video->showYUVFrame(buf,strides,bufw,bufh,w,h,dstx,dsty, titleref);
365 int BIKPlay::setAudioStream()
367 ieDword volume;
368 core->GetDictionary()->Lookup( "Volume Movie", volume) ;
369 int source = core->GetAudioDrv()->SetupNewStream(0, 0, 0, volume, false, false);
370 return source;
373 void BIKPlay::freeAudioStream(int stream)
375 if (stream > -1)
376 core->GetAudioDrv()->ReleaseStream(stream, true);
379 void BIKPlay::queueBuffer(int stream, unsigned short bits, int channels, short* memory, int size, int samplerate)
381 if (stream > -1)
382 core->GetAudioDrv()->QueueBuffer(stream, bits, channels, memory, size, samplerate);
387 * @file libavcodec/binkaudio.c
389 * Technical details here:
390 * http://wiki.multimedia.cx/index.php?title=Bink_Audio
393 int BIKPlay::sound_init(bool need_init)
395 int sample_rate = header.samplerate;
396 int sample_rate_half;
397 unsigned int i;
398 int frame_len_bits;
399 int ret;
401 if(need_init) {
402 s_stream = setAudioStream();
403 } else {
404 s_stream = -1;
405 return 0;
408 if(s_stream<0) {
409 return 0;
412 if(header.audioflag&BINK_AUD_STEREO) {
413 header.channels=2;
416 /* determine frame length */
417 if (sample_rate < 22050) {
418 frame_len_bits = 9;
419 } else if (sample_rate < 44100) {
420 frame_len_bits = 10;
421 } else {
422 frame_len_bits = 11;
424 //audio frame length
425 s_frame_len = 1 << frame_len_bits;
427 if (header.channels > MAX_CHANNELS) {
428 //av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
429 return -1;
432 if (header.audioflag&BINK_AUD_USEDCT) {
433 s_channels = header.channels;
434 } else {
435 // audio is already interleaved for the RDFT format variant
436 sample_rate *= header.channels;
437 s_frame_len *= header.channels;
438 s_channels = 1;
439 if (header.channels == 2)
440 frame_len_bits++;
443 s_overlap_len = s_frame_len / 16;
444 s_block_size = (s_frame_len - s_overlap_len) * s_channels;
445 sample_rate_half = (sample_rate + 1) / 2;
446 s_root = (float) (2.0 / sqrt((float) s_frame_len));
448 /* calculate number of bands */
449 for (s_num_bands = 1; s_num_bands < 25; s_num_bands++) {
450 if (sample_rate_half <= ff_wma_critical_freqs[s_num_bands - 1]) {
451 break;
455 s_bands = (unsigned int *) av_malloc((s_num_bands + 1) * sizeof(*s_bands));
456 if (!s_bands) {
457 return -2;
460 /* populate bands data */
461 s_bands[0] = 1;
462 for (i = 1; i < s_num_bands; i++)
463 s_bands[i] = ff_wma_critical_freqs[i - 1] * (s_frame_len / 2) / sample_rate_half;
464 s_bands[s_num_bands] = s_frame_len / 2;
466 s_first = 1;
468 for (i = 0; i < s_channels; i++)
469 s_coeffs_ptr[i] = s_coeffs + i * s_frame_len;
471 if (header.audioflag&BINK_AUD_USEDCT)
472 ret = ff_dct_init(&s_trans.dct, frame_len_bits, 0);
473 else
474 ret = ff_rdft_init(&s_trans.rdft, frame_len_bits, IRIDFT);
476 return ret;
479 void BIKPlay::ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){
480 int i,j;
481 int end;
483 st->scantable= src_scantable;
485 for(i=0; i<64; i++){
486 j = src_scantable[i];
487 st->permutated[i] = permutation[j];
490 end=-1;
491 for(i=0; i<64; i++){
492 j = st->permutated[i];
493 if(j>end) end=j;
494 st->raster_end[i]= end;
498 int BIKPlay::video_init(int w, int h)
500 int bw, bh, blocks;
501 int i;
503 if (!bink_trees[15].table) {
504 for (i = 0; i < 16; i++) {
505 const int maxbits = bink_tree_lens[i][15];
506 bink_trees[i].table = table + i*128;
507 bink_trees[i].table_allocated = 1 << maxbits;
508 bink_trees[i].init_vlc(maxbits, 16, bink_tree_lens[i], 1, 1,
509 bink_tree_bits[i], 1, 1, INIT_VLC_LE);
513 memset(&c_pic,0, sizeof(AVFrame));
514 memset(&c_last,0, sizeof(AVFrame));
516 if (w<(signed) header.width || h<(signed) header.height) {
517 //movie dimensions are higher than available screen
518 return 1;
521 //pixel format is PIX_FMT_YUV420P
522 //idct permutation is used in various optimisations,
523 //we go with the simplest (no permutation)
524 for(i=0;i<64;i++) {
525 c_idct_permutation[i]=i;
528 ff_init_scantable(c_idct_permutation, &c_scantable, bink_scan);
530 bw = (header.width + 7) >> 3;
531 bh = (header.height + 7) >> 3;
532 blocks = bw * bh;
534 for (i = 0; i < BINK_NB_SRC; i++) {
535 c_bundle[i].data = (uint8_t *) av_malloc(blocks * 64);
536 //not enough memory
537 if(!c_bundle[i].data) {
538 return 2;
540 c_bundle[i].data_end = (uint8_t *) c_bundle[i].data + blocks * 64;
543 return 0;
546 int BIKPlay::EndAudio()
548 freeAudioStream(s_stream);
549 av_freep((void **) &s_bands);
550 if (header.audioflag&BINK_AUD_USEDCT)
551 ff_dct_end(&s_trans.dct);
552 else
553 ff_rdft_end(&s_trans.rdft);
554 return 0;
557 static inline void release_buffer(AVFrame *p)
559 int i;
561 for(i=0;i<3;i++) {
562 av_freep((void **) &p->data[i]);
566 static inline void ff_fill_linesize(AVFrame *picture, int width)
568 memset(picture->linesize, 0, sizeof(picture->linesize));
569 int w2 = (width + (1 << 1) - 1) >> 1;
570 picture->linesize[0] = width;
571 picture->linesize[1] = w2;
572 picture->linesize[2] = w2;
575 static inline void get_buffer(AVFrame *p, int width, int height)
577 ff_fill_linesize(p, width);
578 for(int plane=0;plane<3;plane++) {
579 p->data[plane] = (uint8_t *) av_malloc(p->linesize[plane]*height);
583 int BIKPlay::EndVideo()
585 int i;
587 release_buffer(&c_pic);
588 release_buffer(&c_last);
589 for (i = 0; i < BINK_NB_SRC; i++) {
590 av_freep((void **) &c_bundle[i].data);
592 return 0;
594 static const uint8_t rle_length_tab[16] = {
595 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
598 const uint8_t ff_log2_tab[256]={
599 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
600 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
601 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
602 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
603 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
604 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
605 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
606 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
609 static inline int float_to_int16_one(const float *src){
610 float f = *src;
611 // clamp the values to the range of an int16.
612 if (f > 32767.0)
613 return 32767;
614 else if (f < -32768.0)
615 return -32768;
616 return (int32_t) (f);
619 static void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels){
620 int i;
621 if(channels==2) {
622 for(i=0; i<len; i++) {
623 dst[2*i] = float_to_int16_one(src[0]+i);
624 dst[2*i+1] = float_to_int16_one(src[1]+i);
626 return;
628 //one channel
629 for(i=0; i<len; i++) {
630 dst[i] = float_to_int16_one(src[0]+i);
635 * Decode Bink Audio block
636 * @param[out] out Output buffer (must contain s->block_size elements)
638 void BIKPlay::DecodeBlock(short *out)
640 unsigned int ch, i, j, k;
641 float q, quant[25];
642 int width, coeff;
644 if (header.audioflag&BINK_AUD_USEDCT) {
645 s_gb.skip_bits(2);
648 for (ch = 0; ch < s_channels; ch++) {
649 FFTSample *coeffs = s_coeffs_ptr[ch];
650 q = 0.0;
651 coeffs[0] = s_gb.get_float();
652 coeffs[1] = s_gb.get_float();
654 for (i = 0; i < s_num_bands; i++) {
655 int value = s_gb.get_bits(8);
656 quant[i] = (float) pow(10.0, FFMIN(value, 95) * 0.066399999);
659 // find band (k)
660 for (k = 0; s_bands[k] * 2 < 2; k++) {
661 q = quant[k];
664 // parse coefficients
665 i = 2;
666 while (i < s_frame_len) {
667 if (s_gb.get_bits(1)) {
668 j = i + rle_length_tab[s_gb.get_bits(4)] * 8;
669 } else {
670 j = i + 8;
673 if (j > s_frame_len)
674 j = s_frame_len;
676 width = s_gb.get_bits(4);
677 if (width == 0) {
678 memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
679 i = j;
680 while (s_bands[k] * 2 < i)
681 q = quant[k++];
682 } else {
683 while (i < j) {
684 if (s_bands[k] * 2 == i)
685 q = quant[k++];
686 coeff = s_gb.get_bits(width);
687 if (coeff) {
688 if (s_gb.get_bits(1))
689 coeffs[i] = -q * coeff;
690 else
691 coeffs[i] = q * coeff;
692 } else {
693 coeffs[i] = 0.0;
695 i++;
700 if (header.audioflag&BINK_AUD_USEDCT)
701 ff_dct_calc (&s_trans.dct, coeffs);
702 else
703 ff_rdft_calc(&s_trans.rdft, coeffs);
705 for (i = 0; i < s_frame_len; i++)
706 coeffs[i] *= s_root;
709 ff_float_to_int16_interleave_c(out, (const float **)s_coeffs_ptr, s_frame_len, s_channels);
711 if (!s_first) {
712 unsigned int count = s_overlap_len * s_channels;
713 int shift = av_log2(count);
714 for (i = 0; i < count; i++) {
715 out[i] = (s_previous[i] * (count - i) + out[i] * i) >> shift;
719 memcpy(s_previous, out + s_block_size, s_overlap_len * s_channels * sizeof(*out));
721 s_first = 0;
724 //audio samples
725 int BIKPlay::DecodeAudioFrame(void *data, int data_size)
727 int bits = data_size*8;
728 s_gb.init_get_bits((uint8_t *) data, bits);
730 unsigned int reported_size = s_gb.get_bits_long(32);
731 ieWordSigned *samples = (ieWordSigned *) calloc(reported_size+s_block_size,1);
732 if (!samples) {
733 return -1;
736 ieWordSigned *outbuf = samples;
737 ieWordSigned *samples_end = samples+reported_size/sizeof(ieWordSigned);
739 //s_block_size is in sample units
740 while (s_gb.get_bits_count() < bits && outbuf + s_block_size <= samples_end) {
741 DecodeBlock(outbuf);
742 outbuf += s_block_size;
743 s_gb.get_bits_align32();
746 unsigned int ret = (unsigned int) ((uint8_t*)outbuf - (uint8_t*)samples);
748 //sample format is signed 16 bit integers
749 //ret is a better value here as it provides almost perfect sound.
750 //Original ffmpeg code produces worse results with reported_size.
751 //Ideally ret == reported_size
752 queueBuffer(s_stream, 16, s_channels, samples, ret, header.samplerate);
754 free(samples);
755 return reported_size!=ret;
759 * Reads 8x8 block of DCT coefficients.
761 * @param gb context for reading bits
762 * @param block place for storing coefficients
763 * @param scan scan order table
764 * @return 0 for success, negative value in other cases
766 int BIKPlay::read_dct_coeffs(DCTELEM block[64], const uint8_t *scan)
768 int mode_list[128];
769 int i, t, mask, bits, ccoef, mode;
770 int list_start = 64, list_end = 64, list_pos;
772 mode_list[list_end++] = ( 4 << 2) | 0;
773 mode_list[list_end++] = (24 << 2) | 0;
774 mode_list[list_end++] = (44 << 2) | 0;
775 mode_list[list_end++] = ( 1 << 2) | 3;
776 mode_list[list_end++] = ( 2 << 2) | 3;
777 mode_list[list_end++] = ( 3 << 2) | 3;
779 bits = v_gb.get_bits(4) - 1;
780 for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) {
781 list_pos = list_start;
782 while (list_pos < list_end) {
783 if (!mode_list[list_pos] || !v_gb.get_bits(1)) {
784 list_pos++;
785 continue;
787 ccoef = mode_list[list_pos] >> 2;
788 mode = mode_list[list_pos] & 3;
789 switch (mode) {
790 case 0:
791 case 2:
792 if (!mode) {
793 mode_list[list_pos] = ((ccoef + 4) << 2) | 1;
794 } else {
795 mode_list[list_pos++] = 0;
797 for (i = 0; i < 4; i++, ccoef++) {
798 if (v_gb.get_bits(1)) {
799 mode_list[--list_start] = (ccoef << 2) | 3;
800 } else {
801 int t;
802 if (!bits) {
803 t = v_gb.get_bits(1) ? -1 : 1;
804 } else {
805 t = v_gb.get_bits(bits) | mask;
806 if (v_gb.get_bits(1)) {
807 t = -t;
810 block[scan[ccoef]] = t;
813 break;
814 case 1:
815 mode_list[list_pos] = (ccoef << 2) | 2;
816 for (i = 0; i < 3; i++) {
817 ccoef += 4;
818 mode_list[list_end++] = (ccoef << 2) | 2;
820 break;
821 case 3:
822 if (!bits) {
823 t = v_gb.get_bits(1) ? -1 : 1;
824 } else {
825 t = v_gb.get_bits(bits) | mask;
826 if (v_gb.get_bits(1))
827 t = -t;
829 block[scan[ccoef]] = t;
830 mode_list[list_pos++] = 0;
831 break;
836 return 0;
840 * Reads 8x8 block with residue after motion compensation.
842 * @param gb context for reading bits
843 * @param block place to store read data
844 * @param masks_count number of masks to decode
845 * @return 0 on success, negative value in other cases
847 int BIKPlay::read_residue(DCTELEM block[64], int masks_count)
849 int mode_list[128];
850 int i, mask, ccoef, mode;
851 int list_start = 64, list_end = 64, list_pos;
852 int nz_coeff[64];
853 int nz_coeff_count = 0;
855 mode_list[list_end++] = ( 4 << 2) | 0;
856 mode_list[list_end++] = (24 << 2) | 0;
857 mode_list[list_end++] = (44 << 2) | 0;
858 mode_list[list_end++] = ( 0 << 2) | 2;
860 for (mask = 1 << v_gb.get_bits(3); mask; mask >>= 1) {
861 for (i = 0; i < nz_coeff_count; i++) {
862 if (!v_gb.get_bits(1))
863 continue;
864 if (block[nz_coeff[i]] < 0)
865 block[nz_coeff[i]] -= mask;
866 else
867 block[nz_coeff[i]] += mask;
868 masks_count--;
869 if (masks_count < 0)
870 return 0;
872 list_pos = list_start;
873 while (list_pos < list_end) {
874 if (!mode_list[list_pos] || !v_gb.get_bits(1)) {
875 list_pos++;
876 continue;
878 ccoef = mode_list[list_pos] >> 2;
879 mode = mode_list[list_pos] & 3;
880 switch (mode) {
881 case 0:
882 case 2:
883 if (!mode) {
884 mode_list[list_pos] = ((ccoef + 4) << 2) | 1;
885 } else {
886 mode_list[list_pos++] = 0;
888 for (i = 0; i < 4; i++, ccoef++) {
889 if (v_gb.get_bits(1)) {
890 mode_list[--list_start] = (ccoef << 2) | 3;
891 } else {
892 nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
893 block[bink_scan[ccoef]] = v_gb.get_bits(1) ? -mask : mask;
894 masks_count--;
895 if (masks_count < 0) {
896 return 0;
900 break;
901 case 1:
902 mode_list[list_pos] = (ccoef << 2) | 2;
903 for (i = 0; i < 3; i++) {
904 ccoef += 4;
905 mode_list[list_end++] = (ccoef << 2) | 2;
907 break;
908 case 3:
909 nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
910 block[bink_scan[ccoef]] = v_gb.get_bits(1) ? -mask : mask;
911 mode_list[list_pos++] = 0;
912 masks_count--;
913 if (masks_count < 0)
914 return 0;
915 break;
920 return 0;
924 * Prepares bundle for decoding data.
926 * @param gb context for reading bits
927 * @param c decoder context
928 * @param bundle_num number of the bundle to initialize
930 void BIKPlay::read_bundle(int bundle_num)
932 int i;
934 if (bundle_num == BINK_SRC_COLORS) {
935 for (i = 0; i < 16; i++)
936 v_gb.read_tree(&c_col_high[i]);
937 c_col_lastval = 0;
939 if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC)
940 v_gb.read_tree(&c_bundle[bundle_num].tree);
941 c_bundle[bundle_num].cur_dec =
942 c_bundle[bundle_num].cur_ptr = c_bundle[bundle_num].data;
946 * Initializes length length in all bundles.
948 * @param c decoder context
949 * @param width plane width
950 * @param bw plane width in 8x8 blocks
952 void BIKPlay::init_lengths(int width, int bw)
954 c_bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1;
956 c_bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1;
958 c_bundle[BINK_SRC_COLORS].len = av_log2((width >> 3)*64 + 511) + 1;
960 c_bundle[BINK_SRC_INTRA_DC].len =
961 c_bundle[BINK_SRC_INTER_DC].len =
962 c_bundle[BINK_SRC_X_OFF].len =
963 c_bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1;
965 c_bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1;
967 c_bundle[BINK_SRC_RUN].len = av_log2((width >> 3)*48 + 511) + 1;
970 #define CHECK_READ_VAL(gb, b, t) \
971 if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \
972 return 0; \
973 t = gb.get_bits(b->len); \
974 if (!t) { \
975 b->cur_dec = NULL; \
976 return 0; \
979 int BIKPlay::get_vlc2(int16_t (*table)[2], int bits, int max_depth)
981 int code;
982 int n, index, nb_bits;
984 index= v_gb.peek_bits(bits);
985 code = table[index][0];
986 n = table[index][1];
988 if(max_depth > 1 && n < 0){
989 v_gb.skip_bits(bits);
991 nb_bits = -n;
993 index= v_gb.peek_bits(nb_bits) + code;
994 code = table[index][0];
995 n = table[index][1];
996 if(max_depth > 2 && n < 0){
997 v_gb.skip_bits(nb_bits);
999 nb_bits = -n;
1001 index= v_gb.get_bits(nb_bits) + code;
1002 code = table[index][0];
1003 n = table[index][1];
1006 v_gb.skip_bits(n);
1007 return code;
1010 #define GET_HUFF(tree) \
1011 (tree).syms[get_vlc2(bink_trees[(tree).vlc_num].table, \
1012 bink_trees[(tree).vlc_num].bits, 1)]
1014 int BIKPlay::read_runs(Bundle *b)
1016 int i, t, v;
1018 CHECK_READ_VAL(v_gb, b, t);
1019 if (v_gb.get_bits(1)) {
1020 v = v_gb.get_bits(4);
1021 if (b->cur_dec + t > b->data_end) {
1022 return -1;
1024 memset(b->cur_dec, v, t);
1025 b->cur_dec += t;
1026 } else {
1027 for (i = 0; i < t; i++) {
1028 v = GET_HUFF(b->tree);
1029 *b->cur_dec++ = v;
1032 return 0;
1035 int BIKPlay::read_motion_values(Bundle *b)
1037 int i, t, v;
1039 CHECK_READ_VAL(v_gb, b, t);
1040 if (v_gb.get_bits(1)) {
1041 v = v_gb.get_bits(4);
1042 if (v && v_gb.get_bits(1)) {
1043 v = -v;
1045 if (b->cur_dec + t > b->data_end) {
1046 return -1;
1048 memset(b->cur_dec, v, t);
1049 b->cur_dec += t;
1050 } else {
1051 for (i = 0; i < t; i++) {
1052 v = GET_HUFF(b->tree);
1053 if (v && v_gb.get_bits(1)) {
1054 v = -v;
1056 *b->cur_dec++ = v;
1059 return 0;
1062 const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 };
1064 int BIKPlay::read_block_types(Bundle *b)
1066 int i, t, v;
1067 int last = 0;
1069 CHECK_READ_VAL(v_gb, b, t);
1070 if (v_gb.get_bits(1)) {
1071 v = v_gb.get_bits(4);
1072 memset(b->cur_dec, v, t);
1073 b->cur_dec += t;
1074 } else {
1075 for (i = 0; i < t; i++) {
1076 v = GET_HUFF(b->tree);
1077 if (v < 12) {
1078 last = v;
1079 *b->cur_dec++ = v;
1080 } else {
1081 int run = bink_rlelens[v - 12];
1083 memset(b->cur_dec, last, run);
1084 b->cur_dec += run;
1085 i += run - 1;
1089 return 0;
1092 int BIKPlay::read_patterns(Bundle *b)
1094 int i, t, v;
1096 CHECK_READ_VAL(v_gb, b, t);
1097 for (i = 0; i < t; i++) {
1098 v = GET_HUFF(b->tree);
1099 v |= GET_HUFF(b->tree) << 4;
1100 *b->cur_dec++ = v;
1103 return 0;
1106 int BIKPlay::read_colors(Bundle *b)
1108 int i, t, v, v2;
1110 CHECK_READ_VAL(v_gb, b, t);
1111 if (v_gb.get_bits(1)) {
1112 v2 = GET_HUFF(c_col_high[c_col_lastval]);
1113 c_col_lastval = v2;
1114 v = GET_HUFF(b->tree);
1115 v = (v2 << 4) | v;
1116 memset(b->cur_dec, v, t);
1117 b->cur_dec += t;
1118 } else {
1119 for (i = 0; i < t; i++) {
1120 v2 = GET_HUFF(c_col_high[c_col_lastval]);
1121 c_col_lastval = v2;
1122 v = GET_HUFF(b->tree);
1123 v = (v2 << 4) | v;
1124 *b->cur_dec++ = v;
1127 return 0;
1130 /** number of bits used to store first DC value in bundle */
1131 #define DC_START_BITS 11
1133 int BIKPlay::read_dcs(Bundle *b, int start_bits, int has_sign)
1135 int i, j, len, len2, bsize, v, v2;
1136 int16_t *dst = (int16_t*)b->cur_dec;
1138 CHECK_READ_VAL(v_gb, b, len);
1139 if (has_sign) {
1140 v = v_gb.get_bits(start_bits - 1);
1141 if (v && v_gb.get_bits(1))
1142 v = -v;
1143 } else {
1144 v = v_gb.get_bits(start_bits);
1146 *dst++ = v;
1147 len--;
1148 for (i = 0; i < len; i += 8) {
1149 len2 = FFMIN(len - i, 8);
1150 bsize = v_gb.get_bits(4);
1151 if (bsize) {
1152 for (j = 0; j < len2; j++) {
1153 v2 = v_gb.get_bits(bsize);
1154 if (v2 && v_gb.get_bits(1)) {
1155 v2 = -v2;
1157 v += v2;
1158 *dst++ = v;
1159 if (v < -32768 || v > 32767) {
1160 return -1;
1163 } else {
1164 for (j = 0; j < len2; j++) {
1165 *dst++ = v;
1170 b->cur_dec = (uint8_t*)dst;
1171 return 0;
1174 inline int BIKPlay::get_value(int bundle)
1176 int16_t ret;
1178 if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN) {
1179 return *c_bundle[bundle].cur_ptr++;
1181 if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF) {
1182 return (int8_t)*c_bundle[bundle].cur_ptr++;
1184 ret = *(int16_t*)c_bundle[bundle].cur_ptr;
1185 c_bundle[bundle].cur_ptr += 2;
1186 return ret;
1189 #define PUT2x2(dst, stride, x, y, pix) \
1190 dst[(x)*2 + (y)*2 * stride] = \
1191 dst[(x)*2 + 1 + (y)*2 * stride] = \
1192 dst[(x)*2 + ((y)*2 + 1) * stride] = \
1193 dst[(x)*2 + 1 + ((y)*2 + 1) * stride] = pix;
1195 static void get_pixels(DCTELEM *block, const uint8_t *pixels, int line_size)
1197 int i;
1199 /* read the pixels */
1200 for(i=0;i<8;i++) {
1201 block[0] = pixels[0];
1202 block[1] = pixels[1];
1203 block[2] = pixels[2];
1204 block[3] = pixels[3];
1205 block[4] = pixels[4];
1206 block[5] = pixels[5];
1207 block[6] = pixels[6];
1208 block[7] = pixels[7];
1209 pixels += line_size;
1210 block += 8;
1214 static void put_pixels_clamped(const DCTELEM *block, uint8_t *pixels, int line_size)
1216 int i;
1217 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1219 /* read the pixels */
1220 for(i=0;i<8;i++) {
1221 pixels[0] = cm[block[0]];
1222 pixels[1] = cm[block[1]];
1223 pixels[2] = cm[block[2]];
1224 pixels[3] = cm[block[3]];
1225 pixels[4] = cm[block[4]];
1226 pixels[5] = cm[block[5]];
1227 pixels[6] = cm[block[6]];
1228 pixels[7] = cm[block[7]];
1229 pixels += line_size;
1230 block += 8;
1234 static void add_pixels_clamped(const DCTELEM *block, uint8_t *pixels, int line_size)
1236 int i;
1237 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
1239 /* read the pixels */
1240 for(i=0;i<8;i++) {
1241 pixels[0] = cm[pixels[0] + block[0]];
1242 pixels[1] = cm[pixels[1] + block[1]];
1243 pixels[2] = cm[pixels[2] + block[2]];
1244 pixels[3] = cm[pixels[3] + block[3]];
1245 pixels[4] = cm[pixels[4] + block[4]];
1246 pixels[5] = cm[pixels[5] + block[5]];
1247 pixels[6] = cm[pixels[6] + block[6]];
1248 pixels[7] = cm[pixels[7] + block[7]];
1249 pixels += line_size;
1250 block += 8;
1254 static inline void copy_block(DCTELEM block[64], const uint8_t *src, uint8_t *dst, int stride)
1256 get_pixels(block, src, stride);
1257 put_pixels_clamped(block, dst, stride);
1260 #define clear_block(block) memset( (block), 0, sizeof(DCTELEM)*64);
1262 //This replaces the j_rev_dct module
1263 void bink_idct(DCTELEM *block)
1265 int i, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB, tC;
1266 int tblock[64];
1268 for (i = 0; i < 8; i++) {
1269 t0 = block[i+ 0] + block[i+32];
1270 t1 = block[i+ 0] - block[i+32];
1271 t2 = block[i+16] + block[i+48];
1272 t3 = block[i+16] - block[i+48];
1273 t3 = ((t3 * 0xB50) >> 11) - t2;
1275 t4 = t0 - t2;
1276 t5 = t0 + t2;
1277 t6 = t1 + t3;
1278 t7 = t1 - t3;
1280 t0 = block[i+40] + block[i+24];
1281 t1 = block[i+40] - block[i+24];
1282 t2 = block[i+ 8] + block[i+56];
1283 t3 = block[i+ 8] - block[i+56];
1285 t8 = t2 + t0;
1286 t9 = t3 + t1;
1287 t9 = (0xEC8 * t9) >> 11;
1288 tA = ((-0x14E8 * t1) >> 11) + t9 - t8;
1289 tB = t2 - t0;
1290 tB = ((0xB50 * tB) >> 11) - tA;
1291 tC = ((0x8A9 * t3) >> 11) + tB - t9;
1293 tblock[i+ 0] = t5 + t8;
1294 tblock[i+56] = t5 - t8;
1295 tblock[i+ 8] = t6 + tA;
1296 tblock[i+48] = t6 - tA;
1297 tblock[i+16] = t7 + tB;
1298 tblock[i+40] = t7 - tB;
1299 tblock[i+32] = t4 + tC;
1300 tblock[i+24] = t4 - tC;
1303 for (i = 0; i < 64; i += 8) {
1304 t0 = tblock[i+0] + tblock[i+4];
1305 t1 = tblock[i+0] - tblock[i+4];
1306 t2 = tblock[i+2] + tblock[i+6];
1307 t3 = tblock[i+2] - tblock[i+6];
1308 t3 = ((t3 * 0xB50) >> 11) - t2;
1310 t4 = t0 - t2;
1311 t5 = t0 + t2;
1312 t6 = t1 + t3;
1313 t7 = t1 - t3;
1315 t0 = tblock[i+5] + tblock[i+3];
1316 t1 = tblock[i+5] - tblock[i+3];
1317 t2 = tblock[i+1] + tblock[i+7];
1318 t3 = tblock[i+1] - tblock[i+7];
1320 t8 = t2 + t0;
1321 t9 = t3 + t1;
1322 t9 = (0xEC8 * t9) >> 11;
1323 tA = ((-0x14E8 * t1) >> 11) + t9 - t8;
1324 tB = t2 - t0;
1325 tB = ((0xB50 * tB) >> 11) - tA;
1326 tC = ((0x8A9 * t3) >> 11) + tB - t9;
1328 block[i+0] = (t5 + t8 + 0x7F) >> 8;
1329 block[i+7] = (t5 - t8 + 0x7F) >> 8;
1330 block[i+1] = (t6 + tA + 0x7F) >> 8;
1331 block[i+6] = (t6 - tA + 0x7F) >> 8;
1332 block[i+2] = (t7 + tB + 0x7F) >> 8;
1333 block[i+5] = (t7 - tB + 0x7F) >> 8;
1334 block[i+4] = (t4 + tC + 0x7F) >> 8;
1335 block[i+3] = (t4 - tC + 0x7F) >> 8;
1339 static void idct_put(uint8_t *dest, int line_size, DCTELEM *block)
1341 bink_idct(block);
1342 put_pixels_clamped(block, dest, line_size);
1344 static void idct_add(uint8_t *dest, int line_size, DCTELEM *block)
1346 bink_idct(block);
1347 add_pixels_clamped(block, dest, line_size);
1350 int BIKPlay::DecodeVideoFrame(void *data, int data_size)
1352 int blk, bw, bh;
1353 int i, j, plane, bx, by;
1354 uint8_t *dst, *prev;
1355 int v, c1, c2;
1356 const uint8_t *scan;
1357 const uint32_t *quant;
1358 int xoff, yoff;
1359 #pragma pack(push,16)
1360 DCTELEM block[64];
1361 #pragma pack(pop)
1363 int bits = data_size*8;
1364 v_gb.init_get_bits((uint8_t *) data, bits);
1365 //this is compatible only with the BIKi version
1366 v_gb.skip_bits(32);
1368 get_buffer(&c_pic, header.width, header.height);
1369 //plane order is YUV
1370 for (plane = 0; plane < 3; plane++) {
1371 const int stride = c_pic.linesize[plane];
1373 bw = plane ? (header.width + 15) >> 4 : (header.width + 7) >> 3;
1374 bh = plane ? (header.height + 15) >> 4 : (header.height + 7) >> 3;
1375 if(plane) {
1376 init_lengths(header.width >> 1, bw);
1377 } else {
1378 init_lengths(header.width, bw);
1381 for (i = 0; i < BINK_NB_SRC; i++) {
1382 read_bundle(i);
1385 for (by = 0; by < bh; by++) {
1386 if (read_block_types(&c_bundle[BINK_SRC_BLOCK_TYPES]) < 0)
1387 return -1;
1388 if (read_block_types(&c_bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0)
1389 return -1;
1390 if (read_colors(&c_bundle[BINK_SRC_COLORS]) < 0)
1391 return -1;
1392 if (read_patterns(&c_bundle[BINK_SRC_PATTERN]) < 0)
1393 return -1;
1394 if (read_motion_values(&c_bundle[BINK_SRC_X_OFF]) < 0)
1395 return -1;
1396 if (read_motion_values(&c_bundle[BINK_SRC_Y_OFF]) < 0)
1397 return -1;
1398 if (read_dcs(&c_bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0)
1399 return -1;
1400 if (read_dcs(&c_bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0)
1401 return -1;
1402 if (read_runs(&c_bundle[BINK_SRC_RUN]) < 0)
1403 return -1;
1405 //why is this here?
1406 if (by == bh)
1407 break;
1409 dst = c_pic.data[plane] + 8*by*stride;
1410 prev = c_last.data[plane] + 8*by*stride;
1411 for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {
1412 blk = get_value(BINK_SRC_BLOCK_TYPES);
1413 if ((by & 1) && blk == 1) {
1414 bx++;
1415 dst += 8;
1416 prev += 8;
1417 continue;
1419 switch (blk) {
1420 case SKIP_BLOCK:
1421 copy_block(block, prev, dst, stride);
1422 break;
1423 case SCALED_BLOCK:
1424 blk = get_value(BINK_SRC_SUB_BLOCK_TYPES);
1425 switch (blk) {
1426 case RUN_BLOCK:
1427 scan = bink_patterns[v_gb.get_bits(4)];
1428 i = 0;
1429 do {
1430 int run = get_value(BINK_SRC_RUN) + 1;
1431 if (v_gb.get_bits(1)) {
1432 v = get_value(BINK_SRC_COLORS);
1433 for (j = 0; j < run; j++) {
1434 int pos = *scan++;
1435 PUT2x2(dst, stride, pos & 7, pos >> 3, v);
1437 } else {
1438 for (j = 0; j < run; j++) {
1439 int pos = *scan++;
1440 PUT2x2(dst, stride, pos & 7, pos >> 3, get_value(BINK_SRC_COLORS));
1443 i += run;
1444 } while (i < 63);
1445 if (i == 63) {
1446 int pos = *scan++;
1447 PUT2x2(dst, stride, pos & 7, pos >> 3, get_value(BINK_SRC_COLORS));
1449 break;
1450 case INTRA_BLOCK:
1451 clear_block(block);
1452 block[0] = get_value(BINK_SRC_INTRA_DC);
1453 read_dct_coeffs(block, c_scantable.permutated);
1454 quant = bink_intra_quant[v_gb.get_bits(4)];
1455 for (i = 0; i < 64; i++) {
1456 block[i] = (block[i] * quant[i]) >> 11;
1458 bink_idct(block);
1459 for (j = 0; j < 8; j++) {
1460 for (i = 0; i < 8; i++) {
1461 PUT2x2(dst, stride, i, j, block[i + j*8]);
1464 break;
1465 case FILL_BLOCK:
1466 v = get_value(BINK_SRC_COLORS);
1467 for (j = 0; j < 16; j++) {
1468 memset(dst + j*stride, v, 16);
1470 break;
1471 case PATTERN_BLOCK:
1472 c1 = get_value(BINK_SRC_COLORS);
1473 c2 = get_value(BINK_SRC_COLORS);
1474 for (i = 0; i < 8; i++) {
1475 v = get_value(BINK_SRC_PATTERN);
1476 for (j = 0; j < 8; j++, v >>= 1) {
1477 PUT2x2(dst, stride, i, j, (v & 1) ? c2 : c1);
1480 break;
1481 case RAW_BLOCK:
1482 for (j = 0; j < 8; j++) {
1483 for (i = 0; i < 8; i++) {
1484 PUT2x2(dst, stride, i, j, get_value(BINK_SRC_COLORS));
1487 break;
1488 default:
1489 printf("Incorrect 16x16 block type!\n");
1490 return -1;
1492 bx++;
1493 dst += 8;
1494 prev += 8;
1495 break;
1496 case MOTION_BLOCK:
1497 xoff = get_value(BINK_SRC_X_OFF);
1498 yoff = get_value(BINK_SRC_Y_OFF);
1499 copy_block(block, prev + xoff + yoff*stride, dst, stride);
1500 break;
1501 case RUN_BLOCK:
1502 scan = bink_patterns[v_gb.get_bits(4)];
1503 i = 0;
1504 do {
1505 int run = get_value(BINK_SRC_RUN) + 1;
1506 if (v_gb.get_bits(1)) {
1507 v = get_value(BINK_SRC_COLORS);
1508 for (j = 0; j < run; j++) {
1509 int pos = *scan++;
1510 dst[(pos & 7) + (pos >> 3) * stride] = v;
1512 } else {
1513 for (j = 0; j < run; j++) {
1514 int pos = *scan++;
1515 dst[(pos & 7) + (pos >> 3) * stride] = get_value(BINK_SRC_COLORS);
1518 i += run;
1519 } while (i < 63);
1520 if (i == 63) {
1521 int pos = *scan++;
1522 dst[(pos & 7) + (pos >> 3)*stride] = get_value(BINK_SRC_COLORS);
1524 break;
1525 case RESIDUE_BLOCK:
1526 xoff = get_value(BINK_SRC_X_OFF);
1527 yoff = get_value(BINK_SRC_Y_OFF);
1528 copy_block(block, prev + xoff + yoff*stride, dst, stride);
1529 clear_block(block);
1530 v = v_gb.get_bits(7);
1531 read_residue(block, v);
1532 add_pixels_clamped(block, dst, stride);
1533 break;
1534 case INTRA_BLOCK:
1535 clear_block(block);
1536 block[0] = get_value(BINK_SRC_INTRA_DC);
1537 read_dct_coeffs(block, c_scantable.permutated);
1538 quant = bink_intra_quant[v_gb.get_bits(4)];
1539 for (i = 0; i < 64; i++) {
1540 block[i] = (block[i] * quant[i]) >> 11;
1542 idct_put(dst, stride, block);
1543 break;
1544 case FILL_BLOCK:
1545 v = get_value(BINK_SRC_COLORS);
1546 for (i = 0; i < 8; i++) {
1547 memset(dst + i*stride, v, 8);
1549 break;
1550 case INTER_BLOCK:
1551 xoff = get_value(BINK_SRC_X_OFF);
1552 yoff = get_value(BINK_SRC_Y_OFF);
1553 copy_block(block, prev + xoff + yoff*stride, dst, stride);
1554 clear_block(block);
1555 block[0] = get_value(BINK_SRC_INTER_DC);
1556 read_dct_coeffs(block, c_scantable.permutated);
1557 quant = bink_inter_quant[v_gb.get_bits(4)];
1558 for (i = 0; i < 64; i++) {
1559 block[i] = (block[i] * quant[i]) >> 11;
1561 idct_add(dst, stride, block);
1562 break;
1563 case PATTERN_BLOCK:
1564 c1 = get_value(BINK_SRC_COLORS);
1565 c2 = get_value(BINK_SRC_COLORS);
1566 for (i = 0; i < 8; i++) {
1567 v = get_value(BINK_SRC_PATTERN);
1568 for (j = 0; j < 8; j++, v >>= 1) {
1569 dst[i + j*stride] = (v & 1) ? c2 : c1;
1572 break;
1573 case RAW_BLOCK:
1574 for (i = 0; i < 8; i++) {
1575 memcpy(dst + i*stride, c_bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8);
1577 c_bundle[BINK_SRC_COLORS].cur_ptr += 64;
1578 break;
1579 default:
1580 printf("Unknown block type!\n");
1581 return -1;
1585 v_gb.get_bits_align32();
1588 if (video_frameskip) {
1589 video_frameskip--;
1590 video_skippedframes++;
1591 } else {
1592 unsigned int dest_x = (outputwidth - header.width) >> 1;
1593 unsigned int dest_y = (outputheight - header.height) >> 1;
1594 showFrame((ieByte **) c_pic.data, (unsigned int *) c_pic.linesize, header.width, header.height, header.width, header.height, dest_x, dest_y);
1595 release_buffer(&c_last);
1596 c_last=c_pic;
1597 memset(c_pic.data,0, sizeof(c_pic.data));
1599 return 0;
1602 #include "../../includes/plugindef.h"
1604 GEMRB_PLUGIN(0x316E2EDE, "BIK Video Player")
1605 PLUGIN_RESOURCE(&MoviePlayer::ID, BIKPlay, ".mve")
1606 END_PLUGIN()