📄 video.c
字号:
/* video.c *//* This file contains the main routines for decoding MPEG files. *//* * Copyright (c) 1992 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. *//* This file contains C code that implements * the video decoder model. *//************************************************************************* R C S Information**************************************************************************//* $Log: video.c,v $ * Revision 1.6 1994/01/14 15:36:18 daf * *** empty log message *** * * revision 1.4 locked by: daf; * date: 1994/01/11 20:05:03; author: daf; state: Exp; lines: +4 -0 * Modified for PC compatiblity * * revision 1.3 * date: 1994/01/11 14:58:47; author: daf; state: Exp; lines: +2 -10 * Removed exit calls * * revision 1.2 * (date: 1994/01/07 16:35:12; author: daf; state: Exp; lines: +200 -211 * Modified for use as .mex file. * Main decoder call changed to return 1 on EOF. * Main decoder call now increments totNumFrames for each frame read * XWindows calls removed * malloc, free replaced with mxCalloc, mxFree * function headers changed to ANSI C * * revision 1.1 * date: 1994/01/07 16:13:52; author: daf; state: Exp; * Initial revision*/#include <stdio.h>#include <stdlib.h>#include <assert.h>#ifdef WIN32#include <time.h>#else#ifndef MIPS#include <sys/time.h>#else#include <sys/types.h>#include <sys/system.h>#endif#endif /* WIN32 */#include "decoders.h"#include "video.h"#include "util.h"#include "proto.h"#include "mex.h" /* needed for mxCalloc, mxFree, mexErrMsgTxt *//* function prototypes. */static void ReconIMBlock(VidStream *vid_stream, int bnum);static void ReconPMBlock(VidStream *vid_stream, int bnum, int recon_right_for, int recon_down_for, int zflag);static void ReconBMBlock(VidStream *vid_stream, int bnum, int recon_right_back, int recon_down_back, int zflag);static void ReconBiMBlock(VidStream *vid_stream, int bnum, int recon_right_for, int recon_down_for, int recon_right_back, int recon_down_back, int zflag);static void ReconSkippedBlock(unsigned char *source, unsigned char *dest, int row, int col, int row_size, int right, int down, int right_half, int down_half, int width);static void DoPictureDisplay(VidStream *vid_stream);static int ParseSeqHead(VidStream *vid_stream);static int ParseGOP(VidStream *vid_stream);static int ParsePicture(VidStream *vid_stream, TimeStamp time_stamp);static int ParseSlice(VidStream *vid_stream);static int ParseMacroBlock(VidStream *vid_stream);static void ProcessSkippedPFrameMBlocks(VidStream *vid_stream);static void ProcessSkippedBFrameMBlocks(VidStream *vid_stream);extern int ditherType;char *ditherFlags;extern int start_decode;/* global variable holding the current number decoded frames */int totNumFrames = 0;/* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */#define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))/* Declare global pointer to vid stream used for current decoding. */VidStream *curVidStream = NULL;/* Set up array for fast conversion from zig zag order to row/column coordinates.*/int zigzag[64][2] = { 0, 0, 1, 0, 0, 1, 0, 2, 1, 1, 2, 0, 3, 0, 2, 1, 1, 2, 0, 3, 0, 4, 1, 3, 2, 2, 3, 1, 4, 0, 5, 0, 4, 1, 3, 2, 2, 3, 1, 4, 0, 5, 0, 6, 1, 5, 2, 4, 3, 3, 4, 2, 5, 1, 6, 0, 7, 0, 6, 1, 5, 2, 4, 3, 3, 4, 2, 5, 1, 6, 0, 7, 1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6, 2, 7, 1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6, 2, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 5, 7, 6, 6,7, 5, 7, 6, 6, 7, 7, 7};/* Array mapping zigzag to array pointer offset. */int zigzag_direct[64] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};/* Set up array for fast conversion from row/column coordinates to zig zag order.*/int scan[8][8] = { {0, 1, 5, 6, 14, 15, 27, 28}, {2, 4, 7, 13, 16, 26, 29, 42}, {3, 8, 12, 17, 25, 30, 41, 43}, {9, 11, 18, 24, 31, 40, 44, 53}, {10, 19, 23, 32, 39, 45, 52, 54}, {20, 22, 33, 38, 46, 51, 55, 60}, {21, 34, 37, 47, 50, 56, 59, 61},{35, 36, 48, 49, 57, 58, 62, 63}};/* Initialize P and B skip flags. */static int No_P_Flag = 0;static int No_B_Flag = 0;/* Max lum, chrom indices for illegal block checking. */static int lmaxx;static int lmaxy;static int cmaxx;static int cmaxy;/* * We use a lookup table to make sure values stay in the 0..255 range. * Since this is cropping (ie, x = (x < 0)?0:(x>255)?255:x; ), wee call this * table the "crop table". * MAX_NEG_CROP is the maximum neg/pos value we can handle. */#define MAX_NEG_CROP 384#define NUM_CROP_ENTRIES (256+2*MAX_NEG_CROP)#define assertCrop(x) assert(((x) >= -MAX_NEG_CROP) && \ ((x) <= 256+MAX_NEG_CROP))static unsigned char cropTbl[NUM_CROP_ENTRIES];/* The following accounts for time and size spent in various parsing acitivites if ANALYSIS has been defined.*/#ifdef ANALYSISunsigned int bitCount = 0;int showmb_flag = 0;int showEachFlag = 0;typedef struct { int frametype; unsigned int totsize; unsigned int number; unsigned int i_mbsize; unsigned int p_mbsize; unsigned int b_mbsize; unsigned int bi_mbsize; unsigned int i_mbnum; unsigned int p_mbnum; unsigned int b_mbnum; unsigned int bi_mbnum; unsigned int i_mbcbp[64]; unsigned int p_mbcbp[64]; unsigned int b_mbcbp[64]; unsigned int bi_mbcbp[64]; unsigned int i_mbcoeff[64]; unsigned int p_mbcoeff[64]; unsigned int b_mbcoeff[64]; unsigned int bi_mbcoeff[64]; double tottime;} Statval;Statval stat_a[4];unsigned int pictureSizeCount;unsigned int mbSizeCount;unsigned int *mbCBPPtr, *mbCoeffPtr, *mbSizePtr;unsigned int cacheHit[8][8];unsigned int cacheMiss[8][8];static voidinit_stat_struct(Statval *astat){ int j; astat->frametype = 0; astat->totsize = 0; astat->number = 0; astat->i_mbsize = 0; astat->p_mbsize = 0; astat->b_mbsize = 0; astat->bi_mbsize = 0; astat->i_mbnum = 0; astat->p_mbnum = 0; astat->b_mbnum = 0; astat->bi_mbnum = 0; for (j = 0; j < 64; j++) { astat->i_mbcbp[j] = 0; astat->p_mbcbp[j] = 0; astat->b_mbcbp[j] = 0; astat->bi_mbcbp[j] = 0; astat->i_mbcoeff[j] = 0; astat->p_mbcoeff[j] = 0; astat->b_mbcoeff[j] = 0; astat->bi_mbcoeff[j] = 0; } astat->tottime = 0.0;}voidinit_stats(void){ int i, j; for (i = 0; i < 4; i++) { init_stat_struct(&(stat_a[i])); stat_a[i].frametype = i; } for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { cacheHit[i][j] = 0; cacheMiss[i][j] = 0; } } bitCount = 0;}static voidPrintOneStat(void){ int i; printf("\n"); switch (stat_a[0].frametype) { case I_TYPE: printf("I FRAME\n"); break; case P_TYPE: printf("P FRAME\n"); break; case B_TYPE: printf("B FRAME\n"); break; } printf("Size: %d bytes + %d bits\n", stat_a[0].totsize / 8, stat_a[0].totsize % 8); if (stat_a[0].i_mbnum > 0) { printf("\tI Macro Block Stats:\n"); printf("\t%d I Macroblocks\n", stat_a[0].i_mbnum); printf("\tAvg. Size: %d bytes + %d bits\n", stat_a[0].i_mbsize / (8 * stat_a[0].i_mbnum), (stat_a[0].i_mbsize * stat_a[0].i_mbnum) % 8); printf("\t\tCoded Block Pattern Histogram:\n"); for (i = 0; i < 64; i += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcbp[i], stat_a[0].i_mbcbp[i + 1], stat_a[0].i_mbcbp[i + 2], stat_a[0].i_mbcbp[i + 3], stat_a[0].i_mbcbp[i + 4], stat_a[0].i_mbcbp[i + 5], stat_a[0].i_mbcbp[i + 6], stat_a[0].i_mbcbp[i + 7]); } printf("\n\t\tNumber of Coefficients/Block Histogram:\n"); for (i = 0; i < 64; i += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcoeff[i], stat_a[0].i_mbcoeff[i + 1], stat_a[0].i_mbcoeff[i + 2], stat_a[0].i_mbcoeff[i + 3], stat_a[0].i_mbcoeff[i + 4], stat_a[0].i_mbcoeff[i + 5], stat_a[0].i_mbcoeff[i + 6], stat_a[0].i_mbcoeff[i + 7]); } } if (stat_a[0].p_mbnum > 0) { printf("\tP Macro Block Stats:\n"); printf("\t%d P Macroblocks\n", stat_a[0].p_mbnum); printf("\tAvg. Size: %d bytes + %d bits\n", stat_a[0].p_mbsize / (8 * stat_a[0].p_mbnum), (stat_a[0].p_mbsize / stat_a[0].p_mbnum) % 8); printf("\t\tCoded Block Pattern Histogram:\n"); for (i = 0; i < 64; i += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcbp[i], stat_a[0].p_mbcbp[i + 1], stat_a[0].p_mbcbp[i + 2], stat_a[0].p_mbcbp[i + 3], stat_a[0].p_mbcbp[i + 4], stat_a[0].p_mbcbp[i + 5], stat_a[0].p_mbcbp[i + 6], stat_a[0].p_mbcbp[i + 7]); } printf("\n\t\tNumber of Coefficients/Block Histogram:\n"); for (i = 0; i < 64; i += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcoeff[i], stat_a[0].p_mbcoeff[i + 1], stat_a[0].p_mbcoeff[i + 2], stat_a[0].p_mbcoeff[i + 3], stat_a[0].p_mbcoeff[i + 4], stat_a[0].p_mbcoeff[i + 5], stat_a[0].p_mbcoeff[i + 6], stat_a[0].p_mbcoeff[i + 7]); } } if (stat_a[0].b_mbnum > 0) { printf("\tB Macro Block Stats:\n"); printf("\t%d B Macroblocks\n", stat_a[0].b_mbnum); printf("\tAvg. Size: %d bytes + %d bits\n", stat_a[0].b_mbsize / (8 * stat_a[0].b_mbnum), (stat_a[0].b_mbsize / stat_a[0].b_mbnum) % 8); printf("\t\tCoded Block Pattern Histogram:\n"); for (i = 0; i < 64; i += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcbp[i], stat_a[0].b_mbcbp[i + 1], stat_a[0].b_mbcbp[i + 2], stat_a[0].b_mbcbp[i + 3], stat_a[0].b_mbcbp[i + 4], stat_a[0].b_mbcbp[i + 5], stat_a[0].b_mbcbp[i + 6], stat_a[0].b_mbcbp[i + 7]); } printf("\n\t\tNumber of Coefficients/Block Histogram:\n"); for (i = 0; i < 64; i += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcoeff[i], stat_a[0].b_mbcoeff[i + 1], stat_a[0].b_mbcoeff[i + 2], stat_a[0].b_mbcoeff[i + 3], stat_a[0].b_mbcoeff[i + 4], stat_a[0].b_mbcoeff[i + 5], stat_a[0].b_mbcoeff[i + 6], stat_a[0].b_mbcoeff[i + 7]); } } if (stat_a[0].bi_mbnum > 0) { printf("\tBi Macro Block Stats:\n"); printf("\t%d Bi Macroblocks\n", stat_a[0].bi_mbnum); printf("\tAvg. Size: %d bytes + %d bits\n", stat_a[0].bi_mbsize / (8 * stat_a[0].bi_mbnum), (stat_a[0].bi_mbsize * stat_a[0].bi_mbnum) % 8); printf("\t\tCoded Block Pattern Histogram:\n"); for (i = 0; i < 64; i += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcbp[i], stat_a[0].bi_mbcbp[i + 1], stat_a[0].bi_mbcbp[i + 2], stat_a[0].bi_mbcbp[i + 3], stat_a[0].bi_mbcbp[i + 4], stat_a[0].bi_mbcbp[i + 5], stat_a[0].bi_mbcbp[i + 6], stat_a[0].bi_mbcbp[i + 7]); } printf("\n\t\tNumber of Coefficients/Block Histogram:\n"); for (i = 0; i < 64; i += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcoeff[i], stat_a[0].bi_mbcoeff[i + 1], stat_a[0].bi_mbcoeff[i + 2], stat_a[0].bi_mbcoeff[i + 3], stat_a[0].bi_mbcoeff[i + 4], stat_a[0].bi_mbcoeff[i + 5], stat_a[0].bi_mbcoeff[i + 6], stat_a[0].bi_mbcoeff[i + 7]); } } printf("\nTime to Decode: %g secs.\n", stat_a[0].tottime); printf("****************\n");}voidPrintAllStats(void){ int i, j; unsigned int supertot, supernum; double supertime; printf("\n"); printf("General Info: \n"); printf("Width: %d\nHeight: %d\n", curVidStream->mb_width * 16, curVidStream->mb_height * 16); for (i = 1; i < 4; i++) { if (stat_a[i].number == 0) continue; switch (i) { case 1: printf("I FRAMES\n"); break; case 2: printf("P FRAMES\n"); break; case 3: printf("B FRAMES\n"); break; } printf("Number: %d\n", stat_a[i].number); printf("Avg. Size: %d bytes + %d bits\n", stat_a[i].totsize / (8 * stat_a[i].number), (stat_a[i].totsize / stat_a[i].number) % 8); if (stat_a[i].i_mbnum > 0) { printf("\tI Macro Block Stats:\n"); printf("\t%d I Macroblocks\n", stat_a[i].i_mbnum); printf("\tAvg. Size: %d bytes + %d bits\n", stat_a[i].i_mbsize / (8 * stat_a[i].i_mbnum), (stat_a[i].i_mbsize / stat_a[i].i_mbnum) % 8); printf("\t\tCoded Block Pattern Histogram:\n"); for (j = 0; j < 64; j += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcbp[j], stat_a[i].i_mbcbp[j + 1], stat_a[i].i_mbcbp[j + 2], stat_a[i].i_mbcbp[j + 3], stat_a[i].i_mbcbp[j + 4], stat_a[i].i_mbcbp[j + 5], stat_a[i].i_mbcbp[j + 6], stat_a[i].i_mbcbp[j + 7]); } printf("\n\t\tNumber of Coefficients/Block Histogram:\n"); for (j = 0; j < 64; j += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcoeff[j], stat_a[i].i_mbcoeff[j + 1], stat_a[i].i_mbcoeff[j + 2], stat_a[i].i_mbcoeff[j + 3], stat_a[i].i_mbcoeff[j + 4], stat_a[i].i_mbcoeff[j + 5], stat_a[i].i_mbcoeff[j + 6], stat_a[i].i_mbcoeff[j + 7]); } } if (stat_a[i].p_mbnum > 0) { printf("\tP Macro Block Stats:\n"); printf("\t%d P Macroblocks\n", stat_a[i].p_mbnum); printf("\tAvg. Size: %d bytes + %d bits\n", stat_a[i].p_mbsize / (8 * stat_a[i].p_mbnum), (stat_a[i].p_mbsize / stat_a[i].p_mbnum) % 8); printf("\t\tCoded Block Pattern Histogram:\n"); for (j = 0; j < 64; j += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcbp[j], stat_a[i].p_mbcbp[j + 1], stat_a[i].p_mbcbp[j + 2], stat_a[i].p_mbcbp[j + 3], stat_a[i].p_mbcbp[j + 4], stat_a[i].p_mbcbp[j + 5], stat_a[i].p_mbcbp[j + 6], stat_a[i].p_mbcbp[j + 7]); } printf("\n\t\tNumber of Coefficients/Block Histogram:\n"); for (j = 0; j < 64; j += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcoeff[j], stat_a[i].p_mbcoeff[j + 1], stat_a[i].p_mbcoeff[j + 2], stat_a[i].p_mbcoeff[j + 3], stat_a[i].p_mbcoeff[j + 4], stat_a[i].p_mbcoeff[j + 5], stat_a[i].p_mbcoeff[j + 6], stat_a[i].p_mbcoeff[j + 7]); } } if (stat_a[i].b_mbnum > 0) { printf("\tB Macro Block Stats:\n"); printf("\t%d B Macroblocks\n", stat_a[i].b_mbnum); printf("\tAvg. Size: %d bytes + %d bits\n", stat_a[i].b_mbsize / (8 * stat_a[i].b_mbnum), (stat_a[i].b_mbsize * stat_a[i].b_mbnum) % 8); printf("\t\tCoded Block Pattern Histogram:\n"); for (j = 0; j < 64; j += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcbp[j], stat_a[i].b_mbcbp[j + 1], stat_a[i].b_mbcbp[j + 2], stat_a[i].b_mbcbp[j + 3], stat_a[i].b_mbcbp[j + 4], stat_a[i].b_mbcbp[j + 5], stat_a[i].b_mbcbp[j + 6], stat_a[i].b_mbcbp[j + 7]); } printf("\n\t\tNumber of Coefficients/Block Histogram:\n"); for (j = 0; j < 64; j += 8) { printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcoeff[j], stat_a[i].b_mbcoeff[j + 1], stat_a[i].b_mbcoeff[j + 2], stat_a[i].b_mbcoeff[j + 3], stat_a[i].b_mbcoeff[j + 4], stat_a[i].b_mbcoeff[j + 5], stat_a[i].b_mbcoeff[j + 6], stat_a[i].b_mbcoeff[j + 7]); } } if (stat_a[i].bi_mbnum > 0) { printf("\tBi Macro Block Stats:\n"); printf("\t%d Bi Macroblocks\n", stat_a[i].bi_mbnum); printf("\tAvg. Size: %d bytes + %d bits\n", stat_a[i].bi_mbsize / (8 * stat_a[i].bi_mbnum),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -