📄 getpicture.c
字号:
{ 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; //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; } SDL_SemPost(video->slice_decoders[i].input_sem); } }/* Wait for the slice buffers to finish */ if(video->total_slice_buffers > 0) { int all_complete; do { SDL_SemWait(video->slice_complete_sem); all_complete = 1; for (i = 0; i < video->total_slice_buffers && all_complete == 1; i++) { SDL_LockMutex(video->slice_buffers[i].buffer_completion_lock); if (video->slice_buffers[i].done == 0) { all_complete = 0; } SDL_UnlockMutex(video->slice_buffers[i].buffer_completion_lock); } } while (all_complete == 0); } 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -