h261dec.c

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

C
1,645
字号
    return;
}
*****************/

/**************************************************************************
* initializePicture ( H261Decoder *s) -
*
* this function initializes the picture structures according to the
* format: QCIF or CIF
*
***************************************************************************/
#ifdef WATD
extern void BreakPoint(void);
#pragma aux BreakPoint = 0xcc;
#endif
static int  initializePicture( H261Decoder * s )
{
  S16   format;                     /* locals used for call to getImgParms  */
  S16   numGOBs;                    /* this is done for consistency with    */
  S16   numMBs;                     /* old init method                      */
  S32   imgSize ;
  S32   lumaSize;
  S32   chromaLineLength;
  S32   chromaRows;
  S32   maxsym;  
  int   status, mbHor, mbVert;

#ifdef WATD
   //BreakPoint();
#endif
  format = (S16)s->pic_layer.format;
  s->decMB.format = format;
  s->decMB.type = DECODER_MAP;
    
  if ( (s->formatCap == QCIF) && (format == CIF) )
    H261ErrMsg("decoder not CIF capable");

                    /* get the image parameters for the current format  */
  if (format == ANYSIZE) {
        mbHor = (s->pic_layer.cols + 15) >> 4;
        mbVert = (s->pic_layer.rows + 15) >> 4;
        //imgSize  = (long)384 * mbHor * mbVert;
        lumaSize = (long)256 * mbHor * mbVert;
        chromaLineLength = 8 * mbHor;
        chromaRows = 8 * mbVert;
        //numGOBs  = mbVert;
        numMBs   = mbHor * mbVert;
        //maxsym = 8 * lumaSize;
        status = 0;
        /////////if (numMBs > xxxxx)  status = UNKNOWN_PICTURE_FORMAT;
  } else {
    status = getImgParms (format, &numGOBs, &numMBs, &imgSize, &lumaSize, &chromaLineLength,
                    &chromaRows, &maxsym);
  }
  if (status != 0) {
    H261ErrMsg ("Decoder Error: initializePicture - UNKNOWN_PICTURE_FORMAT");
    status = H261_ERROR;
  } else if (numMBs > s->maxMbnum) {
    H261ErrMsg ("Decoder Error: initializePicture - Too large picture");
    status = H261_ERROR;
  } else if (numMBs > s->maxMbnum) {
    H261ErrMsg ("Decoder Error: initializePicture - Too large picture");
    status = H261_ERROR;
  } else {
    status = OK;
  }
  // setup the image structures
  //s->newOut.picLayout = s->B_Out.picLayout = VVS_LAYOUT_TEE;
  //s->oldOut.picLayout   = VVS_LAYOUT_TEE;
  s->newOut.picLayout = s->B_Out.picLayout = VVS_LAYOUT_YUV12;
  
  // Memory was already allocated when the decoder first opened.
  // The luma pointers hold the address of the start of the memory for image buffers
                                    
  // Set up chroma pointers
  // helix needs 420 out -gneel
  // Layout_Tee also works.
  if(s->newOut.picLayout == VVS_LAYOUT_YUV12)
  {
	s->newOut.cb.ptr = s->newOut.y.ptr + lumaSize;
	s->B_Out.cb.ptr  = s->B_Out.y.ptr  + lumaSize;

	s->newOut.cr.ptr = s->newOut.cb.ptr + (lumaSize>>2);
	s->B_Out.cr.ptr  = s->B_Out.cb.ptr  + (lumaSize>>2);

	s->newOut.cb.ptrAlias = s->newOut.y.ptrAlias + lumaSize;
	s->B_Out.cb.ptrAlias  = s->B_Out.y.ptrAlias  + lumaSize;
	
	s->newOut.cr.ptrAlias = s->newOut.cb.ptrAlias + (lumaSize>>2);
	s->B_Out.cr.ptrAlias  = s->B_Out.cb.ptrAlias  + (lumaSize>>2);

	// Set up remainder of COMPONENT structs
	s->newOut.y.nhor    = s->B_Out.y.nhor    = chromaLineLength * 2;
	s->newOut.y.nvert   = s->B_Out.y.nvert   = chromaRows * 2;
	s->newOut.y.hoffset = s->B_Out.y.hoffset = chromaLineLength * 2;

	s->newOut.cb.nhor    = s->B_Out.cb.nhor    = chromaLineLength;
	s->newOut.cb.nvert   = s->B_Out.cb.nvert   = chromaRows;	
	s->newOut.cb.hoffset = s->B_Out.cb.hoffset = chromaLineLength;

	s->newOut.cr.nhor    = s->B_Out.cr.nhor    = chromaLineLength;
	s->newOut.cr.nvert   = s->B_Out.cr.nvert   = chromaRows;
	s->newOut.cr.hoffset = s->B_Out.cr.hoffset = chromaLineLength;
  } else {
	s->newOut.cb.ptr = s->newOut.y.ptr + lumaSize;
	s->B_Out.cb.ptr  = s->B_Out.y.ptr  + lumaSize;
	//s->oldOut.cb.ptr = s->oldOut.y.ptr + lumaSize;
  
	s->newOut.cr.ptr = s->newOut.cb.ptr + chromaLineLength;

	s->B_Out.cr.ptr  = s->B_Out.cb.ptr  + chromaLineLength;
	//s->oldOut.cr.ptr = s->oldOut.cb.ptr + chromaLineLength;

	s->newOut.cb.ptrAlias = s->newOut.y.ptrAlias + lumaSize;
	s->B_Out.cb.ptrAlias  = s->B_Out.y.ptrAlias  + lumaSize;
	//s->oldOut.cb.ptrAlias = s->oldOut.y.ptrAlias + lumaSize;
	s->newOut.cr.ptrAlias = s->newOut.cb.ptrAlias + chromaLineLength;

	s->B_Out.cr.ptrAlias  = s->B_Out.cb.ptrAlias  + chromaLineLength;
	//s->oldOut.cr.ptrAlias = s->oldOut.cb.ptrAlias + chromaLineLength;

	// Set up remainder of COMPONENT structs
	s->newOut.y.nhor    = s->B_Out.y.nhor    = chromaLineLength * 2;
	s->newOut.y.nvert   = s->B_Out.y.nvert   = chromaRows * 2;
	s->newOut.y.hoffset = s->B_Out.y.hoffset = chromaLineLength * 2;

	s->newOut.cb.nhor    = s->B_Out.cb.nhor    = chromaLineLength;
	s->newOut.cb.nvert   = s->B_Out.cb.nvert   = chromaRows;
	s->newOut.cb.hoffset = s->B_Out.cb.hoffset = chromaLineLength * 2;

	s->newOut.cr.nhor    = s->B_Out.cr.nhor    = chromaLineLength;
	s->newOut.cr.nvert   = s->B_Out.cr.nvert   = chromaRows;
	s->newOut.cr.hoffset = s->B_Out.cr.hoffset = chromaLineLength * 2;
  }
  return (status);
}


//  decodePicLayer - Decode Picture Layer information
static int  decodePicLayer( BS_PTR * bs, int nbits, PICTURE_DESCR * pic,
                            SYMBOL sym[], int maxsym, int codingMethod, GOB_DESCR * gob,
                            int * ptype )
{
    int     status;
    
    if (codingMethod == H263_CODING) {
        status = DecPicLayer263( bs, nbits, pic, gob, ptype );
    } else {
        status = decode_pic261( bs, nbits, pic, sym, maxsym );
    }
    return( status );
}


//  decode_pic261 - Decode H.261 Picture Layer information
//  This routine is very picky when determining whether bitstream is valid.
//  It returns OK only if a startcode ends the bitstream; otherwise, it
//  returns H261_ERROR.
static int  decode_pic261( BS_PTR * bs, int nbits, PICTURE_DESCR * pic,
                            SYMBOL sym[], int maxsym)
{
    int     state, status, parsed_bits, nsym, i;
    BS_ERR_MSG( char msg[120] ); /* Flawfinder: ignore */

    state = ST_AFTER_STARTCODE;
    //printf( "DecodePic: Entering VLDecode with  State = %d  nbits = %d\n",
    //            state, nbits);
    status = VLDECODE( *bs, nbits, &state, &parsed_bits, &nsym, sym, maxsym);
    if (parsed_bits != nbits) {
        BS_ERR_MSG( sprintf( msg, "decode_pic_layer: Tried to decode %d bits, exit after %d bits", /* Flawfinder: ignore */
                nbits, parsed_bits);
                H261ErrMsg( msg ); )
        return (H261_ERROR);
    }
    if (state != ST_AFTER_STARTCODE) {
        BS_ERR_MSG( sprintf( msg, "decode_pic_layer: Bitstream did not end with startcode"); /* Flawfinder: ignore */
                H261ErrMsg( msg); )
        return (H261_ERROR);
    }
/*    {
        int i;
        printf( "DecodePic: Status = %d  State = %d  Decoded %d bits, %d symbols\n",
                status, state, parsed_bits, nsym);
        // Print decoded symbols
        printf("\n");
        for (i = 0; i < nsym; i++) {
            printf("DecodePic: "); printsym( sym[i] ); printf("\n");
        }
        printf("\n");
    }*/
    CHECKSYM( if (checksym( sym[0], SYM_GN, "decode_pic_layer") != OK) exit(0); )
    i = 1;  // Skip first symbol ("GN" = 0)
    CHECKSYM( if (checksym( sym[i], SYM_QUANT_TR, "decode_pic_layer") != OK) exit(0); )
    pic->tr = sym[i++].value;
    CHECKSYM( if (checksym( sym[i], SYM_PTYPE, "decode_pic_layer") != OK) exit(0); )
    pic->ptype = sym[i++].value;
    pic->splitscreen = pic->ptype & FLAG_SPLITSCREEN;
    pic->doccamera = pic->ptype & FLAG_DOCCAMERA;
    pic->fp_release = pic->ptype & FLAG_FP_RELEASE;
    if (pic->ptype & FLAG_CIF_FORMAT) {
        pic->format = CIF;
    } else {
        pic->format = QCIF;
    }
    pic->hi_res = (pic->ptype & FLAG_HI_RES) ^ FLAG_HI_RES; // 1 = off, 0 = on
    pic->advancedPred = 0;  // No overlapped MC for H.261
    pic->PBframeMode = 0;   // No PB-frames for H.261
#ifdef DO_H263_PLUS
    pic->reducedResUpdate = 0;
#endif
    pic->peiCount = 0;                  // Loop 'til PEI=0
    while (sym[i].type == SYM_SPARE) {
        //char msg[100];
        //sprintf(msg,"\n Decode DLL: PEI=%x", sym[i].value);
        //OutputDebugString(msg);
        if (pic->peiCount < MAX_PEI_COUNT) {
            //char msg[100];
            //sprintf(msg,"\n Decode DLL: pSpare: %2x", sym[i].value);
            //OutputDebugString(msg);
            pic->pSpare[pic->peiCount] = sym[i].value;
        }
        pic->peiCount++;                // Inc counter
        i++;                            // Next Symbol  
    }

    CHECKSYM( if (checksym( sym[i], SYM_GEI_PEI, "decode_pic_layer") != OK) exit(0));    
    i++;                                // Skip PEI Symbol
    
    if (sym[i].type != SYM_STARTCODE) {
        BS_ERR_MSG( sprintf( msg, "decode_pic_layer: Did not find startcode after pic_layer"); /* Flawfinder: ignore */
                H261ErrMsg( msg ); )
        return (H261_ERROR);
    }
    return (OK);
}


//  decode261gob - Decode all symbols for a Group Of Blocks
//  This routine is very picky when determining whether bitstream is valid.
//  It returns OK only if a startcode ends the bitstream; otherwise, it
//  returns H261_ERROR.
static int  decode261gob(  BS_PTR * bs, int nbits, GOB_DESCR * gob,
                        MACROBLOCK_DESCR mb[], SYMBOL sym[], int maxsym)
{
    int     state, status, parsed_bits, mbnum, nextsym, quant, i, mba,
            nsym,       // # symbols returned by VLDecode
            isym;       // # symbols returned by this routine, i.e.,
                        // after deletion of EOBs etc.
    BS_ERR_MSG ( char msg[120] ); /* Flawfinder: ignore */

    state = ST_AFTER_STARTCODE;
    //printf( "DecodeGOB: Entering VLDecode with  State: ");
    //printstate( state ); printf("  nbits = %d\n", nbits);
    status = VLDECODE( *bs, nbits, &state, &parsed_bits, &nsym, sym, maxsym);
    if (parsed_bits != nbits) {
        BS_ERR_MSG( sprintf( msg, "decode261gob: Tried to decode %d bits, exit after %d bits", /* Flawfinder: ignore */
                nbits, parsed_bits);
                H261ErrMsg( msg ); )
        return (H261_ERROR);
    }
    if (state != ST_AFTER_STARTCODE) {
        BS_ERR_MSG( sprintf( msg, "decode261gob: Bitstream did not end with startcode"); /* Flawfinder: ignore */
                H261ErrMsg( msg ); )
        return (H261_ERROR);
    }
/*    {
        int num;
        printf( "DecodeGOB: Status = %d  State: ", status); printstate( state );
        printf("  Decoded %d bits, %d symbols\n", parsed_bits, nsym);
        // Print decoded symbols
        printf("DecodeGOB: # symbols to print: ");
        scanf("%d", &num);
        for (i = 0; i < num; i++) {
            printf("DecodeGOB: "); printsym( sym[i] ); printf("\n");
        }
        printf("\n");
    }
 */
    nextsym = 0;
    CHECKSYM( if (checksym( sym[nextsym], SYM_GN, "decode261gob") != OK) exit(0); )
    gob->gn = sym[nextsym++].value;      // GOB number
    CHECKSYM( if (checksym( sym[nextsym], SYM_QUANT_TR, "decode261gob") != OK) exit(0); )
    quant = sym[nextsym++].value;
    if (quant < QUANT_MIN  ||  quant > QUANT_MAX) {
        BS_ERR_MSG( sprintf( msg, "decode261gob: quant = %d", quant); /* Flawfinder: ignore */
                H261ErrMsg( msg ); )
        return (H261_ERROR);
    }

    gob->gquant = quant;
    //CHECKSYM( if (checksym( sym[nextsym], SYM_GEI_PEI, "decode261gob") != OK) exit(0);  )
    //gob->gei = sym[nextsym].value;
    gob->num_gspare = 0;
    while (sym[nextsym].type == SYM_SPARE) {   // Loop until GEI=0
        CHECKSYM( if (checksym( sym[nextsym], SYM_SPARE, "decode261gob") != OK) exit(0); )
        ++nextsym;  // Drop GSPARE on the floor
        ++(gob->num_gspare);
        
    }
    CHECKSYM( if (checksym( sym[nextsym], SYM_GEI_PEI, "decode261gob") != OK) exit(0); )
    ++nextsym;      // Skip GEI
    
            
    mbnum = 0;
    isym = 0;
    //  We expect MBA, MBA Stuffing, or Startcode
    while (sym[nextsym].type == SYM_MBA_STUFFING) {
        ++nextsym;      // Remove MBA stuffing
    }
    while (sym[nextsym].type != SYM_STARTCODE) {    // Keep going until next startcode
        // We expect MBA
        CHECKSYM( if (checksym( sym[nextsym], SYM_MBA, "decode261gob") != OK) exit(0); )
        mba = sym[nextsym++].value;
        //printf("MB #%d: ", mbnum+mba); printsym( sym[nextsym-1] ); // MBA
        //printf("   "); printsym( sym[nextsym] ); printf("\n"); // MTYPE
        if (mbnum + mba  >  gob->num_mb) {
            BS_ERR_MSG( sprintf( msg, "decode261gob: Bitstream error, mbnum=%d", mbnum + mba); /* Flawfinder: ignore */
                    H261ErrMsg( msg ); )
            return (H261_ERROR);
        }
        for (i = mbnum + 1; i < mbnum + mba; i++) {
            mb[i-1].mtype = MTYPE_SKIP;
        }
        mbnum += mba;
        status = decode_mb( sym, &nextsym, &quant, gob, mb, mbnum-1, &sym[isym] );
        if (status == H261_ERROR) {
            BS_ERR_MSG( sprintf( msg, "decode261gob: Bitstream error, MB #%d", mbnum); /* Flawfinder: ignore */
                    H261ErrMsg( msg ); )
            return (H261_ERROR);

⌨️ 快捷键说明

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