📄 h261dec.c
字号:
// savePSCpointer - Pass the pointer to the picture start code to callerstatic void savePSCpointer( BS_PTR *bsPSC, H261Decoder *s ){ s->status.dwPsc = TRUE; s->status.pscIndex.ww.byte = bsPSC->byteptr - s->bsAbs.byteptr; s->status.pscIndex.ww.bit = bsPSC->bitptr & 0xff; return;}// outputBsPointer - Copy "start" pointer and back up by length of startcodestatic void outputBsPointer( BS_PTR * start, BS_PTR * output, int codingMethod ){ int lenStartCode; if (codingMethod == H263_CODING) { lenStartCode = H263_START_ZEROS + 1; } else { lenStartCode = H261_START_ZEROS + 1; } *output = *start; IncBsPtr( output, -lenStartCode ); return;}// decodeBitstream - Decode bitstream for a GOB// Returns H261_ERROR if we need to exit to resync on next PSCstatic int decodeBitstream( H261Decoder *s, GOB_DESCR *gob, BS_PTR start[2], int gn[2], int *structStatus, int *decStatus ){ BS_ERR_MSG(char msg[120];) /* Flawfinder: ignore */ int nextStart; *structStatus = doGobStructures( s, gob, s->mb, &start[0], &gn[0] ); if (*structStatus == OK && gn[0] == s->next_gob) { // GOB number is correct and structures in place *decStatus = doGobDecoding( s, gob, s->mb, &start[0], s->sym, s->maxSym ); } else if (*structStatus == OK && gn[0] == gob->next_gn) { // GBSC was probably trashed // This case will not occur for H.263 *structStatus = H261_ERROR; //printf("Calling ConcealGob \n"); ConcealGob( gob, s->mb, s->pic_layer.reducedResUpdate, &s->oldOut, &s->newOut); ++s->status.dwBadgobs; s->status.dwGobs += gob->num_mb / max(1,gob->mb_width); s->next_gob = gob->next_gn; s->status.dwIntraFrame=0; BS_ERR_MSG( sprintf( msg, "Bitstream error: did not find GOB %d", s->next_gob); /* Flawfinder: ignore */ H261ErrMsg( msg ); ) } else if (gn[0] == 0) { // Unexpected PSC; exit so we can resync *structStatus = H261_ERROR; if (s->codingMethod == H263_CODING && s->next_gob == 0) { nextStart = 1; // Try next startcode; this PSC did not work } else { nextStart = 0; // Start with PSC next time } outputBsPointer( &start[nextStart], &s->newBs, (int)s->codingMethod ); BS_ERR_MSG( H261ErrMsg("Bitstream error: encountered PSC when expecting GBSC"); ) ++s->status.dwBadgobs; s->status.dwIntraFrame=0; s->next_gob = 0; return H261_ERROR; // This picture did not get done; start again } else { // Assume that GBSC was false; keep looking for GN = next_gob *structStatus = H261_ERROR; } return OK;}// doGobStructures - Create gob and mb structuresstatic int doGobStructures( H261Decoder *s, GOB_DESCR *gob, MACROBLOCK_DESCR mb[], BS_PTR start[2], int gn[2] ){ int maxbits, status; //printf("Entering doGobStructures: gn[] = %d %d\n", gn[0], gn[1]); gob->mb = mb; if (s->codingMethod == H263_CODING) { if (s->next_gob > 0) { // No GOB Layer for GOB 0 maxbits = BsDiff(start[1], start[0]); status = DecGobLayer263( &start[0], maxbits, gob, &s->gfid ); // start[0] gets bumped by DecGobLayer263; now pointing to MB layer if (status != OK) { BS_ERR_MSG( H261ErrMsg( "Bit error: DecGobLayer263 returned error" );) return( H261_ERROR ); } } status = build263gob( s->pic_layer.format, s->next_gob, gn[1], gob, &s->pic_layer ); if (status != OK) { BS_ERR_MSG( H261ErrMsg( "Bit error: build263gob returned error" );) return( H261_ERROR ); } } else { // H.261 status = build_gob_struct( s->pic_layer.format, s->next_gob, gob ); if (status != OK) { H261ErrMsg( "Program error: build_gob_struct returned error" ); return( H261_ERROR ); } } return( status );}// doGobDecoding - Decode all information in a GOBstatic int doGobDecoding( H261Decoder *s, GOB_DESCR *gob, MACROBLOCK_DESCR mb[], BS_PTR start[2], SYMBOL sym[], int maxsym ){ int maxbits, status; //printf("Entering doGobDecoding: num_mb = %d\n", gob->num_mb); maxbits = BsDiff(start[1], start[0]); if (s->codingMethod == H263_CODING) { mb += gob->first_col + gob->first_row * gob->mb_offset; status = DecMbLayer263( &start[0], maxbits, gob, mb, (int)s->pic_layer.interFrame, (int)s->pic_layer.PBframeMode, (int)s->pic_layer.unrestrictedMv, (int)s->pic_layer.advancedIntraMode, sym, maxsym); } else { // H.261 status = decode261gob( &start[0], maxbits, gob, mb, sym, maxsym); } if (status != OK) { BS_ERR_MSG( H261ErrMsg( "Bitstream error in doGobDecoding" );) } return( status );}// gobConcealment - Conceal error and update error countersstatic void gobConcealment( H261Decoder *s, GOB_DESCR *gob, MACROBLOCK_DESCR mb[] ){ BS_ERR_MSG( char msg[120]; ) /* Flawfinder: ignore */ //printf("Calling ConcealGob \n"); ConcealGob( gob, mb, s->pic_layer.reducedResUpdate, &s->oldOut, &s->newOut ); if (s->pic_layer.PBframeMode && s->PBframeCap) { // Conceal B-frame ConcealGob( gob, mb, s->pic_layer.reducedResUpdate, &s->oldOut, &s->B_Out ); } if (s->status.dwUpdateGobs == 0) // If this is the first bad gob { s->status.dwFirstBadgob = s->next_gob; // then save the number s->status.dwUpdateGobs = gob->num_mb/max(1,gob->mb_width); } else { s->status.dwUpdateGobs = s->next_gob + gob->num_mb / max(1,gob->mb_width) - s->status.dwFirstBadgob; } ++s->status.dwBadgobs; s->status.dwIntraFrame=0; BS_ERR_MSG( sprintf( msg, "Bitstream error when decoding GOB %d", s->next_gob); /* Flawfinder: ignore */ H261ErrMsg( msg ); )}// build_gob_struct - set up GOB descriptor and MB descriptors for GOB "gn"static int build_gob_struct( S32 format, S32 gn, GOB_DESCR * gob)#define MB_COLS_PER_GOB 11#define MB_ROWS_PER_GOB 3{ int mb_col, mb_row, row, col, index; if (gn < 1 || gn > 12 || // CIF: GN=1,2,..,12 (format == 0 && gn != 1 && gn != 3 && gn != 5)) { // QCIF: 1,3,5 return (H261_ERROR); } // Fill in GOB descriptor gob->num_mb = MB_COLS_PER_GOB * MB_ROWS_PER_GOB; gob->first_col = 0; gob->first_row = 0; gob->mb_width = MB_COLS_PER_GOB; gob->mb_offset = MB_COLS_PER_GOB; // Determine next GOB number if (format == 0 && gn < 5) { // QCIF gob->next_gn = gn + 2; } else if (format != 0 && gn < 12) { // CIF gob->next_gn = gn + 1; } else { // This is last GOB in picture gob->next_gn = 0; // Look for PSC next time } // Fill in macroblock locations if ((gn & 0x1) == 1) { mb_col = 0; // Odd GOBs on left side } else { mb_col = MB_COLS_PER_GOB; // Even GOBs on right side } mb_row = ((gn - 1) / 2) * MB_ROWS_PER_GOB; for (row = 0; row < MB_ROWS_PER_GOB; row++) { for (col = 0; col < MB_COLS_PER_GOB; col++) { index = row * MB_COLS_PER_GOB + col; (gob->mb + index)->x = col + mb_col; (gob->mb + index)->y = row + mb_row; } } return (OK);}// build263gob - set up GOB and MB descriptors for GOBS "gn" to "next_gn-1" (H.263)static int build263gob( S32 format, S32 gn, int next_gn, GOB_DESCR * gob, PICTURE_DESCR * pic ){ int mbhor, mbvert, num_gn, row, col, index, mbRowsPerGob; switch (format) { case SQCIF: mbhor = 8; num_gn = 6; mbRowsPerGob = 1; break; case QCIF: mbhor = 11; num_gn = 9; mbRowsPerGob = 1; break; case CIF: mbhor = 22; num_gn = 18; mbRowsPerGob = 1; break; case CIF4: mbhor = 44; num_gn = 18; mbRowsPerGob = 2; break; case CIF16: mbhor = 88; num_gn = 18; mbRowsPerGob = 4; break; case ANYSIZE: mbhor = (pic->cols + 15) >> 4; num_gn = (pic->rows + 15) >> 4; mbRowsPerGob = 1; while (num_gn > GN_END_OF_SEQUENCE) { // Max Group Number is 30 mbRowsPerGob *= 2; num_gn = (num_gn + 1) >> 1; } break; default: return( H261_ERROR ); break; }#ifdef DO_H263_PLUS if (pic->reducedResUpdate) { // Use 32x32 macroblocks mbhor = ROUNDDIV2( mbhor ); if (mbRowsPerGob == 1) { num_gn = ROUNDDIV2( num_gn ); } else { mbRowsPerGob = ROUNDDIV2( mbRowsPerGob ); } }#endif if (gn < 0 || gn >= num_gn) return( H261_ERROR ); // Fill in GOB descriptor if (next_gn == 0 || next_gn == GN_END_OF_SEQUENCE) { gob->next_gn = 0; // Look for PSC next time mbvert = num_gn - gn; } else { gob->next_gn = next_gn; mbvert = next_gn - gn; } mbvert *= mbRowsPerGob; if (mbvert <= 0) return( H261_ERROR ); gob->num_mb = mbhor * mbvert; gob->first_col = 0; gob->first_row = gn * mbRowsPerGob; // Need previous row for advancedPred mode gob->mb_width = mbhor; gob->mb_offset = mbhor; // Fill in macroblock locations for (row = gn * mbRowsPerGob; row < gn * mbRowsPerGob + mbvert; row++) { for (col = 0; col < mbhor; col++) { index = row * mbhor + col; gob->mb[index].x = col; gob->mb[index].y = row; } } return (OK);}/*********************// update_decMB - Update macroblock map by ORing MTYPE for each MBstatic void update_decMB( GOB_DESCR * gob, MACROBLOCK_DESCR mb[], int mb_per_row, int codingMethod, MBMap * decMB, S32 * iFrame, int forcedUpdate ){ int mbnum, i, row, col; U8 mtype; if (codingMethod == H263_CODING) { mbnum = gob->first_col + gob->first_row * gob->mb_offset; for (i = mbnum; i < mbnum + gob->num_mb; ++i) { mtype = mb[i].mtype; decMB->data[i] |= mtype; if ( mtype != MTYPE263_INTRA && mtype != MTYPE263_INTRA_Q ) *iFrame = 0; } if (forcedUpdate == YES) { // Ensure that macroblock map is non-zero for (i = mbnum; i < mbnum + gob->num_mb; ++i) { decMB->data[i] = 1; } } } else { // H.261 mbnum = mb[0].x + mb[0].y * mb_per_row; i = 0; for (row = 0; row < MB_ROWS_PER_GOB; row++) { for (col = 0; col < MB_COLS_PER_GOB; col++) { mtype = mb[i + col].mtype; decMB->data[mbnum + col] |= mtype; if ( mtype != MTYPE_INTRA && mtype != MTYPE_INTRA_MQUANT ) *iFrame = 0; } mbnum += mb_per_row; i += MB_COLS_PER_GOB; } if (forcedUpdate == YES) { // Ensure that macroblock map is non-zero mbnum = mb[0].x + mb[0].y * mb_per_row; for (row = 0; row < MB_ROWS_PER_GOB; row++) { for (col = 0; col < MB_COLS_PER_GOB; col++) { decMB->data[mbnum + col] = 1; } mbnum += mb_per_row; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -