📄 slice.c
字号:
&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;
while(!slice->done)
{
#ifndef SDL_THREADS
pthread_mutex_lock(&(slice->input_lock));
#else
SDL_LockMutex(slice->input_lock);
#endif
if(!slice->done)
{
/* Get a buffer to decode */
result = 1;
#ifndef SDL_THREADS
pthread_mutex_lock(&(video->slice_lock));
#else
SDL_LockMutex(video->slice_lock);
#endif
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]);
slice->slice_buffer->done = 1;
#ifndef SDL_THREADS
pthread_mutex_unlock(&(video->slice_lock));
pthread_mutex_unlock(&(slice->input_lock));
#else
SDL_UnlockMutex(video->slice_lock);
SDL_UnlockMutex(slice->input_lock);
#endif
mpeg3_decode_slice(slice);
#ifndef SDL_THREADS
pthread_mutex_unlock(&(slice->slice_buffer->completion_lock));
#else
SDL_UnlockMutex(slice->slice_buffer->completion_lock);
#endif
}
else
/* Finished with all */
{
#ifndef SDL_THREADS
pthread_mutex_unlock(&(slice->completion_lock));
pthread_mutex_unlock(&(video->slice_lock));
#else
SDL_UnlockMutex(slice->completion_lock);
SDL_UnlockMutex(video->slice_lock);
#endif
}
}
#ifndef SDL_THREADS
pthread_mutex_unlock(&(slice->output_lock));
#else
SDL_UnlockMutex(slice->output_lock);
#endif
}
}
int mpeg3_new_slice_decoder(void *video, mpeg3_slice_t *slice)
{
#ifndef SDL_THREADS
pthread_attr_t attr;
pthread_mutexattr_t mutex_attr;
#endif
slice->video = video;
slice->done = 0;
#ifndef SDL_THREADS
pthread_mutexattr_init(&mutex_attr);
// pthread_mutexattr_setkind_np(&mutex_attr, PTHREAD_MUTEX_FAST_NP);
pthread_mutex_init(&(slice->input_lock), &mutex_attr);
pthread_mutex_lock(&(slice->input_lock));
pthread_mutex_init(&(slice->output_lock), &mutex_attr);
pthread_mutex_lock(&(slice->output_lock));
pthread_mutex_init(&(slice->completion_lock), &mutex_attr);
pthread_mutex_lock(&(slice->completion_lock));
#else
slice->input_lock = SDL_CreateMutex();
SDL_LockMutex(slice->input_lock);
slice->output_lock = SDL_CreateMutex();
SDL_LockMutex(slice->output_lock);
slice->completion_lock = SDL_CreateMutex();
SDL_LockMutex(slice->completion_lock);
#endif
#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;
#ifndef SDL_THREADS
pthread_mutex_unlock(&(slice->input_lock));
pthread_join(slice->tid, 0);
pthread_mutex_destroy(&(slice->input_lock));
pthread_mutex_destroy(&(slice->output_lock));
#else
SDL_UnlockMutex(slice->input_lock);
SDL_WaitThread(slice->tid, NULL);
SDL_DestroyMutex(slice->input_lock);
SDL_DestroyMutex(slice->output_lock);
#endif
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -