📄 frame.c
字号:
/*===========================================================================* * frame.c * * * * basic frame procedures * * * * EXPORTED PROCEDURES: * * Frame_Init * * Frame_Exit * * Frame_New * * Frame_Free * * Frame_AllocBlocks * * Frame_AllocYCC * * Frame_AllocDecoded * * Frame_AllocHalf * * Frame_Resize * * * *===========================================================================*//* * Copyright (c) 1995 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. *//*==============* * HEADER FILES * *==============*/#include "all.h"#include "mtypes.h"#include "frames.h"#include "frame.h"#include "fsize.h"#include "dct.h"/*===========* * CONSTANTS * *===========*//* The maximum number of B-Frames allowed between reference frames. */#define B_FRAME_RUN 16 /*==================* * GLOBAL VARIABLES * *==================*/MpegFrame *frameMemory[B_FRAME_RUN+2];static unsigned int numOfFrames;/*===============================* * INTERNAL PROCEDURE prototypes * *===============================*/static void FreeFrame _ANSI_ARGS_((MpegFrame * mf));static MpegFrame *GetUnusedFrame _ANSI_ARGS_((void));static void ResetFrame _ANSI_ARGS_((int fnumber, int type, MpegFrame *frame));static void Resize_Width _ANSI_ARGS_((MpegFrame *omfrw,MpegFrame *mfrw, int in_x, int in_y, int out_x));static void Resize_Height _ANSI_ARGS_((MpegFrame *omfrh,MpegFrame *mfrh, int in_x, int in_y, int out_y));static void Resize_Array_Width _ANSI_ARGS_((uint8 **inarray,int in_x, int in_y,uint8 **outarray, int out_x));static void Resize_Array_Height _ANSI_ARGS_((uint8 **inarray,int in_x, int in_y,uint8 **outarray, int out_y));/*=====================* * EXPORTED PROCEDURES * *=====================*//*=============================================================== * * Frame_Resize by James Boucher * Boston University Multimedia Communications Lab * * This function takes the mf input frame, read in READFrame(), * and resizes all the input component arrays to the output * dimensions specified in the parameter file as OUT_SIZE. * The new frame is returned with the omf pointer. As well, * the values of Fsize_x and Fsize_y are adjusted. ***************************************************************/void Frame_Resize(omf,mf,insize_x,insize_y,outsize_x,outsize_y) MpegFrame *omf,*mf; int insize_x,insize_y,outsize_x,outsize_y;{MpegFrame *frameA; /* intermediate frame */frameA = (MpegFrame *)malloc(sizeof(MpegFrame));if((insize_x != outsize_x)&&(insize_y != outsize_y)){Resize_Width(frameA,mf,insize_x,insize_y,outsize_x);Resize_Height(omf,frameA,outsize_x,insize_y,outsize_y);}else if((insize_x ==outsize_x)&&(insize_y != outsize_y)){Resize_Height(omf,mf,insize_x,insize_y,outsize_y);} elseif((insize_x !=outsize_x)&&(insize_y == outsize_y)){Resize_Width(omf,mf,insize_x,insize_y,outsize_x);}else{ exit(1); }/* Free memory */free(frameA);free(mf);}/*========================================================* Resize_Width*======================================================*/static void Resize_Width(omfrw,mfrw,in_x,in_y, out_x)MpegFrame *omfrw,*mfrw;int in_x,in_y, out_x;{register int y;int i;omfrw->orig_y = NULL;Fsize_x = out_x;/* Allocate new frame memory */ omfrw->orig_y = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y); ERRCHK(omfrw->orig_y, "malloc"); for (y = 0; y < Fsize_y; y++) { omfrw->orig_y[y] = (uint8 *) malloc(sizeof(uint8) * out_x); ERRCHK(omfrw->orig_y[y], "malloc"); } omfrw->orig_cr = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2); ERRCHK(omfrw->orig_cr, "malloc"); for (y = 0; y < Fsize_y / 2; y++) { omfrw->orig_cr[y] = (uint8 *) malloc(sizeof(int8) * out_x / 2); ERRCHK(omfrw->orig_cr[y], "malloc"); } omfrw->orig_cb = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2); ERRCHK(omfrw->orig_cb, "malloc"); for (y = 0; y < Fsize_y / 2; y++) { omfrw->orig_cb[y] = (uint8 *) malloc(sizeof(int8) * out_x / 2); ERRCHK(omfrw->orig_cb[y], "malloc"); } if ( referenceFrame == ORIGINAL_FRAME ) { omfrw->ref_y = omfrw->orig_y; omfrw->ref_cr = omfrw->orig_cr; omfrw->ref_cb = omfrw->orig_cb; }/* resize each component array separately */Resize_Array_Width(mfrw->orig_y,in_x,in_y,omfrw->orig_y,out_x);Resize_Array_Width(mfrw->orig_cr,(in_x/2),(in_y/2),omfrw->orig_cr,(out_x/2));Resize_Array_Width(mfrw->orig_cb,(in_x/2),(in_y/2),omfrw->orig_cb,(out_x/2));/* Free old frame memory */ if (mfrw->orig_y) { for (i = 0; i < in_y; i++) { free(mfrw->orig_y[i]); } free(mfrw->orig_y); for (i = 0; i < in_y / 2; i++) { free(mfrw->orig_cr[i]); } free(mfrw->orig_cr); for (i = 0; i < in_y / 2; i++) { free(mfrw->orig_cb[i]); } free(mfrw->orig_cb); }}/*=======================================================* Resize_Height** Resize Frame height up or down*=======================================================*/static voidResize_Height(omfrh,mfrh,in_x,in_y,out_y)MpegFrame *omfrh,*mfrh;int in_x,in_y, out_y;{register int y; int i;Fsize_y = out_y;/* Allocate new frame memory */ omfrh->orig_y = (uint8 **) malloc(sizeof(uint8 *) * out_y); ERRCHK(omfrh->orig_y, "malloc"); for (y = 0; y < out_y; y++) { omfrh->orig_y[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x); ERRCHK(omfrh->orig_y[y], "malloc"); } omfrh->orig_cr = (uint8 **) malloc(sizeof(int8 *) * out_y / 2); ERRCHK(omfrh->orig_cr, "malloc"); for (y = 0; y < out_y / 2; y++) { omfrh->orig_cr[y] = (uint8 *) malloc(sizeof(int8) * Fsize_x / 2); ERRCHK(omfrh->orig_cr[y], "malloc"); } omfrh->orig_cb = (uint8 **) malloc(sizeof(int8 *) * out_y / 2); ERRCHK(omfrh->orig_cb, "malloc"); for (y = 0; y < out_y / 2; y++) { omfrh->orig_cb[y] = (uint8 *) malloc(sizeof(int8) * Fsize_x / 2); ERRCHK(omfrh->orig_cb[y], "malloc"); } if ( referenceFrame == ORIGINAL_FRAME ) { omfrh->ref_y = omfrh->orig_y; omfrh->ref_cr = omfrh->orig_cr; omfrh->ref_cb = omfrh->orig_cb; }/* resize component arrays separately */Resize_Array_Height(mfrh->orig_y,in_x,in_y,omfrh->orig_y,out_y);Resize_Array_Height(mfrh->orig_cr,(in_x/2),(in_y/2),omfrh->orig_cr,(out_y/2));Resize_Array_Height(mfrh->orig_cb,(in_x/2),(in_y/2),omfrh->orig_cb,(out_y/2));/* Free old frame memory */ if (mfrh->orig_y) { for (i = 0; i < in_y; i++) { free(mfrh->orig_y[i]); } free(mfrh->orig_y); for (i = 0; i < in_y / 2; i++) { free(mfrh->orig_cr[i]); } free(mfrh->orig_cr); for (i = 0; i < in_y / 2; i++) { free(mfrh->orig_cb[i]); } free(mfrh->orig_cb); }}/*====================================================* Resize_Array_Width* * This function will resize any array width up* or down in size. The algorithm is based on the* least common multiple approach more commonly* used in audio frequency adjustments.*=====================================================*/static void Resize_Array_Width(inarray,in_x,in_y,outarray,out_x)uint8 **inarray;int in_x;int in_y;uint8 **outarray;int out_x;{int i,j; int in_total;int out_total;uint8 *inptr;uint8 *outptr;uint8 pointA,pointB;/* double slope,diff; */ for(i=0;i<in_y;i++){ /* For every row */ inptr = &inarray[i][0]; outptr = &outarray[i][0]; in_total = 0; out_total = 0; for(j=0;j<out_x;j++){ /* For every output value */ if(in_total == out_total){ *outptr = *inptr; outptr++; out_total=out_total+in_x; while(in_total < out_total){ in_total = in_total + out_x; inptr++; } if(in_total > out_total){ in_total = in_total - out_x; inptr--; } } else { pointA = *inptr; inptr++; pointB = *inptr; inptr--;/*Interpolative solution *//* slope = ((double)(pointB -pointA))/((double)(out_x)); diff = (((double)(out_total - in_total))); if(diff < (out_x/2)){ *outptr = (pointA + (uint8)(slope*diff)); } else { *outptr = (pointB - (uint8)(slope*(((float)(out_x)) - diff))); } *//* Non-Interpolative solution */ *outptr = *inptr; outptr++; out_total=out_total+in_x; while(in_total < out_total){ in_total = in_total + out_x; inptr++; } if(in_total > out_total){ in_total = in_total - out_x; inptr--; } } /* end if */ } /* end for each output value */ } /* end for each row */} /* end main *//*==============================* Resize_Array_Height** Resize any array height larger or smaller.* Same as Resize_array_Width except pointer* manipulation must change.*===============================*/static void Resize_Array_Height(inarray,in_x,in_y,outarray,out_y)uint8 **inarray;int in_x;int in_y;uint8 **outarray;int out_y;{int i,j,k; int in_total;int out_total;uint8 pointA,pointB;double slope,diff; for(i=0;i<in_x;i++){ /* for each column */ in_total = 0; out_total = 0; k = 0; for(j=0;j<out_y;j++){ /* for each output value */ if(in_total == out_total){ outarray[j][i] = inarray[k][i]; out_total=out_total+in_y; while(in_total < out_total){ in_total = in_total + out_y; k++; } if(in_total > out_total){ in_total = in_total - out_y; k--; } } else { pointA = inarray[k][i]; if(k != (in_y -1)){ pointB = inarray[k+1][i]; } else { pointB = pointA; }/* Interpolative case */ slope = ((double)(pointB -pointA))/(double)(out_y); diff = (double)(out_total - in_total);/* outarray[j][i] = (inarray[k][i] + (uint8)(slope*diff));*//* Non-Interpolative case */ outarray[j][i] = inarray[k][i]; out_total=out_total+in_y; while(in_total < out_total){ in_total = in_total + out_y; k++; } if(in_total > out_total){ in_total = in_total - out_y; k--; } } } }}/*===========================================================================* * * Frame_Init * * initializes the memory associated with all frames ever * If the input is not coming in from stdin, only 3 frames are needed ; * else, the program must create frames equal to the greatest distance * between two reference frames to hold the B frames while it is parsing * the input from stdin. * * RETURNS: nothing * * SIDE EFFECTS: frameMemory, numOfFrames * *===========================================================================*/voidFrame_Init(unsigned int numOfFramesRequested) { int idx; numOfFrames = numOfFramesRequested; for (idx = 0; idx < numOfFrames; ++idx) { frameMemory[idx] = (MpegFrame *) malloc(sizeof(MpegFrame)); frameMemory[idx]->inUse = FALSE; frameMemory[idx]->orig_y = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -