📄 header.c
字号:
sequence->pixel_width = 64; sequence->pixel_height = 45; return; case 6: /* 720x480 16:9 */ sequence->pixel_width = 32; sequence->pixel_height = 27; return; case 12: /* 720x480 4:3 */ sequence->pixel_width = 8; sequence->pixel_height = 9; return; default: height = 88 * sequence->pixel_width + 1171; width = 2000; } } if (width && height) { sequence->pixel_width = width; sequence->pixel_height = height; while (width) /* find greatest common divisor */ { int tmp = width; width = height % tmp; height = tmp; } sequence->pixel_width /= height; sequence->pixel_height /= height; } else /* error translating pixel aspect ratio */ { sequence->pixel_width = 0; sequence->pixel_height = 0; } /* HWG050524- */ // $PP sequence->uiFormat = ((sequence->chroma_width == sequence->width) + (sequence->chroma_height == sequence->height)); // 0 - 420, 1-422, 2-444}static void copy_matrix (mpeg2dec_t * mpeg2dec, int index){ if (memcmp (mpeg2dec->quantizer_matrix[index], mpeg2dec->new_quantizer_matrix[index], 64)) { memcpy (mpeg2dec->quantizer_matrix[index], mpeg2dec->new_quantizer_matrix[index], 64); mpeg2dec->scaled[index] = -1; } // $PP // we must do a similar choice for the MAE matrix if (memcmp (mpeg2dec->decoder.MAE_Quant_Matrix[index], mpeg2dec->MAE_New_Quant_Matrix[index], 64)) { memcpy (mpeg2dec->decoder.MAE_Quant_Matrix[index], mpeg2dec->MAE_New_Quant_Matrix[index], 64); if (index == 0 || index == 1) /* INTRA matrix has changed */ mpeg2dec->decoder.bIntraMatrixChanged = 1; else if (index == 2 || index == 3) /* INTER matrix has changed */ mpeg2dec->decoder.bInterMatrixChanged = 1; }}static void finalize_matrix (mpeg2dec_t * mpeg2dec){ mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); int i; for (i = 0; i < 2; i++) { if (mpeg2dec->copy_matrix & (1 << i)) copy_matrix (mpeg2dec, i); if ( (mpeg2dec->copy_matrix & (4 << i)) && memcmp (mpeg2dec->quantizer_matrix[i], mpeg2dec->new_quantizer_matrix[i+2], 64)) { copy_matrix (mpeg2dec, i + 2); decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i+2]; // $PP memcpy (decoder->MAE_Quant_Matrix[i+2], mpeg2dec->MAE_New_Quant_Matrix[i+2], 64); } else if (mpeg2dec->copy_matrix & (5 << i)) { // $PP memcpy (decoder->MAE_Quant_Matrix[i+2], mpeg2dec->MAE_New_Quant_Matrix[i], 64); mpeg2dec->decoder.bInterMatrixChanged = 1; decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i]; } }}static mpeg2_state_t invalid_end_action (mpeg2dec_t * mpeg2dec){ mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.gop = NULL; info_user_data (mpeg2dec); mpeg2_header_state_init (mpeg2dec); mpeg2dec->sequence = mpeg2dec->new_sequence; mpeg2dec->action = mpeg2_seek_header; mpeg2dec->state = STATE_SEQUENCE; return STATE_SEQUENCE;}void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec){ mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence); mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);#ifdef MAE_RENDERER static int nRendererInitDone = 0;#endif finalize_sequence (sequence); finalize_matrix (mpeg2dec); #ifdef MAE_RENDERER // KKHV // Initialize the mae_renderer (just needs the spatial size) if(!mpeg2dec->ulVideoOff && !nRendererInitDone) { printf("\nInitializing MAE-RENDERER\n"); init_mae_renderer(sequence->width, sequence->height); nRendererInitDone++; }#endif decoder->mpeg1 = !(sequence->flags & SEQ_FLAG_MPEG2); // This fixes the black band at the bottom of the screen seen mostly with clips of size 320x240 and 352x240 decoder->width = sequence->picture_width; decoder->height = sequence->picture_height; decoder->aspect = (sequence->pixel_width << 16) | (sequence->pixel_height); decoder->vertical_position_extension = (sequence->picture_height > 2800); decoder->chroma_format = ((sequence->chroma_width == sequence->width) + (sequence->chroma_height == sequence->height)); if (mpeg2dec->sequence.width != (unsigned)-1) { unsigned int new_byte_rate; /* * According to 6.1.1.6, repeat sequence headers should be * identical to the original. However some DVDs dont respect * that and have different bitrates in the repeat sequence * headers. So we'll ignore that in the comparison and still * consider these as repeat sequence headers. * * However, be careful not to alter the current sequence when * returning STATE_INVALID_END. */ new_byte_rate = sequence->byte_rate; sequence->byte_rate = mpeg2dec->sequence.byte_rate; if (memcmp (&(mpeg2dec->sequence), sequence, sizeof (mpeg2_sequence_t))) { decoder->stride_frame = sequence->width; sequence->byte_rate = new_byte_rate; mpeg2_header_end (mpeg2dec); mpeg2dec->action = invalid_end_action; mpeg2dec->state = STATE_INVALID_END; return; } sequence->byte_rate = new_byte_rate; mpeg2dec->state = STATE_SEQUENCE_REPEATED; } else { /* new sequence */ decoder->stride_frame = sequence->width; /* HWG050505+ reset interpolation parameters on new sequence */ mpeg2dec->decoder.bSyncedPTS = 0; mpeg2dec->decoder.uiGOPCount = 0; mpeg2dec->decoder.uiTemporalOffset=0; mpeg2dec->decoder.iPTSDrift=0; mpeg2dec->decoder.uiActualFramePeriod=sequence->uiFramePeriod<<FRAMEPERIOD_SCALE; TIMEPRINTF((M_TEXT("NewSequence: FramePeriod=%d ms\n"), sequence->uiFramePeriod>>FRAMEPERIOD_SCALE)); /* HWG050505-*/ } mpeg2dec->sequence = *sequence; mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.sequence = &(mpeg2dec->sequence); mpeg2dec->info.gop = NULL; info_user_data (mpeg2dec);}int mpeg2_header_gop (mpeg2dec_t * mpeg2dec){ uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_gop_t * gop = &(mpeg2dec->new_gop); DPRINTF((M_TEXT("mpeg2_header_gop() GOPCount=%d\n"), mpeg2dec->decoder.uiGOPCount)); if (! (buffer[1] & 8)) return 1; gop->hours = (buffer[0] >> 2) & 31; gop->minutes = ((buffer[0] << 4) | (buffer[1] >> 4)) & 63; gop->seconds = ((buffer[1] << 3) | (buffer[2] >> 5)) & 63; gop->pictures = ((buffer[2] << 1) | (buffer[3] >> 7)) & 63; gop->flags = (buffer[0] >> 7) | ((buffer[3] >> 4) & 6); mpeg2dec->state = STATE_GOP; /* HWG050505+ for PTS interpolation */ mpeg2dec->decoder.uiGOPCount++; mpeg2dec->decoder.uiGOPsSincePTSSync++; TIMEPRINTF((M_TEXT("NewGOP: GOP=%d (SinceSync=%d) closed=%d broken=%d\n"), mpeg2dec->decoder.uiGOPCount, mpeg2dec->decoder.uiGOPsSincePTSSync, (gop->flags>>2)&1, (gop->flags>>1)&1)); //if (mpeg2dec->decoder.uiWaitForIFrame!=1) { /* compensate for the fact that on a new GOP, temporal numbers start from 0 again */#if 0 /* bugbug - reseting temporal counters on closed_gop confuses MAE - test with "bugs3.mpg" */ if ((gop->flags&4)!=0) /* closed_gop bit set? */ { /* closed_gop: Reset Temporal number counter (sequence will start I=2,P=0,B=1,...) */ mpeg2dec->decoder.uiTemporalOffset=0; } else#endif mpeg2dec->decoder.uiTemporalOffset+=mpeg2dec->decoder.uiMaxTemporal + 1; mpeg2dec->decoder.iTemporalAtSyncPTS-=(mpeg2dec->decoder.uiMaxTemporal + 1); mpeg2dec->decoder.uiMaxTemporal=0; /* we don't know the max temporal number for this GOP yet */ } /* HWG050505- */ return 0;}void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec){ mpeg2dec->gop = mpeg2dec->new_gop; mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.gop = &(mpeg2dec->gop); info_user_data (mpeg2dec);}void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type){ int i; for (i = 0; i < 3; i++) { if (mpeg2dec->fbuf[1] != &mpeg2dec->fbuf_alloc[i].fbuf && mpeg2dec->fbuf[2] != &mpeg2dec->fbuf_alloc[i].fbuf) { mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[i].fbuf; mpeg2dec->info.current_fbuf = mpeg2dec->fbuf[0]; if (b_type || (mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY)) { if (b_type || mpeg2dec->convert) mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[0]; mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[0]; } break; } }}mpeg2_state_t mpeg2_header_picture_start (mpeg2dec_t * mpeg2dec){ mpeg2_picture_t * picture = &(mpeg2dec->new_picture); DPRINTF((M_TEXT("mpeg2_header_picture_start() frametype=%d decmode=%d\n"), mpeg2dec->decoder.coding_type, mpeg2dec->decoder.uiDecodeMode)); mpeg2dec->state = ((mpeg2dec->state != STATE_SLICE_1ST) ? STATE_PICTURE : STATE_PICTURE_2ND); picture->flags = 0; picture->tag = picture->tag2 = 0; if (mpeg2dec->num_tags) { if (mpeg2dec->bytes_since_tag >= 4) { mpeg2dec->num_tags = 0; picture->tag = mpeg2dec->tag_current; picture->tag2 = mpeg2dec->tag2_current; picture->flags = PIC_FLAG_TAGS; } else if (mpeg2dec->num_tags > 1) { mpeg2dec->num_tags = 1; picture->tag = mpeg2dec->tag_previous; picture->tag2 = mpeg2dec->tag2_previous; picture->flags = PIC_FLAG_TAGS; } } picture->display_offset[0].x = picture->display_offset[1].x = picture->display_offset[2].x = mpeg2dec->display_offset_x; picture->display_offset[0].y = picture->display_offset[1].y = picture->display_offset[2].y = mpeg2dec->display_offset_y; return mpeg2_parse_header (mpeg2dec);}#define PTS_SYNC_THRESHOLD 90 /* drift allowed between interpolated & actual PTS (in milliseconds) */#define MAXFRAMES_BEFORE_SYNC 60 /* number of frame before forcing a sync to PTS */mpeg_time_t GetInterpolatedPTS(mpeg2_decoder_t *decoder, mpeg2_picture_t *picture){ /* interpolate PTS from temporal number & last PTS received from mpeg2_settimestamp() call */ mpeg_time_t tInterPTS; int iInterTemporal; int iPTSAdjustByTemporal; /* interpolate PTS */ tInterPTS=decoder->tPTSLastSync; iInterTemporal=picture->temporal_reference-decoder->iTemporalAtSyncPTS; iPTSAdjustByTemporal=((int)(iInterTemporal*decoder->uiActualFramePeriod)>>FRAMEPERIOD_SCALE); TIMEPRINTF2((M_TEXT(" GetInterpolatedPTS: InterPTS=%d iIntraTemporal=%d iPTSAdjustByTemporal(%d)\n"), (int)tInterPTS, iInterTemporal, iPTSAdjustByTemporal));#ifdef UNDER_CE /* when UNCER_CE we expect to have negative PTS after seeks*/ tInterPTS+=iPTSAdjustByTemporal;#else /* when we compensate for temporal offset, check that we don't end up with a negative PTS */ if (iPTSAdjustByTemporal>=0 || tInterPTS>= -iPTSAdjustByTemporal) tInterPTS+=iPTSAdjustByTemporal; else /* Interpolated PTS is negative, force it to zero */ tInterPTS=0;#endif TIMEPRINTF2((M_TEXT(" GetInterpolatedPTS: InterPTS=%d iTemporal=%d (pictemp=%d tnum=%d) Period=%d ms\n"), (int)tInterPTS, iInterTemporal, picture->temporal_reference, decoder->uiTemporalNum, decoder->uiActualFramePeriod>>FRAMEPERIOD_SCALE)); return tInterPTS;}static void ResyncPTS(mpeg2_decoder_t *decoder, mpeg_time_t tInterPTS, mpeg_time_t tNewPTS, int iTemporalAtPTS){ int iPTSdrift=(int)(tNewPTS-tInterPTS); TIMEPRINTF((M_TEXT("ResyncPTS(%d->%d, temporal=%d) drift=%d\n"), (int)decoder->tPTSLastSync, (int)tNewPTS, iTemporalAtPTS, iPTSdrift)); if (iPTSdrift>=-500 && iPTSdrift<=500) { tNewPTS=(tNewPTS+tInterPTS)/2; /* average with interpolated PTS to smooth out transition */ } decoder->bSyncedPTS=1; decoder->tPTSLastSync=tNewPTS; decoder->iTemporalAtSyncPTS=iTemporalAtPTS; decoder->uiFramesSincePTSSync=0; decoder->uiGOPsSincePTSSync=0;}static void mpeg2_finalize_timestamp (mpeg2dec_t * mpeg2dec){ mpeg2_picture_t * picture = &(mpeg2dec->new_picture); mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); mpeg_time_t tInterPTS; /* decoder->uiTemporalNum is passed to MAE, must be sequentially increasing */ //if (decoder->uiWaitForIFrame==1) // decoder->uiTemporalOffset=0; decoder->uiTemporalNum = decoder->uiTemporalOffset + (unsigned int)picture->temporal_reference; tInterPTS=GetInterpolatedPTS(decoder, picture); /* HWG050505+ new PTS interpolation, better accuracy when syncing to external PTS's */ if (picture->temporal_reference>mpeg2dec->decoder.uiMaxTemporal) mpeg2dec->decoder.uiMaxTemporal=picture->temporal_reference; /* check to see if a new time stamp has just been received */ if (mpeg2dec->decoder.bNewPTS && mpeg2dec->decoder.uiFramesSinceNewPTS==0) { int iPTSdrift=(int)(decoder->tNewPTS-tInterPTS); if (mpeg2dec->decoder.bSyncedPTS) iPTSdrift=(iPTSdrift+mpeg2dec->decoder.iPTSDrift)>>1; /* average drift to smooth out spikes */ TIMEPRINTF((M_TEXT("NewPTS=%d temporal=%d->%d gops=%d I(%d)P(%d)B(%d) drift=%d\n"), decoder->tNewPTS, mpeg2dec->decoder.iTemporalAtNewPTS, picture->temporal_reference, decoder->uiGOPsSincePTSSync, decoder->uiIFramesProcessed, decoder->uiPFramesProcessed, decoder->uiBFramesProcessed, iPTSdrift)); mpeg2dec->decoder.iPTSDrift=iPTSdrift; /* remember the temporal frame number at this point */ mpeg2dec->decoder.iTemporalAtNewPTS = picture->temporal_reference; if (decoder->uiIFramesProcessed > 3 && !decoder->uiPFramesProcessed && !decoder->uiBFramesProcessed) { /* special case where PTS are coming in at an uneven rate (I-frame only being received) */ TIMEPRINTF((M_TEXT("Forcing resync: NewPTS=%d, gops=%d, drift=%d, bSyncedPTS=%d, uiFramesSincePTSSync=%d\n"), decoder->tNewPTS, decoder->uiGOPsSincePTSSync, iPTSdrift, mpeg2dec->decoder.bSyncedPTS, mpeg2dec->decoder.uiFramesSincePTSSync)); tInterPTS=decoder->tNewPTS; mpeg2dec->decoder.bSyncedPTS=0; /* force resync on PTS */ mpeg2dec->decoder.uiFramesSincePTSSync=0; } /* avoid actually using the new PTS on every frame, just sync up every>500ms or so */ if (!mpeg2dec->decoder.bSyncedPTS || (mpeg2dec->decoder.uiFramesSincePTSSync>=12 && decoder->uiGOPsSincePTSSync>=1)) { if (iPTSdrift>PTS_SYNC_THRESHOLD || iPTSdrift<-PTS_SYNC_THRESHOLD || mpeg2dec->decoder.uiFramesSincePTSSync>=MAXFRAMES_BEFORE_SYNC) { mpeg_time_t tNewInterPTS; if (mpeg2dec->decoder.uiFramesSincePTSSync>2 && decoder->tNewPTS>mpeg2dec->decoder.tPTSLastSync) { int iPTSdiff=decoder->tNewPTS-mpeg2dec->decoder.tPTSLastSync; unsigned int uiEllapsedFrames=mpeg2dec->decoder.uiFramesSincePTSSync; unsigned int uiInterFramePeriod=(iPTSdiff<<FRAMEPERIOD_SCALE)/uiEllapsedFrames; if (uiInterFramePeriod<=(66<<FRAMEPERIOD_SCALE)) /* is this a reasonable period */ { unsigned int uiNewFramePeriod=((decoder->uiActualFramePeriod*3)+uiInterFramePeriod)>>2; /* average */ /* round to closest valid FramePeriod */ if (uiNewFramePeriod>=(32<<FRAMEPERIOD_SCALE) && uiNewFramePeriod<=(35<<FRAMEPERIOD_SCALE)) decoder->uiActualFramePeriod=(1000<<FRAMEPERIOD_SCALE)/30; /* force to 33 ms (30 fps) */ else if (uiNewFramePeriod>=(38<<FRAMEPERIOD_SCALE) && uiNewFramePeriod<(41<<FRAMEPERIOD_SCALE)) decoder->uiActualFramePeriod=(1000<<FRAMEPERIOD_SCALE)/25; /* force to 40 ms (25 fps) */ else if (uiNewFramePeriod>=(41<<FRAMEPERIOD_SCALE) && uiNewFramePeriod<(46<<FRAMEPERIOD_SCALE)) decoder->uiActualFramePeriod=(1000<<FRAMEPERIOD_SCALE)/24; /* force to 41 ms (24 fps) */ else decoder->uiActualFramePeriod=uiNewFramePeriod; } TIMEPRINTF((M_TEXT("FramePeriod=%d ms (drift=%d diff=%d frames=%d)\n"), decoder->uiActualFramePeriod>>FRAMEPERIOD_SCALE, iPTSdrift, iPTSdiff, mpeg2dec->decoder.uiFramesSincePTSSync)); } ResyncPTS(decoder, tInterPTS, decoder->tNewPTS, mpeg2dec->decoder.iTemporalAtNewPTS); /* re-interpolate our frame's PTS since we have resynced to a new external PTS ** if algorithm works well we'll only see small PTS adjustments here (i.e. diff<60 ms) */ tNewInterPTS=GetInterpolatedPTS(decoder, picture); TIMEPRINTF((M_TEXT("ReInterpolate PTS=%d -> %d (diff=%d FramePeriod=%d)\n"), (int)tInterPTS, (int)tNewInterPTS, (int)(tNewInterPTS-tInterPTS), decoder->uiActualFramePeriod>>FRAMEPERIOD_SCALE)); tInterPTS=tNewInterPTS; } } } /* update current PTS */ TIMEPRINTF((M_TEXT(" CurrentPTS=%d (pictemp=%d tnum=%d toffset=%d) Period=%d ms\n"), (int)tInterPTS, picture->temporal_reference, decoder->uiTemporalNum, decoder->uiTemporalOffset, decoder->uiActualFramePeriod>>FRAMEPERIOD_SCALE)); mpeg2dec->decoder.tCurrentPTS=tInterPTS; /* update frame counters */ mpeg2dec->decoder.uiFramesSinceNewPTS++; mpeg2dec->decoder.uiFramesSincePTSSync++; /* HWG050505- */ mpeg2dec->info.tCurrentDisplayTS = decoder->tCurrentPTS; }int mpeg2_header_picture (mpeg2dec_t * mpeg2dec){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -