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