📄 slice.c
字号:
/*fprintf(stderr, "mpeg3_decode_slice: too many macroblocks in picture\n"); */ return 1; }/* not skipped */ if(mba_inc == 1) { mpeg3video_macroblock_modes(slice, video, &mb_type, &stwtype, &stwclass, &motion_type, &mv_count, &mv_format, &dmv, &mvscale, &dct_type); if(slice->fault) return 1; if(mb_type & MB_QUANT) { qs = mpeg3slice_getbits(slice_buffer, 5); if(video->mpeg2) slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1); else slice->quant_scale = qs; if(video->scalable_mode == SC_DP)/* make sure quant_scale is valid */ slice->quant_scale = slice->quant_scale; }/* motion vectors *//* decode forward motion vectors */ if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv)) { if(video->mpeg2) mpeg3video_motion_vectors(slice, video, pmv, dmvector, mv_field_sel, 0, mv_count, mv_format, video->h_forw_r_size, video->v_forw_r_size, dmv, mvscale); else mpeg3video_motion_vector(slice, video, pmv[0][0], dmvector, video->forw_r_size, video->forw_r_size, 0, 0, video->full_forw); } if(slice->fault) return 1;/* decode backward motion vectors */ if(mb_type & MB_BACKWARD) { if(video->mpeg2) mpeg3video_motion_vectors(slice, video, pmv, dmvector, mv_field_sel, 1, mv_count, mv_format, video->h_back_r_size, video->v_back_r_size, 0, mvscale); else mpeg3video_motion_vector(slice, video, pmv[0][1], dmvector, video->back_r_size, video->back_r_size, 0, 0, video->full_back); } if(slice->fault) return 1;/* remove marker_bit */ if((mb_type & MB_INTRA) && video->conceal_mv) mpeg3slice_flushbit(slice_buffer);/* macroblock_pattern */ if(mb_type & MB_PATTERN) { cbp = mpeg3video_get_cbp(slice); if(video->chroma_format == CHROMA422) {/* coded_block_pattern_1 */ cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer); } else if(video->chroma_format == CHROMA444) {/* coded_block_pattern_2 */ cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6); } } else cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0; if(slice->fault) return 1;/* decode blocks */ mpeg3video_clearblock(slice, 0, video->blk_cnt); for(comp = 0; comp < video->blk_cnt; comp++) { if(cbp & (1 << (video->blk_cnt - comp - 1))) { if(mb_type & MB_INTRA) { if(video->mpeg2) mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred); else mpeg3video_getintrablock(slice, video, comp, dc_dct_pred); } else { if(video->mpeg2) mpeg3video_getmpg2interblock(slice, video, comp); else mpeg3video_getinterblock(slice, video, comp); } if(slice->fault) return 1; } }/* reset intra_dc predictors */ if(!(mb_type & MB_INTRA)) dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;/* reset motion vector predictors */ if((mb_type & MB_INTRA) && !video->conceal_mv) {/* intra mb without concealment motion vectors */ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; } if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA))) {/* non-intra mb without forward mv in a P picture */ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;/* derive motion_type */ if(video->pict_struct == FRAME_PICTURE) motion_type = MC_FRAME; else { motion_type = MC_FIELD;/* predict from field of same parity */ mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD); } } if(stwclass == 4) {/* purely spatially predicted macroblock */ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0; pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0; } } else {/* mba_inc!=1: skipped macroblock */ mpeg3video_clearblock(slice, 0, video->blk_cnt);/* reset intra_dc predictors */ dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;/* reset motion vector predictors */ if(video->pict_type == P_TYPE) pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;/* derive motion_type */ if(video->pict_struct == FRAME_PICTURE) motion_type = MC_FRAME; else { motion_type = MC_FIELD;/* predict from field of same parity */ mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD); }/* skipped I are spatial-only predicted, *//* skipped P and B are temporal-only predicted */ stwtype = (video->pict_type == I_TYPE) ? 8 : 0;/* clear MB_INTRA */ mb_type &= ~MB_INTRA;/* no block data */ cbp = 0; } snr_cbp = 0;/* pixel coordinates of top left corner of current macroblock */ bx = 16 * (macroblock_address % video->mb_width); by = 16 * (macroblock_address / video->mb_width);/* motion compensation */ if(!(mb_type & MB_INTRA)) mpeg3video_reconstruct(video, bx, by, mb_type, motion_type, pmv, mv_field_sel, dmvector, stwtype);/* copy or add block data into picture */ for(comp = 0; comp < video->blk_cnt; comp++) { if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp))) {#ifdef HAVE_MMX if(video->have_mmx) IDCT_mmx(slice->block[comp]); else#endif mpeg3video_idct_conversion(slice->block[comp]); mpeg3video_addblock(slice, video, comp, bx, by, dct_type, (mb_type & MB_INTRA) == 0); } }/* advance to next macroblock */ macroblock_address++; mba_inc--; } return 0;}void mpeg3_slice_loop(mpeg3_slice_t *slice){ mpeg3video_t *video = slice->video; int result = 1; int cont = 0; while(!slice->done) { if (cont == 0) { // only wait if we're done... SDL_SemWait(slice->input_sem); cont = 1; } if(!slice->done) { /* Get a buffer to decode */ result = 1; SDL_LockMutex(video->slice_lock); if(slice->buffer_step > 0) { while(slice->current_buffer <= slice->last_buffer) { if(!video->slice_buffers[slice->current_buffer].done && slice->current_buffer <= slice->last_buffer) { result = 0; break; } slice->current_buffer += slice->buffer_step; } } else { while(slice->current_buffer >= slice->last_buffer) { if(!video->slice_buffers[slice->current_buffer].done && slice->current_buffer >= slice->last_buffer) { result = 0; break; } slice->current_buffer += slice->buffer_step; } } /* Got one */ if (!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers) { slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]); SDL_LockMutex(slice->slice_buffer->buffer_completion_lock); slice->slice_buffer->done = 1; SDL_UnlockMutex(video->slice_lock); mpeg3_decode_slice(slice); SDL_UnlockMutex(slice->slice_buffer->buffer_completion_lock); } else /* Finished with all */ { cont = 0; // back to waiting SDL_UnlockMutex(video->slice_lock); SDL_SemPost(video->slice_complete_sem); } } }}int mpeg3_new_slice_decoder(void *video, mpeg3_slice_t *slice){#ifndef SDL_THREADS pthread_attr_t attr;#endif slice->video = video; slice->done = 0; slice->input_sem = SDL_CreateSemaphore(0);#ifndef SDL_THREADS pthread_attr_init(&attr); pthread_create(&(slice->tid), &attr, (void*)mpeg3_slice_loop, slice);#else slice->tid = SDL_CreateThread((void*)mpeg3_slice_loop, slice);#endif return 0;}int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice){ slice->done = 1; SDL_SemPost(slice->input_sem);#ifndef SDL_THREADS pthread_join(slice->tid, 0);#else SDL_WaitThread(slice->tid, NULL);#endif SDL_DestroySemaphore(slice->input_sem); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -