📄 video_mpeg1.c
字号:
/* Ogle - A video player * Copyright (C) 2000, 2001 Bj鰎n Englund, H錵an Hjort * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * This is core functions that are needed for MPEG-1 decoding. * * It relies on the common functions to parse everything but * the slices level and down. * * The code is a modified and simplified version of the MPEG-2 code. * MPEG-1 can not be interlaced and there are also other extensions * that are only pressent in MPEG-2. Some functions that could have * been shared between MPEG-1 and 2 are not because they have been * simplifid according to what MPEG-1 supports, it should be possible * instead just call the MPEG-2 functions. */ #include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <inttypes.h>#include <signal.h>#include "debug_print.h"#include "video_stream.h"#include "video_types.h"#ifdef HAVE_MLIB#include <mlib_types.h>#include <mlib_status.h>#include <mlib_sys.h>#include <mlib_video.h>#include <mlib_algebra.h>#else#ifdef HAVE_MMX#include "mmx.h"#include "mmx_mlib.h"#else#include "c_mlib.h"#endif#endif#include "common.h"#include "c_getbits.h"#include "video_tables.h"extern yuv_image_t *dst_image;extern void next_start_code(void);extern void exit_program(int exitcode) ATTRIBUTE_NORETURN;#if PRAGMA_NORETURN#pragma does_not_return (exit_program) #endifextern void motion_comp(void);extern void motion_comp_add_coeff(unsigned int i);extern int get_vlc(const vlc_table_t *table, char *func);/* Functions defined within this file: void mpeg1_slice(void); void block_intra(unsigned int); void block_non_intra(unsigned int); void macroblock(void); void macroblock_modes(void); // Could be shared with MPEG2 void coded_block_pattern(void); // Could be shared with MPEG2 void reset_dc_dct_pred(void); // Could be shared with MPEG2 void reset_PMV(); // Could be shared with MPEG2 void reset_vectors(); // Could be shared with MPEG2 void motion_vectors(unsigned int s); // Could be shared with MPEG2 void motion_vector(int r, int s); // Is identical to MPEG2*/staticvoid reset_dc_dct_pred(void){ DPRINTF(3, "Resetting dc_dct_pred\n"); mb.dc_dct_pred[0] = 128; mb.dc_dct_pred[1] = 128; mb.dc_dct_pred[2] = 128;}staticvoid reset_PMV(void){ DPRINTF(3, "Resetting PMV\n"); pic.PMV[0][0][0] = 0; pic.PMV[0][0][1] = 0; pic.PMV[0][1][0] = 0; pic.PMV[0][1][1] = 0;}staticvoid reset_vectors(void){ DPRINTF(3, "Resetting motion vectors\n"); mb.vector[0][0][0] = 0; mb.vector[0][0][1] = 0; mb.vector[0][1][0] = 0; mb.vector[0][1][1] = 0;}/* 6.2.6 Block */staticint block_intra(unsigned int i){ unsigned int dct_dc_size; int dct_diff = 0; unsigned int n; DPRINTF(3, "pattern_code(%d) set\n", i); { /* Reset all coefficients to 0. */ int m; for(m=0; m<16; m++) *(((uint64_t *)mb.QFS) + m) = 0; } /* DC - component */ if(i < 4) { dct_dc_size = get_vlc(table_b12, "dct_dc_size_luminance (b12)"); DPRINTF(4, "luma_size: %d\n", dct_dc_size); } else { dct_dc_size = get_vlc(table_b13, "dct_dc_size_chrominance (b13)"); DPRINTF(4, "chroma_size: %d\n", dct_dc_size); } if(dct_dc_size != 0) { int dct_dc_differential = GETBITS(dct_dc_size, "dct_dc_differential"); int half_range = 1 << (dct_dc_size - 1); if(dct_dc_differential >= half_range) dct_diff = dct_dc_differential; else dct_diff = (dct_dc_differential + 1) - (2 * half_range); } { // qfs is always between 0 and 2^(8+dct_dc_size)-1, i.e unsigned. unsigned int qfs; int cc; /* Table 7-1. Definition of cc, colour component index */ cc = (i>>2) + ((i>>2) & i); qfs = mb.dc_dct_pred[cc] + dct_diff; mb.dc_dct_pred[cc] = qfs; /* inverse quantisation */ { // mb.intra_dc_mult is 8 in MPEG-1 unsigned int f = 8 * qfs; if(f > 2047) f = 2047; mb.QFS[0] = f; n = 1; } } /* AC - components */ while( 1 ) { /* Manually inlined and optimized get_dct(..) */ unsigned int code; const DCTtab *tab; code = nextbits(16); if(code >= 16384) tab = &DCTtabnext[(code >> 12) - 4]; else if(code >= 1024) tab = &DCTtab0[(code >> 8) - 4]; else if(code >= 512) tab = &DCTtab1[(code >> 6) - 8]; else if(code >= 256) tab = &DCTtab2[(code >> 4) - 16]; else if(code >= 128) tab = &DCTtab3[(code >> 3) - 16]; else if(code >= 64) tab = &DCTtab4[(code >> 2) - 16]; else if(code >= 32) tab = &DCTtab5[(code >> 1) - 16]; else if(code >= 16) tab = &DCTtab6[code - 16]; else { fprintf(stderr, "(vlc) invalid huffman code 0x%x in vlc_get_block_coeff() (intra)\n", code); //exit_program(1); return -1; }#if DEBUG if(tab->run < 64 /* VLC_END_OF_BLOCK */) { DPRINTF(4, "coeff run: %d, level: %d\n", tab->run, tab->level); }#endif if (tab->run == 64 /* VLC_END_OF_BLOCK */) { dropbits(2); // tab->len, end of block always = 2 bits break; } else { unsigned int run, val, sgn, i, f; if(tab->run == 65 /* VLC_ESCAPE */) { // dropbits(tab->len); // tab->len, escape always = 6 bits // run = GETBITS(6, "(get_dct escape - run )"); // val = GETBITS(8, "(get_dct escape - level )"); uint32_t tmp = GETBITS(6 + 6 + 8, "(get_dct escape - run & level)" ); val = abs((int8_t)(tmp & 0xff)); run = (tmp >> 8) & 0x3f; sgn = tmp & 0x80; if((tmp & 0x7f) == 0) { // ??? val = GETBITS(8, "(get_dct escape - extended level)"); val = sgn ? (0x100 - val) : val;#if 0 if(val < 128) { fprintf(stderr, "invalid extended dct escape MPEG-1\n"); return -1; }#endif } } else { // dropbits(tab->len); run = tab->run; val = tab->level; sgn = 0x1 & GETBITS(tab->len+1, "(get_dct sign )"); //sign bit } n += run; /* inverse quantisation */ i = inverse_scan[0][n]; f = (2 * val * mb.quantiser_scale * seq.header.intra_inverse_quantiser_matrix[i])/16; if(f > 2047) f = 2047; mb.QFS[i] = sgn ? (-f | 0x1) : -(-f | 0x1); /* Oddification */ n++; } } DPRINTF(4, "nr of coeffs: %d\n", n); return 0;}/* 6.2.6 Block */staticint block_non_intra(unsigned int b){ unsigned int n = 0; DPRINTF(3, "pattern_code(%d) set\n", b); { /* Reset all coefficients to 0. */ int m; for(m=0; m<16; m++) *(((uint64_t *)mb.QFS) + m) = 0; } while(1) { /* Manually inlined and optimized get_dct(..) */ unsigned int code; const DCTtab *tab; code = nextbits(16); if (code>=16384) if(n == 0) tab = &DCTtabfirst[(code>>12)-4]; else tab = &DCTtabnext[(code>>12)-4]; else if(code>=1024) tab = &DCTtab0[(code>>8)-4]; else if(code>=512) tab = &DCTtab1[(code>>6)-8]; else if(code>=256) tab = &DCTtab2[(code>>4)-16]; else if(code>=128) tab = &DCTtab3[(code>>3)-16]; else if(code>=64) tab = &DCTtab4[(code>>2)-16]; else if(code>=32) tab = &DCTtab5[(code>>1)-16]; else if(code>=16) tab = &DCTtab6[code-16]; else { fprintf(stderr, "(vlc) invalid huffman code 0x%x in " "vlc_get_block_coeff() (non intra)\n", code); return -1; } #ifdef DEBUG if(tab->run < 64 /* VLC_END_OF_BLOCK */) { DPRINTF(4, "coeff run: %d, level: %d\n", tab->run, tab->level); }#endif if(tab->run == 64 /* VLC_END_OF_BLOCK */) { dropbits( 2 ); // tab->len, end of block always = 2 bits break; } else { unsigned int run, val, sgn, i, f; if(tab->run == 65 /* VLC_ESCAPE */) { // dropbits(tab->len); // tab->len, escape always = 6 bits // run = GETBITS(6, "(get_dct escape - run )"); // val = GETBITS(8, "(get_dct escape - level )"); uint32_t tmp = GETBITS(6 + 6 + 8, "(get_dct escape - run & level)" ); val = abs((int8_t)(tmp & 0xff)); run = (tmp >> 8) & 0x3f; sgn = tmp & 0x80; if((tmp & 0x7f) == 0) { // ??? val = GETBITS(8, "(get_dct escape - extended level)"); val = sgn ? (0x100 - val) : val;#if 0 if(val < 128) { fprintf(stderr, "invalid extended dct escape MPEG-1\n"); return -1; }#endif } } else { // dropbits(tab->len); run = tab->run; val = tab->level; sgn = 0x1 & GETBITS(tab->len+1, "(get_dct sign )"); //sign bit } n += run; /* inverse scan & quantisation */ i = inverse_scan[0][n]; f = ( (2*val + 1) * mb.quantiser_scale * seq.header.non_intra_inverse_quantiser_matrix[i])/16; if(f > 2047) f = 2047; mb.QFS[i] = sgn ? (-f | 0x1) : -(-f | 0x1); /* Oddification */ n++; } } DPRINTF(4, "nr of coeffs: %d\n", n); return 0;}/* 6.2.5.3 Coded block pattern */staticint coded_block_pattern(void){ DPRINTF(3, "coded_block_pattern\n"); mb.cbp = get_vlc(table_b9, "cbp (b9)"); if(mb.cbp == 0) { fprintf(stderr, "** cbp = 0, shall not be used with 4:2:0 chrominance\n"); //exit_program(-1); return -1; } DPRINTF(4, "cpb = %u\n", mb.cbp); return 0;;}/* 6.2.5.2.1 Motion vector */staticvoid motion_vector(int r, int s){ int t; DPRINTF(2, "motion_vector(%d, %d)\n", r, s); for(t = 0; t < 2; t++) { int delta; int prediction; int vector;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -