📄 slice.c
字号:
#include "../mpeg3private.h"#include "mpeg3video.h"#include "mpeg3videoprotos.h"#include "slice.h"#ifndef SDL_THREADS#include <pthread.h>#else#include "SDL.h"#include "SDL_thread.h"#endif#include <stdlib.h>#define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)#ifndef _MSC_VERstatic unsigned long long MMX_128 = 0x80008000800080LL;#elsestatic uint64_t MMX_128 = 0x80008000800080;#endifint mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer){ slice_buffer->data = malloc(1024); slice_buffer->buffer_size = 0; slice_buffer->buffer_allocation = 1024; slice_buffer->current_position = 0; slice_buffer->bits_size = 0; slice_buffer->bits = 0; slice_buffer->done = 0; slice_buffer->buffer_completion_lock = SDL_CreateMutex(); return 0;}int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer){ free(slice_buffer->data); SDL_DestroyMutex(slice_buffer->buffer_completion_lock); return 0;}int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer){ int i; unsigned char *new_buffer = malloc(slice_buffer->buffer_allocation * 2); for(i = 0; i < slice_buffer->buffer_size; i++) new_buffer[i] = slice_buffer->data[i]; free(slice_buffer->data); slice_buffer->data = new_buffer; slice_buffer->buffer_allocation *= 2; return 0;}/* limit coefficients to -2048..2047 *//* move/add 8x8-Block from block[comp] to refframe */static __inline int mpeg3video_addblock(mpeg3_slice_t *slice, mpeg3video_t *video, int comp, int bx, int by, int dct_type, int addflag){ int cc, i, iincr; unsigned char *rfp; short *bp; int spar = slice->sparse[comp];/* color component index */ cc = (comp < 4) ? 0 : (comp & 1) + 1; if(cc == 0) { /* luminance */ if(video->pict_struct == FRAME_PICTURE) { if(dct_type) {/* field DCT coding */ rfp = video->newframe[0] + video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3); iincr = (video->coded_picture_width << 1); } else {/* frame DCT coding */ rfp = video->newframe[0] + video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3); iincr = video->coded_picture_width; } } else {/* field picture */ rfp = video->newframe[0] + (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3); iincr = (video->coded_picture_width << 1); } } else {/* chrominance *//* scale coordinates */ if(video->chroma_format != CHROMA444) bx >>= 1; if(video->chroma_format == CHROMA420) by >>= 1; if(video->pict_struct == FRAME_PICTURE) { if(dct_type && (video->chroma_format != CHROMA420)) {/* field DCT coding */ rfp = video->newframe[cc] + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8); iincr = (video->chrom_width << 1); } else {/* frame DCT coding */ rfp = video->newframe[cc] + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8); iincr = video->chrom_width; } } else {/* field picture */ rfp = video->newframe[cc] + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8); iincr = (video->chrom_width << 1); } } bp = slice->block[comp]; if(addflag) {#ifdef HAVE_MMX if(video->have_mmx) { if(spar) { __asm__ __volatile__( "movq (%2), %%mm6\n" /* 4 blockvals */ "pxor %%mm4, %%mm4\n" "punpcklwd %%mm6, %%mm6\n" "punpcklwd %%mm6, %%mm6\n" ".align 8\n" "1:" "movq (%1), %%mm0\n" /* 8 rindex1 */ "movq %%mm0, %%mm2\n" "punpcklbw %%mm4, %%mm0\n" "punpckhbw %%mm4, %%mm2\n" "paddw %%mm6, %%mm0\n" "paddw %%mm6, %%mm2\n" "packuswb %%mm2, %%mm0\n" "movq %%mm0, (%1)\n" "leal (%1, %3), %1\n" "loop 1b\n" : /* scr dest */ : "c" (8),"r" (rfp), "r" (bp), "r" (iincr) ); } else { __asm__ __volatile__( "pxor %%mm4, %%mm4\n" ".align 8\n" "1:" "movq (%2), %%mm0\n" /* 8 rfp 0 1 2 3 4 5 6 7*/ "movq (%1), %%mm6\n" /* 4 blockvals 0 1 2 3 */ "movq %%mm0, %%mm2\n" "movq 8(%1), %%mm5\n" /* 4 blockvals 0 1 2 3 */ "punpcklbw %%mm4, %%mm0\n" /* 0 2 4 6 */ "punpckhbw %%mm4, %%mm2\n" /* 1 3 5 7 */ "paddw %%mm6, %%mm0\n" "paddw %%mm5, %%mm2\n" "packuswb %%mm2, %%mm0\n" "addl $16, %1\n" "movq %%mm0, (%2)\n" "leal (%2,%3), %2\n" "loop 1b\n" : /* scr dest */ : "c" (8),"r" (bp), "r" (rfp), "r" (iincr) ); } } else#endif for(i = 0; i < 8; i++) { rfp[0] = CLIP(bp[0] + rfp[0]); rfp[1] = CLIP(bp[1] + rfp[1]); rfp[2] = CLIP(bp[2] + rfp[2]); rfp[3] = CLIP(bp[3] + rfp[3]); rfp[4] = CLIP(bp[4] + rfp[4]); rfp[5] = CLIP(bp[5] + rfp[5]); rfp[6] = CLIP(bp[6] + rfp[6]); rfp[7] = CLIP(bp[7] + rfp[7]); rfp += iincr; bp += 8; } } else {/* libtool PIC causes problems here */#if defined(HAVE_MMX) && !defined(MPEG4IP) if(video->have_mmx) { if(spar) { __asm__ __volatile__( "movd (%2), %%mm0\n" /* " 0 0 0 v1" */ "punpcklwd %%mm0, %%mm0\n" /* " 0 0 v1 v1" */ "punpcklwd %%mm0, %%mm0\n" "paddw MMX_128, %%mm0\n" "packuswb %%mm0, %%mm0\n" "leal (%0,%1,2), %%eax\n" "movq %%mm0, (%0, %1)\n" "movq %%mm0, (%%eax)\n" "leal (%%eax,%1,2), %0\n" "movq %%mm0, (%%eax, %1)\n" "movq %%mm0, (%0)\n" "leal (%0,%1,2), %%eax\n" "movq %%mm0, (%0, %1)\n" "movq %%mm0, (%%eax)\n" "movq %%mm0, (%%eax, %1)\n" : : "D" (rfp), "c" (iincr), "b" (bp) : "eax"); } else { __asm__ __volatile__( "movq MMX_128,%%mm4\n" ".align 8\n" "1:" "movq (%1), %%mm0\n" "movq 8(%1), %%mm1\n" "paddw %%mm4, %%mm0\n" "movq 16(%1), %%mm2\n" "paddw %%mm4, %%mm1\n" "movq 24(%1), %%mm3\n" "paddw %%mm4, %%mm2\n" "packuswb %%mm1, %%mm0\n" "paddw %%mm4, %%mm3\n" "addl $32, %1\n" "packuswb %%mm3, %%mm2\n" "movq %%mm0, (%2)\n" "movq %%mm2, (%2,%3)\n" "leal (%2,%3,2), %2\n" "loop 1b\n" : : "c" (4), "r" (bp), "r" (rfp), "r" (iincr) ); } } else#endif /* HAVE_MMX */ for(i = 0; i < 8; i++) { rfp[0] = CLIP(bp[0] + 128); rfp[1] = CLIP(bp[1] + 128); rfp[2] = CLIP(bp[2] + 128); rfp[3] = CLIP(bp[3] + 128); rfp[4] = CLIP(bp[4] + 128); rfp[5] = CLIP(bp[5] + 128); rfp[6] = CLIP(bp[6] + 128); rfp[7] = CLIP(bp[7] + 128); rfp+= iincr; bp += 8; } } return 0;}int mpeg3_decode_slice(mpeg3_slice_t *slice){ mpeg3video_t *video = slice->video; int comp; int mb_type, cbp, motion_type = 0, dct_type; int macroblock_address, mba_inc, mba_max; int slice_vert_pos_ext; unsigned int code; int bx, by; int dc_dct_pred[3]; int mv_count, mv_format, mvscale; int pmv[2][2][2], mv_field_sel[2][2]; int dmv, dmvector[2]; int qs; int stwtype, stwclass; int snr_cbp; int i; mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;/* number of macroblocks per picture */ mba_max = video->mb_width * video->mb_height;/* field picture has half as many macroblocks as frame */ if(video->pict_struct != FRAME_PICTURE) mba_max >>= 1; /* macroblock address */ macroblock_address = 0; /* first macroblock in slice is not skipped */ mba_inc = 0; slice->fault = 0; code = mpeg3slice_getbits(slice_buffer, 32);/* decode slice header (may change quant_scale) */ slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video);/* reset all DC coefficient and motion vector predictors */ dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; 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; for(i = 0; slice_buffer->current_position < slice_buffer->buffer_size; i++) { if(mba_inc == 0) {/* Done */ if(!mpeg3slice_showbits(slice_buffer, 23)) return 0;/* decode macroblock address increment */ mba_inc = mpeg3video_get_macroblock_address(slice); if(slice->fault) return 1; if(i == 0) {/* Get the macroblock_address */ macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1;/* first macroblock in slice: not skipped */ mba_inc = 1; } } if(slice->fault) return 1; if(macroblock_address >= mba_max) {/* mba_inc points beyond picture dimensions */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -