recongob.c

来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,202 行 · 第 1/4 页

C
1,202
字号
                    Fill32x32( &mb[mbnum], pic, GRAY);
                    intra = NO;
                    ReconReducedResMb( &mb[mbnum], pic, intra, tempPic );
                    state->actComp += 4;   // Increment computation measure
                } else {
                    gray_mb( &mb[mbnum], pic);
                    ReconInter( &mb[mbnum], pic, CLEAN);
                    ++state->actComp;   // Increment computation measure
                    if (reconBflag) {   // Reconstruct B frame
                        gray_mb( &mb[mbnum], Bpic );
                        reconBframe( &mb[mbnum], Bpic );
                    }
                }
                break;
            case MTYPE263_INTRA:
            case MTYPE263_INTRA_Q:
            case MTYPE_INTRA:
            case MTYPE_INTRA_MQUANT:
                if (reducedResUpdate) {
                    Fill32x32( &mb[mbnum], pic, 0 );
                    intra = YES;
                    ReconReducedResMb( &mb[mbnum], pic, intra, tempPic );
                    state->actComp += 4;   // Increment computation measure
                } else {
                    if(advancedIntraMode)
                        ReconAdvancedIntra( &mb[mbnum], pic, CLEAN );
                    else
                        ReconIntra( &mb[mbnum], pic, CLEAN );
                    ++state->actComp;   // Increment computation measure
                    if (reconBflag) {   // Reconstruct B frame
                        gray_mb( &mb[mbnum], Bpic );
                        reconBframe( &mb[mbnum], Bpic );
                    }
                }
                break;
            default:
                CHECKSYM( sprintf( msg, "PROGRAM ERROR: MTYPE = %d in recon_gob", mb[mbnum].mtype); /* Flawfinder: ignore */
                    H261ErrMsg( msg );
                    state->i = 0;   // Indicate that we finished without timing out
                    return( H261_ERROR ); )
                break;
            }
            i++, mbnum++;
            col++;
            if (col == gob->mb_width) { // Start on next row of macroblocks
                mbnum += gob->mb_offset - gob->mb_width;
                col = 0;
            }
            if (maxComp > 0  &&  state->actComp >= maxComp) {
                // We have timed out: save state and return
                state->i    = i;
                state->mbnum= mbnum;
                state->col  = col;
                return H261_ERROR;
            }
        }
        state->i = 0;   // Indicate that we finished without timing out
        return (H261_ERROR);
    }
}


// Reconstruct GOB by repeating previous picture
extern int ConcealGob( GOB_DESCR * gob, MACROBLOCK_DESCR mb[], int reducedResUpdate,
                       PICTURE * prev_pic, PICTURE * pic )
{
    int mbnum, i, col;

    i = 0;
    mbnum = gob->first_col + gob->first_row * gob->mb_offset;
    col = gob->first_col;   // Used to check when we reach end of line
    if (pic->y.nhor == prev_pic->y.nhor  &&  pic->y.nvert == prev_pic->y.nvert) {
        // Size of prev_pic is OK; use it for new picture
        while (i < gob->num_mb) {
            mb[mbnum].mv_x = 0;
            mb[mbnum].mv_y = 0;
            if (reducedResUpdate) {
                MotionComp32x32( &mb[mbnum], prev_pic, pic);
            } else {
                MotionComp( &mb[mbnum], prev_pic, pic);
            }
            i++, mbnum++;
            col++;
            if (col == gob->mb_width) { // Start on next row of macroblocks
                mbnum += gob->mb_offset - gob->mb_width;
                col = 0;
            }
        }
        return (OK);
    } else {    // Paint gray
        while (i < gob->num_mb) {
            if (reducedResUpdate) {
                Fill32x32( &mb[mbnum], pic, GRAY);
            } else {
                gray_mb( &mb[mbnum], pic);
            }
            i++, mbnum++;
            col++;
            if (col == gob->mb_width) { // Start on next row of macroblocks
                mbnum += gob->mb_offset - gob->mb_width;
                col = 0;
            }
        }
        return (H261_ERROR);
    }
}


// ReconIntra
extern void ReconIntra( MACROBLOCK_DESCR * mb, PICTURE * pic, int clean)
{
    int     row, col, offset;
    PIXEL   * pixel0;
    S16   * recon_tab;

    recon_tab = Recon[mb->quant - QUANT_MIN];
    col = 16 * mb->x;
    row = 16 * mb->y;
    /*{
        int isym;
        printf("ReconIntra: x = %d  y = %d\n", col, row);
        printf("nsym = %d %d %d %d %d %d \n", mb->block[0].nsym,
                mb->block[1].nsym, mb->block[2].nsym, mb->block[3].nsym,
                mb->block[4].nsym, mb->block[5].nsym);
        printf("Symbol number to print: ");
        scanf("%d", &isym);
        while (isym > 0) {
            printf("Luma 1: ");
            printsym( *(mb->block[0].sym + isym - 1) ); printf("\n");
            printf("Luma 2: ");
            printsym( *(mb->block[1].sym + isym - 1) ); printf("\n");
            printf("Luma 3: ");
            printsym( *(mb->block[2].sym + isym - 1) ); printf("\n");
            printf("Luma 4: ");
            printsym( *(mb->block[3].sym + isym - 1) ); printf("\n");
            printf("Symbol number to print: ");
            scanf("%d", &isym);
        }
    }*/
    pixel0 = pic->y.ptr + col + row * pic->y.hoffset;
    //printf("Luma block 1 \n");
    Idct2( mb->block[0].sym, mb->block[0].nsym, pixel0,
            pic->y.hoffset, recon_tab, clean);
    //printf("Luma block 2 \n");
    Idct2( mb->block[1].sym, mb->block[1].nsym, pixel0 + 8,
            pic->y.hoffset, recon_tab, clean);
    //printf("Luma block 3 \n");
    Idct2( mb->block[2].sym, mb->block[2].nsym, pixel0 + 8 * pic->y.hoffset,
            pic->y.hoffset, recon_tab, clean);
    //printf("Luma block 4 \n");
    Idct2( mb->block[3].sym, mb->block[3].nsym, pixel0 + 8 + 8 * pic->y.hoffset,
            pic->y.hoffset, recon_tab, clean);
    if (pic->color) {
        // Assuming same offset for Cr and Cb
        col = 8 * mb->x;
        row = 8 * mb->y;
        offset = col + row * pic->cb.hoffset;
        pixel0 = pic->cb.ptr + offset;
        //printf("CB block \n");
        Idct2( mb->block[4].sym, mb->block[4].nsym, pixel0,
            pic->cb.hoffset, recon_tab, clean);
        pixel0 = pic->cr.ptr + offset;
        //printf("CR block \n");
        Idct2( mb->block[5].sym, mb->block[5].nsym, pixel0,
            pic->cr.hoffset, recon_tab, clean);
    }
    return;
}

#ifdef DO_H263_PLUS

#define MAX_MACROBLKS_PER_ROW           (88)    /* Up to 16CIF (1408 pixels/line) */
#define UPPER_LUMA_BLOCK_CACHE_LENGTH   (2 * MAX_MACROBLKS_PER_ROW)
#define UPPER_CHROMA_BLOCK_CACHE_LENGTH (MAX_MACROBLKS_PER_ROW)

// Storage for the first rows of the lower 8x8 blocks of the intra macroblocks in the previous GOB.
// Refer to these for appropriate predictions.  For right now we make this static
// data, but should really allocate it on the heap only if advanced intra is being
// used?
static S8 upperLumaBlockCache[UPPER_LUMA_BLOCK_CACHE_LENGTH][8]; // allocated for CIF video!
static S8 upperCrBlockCache[UPPER_CHROMA_BLOCK_CACHE_LENGTH][8];   // allocated for CIF video!
static S8 upperCbBlockCache[UPPER_CHROMA_BLOCK_CACHE_LENGTH][8];   // allocated for CIF video!
// Storage for the first columns of the 8x8 blocks of the most recent intra macroblock.
// Refer to these for appropriate predictions.
static S8 leftLumaBlockCache[4][8];
static S8 leftCrBlockCache[1][8];
static S8 leftCbBlockCache[1][8];

static U8 upperDCLumaBlockCache[UPPER_LUMA_BLOCK_CACHE_LENGTH][1];
static U8 upperDCCrBlockCache[UPPER_CHROMA_BLOCK_CACHE_LENGTH][1];
static U8 upperDCCbBlockCache[UPPER_CHROMA_BLOCK_CACHE_LENGTH][1];
static U8 leftDCLumaBlockCache[4][1];
static U8 leftDCCrBlockCache[1];
static U8 leftDCCbBlockCache[1];

static void InitializeLeftCache(int qp)
{
    int i;
    for(i=0; i<4; i++) {
        //leftDCLumaBlockCache[i][0] = ( U8 )128; // MPEG4 style boundary conditions
        leftDCLumaBlockCache[i][0] = ( U8 )(512/qp); // H.263+ style boundary conditions
        memset(&leftLumaBlockCache[i][1], 0, 7);
    }

    leftDCCrBlockCache[0] = ( U8 )(512/qp); // H.263+ style boundary conditions
    memset(&leftCrBlockCache[0][1], 0, 7);
    
    leftDCCbBlockCache[0] = ( U8 )(512/qp); // H.263+ style boundary conditions
    memset(&leftCbBlockCache[0][1], 0, 7);
}

static void InitializeUpperCache(int qp, int i)
{
        //upperDCLumaBlockCache[2*i][0] = ( U8 )128; // MPEG4 style boundary conditions
        upperDCLumaBlockCache[2*i][0] = ( U8 )(512/qp); // H.263+ style boundary conditions
        memset(&upperLumaBlockCache[2*i][1], 0, 7);
        //upperDCLumaBlockCache[2*i+1][0] = ( U8 )128; // MPEG4 style boundary conditions
        upperDCLumaBlockCache[2*i+1][0] = ( U8 )(512/qp); // H.263+ style boundary conditions
        memset(&upperLumaBlockCache[2*i+1][1], 0, 7);
        
        //upperDCCrBlockCache[i][0] = ( U8 )128; // MPEG4 style boundary conditions
        upperDCCrBlockCache[i][0] = ( U8 )(512/qp); // H.263+ style boundary conditions
        memset(&upperCrBlockCache[i][1], 0, 7);
        
        //upperDCCbBlockCache[i][0] = ( U8 )128; // MPEG4 style boundary conditions
        upperDCCbBlockCache[i][0] = ( U8 )(512/qp); // H.263+ style boundary conditions
        memset(&upperCbBlockCache[i][1], 0, 7);
}


#define INTRA(mb)   (((mb).mtype >= MTYPE263_INTRA_MIN && (mb).mtype <= MTYPE263_INTRA_MAX) ? 1:0)

extern void ReconAdvancedIntra( MACROBLOCK_DESCR * mb, PICTURE * pic, int clean)
{
    int     row, col, offset;
    PIXEL   * pixel0;
    S16   * recon_tab;
    int   predtype = mb->intra_mode;
    int   fixedDC = mb->quant<8;
    int   numhor=pic->y.nhor>>4; // number of mb per row

    // Ensure that we are not scribbling outside the allocated cache
    if (mb->x >= MAX_MACROBLKS_PER_ROW) return;
    // Reinitialize predictors if we're on a new row or if one of our abutting macroblocks
    // isn't intra
    if(mb->x == 0 || !INTRA(mb[-1])) {
        InitializeLeftCache(fixedDC ? 4 : mb->quant);
    }
    if(mb->y == 0 || !INTRA(mb[-numhor])) {
        InitializeUpperCache(fixedDC ? 4 : mb->quant, mb->x);
    }


    recon_tab = Recon[mb->quant - QUANT_MIN];
    col = 16 * mb->x;
    row = 16 * mb->y;
    /*{
        int isym;
        printf("ReconAdvancedIntra: x = %d  y = %d\n", col, row);
        printf("nsym = %d %d %d %d %d %d \n", mb->block[0].nsym,
                mb->block[1].nsym, mb->block[2].nsym, mb->block[3].nsym,
                mb->block[4].nsym, mb->block[5].nsym);
        printf("Symbol number to print: ");
        scanf("%d", &isym);
        while (isym > 0) {
            printf("Luma 1: ");
            printsym( *(mb->block[0].sym + isym - 1) ); printf("\n");
            printf("Luma 2: ");
            printsym( *(mb->block[1].sym + isym - 1) ); printf("\n");
            printf("Luma 3: ");
            printsym( *(mb->block[2].sym + isym - 1) ); printf("\n");
            printf("Luma 4: ");
            printsym( *(mb->block[3].sym + isym - 1) ); printf("\n");
            printf("Symbol number to print: ");
            scanf("%d", &isym);
        }
    }*/
    pixel0 = pic->y.ptr + col + row * pic->y.hoffset;
    //printf("Luma block 1 \n");
    Idct2AdvancedIntra( mb->block[0].sym, mb->block[0].nsym, pixel0,
            pic->y.hoffset, recon_tab,
            upperDCLumaBlockCache[2*mb->x][0], upperLumaBlockCache[2*mb->x], // DC and AC pred for row  
            upperDCLumaBlockCache[2*mb->x],upperLumaBlockCache[2*mb->x],  // DC and AC store for row
            leftDCLumaBlockCache[1][0], leftLumaBlockCache[1],  // DC and AC pred for column
            leftDCLumaBlockCache[0], leftLumaBlockCache[0],  // DC and AC store for column
            predtype, fixedDC,
            mb->x==0, mb->y==0); // can be on left or upper boundary
       
    //printf("Luma block 2 \n");
    Idct2AdvancedIntra( mb->block[1].sym, mb->block[1].nsym, pixel0 + 8,
            pic->y.hoffset, recon_tab, 
            upperDCLumaBlockCache[2*mb->x+1][0], upperLumaBlockCache[2*mb->x+1], // DC and AC pred for row  
            upperDCLumaBlockCache[2*mb->x+1],upperLumaBlockCache[2*mb->x+1],  // DC and AC store for row
            leftDCLumaBlockCache[0][0], leftLumaBlockCache[0],  // DC and AC pred for column
            leftDCLumaBlockCache[1], leftLumaBlockCache[1],  // DC and AC store for column
            predtype, fixedDC,
            FALSE, mb->y==0); // can only be on upper boudary

    //printf("Luma block 3 \n");
    Idct2AdvancedIntra( mb->block[2].sym, mb->block[2].nsym, pixel0 + 8 * pic->y.hoffset,
            pic->y.hoffset, recon_tab,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?