⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_mpeg1.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -