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 + -
显示快捷键?