📄 header.c
字号:
uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_picture_t * picture = &(mpeg2dec->new_picture); mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); int type; type = (buffer [1] >> 3) & 7; mpeg2dec->ext_state = PIC_CODING_EXT; picture->temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6); picture->flags |= type; if (type == PIC_FLAG_CODING_TYPE_P || type == PIC_FLAG_CODING_TYPE_B) { /* forward_f_code and backward_f_code - used in mpeg1 only */ decoder->f_motion.f_code[1] = (buffer[3] >> 2) & 1; decoder->f_motion.f_code[0] = (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1; decoder->b_motion.f_code[1] = (buffer[4] >> 6) & 1; decoder->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1; } /* XXXXXX decode extra_information_picture as well */ picture->nb_fields = 2; mpeg2dec->q_scale_type = 0; // $PP decoder->intra_dc_mult = 1; // default value if (decoder->mpeg1) { decoder->intra_dc_mult = 8; decoder->intra_dc_pred_reset_value = 128; decoder->scan_type = 0; // scan normal } decoder->iQuant_Scale_Type = 0; decoder->intra_dc_precision = 7; decoder->frame_pred_frame_dct = 1; decoder->concealment_motion_vectors = 0; decoder->scan = mpeg2_scan_norm; decoder->picture_structure = FRAME_PICTURE; mpeg2dec->copy_matrix = 0; return 0;}static int picture_coding_ext (mpeg2dec_t * mpeg2dec){ uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_picture_t * picture = &(mpeg2dec->new_picture); mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); uint32_t flags; /* pre subtract 1 for use later in compute_motion_vector */ decoder->f_motion.f_code[0] = (buffer[0] & 15) - 1; decoder->f_motion.f_code[1] = (buffer[1] >> 4) - 1; decoder->b_motion.f_code[0] = (buffer[1] & 15) - 1; decoder->b_motion.f_code[1] = (buffer[2] >> 4) - 1; flags = picture->flags; decoder->intra_dc_precision = 7 - ((buffer[2] >> 2) & 3); // $PP decoder->intra_dc_mult = 1 << ( 3 - ((buffer[2] >> 2) & 3)); decoder->intra_dc_pred_reset_value = 128 << ((buffer[2] >> 2) & 3); decoder->picture_structure = buffer[2] & 3; switch (decoder->picture_structure) { case TOP_FIELD: flags |= PIC_FLAG_TOP_FIELD_FIRST; case BOTTOM_FIELD: picture->nb_fields = 1; break; case FRAME_PICTURE: if (!(mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE)) { picture->nb_fields = (buffer[3] & 2) ? 3 : 2; flags |= (buffer[3] & 128) ? PIC_FLAG_TOP_FIELD_FIRST : 0; // @@@ libmpeg2 patch flags |= (buffer[3] & 2) ? PIC_FLAG_REPEAT_FIRST_FIELD : 0; } else { picture->nb_fields = (buffer[3]&2) ? ((buffer[3]&128) ? 6 : 4) : 2; } break; default: return 1; } decoder->top_field_first = buffer[3] >> 7; decoder->frame_pred_frame_dct = (buffer[3] >> 6) & 1; decoder->concealment_motion_vectors = (buffer[3] >> 5) & 1; mpeg2dec->q_scale_type = buffer[3] & 16; // $PP decoder->iQuant_Scale_Type = (buffer[3] >> 4) & 1; decoder->intra_vlc_format = (buffer[3] >> 3) & 1; decoder->scan = (buffer[3] & 4) ? mpeg2_scan_alt : mpeg2_scan_norm; // $PP decoder->scan_type = (buffer[3] & 4) ? 1 : 0; flags |= (buffer[4] & 0x80) ? PIC_FLAG_PROGRESSIVE_FRAME : 0; if (buffer[4] & 0x40) flags |= (((buffer[4]<<26) | (buffer[5]<<18) | (buffer[6]<<10)) & PIC_MASK_COMPOSITE_DISPLAY) | PIC_FLAG_COMPOSITE_DISPLAY; picture->flags = flags; mpeg2dec->ext_state = PIC_DISPLAY_EXT | COPYRIGHT_EXT | QUANT_MATRIX_EXT; return 0;}static int picture_display_ext (mpeg2dec_t * mpeg2dec){ uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_picture_t * picture = &(mpeg2dec->new_picture); int i, nb_pos; nb_pos = picture->nb_fields; if (mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE) nb_pos >>= 1; for (i = 0; i < nb_pos; i++) { int x, y; x = ((buffer[4*i] << 24) | (buffer[4*i+1] << 16) | (buffer[4*i+2] << 8) | buffer[4*i+3]) >> (11-2*i); y = ((buffer[4*i+2] << 24) | (buffer[4*i+3] << 16) | (buffer[4*i+4] << 8) | buffer[4*i+5]) >> (10-2*i); if (! (x & y & 1)) return 1; picture->display_offset[i].x = mpeg2dec->display_offset_x = x >> 1; picture->display_offset[i].y = mpeg2dec->display_offset_y = y >> 1; } for (; i < 3; i++) { picture->display_offset[i].x = mpeg2dec->display_offset_x; picture->display_offset[i].y = mpeg2dec->display_offset_y; } return 0;}void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec, uint32_t accels){ mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); int old_type_b = (decoder->coding_type == B_TYPE); int low_delay = mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY; finalize_matrix (mpeg2dec); decoder->coding_type = mpeg2dec->new_picture.flags & PIC_MASK_CODING_TYPE; // $PP mpeg2dec->info.uiFrameType = decoder->coding_type; // $PP // instead of determining in mpeg2_parse(), check here to see if the // decodemode set matches the coding type and set a flag if (!decoder->uiWaitForIFrame && mpeg2dec->decoder.bNewDecodeMode) { if (mpeg2dec->decoder.uiDecodeMode==mpeg2dec->decoder.uiNewDecodeMode && mpeg2dec->decoder.uiSpeed==mpeg2dec->decoder.uiNewSpeed) { mpeg2dec->decoder.bNewDecodeMode = 0; /* no mode change */ } else if (decoder->coding_type==I_TYPE || decoder->coding_type==P_TYPE) { /* Note: We are careful changing between NORMAL, IP, and I mode to prevent ** decoding P or B frame with the incorrect reference frames. ** Without this logic this can happen if we quickly toggle between ** NORMAL and skipping modes, like happens during 2x or 4x playback. */ if (mpeg2dec->decoder.uiNewDecodeMode==DECODE_NORMAL || mpeg2dec->decoder.uiNewDecodeMode==DECODE_IP_ONLY) { DPRINTF((M_TEXT("mpeg2_header_picture_finalize() frametype=%d newdecmode=%d\n"), decoder->coding_type, mpeg2dec->decoder.uiNewDecodeMode)); /* do wait I-frame logic so we are sure to pick up both reference frames */ decoder->uiWaitForIFrame=1; /* wait for next 2 reference frames */ DPRINTF((M_TEXT("mpeg2_header_picture_finalize() WaitForIFrame=%d\n"), decoder->uiWaitForIFrame)); } else /* we're going to I-Only mode, safe to go directly into it */ { DPRINTF((M_TEXT("mpeg2_header_picture_finalize() change speed=0x%X->0x%X decmode=%d->%d frametype=%d\n"), mpeg2dec->decoder.uiSpeed, mpeg2dec->decoder.uiNewSpeed, mpeg2dec->decoder.uiDecodeMode, mpeg2dec->decoder.uiNewDecodeMode, decoder->coding_type));#ifdef MAE_HW DPRINTF((M_TEXT("mpeg2_header_picture_finalize() MAE set_mode(0x%X, 0x%X)\n"), mpeg2dec->decoder.uiNewDecodeMode, mpeg2dec->decoder.uiNewSpeed)); set_mode(mpeg2dec->decoder.uiNewDecodeMode, mpeg2dec->decoder.uiNewSpeed);#endif mpeg2dec->decoder.uiDecodeMode = mpeg2dec->decoder.uiNewDecodeMode; mpeg2dec->decoder.uiSpeed = mpeg2dec->decoder.uiNewSpeed; mpeg2dec->decoder.bNewDecodeMode = 0; } } } if (decoder->uiWaitForIFrame) { DPRINTF((M_TEXT("mpeg2_header_picture_finalize() WaitForI %d: frametype=%d newspeed=0x%X decmode=%d framecount=%d\n"), decoder->uiWaitForIFrame, decoder->coding_type, mpeg2dec->decoder.uiNewSpeed, mpeg2dec->decoder.uiDecodeMode, mpeg2dec->info.uiFrameCount)); if (decoder->uiWaitForIFrame==1 && decoder->coding_type==I_TYPE) { decoder->uiWaitForIFrame = 2; /* 2=wait for 2nd reference picture */ decoder->uiOkToDecode = 1; DPRINTF((M_TEXT("mpeg2_header_picture_finalize() WaitForI (got I): change speed=0x%X->0x%X decmode=%d -> %d\n"), mpeg2dec->decoder.uiSpeed, mpeg2dec->decoder.uiNewSpeed, mpeg2dec->decoder.uiDecodeMode, mpeg2dec->decoder.uiNewDecodeMode)); if (mpeg2dec->decoder.bNewDecodeMode) {#ifdef MAE_HW set_mode(mpeg2dec->decoder.uiNewDecodeMode, mpeg2dec->decoder.uiNewSpeed);#endif mpeg2dec->decoder.uiSpeed = mpeg2dec->decoder.uiNewSpeed; mpeg2dec->decoder.uiDecodeMode = mpeg2dec->decoder.uiNewDecodeMode; mpeg2dec->decoder.bNewDecodeMode = 0; if (mpeg2dec->decoder.uiDecodeMode!=DECODE_I_ONLY) { /* reset previous I-frame skipping variables */ decoder->uiSkipFrameCount=0; decoder->uiSkipIFrames=1; } } } else if (decoder->uiWaitForIFrame==2 && (decoder->coding_type==I_TYPE || decoder->coding_type==P_TYPE)) { DPRINTF((M_TEXT("mpeg2_header_picture_finalize() WaitForI: FrameType=%d uiOkToDecode=1\n"), decoder->coding_type)); decoder->uiOkToDecode = 1; decoder->uiWaitForIFrame = 0; /* we got 2 reference frames, we can decode normal again */ } else { DPRINTF((M_TEXT("mpeg2_header_picture_finalize() WaitForI (skipped): FrameType=%d\n"), decoder->coding_type)); decoder->uiOkToDecode = 0; } } else { switch (decoder->uiDecodeMode) { case DECODE_NORMAL: decoder->uiOkToDecode = 1; break; case DECODE_I_ONLY: if (decoder->coding_type == I_TYPE) { DPRINTF((M_TEXT("IFrame in IFrame only mode skipcount(%d) SkipFrame(%d) MOD(%d)\n"), decoder->uiSkipFrameCount, decoder->uiSkipIFrames, decoder->uiSkipFrameCount%decoder->uiSkipIFrames)); //here check if we are skipping this I Frame if (!decoder->uiSkipIFrames || (decoder->uiSkipFrameCount%decoder->uiSkipIFrames) == 0) decoder->uiOkToDecode = 1; else decoder->uiOkToDecode = 0; decoder->uiSkipFrameCount++; } else decoder->uiOkToDecode = 0; break; case DECODE_P_ONLY: if (decoder->coding_type == P_TYPE) decoder->uiOkToDecode = 1; else decoder->uiOkToDecode = 0; break; case DECODE_IP_ONLY: if ((decoder->coding_type == I_TYPE) || (decoder->coding_type == P_TYPE)) decoder->uiOkToDecode = 1; else decoder->uiOkToDecode = 0; break; default: decoder->uiOkToDecode = 0; break; } } //$KK mpeg2_finalize_timestamp (mpeg2dec); if (mpeg2dec->state == STATE_PICTURE) { mpeg2_picture_t * picture; mpeg2_picture_t * other; decoder->second_field = 0; picture = other = mpeg2dec->pictures; if (old_type_b ^ (mpeg2dec->picture < mpeg2dec->pictures + 2)) picture += 2; else other += 2; mpeg2dec->picture = picture; mpeg2dec->decoder.iMBCount = 0; // $PP mpeg2dec->info.uiFrameCount++; *picture = mpeg2dec->new_picture; if (!old_type_b) { mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1]; mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0]; } mpeg2dec->fbuf[0] = NULL; mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.current_picture = picture; mpeg2dec->info.display_picture = picture; if (decoder->coding_type != B_TYPE) { if (!low_delay) { if (mpeg2dec->first) { mpeg2dec->info.display_picture = NULL; mpeg2dec->first = 0; } else { mpeg2dec->info.display_picture = other; if (other->nb_fields == 1) mpeg2dec->info.display_picture_2nd = other + 1; mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[1]; } } if (!low_delay + !mpeg2dec->convert) mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[!low_delay + !mpeg2dec->convert]; } if (mpeg2dec->convert) { mpeg2_convert_init_t convert_init; if (!mpeg2dec->convert_start) { int y_size, uv_size; mpeg2dec->decoder.convert_id = mpeg2_malloc (mpeg2dec->convert_id_size, MPEG2_ALLOC_CONVERT_ID); mpeg2dec->convert (MPEG2_CONVERT_START, mpeg2dec->decoder.convert_id, &(mpeg2dec->sequence), mpeg2dec->convert_stride, accels, mpeg2dec->convert_arg, &convert_init); mpeg2dec->convert_start = convert_init.start; mpeg2dec->decoder.convert = convert_init.copy; y_size = decoder->stride_frame * mpeg2dec->sequence.height; uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format); mpeg2dec->yuv_buf[0][0] = (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[0][1] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[0][2] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[1][0] = (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[1][1] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[1][2] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV);#ifndef MAE_HW y_size = decoder->stride_frame * 32; uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format);#endif mpeg2dec->yuv_buf[2][0] = (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[2][1] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[2][2] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); } if (!mpeg2dec->custom_fbuf) { while (mpeg2dec->alloc_index < 3) { mpeg2_fbuf_t * fbuf; fbuf = &mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf; fbuf->id = NULL; fbuf->buf[0] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[0], MPEG2_ALLOC_CONVERTED); fbuf->buf[1] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[1], MPEG2_ALLOC_CONVERTED); fbuf->buf[2] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[2], MPEG2_ALLOC_CONVERTED); } mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE)); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -