📄 decode.c
字号:
if(!decoder->ulInitDisplay) { unsigned int w,h; get_display_size(&w, &h); //set_display_size(w, h); set_display_size(640, 480); decoder->ulInitDisplay=1; }#endif #if defined(MAE_HW) if (decoder->bUseMAE && decoder->ulSubmitCalled) { // KK - Fix for bug #6532 - certain poorly encoded clips cause the player to hang. // If the temporal numbers are not progressing properly don't submit these frames to the driver. if((decoder->uiPrevTnum == decoder->uiTemporalNum) && (decoder->coding_type == B_TYPE)) { DPRINTF((M_TEXT("mpeg2_parse() Bad temporals\n"))); decoder->uiOkToDecode = 0; } decoder->uiPrevTnum = decoder->uiTemporalNum; // When code exec comes here, it means all the headers have been parsed // and we have to come to a slice // this is time to go ahead and request the driver for memory to submit MBs if (decoder->uiOkToDecode) { GETPRINTF((M_TEXT("mpeg2_parse() WrapGetContext(0)\n"))); pWrapContext = WrapGetContext (0); if (!pWrapContext) { DPRINTF((M_TEXT("mpeg2_parse() Failed to get WrapContext\n"))); decoder->uiOkToDecode = 0; decoder->ulOkToSubmit = 0; } } if (decoder->uiOkToDecode) { pWrapContext->tnum = decoder->uiTemporalNum;// KK -- changed from picture to decoder temporal number pWrapContext->picture_structure = decoder->picture_structure; switch (decoder->coding_type) { case I_TYPE: pWrapContext->frametype[0] = IFRAME; pWrapContext->anchor_flag = 1; decoder->uiIFramesProcessed++; break; case P_TYPE: pWrapContext->frametype[0] = PFRAME; pWrapContext->anchor_flag = 1; decoder->uiPFramesProcessed++; break; case B_TYPE: pWrapContext->frametype[0] = BFRAME; pWrapContext->anchor_flag = 0; decoder->uiBFramesProcessed++; break; } } decoder->ulSubmitCalled = 0; } if (!pWrapContext) { DPRINTF((M_TEXT("mpeg2_parse() No WrapContext\n"))); /* ensure the Submit/Decode state variables are reset */ decoder->uiOkToDecode = 0; decoder->ulOkToSubmit = 0; decoder->ulSubmitCalled = 1; }#else decoder->uiPrevTnum = decoder->uiTemporalNum; if (decoder->uiOkToDecode) { switch (decoder->coding_type) { case I_TYPE: decoder->uiIFramesProcessed++; break; case P_TYPE: decoder->uiPFramesProcessed++; break; case B_TYPE: decoder->uiBFramesProcessed++; break; } }#endif /* MAE_HW */ if ( decoder->ulDebugFlag ) { decoder->ulDebugFlag = 0; } while (1) { while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) < mpeg2dec->nb_decode_slices) { size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start; size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE - mpeg2dec->chunk_ptr); if (size_buffer <= size_chunk) { copied = copy_chunk (mpeg2dec, size_buffer); if (!copied) { mpeg2dec->bytes_since_tag += size_buffer; mpeg2dec->chunk_ptr += size_buffer; return STATE_BUFFER; } } else { copied = copy_chunk (mpeg2dec, size_chunk); if (!copied) { /* filled the chunk buffer without finding a start code */ mpeg2dec->bytes_since_tag += size_chunk; mpeg2dec->action = seek_chunk; return STATE_INVALID; } } mpeg2dec->bytes_since_tag += copied; if (decoder->uiOkToDecode) {#if !defined(MAE_HW) && !defined(USE_CMODELIF) mpeg2_slice (&(mpeg2dec->decoder), mpeg2dec->code, mpeg2dec->chunk_start, (void*)0);#elif defined(NO_PERF) mpeg2_slice (&(mpeg2dec->decoder), mpeg2dec->code, mpeg2dec->chunk_start, (void*)pWrapContext);#else mpeg2_slice_no_dump (&(mpeg2dec->decoder), mpeg2dec->code, mpeg2dec->chunk_start, (void*)pWrapContext);#endif //#ifdef NO_PERF // Always submit the frame. This allows the driver to free the consumed resources decoder->ulOkToSubmit = 1; // KK - trick mode } mpeg2dec->code = mpeg2dec->buf_start[-1]; mpeg2dec->chunk_ptr = mpeg2dec->chunk_start; } if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1) break; if (seek_chunk (mpeg2dec) == STATE_BUFFER) return STATE_BUFFER; } // $PP // STATE_SLICE indicates that all slices of the current picture have been processed // for a FIELD picture, state slice indicates that slices for BOTH fields have been // processed // So this is the correct time to submit all the MBs to MAE h/w if (mpeg2dec->state == STATE_SLICE) { DPRINTF((M_TEXT("mpeg2_parse() STATE_SLICE\n")));#if defined(USE_CMODELIF) || defined(MAE_HW) if (decoder->bUseMAE && decoder->ulOkToSubmit) { decoder->ulSubmitCalled = 1; pWrapContext->pts = (m_s64)decoder->tCurrentPTS; pWrapContext->encoded_picture_linesize = decoder->width; pWrapContext->encoded_picture_height = decoder->height; pWrapContext->aspect = decoder->aspect; pWrapContext->stream_type = (decoder->mpeg1)?MAE_STREAM_TYPE_MPEG1:MAE_STREAM_TYPE_MPEG2; pWrapContext->dual_prime_field1 = nDMVUpdate1; //pWrapContext->dual_prime_field2 = nDMVUpdate2; pWrapContext->prog_frame = prog_frame; switch (decoder->coding_type) { case I_TYPE: pWrapContext->frametype[1] = IFRAME; break; case P_TYPE: pWrapContext->frametype[1] = PFRAME; break; case B_TYPE: pWrapContext->frametype[1] = BFRAME; break; } pWrapContext->dummysubmit = (decoder->uiOkToDecode)?0:1; // KK - trick mode mpeg2dec->info.uiFrameSent = 1; PUTPRINTF((M_TEXT("mpeg2_parse() WrapSubmitMBs(%p) decmode=%d ftype=%d pts=%d tnum=%d dummysubmit=%d\n"), pWrapContext, decoder->uiDecodeMode, pWrapContext->frametype[1], (int)pWrapContext->pts, pWrapContext->tnum, pWrapContext->dummysubmit)); WrapSubmitMBs(); decoder->ulOkToSubmit = 0; pWrapContext = NULL; } else { decoder->ulSubmitCalled = 1; // KK - trick mode decoder->ulOkToSubmit = 0; }#endif /* USE_CMODELIF || MAE_HW */ #if !defined(UNDER_CE) && defined(MAE_RENDERER) if (!mpeg2dec->ulVideoOff) { // Just pass in the 3 frame pointers to the display routine display_yv12_data(mpeg2dec->sequence.width, mpeg2dec->sequence.height, mpeg2dec->decoder.picture_dest[0], mpeg2dec->decoder.picture_dest[1], mpeg2dec->decoder.picture_dest[2], DISPLAY_FOR_MPEG2, 0, FALSE); }#endif }#ifdef MAE_HW // $PP // In a FIELD picture, STATE_SLICE_1ST indicates that all slices for the current field // (top or bottom) have been processed if (mpeg2dec->state == STATE_SLICE_1ST) { decoder->ulSpecial = 1; decoder->ulDebugFlag = 1; } // Now is the time to dump the output if ( (mpeg2dec->state == STATE_SLICE) && decoder->ulSubmitCalled) { // Check init_fbuf() in slice.c for these two variables ucMarkFieldSet = ucMarkFrameSet = 0; // If this is a special case of a FIELD picture, then // we have to dump the output as two separate fields if (decoder->ulSpecial) {#ifdef NO_PERF if ( decoder->bUseMAE && (decoder->bDumpFinal || decoder->bDumpFiles) ) WriteFrame (&mpeg2dec->decoder, DUMP_FIELD, 1);#endif //#ifdef NO_PERF decoder->ulSpecial = 0; } else {#ifdef NO_PERF if ( decoder->bUseMAE && (decoder->bDumpFinal || decoder->bDumpFiles) ) WriteFrame (&mpeg2dec->decoder, DUMP, 0);#endif //#ifdef NO_PERF } }#endif /* MAE_HW */ switch (mpeg2dec->code) { case 0x00: mpeg2dec->action = mpeg2_header_picture_start; return mpeg2dec->state; case 0xb7: mpeg2dec->action = mpeg2_header_end; break; case 0xb3: case 0xb8: mpeg2dec->action = mpeg2_parse_header; break; default: mpeg2dec->action = seek_chunk; return STATE_INVALID; } return (mpeg2dec->state == STATE_SLICE) ? STATE_SLICE : STATE_INVALID;}mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec){ static int (* process_header[]) (mpeg2dec_t * mpeg2dec) = { mpeg2_header_picture, mpeg2_header_extension, mpeg2_header_user_data, mpeg2_header_sequence, NULL, NULL, NULL, NULL, mpeg2_header_gop }; int size_buffer, size_chunk, copied; mpeg2dec->action = mpeg2_parse_header; mpeg2dec->info.user_data = NULL; mpeg2dec->info.user_data_len = 0; DPRINTF((M_TEXT("mpeg2_parse_header()\n"))); while (1) { size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start; size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE - mpeg2dec->chunk_ptr); if (size_buffer <= size_chunk) { copied = copy_chunk (mpeg2dec, size_buffer); if (!copied) { mpeg2dec->bytes_since_tag += size_buffer; mpeg2dec->chunk_ptr += size_buffer; return STATE_BUFFER; } } else { copied = copy_chunk (mpeg2dec, size_chunk); if (!copied) { /* filled the chunk buffer without finding a start code */ mpeg2dec->bytes_since_tag += size_chunk; mpeg2dec->code = 0xb4; mpeg2dec->action = mpeg2_seek_header; return STATE_INVALID; } } mpeg2dec->bytes_since_tag += copied; if (process_header[mpeg2dec->code & 0x0b] (mpeg2dec)) { mpeg2dec->code = mpeg2dec->buf_start[-1]; mpeg2dec->action = mpeg2_seek_header; return STATE_INVALID; } mpeg2dec->code = mpeg2dec->buf_start[-1]; switch (RECEIVED (mpeg2dec->code, mpeg2dec->state)) { /* state transition after a sequence header */ case RECEIVED (0x00, STATE_SEQUENCE): mpeg2dec->action = mpeg2_header_picture_start; case RECEIVED (0xb8, STATE_SEQUENCE): mpeg2_header_sequence_finalize (mpeg2dec); break; /* other legal state transitions */ case RECEIVED (0x00, STATE_GOP): mpeg2_header_gop_finalize (mpeg2dec); mpeg2dec->action = mpeg2_header_picture_start; break; case RECEIVED (0x01, STATE_PICTURE): case RECEIVED (0x01, STATE_PICTURE_2ND): mpeg2_header_picture_finalize (mpeg2dec, mpeg2_accels); mpeg2dec->action = mpeg2_header_slice_start; break; /* legal headers within a given state */ case RECEIVED (0xb2, STATE_SEQUENCE): case RECEIVED (0xb2, STATE_GOP): case RECEIVED (0xb2, STATE_PICTURE): case RECEIVED (0xb2, STATE_PICTURE_2ND): case RECEIVED (0xb5, STATE_SEQUENCE): case RECEIVED (0xb5, STATE_PICTURE): case RECEIVED (0xb5, STATE_PICTURE_2ND): mpeg2dec->chunk_ptr = mpeg2dec->chunk_start; continue; default: mpeg2dec->action = mpeg2_seek_header; return STATE_INVALID; } mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; mpeg2dec->user_data_len = 0; return mpeg2dec->state; }}int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg){ mpeg2_convert_init_t convert_init; int error; error = convert (MPEG2_CONVERT_SET, NULL, &(mpeg2dec->sequence), 0, mpeg2_accels, arg, &convert_init); if (!error) { mpeg2dec->convert = convert; mpeg2dec->convert_arg = arg; mpeg2dec->convert_id_size = convert_init.id_size; mpeg2dec->convert_stride = 0; } return error;}int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride){ if (!mpeg2dec->convert) { if (stride < (int) mpeg2dec->sequence.width) stride = mpeg2dec->sequence.width; mpeg2dec->decoder.stride_frame = stride; } else { mpeg2_convert_init_t convert_init;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -