h261dec.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,645 行 · 第 1/5 页
C
1,645 行
// savePSCpointer - Pass the pointer to the picture start code to caller
static 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 startcode
static 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 PSC
static 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 structures
static 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 GOB
static 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 counters
static 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 MB
static 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 + =
减小字号Ctrl + -
显示快捷键?