Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * video.c --
3
 *
4
 *      This file contains C code that implements the video decoder model.
5
 *
6
 */
7
 
8
/*
9
 * Copyright (c) 1995 The Regents of the University of California.
10
 * All rights reserved.  
11
 *
12
 * Permission to use, copy, modify, and distribute this software and its
13
 * documentation for any purpose, without fee, and without written agreement is
14
 * hereby granted, provided that the above copyright notice and the following
15
 * two paragraphs appear in all copies of this software.
16
 *
17
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
18
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
19
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
20
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
 *
22
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
23
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
25
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
26
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
27
 */
28
 
29
/*
30
 * Portions of this software Copyright (c) 1995 Brown University.
31
 * All rights reserved.
32
 *
33
 * Permission to use, copy, modify, and distribute this software and its
34
 * documentation for any purpose, without fee, and without written agreement
35
 * is hereby granted, provided that the above copyright notice and the
36
 * following two paragraphs appear in all copies of this software.
37
 *
38
 * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
39
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
40
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
41
 * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
 *
43
 * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
44
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
45
 * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
46
 * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
47
 * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
48
 */
49
 
50
#include <stdio.h>
51
#include <stdlib.h>
52
#include <assert.h>
53
 
54
#ifndef MIPS
55
#include <sys/time.h>
56
#else
57
#include <sys/types.h>
58
#include <sys/system.h>
59
#endif
60
 
61
#ifndef NOCONTROLS
62
#include "ctrlbar.h"
63
#endif
64
#include "decoders.h"
65
#include "video.h"
66
#include "util.h"
67
#include "proto.h"
68
 
69
/* Declarations of functions. */
70
static void ReconIMBlock();
71
static void ReconPMBlock();
72
static void ReconBMBlock();
73
static void ReconBiMBlock();
74
static void ReconSkippedBlock();
75
static void DoPictureDisplay();
76
static int ParseSeqHead();
77
static int ParseGOP();
78
static int ParsePicture();
79
static int ParseSlice();
80
static int ParseMacroBlock();
81
static void ProcessSkippedPFrameMBlocks();
82
static void ProcessSkippedBFrameMBlocks();
83
 
84
/*
85
   Changes to make the code reentrant:
86
     de-globalized: totNumFrames, realTimeStart, matched_depth, ditherType,
87
       curBits, ReconPMBlock statics, first, [lc]max[xy], ditherFlags,
88
       vid_stream, Parse_done, seekValue, ReadPack static, sys_layer,
89
       bitOffset, bitLength, bitBuffer, curVidStream,
90
     X globals to xinfo (window, et al)
91
     use vid_stream->film_has_ended instead of FilmState
92
     lookup tables only initialized once, global as possible
93
        (default_intra_matrix, zigzag, zigzag_direct, scan)
94
     get rid of setjmp, long jmp
95
   Additional changes:
96
     if DISABLE_DITHER defined then do not compile dithering code
97
   -lsh@cs.brown.edu (Loring Holden)
98
 */
99
 
100
/* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
101
 
102
#define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
103
 
104
/* Set up array for fast conversion from zig zag order to row/column
105
   coordinates.
106
*/
107
 
108
const int zigzag[64][2] = {
109
  0, 0, 1, 0, 0, 1, 0, 2, 1, 1, 2, 0, 3, 0, 2, 1, 1, 2, 0, 3, 0, 4, 1, 3,
110
  2, 2, 3, 1, 4, 0, 5, 0, 4, 1, 3, 2, 2, 3, 1, 4, 0, 5, 0, 6, 1, 5, 2, 4,
111
  3, 3, 4, 2, 5, 1, 6, 0, 7, 0, 6, 1, 5, 2, 4, 3, 3, 4, 2, 5, 1, 6, 0, 7,
112
  1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6, 2, 7, 1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6,
113
  2, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 5, 7, 6, 6,
114
  7, 5, 7, 6, 6, 7, 7, 7};
115
/* Array mapping zigzag to array pointer offset. */
116
 
117
const int zigzag_direct[64] = {
118
  0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,
119
  19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
120
  42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
121
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
122
/* Set up array for fast conversion from row/column coordinates to
123
   zig zag order.
124
*/
125
 
126
const int scan[8][8] = {
127
  {0, 1, 5, 6, 14, 15, 27, 28},
128
  {2, 4, 7, 13, 16, 26, 29, 42},
129
  {3, 8, 12, 17, 25, 30, 41, 43},
130
  {9, 11, 18, 24, 31, 40, 44, 53},
131
  {10, 19, 23, 32, 39, 45, 52, 54},
132
  {20, 22, 33, 38, 46, 51, 55, 60},
133
  {21, 34, 37, 47, 50, 56, 59, 61},
134
{35, 36, 48, 49, 57, 58, 62, 63}};
135
/* Initialize P and B skip flags. */
136
 
137
static int No_P_Flag = FALSE;
138
static int No_B_Flag = FALSE;
139
 
140
/* Max lum, chrom indices for illegal block checking. */
141
 
142
 
143
/*
144
 * We use a lookup table to make sure values stay in the 0..255 range.
145
 * Since this is cropping (ie, x = (x < 0)?0:(x>255)?255:x; ), wee call this
146
 * table the "crop table".
147
 * MAX_NEG_CROP is the maximum neg/pos value we can handle.
148
 */
149
 
150
#define MAX_NEG_CROP 2048
151
#define NUM_CROP_ENTRIES (2048+2*MAX_NEG_CROP)
152
static unsigned char cropTbl[NUM_CROP_ENTRIES];
153
 
154
/*
155
  The following accounts for time and size  spent in various parsing acitivites
156
  if ANALYSIS has been defined.
157
*/
158
 
159
#ifdef ANALYSIS
160
 
161
 
162
unsigned int bitCount = 0;
163
 
164
int showmb_flag = 0;
165
int showEachFlag = 0;
166
 
167
typedef struct {
168
  int frametype;
169
  unsigned int totsize;
170
  unsigned int number;
171
  unsigned int i_mbsize;
172
  unsigned int p_mbsize;
173
  unsigned int b_mbsize;
174
  unsigned int bi_mbsize;
175
  unsigned int i_mbnum;
176
  unsigned int p_mbnum;
177
  unsigned int b_mbnum;
178
  unsigned int bi_mbnum;
179
  unsigned int i_mbcbp[64];
180
  unsigned int p_mbcbp[64];
181
  unsigned int b_mbcbp[64];
182
  unsigned int bi_mbcbp[64];
183
  unsigned int i_mbcoeff[64];
184
  unsigned int p_mbcoeff[64];
185
  unsigned int b_mbcoeff[64];
186
  unsigned int bi_mbcoeff[64];
187
  double tottime;
188
} Statval;
189
 
190
Statval stat_a[4];
191
unsigned int pictureSizeCount;
192
unsigned int mbSizeCount;
193
unsigned int *mbCBPPtr, *mbCoeffPtr, *mbSizePtr;
194
unsigned int cacheHit[8][8];
195
unsigned int cacheMiss[8][8];
196
 
197
static void
198
init_stat_struct(astat)
199
  Statval *astat;
200
{
201
  int j;
202
 
203
  astat->frametype = 0;
204
  astat->totsize = 0;
205
  astat->number = 0;
206
  astat->i_mbsize = 0;
207
  astat->p_mbsize = 0;
208
  astat->b_mbsize = 0;
209
  astat->bi_mbsize = 0;
210
  astat->i_mbnum = 0;
211
  astat->p_mbnum = 0;
212
  astat->b_mbnum = 0;
213
  astat->bi_mbnum = 0;
214
 
215
  for (j = 0; j < 64; j++) {
216
 
217
    astat->i_mbcbp[j] = 0;
218
    astat->p_mbcbp[j] = 0;
219
    astat->b_mbcbp[j] = 0;
220
    astat->bi_mbcbp[j] = 0;
221
    astat->i_mbcoeff[j] = 0;
222
    astat->p_mbcoeff[j] = 0;
223
    astat->b_mbcoeff[j] = 0;
224
    astat->bi_mbcoeff[j] = 0;
225
  }
226
  astat->tottime = 0.0;
227
}
228
 
229
void
230
init_stats()
231
{
232
  int i, j;
233
 
234
  for (i = 0; i < 4; i++) {
235
    init_stat_struct(&(stat_a[i]));
236
    stat_a[i].frametype = i;
237
  }
238
 
239
  for (i = 0; i < 8; i++) {
240
    for (j = 0; j < 8; j++) {
241
      cacheHit[i][j] = 0;
242
      cacheMiss[i][j] = 0;
243
    }
244
  }
245
 
246
  bitCount = 0;
247
}
248
 
249
static void
250
PrintOneStat()
251
{
252
  int i;
253
 
254
  printf("\n");
255
  switch (stat_a[0].frametype) {
256
  case I_TYPE:
257
    printf("I FRAME\n");
258
    break;
259
  case P_TYPE:
260
    printf("P FRAME\n");
261
    break;
262
  case B_TYPE:
263
    printf("B FRAME\n");
264
    break;
265
  }
266
 
267
  printf("Size: %d bytes + %d bits\n", stat_a[0].totsize / 8, stat_a[0].totsize % 8);
268
  if (stat_a[0].i_mbnum > 0) {
269
    printf("\tI Macro Block Stats:\n");
270
    printf("\t%d I Macroblocks\n", stat_a[0].i_mbnum);
271
    printf("\tAvg. Size: %d bytes + %d bits\n",
272
           stat_a[0].i_mbsize / (8 * stat_a[0].i_mbnum),
273
           (stat_a[0].i_mbsize * stat_a[0].i_mbnum) % 8);
274
    printf("\t\tCoded Block Pattern Histogram:\n");
275
    for (i = 0; i < 64; i += 8) {
276
      printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcbp[i],
277
             stat_a[0].i_mbcbp[i + 1], stat_a[0].i_mbcbp[i + 2], stat_a[0].i_mbcbp[i + 3],
278
             stat_a[0].i_mbcbp[i + 4], stat_a[0].i_mbcbp[i + 5], stat_a[0].i_mbcbp[i + 6],
279
             stat_a[0].i_mbcbp[i + 7]);
280
    }
281
    printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
282
    for (i = 0; i < 64; i += 8) {
283
      printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcoeff[i],
284
             stat_a[0].i_mbcoeff[i + 1], stat_a[0].i_mbcoeff[i + 2],
285
             stat_a[0].i_mbcoeff[i + 3], stat_a[0].i_mbcoeff[i + 4],
286
             stat_a[0].i_mbcoeff[i + 5], stat_a[0].i_mbcoeff[i + 6],
287
             stat_a[0].i_mbcoeff[i + 7]);
288
    }
289
  }
290
  if (stat_a[0].p_mbnum > 0) {
291
    printf("\tP Macro Block Stats:\n");
292
    printf("\t%d P Macroblocks\n", stat_a[0].p_mbnum);
293
    printf("\tAvg. Size: %d bytes + %d bits\n",
294
           stat_a[0].p_mbsize / (8 * stat_a[0].p_mbnum),
295
           (stat_a[0].p_mbsize / stat_a[0].p_mbnum) % 8);
296
    printf("\t\tCoded Block Pattern Histogram:\n");
297
    for (i = 0; i < 64; i += 8) {
298
      printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcbp[i],
299
             stat_a[0].p_mbcbp[i + 1], stat_a[0].p_mbcbp[i + 2], stat_a[0].p_mbcbp[i + 3],
300
             stat_a[0].p_mbcbp[i + 4], stat_a[0].p_mbcbp[i + 5], stat_a[0].p_mbcbp[i + 6],
301
             stat_a[0].p_mbcbp[i + 7]);
302
    }
303
    printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
304
    for (i = 0; i < 64; i += 8) {
305
      printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcoeff[i],
306
             stat_a[0].p_mbcoeff[i + 1], stat_a[0].p_mbcoeff[i + 2],
307
             stat_a[0].p_mbcoeff[i + 3], stat_a[0].p_mbcoeff[i + 4],
308
             stat_a[0].p_mbcoeff[i + 5], stat_a[0].p_mbcoeff[i + 6],
309
             stat_a[0].p_mbcoeff[i + 7]);
310
    }
311
  }
312
  if (stat_a[0].b_mbnum > 0) {
313
    printf("\tB Macro Block Stats:\n");
314
    printf("\t%d B Macroblocks\n", stat_a[0].b_mbnum);
315
    printf("\tAvg. Size: %d bytes + %d bits\n",
316
           stat_a[0].b_mbsize / (8 * stat_a[0].b_mbnum),
317
           (stat_a[0].b_mbsize / stat_a[0].b_mbnum) % 8);
318
    printf("\t\tCoded Block Pattern Histogram:\n");
319
    for (i = 0; i < 64; i += 8) {
320
      printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcbp[i],
321
             stat_a[0].b_mbcbp[i + 1], stat_a[0].b_mbcbp[i + 2], stat_a[0].b_mbcbp[i + 3],
322
             stat_a[0].b_mbcbp[i + 4], stat_a[0].b_mbcbp[i + 5], stat_a[0].b_mbcbp[i + 6],
323
             stat_a[0].b_mbcbp[i + 7]);
324
    }
325
    printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
326
    for (i = 0; i < 64; i += 8) {
327
      printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcoeff[i],
328
             stat_a[0].b_mbcoeff[i + 1], stat_a[0].b_mbcoeff[i + 2],
329
             stat_a[0].b_mbcoeff[i + 3], stat_a[0].b_mbcoeff[i + 4],
330
             stat_a[0].b_mbcoeff[i + 5], stat_a[0].b_mbcoeff[i + 6],
331
             stat_a[0].b_mbcoeff[i + 7]);
332
    }
333
  }
334
  if (stat_a[0].bi_mbnum > 0) {
335
    printf("\tBi Macro Block Stats:\n");
336
    printf("\t%d Bi Macroblocks\n", stat_a[0].bi_mbnum);
337
    printf("\tAvg. Size: %d bytes + %d bits\n",
338
           stat_a[0].bi_mbsize / (8 * stat_a[0].bi_mbnum),
339
           (stat_a[0].bi_mbsize * stat_a[0].bi_mbnum) % 8);
340
    printf("\t\tCoded Block Pattern Histogram:\n");
341
    for (i = 0; i < 64; i += 8) {
342
      printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcbp[i],
343
             stat_a[0].bi_mbcbp[i + 1], stat_a[0].bi_mbcbp[i + 2], stat_a[0].bi_mbcbp[i + 3],
344
             stat_a[0].bi_mbcbp[i + 4], stat_a[0].bi_mbcbp[i + 5], stat_a[0].bi_mbcbp[i + 6],
345
             stat_a[0].bi_mbcbp[i + 7]);
346
    }
347
    printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
348
    for (i = 0; i < 64; i += 8) {
349
      printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcoeff[i],
350
             stat_a[0].bi_mbcoeff[i + 1], stat_a[0].bi_mbcoeff[i + 2],
351
             stat_a[0].bi_mbcoeff[i + 3], stat_a[0].bi_mbcoeff[i + 4],
352
             stat_a[0].bi_mbcoeff[i + 5], stat_a[0].bi_mbcoeff[i + 6],
353
             stat_a[0].bi_mbcoeff[i + 7]);
354
    }
355
  }
356
  printf("\nTime to Decode: %g secs.\n", stat_a[0].tottime);
357
  printf("****************\n");
358
}
359
 
360
void
361
PrintAllStats(vid_stream)
362
VidStream *vid_stream;
363
{
364
  int i, j;
365
  unsigned int supertot, supernum;
366
  double supertime;
367
 
368
  printf("\n");
369
  printf("General Info: \n");
370
  printf("Width: %d\nHeight: %d\n", vid_stream->mb_width * 16, vid_stream->mb_height * 16);
371
 
372
  for (i = 1; i < 4; i++) {
373
 
374
    if (stat_a[i].number == 0)
375
      continue;
376
 
377
    switch (i) {
378
    case 1:
379
      printf("I FRAMES\n");
380
      break;
381
    case 2:
382
      printf("P FRAMES\n");
383
      break;
384
    case 3:
385
      printf("B FRAMES\n");
386
      break;
387
    }
388
 
389
    printf("Number: %d\n", stat_a[i].number);
390
    printf("Avg. Size: %d bytes + %d bits\n",
391
           stat_a[i].totsize / (8 * stat_a[i].number), (stat_a[i].totsize / stat_a[i].number) % 8);
392
    if (stat_a[i].i_mbnum > 0) {
393
      printf("\tI Macro Block Stats:\n");
394
      printf("\t%d I Macroblocks\n", stat_a[i].i_mbnum);
395
      printf("\tAvg. Size: %d bytes + %d bits\n",
396
             stat_a[i].i_mbsize / (8 * stat_a[i].i_mbnum),
397
             (stat_a[i].i_mbsize / stat_a[i].i_mbnum) % 8);
398
      printf("\t\tCoded Block Pattern Histogram:\n");
399
      for (j = 0; j < 64; j += 8) {
400
        printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcbp[j],
401
               stat_a[i].i_mbcbp[j + 1], stat_a[i].i_mbcbp[j + 2], stat_a[i].i_mbcbp[j + 3],
402
               stat_a[i].i_mbcbp[j + 4], stat_a[i].i_mbcbp[j + 5], stat_a[i].i_mbcbp[j + 6],
403
               stat_a[i].i_mbcbp[j + 7]);
404
      }
405
      printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
406
      for (j = 0; j < 64; j += 8) {
407
        printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcoeff[j],
408
               stat_a[i].i_mbcoeff[j + 1], stat_a[i].i_mbcoeff[j + 2],
409
               stat_a[i].i_mbcoeff[j + 3], stat_a[i].i_mbcoeff[j + 4],
410
               stat_a[i].i_mbcoeff[j + 5], stat_a[i].i_mbcoeff[j + 6],
411
               stat_a[i].i_mbcoeff[j + 7]);
412
      }
413
    }
414
    if (stat_a[i].p_mbnum > 0) {
415
      printf("\tP Macro Block Stats:\n");
416
      printf("\t%d P Macroblocks\n", stat_a[i].p_mbnum);
417
      printf("\tAvg. Size: %d bytes + %d bits\n",
418
             stat_a[i].p_mbsize / (8 * stat_a[i].p_mbnum),
419
             (stat_a[i].p_mbsize / stat_a[i].p_mbnum) % 8);
420
      printf("\t\tCoded Block Pattern Histogram:\n");
421
      for (j = 0; j < 64; j += 8) {
422
        printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcbp[j],
423
               stat_a[i].p_mbcbp[j + 1], stat_a[i].p_mbcbp[j + 2], stat_a[i].p_mbcbp[j + 3],
424
               stat_a[i].p_mbcbp[j + 4], stat_a[i].p_mbcbp[j + 5], stat_a[i].p_mbcbp[j + 6],
425
               stat_a[i].p_mbcbp[j + 7]);
426
      }
427
      printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
428
      for (j = 0; j < 64; j += 8) {
429
        printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcoeff[j],
430
               stat_a[i].p_mbcoeff[j + 1], stat_a[i].p_mbcoeff[j + 2],
431
               stat_a[i].p_mbcoeff[j + 3], stat_a[i].p_mbcoeff[j + 4],
432
               stat_a[i].p_mbcoeff[j + 5], stat_a[i].p_mbcoeff[j + 6],
433
               stat_a[i].p_mbcoeff[j + 7]);
434
      }
435
    }
436
    if (stat_a[i].b_mbnum > 0) {
437
      printf("\tB Macro Block Stats:\n");
438
      printf("\t%d B Macroblocks\n", stat_a[i].b_mbnum);
439
      printf("\tAvg. Size: %d bytes + %d bits\n",
440
             stat_a[i].b_mbsize / (8 * stat_a[i].b_mbnum),
441
             (stat_a[i].b_mbsize * stat_a[i].b_mbnum) % 8);
442
      printf("\t\tCoded Block Pattern Histogram:\n");
443
      for (j = 0; j < 64; j += 8) {
444
        printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcbp[j],
445
               stat_a[i].b_mbcbp[j + 1], stat_a[i].b_mbcbp[j + 2], stat_a[i].b_mbcbp[j + 3],
446
               stat_a[i].b_mbcbp[j + 4], stat_a[i].b_mbcbp[j + 5], stat_a[i].b_mbcbp[j + 6],
447
               stat_a[i].b_mbcbp[j + 7]);
448
      }
449
      printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
450
      for (j = 0; j < 64; j += 8) {
451
        printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcoeff[j],
452
               stat_a[i].b_mbcoeff[j + 1], stat_a[i].b_mbcoeff[j + 2],
453
               stat_a[i].b_mbcoeff[j + 3], stat_a[i].b_mbcoeff[j + 4],
454
               stat_a[i].b_mbcoeff[j + 5], stat_a[i].b_mbcoeff[j + 6],
455
               stat_a[i].b_mbcoeff[j + 7]);
456
      }
457
    }
458
    if (stat_a[i].bi_mbnum > 0) {
459
      printf("\tBi Macro Block Stats:\n");
460
      printf("\t%d Bi Macroblocks\n", stat_a[i].bi_mbnum);
461
      printf("\tAvg. Size: %d bytes + %d bits\n",
462
             stat_a[i].bi_mbsize / (8 * stat_a[i].bi_mbnum),
463
             (stat_a[i].bi_mbsize * stat_a[i].bi_mbnum) % 8);
464
      printf("\t\tCoded Block Pattern Histogram:\n");
465
      for (j = 0; j < 64; j += 8) {
466
        printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].bi_mbcbp[j],
467
               stat_a[i].bi_mbcbp[j + 1], stat_a[i].bi_mbcbp[j + 2], stat_a[i].bi_mbcbp[j + 3],
468
               stat_a[i].bi_mbcbp[j + 4], stat_a[i].bi_mbcbp[j + 5], stat_a[i].bi_mbcbp[j + 6],
469
               stat_a[i].bi_mbcbp[j + 7]);
470
      }
471
      printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
472
      for (j = 0; j < 64; j += 8) {
473
        printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].bi_mbcoeff[j],
474
               stat_a[i].bi_mbcoeff[j + 1], stat_a[i].bi_mbcoeff[j + 2],
475
               stat_a[i].bi_mbcoeff[j + 3], stat_a[i].bi_mbcoeff[j + 4],
476
               stat_a[i].bi_mbcoeff[j + 5], stat_a[i].bi_mbcoeff[j + 6],
477
               stat_a[i].bi_mbcoeff[j + 7]);
478
      }
479
    }
480
    printf("\nAvg. Time to Decode: %f secs.\n",
481
           (stat_a[i].tottime / ((double) stat_a[i].number)));
482
    printf("\n");
483
    printf("*************************\n\n");
484
  }
485
 
486
  supertot = stat_a[1].totsize + stat_a[2].totsize + stat_a[3].totsize;
487
  supernum = stat_a[1].number + stat_a[2].number + stat_a[3].number;
488
  supertime = stat_a[1].tottime + stat_a[2].tottime + stat_a[3].tottime;
489
 
490
  printf("Total Number of Frames: %d\n", supernum);
491
  printf("Avg Frame Size: %d bytes %d bits\n",
492
         supertot / (8 * supernum), (supertot / supernum) % 8);
493
  printf("Total Time Decoding: %g secs.\n", supertime);
494
  printf("Avg Decoding Time/Frame: %g secs.\n", supertime / ((double) supernum));
495
  printf("Avg Decoding Frames/Sec: %g secs.\n", ((double) supernum) / supertime);
496
  printf("\n");
497
 
498
  printf("Cache Hits/Miss\n");
499
  for (i = 0; i < 8; i++) {
500
    printf("%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\n",
501
           cacheHit[i][0], cacheMiss[i][0], cacheHit[i][1], cacheMiss[i][1],
502
           cacheHit[i][2], cacheMiss[i][2], cacheHit[i][3], cacheMiss[i][3]);
503
    printf("%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\n",
504
           cacheHit[i][4], cacheMiss[i][4], cacheHit[i][5], cacheMiss[i][5],
505
           cacheHit[i][6], cacheMiss[i][6], cacheHit[i][7], cacheMiss[i][7]);
506
  }
507
 
508
}
509
 
510
static void
511
CollectStats()
512
{
513
  int i, j;
514
 
515
  i = stat_a[0].frametype;
516
 
517
  stat_a[i].totsize += stat_a[0].totsize;
518
  stat_a[i].number += stat_a[0].number;
519
  stat_a[i].i_mbsize += stat_a[0].i_mbsize;
520
  stat_a[i].p_mbsize += stat_a[0].p_mbsize;
521
  stat_a[i].b_mbsize += stat_a[0].b_mbsize;
522
  stat_a[i].bi_mbsize += stat_a[0].bi_mbsize;
523
  stat_a[i].i_mbnum += stat_a[0].i_mbnum;
524
  stat_a[i].p_mbnum += stat_a[0].p_mbnum;
525
  stat_a[i].b_mbnum += stat_a[0].b_mbnum;
526
  stat_a[i].bi_mbnum += stat_a[0].bi_mbnum;
527
 
528
  for (j = 0; j < 64; j++) {
529
 
530
    stat_a[i].i_mbcbp[j] += stat_a[0].i_mbcbp[j];
531
    stat_a[i].p_mbcbp[j] += stat_a[0].p_mbcbp[j];
532
    stat_a[i].b_mbcbp[j] += stat_a[0].b_mbcbp[j];
533
    stat_a[i].bi_mbcbp[j] += stat_a[0].bi_mbcbp[j];
534
    stat_a[i].i_mbcoeff[j] += stat_a[0].i_mbcoeff[j];
535
    stat_a[i].p_mbcoeff[j] += stat_a[0].p_mbcoeff[j];
536
    stat_a[i].b_mbcoeff[j] += stat_a[0].b_mbcoeff[j];
537
    stat_a[i].bi_mbcoeff[j] += stat_a[0].bi_mbcoeff[j];
538
  }
539
 
540
  stat_a[i].tottime += stat_a[0].tottime;
541
 
542
  init_stat_struct(&(stat_a[0]));
543
}
544
 
545
static unsigned int
546
bitCountRead()
547
{
548
  return bitCount;
549
}
550
 
551
static void
552
StartTime()
553
{
554
  stat_a[0].tottime = ReadSysClock();
555
}
556
 
557
static void
558
EndTime()
559
{
560
  stat_a[0].tottime = ReadSysClock() - stat_a[0].tottime;
561
}
562
#endif
563
 
564
 
565
/*
566
 *--------------------------------------------------------------
567
 *
568
 * ReadSysClock --
569
 *
570
 *      Computes the current time according to the system clock.
571
 *
572
 * Results:
573
 *  The current time according to the system clock.
574
 *
575
 * Side effects:
576
 *      None.
577
 *
578
 *--------------------------------------------------------------
579
 */
580
 
581
double
582
ReadSysClock()
583
{
584
  extern long sys_gettime(void*);
585
  /*struct timeval tv;
586
  (void) gettimeofday(&tv, (struct timezone *)NULL);
587
  return (tv.tv_sec + tv.tv_usec / 1000000.0);*/
588
  //return sys_time();
589
  return sys_gettime(NULL)/1000000.0;
590
}
591
 
592
 
593
/*
594
 *--------------------------------------------------------------
595
 *
596
 * PrintTimeInfo --
597
 *
598
 *      Displays statistics regarding the video playback time.
599
 *
600
 * Results:
601
 *  Outputs time statistics to the screen.
602
 *
603
 * Side effects:
604
 *      None.
605
 *
606
 *--------------------------------------------------------------
607
 */
608
 
609
void
610
PrintTimeInfo(vid_stream)
611
  VidStream *vid_stream;
612
{
613
  double spent;
614
 
615
#ifndef NOCONTROLS
616
  if (ControlShow != CTRLBAR_NONE)
617
    spent = StopWatch(STOPWATCH_STOP);
618
  else  
619
    spent = ReadSysClock() - vid_stream->realTimeStart;
620
#else
621
  spent = ReadSysClock() - vid_stream->realTimeStart;
622
#endif
623
  if (!quietFlag) {
624
    printf("\nReal Time Spent (After Initializations): %f secs.\n", spent);
625
    printf("Avg. Frames/Sec: %f\n",
626
           ((double) vid_stream->totNumFrames) / spent);
627
  }
628
}
629
 
630
 
631
/*
632
 *--------------------------------------------------------------
633
 *
634
 * InitCrop --
635
 *
636
 *      Initializes cropTbl - this was taken from newVidStream so
637
 *      that it wasn't done for each new video stream
638
 *
639
 * Results:
640
 *      None
641
 *
642
 * Side effects:
643
 *      cropTbl will be initialized
644
 *
645
 *--------------------------------------------------------------
646
 */
647
void
648
InitCrop()
649
{
650
  int i;
651
 
652
  /* Initialize crop table. */
653
 
654
  for (i = (-MAX_NEG_CROP); i < NUM_CROP_ENTRIES - MAX_NEG_CROP; i++) {
655
    if (i <= 0) {
656
      cropTbl[i + MAX_NEG_CROP] = 0;
657
#ifdef TWELVE_BITS
658
        } else if (i >= 2047) {
659
      cropTbl[i + MAX_NEG_CROP] = 2047;
660
#endif
661
    } else if (i >= 255) {
662
      cropTbl[i + MAX_NEG_CROP] = 255;
663
    } else {
664
      cropTbl[i + MAX_NEG_CROP] = i;
665
    }
666
  }
667
 
668
}
669
 
670
 
671
 
672
/*
673
 *--------------------------------------------------------------
674
 *
675
 * NewVidStream --
676
 *
677
 *      Allocates and initializes a VidStream structure. Takes
678
 *      as parameter requested size for buffer length.
679
 *
680
 * Results:
681
 *      A pointer to the new VidStream structure.
682
 *
683
 * Side effects:
684
 *      None.
685
 *
686
 *--------------------------------------------------------------
687
 */
688
 
689
VidStream *
690
NewVidStream(buffer_len)
691
  unsigned int buffer_len;
692
{
693
  int i, j;
694
  VidStream *new;
695
  static const unsigned char default_intra_matrix[64] = {
696
    8, 16, 19, 22, 26, 27, 29, 34,
697
    16, 16, 22, 24, 27, 29, 34, 37,
698
    19, 22, 26, 27, 29, 34, 34, 38,
699
    22, 22, 26, 27, 29, 34, 37, 40,
700
    22, 26, 27, 29, 32, 35, 40, 48,
701
    26, 27, 29, 32, 35, 40, 48, 58,
702
    26, 27, 29, 34, 38, 46, 56, 69,
703
  27, 29, 35, 38, 46, 56, 69, 83};
704
 
705
  /* Check for legal buffer length. */
706
 
707
  if (buffer_len < 4)
708
    return NULL;
709
 
710
  /* Make buffer length multiple of 4. */
711
 
712
  buffer_len = (buffer_len + 3) >> 2;
713
 
714
  /* Allocate memory for new structure. */
715
 
716
  new = (VidStream *) malloc(sizeof(VidStream));
717
 
718
  /* Initialize pointers to extension and user data. */
719
 
720
  new->group.ext_data = new->group.user_data =
721
    new->picture.extra_info = new->picture.user_data =
722
    new->picture.ext_data = new->slice.extra_info =
723
    new->ext_data = new->user_data = NULL;
724
 
725
  /* Copy default intra matrix. */
726
 
727
  for (i = 0; i < 8; i++) {
728
    for (j = 0; j < 8; j++) {
729
      new->intra_quant_matrix[i][j] = default_intra_matrix[i * 8 + j];
730
    }
731
  }
732
 
733
  /* Initialize non intra quantization matrix. */
734
 
735
  for (i = 0; i < 8; i++) {
736
    for (j = 0; j < 8; j++) {
737
      new->non_intra_quant_matrix[i][j] = 16;
738
    }
739
  }
740
 
741
  /* Initialize pointers to image spaces. */
742
 
743
  new->current = new->past = new->future = NULL;
744
  for (i = 0; i < RING_BUF_SIZE; i++) {
745
    new->ring[i] = NULL;
746
  }
747
 
748
  /* Create buffer. */
749
 
750
  new->buf_start = (unsigned int *) malloc(buffer_len * 4);
751
 
752
  /*
753
   * Set max_buf_length to one less than actual length to deal with messy
754
   * data without proper seq. end codes.
755
   */
756
 
757
  new->max_buf_length = buffer_len - 1;
758
 
759
  /* Initialize bitstream i/o fields. */
760
 
761
  new->bit_offset = 0;
762
  new->buf_length = 0;
763
  new->buffer = new->buf_start;
764
 
765
  /* Initialize fields that used to be global */
766
  new->film_has_ended = FALSE;
767
  new->filename = NULL;
768
  new->totNumFrames = 0;
769
  new->ditherFlags = NULL;
770
  new->EOF_flag = FALSE;
771
 
772
  /* Return structure. */
773
 
774
  return new;
775
}
776
 
777
 
778
 
779
/*
780
 *--------------------------------------------------------------
781
 *
782
 * ResetVidStream --
783
 *
784
 *      Re-initializes a VidStream structure. Takes
785
 *      as parameter a pointer to the VidStream to reset.
786
 *
787
 * Results:
788
 *      None.
789
 *
790
 * Side effects:
791
 *      None.
792
 *
793
 *--------------------------------------------------------------
794
 */
795
 
796
void
797
ResetVidStream(vid)
798
  VidStream *vid;
799
{
800
  int i;
801
 
802
  /* Initialize pointers to image spaces. */
803
  vid->current = vid->past = vid->future = NULL;
804
 
805
  /* Initialize rings */
806
  for (i = 0; i < RING_BUF_SIZE; i++)
807
    vid->ring[i]->locked = 0;  /* Unlock */
808
 
809
  /* Initialize bitstream i/o fields. */
810
  vid->bit_offset = vid->buf_length = 0;
811
  vid->buffer = vid->buf_start;
812
  vid->curBits = 0;
813
 
814
  /* We are at the beginning of the film, so film has not ended */
815
  vid->film_has_ended = FALSE;
816
 
817
  /* Initialize start time */
818
  vid->realTimeStart = ReadSysClock();
819
 
820
  /* Reset number of frames to zero */
821
  vid->totNumFrames=0;
822
 
823
  /* Reset EOF_flag to 0 */
824
  vid->EOF_flag = 0;
825
}
826
 
827
 
828
/*
829
 *--------------------------------------------------------------
830
 *
831
 * DestroyVidStream --
832
 *
833
 *      Deallocates a VidStream structure.
834
 *
835
 * Results:
836
 *      None.
837
 *
838
 * Side effects:
839
 *      None.
840
 *
841
 *--------------------------------------------------------------
842
 */
843
void
844
DestroyVidStream(astream, xinfo)
845
  VidStream *astream;
846
  XInfo *xinfo;
847
{
848
  int i;
849
 
850
  if (astream->ext_data != NULL)
851
    free(astream->ext_data);
852
 
853
  if (astream->user_data != NULL)
854
    free(astream->user_data);
855
 
856
  if (astream->group.ext_data != NULL)
857
    free(astream->group.ext_data);
858
 
859
  if (astream->group.user_data != NULL)
860
    free(astream->group.user_data);
861
 
862
  if (astream->picture.extra_info != NULL)
863
    free(astream->picture.extra_info);
864
 
865
  if (astream->picture.ext_data != NULL)
866
    free(astream->picture.ext_data);
867
 
868
  if (astream->picture.user_data != NULL)
869
    free(astream->picture.user_data);
870
 
871
  if (astream->slice.extra_info != NULL)
872
    free(astream->slice.extra_info);
873
 
874
  if (astream->buf_start != NULL)
875
    free(astream->buf_start);
876
 
877
  for (i = 0; i < RING_BUF_SIZE; i++) {
878
    if (astream->ring[i] != NULL) {
879
      DestroyPictImage(astream->ring[i], xinfo);
880
      astream->ring[i] = NULL;
881
    }
882
  }
883
 
884
  if (astream->ditherFlags !=NULL)
885
    free(astream->ditherFlags);
886
 
887
  free((char *) astream);
888
}
889
 
890
 
891
 
892
 
893
/*
894
 *--------------------------------------------------------------
895
 *
896
 * NewPictImage --
897
 *
898
 *      Allocates and initializes a PictImage structure.
899
 *      The width and height of the image space are passed in
900
 *      as parameters.
901
 *
902
 * Results:
903
 *      A pointer to the new PictImage structure.
904
 *
905
 * Side effects:
906
 *      None.
907
 *
908
 *--------------------------------------------------------------
909
 */
910
 
911
PictImage *
912
NewPictImage(vid_stream,xinfo)
913
  VidStream *vid_stream;
914
  XInfo *xinfo;
915
{
916
  PictImage *new;
917
  int ditherType=vid_stream->ditherType;
918
  unsigned int width=vid_stream->mb_width * 16;
919
  unsigned int height=vid_stream->mb_height * 16;
920
#ifdef SH_MEM
921
  Display *display=xinfo->display;
922
#endif
923
 
924
  /* Allocate memory space for new structure. */
925
 
926
  new = (PictImage *) malloc(sizeof(PictImage));
927
 
928
 
929
  /* Allocate memory for image spaces. */
930
 
931
#ifdef SH_MEM
932
  new->ximage = NULL;
933
 
934
  if (shmemFlag) {
935
    Visual *fc_visual;
936
    int depth;
937
    /*
938
     * factor is 1 or 2
939
     */
940
    int factor = 1 + IS_2x2_DITHER(ditherType);
941
 
942
    Visual *FindFullColorVisual();
943
 
944
#ifndef DISABLE_DITHER
945
    if (ditherType == FULL_COLOR_DITHER || ditherType == FULL_COLOR2_DITHER) {
946
#endif
947
      fc_visual = FindFullColorVisual(display, &depth);
948
      new->ximage = XShmCreateImage(display, fc_visual, (unsigned int) depth,
949
                                    ZPixmap,
950
                                    NULL, &(new->shminfo), width * factor,
951
                                    height * factor);
952
#ifndef DISABLE_DITHER
953
    } else if (ditherType == FULL_COLOR2_DITHER) {
954
      fc_visual = FindFullColorVisual(display, &depth);
955
      new->ximage = XShmCreateImage(display, fc_visual, (unsigned int) depth,
956
                                   ZPixmap,
957
                                    NULL, &(new->shminfo), width*2, height*2);
958
    } else if (ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
959
      new->ximage = XShmCreateImage(display, None, 1, XYBitmap,
960
                                    NULL, &(new->shminfo), width * factor,
961
                                    height * factor);
962
    } else {
963
      new->ximage = XShmCreateImage(display, None, xinfo->depth, ZPixmap, NULL,
964
                                    &(new->shminfo), width * factor,
965
                                    height * factor);
966
    }
967
#endif
968
 
969
    /* If no go, then revert to normal Xlib calls. */
970
 
971
    if (new->ximage == NULL) {
972
      shmemFlag = 0;
973
      if (!quietFlag) {
974
        fprintf(stderr, "Shared memory error, disabling.\n");
975
        fprintf(stderr, "Ximage error.\n");
976
      }
977
      goto shmemerror;
978
    }
979
 
980
    /* Success here, continue. */
981
 
982
#ifdef LITTLE_ENDIAN_ARCHITECTURE
983
    new->ximage->byte_order = LSBFirst;
984
    new->ximage->bitmap_bit_order = LSBFirst;
985
#else
986
    new->ximage->byte_order = MSBFirst;
987
    new->ximage->bitmap_bit_order = MSBFirst;
988
#endif
989
 
990
    new->shminfo.shmid = shmget(IPC_PRIVATE, (unsigned int) (new->ximage->bytes_per_line *
991
                                              new->ximage->height),
992
                                IPC_CREAT | 0777);
993
 
994
    if (new->shminfo.shmid < 0) {
995
      XDestroyImage(new->ximage);
996
      new->ximage = NULL;
997
      shmemFlag = 0;
998
      if (!quietFlag) {
999
        fprintf(stderr, "Shared memory error, disabling.\n");
1000
        fprintf(stderr, "Seg. id. error.\n");
1001
      }
1002
      goto shmemerror;
1003
    }
1004
 
1005
    new->shminfo.shmaddr = (char *) shmat(new->shminfo.shmid, 0, 0);
1006
 
1007
    if (new->shminfo.shmaddr == ((char *) -1)) {
1008
      XDestroyImage(new->ximage);
1009
      new->ximage = NULL;
1010
      shmemFlag = 0;
1011
      if (!quietFlag) {
1012
        fprintf(stderr, "Shared memory error, disabling.\n");
1013
        fprintf(stderr, "Address error.\n");
1014
      }
1015
      goto shmemerror;
1016
    }
1017
 
1018
    new->ximage->data = new->shminfo.shmaddr;
1019
    new->display = (unsigned char *) new->ximage->data;
1020
    new->shminfo.readOnly = False;
1021
 
1022
    XShmAttach(display, &(new->shminfo));
1023
    XSync(display, False);
1024
 
1025
    if (gXErrorFlag) {
1026
      /* Ultimate failure here. */
1027
      XShmDetach(display,&(new->shminfo));
1028
      XSync(display, False);
1029
      XDestroyImage(new->ximage);
1030
      shmdt (new->shminfo.shmaddr);
1031
      shmctl (new->shminfo.shmid, IPC_RMID, 0);
1032
      new->ximage = NULL;
1033
      shmemFlag = 0;
1034
      if (!quietFlag) {
1035
        fprintf(stderr, "Shared memory error, disabling.\n");
1036
      }
1037
      gXErrorFlag = 0;
1038
      goto shmemerror;
1039
    } else {
1040
      shmctl(new->shminfo.shmid, IPC_RMID, 0);
1041
    }
1042
 
1043
    if (!quietFlag) {
1044
      fprintf(stderr, "Sharing memory.\n");
1045
    }
1046
  } else
1047
#endif
1048
    {
1049
    int temp_sz;
1050
    int factor;
1051
shmemerror:
1052
#ifndef DISABLE_DITHER
1053
    temp_sz = vid_stream->matched_depth >> 3;
1054
#else
1055
    temp_sz = 4;
1056
#endif
1057
    if(!temp_sz) temp_sz = 1;
1058
    if(temp_sz == 3) temp_sz = 4;
1059
    factor = 1 + IS_2x2_DITHER(ditherType); /* 1 or 2 */
1060
 
1061
    new->display = (unsigned char *) malloc(width * height * temp_sz *
1062
                                                            factor * factor);
1063
    }
1064
  new->luminance = (unsigned char *) malloc(width * height);
1065
  new->Cr = (unsigned char *) malloc(width * height / 4);
1066
  new->Cb = (unsigned char *) malloc(width * height / 4);
1067
 
1068
  /* Reset locked flag. */
1069
 
1070
  new->locked = 0;
1071
 
1072
  /* Return pointer to new structure. */
1073
 
1074
  return new;
1075
}
1076
 
1077
 
1078
 
1079
/*
1080
 *--------------------------------------------------------------
1081
 *
1082
 * DestroyPictImage --
1083
 *
1084
 *      Deallocates a PictImage structure.
1085
 *
1086
 * Results:
1087
 *      None.
1088
 *
1089
 * Side effects:
1090
 *      None.
1091
 *
1092
 *--------------------------------------------------------------
1093
 */
1094
void
1095
DestroyPictImage(apictimage, xinfo)
1096
  PictImage *apictimage;
1097
  XInfo *xinfo;
1098
{
1099
  if (apictimage->luminance != NULL) {
1100
    free(apictimage->luminance);
1101
  }
1102
  if (apictimage->Cr != NULL) {
1103
    free(apictimage->Cr);
1104
  }
1105
  if (apictimage->Cb != NULL) {
1106
    free(apictimage->Cb);
1107
  }
1108
#ifdef SH_MEM
1109
  if ((apictimage->ximage != NULL)&&!noDisplayFlag&&shmemFlag) {
1110
    if (xinfo!=NULL) XShmDetach(xinfo->display, &(apictimage->shminfo));
1111
    XDestroyImage(apictimage->ximage);
1112
    shmdt(apictimage->shminfo.shmaddr);
1113
    apictimage->ximage = NULL;
1114
    apictimage->display = NULL;
1115
  }
1116
#endif
1117
 
1118
  if (apictimage->display != NULL) {
1119
    free(apictimage->display);
1120
  }
1121
  free(apictimage);
1122
}
1123
 
1124
 
1125
/*
1126
 *--------------------------------------------------------------
1127
 *
1128
 * mpegVidRsrc --
1129
 *
1130
 *      Parses bit stream until MB_QUANTUM number of
1131
 *      macroblocks have been decoded or current slice or
1132
 *      picture ends, whichever comes first. If the start
1133
 *      of a frame is encountered, the frame is time stamped
1134
 *      with the value passed in time_stamp. If the value
1135
 *      passed in buffer is not null, the video stream buffer
1136
 *      is set to buffer and the length of the buffer is
1137
 *      expected in value passed in through length. The current
1138
 *      video stream is set to vid_stream. If vid_stream
1139
 *      is passed as NULL, a new VidStream structure is created
1140
 *      and initialized and used as the current video stream.
1141
 *
1142
 * Results:
1143
 *      A pointer to the video stream structure used.
1144
 *
1145
 * Side effects:
1146
 *      Bit stream is irreversibly parsed. If a picture is completed,
1147
 *      a function is called to display the frame at the correct time.
1148
 *
1149
 *--------------------------------------------------------------
1150
 */
1151
 
1152
VidStream *
1153
mpegVidRsrc(time_stamp, vid_stream, first, xinfo)
1154
  TimeStamp  time_stamp;
1155
  VidStream *vid_stream;
1156
  int        first;
1157
  XInfo     *xinfo;
1158
{
1159
  unsigned int data;
1160
  int i, status;
1161
 
1162
  /* If vid_stream is null, create new VidStream structure. */
1163
 
1164
  if (vid_stream == NULL) {
1165
    return NULL;
1166
  }
1167
 
1168
  /*
1169
   * If called for the first time, find start code, make sure it is a
1170
   * sequence start code.
1171
   */
1172
 
1173
  if (first) {
1174
    vid_stream->sys_layer=-1;
1175
    vid_stream->num_left=0;
1176
    vid_stream->leftover_bytes=0;
1177
    vid_stream->seekValue=0;
1178
    vid_stream->Parse_done=FALSE;
1179
    next_start_code(vid_stream);  /* sets curBits */
1180
    show_bits32(data);
1181
    if (data != SEQ_START_CODE) {
1182
      fprintf(stderr, "This is not an MPEG video stream. (%x)\n",data);
1183
      DestroyVidStream(vid_stream,xinfo);
1184
      return NULL;
1185
    }
1186
  } else {
1187
#ifdef UTIL2
1188
    vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;
1189
#else
1190
    vid_stream->curBits = *vid_stream->buffer;
1191
#endif
1192
  }
1193
 
1194
  /* Get next 32 bits (size of start codes). */
1195
 
1196
  show_bits32(data);
1197
 
1198
  /*
1199
   * Process according to start code (or parse macroblock if not a start code
1200
   * at all).
1201
   */
1202
 
1203
  switch (data) {
1204
 
1205
  case SEQ_END_CODE:
1206
  case 0x000001b9:   /*  handle ISO_11172_END_CODE too */
1207
 
1208
    /* Display last frame. */
1209
 
1210
    if (vid_stream->future != NULL) {
1211
      vid_stream->current = vid_stream->future;
1212
#ifndef NOCONTROLS
1213
      ExecuteDisplay(vid_stream, 1, xinfo);
1214
#else
1215
      ExecuteDisplay(vid_stream, xinfo);
1216
#endif
1217
    }
1218
 
1219
    /* Sequence done. Do the right thing. For right now, exit. */
1220
    if (!quietFlag) {
1221
      fprintf(stderr, "\nDone!\n");
1222
    }
1223
 
1224
#ifdef ANALYSIS
1225
    PrintAllStats(vid_stream);
1226
#endif
1227
    PrintTimeInfo(vid_stream);
1228
 
1229
    vid_stream->film_has_ended=TRUE;
1230
#ifdef NOCONTROLS
1231
    if (loopFlag) {
1232
      clear_data_stream(vid_stream);
1233
    } else DestroyVidStream(vid_stream, xinfo);
1234
#endif /* !NOCONTROLS */
1235
    goto done;
1236
    break;
1237
 
1238
  case SEQ_START_CODE:
1239
 
1240
    /* Sequence start code. Parse sequence header. */
1241
 
1242
    if (ParseSeqHead(vid_stream,xinfo) != PARSE_OK)
1243
      goto error;
1244
 
1245
    /*
1246
     * Return after sequence start code so that application above can use
1247
     * info in header.
1248
     */
1249
    if (vid_stream->seekValue > 0) {
1250
      SeekStream(vid_stream);      
1251
    }
1252
 
1253
 
1254
    goto done;
1255
 
1256
  case GOP_START_CODE:
1257
 
1258
    /* Group of Pictures start code. Parse gop header. */
1259
 
1260
    if (ParseGOP(vid_stream) != PARSE_OK)
1261
      goto error;
1262
    goto done;
1263
 
1264
  case PICTURE_START_CODE:
1265
 
1266
    /* Picture start code. Parse picture header and first slice header. */
1267
 
1268
    status = ParsePicture(vid_stream, time_stamp);
1269
 
1270
    if (status == SKIP_PICTURE) {
1271
      next_start_code(vid_stream);
1272
      while (!next_bits(32, PICTURE_START_CODE, vid_stream)) {
1273
        if (next_bits(32, GOP_START_CODE, vid_stream))
1274
          break;
1275
        else if (next_bits(32, SEQ_END_CODE, vid_stream))
1276
          break;
1277
        flush_bits(24);
1278
        next_start_code(vid_stream);
1279
      }
1280
      goto done;
1281
    } else if (status != PARSE_OK)
1282
      goto error;
1283
 
1284
 
1285
    if (ParseSlice(vid_stream) != PARSE_OK)
1286
      goto error;
1287
    break;
1288
 
1289
  case SEQUENCE_ERROR_CODE:
1290
    flush_bits32;
1291
    next_start_code(vid_stream);
1292
    goto done;
1293
 
1294
  default:
1295
 
1296
    /* Check for slice start code. */
1297
 
1298
    if ((data >= SLICE_MIN_START_CODE) && (data <= SLICE_MAX_START_CODE)) {
1299
 
1300
      /* Slice start code. Parse slice header. */
1301
 
1302
      if (ParseSlice(vid_stream) != PARSE_OK)
1303
        goto error;
1304
    }
1305
    break;
1306
  }
1307
 
1308
  /* Parse next MB_QUANTUM macroblocks. */
1309
 
1310
  for (i = 0; i < MB_QUANTUM; i++) {
1311
 
1312
    /* Check to see if actually a startcode and not a macroblock. */
1313
 
1314
    if (!next_bits(23, 0x00000000, vid_stream)) {
1315
 
1316
      /* Not start code. Parse Macroblock. */
1317
 
1318
      if (ParseMacroBlock(vid_stream) != PARSE_OK)
1319
        goto error;
1320
 
1321
#ifdef ANALYSIS
1322
      if (showmb_flag) {
1323
        DoDitherImage(vid_stream);
1324
#ifndef NOCONTROLS
1325
        ExecuteDisplay(vid_stream, 1, xinfo);
1326
#else
1327
        ExecuteDisplay(vid_stream, xinfo);
1328
#endif /* !NOCONTROLS */
1329
      }
1330
#endif /* ANALYSIS */
1331
 
1332
    } else {
1333
 
1334
      /* Not macroblock, actually start code. Get start code. */
1335
 
1336
      next_start_code(vid_stream);
1337
      show_bits32(data);
1338
 
1339
      /*
1340
       * If start code is outside range of slice start codes, frame is
1341
       * complete, display frame.
1342
       */
1343
 
1344
      if (((data < SLICE_MIN_START_CODE) || (data > SLICE_MAX_START_CODE)) &&
1345
          (data != SEQUENCE_ERROR_CODE)) {
1346
 
1347
#ifdef ANALYSIS
1348
        EndTime();
1349
        stat_a[0].totsize += bitCountRead() - pictureSizeCount;
1350
        if (showEachFlag) {
1351
          PrintOneStat();
1352
        };
1353
 
1354
        CollectStats();
1355
#endif
1356
 
1357
        DoPictureDisplay(vid_stream, xinfo);
1358
      }
1359
      goto done;
1360
    }
1361
  }
1362
 
1363
  /* Check if we just finished a picture on the MB_QUANTUMth macroblock */
1364
  if (next_bits(23, 0x00000000, vid_stream)) {
1365
    next_start_code(vid_stream);
1366
    show_bits32(data);
1367
    if ((data < SLICE_MIN_START_CODE) || (data > SLICE_MAX_START_CODE)) {
1368
 
1369
#ifdef ANALYSIS
1370
        EndTime();
1371
        stat_a[0].totsize += bitCountRead() - pictureSizeCount;
1372
        if (showEachFlag) {
1373
          PrintOneStat();
1374
        };
1375
 
1376
        CollectStats();
1377
#endif
1378
 
1379
        DoPictureDisplay(vid_stream, xinfo);
1380
    }
1381
  }
1382
 
1383
  /* Return pointer to video stream structure. */
1384
 
1385
  goto done;
1386
 
1387
error:
1388
  fprintf(stderr, "Error!!!!\n");
1389
  next_start_code(vid_stream);
1390
  goto done;
1391
 
1392
done:
1393
 
1394
  return vid_stream;
1395
 
1396
}
1397
 
1398
 
1399
 
1400
 
1401
/*
1402
 *--------------------------------------------------------------
1403
 *
1404
 * ParseSeqHead --
1405
 *
1406
 *      Assumes bit stream is at the begining of the sequence
1407
 *      header start code. Parses off the sequence header.
1408
 *
1409
 * Results:
1410
 *      Fills the vid_stream structure with values derived and
1411
 *      decoded from the sequence header. Allocates the pict image
1412
 *      structures based on the dimensions of the image space
1413
 *      found in the sequence header.
1414
 *
1415
 * Side effects:
1416
 *      Bit stream irreversibly parsed off.
1417
 *
1418
 *--------------------------------------------------------------
1419
 */
1420
static int
1421
ParseSeqHead(vid_stream,xinfo)
1422
  VidStream *vid_stream;
1423
  XInfo *xinfo;
1424
{
1425
  unsigned int data;
1426
  int i, ditherType=vid_stream->ditherType;
1427
 
1428
  /* Flush off sequence start code. */
1429
 
1430
  flush_bits32;
1431
 
1432
  /* Get horizontal size of image space. */
1433
 
1434
  get_bits12(data);
1435
  vid_stream->h_size = data;
1436
 
1437
  /* Get vertical size of image space. */
1438
 
1439
  get_bits12(data);
1440
  vid_stream->v_size = data;
1441
 
1442
  /* Calculate macroblock width and height of image space. */
1443
 
1444
  vid_stream->mb_width = (vid_stream->h_size + 15) / 16;
1445
  vid_stream->mb_height = (vid_stream->v_size + 15) / 16;
1446
 
1447
#ifndef DISABLE_DITHER
1448
  /* If dither type is MBORDERED allocate ditherFlags. */
1449
  if (ditherType == MBORDERED_DITHER) {
1450
    vid_stream->ditherFlags =
1451
         (char *) malloc(vid_stream->mb_width*vid_stream->mb_height);
1452
  }
1453
#endif
1454
 
1455
  /*
1456
   * Initialize ring buffer of pict images now that dimensions of image space
1457
   * are known.
1458
   */
1459
 
1460
#ifdef SH_MEM
1461
  if (xinfo->display != NULL) {
1462
    InstallXErrorHandler(xinfo->display);
1463
  }
1464
#endif
1465
 
1466
  if (vid_stream->ring[0] == NULL) {
1467
    for (i = 0; i < RING_BUF_SIZE; i++) {
1468
      vid_stream->ring[i] = NewPictImage(vid_stream,xinfo);
1469
    }
1470
  }
1471
#ifdef SH_MEM
1472
  if (xinfo->display != NULL) {
1473
    DeInstallXErrorHandler(xinfo->display);
1474
  }
1475
#endif
1476
 
1477
  /* Parse of aspect ratio code. */
1478
 
1479
  get_bits4(data);
1480
  vid_stream->aspect_ratio = (unsigned char) data;
1481
 
1482
  /* Parse off picture rate code. */
1483
 
1484
  get_bits4(data);
1485
  vid_stream->picture_rate = (unsigned char) data;
1486
 
1487
  /* Parse off bit rate. */
1488
 
1489
  get_bits18(data);
1490
  vid_stream->bit_rate = data;
1491
 
1492
  /* Flush marker bit. */
1493
 
1494
  flush_bits(1);
1495
 
1496
  /* Parse off vbv buffer size. */
1497
 
1498
  get_bits10(data);
1499
  vid_stream->vbv_buffer_size = data;
1500
 
1501
#ifdef not_def
1502
  /* Lets not bother with this.  Only increases memory image */
1503
  if (data*1024>vid_stream->max_buf_length) {
1504
    unsigned int *newbuf;
1505
    int sz=1024*data+1;
1506
    /* If they actually want a bigger buffer than we default to,
1507
       let them have it! (if we can) */
1508
    newbuf = (unsigned int *) realloc(vid_stream->buf_start, (unsigned int) 4*sz);
1509
    if (newbuf!=(unsigned int *)NULL) {
1510
      vid_stream->max_buf_length=sz;
1511
      vid_stream->buffer=
1512
          (vid_stream->buffer-vid_stream->buf_start)+newbuf;
1513
      vid_stream->buf_start=newbuf;
1514
    }}
1515
#endif
1516
 
1517
  /* Parse off contrained parameter flag. */
1518
 
1519
  get_bits1(data);
1520
  if (data) {
1521
    vid_stream->const_param_flag = TRUE;
1522
  } else
1523
    vid_stream->const_param_flag = FALSE;
1524
 
1525
  /*
1526
   * If intra_quant_matrix_flag set, parse off intra quant matrix values.
1527
   */
1528
 
1529
  get_bits1(data);
1530
  if (data) {
1531
    for (i = 0; i < 64; i++) {
1532
      get_bits8(data);
1533
 
1534
      vid_stream->intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
1535
        (unsigned char) data;
1536
    }
1537
  }
1538
  /*
1539
   * If non intra quant matrix flag set, parse off non intra quant matrix
1540
   * values.
1541
   */
1542
 
1543
  get_bits1(data);
1544
  if (data) {
1545
    for (i = 0; i < 64; i++) {
1546
      get_bits8(data);
1547
 
1548
      vid_stream->non_intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
1549
        (unsigned char) data;
1550
    }
1551
  }
1552
  /* Go to next start code. */
1553
 
1554
  next_start_code(vid_stream);
1555
 
1556
  /*
1557
   * If next start code is extension start code, parse off extension data.
1558
   */
1559
 
1560
  if (next_bits(32, EXT_START_CODE, vid_stream)) {
1561
    flush_bits32;
1562
    if (vid_stream->ext_data != NULL) {
1563
      free(vid_stream->ext_data);
1564
      vid_stream->ext_data = NULL;
1565
    }
1566
    vid_stream->ext_data = get_ext_data(vid_stream);
1567
  }
1568
  /* If next start code is user start code, parse off user data. */
1569
 
1570
  if (next_bits(32, USER_START_CODE, vid_stream)) {
1571
    flush_bits32;
1572
    if (vid_stream->user_data != NULL) {
1573
      free(vid_stream->user_data);
1574
      vid_stream->user_data = NULL;
1575
    }
1576
    vid_stream->user_data = get_ext_data(vid_stream);
1577
  }
1578
  return PARSE_OK;
1579
}
1580
 
1581
 
1582
 
1583
/*
1584
 *--------------------------------------------------------------
1585
 *
1586
 * ParseGOP --
1587
 *
1588
 *      Parses of group of pictures header from bit stream
1589
 *      associated with vid_stream.
1590
 *
1591
 * Results:
1592
 *      Values in gop header placed into video stream structure.
1593
 *
1594
 * Side effects:
1595
 *      Bit stream irreversibly parsed.
1596
 *
1597
 *--------------------------------------------------------------
1598
 */
1599
 
1600
static int
1601
ParseGOP(vid_stream)
1602
  VidStream *vid_stream;
1603
{
1604
  unsigned int data;
1605
 
1606
  /* Flush group of pictures start code. */
1607
 
1608
  flush_bits32;
1609
 
1610
  /* Parse off drop frame flag. */
1611
 
1612
  get_bits1(data);
1613
  if (data) {
1614
    vid_stream->group.drop_flag = TRUE;
1615
  } else
1616
    vid_stream->group.drop_flag = FALSE;
1617
 
1618
  /* Parse off hour component of time code. */
1619
 
1620
  get_bits5(data);
1621
  vid_stream->group.tc_hours = data;
1622
 
1623
  /* Parse off minute component of time code. */
1624
 
1625
  get_bits6(data);
1626
  vid_stream->group.tc_minutes = data;
1627
 
1628
  /* Flush marker bit. */
1629
 
1630
  flush_bits(1);
1631
 
1632
  /* Parse off second component of time code. */
1633
 
1634
  get_bits6(data);
1635
  vid_stream->group.tc_seconds = data;
1636
 
1637
  /* Parse off picture count component of time code. */
1638
 
1639
  get_bits6(data);
1640
  vid_stream->group.tc_pictures = data;
1641
 
1642
  /* Parse off closed gop and broken link flags. */
1643
 
1644
  get_bits2(data);
1645
  if (data > 1) {
1646
    vid_stream->group.closed_gop = TRUE;
1647
    if (data > 2) {
1648
      vid_stream->group.broken_link = TRUE;
1649
    } else
1650
      vid_stream->group.broken_link = FALSE;
1651
  } else {
1652
    vid_stream->group.closed_gop = FALSE;
1653
    if (data) {
1654
      vid_stream->group.broken_link = TRUE;
1655
    } else
1656
      vid_stream->group.broken_link = FALSE;
1657
  }
1658
 
1659
  /* Goto next start code. */
1660
 
1661
  next_start_code(vid_stream);
1662
 
1663
  /* If next start code is extension data, parse off extension data. */
1664
 
1665
  if (next_bits(32, EXT_START_CODE, vid_stream)) {
1666
    flush_bits32;
1667
    if (vid_stream->group.ext_data != NULL) {
1668
      free(vid_stream->group.ext_data);
1669
      vid_stream->group.ext_data = NULL;
1670
    }
1671
    vid_stream->group.ext_data = get_ext_data(vid_stream);
1672
  }
1673
  /* If next start code is user data, parse off user data. */
1674
 
1675
  if (next_bits(32, USER_START_CODE,vid_stream)) {
1676
    flush_bits32;
1677
    if (vid_stream->group.user_data != NULL) {
1678
      free(vid_stream->group.user_data);
1679
      vid_stream->group.user_data = NULL;
1680
    }
1681
    vid_stream->group.user_data = get_ext_data(vid_stream);
1682
  }
1683
  return PARSE_OK;
1684
}
1685
 
1686
 
1687
 
1688
/*
1689
 *--------------------------------------------------------------
1690
 *
1691
 * ParsePicture --
1692
 *
1693
 *      Parses picture header. Marks picture to be presented
1694
 *      at particular time given a time stamp.
1695
 *
1696
 * Results:
1697
 *      Values from picture header put into video stream structure.
1698
 *
1699
 * Side effects:
1700
 *      Bit stream irreversibly parsed.
1701
 *
1702
 *--------------------------------------------------------------
1703
 */
1704
 
1705
static int
1706
ParsePicture(vid_stream, time_stamp)
1707
  VidStream *vid_stream;
1708
  TimeStamp time_stamp;
1709
{
1710
  unsigned int data;
1711
  int i;
1712
 
1713
  /* Flush header start code. */
1714
  flush_bits32;
1715
 
1716
  /* Parse off temporal reference. */
1717
  get_bits10(data);
1718
  vid_stream->picture.temp_ref = data;
1719
 
1720
  /* Parse of picture type. */
1721
  get_bits3(data);
1722
  vid_stream->picture.code_type = data;
1723
 
1724
  if ((vid_stream->picture.code_type == B_TYPE) &&
1725
      (/* No_B_Flag || */
1726
       (vid_stream->future == NULL) ||
1727
       ((vid_stream->past == NULL) && !(vid_stream->group.closed_gop))))
1728
    /* According to 2-D.5.1 (p D-18) this is ok, if the refereneces are OK */
1729
    return SKIP_PICTURE;
1730
 
1731
  if ((vid_stream->picture.code_type == P_TYPE) &&
1732
      (No_P_Flag || (vid_stream->future == NULL)))
1733
    return SKIP_PICTURE;
1734
 
1735
#ifdef ANALYSIS
1736
  StartTime();
1737
  stat_a[0].frametype = vid_stream->picture.code_type;
1738
  stat_a[0].number = 1;
1739
  stat_a[0].totsize = 45;
1740
  pictureSizeCount = bitCountRead();
1741
#endif
1742
 
1743
  /* Parse off vbv buffer delay value. */
1744
  get_bits16(data);
1745
  vid_stream->picture.vbv_delay = data;
1746
 
1747
  /* If P or B type frame... */
1748
 
1749
  if ((vid_stream->picture.code_type == P_TYPE) ||
1750
      (vid_stream->picture.code_type == B_TYPE)) {
1751
 
1752
    /* Parse off forward vector full pixel flag. */
1753
    get_bits1(data);
1754
    if (data) {
1755
      vid_stream->picture.full_pel_forw_vector = TRUE;
1756
    } else {
1757
      vid_stream->picture.full_pel_forw_vector = FALSE;
1758
    }
1759
 
1760
    /* Parse of forw_r_code. */
1761
    get_bits3(data);
1762
 
1763
    /* Decode forw_r_code into forw_r_size and forw_f. */
1764
 
1765
    vid_stream->picture.forw_r_size = data - 1;
1766
    vid_stream->picture.forw_f = (1 << vid_stream->picture.forw_r_size);
1767
  }
1768
  /* If B type frame... */
1769
 
1770
  if (vid_stream->picture.code_type == B_TYPE) {
1771
 
1772
    /* Parse off back vector full pixel flag. */
1773
    get_bits1(data);
1774
    if (data)
1775
      vid_stream->picture.full_pel_back_vector = TRUE;
1776
    else
1777
      vid_stream->picture.full_pel_back_vector = FALSE;
1778
 
1779
    /* Parse off back_r_code. */
1780
    get_bits3(data);
1781
 
1782
    /* Decode back_r_code into back_r_size and back_f. */
1783
 
1784
    vid_stream->picture.back_r_size = data - 1;
1785
    vid_stream->picture.back_f = (1 << vid_stream->picture.back_r_size);
1786
  }
1787
  /* Get extra bit picture info. */
1788
 
1789
  if (vid_stream->picture.extra_info != NULL) {
1790
    free(vid_stream->picture.extra_info);
1791
    vid_stream->picture.extra_info = NULL;
1792
  }
1793
  vid_stream->picture.extra_info = get_extra_bit_info(vid_stream);
1794
 
1795
  /* Goto next start code. */
1796
  next_start_code(vid_stream);
1797
 
1798
  /* If start code is extension start code, parse off extension data. */
1799
 
1800
  if (next_bits(32, EXT_START_CODE, vid_stream)) {
1801
    flush_bits32;
1802
 
1803
    if (vid_stream->picture.ext_data != NULL) {
1804
      free(vid_stream->picture.ext_data);
1805
      vid_stream->picture.ext_data = NULL;
1806
    }
1807
    vid_stream->picture.ext_data = get_ext_data(vid_stream);
1808
  }
1809
  /* If start code is user start code, parse off user data. */
1810
 
1811
  if (next_bits(32, USER_START_CODE, vid_stream)) {
1812
    flush_bits32;
1813
 
1814
    if (vid_stream->picture.user_data != NULL) {
1815
      free(vid_stream->picture.user_data);
1816
      vid_stream->picture.user_data = NULL;
1817
    }
1818
    vid_stream->picture.user_data = get_ext_data(vid_stream);
1819
  }
1820
  /* Find a pict image structure in ring buffer not currently locked. */
1821
 
1822
  i = 0;
1823
 
1824
  while (vid_stream->ring[i]->locked != 0) {
1825
    if (++i >= RING_BUF_SIZE) {
1826
      perror("Fatal error. Ring buffer full.");
1827
      exit(1);
1828
    }
1829
  }
1830
 
1831
  /* Set current pict image structure to the one just found in ring. */
1832
 
1833
  vid_stream->current = vid_stream->ring[i];
1834
 
1835
  /* Set time stamp. */
1836
 
1837
  vid_stream->current->show_time = time_stamp;
1838
 
1839
  /* Reset past macroblock address field. */
1840
 
1841
  vid_stream->mblock.past_mb_addr = -1;
1842
 
1843
  return PARSE_OK;
1844
}
1845
 
1846
 
1847
 
1848
/*
1849
 *--------------------------------------------------------------
1850
 *
1851
 * ParseSlice --
1852
 *
1853
 *      Parses off slice header.
1854
 *
1855
 * Results:
1856
 *      Values found in slice header put into video stream structure.
1857
 *
1858
 * Side effects:
1859
 *      Bit stream irreversibly parsed.
1860
 *
1861
 *--------------------------------------------------------------
1862
 */
1863
 
1864
static int
1865
ParseSlice(vid_stream)
1866
  VidStream *vid_stream;
1867
{
1868
  unsigned int data;
1869
 
1870
  /* Flush slice start code. */
1871
 
1872
  flush_bits(24);
1873
 
1874
  /* Parse off slice vertical position. */
1875
 
1876
  get_bits8(data);
1877
  vid_stream->slice.vert_pos = data;
1878
 
1879
  /* Parse off quantization scale. */
1880
 
1881
  get_bits5(data);
1882
  vid_stream->slice.quant_scale = data;
1883
 
1884
  /* Parse off extra bit slice info. */
1885
 
1886
  if (vid_stream->slice.extra_info != NULL) {
1887
    free(vid_stream->slice.extra_info);
1888
    vid_stream->slice.extra_info = NULL;
1889
  }
1890
  vid_stream->slice.extra_info = get_extra_bit_info(vid_stream);
1891
 
1892
  /* Reset past intrablock address. */
1893
 
1894
  vid_stream->mblock.past_intra_addr = -2;
1895
 
1896
  /* Reset previous recon motion vectors. */
1897
 
1898
  vid_stream->mblock.recon_right_for_prev = 0;
1899
  vid_stream->mblock.recon_down_for_prev = 0;
1900
  vid_stream->mblock.recon_right_back_prev = 0;
1901
  vid_stream->mblock.recon_down_back_prev = 0;
1902
 
1903
  /* Reset macroblock address. */
1904
 
1905
  vid_stream->mblock.mb_address = ((vid_stream->slice.vert_pos - 1) *
1906
                                   vid_stream->mb_width) - 1;
1907
 
1908
  /* Reset past dct dc y, cr, and cb values. */
1909
 
1910
  vid_stream->block.dct_dc_y_past = 1024 << 3;
1911
  vid_stream->block.dct_dc_cr_past = 1024 << 3;
1912
  vid_stream->block.dct_dc_cb_past = 1024 << 3;
1913
 
1914
  return PARSE_OK;
1915
}
1916
 
1917
 
1918
 
1919
/*
1920
 *--------------------------------------------------------------
1921
 *
1922
 * ParseMacroBlock --
1923
 *
1924
 *      Parseoff macroblock. Reconstructs DCT values. Applies
1925
 *      inverse DCT, reconstructs motion vectors, calculates and
1926
 *      set pixel values for macroblock in current pict image
1927
 *      structure.
1928
 *
1929
 * Results:
1930
 *      Here's where everything really happens. Welcome to the
1931
 *      heart of darkness.
1932
 *
1933
 * Side effects:
1934
 *      Bit stream irreversibly parsed off.
1935
 *
1936
 *--------------------------------------------------------------
1937
 */
1938
 
1939
static int
1940
ParseMacroBlock(vid_stream)
1941
  VidStream *vid_stream;
1942
{
1943
  int addr_incr;
1944
  unsigned int data;
1945
  int mask, i, recon_right_for, recon_down_for, recon_right_back,
1946
      recon_down_back;
1947
  int zero_block_flag;
1948
  BOOLEAN mb_quant = 0, mb_motion_forw = 0, mb_motion_back = 0,
1949
      mb_pattern = 0;
1950
  int no_dith_flag = 0;
1951
  int ditherType = vid_stream->ditherType;
1952
 
1953
#ifdef ANALYSIS
1954
  mbSizeCount = bitCountRead();
1955
#endif
1956
 
1957
  /*
1958
   * Parse off macroblock address increment and add to macroblock address.
1959
   */
1960
  do {
1961
    unsigned int ind;                                  
1962
    show_bits11(ind);                                  
1963
    DecodeMBAddrInc(addr_incr);
1964
    if (mb_addr_inc[ind].num_bits==0) {
1965
      addr_incr = 1;
1966
    }
1967
    if (addr_incr == MB_ESCAPE) {
1968
      vid_stream->mblock.mb_address += 33;
1969
      addr_incr = MB_STUFFING;
1970
    }
1971
  } while (addr_incr == MB_STUFFING);
1972
  vid_stream->mblock.mb_address += addr_incr;
1973
 
1974
  if (vid_stream->mblock.mb_address > (vid_stream->mb_height *
1975
                                       vid_stream->mb_width - 1))
1976
    return SKIP_TO_START_CODE;
1977
 
1978
  /*
1979
   * If macroblocks have been skipped, process skipped macroblocks.
1980
   */
1981
 
1982
  if (vid_stream->mblock.mb_address - vid_stream->mblock.past_mb_addr > 1) {
1983
    if (vid_stream->picture.code_type == P_TYPE)
1984
      ProcessSkippedPFrameMBlocks(vid_stream);
1985
    else if (vid_stream->picture.code_type == B_TYPE)
1986
      ProcessSkippedBFrameMBlocks(vid_stream);
1987
  }
1988
  /* Set past macroblock address to current macroblock address. */
1989
  vid_stream->mblock.past_mb_addr = vid_stream->mblock.mb_address;
1990
 
1991
  /* Based on picture type decode macroblock type. */
1992
  switch (vid_stream->picture.code_type) {
1993
  case I_TYPE:
1994
    DecodeMBTypeI(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
1995
                  vid_stream->mblock.mb_intra);
1996
    break;
1997
 
1998
  case P_TYPE:
1999
    DecodeMBTypeP(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
2000
                  vid_stream->mblock.mb_intra);
2001
    break;
2002
 
2003
  case B_TYPE:
2004
    DecodeMBTypeB(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
2005
                  vid_stream->mblock.mb_intra);
2006
    break;
2007
  case D_TYPE:
2008
    fprintf(stderr, "ERROR:  MPEG-1 Streams with D-frames are not supported\n");
2009
    exit(1);
2010
  }
2011
 
2012
  /* If quantization flag set, parse off new quantization scale. */
2013
 
2014
  if (mb_quant == TRUE) {
2015
    get_bits5(data);
2016
    vid_stream->slice.quant_scale = data;
2017
  }
2018
  /* If forward motion vectors exist... */
2019
  if (mb_motion_forw == TRUE) {
2020
 
2021
    /* Parse off and decode horizontal forward motion vector. */
2022
    DecodeMotionVectors(vid_stream->mblock.motion_h_forw_code);
2023
 
2024
    /* If horiz. forward r data exists, parse off. */
2025
 
2026
    if ((vid_stream->picture.forw_f != 1) &&
2027
        (vid_stream->mblock.motion_h_forw_code != 0)) {
2028
      get_bitsn(vid_stream->picture.forw_r_size, data);
2029
      vid_stream->mblock.motion_h_forw_r = data;
2030
    }
2031
    /* Parse off and decode vertical forward motion vector. */
2032
    DecodeMotionVectors(vid_stream->mblock.motion_v_forw_code);
2033
 
2034
    /* If vert. forw. r data exists, parse off. */
2035
 
2036
    if ((vid_stream->picture.forw_f != 1) &&
2037
        (vid_stream->mblock.motion_v_forw_code != 0)) {
2038
      get_bitsn(vid_stream->picture.forw_r_size, data);
2039
      vid_stream->mblock.motion_v_forw_r = data;
2040
    }
2041
  }
2042
  /* If back motion vectors exist... */
2043
  if (mb_motion_back == TRUE) {
2044
 
2045
    /* Parse off and decode horiz. back motion vector. */
2046
    DecodeMotionVectors(vid_stream->mblock.motion_h_back_code);
2047
 
2048
    /* If horiz. back r data exists, parse off. */
2049
 
2050
    if ((vid_stream->picture.back_f != 1) &&
2051
        (vid_stream->mblock.motion_h_back_code != 0)) {
2052
      get_bitsn(vid_stream->picture.back_r_size, data);
2053
      vid_stream->mblock.motion_h_back_r = data;
2054
    }
2055
    /* Parse off and decode vert. back motion vector. */
2056
    DecodeMotionVectors(vid_stream->mblock.motion_v_back_code);
2057
 
2058
    /* If vert. back r data exists, parse off. */
2059
 
2060
    if ((vid_stream->picture.back_f != 1) &&
2061
        (vid_stream->mblock.motion_v_back_code != 0)) {
2062
      get_bitsn(vid_stream->picture.back_r_size, data);
2063
      vid_stream->mblock.motion_v_back_r = data;
2064
    }
2065
  }
2066
#ifdef ANALYSIS
2067
  if (vid_stream->mblock.mb_intra) {
2068
    stat_a[0].i_mbnum++;
2069
    mbCBPPtr = stat_a[0].i_mbcbp;
2070
    mbCoeffPtr = stat_a[0].i_mbcoeff;
2071
    mbSizePtr = &(stat_a[0].i_mbsize);
2072
  } else if (mb_motion_back && mb_motion_forw) {
2073
    stat_a[0].bi_mbnum++;
2074
    mbCBPPtr = stat_a[0].bi_mbcbp;
2075
    mbCoeffPtr = stat_a[0].bi_mbcoeff;
2076
    mbSizePtr = &(stat_a[0].bi_mbsize);
2077
  } else if (mb_motion_back) {
2078
    stat_a[0].b_mbnum++;
2079
    mbCBPPtr = stat_a[0].b_mbcbp;
2080
    mbCoeffPtr = stat_a[0].b_mbcoeff;
2081
    mbSizePtr = &(stat_a[0].b_mbsize);
2082
  } else {
2083
    stat_a[0].p_mbnum++;
2084
    mbCBPPtr = stat_a[0].p_mbcbp;
2085
    mbCoeffPtr = stat_a[0].p_mbcoeff;
2086
    mbSizePtr = &(stat_a[0].p_mbsize);
2087
  }
2088
#endif
2089
 
2090
  /* If mblock pattern flag set, parse and decode CBP (code block pattern). */
2091
  if (mb_pattern == TRUE) {
2092
    DecodeCBP(vid_stream->mblock.cbp);
2093
  }
2094
  /* Otherwise, set CBP to zero. */
2095
  else
2096
    vid_stream->mblock.cbp = 0;
2097
 
2098
 
2099
#ifdef ANALYSIS
2100
  mbCBPPtr[vid_stream->mblock.cbp]++;
2101
#endif
2102
 
2103
  /* Reconstruct motion vectors depending on picture type. */
2104
  if (vid_stream->picture.code_type == P_TYPE) {
2105
 
2106
    /*
2107
     * If no forw motion vectors, reset previous and current vectors to 0.
2108
     */
2109
 
2110
    if (!mb_motion_forw) {
2111
      recon_right_for = 0;
2112
      recon_down_for = 0;
2113
      vid_stream->mblock.recon_right_for_prev = 0;
2114
      vid_stream->mblock.recon_down_for_prev = 0;
2115
    }
2116
    /*
2117
     * Otherwise, compute new forw motion vectors. Reset previous vectors to
2118
     * current vectors.
2119
     */
2120
 
2121
    else {
2122
      ComputeForwVector(&recon_right_for, &recon_down_for, vid_stream);
2123
    }
2124
  }
2125
  if (vid_stream->picture.code_type == B_TYPE) {
2126
 
2127
    /* Reset prev. and current vectors to zero if mblock is intracoded. */
2128
 
2129
    if (vid_stream->mblock.mb_intra) {
2130
      vid_stream->mblock.recon_right_for_prev = 0;
2131
      vid_stream->mblock.recon_down_for_prev = 0;
2132
      vid_stream->mblock.recon_right_back_prev = 0;
2133
      vid_stream->mblock.recon_down_back_prev = 0;
2134
    } else {
2135
 
2136
      /* If no forw vectors, current vectors equal prev. vectors. */
2137
 
2138
      if (!mb_motion_forw) {
2139
        recon_right_for = vid_stream->mblock.recon_right_for_prev;
2140
        recon_down_for = vid_stream->mblock.recon_down_for_prev;
2141
      }
2142
      /*
2143
       * Otherwise compute forw. vectors. Reset prev vectors to new values.
2144
       */
2145
 
2146
      else {
2147
        ComputeForwVector(&recon_right_for, &recon_down_for, vid_stream);
2148
      }
2149
 
2150
      /* If no back vectors, set back vectors to prev back vectors. */
2151
 
2152
      if (!mb_motion_back) {
2153
        recon_right_back = vid_stream->mblock.recon_right_back_prev;
2154
        recon_down_back = vid_stream->mblock.recon_down_back_prev;
2155
      }
2156
      /* Otherwise compute new vectors and reset prev. back vectors. */
2157
 
2158
      else {
2159
        ComputeBackVector(&recon_right_back, &recon_down_back, vid_stream);
2160
      }
2161
 
2162
      /*
2163
       * Store vector existence flags in structure for possible skipped
2164
       * macroblocks to follow.
2165
       */
2166
 
2167
      vid_stream->mblock.bpict_past_forw = mb_motion_forw;
2168
      vid_stream->mblock.bpict_past_back = mb_motion_back;
2169
    }
2170
  }
2171
 
2172
#ifndef DISABLE_DITHER
2173
  /* For each possible block in macroblock. */
2174
  if (ditherType == GRAY_DITHER ||
2175
      ditherType == GRAY2_DITHER ||
2176
      ditherType == GRAY256_DITHER ||
2177
      ditherType == GRAY2562_DITHER ||
2178
      ditherType == MONO_DITHER ||
2179
      ditherType == MONO_THRESHOLD) {
2180
    for (mask = 32, i = 0; i < 4; mask >>= 1, i++) {
2181
 
2182
      /* If block exists... */
2183
      if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {
2184
        zero_block_flag = 0;
2185
        ParseReconBlock(i, vid_stream);
2186
      } else {
2187
        zero_block_flag = 1;
2188
      }
2189
 
2190
      /* If macroblock is intra coded... */
2191
      if (vid_stream->mblock.mb_intra) {
2192
        ReconIMBlock(vid_stream, i);
2193
      } else if (mb_motion_forw && mb_motion_back) {
2194
        ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,
2195
                    recon_right_back, recon_down_back, zero_block_flag);
2196
      } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
2197
        ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,
2198
                    zero_block_flag);
2199
      } else if (mb_motion_back) {
2200
        ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,
2201
                    zero_block_flag);
2202
      }
2203
    }
2204
    /* Kill the Chrominance blocks... */
2205
    if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x2)) {
2206
        ParseAwayBlock(4, vid_stream);
2207
    }
2208
    if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x1)) {
2209
        ParseAwayBlock(5, vid_stream);
2210
    }
2211
  } else {
2212
    if ((ditherType == MBORDERED_DITHER) &&
2213
        (vid_stream->mblock.cbp == 0) &&
2214
        (vid_stream->picture.code_type == 3) &&
2215
        (!vid_stream->mblock.mb_intra) &&
2216
        (!(mb_motion_forw && mb_motion_back))) {
2217
      MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address,
2218
                     mb_motion_forw, recon_right_for, recon_down_for,
2219
                     mb_motion_back, recon_right_back, recon_down_back,
2220
                     vid_stream->past->display, vid_stream->future->display);
2221
      vid_stream->ditherFlags[vid_stream->mblock.mb_address] = 0;
2222
      no_dith_flag = 1;
2223
    }
2224
    else {
2225
#endif
2226
      for (mask = 32, i = 0; i < 6; mask >>= 1, i++) {
2227
 
2228
        /* If block exists... */
2229
        if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {
2230
          zero_block_flag = 0;
2231
          ParseReconBlock(i, vid_stream);
2232
        } else {
2233
          zero_block_flag = 1;
2234
        }
2235
 
2236
        /* If macroblock is intra coded... */
2237
        if (vid_stream->mblock.mb_intra) {
2238
          ReconIMBlock(vid_stream, i);
2239
        } else if (mb_motion_forw && mb_motion_back) {
2240
          ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,
2241
                        recon_right_back, recon_down_back, zero_block_flag);
2242
        } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
2243
          ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,
2244
                       zero_block_flag);
2245
        } else if (mb_motion_back) {
2246
          ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,
2247
                       zero_block_flag);
2248
        }
2249
      }
2250
#ifndef DISABLE_DITHER
2251
    }
2252
  }
2253
#endif
2254
 
2255
#ifndef DISABLE_DITHER
2256
  if ((ditherType == MBORDERED_DITHER) && (!no_dith_flag)) {
2257
    if ((vid_stream->picture.code_type == 2) &&
2258
        (vid_stream->mblock.cbp == 0) &&
2259
        (!vid_stream->mblock.mb_intra)) {
2260
      MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address,
2261
                                 1, recon_right_for, recon_down_for,
2262
                                 0, 0, 0,
2263
                                 vid_stream->future->display,
2264
                                 (unsigned char *) NULL);
2265
      vid_stream->ditherFlags[vid_stream->mblock.mb_address] = 0;
2266
    }
2267
    else {
2268
      vid_stream->ditherFlags[vid_stream->mblock.mb_address] = 1;
2269
    }
2270
  }
2271
#endif
2272
 
2273
  /* If D Type picture, flush marker bit. */
2274
  if (vid_stream->picture.code_type == 4)
2275
    flush_bits(1);
2276
 
2277
  /* If macroblock was intracoded, set macroblock past intra address. */
2278
  if (vid_stream->mblock.mb_intra)
2279
    vid_stream->mblock.past_intra_addr =
2280
      vid_stream->mblock.mb_address;
2281
 
2282
#ifdef ANALYSIS
2283
  *mbSizePtr += bitCountRead() - mbSizeCount;
2284
#endif
2285
  return PARSE_OK;
2286
}
2287
 
2288
 
2289
 
2290
/*
2291
 *--------------------------------------------------------------
2292
 *
2293
 * ReconIMBlock --
2294
 *
2295
 *      Reconstructs intra coded macroblock.
2296
 *
2297
 * Results:
2298
 *      None.
2299
 *
2300
 * Side effects:
2301
 *      None.
2302
 *
2303
 *--------------------------------------------------------------
2304
 */
2305
#ifndef NDEBUG
2306
/* If people really want to see such things, check 'em */
2307
#define myassert(x,expression)\
2308
  if (!(expression)) {\
2309
  fprintf (stderr,"Bad crop value (%d) at line %d\n", x, __LINE__);\
2310
  next_start_code(vid_stream); return;}
2311
#define assertCrop(x)   myassert(x,((x) >= -MAX_NEG_CROP) && \
2312
                                 ((x) <= 2048+MAX_NEG_CROP))
2313
#else
2314
#define assertCrop(x)
2315
#endif
2316
 
2317
static void
2318
ReconIMBlock(vid_stream, bnum)
2319
  VidStream *vid_stream;
2320
  int bnum;
2321
{
2322
  int mb_row, mb_col, row, col, row_size, rr;
2323
  unsigned char *dest;
2324
 
2325
  /* Calculate macroblock row and column from address. */
2326
 
2327
  mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
2328
  mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
2329
 
2330
 
2331
  /* If block is luminance block... */
2332
 
2333
  if (bnum < 4) {
2334
 
2335
    /* Calculate row and col values for upper left pixel of block. */
2336
 
2337
    row = mb_row * 16;
2338
    col = mb_col * 16;
2339
    if (bnum > 1)
2340
      row += 8;
2341
    if (bnum % 2)
2342
      col += 8;
2343
 
2344
    /* Set dest to luminance plane of current pict image. */
2345
 
2346
    dest = vid_stream->current->luminance;
2347
 
2348
    /* Establish row size. */
2349
 
2350
    row_size = vid_stream->mb_width * 16;
2351
  }
2352
  /* Otherwise if block is Cr block... */
2353
  /* Cr first because of the earlier mixup */
2354
 
2355
  else if (bnum == 5) {
2356
 
2357
    /* Set dest to Cr plane of current pict image. */
2358
 
2359
    dest = vid_stream->current->Cr;
2360
 
2361
    /* Establish row size. */
2362
 
2363
    row_size = vid_stream->mb_width * 8;
2364
 
2365
    /* Calculate row,col for upper left pixel of block. */
2366
 
2367
    row = mb_row * 8;
2368
    col = mb_col * 8;
2369
  }
2370
  /* Otherwise block is Cb block, and ... */
2371
 
2372
  else {
2373
 
2374
    /* Set dest to Cb plane of current pict image. */
2375
 
2376
    dest = vid_stream->current->Cb;
2377
 
2378
    /* Establish row size. */
2379
 
2380
    row_size = vid_stream->mb_width * 8;
2381
 
2382
    /* Calculate row,col for upper left pixel value of block. */
2383
 
2384
    row = mb_row * 8;
2385
    col = mb_col * 8;
2386
  }
2387
 
2388
  /*
2389
   * For each pixel in block, set to cropped reconstructed value from inverse
2390
   * dct.
2391
   */
2392
  {
2393
    short *sp = &vid_stream->block.dct_recon[0][0];
2394
    unsigned char *cm = cropTbl + MAX_NEG_CROP;
2395
    dest += row * row_size + col;
2396
    for (rr = 0; rr < 4; rr++, sp += 16, dest += row_size) {
2397
      dest[0] = cm[sp[0]];
2398
          assertCrop(sp[0]);
2399
      dest[1] = cm[sp[1]];
2400
      assertCrop(sp[1]);
2401
      dest[2] = cm[sp[2]];
2402
      assertCrop(sp[2]);
2403
      dest[3] = cm[sp[3]];
2404
      assertCrop(sp[3]);
2405
      dest[4] = cm[sp[4]];
2406
      assertCrop(sp[4]);
2407
      dest[5] = cm[sp[5]];
2408
      assertCrop(sp[5]);
2409
      dest[6] = cm[sp[6]];
2410
      assertCrop(sp[6]);
2411
      dest[7] = cm[sp[7]];
2412
      assertCrop(sp[7]);
2413
 
2414
      dest += row_size;
2415
      dest[0] = cm[sp[8]];
2416
      assertCrop(sp[8]);
2417
      dest[1] = cm[sp[9]];
2418
      assertCrop(sp[9]);
2419
      dest[2] = cm[sp[10]];
2420
      assertCrop(sp[10]);
2421
      dest[3] = cm[sp[11]];
2422
      assertCrop(sp[11]);
2423
      dest[4] = cm[sp[12]];
2424
      assertCrop(sp[12]);
2425
      dest[5] = cm[sp[13]];
2426
      assertCrop(sp[13]);
2427
      dest[6] = cm[sp[14]];
2428
      assertCrop(sp[14]);
2429
      dest[7] = cm[sp[15]];
2430
      assertCrop(sp[15]);
2431
    }
2432
  }
2433
}
2434
 
2435
 
2436
 
2437
/*
2438
 *--------------------------------------------------------------
2439
 *
2440
 * ReconPMBlock --
2441
 *
2442
 *      Reconstructs forward predicted macroblocks.
2443
 *
2444
 * Results:
2445
 *      None.
2446
 *
2447
 * Side effects:
2448
 *      None.
2449
 *
2450
 *--------------------------------------------------------------
2451
 */
2452
 
2453
static void
2454
ReconPMBlock(vid_stream, bnum, recon_right_for, recon_down_for, zflag)
2455
  VidStream *vid_stream;
2456
  int bnum, recon_right_for, recon_down_for, zflag;
2457
{
2458
  int mb_row, mb_col, row, col, row_size, rr;
2459
  unsigned char *dest, *past;
2460
  unsigned char *rindex1, *rindex2, *rindex3, *rindex4;
2461
  unsigned char *index;
2462
  short int *blockvals;
2463
 
2464
#ifdef LOOSE_MPEG
2465
  int maxx, maxy, cc;
2466
  int illegalBlock = 0;
2467
  int row_start, row_end, rfirst, rlast, col_start, col_end, cfirst, clast;
2468
#endif
2469
 
2470
  /* Calculate macroblock row and column from address. */
2471
 
2472
  mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
2473
  mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
2474
 
2475
  if (bnum < 4) {
2476
 
2477
    /* Calculate right_for, down_for motion vectors. */
2478
 
2479
    vid_stream->right_for = recon_right_for >> 1;
2480
    vid_stream->down_for = recon_down_for >> 1;
2481
    vid_stream->right_half_for = recon_right_for & 0x1;
2482
    vid_stream->down_half_for = recon_down_for & 0x1;
2483
 
2484
    /* Set dest to luminance plane of current pict image. */
2485
 
2486
    dest = vid_stream->current->luminance;
2487
 
2488
    if (vid_stream->picture.code_type == B_TYPE) {
2489
      if (vid_stream->past != NULL)
2490
       past = vid_stream->past->luminance;
2491
    } else {
2492
 
2493
      /* Set predictive frame to current future frame. */
2494
 
2495
      if (vid_stream->future != NULL)
2496
        past = vid_stream->future->luminance;
2497
    }
2498
 
2499
    /* Establish row size. */
2500
 
2501
    row_size = vid_stream->mb_width << 4;
2502
 
2503
    /* Calculate row,col of upper left pixel in block. */
2504
 
2505
    row = mb_row << 4;
2506
    col = mb_col << 4;
2507
    if (bnum > 1)
2508
      row += 8;
2509
    if (bnum % 2)
2510
      col += 8;
2511
 
2512
#ifdef LOOSE_MPEG
2513
    /* Check for block illegality. */
2514
 
2515
    maxx = vid_stream->mb_width*16-1;
2516
    maxy = vid_stream->mb_height*16-1;
2517
 
2518
    if (row + vid_stream->down_for + 7 > maxy) illegalBlock |= 0x4;
2519
    else if (row + vid_stream->down_for < 0)  illegalBlock |= 0x1;
2520
 
2521
    if (col + vid_stream->right_for + 7 > maxx) illegalBlock |= 0x2;
2522
    else if (col + vid_stream->right_for < 0) illegalBlock |= 0x8;
2523
 
2524
#endif
2525
  }
2526
  /* Otherwise, block is NOT luminance block, ... */
2527
 
2528
  else {
2529
 
2530
    /* Construct motion vectors. */
2531
 
2532
    recon_right_for /= 2;
2533
    recon_down_for /= 2;
2534
    vid_stream->right_for = recon_right_for >> 1;
2535
    vid_stream->down_for = recon_down_for >> 1;
2536
    vid_stream->right_half_for = recon_right_for & 0x1;
2537
    vid_stream->down_half_for = recon_down_for & 0x1;
2538
 
2539
    /* Establish row size. */
2540
 
2541
    row_size = vid_stream->mb_width << 3;
2542
 
2543
    /* Calculate row,col of upper left pixel in block. */
2544
 
2545
    row = mb_row << 3;
2546
    col = mb_col << 3;
2547
 
2548
#ifdef LOOSE_MPEG
2549
    /* Check for block illegality. */
2550
 
2551
    maxx = vid_stream->mb_width*16-1;
2552
    maxy = vid_stream->mb_height*16-1;
2553
 
2554
    if (row + vid_stream->down_for  + 7 > maxy) illegalBlock |= 0x4;
2555
    else if (row + vid_stream->down_for < 0) illegalBlock |= 0x1;
2556
 
2557
    if (col + vid_stream->right_for  + 7 > maxx) illegalBlock  |= 0x2;
2558
    else if (col + vid_stream->right_for < 0) illegalBlock |= 0x8;
2559
 
2560
#endif
2561
 
2562
    /* If block is Cr block... */
2563
    /* 5 first because order was mixed up in earlier versions */
2564
 
2565
    if (bnum == 5) {
2566
 
2567
      /* Set dest to Cr plane of current pict image. */
2568
 
2569
      dest = vid_stream->current->Cr;
2570
 
2571
      if (vid_stream->picture.code_type == B_TYPE) {
2572
 
2573
    if (vid_stream->past != NULL)
2574
      past = vid_stream->past->Cr;
2575
      } else {
2576
    if (vid_stream->future != NULL)
2577
      past = vid_stream->future->Cr;
2578
      }
2579
    }
2580
    /* Otherwise, block is Cb block... */
2581
 
2582
    else {
2583
 
2584
      /* Set dest to Cb plane of current pict image. */
2585
 
2586
      dest = vid_stream->current->Cb;
2587
 
2588
      if (vid_stream->picture.code_type == B_TYPE) {
2589
        if (vid_stream->past != NULL)
2590
          past = vid_stream->past->Cb;
2591
      } else {
2592
        if (vid_stream->future != NULL)
2593
          past = vid_stream->future->Cb;
2594
      }
2595
    }
2596
  }
2597
 
2598
  /* For each pixel in block... */
2599
 
2600
#ifdef LOOSE_MPEG
2601
 
2602
  if (illegalBlock) {
2603
    if (illegalBlock & 0x1) {
2604
      row_start = 0;
2605
      row_end = row+vid_stream->down_for+8;
2606
      rfirst = rlast = 8 - row_end;
2607
    }
2608
    else if (illegalBlock & 0x4) {
2609
      row_start = row + vid_stream->down_for;
2610
      row_end = maxy+1;
2611
      rlast = row_end - row_start - 1;
2612
      rfirst = 0;
2613
    }
2614
    else {
2615
      row_start = row+vid_stream->down_for;
2616
      row_end = row_start+8;
2617
      rfirst = 0;
2618
    }
2619
 
2620
    if (illegalBlock & 0x8) {
2621
      col_start = 0;
2622
      col_end = col + vid_stream->right_for + 8;
2623
      cfirst = clast = 8 - col_end;
2624
    }
2625
    else if (illegalBlock & 0x2) {
2626
      col_start = col + vid_stream->right_for;
2627
      col_end = maxx + 1;
2628
      clast = col_end - col_start - 1;
2629
      cfirst = 0;
2630
    }
2631
    else {
2632
      col_start = col + vid_stream->right_for;
2633
      col_end = col_start + 8;
2634
      cfirst = 0;
2635
    }
2636
 
2637
    for (rr = row_start; rr < row_end; rr++) {
2638
      rindex1 = past + (rr * row_size) + col_start;
2639
      index = dest + ((row + rfirst) * row_size) + col + cfirst;
2640
      for (cc = col_start; cc < col_end; cc++) {
2641
    *index++ = *rindex1++;
2642
      }
2643
    }
2644
 
2645
    if (illegalBlock & 0x1) {
2646
      for (rr = rlast -1; rr >=0; rr--) {
2647
        index = dest + ((row + rr) * row_size) + col;
2648
        rindex1 = dest + ((row + rlast) * row_size) + col;
2649
        for (cc = 0; cc < 8; cc ++) {
2650
          *index++ = *rindex1++;
2651
        }
2652
      }
2653
    }
2654
    else if (illegalBlock & 0x4) {
2655
      for (rr = rlast+1; rr < 8; rr++) {
2656
        index = dest + ((row + rr) * row_size) + col;
2657
        rindex1 = dest + ((row + rlast) * row_size) + col;
2658
        for (cc = 0; cc < 8; cc ++) {
2659
          *index++ = *rindex1++;
2660
        }
2661
      }
2662
    }
2663
 
2664
    if (illegalBlock & 0x2) {
2665
      for (cc = clast+1; cc < 8; cc++) {
2666
        index = dest + (row * row_size) + (col + cc);
2667
        rindex1 = dest + (row * row_size) + (col + clast);
2668
        for (rr = 0; rr < 8; rr++) {
2669
          *index = *rindex1;
2670
          index += row_size;
2671
          rindex1 += row_size;
2672
        }
2673
      }
2674
    }
2675
    else if (illegalBlock & 0x8) {
2676
      for (cc = clast-1; cc >= 0; cc--) {
2677
        index = dest + (row * row_size) + (col + cc);
2678
        rindex1 = dest + (row * row_size) + (col + clast);
2679
        for (rr = 0; rr < 8; rr++) {
2680
          *index = *rindex1;
2681
          index += row_size;
2682
          rindex1 += row_size;
2683
        }
2684
      }
2685
    }
2686
 
2687
    if (!zflag) {
2688
      for (rr = 0; rr < 8; rr++) {
2689
        index = dest + (row*row_size) + col;
2690
        blockvals = &(vid_stream->block.dct_recon[rr][0]);
2691
        index[0] += blockvals[0];
2692
        index[1] += blockvals[1];
2693
        index[2] += blockvals[2];
2694
        index[3] += blockvals[3];
2695
        index[4] += blockvals[4];
2696
        index[5] += blockvals[5];
2697
        index[6] += blockvals[6];
2698
        index[7] += blockvals[7];
2699
      }
2700
    }
2701
  }
2702
  else {
2703
 
2704
#endif
2705
 
2706
    index = dest + (row * row_size) + col;
2707
    rindex1 = past + (row + vid_stream->down_for) * row_size
2708
              + col + vid_stream->right_for;
2709
 
2710
    blockvals = &(vid_stream->block.dct_recon[0][0]);
2711
 
2712
    /*
2713
     * Calculate predictive pixel value based on motion vectors and copy to
2714
     * dest plane.
2715
     */
2716
 
2717
    if ((!vid_stream->down_half_for) && (!vid_stream->right_half_for)) {
2718
      unsigned char *cm = cropTbl + MAX_NEG_CROP;
2719
      if (!zflag)
2720
        for (rr = 0; rr < 4; rr++) {
2721
          index[0] = cm[(int) rindex1[0] + (int) blockvals[0]];
2722
          index[1] = cm[(int) rindex1[1] + (int) blockvals[1]];
2723
          index[2] = cm[(int) rindex1[2] + (int) blockvals[2]];
2724
          index[3] = cm[(int) rindex1[3] + (int) blockvals[3]];
2725
          index[4] = cm[(int) rindex1[4] + (int) blockvals[4]];
2726
          index[5] = cm[(int) rindex1[5] + (int) blockvals[5]];
2727
          index[6] = cm[(int) rindex1[6] + (int) blockvals[6]];
2728
          index[7] = cm[(int) rindex1[7] + (int) blockvals[7]];
2729
          index += row_size;
2730
          rindex1 += row_size;
2731
 
2732
          index[0] = cm[(int) rindex1[0] + (int) blockvals[8]];
2733
          index[1] = cm[(int) rindex1[1] + (int) blockvals[9]];
2734
          index[2] = cm[(int) rindex1[2] + (int) blockvals[10]];
2735
          index[3] = cm[(int) rindex1[3] + (int) blockvals[11]];
2736
          index[4] = cm[(int) rindex1[4] + (int) blockvals[12]];
2737
          index[5] = cm[(int) rindex1[5] + (int) blockvals[13]];
2738
          index[6] = cm[(int) rindex1[6] + (int) blockvals[14]];
2739
          index[7] = cm[(int) rindex1[7] + (int) blockvals[15]];
2740
          blockvals += 16;
2741
          index += row_size;
2742
          rindex1 += row_size;
2743
        }
2744
      else {
2745
        if (vid_stream->right_for & 0x1) {
2746
          /* No alignment, use bye copy */
2747
          for (rr = 0; rr < 4; rr++) {
2748
            index[0] = rindex1[0];
2749
            index[1] = rindex1[1];
2750
            index[2] = rindex1[2];
2751
            index[3] = rindex1[3];
2752
            index[4] = rindex1[4];
2753
            index[5] = rindex1[5];
2754
            index[6] = rindex1[6];
2755
            index[7] = rindex1[7];
2756
            index += row_size;
2757
            rindex1 += row_size;
2758
 
2759
            index[0] = rindex1[0];
2760
            index[1] = rindex1[1];
2761
            index[2] = rindex1[2];
2762
            index[3] = rindex1[3];
2763
            index[4] = rindex1[4];
2764
            index[5] = rindex1[5];
2765
            index[6] = rindex1[6];
2766
            index[7] = rindex1[7];
2767
            index += row_size;
2768
            rindex1 += row_size;
2769
          }
2770
        } else if (vid_stream->right_for & 0x2) {
2771
          /* Half-word bit aligned, use 16 bit copy */
2772
          short *src = (short *)rindex1;
2773
          short *dest = (short *)index;
2774
          row_size >>= 1;
2775
          for (rr = 0; rr < 4; rr++) {
2776
            dest[0] = src[0];
2777
            dest[1] = src[1];
2778
            dest[2] = src[2];
2779
            dest[3] = src[3];
2780
            dest += row_size;
2781
            src += row_size;
2782
 
2783
            dest[0] = src[0];
2784
            dest[1] = src[1];
2785
            dest[2] = src[2];
2786
            dest[3] = src[3];
2787
            dest += row_size;
2788
            src += row_size;
2789
          }
2790
        } else {
2791
          /* Word aligned, use 32 bit copy */
2792
          int *src = (int *)rindex1;
2793
          int *dest = (int *)index;
2794
          row_size >>= 2;
2795
          for (rr = 0; rr < 4; rr++) {
2796
            dest[0] = src[0];
2797
            dest[1] = src[1];
2798
            dest += row_size;
2799
            src += row_size;
2800
 
2801
            dest[0] = src[0];
2802
            dest[1] = src[1];
2803
            dest += row_size;
2804
            src += row_size;
2805
          }
2806
        }
2807
      }
2808
    } else {
2809
      unsigned char *cm = cropTbl + MAX_NEG_CROP;
2810
      rindex2 = rindex1 + vid_stream->right_half_for
2811
                + (vid_stream->down_half_for * row_size);
2812
 
2813
      /* if one of the two is zero, then quality makes no difference */
2814
      if ((!vid_stream->right_half_for) ||
2815
          (!vid_stream->down_half_for) || (!qualityFlag)) {
2816
 
2817
        if (!zflag) {
2818
          for (rr = 0; rr < 4; rr++) {
2819
            index[0] = cm[((int) (rindex1[0] + rindex2[0] + 1) >> 1) + blockvals[0]];
2820
            index[1] = cm[((int) (rindex1[1] + rindex2[1] + 1) >> 1) + blockvals[1]];
2821
            index[2] = cm[((int) (rindex1[2] + rindex2[2] + 1) >> 1) + blockvals[2]];
2822
            index[3] = cm[((int) (rindex1[3] + rindex2[3] + 1) >> 1) + blockvals[3]];
2823
            index[4] = cm[((int) (rindex1[4] + rindex2[4] + 1) >> 1) + blockvals[4]];
2824
            index[5] = cm[((int) (rindex1[5] + rindex2[5] + 1) >> 1) + blockvals[5]];
2825
            index[6] = cm[((int) (rindex1[6] + rindex2[6] + 1) >> 1) + blockvals[6]];
2826
            index[7] = cm[((int) (rindex1[7] + rindex2[7] + 1) >> 1) + blockvals[7]];
2827
            index += row_size;
2828
            rindex1 += row_size;
2829
            rindex2 += row_size;
2830
 
2831
            index[0] = cm[((int) (rindex1[0] + rindex2[0] + 1) >> 1) + blockvals[8]];
2832
            index[1] = cm[((int) (rindex1[1] + rindex2[1] + 1) >> 1) + blockvals[9]];
2833
            index[2] = cm[((int) (rindex1[2] + rindex2[2] + 1) >> 1) + blockvals[10]];
2834
            index[3] = cm[((int) (rindex1[3] + rindex2[3] + 1) >> 1) + blockvals[11]];
2835
            index[4] = cm[((int) (rindex1[4] + rindex2[4] + 1) >> 1) + blockvals[12]];
2836
            index[5] = cm[((int) (rindex1[5] + rindex2[5] + 1) >> 1) + blockvals[13]];
2837
            index[6] = cm[((int) (rindex1[6] + rindex2[6] + 1) >> 1) + blockvals[14]];
2838
            index[7] = cm[((int) (rindex1[7] + rindex2[7] + 1) >> 1) + blockvals[15]];
2839
            blockvals += 16;
2840
            index += row_size;
2841
            rindex1 += row_size;
2842
            rindex2 += row_size;
2843
          }
2844
        } else { /* zflag */
2845
          for (rr = 0; rr < 8; rr++) {
2846
            index[0] = (int) (rindex1[0] + rindex2[0] + 1) >> 1;
2847
            index[1] = (int) (rindex1[1] + rindex2[1] + 1) >> 1;
2848
            index[2] = (int) (rindex1[2] + rindex2[2] + 1) >> 1;
2849
            index[3] = (int) (rindex1[3] + rindex2[3] + 1) >> 1;
2850
            index[4] = (int) (rindex1[4] + rindex2[4] + 1) >> 1;
2851
            index[5] = (int) (rindex1[5] + rindex2[5] + 1) >> 1;
2852
            index[6] = (int) (rindex1[6] + rindex2[6] + 1) >> 1;
2853
            index[7] = (int) (rindex1[7] + rindex2[7] + 1) >> 1;
2854
            index += row_size;
2855
            rindex1 += row_size;
2856
            rindex2 += row_size;
2857
          }
2858
        }
2859
      } else { /* qualityFlag on and both vectors are non-zero */
2860
        rindex3 = rindex1 + vid_stream->right_half_for;
2861
        rindex4 = rindex1 + (vid_stream->down_half_for * row_size);
2862
        if (!zflag) {
2863
          for (rr = 0; rr < 4; rr++) {
2864
            index[0] = cm[((int) (rindex1[0] + rindex2[0] + rindex3[0] + rindex4[0] + 2) >> 2) + blockvals[0]];
2865
            index[1] = cm[((int) (rindex1[1] + rindex2[1] + rindex3[1] + rindex4[1] + 2) >> 2) + blockvals[1]];
2866
            index[2] = cm[((int) (rindex1[2] + rindex2[2] + rindex3[2] + rindex4[2] + 2) >> 2) + blockvals[2]];
2867
            index[3] = cm[((int) (rindex1[3] + rindex2[3] + rindex3[3] + rindex4[3] + 2) >> 2) + blockvals[3]];
2868
            index[4] = cm[((int) (rindex1[4] + rindex2[4] + rindex3[4] + rindex4[4] + 2) >> 2) + blockvals[4]];
2869
            index[5] = cm[((int) (rindex1[5] + rindex2[5] + rindex3[5] + rindex4[5] + 2) >> 2) + blockvals[5]];
2870
            index[6] = cm[((int) (rindex1[6] + rindex2[6] + rindex3[6] + rindex4[6] + 2) >> 2) + blockvals[6]];
2871
            index[7] = cm[((int) (rindex1[7] + rindex2[7] + rindex3[7] + rindex4[7] + 2) >> 2) + blockvals[7]];
2872
            index += row_size;
2873
            rindex1 += row_size;
2874
            rindex2 += row_size;
2875
            rindex3 += row_size;
2876
            rindex4 += row_size;
2877
 
2878
            index[0] = cm[((int) (rindex1[0] + rindex2[0] + rindex3[0] + rindex4[0] + 2) >> 2) + blockvals[8]];
2879
            index[1] = cm[((int) (rindex1[1] + rindex2[1] + rindex3[1] + rindex4[1] + 2) >> 2) + blockvals[9]];
2880
            index[2] = cm[((int) (rindex1[2] + rindex2[2] + rindex3[2] + rindex4[2] + 2) >> 2) + blockvals[10]];
2881
            index[3] = cm[((int) (rindex1[3] + rindex2[3] + rindex3[3] + rindex4[3] + 2) >> 2) + blockvals[11]];
2882
            index[4] = cm[((int) (rindex1[4] + rindex2[4] + rindex3[4] + rindex4[4] + 2) >> 2) + blockvals[12]];
2883
            index[5] = cm[((int) (rindex1[5] + rindex2[5] + rindex3[5] + rindex4[5] + 2) >> 2) + blockvals[13]];
2884
            index[6] = cm[((int) (rindex1[6] + rindex2[6] + rindex3[6] + rindex4[6] + 2) >> 2) + blockvals[14]];
2885
            index[7] = cm[((int) (rindex1[7] + rindex2[7] + rindex3[7] + rindex4[7] + 2) >> 2) + blockvals[15]];
2886
            blockvals += 16;
2887
            index += row_size;
2888
            rindex1 += row_size;
2889
            rindex2 += row_size;
2890
            rindex3 += row_size;
2891
            rindex4 += row_size;
2892
          }
2893
        } else { /* zflag */
2894
          for (rr = 0; rr < 8; rr++) {
2895
            index[0] = (int) (rindex1[0] + rindex2[0] + rindex3[0] + rindex4[0] + 2) >> 2;
2896
            index[1] = (int) (rindex1[1] + rindex2[1] + rindex3[1] + rindex4[1] + 2) >> 2;
2897
            index[2] = (int) (rindex1[2] + rindex2[2] + rindex3[2] + rindex4[2] + 2) >> 2;
2898
            index[3] = (int) (rindex1[3] + rindex2[3] + rindex3[3] + rindex4[3] + 2) >> 2;
2899
            index[4] = (int) (rindex1[4] + rindex2[4] + rindex3[4] + rindex4[4] + 2) >> 2;
2900
            index[5] = (int) (rindex1[5] + rindex2[5] + rindex3[5] + rindex4[5] + 2) >> 2;
2901
            index[6] = (int) (rindex1[6] + rindex2[6] + rindex3[6] + rindex4[6] + 2) >> 2;
2902
            index[7] = (int) (rindex1[7] + rindex2[7] + rindex3[7] + rindex4[7] + 2) >> 2;
2903
            index += row_size;
2904
            rindex1 += row_size;
2905
            rindex2 += row_size;
2906
            rindex3 += row_size;
2907
            rindex4 += row_size;
2908
          }
2909
        }
2910
      }
2911
 
2912
    }
2913
#ifdef LOOSE_MPEG
2914
  }
2915
#endif
2916
}
2917
 
2918
 
2919
/*
2920
 *--------------------------------------------------------------
2921
 *
2922
 * ReconBMBlock --
2923
 *
2924
 *      Reconstructs back predicted macroblocks.
2925
 *
2926
 * Results:
2927
 *      None.
2928
 *
2929
 * Side effects:
2930
 *      None.
2931
 *
2932
 *--------------------------------------------------------------
2933
 */
2934
 
2935
static void
2936
ReconBMBlock(vid_stream, bnum, recon_right_back, recon_down_back, zflag)
2937
  VidStream *vid_stream;
2938
  int bnum, recon_right_back, recon_down_back, zflag;
2939
{
2940
  int mb_row, mb_col, row, col, row_size, rr;
2941
  unsigned char *dest, *future;
2942
  int right_back, down_back, right_half_back, down_half_back;
2943
  unsigned char *rindex1, *rindex2, *rindex3, *rindex4;
2944
  unsigned char *index;
2945
  short int *blockvals;
2946
 
2947
#ifdef LOOSE_MPEG
2948
  int illegalBlock = 0;
2949
  int maxx, maxy, cc;
2950
  int row_start, row_end, rlast, rfirst, col_start, col_end, clast, cfirst;
2951
#endif
2952
 
2953
  /* Calculate macroblock row and column from address. */
2954
 
2955
  mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
2956
  mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
2957
 
2958
  /* If block is luminance block... */
2959
 
2960
  if (bnum < 4) {
2961
 
2962
    /* Calculate right_back, down_back motion vectors. */
2963
 
2964
    right_back = recon_right_back >> 1;
2965
    down_back = recon_down_back >> 1;
2966
    right_half_back = recon_right_back & 0x1;
2967
    down_half_back = recon_down_back & 0x1;
2968
 
2969
    /* Set dest to luminance plane of current pict image. */
2970
 
2971
    dest = vid_stream->current->luminance;
2972
 
2973
    /*
2974
     * If future frame exists, set future to luminance plane of future frame.
2975
     */
2976
 
2977
    if (vid_stream->future != NULL)
2978
      future = vid_stream->future->luminance;
2979
 
2980
    /* Establish row size. */
2981
 
2982
    row_size = vid_stream->mb_width << 4;
2983
 
2984
    /* Calculate row,col of upper left pixel in block. */
2985
 
2986
    row = mb_row << 4;
2987
    col = mb_col << 4;
2988
    if (bnum > 1)
2989
      row += 8;
2990
    if (bnum % 2)
2991
      col += 8;
2992
 
2993
#ifdef LOOSE_MPEG
2994
 
2995
    /* Check for block illegality. */
2996
 
2997
    maxx = vid_stream->mb_width*16-1;
2998
    maxy = vid_stream->mb_height*16-1;
2999
 
3000
    if (row + down_back + 7 > maxy) illegalBlock |= 0x4;
3001
    else if (row + down_back < 0)  illegalBlock |= 0x1;
3002
 
3003
    if (col + right_back + 7 > maxx) illegalBlock |= 0x2;
3004
    else if (col + right_back < 0) illegalBlock |= 0x8;
3005
 
3006
#endif
3007
 
3008
  }
3009
  /* Otherwise, block is NOT luminance block, ... */
3010
 
3011
  else {
3012
 
3013
    /* Construct motion vectors. */
3014
 
3015
    recon_right_back /= 2;
3016
    recon_down_back /= 2;
3017
    right_back = recon_right_back >> 1;
3018
    down_back = recon_down_back >> 1;
3019
    right_half_back = recon_right_back & 0x1;
3020
    down_half_back = recon_down_back & 0x1;
3021
 
3022
    /* Establish row size. */
3023
 
3024
    row_size = vid_stream->mb_width << 3;
3025
 
3026
    /* Calculate row,col of upper left pixel in block. */
3027
 
3028
    row = mb_row << 3;
3029
    col = mb_col << 3;
3030
 
3031
#ifdef LOOSE_MPEG
3032
 
3033
    /* Check for block illegality. */
3034
 
3035
    maxx = vid_stream->mb_width*8-1;
3036
    maxy = vid_stream->mb_height*8-1;
3037
 
3038
    if (row + down_back + 7 > maxy) illegalBlock |= 0x4;
3039
    else if (row + down_back < 0) illegalBlock |= 0x1;
3040
 
3041
    if (col + right_back + 7 > maxx) illegalBlock  |= 0x2;
3042
    else if (col + right_back < 0) illegalBlock |= 0x8;
3043
 
3044
#endif
3045
 
3046
    /* If block is Cr block... */
3047
    /* They were switched earlier, so 5 is first - eyhung */
3048
 
3049
    if (bnum == 5) {
3050
 
3051
      /* Set dest to Cr plane of current pict image. */
3052
 
3053
      dest = vid_stream->current->Cr;
3054
 
3055
      /*
3056
       * If future frame exists, set future to Cr plane of future image.
3057
       */
3058
 
3059
      if (vid_stream->future != NULL)
3060
        future = vid_stream->future->Cr;
3061
    }
3062
    /* Otherwise, block is Cb block... */
3063
 
3064
    else {
3065
 
3066
      /* Set dest to Cb plane of current pict image. */
3067
 
3068
      dest = vid_stream->current->Cb;
3069
 
3070
      /*
3071
       * If future frame exists, set future to Cb plane of future frame.
3072
       */
3073
 
3074
      if (vid_stream->future != NULL)
3075
        future = vid_stream->future->Cb;
3076
    }
3077
  }
3078
 
3079
  /* For each pixel in block do... */
3080
 
3081
#ifdef LOOSE_MPEG
3082
 
3083
  if (illegalBlock) {
3084
    if (illegalBlock & 0x1) {
3085
      row_start = 0;
3086
      row_end = row+down_back+8;
3087
      rfirst = rlast = 8 - row_end;
3088
    }
3089
    else if (illegalBlock & 0x4) {
3090
      row_start = row + down_back;
3091
      row_end = maxy+1;
3092
      rlast = row_end - row_start - 1;
3093
      rfirst = 0;
3094
    }
3095
    else {
3096
      row_start = row+down_back;
3097
      row_end = row_start+8;
3098
      rfirst = 0;
3099
    }
3100
 
3101
    if (illegalBlock & 0x8) {
3102
      col_start = 0;
3103
      col_end = col + right_back + 8;
3104
      cfirst = clast = 8 - col_end;
3105
    }
3106
    else if (illegalBlock & 0x2) {
3107
      col_start = col + right_back;
3108
      col_end = maxx + 1;
3109
      clast = col_end - col_start - 1;
3110
      cfirst = 0;
3111
    }
3112
    else {
3113
      col_start = col + right_back;
3114
      col_end = col_start + 8;
3115
      cfirst = 0;
3116
    }
3117
 
3118
    for (rr = row_start; rr < row_end; rr++) {
3119
      rindex1 = future + (rr * row_size) + col_start;
3120
      index = dest + ((row + rfirst) * row_size) + col + cfirst;
3121
      for (cc = col_start; cc < col_end; cc++) {
3122
        *index++ = *rindex1++;
3123
      }
3124
    }
3125
 
3126
    if (illegalBlock & 0x1) {
3127
      for (rr = rlast -1; rr >=0; rr--) {
3128
        index = dest + ((row + rr) * row_size) + col;
3129
        rindex1 = dest + ((row + rlast) * row_size) + col;
3130
        for (cc = 0; cc < 8; cc ++) {
3131
          *index++ = *rindex1++;
3132
        }
3133
      }
3134
    }
3135
    else if (illegalBlock & 0x4) {
3136
      for (rr = rlast+1; rr < 8; rr++) {
3137
        index = dest + ((row + rr) * row_size) + col;
3138
        rindex1 = dest + ((row + rlast) * row_size) + col;
3139
        for (cc = 0; cc < 8; cc ++) {
3140
          *index++ = *rindex1++;
3141
        }
3142
      }
3143
    }
3144
 
3145
    if (illegalBlock & 0x2) {
3146
      for (cc = clast+1; cc < 8; cc++) {
3147
        index = dest + (row * row_size) + (col + cc);
3148
        rindex1 = dest + (row * row_size) + (col + clast);
3149
        for (rr = 0; rr < 8; rr++) {
3150
          *index = *rindex1;
3151
          index += row_size;
3152
          rindex1 += row_size;
3153
        }
3154
      }
3155
    }
3156
    else if (illegalBlock & 0x8) {
3157
      for (cc = clast-1; cc >= 0; cc--) {
3158
        index = dest + (row * row_size) + (col + cc);
3159
        rindex1 = dest + (row * row_size) + (col + clast);
3160
        for (rr = 0; rr < 8; rr++) {
3161
          *index = *rindex1;
3162
          index += row_size;
3163
          rindex1 += row_size;
3164
        }
3165
      }
3166
    }
3167
 
3168
    if (!zflag) {
3169
      for (rr = 0; rr < 8; rr++) {
3170
        index = dest + (row*row_size) + col;
3171
        blockvals = &(vid_stream->block.dct_recon[rr][0]);
3172
        index[0] += blockvals[0];
3173
        index[1] += blockvals[1];
3174
        index[2] += blockvals[2];
3175
        index[3] += blockvals[3];
3176
        index[4] += blockvals[4];
3177
        index[5] += blockvals[5];
3178
        index[6] += blockvals[6];
3179
        index[7] += blockvals[7];
3180
      }
3181
    }
3182
  }
3183
  else {
3184
 
3185
#endif
3186
 
3187
    index = dest + (row * row_size) + col;
3188
    rindex1 = future + (row + down_back) * row_size + col + right_back;
3189
 
3190
    blockvals = &(vid_stream->block.dct_recon[0][0]);
3191
 
3192
    if ((!right_half_back) && (!down_half_back)) {
3193
      unsigned char *cm = cropTbl + MAX_NEG_CROP;
3194
      if (!zflag)
3195
        for (rr = 0; rr < 4; rr++) {
3196
          index[0] = cm[(int) rindex1[0] + (int) blockvals[0]];
3197
          index[1] = cm[(int) rindex1[1] + (int) blockvals[1]];
3198
          index[2] = cm[(int) rindex1[2] + (int) blockvals[2]];
3199
          index[3] = cm[(int) rindex1[3] + (int) blockvals[3]];
3200
          index[4] = cm[(int) rindex1[4] + (int) blockvals[4]];
3201
          index[5] = cm[(int) rindex1[5] + (int) blockvals[5]];
3202
          index[6] = cm[(int) rindex1[6] + (int) blockvals[6]];
3203
          index[7] = cm[(int) rindex1[7] + (int) blockvals[7]];
3204
          index += row_size;
3205
          rindex1 += row_size;
3206
 
3207
          index[0] = cm[(int) rindex1[0] + (int) blockvals[8]];
3208
          index[1] = cm[(int) rindex1[1] + (int) blockvals[9]];
3209
          index[2] = cm[(int) rindex1[2] + (int) blockvals[10]];
3210
          index[3] = cm[(int) rindex1[3] + (int) blockvals[11]];
3211
          index[4] = cm[(int) rindex1[4] + (int) blockvals[12]];
3212
          index[5] = cm[(int) rindex1[5] + (int) blockvals[13]];
3213
          index[6] = cm[(int) rindex1[6] + (int) blockvals[14]];
3214
          index[7] = cm[(int) rindex1[7] + (int) blockvals[15]];
3215
          blockvals += 16;
3216
          index += row_size;
3217
          rindex1 += row_size;
3218
        }
3219
      else {
3220
        if (right_back & 0x1) {
3221
          /* No alignment, use bye copy */
3222
          for (rr = 0; rr < 4; rr++) {
3223
            index[0] = rindex1[0];
3224
            index[1] = rindex1[1];
3225
            index[2] = rindex1[2];
3226
            index[3] = rindex1[3];
3227
            index[4] = rindex1[4];
3228
            index[5] = rindex1[5];
3229
            index[6] = rindex1[6];
3230
            index[7] = rindex1[7];
3231
            index += row_size;
3232
            rindex1 += row_size;
3233
 
3234
            index[0] = rindex1[0];
3235
            index[1] = rindex1[1];
3236
            index[2] = rindex1[2];
3237
            index[3] = rindex1[3];
3238
            index[4] = rindex1[4];
3239
            index[5] = rindex1[5];
3240
            index[6] = rindex1[6];
3241
            index[7] = rindex1[7];
3242
            index += row_size;
3243
            rindex1 += row_size;
3244
          }
3245
        } else if (right_back & 0x2) {
3246
          /* Half-word bit aligned, use 16 bit copy */
3247
          short *src = (short *)rindex1;
3248
          short *dest = (short *)index;
3249
          row_size >>= 1;
3250
          for (rr = 0; rr < 4; rr++) {
3251
            dest[0] = src[0];
3252
            dest[1] = src[1];
3253
            dest[2] = src[2];
3254
            dest[3] = src[3];
3255
            dest += row_size;
3256
            src += row_size;
3257
 
3258
            dest[0] = src[0];
3259
            dest[1] = src[1];
3260
            dest[2] = src[2];
3261
            dest[3] = src[3];
3262
            dest += row_size;
3263
            src += row_size;
3264
          }
3265
        } else {
3266
          /* Word aligned, use 32 bit copy */
3267
          int *src = (int *)rindex1;
3268
          int *dest = (int *)index;
3269
          row_size >>= 2;
3270
          for (rr = 0; rr < 4; rr++) {
3271
            dest[0] = src[0];
3272
            dest[1] = src[1];
3273
            dest += row_size;
3274
            src += row_size;
3275
 
3276
            dest[0] = src[0];
3277
            dest[1] = src[1];
3278
            dest += row_size;
3279
            src += row_size;
3280
          }
3281
        }
3282
      }
3283
    } else {
3284
      unsigned char *cm = cropTbl + MAX_NEG_CROP;
3285
      rindex2 = rindex1 + right_half_back + (down_half_back * row_size);
3286
      if (!qualityFlag) {
3287
 
3288
        if (!zflag) {
3289
          for (rr = 0; rr < 4; rr++) {
3290
            index[0] = cm[((int) (rindex1[0] + rindex2[0] + 1) >> 1) + blockvals[0]];
3291
            index[1] = cm[((int) (rindex1[1] + rindex2[1] + 1) >> 1) + blockvals[1]];
3292
            index[2] = cm[((int) (rindex1[2] + rindex2[2] + 1) >> 1) + blockvals[2]];
3293
            index[3] = cm[((int) (rindex1[3] + rindex2[3] + 1) >> 1) + blockvals[3]];
3294
            index[4] = cm[((int) (rindex1[4] + rindex2[4] + 1) >> 1) + blockvals[4]];
3295
            index[5] = cm[((int) (rindex1[5] + rindex2[5] + 1) >> 1) + blockvals[5]];
3296
            index[6] = cm[((int) (rindex1[6] + rindex2[6] + 1) >> 1) + blockvals[6]];
3297
            index[7] = cm[((int) (rindex1[7] + rindex2[7] + 1) >> 1) + blockvals[7]];
3298
            index += row_size;
3299
            rindex1 += row_size;
3300
            rindex2 += row_size;
3301
 
3302
            index[0] = cm[((int) (rindex1[0] + rindex2[0] + 1) >> 1) + blockvals[8]];
3303
            index[1] = cm[((int) (rindex1[1] + rindex2[1] + 1) >> 1) + blockvals[9]];
3304
            index[2] = cm[((int) (rindex1[2] + rindex2[2] + 1) >> 1) + blockvals[10]];
3305
            index[3] = cm[((int) (rindex1[3] + rindex2[3] + 1) >> 1) + blockvals[11]];
3306
            index[4] = cm[((int) (rindex1[4] + rindex2[4] + 1) >> 1) + blockvals[12]];
3307
            index[5] = cm[((int) (rindex1[5] + rindex2[5] + 1) >> 1) + blockvals[13]];
3308
            index[6] = cm[((int) (rindex1[6] + rindex2[6] + 1) >> 1) + blockvals[14]];
3309
            index[7] = cm[((int) (rindex1[7] + rindex2[7] + 1) >> 1) + blockvals[15]];
3310
            blockvals += 16;
3311
            index += row_size;
3312
            rindex1 += row_size;
3313
            rindex2 += row_size;
3314
          }
3315
        } else { /* zflag */
3316
          for (rr = 0; rr < 8; rr++) {
3317
            index[0] = (int) (rindex1[0] + rindex2[0] + 1) >> 1;
3318
            index[1] = (int) (rindex1[1] + rindex2[1] + 1) >> 1;
3319
            index[2] = (int) (rindex1[2] + rindex2[2] + 1) >> 1;
3320
            index[3] = (int) (rindex1[3] + rindex2[3] + 1) >> 1;
3321
            index[4] = (int) (rindex1[4] + rindex2[4] + 1) >> 1;
3322
            index[5] = (int) (rindex1[5] + rindex2[5] + 1) >> 1;
3323
            index[6] = (int) (rindex1[6] + rindex2[6] + 1) >> 1;
3324
            index[7] = (int) (rindex1[7] + rindex2[7] + 1) >> 1;
3325
            index += row_size;
3326
            rindex1 += row_size;
3327
            rindex2 += row_size;
3328
          }
3329
        }
3330
      } else { /* qualityFlag on */
3331
        rindex3 = rindex1 + right_half_back;
3332
        rindex4 = rindex1 + (down_half_back * row_size);
3333
        if (!zflag) {
3334
          for (rr = 0; rr < 4; rr++) {
3335
            index[0] = cm[((int) (rindex1[0] + rindex2[0] + rindex3[0] + rindex4[0] + 2) >> 2) + blockvals[0]];
3336
            index[1] = cm[((int) (rindex1[1] + rindex2[1] + rindex3[1] + rindex4[1] + 2) >> 2) + blockvals[1]];
3337
            index[2] = cm[((int) (rindex1[2] + rindex2[2] + rindex3[2] + rindex4[2] + 2) >> 2) + blockvals[2]];
3338
            index[3] = cm[((int) (rindex1[3] + rindex2[3] + rindex3[3] + rindex4[3] + 2) >> 2) + blockvals[3]];
3339
            index[4] = cm[((int) (rindex1[4] + rindex2[4] + rindex3[4] + rindex4[4] + 2) >> 2) + blockvals[4]];
3340
            index[5] = cm[((int) (rindex1[5] + rindex2[5] + rindex3[5] + rindex4[5] + 2) >> 2) + blockvals[5]];
3341
            index[6] = cm[((int) (rindex1[6] + rindex2[6] + rindex3[6] + rindex4[6] + 2) >> 2) + blockvals[6]];
3342
            index[7] = cm[((int) (rindex1[7] + rindex2[7] + rindex3[7] + rindex4[7] + 2) >> 2) + blockvals[7]];
3343
            index += row_size;
3344
            rindex1 += row_size;
3345
            rindex2 += row_size;
3346
            rindex3 += row_size;
3347
            rindex4 += row_size;
3348
 
3349
            index[0] = cm[((int) (rindex1[0] + rindex2[0] + rindex3[0] + rindex4[0] + 2) >> 2) + blockvals[8]];
3350
            index[1] = cm[((int) (rindex1[1] + rindex2[1] + rindex3[1] + rindex4[1] + 2) >> 2) + blockvals[9]];
3351
            index[2] = cm[((int) (rindex1[2] + rindex2[2] + rindex3[2] + rindex4[2] + 2) >> 2) + blockvals[10]];
3352
            index[3] = cm[((int) (rindex1[3] + rindex2[3] + rindex3[3] + rindex4[3] + 2) >> 2) + blockvals[11]];
3353
            index[4] = cm[((int) (rindex1[4] + rindex2[4] + rindex3[4] + rindex4[4] + 2) >> 2) + blockvals[12]];
3354
            index[5] = cm[((int) (rindex1[5] + rindex2[5] + rindex3[5] + rindex4[5] + 2) >> 2) + blockvals[13]];
3355
            index[6] = cm[((int) (rindex1[6] + rindex2[6] + rindex3[6] + rindex4[6] + 2) >> 2) + blockvals[14]];
3356
            index[7] = cm[((int) (rindex1[7] + rindex2[7] + rindex3[7] + rindex4[7] + 2) >> 2) + blockvals[15]];
3357
            blockvals += 16;
3358
            index += row_size;
3359
            rindex1 += row_size;
3360
            rindex2 += row_size;
3361
            rindex3 += row_size;
3362
            rindex4 += row_size;
3363
          }
3364
        } else { /* zflag */
3365
          for (rr = 0; rr < 8; rr++) {
3366
            index[0] = (int) (rindex1[0] + rindex2[0] + rindex3[0] + rindex4[0] + 2) >> 2;
3367
            index[1] = (int) (rindex1[1] + rindex2[1] + rindex3[1] + rindex4[1] + 2) >> 2;
3368
            index[2] = (int) (rindex1[2] + rindex2[2] + rindex3[2] + rindex4[2] + 2) >> 2;
3369
            index[3] = (int) (rindex1[3] + rindex2[3] + rindex3[3] + rindex4[3] + 2) >> 2;
3370
            index[4] = (int) (rindex1[4] + rindex2[4] + rindex3[4] + rindex4[4] + 2) >> 2;
3371
            index[5] = (int) (rindex1[5] + rindex2[5] + rindex3[5] + rindex4[5] + 2) >> 2;
3372
            index[6] = (int) (rindex1[6] + rindex2[6] + rindex3[6] + rindex4[6] + 2) >> 2;
3373
            index[7] = (int) (rindex1[7] + rindex2[7] + rindex3[7] + rindex4[7] + 2) >> 2;
3374
            index += row_size;
3375
            rindex1 += row_size;
3376
            rindex2 += row_size;
3377
            rindex3 += row_size;
3378
            rindex4 += row_size;
3379
          }
3380
        }
3381
      }
3382
 
3383
    }
3384
#ifdef LOOSE_MPEG
3385
  }
3386
#endif
3387
}
3388
 
3389
 
3390
/*
3391
 *--------------------------------------------------------------
3392
 *
3393
 * ReconBiMBlock --
3394
 *
3395
 *      Reconstructs bidirectionally predicted macroblocks.
3396
 *
3397
 * Results:
3398
 *      None.
3399
 *
3400
 * Side effects:
3401
 *      None.
3402
 *
3403
 *--------------------------------------------------------------
3404
 */
3405
 
3406
static void
3407
ReconBiMBlock(vid_stream, bnum, recon_right_for, recon_down_for,
3408
              recon_right_back, recon_down_back, zflag)
3409
  VidStream *vid_stream;
3410
  int bnum, recon_right_for, recon_down_for, recon_right_back, recon_down_back;
3411
  int zflag;
3412
{
3413
  int mb_row, mb_col, row, col, row_size, rr;
3414
  unsigned char *dest, *past=NULL, *future=NULL;
3415
  int right_for, down_for, right_half_for, down_half_for;
3416
  int right_back, down_back, right_half_back, down_half_back;
3417
  unsigned char *index, *rindex1, *bindex1;
3418
  short int *blockvals;
3419
  int forw_row_start, back_row_start, forw_col_start, back_col_start;
3420
#ifdef LOOSE_MPEG
3421
  int lmaxx = vid_stream->mb_width*16-1;
3422
  int lmaxy = vid_stream->mb_height*16-1;
3423
  int cmaxx = vid_stream->mb_width*8-1;
3424
  int cmaxy = vid_stream->mb_height*8-1;
3425
#endif
3426
 
3427
#ifdef LOOSE_MPEG
3428
  int illegal_forw = 0;
3429
  int illegal_back = 0;
3430
#endif
3431
 
3432
  /* Calculate macroblock row and column from address. */
3433
 
3434
  mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
3435
  mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
3436
 
3437
  /* If block is luminance block... */
3438
 
3439
  if (bnum < 4) {
3440
 
3441
    /*
3442
     * Calculate right_for, down_for, right_half_for, down_half_for,
3443
     * right_back, down_bakc, right_half_back, and down_half_back, motion
3444
     * vectors.
3445
     */
3446
 
3447
    right_for = recon_right_for >> 1;
3448
    down_for = recon_down_for >> 1;
3449
    right_half_for = recon_right_for & 0x1;
3450
    down_half_for = recon_down_for & 0x1;
3451
 
3452
    right_back = recon_right_back >> 1;
3453
    down_back = recon_down_back >> 1;
3454
    right_half_back = recon_right_back & 0x1;
3455
    down_half_back = recon_down_back & 0x1;
3456
 
3457
    /* Set dest to luminance plane of current pict image. */
3458
 
3459
    dest = vid_stream->current->luminance;
3460
 
3461
    /* If past frame exists, set past to luminance plane of past frame. */
3462
 
3463
    if (vid_stream->past != NULL)
3464
      past = vid_stream->past->luminance;
3465
 
3466
    /*
3467
     * If future frame exists, set future to luminance plane of future frame.
3468
     */
3469
 
3470
    if (vid_stream->future != NULL)
3471
      future = vid_stream->future->luminance;
3472
 
3473
    /* Establish row size. */
3474
 
3475
    row_size = (vid_stream->mb_width << 4);
3476
 
3477
    /* Calculate row,col of upper left pixel in block. */
3478
 
3479
    row = (mb_row << 4);
3480
    col = (mb_col << 4);
3481
    if (bnum > 1)
3482
      row += 8;
3483
    if (bnum & 0x01)
3484
      col += 8;
3485
 
3486
    forw_col_start = col + right_for;
3487
    forw_row_start = row + down_for;
3488
 
3489
    back_col_start = col + right_back;
3490
    back_row_start = row + down_back;
3491
 
3492
#ifdef LOOSE_MPEG
3493
 
3494
    /* Check for illegal pred. blocks. */
3495
 
3496
 
3497
    if (forw_col_start+7 > lmaxx) illegal_forw = 1;
3498
    else if (forw_col_start < 0) illegal_forw = 1;
3499
 
3500
    if (forw_row_start+7 > lmaxy) illegal_forw = 1;
3501
    else if (forw_row_start < 0) illegal_forw = 1;
3502
 
3503
    if (back_col_start+7 > lmaxx) illegal_back = 1;
3504
    else if (back_col_start < 0) illegal_back = 1;
3505
 
3506
    if (back_row_start+7 > lmaxy) illegal_back = 1;
3507
    else if (back_row_start < 0) illegal_back = 1;
3508
 
3509
#endif
3510
 
3511
  }
3512
  /* Otherwise, block is NOT luminance block, ... */
3513
 
3514
  else {
3515
 
3516
    /* Construct motion vectors. */
3517
 
3518
    recon_right_for /= 2;
3519
    recon_down_for /= 2;
3520
    right_for = recon_right_for >> 1;
3521
    down_for = recon_down_for >> 1;
3522
    right_half_for = recon_right_for & 0x1;
3523
    down_half_for = recon_down_for & 0x1;
3524
 
3525
    recon_right_back /= 2;
3526
    recon_down_back /= 2;
3527
    right_back = recon_right_back >> 1;
3528
    down_back = recon_down_back >> 1;
3529
    right_half_back = recon_right_back & 0x1;
3530
    down_half_back = recon_down_back & 0x1;
3531
 
3532
    /* Establish row size. */
3533
 
3534
    row_size = (vid_stream->mb_width << 3);
3535
 
3536
    /* Calculate row,col of upper left pixel in block. */
3537
 
3538
    row = (mb_row << 3);
3539
    col = (mb_col << 3);
3540
 
3541
    forw_col_start = col + right_for;
3542
    forw_row_start = row + down_for;
3543
 
3544
    back_col_start = col + right_back;
3545
    back_row_start = row + down_back;
3546
 
3547
#ifdef LOOSE_MPEG
3548
 
3549
    /* Check for illegal pred. blocks. */
3550
 
3551
    if (forw_col_start+7 > cmaxx) illegal_forw = 1;
3552
    else if (forw_col_start < 0) illegal_forw = 1;
3553
 
3554
    if (forw_row_start+7 > cmaxy) illegal_forw = 1;
3555
    else if (forw_row_start < 0) illegal_forw = 1;
3556
 
3557
    if (back_col_start+7 > cmaxx) illegal_back = 1;
3558
    else if (back_col_start < 0) illegal_back = 1;
3559
 
3560
    if (back_row_start+7 > cmaxy) illegal_back = 1;
3561
    else if (back_row_start < 0) illegal_back = 1;
3562
 
3563
#endif
3564
 
3565
    /* If block is Cr block... */
3566
        /* Switched earlier, so we test Cr first - eyhung */
3567
 
3568
    if (bnum == 5) {
3569
 
3570
      /* Set dest to Cr plane of current pict image. */
3571
 
3572
      dest = vid_stream->current->Cr;
3573
 
3574
      /* If past frame exists, set past to Cr plane of past image. */
3575
 
3576
      if (vid_stream->past != NULL)
3577
        past = vid_stream->past->Cr;
3578
 
3579
      /*
3580
       * If future frame exists, set future to Cr plane of future image.
3581
       */
3582
 
3583
      if (vid_stream->future != NULL)
3584
        future = vid_stream->future->Cr;
3585
    }
3586
    /* Otherwise, block is Cb block... */
3587
 
3588
    else {
3589
 
3590
      /* Set dest to Cb plane of current pict image. */
3591
 
3592
      dest = vid_stream->current->Cb;
3593
 
3594
      /* If past frame exists, set past to Cb plane of past frame. */
3595
 
3596
      if (vid_stream->past != NULL)
3597
        past = vid_stream->past->Cb;
3598
 
3599
      /*
3600
       * If future frame exists, set future to Cb plane of future frame.
3601
       */
3602
 
3603
      if (vid_stream->future != NULL)
3604
        future = vid_stream->future->Cb;
3605
    }
3606
  }
3607
 
3608
  /* For each pixel in block... */
3609
 
3610
  index = dest + (row * row_size) + col;
3611
 
3612
#ifdef LOOSE_MPEG
3613
  if (illegal_forw)
3614
    rindex1 = future + back_row_start * row_size + back_col_start;
3615
  else
3616
#endif
3617
    rindex1 = past + forw_row_start  * row_size + forw_col_start;
3618
 
3619
#ifdef LOOSE_MPEG
3620
  if (illegal_back)
3621
    bindex1 = past + forw_row_start * row_size + forw_col_start;
3622
  else
3623
#endif
3624
    bindex1 = future + back_row_start * row_size + back_col_start;
3625
 
3626
  blockvals = (short int *) &(vid_stream->block.dct_recon[0][0]);
3627
 
3628
  {
3629
  unsigned char *cm = cropTbl + MAX_NEG_CROP;
3630
  if (!zflag)
3631
    for (rr = 0; rr < 4; rr++) {
3632
      index[0] = cm[((int) (rindex1[0] + bindex1[0]) >> 1) + blockvals[0]];
3633
      index[1] = cm[((int) (rindex1[1] + bindex1[1]) >> 1) + blockvals[1]];
3634
      index[2] = cm[((int) (rindex1[2] + bindex1[2]) >> 1) + blockvals[2]];
3635
      index[3] = cm[((int) (rindex1[3] + bindex1[3]) >> 1) + blockvals[3]];
3636
      index[4] = cm[((int) (rindex1[4] + bindex1[4]) >> 1) + blockvals[4]];
3637
      index[5] = cm[((int) (rindex1[5] + bindex1[5]) >> 1) + blockvals[5]];
3638
      index[6] = cm[((int) (rindex1[6] + bindex1[6]) >> 1) + blockvals[6]];
3639
      index[7] = cm[((int) (rindex1[7] + bindex1[7]) >> 1) + blockvals[7]];
3640
      index += row_size;
3641
      rindex1 += row_size;
3642
      bindex1 += row_size;
3643
 
3644
      index[0] = cm[((int) (rindex1[0] + bindex1[0]) >> 1) + blockvals[8]];
3645
      index[1] = cm[((int) (rindex1[1] + bindex1[1]) >> 1) + blockvals[9]];
3646
      index[2] = cm[((int) (rindex1[2] + bindex1[2]) >> 1) + blockvals[10]];
3647
      index[3] = cm[((int) (rindex1[3] + bindex1[3]) >> 1) + blockvals[11]];
3648
      index[4] = cm[((int) (rindex1[4] + bindex1[4]) >> 1) + blockvals[12]];
3649
      index[5] = cm[((int) (rindex1[5] + bindex1[5]) >> 1) + blockvals[13]];
3650
      index[6] = cm[((int) (rindex1[6] + bindex1[6]) >> 1) + blockvals[14]];
3651
      index[7] = cm[((int) (rindex1[7] + bindex1[7]) >> 1) + blockvals[15]];
3652
      blockvals += 16;
3653
      index += row_size;
3654
      rindex1 += row_size;
3655
      bindex1 += row_size;
3656
    }
3657
 
3658
  else
3659
    for (rr = 0; rr < 4; rr++) {
3660
      index[0] = (int) (rindex1[0] + bindex1[0]) >> 1;
3661
      index[1] = (int) (rindex1[1] + bindex1[1]) >> 1;
3662
      index[2] = (int) (rindex1[2] + bindex1[2]) >> 1;
3663
      index[3] = (int) (rindex1[3] + bindex1[3]) >> 1;
3664
      index[4] = (int) (rindex1[4] + bindex1[4]) >> 1;
3665
      index[5] = (int) (rindex1[5] + bindex1[5]) >> 1;
3666
      index[6] = (int) (rindex1[6] + bindex1[6]) >> 1;
3667
      index[7] = (int) (rindex1[7] + bindex1[7]) >> 1;
3668
      index += row_size;
3669
      rindex1 += row_size;
3670
      bindex1 += row_size;
3671
 
3672
      index[0] = (int) (rindex1[0] + bindex1[0]) >> 1;
3673
      index[1] = (int) (rindex1[1] + bindex1[1]) >> 1;
3674
      index[2] = (int) (rindex1[2] + bindex1[2]) >> 1;
3675
      index[3] = (int) (rindex1[3] + bindex1[3]) >> 1;
3676
      index[4] = (int) (rindex1[4] + bindex1[4]) >> 1;
3677
      index[5] = (int) (rindex1[5] + bindex1[5]) >> 1;
3678
      index[6] = (int) (rindex1[6] + bindex1[6]) >> 1;
3679
      index[7] = (int) (rindex1[7] + bindex1[7]) >> 1;
3680
      index += row_size;
3681
      rindex1 += row_size;
3682
      bindex1 += row_size;
3683
    }
3684
  }
3685
}
3686
 
3687
 
3688
/*
3689
 *--------------------------------------------------------------
3690
 *
3691
 * ProcessSkippedPFrameMBlocks --
3692
 *
3693
 *      Processes skipped macroblocks in P frames.
3694
 *
3695
 * Results:
3696
 *      Calculates pixel values for luminance, Cr, and Cb planes
3697
 *      in current pict image for skipped macroblocks.
3698
 *
3699
 * Side effects:
3700
 *      Pixel values in pict image changed.
3701
 *
3702
 *--------------------------------------------------------------
3703
 */
3704
 
3705
static void
3706
ProcessSkippedPFrameMBlocks(vid_stream)
3707
  VidStream *vid_stream;
3708
{
3709
  int row_size, half_row, mb_row, mb_col, row, col, rr;
3710
  int addr, row_incr, half_row_incr, crow, ccol;
3711
  int *dest, *src, *dest1, *src1;
3712
  int ditherType=vid_stream->ditherType;
3713
 
3714
  /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
3715
 
3716
  row_size = vid_stream->mb_width << 4;
3717
  half_row = (row_size >> 1);
3718
  row_incr = row_size >> 2;
3719
  half_row_incr = half_row >> 2;
3720
 
3721
  /* For each skipped macroblock, do... */
3722
 
3723
  for (addr = vid_stream->mblock.past_mb_addr + 1;
3724
       addr < vid_stream->mblock.mb_address; addr++) {
3725
 
3726
    /* Calculate macroblock row and col. */
3727
 
3728
    mb_row = addr / vid_stream->mb_width;
3729
    mb_col = addr % vid_stream->mb_width;
3730
 
3731
    /* Calculate upper left pixel row,col for luminance plane. */
3732
 
3733
    row = mb_row << 4;
3734
    col = mb_col << 4;
3735
 
3736
 
3737
    /* For each row in macroblock luminance plane... */
3738
 
3739
    dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
3740
    src = (int *)(vid_stream->future->luminance + (row * row_size) + col);
3741
 
3742
    for (rr = 0; rr < 8; rr++) {
3743
 
3744
      /* Copy pixel values from last I or P picture. */
3745
 
3746
      dest[0] = src[0];
3747
      dest[1] = src[1];
3748
      dest[2] = src[2];
3749
      dest[3] = src[3];
3750
      dest += row_incr;
3751
      src += row_incr;
3752
 
3753
      dest[0] = src[0];
3754
      dest[1] = src[1];
3755
      dest[2] = src[2];
3756
      dest[3] = src[3];
3757
      dest += row_incr;
3758
      src += row_incr;
3759
    }
3760
 
3761
    /*
3762
     * Divide row,col to get upper left pixel of macroblock in Cr and Cb
3763
     * planes.
3764
     */
3765
 
3766
    crow = row >> 1;
3767
    ccol = col >> 1;
3768
 
3769
    /* For each row in Cr, and Cb planes... */
3770
 
3771
    dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
3772
    src = (int *)(vid_stream->future->Cr + (crow * half_row) + ccol);
3773
    dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
3774
    src1 = (int *)(vid_stream->future->Cb + (crow * half_row) + ccol);
3775
 
3776
    for (rr = 0; rr < 4; rr++) {
3777
 
3778
      /* Copy pixel values from last I or P picture. */
3779
 
3780
      dest[0] = src[0];
3781
      dest[1] = src[1];
3782
 
3783
      dest1[0] = src1[0];
3784
      dest1[1] = src1[1];
3785
 
3786
      dest += half_row_incr;
3787
      src += half_row_incr;
3788
      dest1 += half_row_incr;
3789
      src1 += half_row_incr;
3790
 
3791
      dest[0] = src[0];
3792
      dest[1] = src[1];
3793
 
3794
      dest1[0] = src1[0];
3795
      dest1[1] = src1[1];
3796
 
3797
      dest += half_row_incr;
3798
      src += half_row_incr;
3799
      dest1 += half_row_incr;
3800
      src1 += half_row_incr;
3801
    }
3802
 
3803
#ifndef DISABLE_DITHER
3804
    if (ditherType == MBORDERED_DITHER) {
3805
      MBOrderedDitherDisplayCopy(vid_stream, addr,
3806
                                 1, 0, 0, 0, 0, 0,
3807
                                 vid_stream->future->display,
3808
                                 (unsigned char *) NULL);
3809
      vid_stream->ditherFlags[addr] = 0;
3810
    }
3811
#endif
3812
  }
3813
 
3814
  vid_stream->mblock.recon_right_for_prev = 0;
3815
  vid_stream->mblock.recon_down_for_prev = 0;
3816
}
3817
 
3818
 
3819
 
3820
 
3821
 
3822
/*
3823
 *--------------------------------------------------------------
3824
 *
3825
 * ProcessSkippedBFrameMBlocks --
3826
 *
3827
 *      Processes skipped macroblocks in B frames.
3828
 *
3829
 * Results:
3830
 *      Calculates pixel values for luminance, Cr, and Cb planes
3831
 *      in current pict image for skipped macroblocks.
3832
 *
3833
 * Side effects:
3834
 *      Pixel values in pict image changed.
3835
 *
3836
 *--------------------------------------------------------------
3837
 */
3838
 
3839
static void
3840
ProcessSkippedBFrameMBlocks(vid_stream)
3841
  VidStream *vid_stream;
3842
{
3843
  int row_size, half_row, mb_row, mb_col, row, col, rr;
3844
  int right_half_for = 0, down_half_for = 0;
3845
  int c_right_half_for = 0, c_down_half_for = 0;
3846
  int right_half_back = 0, down_half_back = 0;
3847
  int c_right_half_back = 0, c_down_half_back = 0;
3848
  int addr, right_for = 0, down_for = 0;
3849
  int recon_right_for, recon_down_for;
3850
  int recon_right_back, recon_down_back;
3851
  int right_back = 0, down_back = 0;
3852
  int c_right_for = 0, c_down_for = 0;
3853
  int c_right_back = 0, c_down_back = 0;
3854
  unsigned char forw_lum[256];
3855
  unsigned char forw_cr[64], forw_cb[64];
3856
  unsigned char back_lum[256], back_cr[64], back_cb[64];
3857
  int row_incr, half_row_incr;
3858
  int ccol, crow;
3859
  int ditherType=vid_stream->ditherType;
3860
 
3861
  /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
3862
 
3863
  row_size = vid_stream->mb_width << 4;
3864
  half_row = (row_size >> 1);
3865
  row_incr = row_size >> 2;
3866
  half_row_incr =  half_row >> 2;
3867
 
3868
  /* Establish motion vector codes based on full pixel flag. */
3869
 
3870
  if (vid_stream->picture.full_pel_forw_vector) {
3871
    recon_right_for = vid_stream->mblock.recon_right_for_prev << 1;
3872
    recon_down_for = vid_stream->mblock.recon_down_for_prev << 1;
3873
  } else {
3874
    recon_right_for = vid_stream->mblock.recon_right_for_prev;
3875
    recon_down_for = vid_stream->mblock.recon_down_for_prev;
3876
  }
3877
 
3878
  if (vid_stream->picture.full_pel_back_vector) {
3879
    recon_right_back = vid_stream->mblock.recon_right_back_prev << 1;
3880
    recon_down_back = vid_stream->mblock.recon_down_back_prev << 1;
3881
  } else {
3882
    recon_right_back = vid_stream->mblock.recon_right_back_prev;
3883
    recon_down_back = vid_stream->mblock.recon_down_back_prev;
3884
  }
3885
 
3886
 
3887
  /* If only one motion vector, do display copy, else do full
3888
     calculation.
3889
  */
3890
 
3891
#ifndef DISABLE_DITHER
3892
  if (ditherType == MBORDERED_DITHER) {
3893
    if (vid_stream->mblock.bpict_past_forw &&
3894
        !vid_stream->mblock.bpict_past_back) {
3895
      for (addr = vid_stream->mblock.past_mb_addr+1;
3896
           addr < vid_stream->mblock.mb_address; addr++) {
3897
 
3898
        MBOrderedDitherDisplayCopy(vid_stream, addr,
3899
                                   1, recon_right_for, recon_down_for,
3900
                                 0, 0, 0, vid_stream->past->display,
3901
                                   vid_stream->future->display);
3902
        vid_stream->ditherFlags[addr] = 0;
3903
      }
3904
      return;
3905
    }
3906
    if (vid_stream->mblock.bpict_past_back &&
3907
        !vid_stream->mblock.bpict_past_forw) {
3908
      for (addr = vid_stream->mblock.past_mb_addr+1;
3909
           addr < vid_stream->mblock.mb_address; addr++) {
3910
 
3911
        MBOrderedDitherDisplayCopy(vid_stream, addr,
3912
                                   0, 0, 0,
3913
                                   1, recon_right_back, recon_down_back,
3914
                                   vid_stream->past->display, vid_stream->future->display);
3915
        vid_stream->ditherFlags[addr] = 0;
3916
      }
3917
      return;
3918
    }
3919
  }
3920
#endif
3921
 
3922
  /* Calculate motion vectors. */
3923
 
3924
  if (vid_stream->mblock.bpict_past_forw) {
3925
    right_for = recon_right_for >> 1;
3926
    down_for = recon_down_for >> 1;
3927
    right_half_for = recon_right_for & 0x1;
3928
    down_half_for = recon_down_for & 0x1;
3929
 
3930
    recon_right_for /= 2;
3931
    recon_down_for /= 2;
3932
    c_right_for = recon_right_for >> 1;
3933
    c_down_for = recon_down_for >> 1;
3934
    c_right_half_for = recon_right_for & 0x1;
3935
    c_down_half_for = recon_down_for & 0x1;
3936
 
3937
  }
3938
  if (vid_stream->mblock.bpict_past_back) {
3939
    right_back = recon_right_back >> 1;
3940
    down_back = recon_down_back >> 1;
3941
    right_half_back = recon_right_back & 0x1;
3942
    down_half_back = recon_down_back & 0x1;
3943
 
3944
    recon_right_back /= 2;
3945
    recon_down_back /= 2;
3946
    c_right_back = recon_right_back >> 1;
3947
    c_down_back = recon_down_back >> 1;
3948
    c_right_half_back = recon_right_back & 0x1;
3949
    c_down_half_back = recon_down_back & 0x1;
3950
 
3951
  }
3952
  /* For each skipped macroblock, do... */
3953
 
3954
  for (addr = vid_stream->mblock.past_mb_addr + 1;
3955
       addr < vid_stream->mblock.mb_address; addr++) {
3956
 
3957
    /* Calculate macroblock row and col. */
3958
 
3959
    mb_row = addr / vid_stream->mb_width;
3960
    mb_col = addr % vid_stream->mb_width;
3961
 
3962
    /* Calculate upper left pixel row,col for luminance plane. */
3963
 
3964
    row = mb_row << 4;
3965
    col = mb_col << 4;
3966
    crow = row / 2;
3967
    ccol = col / 2;
3968
 
3969
    /* If forward predicted, calculate prediction values. */
3970
 
3971
    if (vid_stream->mblock.bpict_past_forw) {
3972
 
3973
      ReconSkippedBlock(vid_stream->past->luminance, forw_lum,
3974
                        row, col, row_size, right_for, down_for,
3975
                        right_half_for, down_half_for, 16);
3976
      ReconSkippedBlock(vid_stream->past->Cr, forw_cr, crow,
3977
                        ccol, half_row,
3978
                        c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
3979
      ReconSkippedBlock(vid_stream->past->Cb, forw_cb, crow,
3980
                        ccol, half_row,
3981
                        c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
3982
    }
3983
    /* If back predicted, calculate prediction values. */
3984
 
3985
    if (vid_stream->mblock.bpict_past_back) {
3986
      ReconSkippedBlock(vid_stream->future->luminance, back_lum,
3987
                        row, col, row_size, right_back, down_back,
3988
                        right_half_back, down_half_back, 16);
3989
      ReconSkippedBlock(vid_stream->future->Cr, back_cr, crow,
3990
                        ccol, half_row,
3991
                        c_right_back, c_down_back,
3992
                        c_right_half_back, c_down_half_back, 8);
3993
      ReconSkippedBlock(vid_stream->future->Cb, back_cb, crow,
3994
                        ccol, half_row,
3995
                        c_right_back, c_down_back,
3996
                        c_right_half_back, c_down_half_back, 8);
3997
    }
3998
    if (vid_stream->mblock.bpict_past_forw &&
3999
        !vid_stream->mblock.bpict_past_back) {
4000
 
4001
      int *dest, *dest1;
4002
      int *src, *src1;
4003
      dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
4004
      src = (int *)forw_lum;
4005
 
4006
      for (rr = 0; rr < 16; rr++) {
4007
 
4008
        /* memcpy(dest, forw_lum+(rr<<4), 16);  */
4009
        dest[0] = src[0];
4010
        dest[1] = src[1];
4011
        dest[2] = src[2];
4012
        dest[3] = src[3];
4013
        dest += row_incr;
4014
        src += 4;
4015
      }
4016
 
4017
      dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
4018
      dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
4019
      src = (int *)forw_cr;
4020
      src1 = (int *)forw_cb;
4021
 
4022
      for (rr = 0; rr < 8; rr++) {
4023
        /*
4024
         * memcpy(dest, forw_cr+(rr<<3), 8); memcpy(dest1, forw_cb+(rr<<3),
4025
         * 8);
4026
         */
4027
 
4028
        dest[0] = src[0];
4029
        dest[1] = src[1];
4030
 
4031
        dest1[0] = src1[0];
4032
        dest1[1] = src1[1];
4033
 
4034
        dest += half_row_incr;
4035
        dest1 += half_row_incr;
4036
        src += 2;
4037
        src1 += 2;
4038
      }
4039
    } else if (vid_stream->mblock.bpict_past_back &&
4040
               !vid_stream->mblock.bpict_past_forw) {
4041
 
4042
      int *src, *src1;
4043
      int *dest, *dest1;
4044
      dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
4045
      src = (int *)back_lum;
4046
 
4047
      for (rr = 0; rr < 16; rr++) {
4048
        dest[0] = src[0];
4049
        dest[1] = src[1];
4050
        dest[2] = src[2];
4051
        dest[3] = src[3];
4052
        dest += row_incr;
4053
        src += 4;
4054
      }
4055
 
4056
 
4057
      dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
4058
      dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
4059
      src = (int *)back_cr;
4060
      src1 = (int *)back_cb;
4061
 
4062
      for (rr = 0; rr < 8; rr++) {
4063
        /*
4064
         * memcpy(dest, back_cr+(rr<<3), 8); memcpy(dest1, back_cb+(rr<<3),
4065
         * 8);
4066
         */
4067
 
4068
        dest[0] = src[0];
4069
        dest[1] = src[1];
4070
 
4071
        dest1[0] = src1[0];
4072
        dest1[1] = src1[1];
4073
 
4074
        dest += half_row_incr;
4075
        dest1 += half_row_incr;
4076
        src += 2;
4077
        src1 += 2;
4078
      }
4079
    } else {
4080
 
4081
      unsigned char *src1, *src2, *src1a, *src2a;
4082
      unsigned char *dest, *dest1;
4083
      dest = vid_stream->current->luminance + (row * row_size) + col;
4084
      src1 = forw_lum;
4085
      src2 = back_lum;
4086
 
4087
      for (rr = 0; rr < 16; rr++) {
4088
        dest[0] = (int) (src1[0] + src2[0]) >> 1;
4089
        dest[1] = (int) (src1[1] + src2[1]) >> 1;
4090
        dest[2] = (int) (src1[2] + src2[2]) >> 1;
4091
        dest[3] = (int) (src1[3] + src2[3]) >> 1;
4092
        dest[4] = (int) (src1[4] + src2[4]) >> 1;
4093
        dest[5] = (int) (src1[5] + src2[5]) >> 1;
4094
        dest[6] = (int) (src1[6] + src2[6]) >> 1;
4095
        dest[7] = (int) (src1[7] + src2[7]) >> 1;
4096
        dest[8] = (int) (src1[8] + src2[8]) >> 1;
4097
        dest[9] = (int) (src1[9] + src2[9]) >> 1;
4098
        dest[10] = (int) (src1[10] + src2[10]) >> 1;
4099
        dest[11] = (int) (src1[11] + src2[11]) >> 1;
4100
        dest[12] = (int) (src1[12] + src2[12]) >> 1;
4101
        dest[13] = (int) (src1[13] + src2[13]) >> 1;
4102
        dest[14] = (int) (src1[14] + src2[14]) >> 1;
4103
        dest[15] = (int) (src1[15] + src2[15]) >> 1;
4104
        dest += row_size;
4105
        src1 += 16;
4106
        src2 += 16;
4107
      }
4108
 
4109
 
4110
      dest = vid_stream->current->Cr + (crow * half_row) + ccol;
4111
      dest1 = vid_stream->current->Cb + (crow * half_row) + ccol;
4112
      src1 = forw_cr;
4113
      src2 = back_cr;
4114
      src1a = forw_cb;
4115
      src2a = back_cb;
4116
 
4117
      for (rr = 0; rr < 8; rr++) {
4118
        dest[0] = (int) (src1[0] + src2[0]) >> 1;
4119
        dest[1] = (int) (src1[1] + src2[1]) >> 1;
4120
        dest[2] = (int) (src1[2] + src2[2]) >> 1;
4121
        dest[3] = (int) (src1[3] + src2[3]) >> 1;
4122
        dest[4] = (int) (src1[4] + src2[4]) >> 1;
4123
        dest[5] = (int) (src1[5] + src2[5]) >> 1;
4124
        dest[6] = (int) (src1[6] + src2[6]) >> 1;
4125
        dest[7] = (int) (src1[7] + src2[7]) >> 1;
4126
        dest += half_row;
4127
        src1 += 8;
4128
        src2 += 8;
4129
 
4130
        dest1[0] = (int) (src1a[0] + src2a[0]) >> 1;
4131
        dest1[1] = (int) (src1a[1] + src2a[1]) >> 1;
4132
        dest1[2] = (int) (src1a[2] + src2a[2]) >> 1;
4133
        dest1[3] = (int) (src1a[3] + src2a[3]) >> 1;
4134
        dest1[4] = (int) (src1a[4] + src2a[4]) >> 1;
4135
        dest1[5] = (int) (src1a[5] + src2a[5]) >> 1;
4136
        dest1[6] = (int) (src1a[6] + src2a[6]) >> 1;
4137
        dest1[7] = (int) (src1a[7] + src2a[7]) >> 1;
4138
        dest1 += half_row;
4139
        src1a += 8;
4140
        src2a += 8;
4141
      }
4142
    }
4143
 
4144
#ifndef DISABLE_DITHER
4145
    if (ditherType == MBORDERED_DITHER) {
4146
      vid_stream->ditherFlags[addr] = 1;
4147
    }
4148
#endif
4149
  }
4150
}
4151
 
4152
 
4153
 
4154
 
4155
 
4156
/*
4157
 *--------------------------------------------------------------
4158
 *
4159
 * ReconSkippedBlock --
4160
 *
4161
 *      Reconstructs predictive block for skipped macroblocks
4162
 *      in B Frames.
4163
 *
4164
 * Results:
4165
 *      No return values.
4166
 *
4167
 * Side effects:
4168
 *      None.
4169
 *
4170
 *--------------------------------------------------------------
4171
 */
4172
 
4173
static void
4174
ReconSkippedBlock(source, dest, row, col, row_size,
4175
                  right, down, right_half, down_half, width)
4176
  unsigned char *source;
4177
  unsigned char *dest;
4178
  int row, col, row_size, right, down, right_half, down_half, width;
4179
{
4180
  int rr;
4181
  unsigned char *source2;
4182
 
4183
  source += ((row + down) * row_size) + col + right;
4184
 
4185
  if (width == 16) {
4186
    if ((!right_half) && (!down_half)) {
4187
        if (right & 0x1) {
4188
          /* No alignment, use bye copy */
4189
          for (rr = 0; rr < 16; rr++) {
4190
            dest[0] = source[0];
4191
            dest[1] = source[1];
4192
            dest[2] = source[2];
4193
            dest[3] = source[3];
4194
            dest[4] = source[4];
4195
            dest[5] = source[5];
4196
            dest[6] = source[6];
4197
            dest[7] = source[7];
4198
            dest[8] = source[8];
4199
            dest[9] = source[9];
4200
            dest[10] = source[10];
4201
            dest[11] = source[11];
4202
            dest[12] = source[12];
4203
            dest[13] = source[13];
4204
            dest[14] = source[14];
4205
            dest[15] = source[15];
4206
            dest += 16;
4207
            source += row_size;
4208
          }
4209
        } else if (right & 0x2) {
4210
          /* Half-word bit aligned, use 16 bit copy */
4211
          short *src = (short *)source;
4212
          short *d = (short *)dest;
4213
          row_size >>= 1;
4214
          for (rr = 0; rr < 16; rr++) {
4215
            d[0] = src[0];
4216
            d[1] = src[1];
4217
            d[2] = src[2];
4218
            d[3] = src[3];
4219
            d[4] = src[4];
4220
            d[5] = src[5];
4221
            d[6] = src[6];
4222
            d[7] = src[7];
4223
            d += 8;
4224
            src += row_size;
4225
          }
4226
        } else {
4227
          /* Word aligned, use 32 bit copy */
4228
          int *src = (int *)source;
4229
          int *d = (int *)dest;
4230
          row_size >>= 2;
4231
          for (rr = 0; rr < 16; rr++) {
4232
            d[0] = src[0];
4233
            d[1] = src[1];
4234
            d[2] = src[2];
4235
            d[3] = src[3];
4236
            d += 4;
4237
            src += row_size;
4238
          }
4239
        }
4240
    } else {
4241
      source2 = source + right_half + (row_size * down_half);
4242
      for (rr = 0; rr < width; rr++) {
4243
        dest[0] = (int) (source[0] + source2[0]) >> 1;
4244
        dest[1] = (int) (source[1] + source2[1]) >> 1;
4245
        dest[2] = (int) (source[2] + source2[2]) >> 1;
4246
        dest[3] = (int) (source[3] + source2[3]) >> 1;
4247
        dest[4] = (int) (source[4] + source2[4]) >> 1;
4248
        dest[5] = (int) (source[5] + source2[5]) >> 1;
4249
        dest[6] = (int) (source[6] + source2[6]) >> 1;
4250
        dest[7] = (int) (source[7] + source2[7]) >> 1;
4251
        dest[8] = (int) (source[8] + source2[8]) >> 1;
4252
        dest[9] = (int) (source[9] + source2[9]) >> 1;
4253
        dest[10] = (int) (source[10] + source2[10]) >> 1;
4254
        dest[11] = (int) (source[11] + source2[11]) >> 1;
4255
        dest[12] = (int) (source[12] + source2[12]) >> 1;
4256
        dest[13] = (int) (source[13] + source2[13]) >> 1;
4257
        dest[14] = (int) (source[14] + source2[14]) >> 1;
4258
        dest[15] = (int) (source[15] + source2[15]) >> 1;
4259
        dest += width;
4260
        source += row_size;
4261
        source2 += row_size;
4262
      }
4263
    }
4264
  } else {                      /* (width == 8) */
4265
    assert(width == 8);
4266
    if ((!right_half) && (!down_half)) {
4267
      if (right & 0x1) {
4268
        for (rr = 0; rr < width; rr++) {
4269
          dest[0] = source[0];
4270
          dest[1] = source[1];
4271
          dest[2] = source[2];
4272
          dest[3] = source[3];
4273
          dest[4] = source[4];
4274
          dest[5] = source[5];
4275
          dest[6] = source[6];
4276
          dest[7] = source[7];
4277
          dest += 8;
4278
          source += row_size;
4279
        }
4280
      } else if (right & 0x02) {
4281
        short *d = (short *)dest;
4282
        short *src = (short *)source;
4283
        row_size >>= 1;
4284
        for (rr = 0; rr < width; rr++) {
4285
          d[0] = src[0];
4286
          d[1] = src[1];
4287
          d[2] = src[2];
4288
          d[3] = src[3];
4289
          d += 4;
4290
          src += row_size;
4291
        }
4292
      } else {
4293
        int *d = (int *)dest;
4294
        int *src = (int *)source;
4295
        row_size >>= 2;
4296
        for (rr = 0; rr < width; rr++) {
4297
          d[0] = src[0];
4298
          d[1] = src[1];
4299
          d += 2;
4300
          src += row_size;
4301
        }
4302
      }
4303
    } else {
4304
      source2 = source + right_half + (row_size * down_half);
4305
      for (rr = 0; rr < width; rr++) {
4306
        dest[0] = (int) (source[0] + source2[0]) >> 1;
4307
        dest[1] = (int) (source[1] + source2[1]) >> 1;
4308
        dest[2] = (int) (source[2] + source2[2]) >> 1;
4309
        dest[3] = (int) (source[3] + source2[3]) >> 1;
4310
        dest[4] = (int) (source[4] + source2[4]) >> 1;
4311
        dest[5] = (int) (source[5] + source2[5]) >> 1;
4312
        dest[6] = (int) (source[6] + source2[6]) >> 1;
4313
        dest[7] = (int) (source[7] + source2[7]) >> 1;
4314
        dest += width;
4315
        source += row_size;
4316
        source2 += row_size;
4317
      }
4318
    }
4319
  }
4320
}
4321
 
4322
 
4323
 
4324
 
4325
/*
4326
 *--------------------------------------------------------------
4327
 *
4328
 * DoPictureDisplay --
4329
 *
4330
 *      Converts image from Lum, Cr, Cb to colormap space. Puts
4331
 *      image in lum plane. Updates past and future frame
4332
 *      pointers. Dithers image. Sends to display mechanism.
4333
 *
4334
 * Results:
4335
 *      Pict image structure locked if displaying or if frame
4336
 *      is needed as past or future reference.
4337
 *
4338
 * Side effects:
4339
 *      Lum plane pummelled.
4340
 *
4341
 *--------------------------------------------------------------
4342
 */
4343
 
4344
static void
4345
DoPictureDisplay(vid_stream, xinfo)
4346
  VidStream *vid_stream;
4347
  XInfo *xinfo;
4348
{
4349
 
4350
  if (No_B_Flag && (vid_stream->picture.code_type == B_TYPE)) return;
4351
 
4352
  /* Convert to colormap space and dither. */
4353
  DoDitherImage(vid_stream);
4354
 
4355
  /* Update past and future references if needed. */
4356
 
4357
  if ((vid_stream->picture.code_type == I_TYPE) || (vid_stream->picture.code_type == P_TYPE)) {
4358
    if (vid_stream->future == NULL) {
4359
      vid_stream->future = vid_stream->current;
4360
      vid_stream->future->locked |= FUTURE_LOCK;
4361
    } else {
4362
      if (vid_stream->past != NULL) {
4363
        vid_stream->past->locked &= ~PAST_LOCK;
4364
      }
4365
      vid_stream->past = vid_stream->future;
4366
      vid_stream->past->locked &= ~FUTURE_LOCK;
4367
      vid_stream->past->locked |= PAST_LOCK;
4368
      vid_stream->future = vid_stream->current;
4369
      vid_stream->future->locked |= FUTURE_LOCK;
4370
      vid_stream->current = vid_stream->past;
4371
#ifndef NOCONTROLS
4372
      ExecuteDisplay(vid_stream, 1, xinfo);
4373
#else
4374
      ExecuteDisplay(vid_stream, xinfo);
4375
#endif /* !NOCONTROLS */
4376
    }
4377
  } else {
4378
#ifndef NOCONTROLS
4379
    ExecuteDisplay(vid_stream, 1, xinfo);
4380
#else
4381
    ExecuteDisplay(vid_stream, xinfo);
4382
#endif /* !NOCONTROLS */
4383
  }
4384
}
4385
 
4386
 
4387
 
4388
 
4389
/*
4390
 *--------------------------------------------------------------
4391
 *
4392
 * SetBFlag --
4393
 *
4394
 *      Called to set no b frame processing flag.
4395
 *
4396
 * Results:
4397
 *      No_B_Flag flag is set to its argument.
4398
 *
4399
 * Side effects:
4400
 *      None.
4401
 *
4402
 *--------------------------------------------------------------
4403
 */
4404
 
4405
void
4406
SetBFlag(val)
4407
BOOLEAN val;
4408
{
4409
    No_B_Flag = val;
4410
}
4411
 
4412
 
4413
 
4414
 
4415
 
4416
/*
4417
 *--------------------------------------------------------------
4418
 *
4419
 * SetPFlag --
4420
 *
4421
 *      Called to set no p frame processing flag.
4422
 *
4423
 * Results:
4424
 *      No_P_Flag flag is set to value of argument
4425
 *
4426
 * Side effects:
4427
 *      None.
4428
 *
4429
 *--------------------------------------------------------------
4430
 */
4431
 
4432
void
4433
SetPFlag(val)
4434
BOOLEAN val;
4435
{
4436
    No_P_Flag = val;
4437
}