Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / theora-fpga / doc / leon3_integration / dct_decode2.c
blobd2756d96d4426eacef223cbe076d9b48eb9931e1
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function:
14 last mod: $Id: dct_decode.c 11442 2006-05-27 17:28:08Z giles $
16 ********************************************************************/
18 #include <stdlib.h>
19 #include <string.h>
20 #include "codec_internal.h"
21 #include "dsp.h"
23 # include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/fcntl.h>
27 #define GOLDEN_FRAME_THRESH_Q 50
28 #define PUR 8
29 #define PU 4
30 #define PUL 2
31 #define PL 1
32 #define HIGHBITDUPPED(X) (((signed short) X) >> 15)
34 /* in-loop filter tables. one of these is used in dct_decode.c */
36 static const unsigned char LoopFilterLimitValuesV1[Q_TABLE_SIZE] = {
37 30, 25, 20, 20, 15, 15, 14, 14,
38 13, 13, 12, 12, 11, 11, 10, 10,
39 9, 9, 8, 8, 7, 7, 7, 7,
40 6, 6, 6, 6, 5, 5, 5, 5,
41 4, 4, 4, 4, 3, 3, 3, 3,
42 2, 2, 2, 2, 2, 2, 2, 2,
43 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 0, 0, 0, 0, 0, 0, 0
47 static const unsigned char LoopFilterLimitValuesV2[Q_TABLE_SIZE] = {
48 30, 25, 20, 20, 15, 15, 14, 14,
49 13, 13, 12, 12, 11, 11, 10, 10,
50 9, 9, 8, 8, 7, 7, 7, 7,
51 6, 6, 6, 6, 5, 5, 5, 5,
52 4, 4, 4, 4, 3, 3, 3, 3,
53 2, 2, 2, 2, 2, 2, 2, 2,
54 2, 2, 2, 2, 2, 2, 2, 2,
55 1, 1, 1, 1, 1, 1, 1, 1
58 static const int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
60 static void SetupBoundingValueArray_Generic(PB_INSTANCE *pbi,
61 ogg_int32_t FLimit){
63 ogg_int32_t * BoundingValuePtr = pbi->FiltBoundingValue+256;
64 ogg_int32_t i;
66 /* Set up the bounding value array. */
67 memset ( pbi->FiltBoundingValue, 0, (512*sizeof(*pbi->FiltBoundingValue)) );
68 for ( i = 0; i < FLimit; i++ ){
69 BoundingValuePtr[-i-FLimit] = (-FLimit+i);
70 BoundingValuePtr[-i] = -i;
71 BoundingValuePtr[i] = i;
72 BoundingValuePtr[i+FLimit] = FLimit-i;
76 /* handle the in-loop filter limit value table */
78 void WriteFilterTables(PB_INSTANCE *pbi, oggpack_buffer *opb){
79 int i;
80 int bits=5;
81 oggpackB_write(opb, bits, 3);
82 for(i=0;i<Q_TABLE_SIZE;i++)
83 oggpackB_write(opb, pbi->LoopFilterLimits[i],bits);
86 int ReadFilterTables(codec_setup_info *ci, oggpack_buffer *opb){
87 int i;
88 int bits, value;
90 theora_read(opb, 3, &bits);
91 for(i=0;i<Q_TABLE_SIZE;i++){
92 theora_read(opb,bits,&value);
93 ci->LoopFilterLimitValues[i]=value;
95 if(bits<0)return OC_BADHEADER;
97 return 0;
100 /* copy in-loop filter limits from the bitstream header into our instance */
101 void CopyFilterTables(PB_INSTANCE *pbi, codec_setup_info *ci){
102 memcpy(pbi->LoopFilterLimits, ci->LoopFilterLimitValues, Q_TABLE_SIZE);
105 /* initialize the filter limits from our static table */
106 void InitFilterTables(PB_INSTANCE *pbi){
107 memcpy(pbi->LoopFilterLimits, LoopFilterLimitValuesV1, Q_TABLE_SIZE);
110 void SetupLoopFilter(PB_INSTANCE *pbi){
111 ogg_int32_t FLimit;
113 /* nb: this was using the V2 values rather than V1
114 we think is was a mistake; the results were not used */
115 FLimit = pbi->LoopFilterLimits[pbi->FrameQIndex];
116 SetupBoundingValueArray_Generic(pbi, FLimit);
119 static void ExpandKFBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){
120 ogg_uint32_t ReconPixelsPerLine;
121 ogg_int32_t ReconPixelIndex;
123 /* Select the appropriate inverse Q matrix and line stride */
124 if ( FragmentNumber<(ogg_int32_t)pbi->YPlaneFragments ){
125 ReconPixelsPerLine = pbi->YStride;
126 pbi->dequant_coeffs = pbi->dequant_Y_coeffs;
127 }else if ( FragmentNumber<(ogg_int32_t)(pbi->YPlaneFragments + pbi->UVPlaneFragments) ){
128 ReconPixelsPerLine = pbi->UVStride;
129 pbi->dequant_coeffs = pbi->dequant_U_coeffs;
130 }else{
131 ReconPixelsPerLine = pbi->UVStride;
132 pbi->dequant_coeffs = pbi->dequant_V_coeffs;
135 /* Set up pointer into the quantisation buffer. */
136 pbi->quantized_list = &pbi->QFragData[FragmentNumber][0];
138 /* Invert quantisation and DCT to get pixel data. */
139 switch(pbi->FragCoefEOB[FragmentNumber]){
140 case 0:case 1:
141 IDct1( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
142 break;
143 case 2: case 3:case 4:case 5:case 6:case 7:case 8: case 9:case 10:
144 IDct10( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
145 break;
146 default:
147 IDctSlow( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
150 /* Convert fragment number to a pixel offset in a reconstruction buffer. */
151 ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];
153 /* Get the pixel index for the first pixel in the fragment. */
154 dsp_recon_intra8x8 (pbi->dsp, (unsigned char *)(&pbi->ThisFrameRecon[ReconPixelIndex]),
155 (ogg_int16_t *)pbi->ReconDataBuffer, ReconPixelsPerLine);
159 static void ExpandBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){
160 unsigned char *LastFrameRecPtr; /* Pointer into previous frame
161 reconstruction. */
162 unsigned char *LastFrameRecPtr2; /* Pointer into previous frame
163 reconstruction for 1/2 pixel MC. */
165 ogg_uint32_t ReconPixelsPerLine; /* Pixels per line */
166 ogg_int32_t ReconPixelIndex; /* Offset for block into a
167 reconstruction buffer */
168 ogg_int32_t ReconPtr2Offset; /* Offset for second
169 reconstruction in half pixel
170 MC */
171 ogg_int32_t MVOffset; /* Baseline motion vector offset */
172 ogg_int32_t MvShift ; /* Shift to correct to 1/2 or 1/4 pixel */
173 ogg_int32_t MvModMask; /* Mask to determine whether 1/2
174 pixel is used */
176 /* Get coding mode for this block */
177 if ( GetFrameType(pbi) == KEY_FRAME ){
178 pbi->CodingMode = CODE_INTRA;
179 }else{
180 /* Get Motion vector and mode for this block. */
181 pbi->CodingMode = pbi->FragCodingMethod[FragmentNumber];
184 /* Select the appropriate inverse Q matrix and line stride */
185 if ( FragmentNumber<(ogg_int32_t)pbi->YPlaneFragments ) {
186 ReconPixelsPerLine = pbi->YStride;
187 MvShift = 1;
188 MvModMask = 0x00000001;
190 /* Select appropriate dequantiser matrix. */
191 if ( pbi->CodingMode == CODE_INTRA )
192 pbi->dequant_coeffs = pbi->dequant_Y_coeffs;
193 else
194 pbi->dequant_coeffs = pbi->dequant_InterY_coeffs;
195 }else{
196 ReconPixelsPerLine = pbi->UVStride;
197 MvShift = 2;
198 MvModMask = 0x00000003;
200 /* Select appropriate dequantiser matrix. */
201 if ( pbi->CodingMode == CODE_INTRA )
202 if ( FragmentNumber <
203 (ogg_int32_t)(pbi->YPlaneFragments + pbi->UVPlaneFragments) )
204 pbi->dequant_coeffs = pbi->dequant_U_coeffs;
205 else
206 pbi->dequant_coeffs = pbi->dequant_V_coeffs;
207 else
208 if ( FragmentNumber <
209 (ogg_int32_t)(pbi->YPlaneFragments + pbi->UVPlaneFragments) )
210 pbi->dequant_coeffs = pbi->dequant_InterU_coeffs;
211 else
212 pbi->dequant_coeffs = pbi->dequant_InterV_coeffs;
215 /* Set up pointer into the quantisation buffer. */
216 pbi->quantized_list = &pbi->QFragData[FragmentNumber][0];
218 /* Invert quantisation and DCT to get pixel data. */
219 switch(pbi->FragCoefEOB[FragmentNumber]){
220 case 0:case 1:
221 IDct1( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
222 break;
223 case 2: case 3:case 4:case 5:case 6:case 7:case 8: case 9:case 10:
224 IDct10( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
225 break;
226 default:
227 IDctSlow( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
230 /* Convert fragment number to a pixel offset in a reconstruction buffer. */
231 ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];
233 /* Action depends on decode mode. */
234 if ( pbi->CodingMode == CODE_INTER_NO_MV ){
235 /* Inter with no motion vector */
236 /* Reconstruct the pixel data using the last frame reconstruction
237 and change data when the motion vector is (0,0), the recon is
238 based on the lastframe without loop filtering---- for testing */
239 dsp_recon_inter8x8 (pbi->dsp, &pbi->ThisFrameRecon[ReconPixelIndex],
240 &pbi->LastFrameRecon[ReconPixelIndex],
241 pbi->ReconDataBuffer, ReconPixelsPerLine);
242 }else if ( ModeUsesMC[pbi->CodingMode] ) {
243 /* The mode uses a motion vector. */
244 /* Get vector from list */
245 pbi->MVector.x = pbi->FragMVect[FragmentNumber].x;
246 pbi->MVector.y = pbi->FragMVect[FragmentNumber].y;
248 /* Work out the base motion vector offset and the 1/2 pixel offset
249 if any. For the U and V planes the MV specifies 1/4 pixel
250 accuracy. This is adjusted to 1/2 pixel as follows ( 0->0,
251 1/4->1/2, 1/2->1/2, 3/4->1/2 ). */
252 MVOffset = 0;
253 ReconPtr2Offset = 0;
254 if ( pbi->MVector.x > 0 ){
255 MVOffset = pbi->MVector.x >> MvShift;
256 if ( pbi->MVector.x & MvModMask )
257 ReconPtr2Offset += 1;
258 } else if ( pbi->MVector.x < 0 ) {
259 MVOffset -= (-pbi->MVector.x) >> MvShift;
260 if ( (-pbi->MVector.x) & MvModMask )
261 ReconPtr2Offset -= 1;
264 if ( pbi->MVector.y > 0 ){
265 MVOffset += (pbi->MVector.y >> MvShift) * ReconPixelsPerLine;
266 if ( pbi->MVector.y & MvModMask )
267 ReconPtr2Offset += ReconPixelsPerLine;
268 } else if ( pbi->MVector.y < 0 ){
269 MVOffset -= ((-pbi->MVector.y) >> MvShift) * ReconPixelsPerLine;
270 if ( (-pbi->MVector.y) & MvModMask )
271 ReconPtr2Offset -= ReconPixelsPerLine;
274 /* Set up the first of the two reconstruction buffer pointers. */
275 if ( pbi->CodingMode==CODE_GOLDEN_MV ) {
276 LastFrameRecPtr = &pbi->GoldenFrame[ReconPixelIndex] + MVOffset;
277 }else{
278 LastFrameRecPtr = &pbi->LastFrameRecon[ReconPixelIndex] + MVOffset;
281 /* Set up the second of the two reconstruction pointers. */
282 LastFrameRecPtr2 = LastFrameRecPtr + ReconPtr2Offset;
284 /* Select the appropriate reconstruction function */
285 if ( (int)(LastFrameRecPtr - LastFrameRecPtr2) == 0 ) {
286 /* Reconstruct the pixel dats from the reference frame and change data
287 (no half pixel in this case as the two references were the same. */
288 dsp_recon_inter8x8 (pbi->dsp,
289 &pbi->ThisFrameRecon[ReconPixelIndex],
290 LastFrameRecPtr, pbi->ReconDataBuffer,
291 ReconPixelsPerLine);
292 }else{
293 /* Fractional pixel reconstruction. */
294 /* Note that we only use two pixels per reconstruction even for
295 the diagonal. */
296 dsp_recon_inter8x8_half(pbi->dsp, &pbi->ThisFrameRecon[ReconPixelIndex],
297 LastFrameRecPtr, LastFrameRecPtr2,
298 pbi->ReconDataBuffer, ReconPixelsPerLine);
300 } else if ( pbi->CodingMode == CODE_USING_GOLDEN ){
301 /* Golden frame with motion vector */
302 /* Reconstruct the pixel data using the golden frame
303 reconstruction and change data */
304 dsp_recon_inter8x8 (pbi->dsp, &pbi->ThisFrameRecon[ReconPixelIndex],
305 &pbi->GoldenFrame[ ReconPixelIndex ],
306 pbi->ReconDataBuffer, ReconPixelsPerLine);
307 } else {
308 /* Simple Intra coding */
309 /* Get the pixel index for the first pixel in the fragment. */
310 dsp_recon_intra8x8 (pbi->dsp, &pbi->ThisFrameRecon[ReconPixelIndex],
311 pbi->ReconDataBuffer, ReconPixelsPerLine);
315 static void UpdateUMV_HBorders( PB_INSTANCE *pbi,
316 unsigned char * DestReconPtr,
317 ogg_uint32_t PlaneFragOffset ) {
318 ogg_uint32_t i;
319 ogg_uint32_t PixelIndex;
321 ogg_uint32_t PlaneStride;
322 ogg_uint32_t BlockVStep;
323 ogg_uint32_t PlaneFragments;
324 ogg_uint32_t LineFragments;
325 ogg_uint32_t PlaneBorderWidth;
327 unsigned char *SrcPtr1;
328 unsigned char *SrcPtr2;
329 unsigned char *DestPtr1;
330 unsigned char *DestPtr2;
332 /* Work out various plane specific values */
333 if ( PlaneFragOffset == 0 ) {
334 /* Y Plane */
335 BlockVStep = (pbi->YStride *
336 (VFRAGPIXELS - 1));
337 PlaneStride = pbi->YStride;
338 PlaneBorderWidth = UMV_BORDER;
339 PlaneFragments = pbi->YPlaneFragments;
340 LineFragments = pbi->HFragments;
341 }else{
342 /* U or V plane. */
343 BlockVStep = (pbi->UVStride *
344 (VFRAGPIXELS - 1));
345 PlaneStride = pbi->UVStride;
346 PlaneBorderWidth = UMV_BORDER / 2;
347 PlaneFragments = pbi->UVPlaneFragments;
348 LineFragments = pbi->HFragments / 2;
351 /* Setup the source and destination pointers for the top and bottom
352 borders */
353 PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset];
354 SrcPtr1 = &DestReconPtr[ PixelIndex - PlaneBorderWidth ];
355 DestPtr1 = SrcPtr1 - (PlaneBorderWidth * PlaneStride);
357 PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset +
358 PlaneFragments - LineFragments] +
359 BlockVStep;
360 SrcPtr2 = &DestReconPtr[ PixelIndex - PlaneBorderWidth];
361 DestPtr2 = SrcPtr2 + PlaneStride;
363 /* Now copy the top and bottom source lines into each line of the
364 respective borders */
365 for ( i = 0; i < PlaneBorderWidth; i++ ) {
366 memcpy( DestPtr1, SrcPtr1, PlaneStride );
367 memcpy( DestPtr2, SrcPtr2, PlaneStride );
368 DestPtr1 += PlaneStride;
369 DestPtr2 += PlaneStride;
373 static void UpdateUMV_VBorders( PB_INSTANCE *pbi,
374 unsigned char * DestReconPtr,
375 ogg_uint32_t PlaneFragOffset ){
376 ogg_uint32_t i;
377 ogg_uint32_t PixelIndex;
379 ogg_uint32_t PlaneStride;
380 ogg_uint32_t LineFragments;
381 ogg_uint32_t PlaneBorderWidth;
382 ogg_uint32_t PlaneHeight;
384 unsigned char *SrcPtr1;
385 unsigned char *SrcPtr2;
386 unsigned char *DestPtr1;
387 unsigned char *DestPtr2;
389 /* Work out various plane specific values */
390 if ( PlaneFragOffset == 0 ) {
391 /* Y Plane */
392 PlaneStride = pbi->YStride;
393 PlaneBorderWidth = UMV_BORDER;
394 LineFragments = pbi->HFragments;
395 PlaneHeight = pbi->info.height;
396 }else{
397 /* U or V plane. */
398 PlaneStride = pbi->UVStride;
399 PlaneBorderWidth = UMV_BORDER / 2;
400 LineFragments = pbi->HFragments / 2;
401 PlaneHeight = pbi->info.height / 2;
404 /* Setup the source data values and destination pointers for the
405 left and right edge borders */
406 PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset];
407 SrcPtr1 = &DestReconPtr[ PixelIndex ];
408 DestPtr1 = &DestReconPtr[ PixelIndex - PlaneBorderWidth ];
410 PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset +
411 LineFragments - 1] +
412 (HFRAGPIXELS - 1);
413 SrcPtr2 = &DestReconPtr[ PixelIndex ];
414 DestPtr2 = &DestReconPtr[ PixelIndex + 1 ];
416 /* Now copy the top and bottom source lines into each line of the
417 respective borders */
418 for ( i = 0; i < PlaneHeight; i++ ) {
419 memset( DestPtr1, SrcPtr1[0], PlaneBorderWidth );
420 memset( DestPtr2, SrcPtr2[0], PlaneBorderWidth );
421 SrcPtr1 += PlaneStride;
422 SrcPtr2 += PlaneStride;
423 DestPtr1 += PlaneStride;
424 DestPtr2 += PlaneStride;
428 void UpdateUMVBorder( PB_INSTANCE *pbi,
429 unsigned char * DestReconPtr ) {
430 ogg_uint32_t PlaneFragOffset;
432 /* Y plane */
433 PlaneFragOffset = 0;
434 UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
435 UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
437 /* Then the U and V Planes */
438 PlaneFragOffset = pbi->YPlaneFragments;
439 UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
440 UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
442 PlaneFragOffset = pbi->YPlaneFragments + pbi->UVPlaneFragments;
443 UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
444 UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
447 static void CopyRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr,
448 unsigned char * SrcReconPtr ) {
449 ogg_uint32_t i;
450 ogg_uint32_t PlaneLineStep; /* Pixels per line */
451 ogg_uint32_t PixelIndex;
453 unsigned char *SrcPtr; /* Pointer to line of source image data */
454 unsigned char *DestPtr; /* Pointer to line of destination image data */
456 /* Copy over only updated blocks.*/
458 /* First Y plane */
459 PlaneLineStep = pbi->YStride;
460 for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
461 if ( pbi->display_fragments[i] ) {
462 PixelIndex = pbi->recon_pixel_index_table[i];
463 SrcPtr = &SrcReconPtr[ PixelIndex ];
464 DestPtr = &DestReconPtr[ PixelIndex ];
466 dsp_copy8x8 (pbi->dsp, SrcPtr, DestPtr, PlaneLineStep);
470 /* Then U and V */
471 PlaneLineStep = pbi->UVStride;
472 for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) {
473 if ( pbi->display_fragments[i] ) {
474 PixelIndex = pbi->recon_pixel_index_table[i];
475 SrcPtr = &SrcReconPtr[ PixelIndex ];
476 DestPtr = &DestReconPtr[ PixelIndex ];
478 dsp_copy8x8 (pbi->dsp, SrcPtr, DestPtr, PlaneLineStep);
484 static void CopyNotRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr,
485 unsigned char * SrcReconPtr ) {
486 ogg_uint32_t i;
487 ogg_uint32_t PlaneLineStep; /* Pixels per line */
488 ogg_uint32_t PixelIndex;
490 unsigned char *SrcPtr; /* Pointer to line of source image data */
491 unsigned char *DestPtr; /* Pointer to line of destination image data*/
493 /* Copy over only updated blocks. */
495 /* First Y plane */
496 PlaneLineStep = pbi->YStride;
497 for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
498 if ( !pbi->display_fragments[i] ) {
499 PixelIndex = pbi->recon_pixel_index_table[i];
500 SrcPtr = &SrcReconPtr[ PixelIndex ];
501 DestPtr = &DestReconPtr[ PixelIndex ];
503 dsp_copy8x8 (pbi->dsp, SrcPtr, DestPtr, PlaneLineStep);
507 /* Then U and V */
508 PlaneLineStep = pbi->UVStride;
509 for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) {
510 if ( !pbi->display_fragments[i] ) {
511 PixelIndex = pbi->recon_pixel_index_table[i];
512 SrcPtr = &SrcReconPtr[ PixelIndex ];
513 DestPtr = &DestReconPtr[ PixelIndex ];
515 dsp_copy8x8 (pbi->dsp, SrcPtr, DestPtr, PlaneLineStep);
521 void ExpandToken( Q_LIST_ENTRY * ExpandedBlock,
522 unsigned char * CoeffIndex, ogg_uint32_t Token,
523 ogg_int32_t ExtraBits ){
524 /* Is the token is a combination run and value token. */
525 if ( Token >= DCT_RUN_CATEGORY1 ){
526 /* Expand the token and additional bits to a zero run length and
527 data value. */
528 if ( Token < DCT_RUN_CATEGORY2 ) {
529 /* Decoding method depends on token */
530 if ( Token < DCT_RUN_CATEGORY1B ) {
531 /* Step on by the zero run length */
532 *CoeffIndex += (unsigned char)((Token - DCT_RUN_CATEGORY1) + 1);
534 /* The extra bit determines the sign. */
535 if ( ExtraBits & 0x01 )
536 ExpandedBlock[*CoeffIndex] = -1;
537 else
538 ExpandedBlock[*CoeffIndex] = 1;
539 } else if ( Token == DCT_RUN_CATEGORY1B ) {
540 /* Bits 0-1 determines the zero run length */
541 *CoeffIndex += (6 + (ExtraBits & 0x03));
543 /* Bit 2 determines the sign */
544 if ( ExtraBits & 0x04 )
545 ExpandedBlock[*CoeffIndex] = -1;
546 else
547 ExpandedBlock[*CoeffIndex] = 1;
548 }else{
549 /* Bits 0-2 determines the zero run length */
550 *CoeffIndex += (10 + (ExtraBits & 0x07));
552 /* Bit 3 determines the sign */
553 if ( ExtraBits & 0x08 )
554 ExpandedBlock[*CoeffIndex] = -1;
555 else
556 ExpandedBlock[*CoeffIndex] = 1;
558 }else{
559 /* If token == DCT_RUN_CATEGORY2 we have a single 0 followed by
560 a value */
561 if ( Token == DCT_RUN_CATEGORY2 ){
562 /* Step on by the zero run length */
563 *CoeffIndex += 1;
565 /* Bit 1 determines sign, bit 0 the value */
566 if ( ExtraBits & 0x02 )
567 ExpandedBlock[*CoeffIndex] = -(2 + (ExtraBits & 0x01));
568 else
569 ExpandedBlock[*CoeffIndex] = 2 + (ExtraBits & 0x01);
570 }else{
571 /* else we have 2->3 zeros followed by a value */
572 /* Bit 0 determines the zero run length */
573 *CoeffIndex += 2 + (ExtraBits & 0x01);
575 /* Bit 2 determines the sign, bit 1 the value */
576 if ( ExtraBits & 0x04 )
577 ExpandedBlock[*CoeffIndex] = -(2 + ((ExtraBits & 0x02) >> 1));
578 else
579 ExpandedBlock[*CoeffIndex] = 2 + ((ExtraBits & 0x02) >> 1);
583 /* Step on over value */
584 *CoeffIndex += 1;
586 } else if ( Token == DCT_SHORT_ZRL_TOKEN ) {
587 /* Token is a ZRL token so step on by the appropriate number of zeros */
588 *CoeffIndex += ExtraBits + 1;
589 } else if ( Token == DCT_ZRL_TOKEN ) {
590 /* Token is a ZRL token so step on by the appropriate number of zeros */
591 *CoeffIndex += ExtraBits + 1;
592 } else if ( Token < LOW_VAL_TOKENS ) {
593 /* Token is a small single value token. */
594 switch ( Token ) {
595 case ONE_TOKEN:
596 ExpandedBlock[*CoeffIndex] = 1;
597 break;
598 case MINUS_ONE_TOKEN:
599 ExpandedBlock[*CoeffIndex] = -1;
600 break;
601 case TWO_TOKEN:
602 ExpandedBlock[*CoeffIndex] = 2;
603 break;
604 case MINUS_TWO_TOKEN:
605 ExpandedBlock[*CoeffIndex] = -2;
606 break;
609 /* Step on the coefficient index. */
610 *CoeffIndex += 1;
611 }else{
612 /* Token is a larger single value token */
613 /* Expand the token and additional bits to a data value. */
614 if ( Token < DCT_VAL_CATEGORY3 ) {
615 /* Offset from LOW_VAL_TOKENS determines value */
616 Token = Token - LOW_VAL_TOKENS;
618 /* Extra bit determines sign */
619 if ( ExtraBits )
620 ExpandedBlock[*CoeffIndex] =
621 -((Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN));
622 else
623 ExpandedBlock[*CoeffIndex] =
624 (Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN);
625 } else if ( Token == DCT_VAL_CATEGORY3 ) {
626 /* Bit 1 determines sign, Bit 0 the value */
627 if ( ExtraBits & 0x02 )
628 ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT3_MIN + (ExtraBits & 0x01));
629 else
630 ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT3_MIN + (ExtraBits & 0x01);
631 } else if ( Token == DCT_VAL_CATEGORY4 ) {
632 /* Bit 2 determines sign, Bit 0-1 the value */
633 if ( ExtraBits & 0x04 )
634 ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT4_MIN + (ExtraBits & 0x03));
635 else
636 ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT4_MIN + (ExtraBits & 0x03);
637 } else if ( Token == DCT_VAL_CATEGORY5 ) {
638 /* Bit 3 determines sign, Bit 0-2 the value */
639 if ( ExtraBits & 0x08 )
640 ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT5_MIN + (ExtraBits & 0x07));
641 else
642 ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT5_MIN + (ExtraBits & 0x07);
643 } else if ( Token == DCT_VAL_CATEGORY6 ) {
644 /* Bit 4 determines sign, Bit 0-3 the value */
645 if ( ExtraBits & 0x10 )
646 ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F));
647 else
648 ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F);
649 } else if ( Token == DCT_VAL_CATEGORY7 ) {
650 /* Bit 5 determines sign, Bit 0-4 the value */
651 if ( ExtraBits & 0x20 )
652 ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F));
653 else
654 ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F);
655 } else if ( Token == DCT_VAL_CATEGORY8 ) {
656 /* Bit 9 determines sign, Bit 0-8 the value */
657 if ( ExtraBits & 0x200 )
658 ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF));
659 else
660 ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF);
663 /* Step on the coefficient index. */
664 *CoeffIndex += 1;
668 void ClearDownQFragData(PB_INSTANCE *pbi){
669 ogg_int32_t i;
670 Q_LIST_ENTRY * QFragPtr;
672 for ( i = 0; i < pbi->CodedBlockIndex; i++ ) {
673 /* Get the linear index for the current fragment. */
674 QFragPtr = pbi->QFragData[pbi->CodedBlockList[i]];
675 memset(QFragPtr, 0, 64*sizeof(Q_LIST_ENTRY));
679 static void FilterHoriz(unsigned char * PixelPtr,
680 ogg_int32_t LineLength,
681 ogg_int32_t *BoundingValuePtr){
682 ogg_int32_t j;
683 ogg_int32_t FiltVal;
685 for ( j = 0; j < 8; j++ ){
686 FiltVal =
687 ( PixelPtr[0] ) -
688 ( PixelPtr[1] * 3 ) +
689 ( PixelPtr[2] * 3 ) -
690 ( PixelPtr[3] );
692 FiltVal = *(BoundingValuePtr+((FiltVal + 4) >> 3));
694 PixelPtr[1] = clamp255(PixelPtr[1] + FiltVal);
695 PixelPtr[2] = clamp255(PixelPtr[2] - FiltVal);
697 PixelPtr += LineLength;
701 static void FilterVert(unsigned char * PixelPtr,
702 ogg_int32_t LineLength,
703 ogg_int32_t *BoundingValuePtr){
704 ogg_int32_t j;
705 ogg_int32_t FiltVal;
707 /* the math was correct, but negative array indicies are forbidden
708 by ANSI/C99 and will break optimization on several modern
709 compilers */
711 PixelPtr -= 2*LineLength;
713 for ( j = 0; j < 8; j++ ) {
714 FiltVal = ( (ogg_int32_t)PixelPtr[0] ) -
715 ( (ogg_int32_t)PixelPtr[LineLength] * 3 ) +
716 ( (ogg_int32_t)PixelPtr[2 * LineLength] * 3 ) -
717 ( (ogg_int32_t)PixelPtr[3 * LineLength] );
719 FiltVal = *(BoundingValuePtr+((FiltVal + 4) >> 3));
721 PixelPtr[LineLength] = clamp255(PixelPtr[LineLength] + FiltVal);
722 PixelPtr[2 * LineLength] = clamp255(PixelPtr[2*LineLength] - FiltVal);
724 PixelPtr ++;
728 void LoopFilter(PB_INSTANCE *pbi){
729 ogg_int32_t i;
731 ogg_int32_t * BoundingValuePtr=pbi->FiltBoundingValue+256;
732 int FragsAcross=pbi->HFragments;
733 int FromFragment,ToFragment;
734 int FragsDown = pbi->VFragments;
735 ogg_int32_t LineFragments;
736 ogg_int32_t LineLength;
737 ogg_int32_t FLimit;
738 int QIndex;
739 int j,m,n;
741 /* Set the limit value for the loop filter based upon the current
742 quantizer. */
743 QIndex = Q_TABLE_SIZE - 1;
744 while ( QIndex >= 0 ) {
745 if ( (QIndex == 0) ||
746 ( pbi->QThreshTable[QIndex] >= pbi->ThisFrameQualityValue) )
747 break;
748 QIndex --;
751 FLimit = pbi->LoopFilterLimits[QIndex];
752 if ( FLimit == 0 ) return;
753 SetupBoundingValueArray_Generic(pbi, FLimit);
755 for ( j = 0; j < 3 ; j++){
756 switch(j) {
757 case 0: /* y */
758 FromFragment = 0;
759 ToFragment = pbi->YPlaneFragments;
760 FragsAcross = pbi->HFragments;
761 FragsDown = pbi->VFragments;
762 LineLength = pbi->YStride;
763 LineFragments = pbi->HFragments;
764 break;
765 case 1: /* u */
766 FromFragment = pbi->YPlaneFragments;
767 ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ;
768 FragsAcross = pbi->HFragments >> 1;
769 FragsDown = pbi->VFragments >> 1;
770 LineLength = pbi->UVStride;
771 LineFragments = pbi->HFragments / 2;
772 break;
773 /*case 2: v */
774 default:
775 FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
776 ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
777 FragsAcross = pbi->HFragments >> 1;
778 FragsDown = pbi->VFragments >> 1;
779 LineLength = pbi->UVStride;
780 LineFragments = pbi->HFragments / 2;
781 break;
784 i=FromFragment;
786 /**************************************************************
787 First Row
788 **************************************************************/
789 /* first column conditions */
790 /* only do 2 prediction if fragment coded and on non intra or if
791 all fragments are intra */
792 if( pbi->display_fragments[i]){
793 /* Filter right hand border only if the block to the right is
794 not coded */
795 if ( !pbi->display_fragments[ i + 1 ] ){
796 FilterHoriz(pbi->LastFrameRecon+
797 pbi->recon_pixel_index_table[i]+6,
798 LineLength,BoundingValuePtr);
801 /* Bottom done if next row set */
802 if( !pbi->display_fragments[ i + LineFragments] ){
803 FilterVert(pbi->LastFrameRecon+
804 pbi->recon_pixel_index_table[i+LineFragments],
805 LineLength, BoundingValuePtr);
808 i++;
810 /***************************************************************/
811 /* middle columns */
812 for ( n = 1 ; n < FragsAcross - 1 ; n++, i++) {
813 if( pbi->display_fragments[i]){
814 /* Filter Left edge always */
815 FilterHoriz(pbi->LastFrameRecon+
816 pbi->recon_pixel_index_table[i]-2,
817 LineLength, BoundingValuePtr);
819 /* Filter right hand border only if the block to the right is
820 not coded */
821 if ( !pbi->display_fragments[ i + 1 ] ){
822 FilterHoriz(pbi->LastFrameRecon+
823 pbi->recon_pixel_index_table[i]+6,
824 LineLength, BoundingValuePtr);
827 /* Bottom done if next row set */
828 if( !pbi->display_fragments[ i + LineFragments] ){
829 FilterVert(pbi->LastFrameRecon+
830 pbi->recon_pixel_index_table[i + LineFragments],
831 LineLength, BoundingValuePtr);
837 /***************************************************************/
838 /* Last Column */
839 if( pbi->display_fragments[i]){
840 /* Filter Left edge always */
841 FilterHoriz(pbi->LastFrameRecon+
842 pbi->recon_pixel_index_table[i] - 2 ,
843 LineLength, BoundingValuePtr);
845 /* Bottom done if next row set */
846 if( !pbi->display_fragments[ i + LineFragments] ){
847 FilterVert(pbi->LastFrameRecon+
848 pbi->recon_pixel_index_table[i + LineFragments],
849 LineLength, BoundingValuePtr);
852 i++;
854 /***************************************************************/
855 /* Middle Rows */
856 /***************************************************************/
857 for ( m = 1 ; m < FragsDown-1 ; m++) {
859 /*****************************************************************/
860 /* first column conditions */
861 /* only do 2 prediction if fragment coded and on non intra or if
862 all fragments are intra */
863 if( pbi->display_fragments[i]){
864 /* TopRow is always done */
865 FilterVert(pbi->LastFrameRecon+
866 pbi->recon_pixel_index_table[i],
867 LineLength, BoundingValuePtr);
869 /* Filter right hand border only if the block to the right is
870 not coded */
871 if ( !pbi->display_fragments[ i + 1 ] ){
872 FilterHoriz(pbi->LastFrameRecon+
873 pbi->recon_pixel_index_table[i] + 6,
874 LineLength, BoundingValuePtr);
877 /* Bottom done if next row set */
878 if( !pbi->display_fragments[ i + LineFragments] ){
879 FilterVert(pbi->LastFrameRecon+
880 pbi->recon_pixel_index_table[i + LineFragments],
881 LineLength, BoundingValuePtr);
884 i++;
886 /*****************************************************************/
887 /* middle columns */
888 for ( n = 1 ; n < FragsAcross - 1 ; n++, i++){
889 if( pbi->display_fragments[i]){
890 /* Filter Left edge always */
891 FilterHoriz(pbi->LastFrameRecon+
892 pbi->recon_pixel_index_table[i] - 2,
893 LineLength, BoundingValuePtr);
895 /* TopRow is always done */
896 FilterVert(pbi->LastFrameRecon+
897 pbi->recon_pixel_index_table[i],
898 LineLength, BoundingValuePtr);
900 /* Filter right hand border only if the block to the right
901 is not coded */
902 if ( !pbi->display_fragments[ i + 1 ] ){
903 FilterHoriz(pbi->LastFrameRecon+
904 pbi->recon_pixel_index_table[i] + 6,
905 LineLength, BoundingValuePtr);
908 /* Bottom done if next row set */
909 if( !pbi->display_fragments[ i + LineFragments] ){
910 FilterVert(pbi->LastFrameRecon+
911 pbi->recon_pixel_index_table[i + LineFragments],
912 LineLength, BoundingValuePtr);
917 /******************************************************************/
918 /* Last Column */
919 if( pbi->display_fragments[i]){
920 /* Filter Left edge always*/
921 FilterHoriz(pbi->LastFrameRecon+
922 pbi->recon_pixel_index_table[i] - 2,
923 LineLength, BoundingValuePtr);
925 /* TopRow is always done */
926 FilterVert(pbi->LastFrameRecon+
927 pbi->recon_pixel_index_table[i],
928 LineLength, BoundingValuePtr);
930 /* Bottom done if next row set */
931 if( !pbi->display_fragments[ i + LineFragments] ){
932 FilterVert(pbi->LastFrameRecon+
933 pbi->recon_pixel_index_table[i + LineFragments],
934 LineLength, BoundingValuePtr);
937 i++;
941 /*******************************************************************/
942 /* Last Row */
944 /* first column conditions */
945 /* only do 2 prediction if fragment coded and on non intra or if
946 all fragments are intra */
947 if( pbi->display_fragments[i]){
949 /* TopRow is always done */
950 FilterVert(pbi->LastFrameRecon+
951 pbi->recon_pixel_index_table[i],
952 LineLength, BoundingValuePtr);
954 /* Filter right hand border only if the block to the right is
955 not coded */
956 if ( !pbi->display_fragments[ i + 1 ] ){
957 FilterHoriz(pbi->LastFrameRecon+
958 pbi->recon_pixel_index_table[i] + 6,
959 LineLength, BoundingValuePtr);
962 i++;
964 /******************************************************************/
965 /* middle columns */
966 for ( n = 1 ; n < FragsAcross - 1 ; n++, i++){
967 if( pbi->display_fragments[i]){
968 /* Filter Left edge always */
969 FilterHoriz(pbi->LastFrameRecon+
970 pbi->recon_pixel_index_table[i] - 2,
971 LineLength, BoundingValuePtr);
973 /* TopRow is always done */
974 FilterVert(pbi->LastFrameRecon+
975 pbi->recon_pixel_index_table[i],
976 LineLength, BoundingValuePtr);
978 /* Filter right hand border only if the block to the right is
979 not coded */
980 if ( !pbi->display_fragments[ i + 1 ] ){
981 FilterHoriz(pbi->LastFrameRecon+
982 pbi->recon_pixel_index_table[i] + 6,
983 LineLength, BoundingValuePtr);
988 /******************************************************************/
989 /* Last Column */
990 if( pbi->display_fragments[i]){
991 /* Filter Left edge always */
992 FilterHoriz(pbi->LastFrameRecon+
993 pbi->recon_pixel_index_table[i] - 2,
994 LineLength, BoundingValuePtr);
996 /* TopRow is always done */
997 FilterVert(pbi->LastFrameRecon+
998 pbi->recon_pixel_index_table[i],
999 LineLength, BoundingValuePtr);
1002 i++;
1007 struct _data
1009 int read; // Driver read on Theora Hardware
1010 int wrote; // Driver wrote on Theora Hardware
1011 int data; // Read or transmitted data
1014 struct _data dt;
1015 static int pf;
1017 int flag_theora = 0;
1019 void write_theoradriver(int pf, int data) {
1020 dt.data = data;
1021 do ioctl(pf, 0, &dt); while (dt.read == 0);
1024 void ReconRefFrames (PB_INSTANCE *pbi){
1025 ogg_int32_t i;
1026 unsigned char *SwapReconBuffersTemp;
1028 /* predictor multiplier up-left, up, up-right,left, shift
1029 Entries are packed in the order L, UL, U, UR, with missing entries
1030 moved to the end (before the shift parameters). */
1031 static const ogg_int16_t pc[16][6]={
1032 {0,0,0,0,0,0},
1033 {1,0,0,0,0,0}, /* PL */
1034 {1,0,0,0,0,0}, /* PUL */
1035 {1,0,0,0,0,0}, /* PUL|PL */
1036 {1,0,0,0,0,0}, /* PU */
1037 {1,1,0,0,1,1}, /* PU|PL */
1038 {0,1,0,0,0,0}, /* PU|PUL */
1039 {29,-26,29,0,5,31}, /* PU|PUL|PL */
1040 {1,0,0,0,0,0}, /* PUR */
1041 {75,53,0,0,7,127}, /* PUR|PL */
1042 {1,1,0,0,1,1}, /* PUR|PUL */
1043 {75,0,53,0,7,127}, /* PUR|PUL|PL */
1044 {1,0,0,0,0,0}, /* PUR|PU */
1045 {75,0,53,0,7,127}, /* PUR|PU|PL */
1046 {3,10,3,0,4,15}, /* PUR|PU|PUL */
1047 {29,-26,29,0,5,31} /* PUR|PU|PUL|PL */
1050 /* boundary case bit masks. */
1051 static const int bc_mask[8]={
1052 /* normal case no boundary condition */
1053 PUR|PU|PUL|PL,
1054 /* left column */
1055 PUR|PU,
1056 /* top row */
1058 /* top row, left column */
1060 /* right column */
1061 PU|PUL|PL,
1062 /* right and left column */
1064 /* top row, right column */
1066 /* top row, right and left column */
1070 /* value left value up-left, value up, value up-right, missing
1071 values skipped. */
1072 int v[4];
1074 /* fragment number left, up-left, up, up-right */
1075 int fn[4];
1077 /* predictor count. */
1078 int pcount;
1080 short wpc;
1081 static const short Mode2Frame[] = {
1082 1, /* CODE_INTER_NO_MV 0 => Encoded diff from same MB last frame */
1083 0, /* CODE_INTRA 1 => DCT Encoded Block */
1084 1, /* CODE_INTER_PLUS_MV 2 => Encoded diff from included MV MB last frame */
1085 1, /* CODE_INTER_LAST_MV 3 => Encoded diff from MRU MV MB last frame */
1086 1, /* CODE_INTER_PRIOR_MV 4 => Encoded diff from included 4 separate MV blocks */
1087 2, /* CODE_USING_GOLDEN 5 => Encoded diff from same MB golden frame */
1088 2, /* CODE_GOLDEN_MV 6 => Encoded diff from included MV MB golden frame */
1089 1 /* CODE_INTER_FOUR_MV 7 => Encoded diff from included 4 separate MV blocks */
1091 short Last[3];
1092 short PredictedDC;
1093 int FragsAcross=pbi->HFragments;
1094 int FromFragment,ToFragment;
1095 int FragsDown = pbi->VFragments;
1097 int WhichFrame;
1098 int WhichCase;
1099 int j,k,m,n;
1101 void (*ExpandBlockA) ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber );
1103 int int1, int2, int3, int4;
1105 static int flag_first_time = 1;
1106 int flag_first_iteration = 1;
1108 int e;
1109 int fout;
1111 if (!flag_theora) {
1112 pf = open("/dev/theora",O_RDONLY|O_WRONLY|O_TRUNC|O_CREAT);
1113 flag_theora = 1;
1116 // if ( GetFrameType(pbi) == KEY_FRAME )
1117 // ExpandBlockA=ExpandKFBlock;
1118 // else
1119 ExpandBlockA=ExpandBlock;
1121 SetupLoopFilter(pbi);
1123 if (flag_first_time) {
1124 flag_first_time = 0;
1126 write_theoradriver(pf, 0);
1127 write_theoradriver(pf, pbi->ReconYPlaneSize + 2 * pbi->ReconUVPlaneSize);
1128 write_theoradriver(pf, pbi->HFragments);
1129 write_theoradriver(pf, pbi->YPlaneFragments);
1130 write_theoradriver(pf, pbi->YStride);
1131 write_theoradriver(pf, pbi->UVPlaneFragments);
1132 write_theoradriver(pf, pbi->UVStride);
1133 write_theoradriver(pf, pbi->VFragments);
1134 write_theoradriver(pf, pbi->ReconYDataOffset);
1135 write_theoradriver(pf, pbi->ReconUDataOffset);
1136 write_theoradriver(pf, pbi->ReconVDataOffset);
1137 write_theoradriver(pf, pbi->UnitFragments);
1139 /* QThreshTable */
1140 for (int1 = 0; int1 < 64; int1++) {
1141 write_theoradriver(pf, pbi->QThreshTable[int1]);
1144 /* LoopFilterLimits */
1145 for (int1 = 0; int1 < 64; int1=int1+4) {
1146 int2 = 0;
1147 for (int3 = 0; int3 < 4; int3++) {
1148 int2 = (int2 << 8);
1149 int2 = int2 + ((unsigned int)pbi->LoopFilterLimits[int1 + int3]);
1151 write_theoradriver(pf, int2);
1154 write_theoradriver(pf, pbi->info.height);
1158 /* for y,u,v */
1159 for ( j = 0; j < 3 ; j++) {
1160 /* pick which fragments based on Y, U, V */
1161 switch(j){
1162 case 0: /* y */
1163 FromFragment = 0;
1164 ToFragment = pbi->YPlaneFragments;
1165 FragsAcross = pbi->HFragments;
1166 FragsDown = pbi->VFragments;
1167 break;
1168 case 1: /* u */
1169 FromFragment = pbi->YPlaneFragments;
1170 ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ;
1171 FragsAcross = pbi->HFragments >> 1;
1172 FragsDown = pbi->VFragments >> 1;
1173 break;
1174 /*case 2: v */
1175 default:
1176 FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
1177 ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
1178 FragsAcross = pbi->HFragments >> 1;
1179 FragsDown = pbi->VFragments >> 1;
1180 break;
1183 /* initialize our array of last used DC Components */
1184 for(k=0;k<3;k++)
1185 Last[k]=0;
1187 i=FromFragment;
1189 /* do prediction on all of Y, U or V */
1190 for ( m = 0 ; m < FragsDown ; m++) {
1191 for ( n = 0 ; n < FragsAcross ; n++, i++){
1193 /* only do 2 prediction if fragment coded and on non intra or
1194 if all fragments are intra */
1195 if( pbi->display_fragments[i] || (GetFrameType(pbi) == KEY_FRAME) ){
1196 /* Type of Fragment */
1197 WhichFrame = Mode2Frame[pbi->FragCodingMethod[i]];
1199 /* Check Borderline Cases */
1200 WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2);
1202 fn[0]=i-1;
1203 fn[1]=i-FragsAcross-1;
1204 fn[2]=i-FragsAcross;
1205 fn[3]=i-FragsAcross+1;
1207 /* fragment valid for prediction use if coded and it comes
1208 from same frame as the one we are predicting */
1209 for(k=pcount=wpc=0; k<4; k++) {
1210 int pflag;
1211 pflag=1<<k;
1212 if((bc_mask[WhichCase]&pflag) &&
1213 pbi->display_fragments[fn[k]] &&
1214 (Mode2Frame[pbi->FragCodingMethod[fn[k]]] == WhichFrame)){
1215 v[pcount]=pbi->QFragData[fn[k]][0];
1216 wpc|=pflag;
1217 pcount++;
1221 if(wpc==0){
1222 /* fall back to the last coded fragment */
1223 pbi->QFragData[i][0] += Last[WhichFrame];
1225 }else{
1227 /* don't do divide if divisor is 1 or 0 */
1228 PredictedDC = pc[wpc][0]*v[0];
1229 for(k=1; k<pcount; k++){
1230 PredictedDC += pc[wpc][k]*v[k];
1233 /* if we need to do a shift */
1234 if(pc[wpc][4] != 0 ){
1236 /* If negative add in the negative correction factor */
1237 PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);
1239 /* Shift in lieu of a divide */
1240 PredictedDC >>= pc[wpc][4];
1243 /* check for outranging on the two predictors that can outrange */
1244 if((wpc&(PU|PUL|PL)) == (PU|PUL|PL)){
1245 if( abs(PredictedDC - v[2]) > 128) {
1246 PredictedDC = v[2];
1247 } else if( abs(PredictedDC - v[0]) > 128) {
1248 PredictedDC = v[0];
1249 } else if( abs(PredictedDC - v[1]) > 128) {
1250 PredictedDC = v[1];
1254 pbi->QFragData[i][0] += PredictedDC;
1258 /* Save the last fragment coded for whatever frame we are
1259 predicting from */
1260 Last[WhichFrame] = pbi->QFragData[i][0];
1262 if (flag_first_iteration) {
1263 flag_first_iteration = 0;
1264 write_theoradriver(pf, pbi->CodedBlockIndex);
1265 for (int1 = 0; int1 < 64; int1++)
1266 write_theoradriver(pf, pbi->dequant_Y_coeffs[int1]);
1267 for (int1 = 0; int1 < 64; int1++)
1268 write_theoradriver(pf, pbi->dequant_U_coeffs[int1]);
1269 for (int1 = 0; int1 < 64; int1++)
1270 write_theoradriver(pf, pbi->dequant_V_coeffs[int1]);
1271 for (int1 = 0; int1 < 64; int1++)
1272 write_theoradriver(pf, pbi->dequant_InterY_coeffs[int1]);
1273 for (int1 = 0; int1 < 64; int1++)
1274 write_theoradriver(pf, pbi->dequant_InterU_coeffs[int1]);
1275 for (int1 = 0; int1 < 64; int1++)
1276 write_theoradriver(pf, pbi->dequant_InterV_coeffs[int1]);
1277 write_theoradriver(pf, pbi->FrameType);
1280 for (int1 = 0; int1 < 64; int1++)
1281 write_theoradriver(pf, pbi->QFragData[i][int1]);
1282 write_theoradriver(pf, pbi->FragCodingMethod[i]);
1283 write_theoradriver(pf, pbi->FragCoefEOB[i]);
1284 write_theoradriver(pf, pbi->FragMVect[i].x);
1285 write_theoradriver(pf, pbi->FragMVect[i].y);
1286 write_theoradriver(pf, i);
1288 /* Inverse DCT and reconstitute buffer in thisframe */
1289 //ExpandBlockA( pbi, i );
1297 int1 = 0;
1298 int2 = pbi->UnitFragments / 32;
1299 for (int3 = 0; int3 < int2; int3++) {
1300 for (int4 = 0; int4 < 32; int4++)
1301 int1 = (int1 << 1) + pbi->display_fragments[int3*32 + int4];
1302 write_theoradriver(pf, int1);
1305 for (int1 = 0, int3 = 0; int3 < (pbi->UnitFragments % 32); int3++)
1306 int1 = (int1 << 1) + pbi->display_fragments[int2*32 + int3];
1308 if (pbi->UnitFragments % 32)
1309 write_theoradriver(pf, (int1 << (32 - (pbi->UnitFragments % 32))));
1311 write_theoradriver(pf, pbi->ThisFrameQualityValue);
1313 /* display_fragments */
1315 /* Copy the current reconstruction back to the last frame recon buffer. */
1317 if(pbi->CodedBlockIndex > (ogg_int32_t) (pbi->UnitFragments >> 1)){
1318 SwapReconBuffersTemp = pbi->ThisFrameRecon;
1319 pbi->ThisFrameRecon = pbi->LastFrameRecon;
1320 pbi->LastFrameRecon = SwapReconBuffersTemp;
1321 CopyNotRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon );
1322 }else{ */
1323 CopyRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon );
1326 /* Apply a loop filter to edge pixels of updated blocks */
1327 LoopFilter(pbi);
1329 /* We may need to update the UMV border */
1330 UpdateUMVBorder(pbi, pbi->LastFrameRecon);
1332 /* Reconstruct the golden frame if necessary.
1333 For VFW codec only on key frames */
1334 if ( GetFrameType(pbi) == KEY_FRAME ){
1335 CopyRecon( pbi, pbi->GoldenFrame, pbi->LastFrameRecon );
1336 /* We may need to update the UMV border */
1337 UpdateUMVBorder(pbi, pbi->GoldenFrame);
1340 // Reading the outputs from driver
1341 //Matriz LastFrameRecon
1342 for (int1 = 0; int1 < pbi->LastFraRecLen; int1=int1+4) {
1343 int3 = 0;
1344 for (int2 = 0; int2 < 4; int2++) {
1345 int3 = (int3 << 8);
1346 int3 = int3 + ((unsigned int)pbi->LastFrameRecon[int1 + int2]);
1350 do {
1351 dt.wrote = 0;
1352 if (ioctl(pf, 1, &dt) < 0) {
1353 printf("ERROR: ioctl(0,&a) failed\n");
1354 exit(1);
1356 } while (dt.wrote == 0);
1357 printf("saida = soft %d : hard %d\n", int3, dt.data);