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