www.pudn.com > jm50g.zip > fmo.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2001, International Telecommunications Union, Geneva * * DISCLAIMER OF WARRANTY * * These software programs are available to the user without any * license fee or royalty on an "as is" basis. The ITU disclaims * any and all warranties, whether express, implied, or * statutory, including any implied warranties of merchantability * or of fitness for a particular purpose. In no event shall the * contributor or the ITU 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 ITU does not represent or warrant that the programs furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of ITU-T Recommendations, including * shareware, may be subject to royalty fees to patent holders. * Information regarding the ITU-T patent policy is available from * the ITU Web site at http://www.itu.int. * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY. ************************************************************************ */ /*! ***************************************************************************** * * \file scatter.c * * \brief * Support for Flexible Macroblock Ordering (FMO) * * \date * 19 June, 2002 * * \author * Stephan Wenger stewe@cs.tu-berlin.de *****************************************************************************/ #include#include #include #include #include #include #include "global.h" #include "elements.h" #include "defines.h" #include "header.h" #include "fmo.h" int *MBAmap; static int PictureXSize, PictureYSize, PictureSizeInMBs; static int NumberOfSliceGroups; // the number of slice groups -1 (0 == scan order, 7 == maximum) // JVT-D095, JVT-D097 static int FmoGenerateType3MBAmap (struct img_par *img, struct inp_par *inp, int NumSliceGroups, int XSize, int YSize, int *MBAmap); static int FmoBoxoutCounterClockwise (struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap); static int FmoBoxoutClockwise (struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap); static int FmoRasterScan(struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap); static int FmoInverseRasterScan(struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap); static int FmoWipeRight(struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap); static int FmoWipeLeft(struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap); // End JVT-D095, JVT-D097 /*! ************************************************************************ * \brief * FmoInit: Initializes (called always when a Parameter Set with a * new MBAmap is used). Current simplification: we have only one * ParameterSet, hence it is sufficient to run this function whenever * a new PUP is received. this needs to be fixed when using multiple * Parameter Sets (including a consistsency check that the MBAmap * stays identical within a picture) * * \par Input: * xs, ys: size of picture (in MBs, 11, 9 for QCIF) * pattern: scatter pattern, or NULL for default pattern * ************************************************************************ */ int FmoInit (struct img_par *img, struct inp_par *inp, int xs, int ys, int NewMBAmap[], int SizeOfNewMBAmap) { int i, FmoMode; NumberOfSliceGroups = 0; PictureXSize = xs; PictureYSize = ys; PictureSizeInMBs = xs*ys; // printf ("In FMOInit\n"); if (MBAmap != NULL) free (MBAmap); if ((MBAmap = malloc (PictureSizeInMBs * sizeof (int))) == NULL) { printf ("cannot allocated %d bytes for MBAmap, exit\n", PictureSizeInMBs * sizeof (int)); exit (-1); } if (NewMBAmap == NULL || SizeOfNewMBAmap == 0) // no new MBAmap ->default MBAmap { memset (MBAmap, 0, PictureSizeInMBs * sizeof (int)); return 0; } for (i=0; i NumberOfSliceGroups) NumberOfSliceGroups = MBAmap[i]; } // JVT-D095, JVT-D097 NumberOfSliceGroups = img->num_slice_groups_minus1; FmoMode = img->mb_allocation_map_type; if (NumberOfSliceGroups && FmoMode >= 3) { switch (FmoMode) { case 3: FmoGenerateType3MBAmap (img, inp, NumberOfSliceGroups, xs, ys, MBAmap); break; case 4: case 5: case 6: assert(NumberOfSliceGroups == 1); //FmoInitEvolvingMBAmap (img, inp, FmoMode, PictureXSize, PictureYSize, MBAmap); // need to be updated before coding of each picture break; default: printf ("Illegal FmoMode %d , exit \n", FmoMode); exit (-1); } } // End JVT-D095, JVT-D097 /* printf ("FmoInit: Using MBAmap as follows\n"); for (y=0;y =0; i--) if (FmoMB2Slice (i) == SliceGroup) return i; return -1; }; /*! ************************************************************************ * \brief * FmoMB2Slice: Returns SliceGroupID for a given MB * * \par Input: * Macroblock Nr (in scan order) ************************************************************************ */ int FmoMB2Slice (int mb) { assert (mb < PictureSizeInMBs); assert (MBAmap != NULL); return MBAmap[mb]; } /*! ************************************************************************ * \brief * FmoGetNextMBBr: Returns the MB-Nr (in scan order) of the next * MB in the (scattered) Slice, -1 if the slice is finished * * \par Input: * CurrentMbNumber ************************************************************************ */ int FmoGetNextMBNr (int CurrentMbNr, int structure) { int SliceGroup = FmoMB2Slice (CurrentMbNr); // KS: dirty hack for interlace int PictureSize = PictureSize = (structure?(structure == 3 ? PictureSizeInMBs:PictureSizeInMBs/2):PictureSizeInMBs); while (++CurrentMbNr = PictureSize) return -1; // No further MB in this slice (could be end of picture) else return CurrentMbNr; } // JVT-D095 int FmoGenerateType3MBAmap (struct img_par *img, struct inp_par *inp, int NumSliceGroups, int XSize, int YSize, int *MBAmap) { int x, y, xx; int n = XSize; // Number of columns int p = NumSliceGroups+1; // Number of Slice Groups int rx0, rx1, ry0, ry1; // coordinates of the rectangule assert (NumSliceGroups == 1); rx0 = img->top_left_mb%n; ry0 = img->top_left_mb/n; rx1 = img->bottom_right_mb%n; ry1 = img->bottom_right_mb/n; for (y=0; y = rx0 && x <= rx1 && y >= ry0 && y<= ry1) // within the rectangular slice group MBAmap[xx] = 0; else MBAmap[xx] = 1; } return 0; } // End JVT-D095 // JVT-D097 int FmoUpdateEvolvingMBAmap (struct img_par *img, struct inp_par *inp, int *MBAmap) { int FmoMode = img->mb_allocation_map_type; int XSize = img->width/16; int YSize = img->height/16; int i; for (i=0; i slice_group_change_direction == 0) FmoBoxoutClockwise (img, inp, XSize, YSize, MBAmap); else FmoBoxoutCounterClockwise (img, inp, XSize, YSize, MBAmap); break; case 5: if(img->slice_group_change_direction == 0) FmoRasterScan (img, inp, XSize, YSize, MBAmap); else FmoInverseRasterScan (img, inp, XSize, YSize, MBAmap); break; case 6: if(img->slice_group_change_direction == 0) FmoWipeRight (img, inp, XSize, YSize, MBAmap); else FmoWipeLeft (img, inp, XSize, YSize, MBAmap); break; } /* { int xx, yy; for (yy=0;yy slice_group_change_cycle+1) * (img->slice_group_change_rate_minus1+1); for(i=0; i 0) y--; else if(x > 0) { y = YSize-1; x--; } else break; } return 0; } int FmoWipeRight(struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap) { int i, x, y, n; x = 0; y = 0; n = (img->slice_group_change_cycle+1) * (img->slice_group_change_rate_minus1+1); for(i=0; i slice_group_change_cycle+1) * (img->slice_group_change_rate_minus1+1); nextMBnum = y * XSize + x; for(i=0; i slice_group_change_cycle+1) * (img->slice_group_change_rate_minus1+1); nextMBnum = y * XSize + x; for(i=0; i = XSize*YSize ) break; } return 0; } int FmoBoxoutCounterClockwise (struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap) { int i, n; int W = XSize, H = YSize; int x = ( XSize - 1 ) / 2; int y = ( YSize - 1) / 2; int directx = 0; int directy = 1; int left = x; int right = x; int top = y; int bottom = y; n = (img->slice_group_change_cycle+1) * (img->slice_group_change_rate_minus1+1); for(i=0; i left) x--; else if (x == 0) { y = bottom + 1; bottom++; directx = 1; directy = 0; } else if (x == left) { x--; left--; directx = 0; directy = 1; } } else if ( directx == 1 && directy == 0 ) { if (x < right) x++; else if (x == W - 1) { y = top - 1; top--; directx = -1; directy = 0; } else if (x == right) { x++; right++; directx = 0; directy = -1; } } else if ( directx == 0 && directy == -1 ) { if ( y > top) y--; else if (y == 0) { x = left - 1; left--; directx = 0; directy = 1; } else if (y == top) { y--; top--; directx = -1; directy = 0; } } else if ( directx == 0 && directy == 1 ) { if (y < bottom) y++; else if (y == H - 1) { x = right+1; right++; directx = 0; directy = -1; } else if (y == bottom) { y++; bottom++; directx = 1; directy = 0; } } // check whether passed already the last MB in the evolving period if( !(left >= 0 && right < W && top >= 0 && bottom < H) ) break; } return 0; } int FmoBoxoutClockwise (struct img_par *img, struct inp_par *inp, int XSize, int YSize, int *MBAmap) { int i, n; int W = XSize, H = YSize; int x = XSize / 2; int y = YSize / 2; int directx = -1; int directy = 0; int left = x; int right = x; int top = y; int bottom = y; n = (img->slice_group_change_cycle+1) * (img->slice_group_change_rate_minus1+1); for(i=0; i left) x--; else if (x == 0) { y = top - 1; top--; directx = 1; directy = 0; } else if (x == left) { x--; left--; directx = 0; directy = -1; } } else if ( directx == 1 && directy == 0 ) { if (x < right) x++; else if (x == W - 1) { y = bottom + 1; bottom++; directx = -1; directy = 0; } else if (x == right) { x++; right++; directx = 0; directy = 1; } } else if ( directx == 0 && directy == -1 ) { if ( y > top) y--; else if (y == 0) { x = right + 1; right++; directx = 0; directy = 1; } else if (y == top) { y--; top--; directx = 1; directy = 0; } } else if ( directx == 0 && directy == 1 ) { if (y < bottom) y++; else if (y == H - 1) { x = left - 1; left--; directx = 0; directy = -1; } else if (y == bottom) { y++; bottom++; directx = -1; directy = 0; } } // check whether passed already the last MB in the evolving period if( !(left >= 0 && right < W && top >= 0 && bottom < H) ) break; } return 0; } // End JVT-D097 #if 0 /*! ************************************************************************ * \brief * ScatterGetFirstMBOfSlice: Returns the MB-Nr (in scan order) of the * next first MB of the scattered Slice, -1 if no such slice is exists * * \par Input: * SliceID: Id of Slice ************************************************************************ */ int ScatterGetFirstMBOfSlice (int SliceID, int structure) { int i = 0; // KS: dirty hack for interlace int PictureSize = PictureSize = (structure?(structure == 3 ? PictureSizeInMBs:PictureSizeInMBs/2):PictureSizeInMBs);; while ((i = 0) * -1 if the slice doesn't exist * -2 if last MB is unknown (not yet used) ************************************************************************ */ int ScatterGetLastCodedMBOfSlice (int SliceID, int structure) { int i; int LastMB = -1; // KS: dirty hack for interlace int PictureSize = PictureSize = (structure?(structure == 3 ? PictureSizeInMBs:PictureSizeInMBs/2):PictureSizeInMBs);; for (i=0; i