www.pudn.com > NETVIDEO.rar > getpicture.c


#include "../mpeg3private.h" 
#include "mpeg3video.h" 
#include "vlc.h" 
 
#include  
#include  
#include  
 
int mpeg3video_get_cbp(mpeg3_slice_t *slice) 
{ 
  	int code; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
 
  	if((code = mpeg3slice_showbits9(slice_buffer)) >= 128) 
	{ 
    	code >>= 4; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab0[code].len); 
    	return mpeg3_CBPtab0[code].val; 
  	} 
 
  	if(code >= 8) 
	{ 
    	code >>= 1; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab1[code].len); 
    	return mpeg3_CBPtab1[code].val; 
  	} 
 
  	if(code < 1) 
	{ 
/*    	fprintf(stderr,"mpeg3video_get_cbp: invalid coded_block_pattern code\n"); */ 
    	slice->fault = 1; 
    	return 0; 
  	} 
 
  	mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab2[code].len); 
  	return mpeg3_CBPtab2[code].val; 
} 
 
 
/* set block to zero */ 
int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size) 
{ 
	slice->sparse[comp] = 1; 
 
/* Compiler error with 2.95 required hard coding the size to 6 */ 
 
	memset(slice->block[comp], 0, sizeof(short) * 64 * size); 
	return 0; 
} 
 
static __inline int mpeg3video_getdclum(mpeg3_slice_buffer_t *slice_buffer) 
{ 
	int code, size, val; 
/* decode length */ 
	code = mpeg3slice_showbits5(slice_buffer); 
 
	if(code < 31) 
	{ 
    	size = mpeg3_DClumtab0[code].val; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab0[code].len); 
	} 
	else  
	{ 
    	code = mpeg3slice_showbits9(slice_buffer) - 0x1f0; 
    	size = mpeg3_DClumtab1[code].val; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab1[code].len); 
	} 
 
	if(size == 0) val = 0; 
	else  
	{ 
    	val = mpeg3slice_getbits(slice_buffer, size); 
    	if((val & (1 << (size - 1))) == 0)  val -= (1 << size) - 1; 
	} 
 
	return val; 
} 
 
 
int mpeg3video_getdcchrom(mpeg3_slice_buffer_t *slice_buffer) 
{ 
	int code, size, val; 
 
/* decode length */ 
	code = mpeg3slice_showbits5(slice_buffer); 
 
	if(code < 31) 
	{ 
    	size = mpeg3_DCchromtab0[code].val; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab0[code].len); 
	} 
	else  
	{ 
    	code = mpeg3slice_showbits(slice_buffer, 10) - 0x3e0; 
    	size = mpeg3_DCchromtab1[code].val; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab1[code].len); 
	} 
 
	if(size == 0) val = 0; 
	else  
	{ 
      val = mpeg3slice_getbits(slice_buffer, size); 
      if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1; 
	} 
 
	return val; 
} 
 
 
/* decode one intra coded MPEG-1 block */ 
 
int mpeg3video_getintrablock(mpeg3_slice_t *slice,  
		mpeg3video_t *video, 
		int comp,  
		int dc_dct_pred[]) 
{ 
	int val, i, j, sign; 
	unsigned int code; 
	mpeg3_DCTtab_t *tab = 0; 
	short *bp = slice->block[comp]; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
 
/* decode DC coefficients */ 
  	if(comp < 4)          
  		bp[0] = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)) << 3; 
  	else  
  	if(comp == 4)    
  		bp[0] = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)) << 3; 
	else                 
  		bp[0] = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)) << 3; 
 
#ifdef HAVE_MMX 
	if(video->have_mmx) 
  		bp[0] <<= 4; 
#endif 
 
  	if(slice->fault) return 1; 
 
/* decode AC coefficients */ 
  	for(i = 1; ; i++) 
	{ 
    	code = mpeg3slice_showbits16(slice_buffer); 
    	if(code >= 16384) 
			tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; 
    	else  
		if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; 
    	else  
		if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8]; 
    	else  
		if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; 
    	else  
		if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; 
    	else  
		if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16]; 
    	else  
		if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16]; 
    	else  
		if(code >= 16) tab = &mpeg3_DCTtab6[code - 16]; 
    	else  
		{ 
/*    	  	fprintf(stderr, "mpeg3video_getintrablock: invalid Huffman code\n"); */ 
    	  	slice->fault = 1; 
    	  	return 0; 
    	} 
 
    	mpeg3slice_flushbits(slice_buffer, tab->len); 
 
    	if(tab->run == 64) break;  /* end_of_block */ 
 
    	if(tab->run == 65) 
		{ 
/* escape */ 
    		i += mpeg3slice_getbits(slice_buffer, 6); 
 
    		if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0)  
				val = mpeg3slice_getbits(slice_buffer, 8); 
    		else  
			if(val == 128)          
				val = mpeg3slice_getbits(slice_buffer, 8) - 256; 
    		else  
			if(val > 128)           
				val -= 256; 
 
    		if((sign = (val < 0)) != 0) val= -val; 
    	} 
    	else  
		{ 
    		i += tab->run; 
    		val = tab->level; 
    		sign = mpeg3slice_getbit(slice_buffer); 
    	} 
 
		if(i < 64) 
	    	j = video->mpeg3_zigzag_scan_table[i]; 
		else 
		{ 
    	  	slice->fault = 1; 
    	  	return 0; 
		} 
			 
 
#ifdef HAVE_MMX 
		if(video->have_mmx) 
		{ 
    		val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) << 1; 
    		val = (val - 16) | 16; 
		} 
		else 
#endif 
		{ 
    		val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) >> 3; 
    		val = (val - 1) | 1; 
		} 
 
    	bp[j] = sign ? -val : val; 
	} 
 
	if(j != 0)  
	{ 
/* not a sparse matrix ! */ 
       slice->sparse[comp] = 0; 
	} 
	return 0; 
} 
 
 
/* decode one non-intra coded MPEG-1 block */ 
 
int mpeg3video_getinterblock(mpeg3_slice_t *slice,  
		mpeg3video_t *video,  
		int comp) 
{ 
	int val, i, j, sign; 
	unsigned int code; 
	mpeg3_DCTtab_t *tab;  
	short *bp = slice->block[comp]; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
 
/* decode AC coefficients */ 
	for(i = 0; ; i++) 
	{ 
    	code = mpeg3slice_showbits16(slice_buffer); 
    	if(code >= 16384) 
		{ 
    	    if(i == 0)  
				tab = &mpeg3_DCTtabfirst[(code >> 12) - 4]; 
    	    else       
				tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; 
    	} 
    	else  
		if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; 
    	else  
		if(code >= 512)  tab = &mpeg3_DCTtab1[(code >> 6) - 8]; 
    	else  
		if(code >= 256)  tab = &mpeg3_DCTtab2[(code >> 4) - 16]; 
    	else  
		if(code >= 128)  tab = &mpeg3_DCTtab3[(code >> 3) - 16]; 
    	else  
		if(code >= 64)   tab = &mpeg3_DCTtab4[(code >> 2) - 16]; 
    	else  
		if(code >= 32)   tab = &mpeg3_DCTtab5[(code >> 1) - 16]; 
    	else  
		if(code >= 16)   tab = &mpeg3_DCTtab6[code - 16]; 
    	else  
		{ 
// invalid Huffman code 
    		slice->fault = 1; 
    		return 1; 
    	} 
 
    	mpeg3slice_flushbits(slice_buffer, tab->len); 
 
/* end of block */ 
    	if(tab->run == 64) 
    	   break;    
 
    	if(tab->run == 65) 
		{           
/* escape  */ 
    		i += mpeg3slice_getbits(slice_buffer, 6); 
    		if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0)  
				val = mpeg3slice_getbits(slice_buffer, 8); 
    		else  
			if(val == 128)   
				val = mpeg3slice_getbits(slice_buffer, 8) - 256; 
    		else  
			if(val > 128)  
				val -= 256; 
 
    		if((sign = (val < 0)) != 0) val = -val; 
    	} 
    	else  
		{ 
    		i += tab->run; 
    		val = tab->level; 
    		sign = mpeg3slice_getbit(slice_buffer); 
    	} 
 
    	j = video->mpeg3_zigzag_scan_table[i]; 
 
#ifdef HAVE_MMX 
		if(video->have_mmx) 
		{ 
    		val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]); 
    		val = (val - 16) | 16; 
		} 
		else 
#endif 
		{ 
    		val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]) >> 4; 
    		val = (val - 1) | 1; 
		} 
 
    	bp[j] = sign ? -val : val; 
	} 
 
	if(j != 0)  
	{ 
/* not a sparse matrix ! */ 
       slice->sparse[comp] = 0; 
	} 
	return 0; 
} 
 
 
/* decode one intra coded MPEG-2 block */ 
int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice,  
		mpeg3video_t *video,  
		int comp,  
		int dc_dct_pred[]) 
{ 
	int val, i, j, sign, nc; 
	unsigned int code; 
	mpeg3_DCTtab_t *tab; 
	short *bp; 
	int *qmat; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
 
/* with data partitioning, data always goes to base layer */ 
  	bp = slice->block[comp]; 
 
  	qmat = (comp < 4 || video->chroma_format == CHROMA420) 
         ? video->intra_quantizer_matrix 
         : video->chroma_intra_quantizer_matrix; 
 
/* decode DC coefficients */ 
	if(comp < 4)            
		val = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)); 
	else  
	if((comp & 1) == 0)  
		val = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)); 
	else                   
		val = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)); 
 
  	if(slice->fault) return 0; 
#ifdef HAVE_MMX 
	if(video->have_mmx) 
  		bp[0] = val << (7 - video->dc_prec); 
	else 
#endif 
  		bp[0] = val << (3 - video->dc_prec); 
 
  	nc = 0; 
 
/* decode AC coefficients */ 
  	for(i = 1; ; i++) 
	{ 
    	code = mpeg3slice_showbits16(slice_buffer); 
 
    	if(code >= 16384 && !video->intravlc) 
			tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; 
    	else  
		if(code >= 1024) 
		{ 
    		if(video->intravlc)  
				tab = &mpeg3_DCTtab0a[(code >> 8) - 4]; 
    		else  
				tab = &mpeg3_DCTtab0[(code >> 8) - 4]; 
    	} 
    	else  
		if(code >= 512) 
		{ 
    		if(video->intravlc)      
		  	  	tab = &mpeg3_DCTtab1a[(code >> 6) - 8]; 
    		else               
				tab = &mpeg3_DCTtab1[(code >> 6) - 8]; 
    	} 
    	else  
		if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16]; 
    	else  
		if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16]; 
    	else  
		if(code >= 64)  tab = &mpeg3_DCTtab4[(code >> 2) - 16]; 
    	else  
		if(code >= 32)  tab = &mpeg3_DCTtab5[(code >> 1) - 16]; 
    	else  
		if(code >= 16)  tab = &mpeg3_DCTtab6[code - 16]; 
    	else  
		{ 
/*    		fprintf(stderr,"mpeg3video_getmpg2intrablock: invalid Huffman code\n"); */ 
    		slice->fault = 1; 
    		return 1; 
    	} 
 
    	mpeg3slice_flushbits(slice_buffer, tab->len); 
 
/* end_of_block */ 
    	if(tab->run == 64) 
    	   	break;  
 
    	if(tab->run == 65) 
		{ 
/* escape */ 
    	  	i += mpeg3slice_getbits(slice_buffer, 6); 
 
    	  	val = mpeg3slice_getbits(slice_buffer, 12); 
    	  	if((val & 2047) == 0) 
			{ 
// invalid signed_level (escape) 
        		slice->fault = 1; 
        		return 0; 
    	  	} 
    	  	if((sign = (val >= 2048)) != 0) val = 4096 - val; 
    	} 
    	else  
		{ 
    		i += tab->run; 
    		val = tab->level; 
    		sign = mpeg3slice_getbit(slice_buffer); 
    	} 
 
    	j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i]; 
 
#ifdef HAVE_MMX 
		if(video->have_mmx) 
	    	val = (val * slice->quant_scale * qmat[j]); 
		else 
#endif 
    		val = (val * slice->quant_scale * qmat[j]) >> 4; 
 
    	bp[j] = sign ? -val : val; 
    	nc++; 
	} 
 
	if(j != 0) 
	{ 
/* not a sparse matrix ! */ 
    	 slice->sparse[comp] = 0; 
	} 
	return 1; 
} 
 
 
/* decode one non-intra coded MPEG-2 block */ 
 
int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice,  
		mpeg3video_t *video,  
		int comp) 
{ 
	int val, i, j, sign, nc; 
	unsigned int code; 
	mpeg3_DCTtab_t *tab; 
	short *bp; 
	int *qmat; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
 
/* with data partitioning, data always goes to base layer */ 
  	bp = slice->block[comp]; 
 
  	qmat = (comp < 4 || video->chroma_format == CHROMA420) 
         ? video->non_intra_quantizer_matrix 
         : video->chroma_non_intra_quantizer_matrix; 
 
  	nc = 0; 
 
/* decode AC coefficients */ 
  	for(i = 0; ; i++) 
	{ 
    	code = mpeg3slice_showbits16(slice_buffer); 
    	if(code >= 16384) 
		{ 
    	  if(i == 0) tab = &mpeg3_DCTtabfirst[(code >> 12) - 4]; 
    	  else      tab = &mpeg3_DCTtabnext[(code >> 12) - 4]; 
    	} 
    	else  
		if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4]; 
    	else  
		if(code >= 512)  tab = &mpeg3_DCTtab1[(code >> 6) - 8]; 
    	else  
		if(code >= 256)  tab = &mpeg3_DCTtab2[(code >> 4) - 16]; 
    	else  
		if(code >= 128)  tab = &mpeg3_DCTtab3[(code >> 3) - 16]; 
    	else  
		if(code >= 64)   tab = &mpeg3_DCTtab4[(code >> 2) - 16]; 
    	else  
		if(code >= 32)   tab = &mpeg3_DCTtab5[(code >> 1) - 16]; 
    	else  
		if(code >= 16)   tab = &mpeg3_DCTtab6[code - 16]; 
    	else  
		{ 
// invalid Huffman code 
    		slice->fault = 1; 
    		return 0; 
    	} 
 
    	mpeg3slice_flushbits(slice_buffer, tab->len); 
 
/* end_of_block */ 
    	if(tab->run == 64) 
       		break;           
 
    	if(tab->run == 65) 
		{                  
/* escape */ 
    		i += mpeg3slice_getbits(slice_buffer, 6); 
    		val = mpeg3slice_getbits(slice_buffer, 12); 
    		if((val & 2047) == 0) 
			{ 
/*        		fprintf(stderr, "mpeg3video_getmpg2interblock: invalid signed_level (escape)\n"); */ 
        		slice->fault = 1; 
        		return 1; 
    		} 
    		if((sign = (val >= 2048)) != 0) val = 4096 - val; 
    	} 
    	else  
		{ 
    		i += tab->run; 
    		val = tab->level; 
    		sign = mpeg3slice_getbit(slice_buffer); 
    	} 
 
    	j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i]; 
 
#ifdef HAVE_MMX 
 		if(video->have_mmx) 
    		val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 1; 
		else 
#endif 
     		val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 5; 
 
    	bp[j] = sign ? (-val) : val ; 
    	nc++; 
	} 
 
	if(j != 0)  
	{ 
      	slice->sparse[comp] = 0; 
	} 
	return 0; 
} 
 
 
/* decode all macroblocks of the current picture */ 
int mpeg3video_get_macroblocks(mpeg3video_t *video, int framenum) 
{ 
	unsigned int code; 
	mpeg3_slice_buffer_t *slice_buffer; /* Buffer being loaded */ 
	int i; 
	int current_buffer; 
	mpeg3_bits_t *vstream = video->vstream; 
 
/* Load every slice into a buffer array */ 
	video->total_slice_buffers = 0; 
	current_buffer = 0; 
	while(!mpeg3bits_eof(vstream) &&  
		mpeg3bits_showbits32_noptr(vstream) >= MPEG3_SLICE_MIN_START &&  
		mpeg3bits_showbits32_noptr(vstream) <= MPEG3_SLICE_MAX_START && 
		video->total_slice_buffers < MPEG3_MAX_CPUS) 
	{ 
/* Initialize the buffer */ 
		if(current_buffer >= video->slice_buffers_initialized) 
			mpeg3_new_slice_buffer(&(video->slice_buffers[video->slice_buffers_initialized++])); 
		slice_buffer = &(video->slice_buffers[current_buffer]); 
		slice_buffer->buffer_size = 0; 
		slice_buffer->current_position = 0; 
		slice_buffer->bits_size = 0; 
		slice_buffer->done = 0; 
 
/* Read the slice into the buffer including the slice start code */ 
		do 
		{ 
/* Expand buffer */ 
			if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size) 
				mpeg3_expand_slice_buffer(slice_buffer); 
 
/* Load 1 char into buffer */ 
			slice_buffer->data[slice_buffer->buffer_size++] = mpeg3bits_getbyte_noptr(vstream); 
		}while(!mpeg3bits_eof(vstream) && 
			mpeg3bits_showbits24_noptr(vstream) != MPEG3_PACKET_START_CODE_PREFIX); 
 
/* Pad the buffer to get the last macroblock */ 
		if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size + 4) 
			mpeg3_expand_slice_buffer(slice_buffer); 
 
		slice_buffer->data[slice_buffer->buffer_size++] = 0; 
		slice_buffer->data[slice_buffer->buffer_size++] = 0; 
		slice_buffer->data[slice_buffer->buffer_size++] = 1; 
		slice_buffer->data[slice_buffer->buffer_size++] = 0; 
		slice_buffer->bits_size = 0; 
 
#ifndef SDL_THREADS 
		pthread_mutex_lock(&(slice_buffer->completion_lock)); 
#else 
		SDL_LockMutex(slice_buffer->completion_lock); 
#endif 
		fflush(stdout); 
		current_buffer++; 
		video->total_slice_buffers++; 
	} 
 
/* Run the slice decoders */ 
	if(video->total_slice_buffers > 0) 
	{ 
		for(i = 0; i < video->total_slice_decoders; i++) 
		{ 
			if(i == 0 && video->total_slice_decoders > 1) 
			{ 
				video->slice_decoders[i].current_buffer = 0; 
				video->slice_decoders[i].buffer_step = 1; 
				video->slice_decoders[i].last_buffer = (video->total_slice_buffers - 1); 
			} 
			else 
			if(i == 1) 
			{ 
				video->slice_decoders[i].current_buffer = video->total_slice_buffers - 1; 
				video->slice_decoders[i].buffer_step = -1; 
				video->slice_decoders[i].last_buffer = 0; 
			} 
			else 
			{ 
				video->slice_decoders[i].current_buffer = i; 
				video->slice_decoders[i].buffer_step = 1; 
				video->slice_decoders[i].last_buffer = video->total_slice_buffers - 1; 
			} 
#ifndef SDL_THREADS 
			pthread_mutex_unlock(&(video->slice_decoders[i].input_lock)); 
#else 
			SDL_UnlockMutex(video->slice_decoders[i].input_lock); 
#endif 
		} 
	} 
 
/* Wait for the slice buffers to finish */ 
	if(video->total_slice_buffers > 0) 
	{ 
		for(i = 0; i < video->total_slice_buffers; i++) 
		{ 
#ifndef SDL_THREADS 
			pthread_mutex_lock(&(video->slice_buffers[i].completion_lock)); 
			pthread_mutex_unlock(&(video->slice_buffers[i].completion_lock)); 
#else 
			SDL_LockMutex(video->slice_buffers[i].completion_lock); 
			SDL_UnlockMutex(video->slice_buffers[i].completion_lock); 
#endif 
		} 
 
/* Wait for decoders to finish so packages aren't overwritten */ 
		for(i = 0; i < video->total_slice_decoders; i++) 
		{ 
#ifndef SDL_THREADS 
			pthread_mutex_lock(&(video->slice_decoders[i].completion_lock)); 
#else 
			SDL_LockMutex(video->slice_decoders[i].completion_lock); 
#endif 
		} 
	} 
	return 0; 
} 
 
int mpeg3video_allocate_decoders(mpeg3video_t *video, int decoder_count) 
{ 
	int i; 
	int cpus = video->cpus; 
	  if (video->total_slice_decoders != cpus) 
	{ 
		for(i = 0; i < video->total_slice_decoders; i++) 
		{ 
			mpeg3_delete_slice_decoder(&(video->slice_decoders[i])); 
		} 
 
		for(i = 0; i < cpus && i < MPEG3_MAX_CPUS; i++) 
		{ 
			mpeg3_new_slice_decoder(video, &(video->slice_decoders[i])); 
			video->slice_decoders[i].thread_number = i; 
		} 
 
		video->total_slice_decoders = cpus; 
	} 
	return 0; 
} 
 
/* decode one frame or field picture */ 
 
int mpeg3video_getpicture(mpeg3video_t *video, int framenum) 
{ 
	int i, result = 0; 
	int cpus = video->cpus; 
 
	if(video->pict_struct == FRAME_PICTURE && video->secondfield) 
	{ 
/* recover from illegal number of field pictures */ 
    	video->secondfield = 0; 
	} 
 
	if(!video->mpeg2) 
	{ 
		video->current_repeat = video->repeat_count = 0; 
	} 
 
	mpeg3video_allocate_decoders(video, cpus); 
 
  	for(i = 0; i < 3; i++) 
	{ 
    	if(video->pict_type == B_TYPE) 
		{ 
			video->newframe[i] = video->auxframe[i]; 
		} 
    	else  
		{ 
    	  	if(!video->secondfield && !video->current_repeat) 
			{ 
/* Swap refframes for I frames */ 
        		unsigned char* tmp = video->oldrefframe[i]; 
        		video->oldrefframe[i] = video->refframe[i]; 
        		video->refframe[i] = tmp; 
    	  	} 
 
    	 	video->newframe[i] = video->refframe[i]; 
    	} 
 
    	if(video->pict_struct == BOTTOM_FIELD) 
		{ 
/* Only used if fields are in different pictures */ 
    	    video->newframe[i] += (i == 0) ? video->coded_picture_width : video->chrom_width; 
		} 
	} 
 
 
/* The problem is when a B frame lands on the first repeat and is skipped, */ 
/* the second repeat goes for the same bitmap as the skipped repeat, */ 
/* so it picks up a frame from 3 frames back. */ 
/* The first repeat must consititutively read a B frame if its B frame is going to be */ 
/* used in a later repeat. */ 
	if(!video->current_repeat) 
		if(!(video->skip_bframes && video->pict_type == B_TYPE) ||  
			(video->repeat_count >= 100 + 100 * video->skip_bframes)) 
  			result = mpeg3video_get_macroblocks(video, framenum); 
 
/* Set the frame to display */ 
	video->output_src = 0; 
	if(framenum > -1 && !result) 
	{ 
    	if(video->pict_struct == FRAME_PICTURE || video->secondfield) 
		{ 
     	  	if(video->pict_type == B_TYPE) 
			{ 
				video->output_src = video->auxframe; 
			} 
     	  	else 
			{ 
				video->output_src = video->oldrefframe; 
			} 
    	} 
    	else  
		{ 
			mpeg3video_display_second_field(video); 
		} 
	} 
 
	if(video->mpeg2) 
	{ 
		video->current_repeat += 100; 
	} 
 
  	if(video->pict_struct != FRAME_PICTURE) video->secondfield = !video->secondfield; 
	return result; 
}