⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slice.c

📁 jpeg and mpeg 编解码技术源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				&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 + -