getpicture.c
资源名称:NETVIDEO.rar [点击查看]
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:19k
源码类别:
流媒体/Mpeg4/MP4
开发平台:
Visual C++
- #include "../mpeg3private.h"
- #include "mpeg3video.h"
- #include "vlc.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- 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 coden"); */
- 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 coden"); */
- 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 coden"); */
- 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;
- }