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

📄 getpic.c

📁 H.263的压缩算法
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************************ * *  getpic.c, picture decoding for tmndecode (H.263 decoder) *  Copyright (C) 1995, 1996  Telenor R&D, Norway * *  Contacts: *  Robert Danielsen                  <Robert.Danielsen@nta.no> * *  Telenor Research and Development  http://www.nta.no/brukere/DVC/ *  P.O.Box 83                        tel.:   +47 63 84 84 00 *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76 * *  Copyright (C) 1997  University of BC, Canada *  Modified by: Mike Gallant <mikeg@ee.ubc.ca> *               Guy Cote <guyc@ee.ubc.ca> *               Berna Erol <bernae@ee.ubc.ca> * *  Contacts: *  Micheal Gallant                   <mikeg@ee.ubc.ca> * *  UBC Image Processing Laboratory   http://www.ee.ubc.ca/image *  2356 Main Mall                    tel.: +1 604 822 4051 *  Vancouver BC Canada V6T1Z4        fax.: +1 604 822 5949 * ************************************************************************//* Disclaimer of Warranty *  * These software programs are available to the user without any license fee * or royalty on an "as is" basis. The University of British Columbia * disclaims any and all warranties, whether express, implied, or * statuary, including any implied warranties or merchantability or of * fitness for a particular purpose.  In no event shall the * copyright-holder be liable for any incidental, punitive, or * consequential damages of any kind whatsoever arising from the use of * these programs. *  * This disclaimer of warranty extends to the user of these programs and * user's customers, employees, agents, transferees, successors, and * assigns. *  * The University of British Columbia does not represent or warrant that the * programs furnished hereunder are free of infringement of any * third-party patents. *  * Commercial implementations of H.263, including shareware, are subject to * royalty fees to patent holders.  Many of these patents are general * enough such that they are unavoidable regardless of implementation * design. *  *//* modified to support annex O true B frames, mikeg@ee.ubc.ca *  * modified by Wayne Ellis BT Labs to run Annex E Arithmetic Decoding * <ellis_w_wayne@bt-web.bt.co.uk> *  * based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de> */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "config.h"#include "tmndec.h"#include "global.h"#include "indices.h"#include "sactbls.h"static int coded_map[MBR + 1][MBC + 1];static int quant_map[MBR + 1][MBC + 1];static int STRENGTH[] = {1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12};static int STRENGTH1[] = {1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};static int STRENGTH2[] = {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};/* private prototypes */static void get_I_P_MBs _ANSI_ARGS_ ((int framenum, int gob));static void get_B_MBs _ANSI_ARGS_ ((int framenum));static void get_EI_EP_MBs _ANSI_ARGS_ ((int framenum));static void clearblock _ANSI_ARGS_ ((int comp));static int motion_decode _ANSI_ARGS_ ((int vec, int pmv));static int find_pmv _ANSI_ARGS_ ((int x, int y, int block, int comp));static void addblock _ANSI_ARGS_ ((int comp, int bx, int by, int addflag));static void reconblock_b _ANSI_ARGS_ ((int comp, int bx, int by, int mode, int bdx, int bdy));static void find_bidir_limits _ANSI_ARGS_ ((int vec, int *start, int *stop, int nhv));static void find_bidir_chroma_limits _ANSI_ARGS_ ((int vec, int *start, int *stop));static void make_edge_image _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst, int width, int height, int edge));static void init_enhancement_layer _ANSI_ARGS_((int layer));void edge_filter _ANSI_ARGS_ ((unsigned char *lum, unsigned char *Cb, unsigned char *Cr, int width, int height));void horiz_edge_filter _ANSI_ARGS_ ((unsigned char *rec, int width, int height, int chr));void vert_edge_filter _ANSI_ARGS_ ((unsigned char *rec, int width, int height, int chr));void vert_post_filter (unsigned char *rec, int width, int height, int chr);void horiz_post_filter (unsigned char *rec, int width, int height, int chr);void PostFilter (unsigned char *lum, unsigned char *Cb, unsigned char *Cr, int width, int height);/* reference picture selection */int  get_reference_picture(void);void store_picture(int);/* error concealment */void conceal_missing_gobs(int start_mb_row_missing, int number_of_mb_rows_missing);/********************************************************************** * *      Name:         getpicture *      Description:  decode and display one picture  *      Input:        frame number *      Returns:       *      Side effects:  * *  Date: 971102  Author: mikeg@ee.ubc.ca * * ***********************************************************************/void getpicture (int *framenum, int gob){  unsigned char *tmp;  int            i, store_pb, quality=0;  static int absolute_temp_ref = 0;  static int prev_temp_ref = 0;  switch (pict_type)  {    case PCT_INTRA:    case PCT_INTER:    case PCT_PB:    case PCT_IPB:      enhance_pict = NO;      if (0 == UFEP && plus_type)       {        mv_outside_frame = prev_mv_outside_frame;        deblocking_filter_mode = prev_df;        adv_pred_mode = prev_adv_pred;        overlapping_MC = prev_obmc;        use_4mv = prev_4mv;        long_vectors = prev_long_vectors;        syntax_arith_coding = prev_sac;        advanced_intra_coding = prev_aic;          slice_structured_mode = prev_slice_struct;          reference_picture_selection_mode = prev_rps;          independently_segmented_decoding_mode = prev_isd;        alternative_inter_VLC_mode = prev_aivlc;        modified_quantization_mode = prev_mq;      }      for (i = 0; i < 3; i++)      {        tmp = prev_frame[i];        prev_I_P_frame[i] = prev_frame[i] = next_I_P_frame[i];        next_I_P_frame[i] = current_frame[i] = tmp;      }      /* if the picture header is missing, assume temp_ref increments */      /* not done yet*/            /* Annex N: get the correct reference picture for prediction */       if (reference_picture_selection_mode)      {        if (-1 == (quality = get_reference_picture()))          break;        if (quality > 256)         {          fprintf(stderr,"completely out of sync -- waiting for I-frame\n");          stop_decoder = 1;          break;        }      }#ifdef DEBUG      if (temp_ref < prev_temp_ref) prev_temp_ref -= 256;      absolute_temp_ref += temp_ref - prev_temp_ref;      prev_temp_ref = temp_ref;      fprintf(stdout, "%d\n", absolute_temp_ref);#endif      if ((mv_outside_frame) && (*framenum > 0))      {        make_edge_image (prev_I_P_frame[0], edgeframe[0], coded_picture_width,                         coded_picture_height, 32);        make_edge_image (prev_I_P_frame[1], edgeframe[1], chrom_width, chrom_height, 16);        make_edge_image (prev_I_P_frame[2], edgeframe[2], chrom_width, chrom_height, 16);      }      get_I_P_MBs (*framenum, gob);      store_pb = pb_frame;      pb_frame = 0;      if (deblocking_filter_mode)        edge_filter (current_frame[0], current_frame[1], current_frame[2],                     coded_picture_width, coded_picture_height);           pb_frame = store_pb;       if (pb_frame)       {         if (deblocking_filter_mode)          edge_filter(bframe[0],bframe[1],bframe[2],                      coded_picture_width,coded_picture_height);       }      PictureDisplay(framenum);            if (reference_picture_selection_mode)        store_picture((pict_type == PCT_INTRA) ? 0 : quality);            if (1 == UFEP)      {        prev_mv_outside_frame = mv_outside_frame;        prev_sac = syntax_arith_coding;        prev_adv_pred = adv_pred_mode;        prev_aic = advanced_intra_coding;        prev_df = deblocking_filter_mode;        prev_slice_struct = slice_structured_mode;        prev_rps = reference_picture_selection_mode;        prev_isd = independently_segmented_decoding_mode;        prev_aivlc = alternative_inter_VLC_mode;        prev_mq = modified_quantization_mode;        prev_long_vectors = long_vectors;        prev_obmc = overlapping_MC;        prev_4mv = use_4mv;      }      break;    case PCT_B:      if (enhancement_layer_num > 1)        enhance_pict = YES;      else        enhance_pict = NO;      for (i = 0; i < 3; i++)      {        current_frame[i] = bframe[i];      }      /* Forward prediction */      make_edge_image (prev_I_P_frame[0], edgeframe[0], coded_picture_width,                       coded_picture_height, 32);      make_edge_image (prev_I_P_frame[1], edgeframe[1], chrom_width, chrom_height, 16);      make_edge_image (prev_I_P_frame[2], edgeframe[2], chrom_width, chrom_height, 16);            /* Backward prediction */      make_edge_image (next_I_P_frame[0], nextedgeframe[0], coded_picture_width,                       coded_picture_height, 32);      make_edge_image (next_I_P_frame[1], nextedgeframe[1], chrom_width, chrom_height, 16);      make_edge_image (next_I_P_frame[2], nextedgeframe[2], chrom_width, chrom_height, 16);        get_B_MBs (*framenum);      PictureDisplay(framenum);      break;    case PCT_EI:    case PCT_EP:      enhance_pict = YES;      if (!enhancement_layer_init[enhancement_layer_num-2])      {        init_enhancement_layer(enhancement_layer_num-2);        enhancement_layer_init[enhancement_layer_num-2] = ON;      }      for (i = 0; i < 3; i++)      {        tmp = prev_enhancement_frame[enhancement_layer_num-2][i];        prev_enhancement_frame[enhancement_layer_num-2][i] =           current_enhancement_frame[enhancement_layer_num-2][i];        current_enhancement_frame[enhancement_layer_num-2][i] = tmp;      }      if (scalability_mode >= 3)      {        UpsampleReferenceLayerPicture();        curr_reference_frame[0] = upsampled_reference_frame[0];        curr_reference_frame[1] = upsampled_reference_frame[1];        curr_reference_frame[2] = upsampled_reference_frame[2];      }      else      {        curr_reference_frame[0] = current_frame[0];        curr_reference_frame[1] = current_frame[1];        curr_reference_frame[2] = current_frame[2];      }      make_edge_image (prev_enhancement_frame[enhancement_layer_num-2][0],                        enhance_edgeframe[enhancement_layer_num-2][0],                        coded_picture_width, coded_picture_height, 32);      make_edge_image (prev_enhancement_frame[enhancement_layer_num-2][1],                        enhance_edgeframe[enhancement_layer_num-2][1],                        chrom_width, chrom_height, 16);      make_edge_image (prev_enhancement_frame[enhancement_layer_num-2][2],                        enhance_edgeframe[enhancement_layer_num-2][2],                        chrom_width, chrom_height, 16);        get_EI_EP_MBs (*framenum);      if (deblocking_filter_mode)        edge_filter (current_enhancement_frame[enhancement_layer_num-2][0],                      current_enhancement_frame[enhancement_layer_num-2][1],                      current_enhancement_frame[enhancement_layer_num-2][2],                      coded_picture_width, coded_picture_height);      store_one (enhance_recon_file_name[enhancement_layer_num-2],                  current_enhancement_frame[enhancement_layer_num-2],                  0, coded_picture_width, vertical_size);        break;    default:      break;  }}/* decode all macroblocks of the current picture */static int change_of_quant_tab_10[32] = {0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3};static int change_of_quant_tab_11[32] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, -5};static void get_I_P_MBs (int framenum, int gob){  int comp;  int MBA, MBAmax;  int bx, by;  int COD = 0, MCBPC, CBPY, CBP = 0, CBPB = 0, MODB = 0, Mode = 0, DQUANT;  int COD_index, CBPY_index, MODB_index, DQUANT_index, MCBPC_index;  int INTRADC_index, YCBPB_index, UVCBPB_index, mvdbx_index, mvdby_index;  int mvx = 0, mvy = 0, mvy_index, mvx_index, pmv0, pmv1, xpos, ypos, i, k;  int mvdbx = 0, mvdby = 0, pmvdbx, pmvdby, YCBPB, UVCBPB, gobheader_read;  int startmv, stopmv, offset, bsize, last_done = 0, pCBP = 0, pCBPB = 0, pCOD = 0, pMODB = 0;  int DQ_tab[4] = {-1, -2, 1, 2};  short *bp;  int long_vectors_bak;  int tmp = 0;  int pnewgob = 0;  /* Error concealment variables */  int pypos = 0;  int start_mb_row_missing, number_of_mb_rows_missing;  /* variables used in advanced intra coding mode */  int INTRA_AC_DC = 0, INTRA_AC_DC_index;  short *store_qcoeff;  int quality=0;  int decode_last_mb = 0;  int dont_reconstruct_next_mb;  /* number of macroblocks per picture */  MBAmax = mb_width * mb_height;  gob -= 1; /* 1 was added in getheader() */  MBA = 0;                      /* macroblock address */  newgob = 0;  xpos = ypos = 0;  /* mark MV's above the picture */  for (i = 1; i < mb_width + 1; i++)  {    for (k = 0; k < 5; k++)    {      MV[0][k][0][i] = NO_VEC;      MV[1][k][0][i] = NO_VEC;    }    modemap[0][i] = MODE_INTRA;  }  /* zero MV's on the sides of the picture */  for (i = 0; i < mb_height + 1; i++)  {    for (k = 0; k < 5; k++)    {      MV[0][k][i][0] = 0;      MV[1][k][i][0] = 0;      MV[0][k][i][mb_width + 1] = 0;      MV[1][k][i][mb_width + 1] = 0;    }    modemap[i][0] = MODE_INTRA;    modemap[i][mb_width + 1] = MODE_INTRA;  }  /* initialize the qcoeff used in advanced intra coding */  if (advanced_intra_coding)  {    /* store the qcoeff for the frame */    if ((store_qcoeff = (short *) calloc (64 * MBAmax * blk_cnt, sizeof (short))) == 0)    {      fprintf (stderr, "getMB(): Couldn't allocate store_qcoeff.\n");      exit (-1);    }  }  fault = 0;  gobheader_read = 0;  /* if a gob with GN != 0 was present as the first gob   * of a picture, decode the rest of the gob header */  if (gob) goto getgobhrd;  for (;;)  {    if (MBA >= MBAmax)    {      /* all macroblocks decoded */      memcpy(anchorframemodemap,modemap,(sizeof(int)*(MBR+1)*(MBC+2)) );      return;    }    if (trace)      fprintf (trace_file, "frame %d, MB %d\n", framenum, MBA);resync:    /* This version of the decoder does not resync on every possible     * error, and it does not do all possible error checks. It is not     * difficult to make it much more error robust, but I do not think it     * is necessary to include this in the freely available version. */       if (fault)    {      printf ("Warning: A Fault Condition Has Occurred - Resyncing \n");      startcode ();             /* sync on new startcode */      fault = 0;    }    if (!(showbits (22) >> 6))    {      /* startcode */      startcode ();      /* in case of byte aligned start code, ie. PSTUF, GSTUF or ESTUF is       * used */      if (showbits (22) == (32 | SE_CODE))      {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -