Especificação



Baixar 2,81 Mb.
Página17/24
Encontro01.07.2018
Tamanho2,81 Mb.
1   ...   13   14   15   16   17   18   19   20   ...   24

A9 Classes para controle dos macroblocos vizinhos




      1. A9.1 Classe MacroblockAccess



package br.ufsc.inf.guiga.media.codec.video.h264.vcl.macroblock;
import java.awt.Point;
import br.ufsc.inf.guiga.media.codec.video.h264.vcl.Macroblock;
/**

* Macroblock Neighbours Access.

*

* This class provides facilities to access the macroblock neighbours.

*

* @author Guilherme Ferreira



*/

public abstract class MacroblockAccess {
protected Macroblock macroblockX; // current macroblock

protected Macroblock macroblockA; // left

protected Macroblock macroblockB; // upper

protected Macroblock macroblockC; // upper-right

protected Macroblock macroblockD; // upper-left
protected int mbNr;

protected int frameWidth;

protected int picWidthInMbs;

protected int picSizeInMbs;
/**

* @param macroblockX the {@link Macroblock} owner of this {@link MacroblockAccess}.

*/

public MacroblockAccess(Macroblock macroblock) {

this.macroblockX = macroblock;
mbNr = macroblockX.getMbNr();

frameWidth = macroblockX.getSlice().getPicture().getWidth();

picWidthInMbs = frameWidth / Macroblock.MB_WIDTH;

picSizeInMbs = macroblockX.getSlice().getPicture().getPicSizeInMbs();

}
/**

* Checks the availability of neighboring macroblocks of the current macroblock for

* prediction and context determination.

*/

public abstract void checkAvailableNeighbours();


/**

* Gets the absolute frame pixel point from the macroblock relative point (xN, yN).

*

* @param xN input x position. The macroblock relative x coordinate within the interval



* [-1..15].

* @param yN input y position. The macroblock relative y coordinate within the interval

* [-1..15].

* @param maxW the block pixel width.

* @param maxH the block pixel height.

* @param p the {@link Point} where the absolute (x, y) coordinates will return.

* @return true if the {@link Point} was successfully filled with the

* absolute pixel coordinates, or false if there are no valid

* neighbours at the specified (xN, yN) coordinates.

*/

public abstract boolean getNeighbour(int xN, int yN, int maxW, int maxH, Point p);


/**

* Checks out if there are maxW pixels above this macroblock available for prediction.

*

* @param maxW the amount of pixels to check for availability.



* @return true if maxW pixels above this macroblock are available for

* prediction, or false otherwise.

*/

public boolean isUpAvailable(int maxW) {

Point p = new Point();



int maxH = 0;
return getNeighbour(0, -1, maxW, maxH, p);

}
/**

* Checks out if there are maxH pixels available for prediction on the left side of this

* macroblock.

*

* @param maxH the amount of pixels to check for availability



* @return true if maxW pixels on the left of this macroblock are available

* for prediction, or false otherwise.

*/

public boolean isLeftAvailable(int maxH) {

Point p = new Point();



int maxW = 0;
return getNeighbour(-1, 0, maxW, maxH, p);

}
/**

* Checks out if the pixel on the left upper corner of this macroblock available for

* prediction.

*

* @return true if the pixel on the left upper corner of this macroblock are



* available for prediction, or false otherwise.

*/

public boolean isLeftUpAvailable() {

Point p = new Point();

int maxW = 0;

int maxH = 0;

return getNeighbour(-1, -1, maxW, maxH, p);

}
/**

* Gets the {@link Macroblock} with the given number.

*

* @param mbNr



* @return the {@link Macroblock} with the given number or null if its not

* available.

*/

public Macroblock getMacroblock(int mbNr) {

if ((mbNr < 0) || (mbNr > (picSizeInMbs - 1)))

return null;
return macroblockX.getSlice().getMacroblocks().get(mbNr);

}
/**

* Gets the column number where lies the given macroblock number.

*

* @param mbNr



* @return the column this macroblock number belongs.

*/

public int column(int mbNr) {



return (mbNr % picWidthInMbs);

}
/**

* Gets the line number where lies the given macroblock number.

*

* @param mbNr



* @return the line this macroblock number belongs.

*/

public int line(int mbNr) {



return (mbNr / picWidthInMbs);

}
/**

* @return the {@link Macroblock} on the left side of this one.

*/

public Macroblock getMacroblockA() {



return macroblockA;

}
/**

* @return the {@link Macroblock} above this one, the upper side one.

*/

public Macroblock getMacroblockB() {



return macroblockB;

}
/**

* @return the upper-right {@link Macroblock}.

*/

public Macroblock getMacroblockC() {



return macroblockC;

}
/**

* @return the upper-left {@link Macroblock}.

*/

public Macroblock getMacroblockD() {



return macroblockD;

}
}



      1. A9.2 Classe MacroblockAccessNonMBAFF



package br.ufsc.inf.guiga.media.codec.video.h264.vcl.macroblock;
import java.awt.Point;
import br.ufsc.inf.guiga.media.codec.video.h264.vcl.Macroblock;
/**

* Macroblock Neighbours Access for Non MBAFF coding.

*

* @author Guilherme Ferreira



*/

public class MacroblockAccessNonMBAFF extends MacroblockAccess {
/**

* @param macroblockX the {@link Macroblock} owner of this {@link MacroblockAccessNonMBAFF}.

*/

public MacroblockAccessNonMBAFF(Macroblock macroblock) {

super(macroblock);

}
public void checkAvailableNeighbours() {



int mbNrA = mbNr - 1;

int mbNrB = mbNr - picWidthInMbs;

int mbNrC = mbNr - picWidthInMbs + 1;

int mbNrD = mbNr - picWidthInMbs - 1;
if (column(mbNr) != 0)

macroblockA = getMacroblock(mbNrA);

macroblockB = getMacroblock(mbNrB);

if (column(mbNr + 1) != 0)

macroblockC = getMacroblock(mbNrC);



if (column(mbNr) != 0)

macroblockD = getMacroblock(mbNrD);

}
public boolean getNeighbour(int xN, int yN, int maxW, int maxH, Point p) {

Macroblock neighbour = null;



boolean available = false;
if ((xN < 0) && (yN < 0)) {

neighbour = macroblockD;

} else if ((xN < 0) && ((yN >= 0) && (yN < maxH))) {

neighbour = macroblockA;

} else if (((xN >= 0) && (xN < maxW)) && (yN < 0)) {

neighbour = macroblockB;

} else if (((xN >= 0) && (xN < maxW)) && ((yN >= 0) && (yN < maxH))) {

neighbour = macroblockX;

} else if ((xN >= maxW) && (yN < 0)) {

neighbour = macroblockC;

} else {

neighbour = null;

}
if (neighbour != null) {

int xW = xN & (maxW - 1); // xW = (xN + maxW) % maxW

int yW = yN & (maxH - 1); // yW = (yN + maxH) % maxH

int pos_x = xW + column(neighbour.getMbNr()) * maxW;

int pos_y = yW + line(neighbour.getMbNr()) * maxH;

p.setLocation(pos_x, pos_y);


available = true;

}
return available;

}
}


      1. A9.3 Classe MacroblockInfo



package br.ufsc.inf.guiga.media.codec.video.h264.vcl.macroblock;
import br.ufsc.inf.guiga.media.codec.video.h264.vcl.Macroblock;

import br.ufsc.inf.guiga.media.codec.video.h264.vcl.block.ResidualBlockInfo;

import br.ufsc.inf.guiga.media.codec.video.h264.vcl.datatype.ResidualBlockType;
/**

* Holds information about the residual blocks of a macroblock.

*

* @author Guilherme Ferreira



*/

public class MacroblockInfo {
private int mbNr;

private MacroblockAccess access;

private ResidualBlockInfo[][] lumaAcBlk;

private ResidualBlockInfo[][] cbChromaAcBlk;

private ResidualBlockInfo[][] crChromaAcBlk;
// Note: For 4:2:0, chroma statistics are unavailable
public MacroblockInfo(Macroblock macroblock) {

mbNr = macroblock.getMbNr();

access = macroblock.getMacroblockAccess();

lumaAcBlk = new ResidualBlockInfo[4][4];

cbChromaAcBlk = new ResidualBlockInfo[2][2];

crChromaAcBlk = new ResidualBlockInfo[2][2];

}
/**

* Get the {@link ResidualBlockInfo} object at a given (x,y) position.

*

* @param blkIdxX the x position.



* @param blkIdxY the y position.

* @param type the {@link ResidualBlockType}.

* @return the {@link ResidualBlockInfo} of type at position (x,y).

*/

public ResidualBlockInfo getBlockInfo(int blkIdxX, int blkIdxY, ResidualBlockType type)

{

ResidualBlockInfo blockInfo = null;


switch (type) {

case Intra16x16LumaDCLevel: // AC(0,0) and DC share the same prediction block

case Intra16x16LumaACLevel:

blockInfo = lumaAcBlk[blkIdxX][blkIdxY];



break;

case CbIntra8x8ChromaDCLevel: // AC(0,0) and DC share the same prediction block

case CbIntra8x8ChromaACLevel:

blockInfo = cbChromaAcBlk[blkIdxX][blkIdxY];



break;

case CrIntra8x8ChromaDCLevel: // AC(0,0) and DC share the same prediction block

case CrIntra8x8ChromaACLevel:

blockInfo = crChromaAcBlk[blkIdxX][blkIdxY];



break;

}
return blockInfo;

}
/**

* Set the {@link ResidualBlockInfo} object at a given (x,y) position.

*

* @param blkIdxX the x position.



* @param blkIdxY the y position.

* @param type the {@link ResidualBlockType}.

* @param blockInfo the {@link ResidualBlockInfo} of type at position (x,y).

*/

public void setBlockInfo(



int blkIdxX, int blkIdxY, ResidualBlockType type, ResidualBlockInfo blockInfo)

{

blockInfo.setMacroblockInfo(this);


switch (type) {

case Intra16x16LumaDCLevel: // AC(0,0) and DC share the same prediction block

case Intra16x16LumaACLevel:

blockInfo.setBlockIndexX(blkIdxX);

blockInfo.setBlockIndexY(blkIdxY);

lumaAcBlk[blkIdxX][blkIdxY] = blockInfo;



break;

case CbIntra8x8ChromaDCLevel: // AC(0,0) and DC share the same prediction block

case CbIntra8x8ChromaACLevel:

blockInfo.setBlockIndexX(blkIdxX);

blockInfo.setBlockIndexY(blkIdxY);

cbChromaAcBlk[blkIdxX][blkIdxY] = blockInfo;



break;

case CrIntra8x8ChromaDCLevel: // AC(0,0) and DC share the same prediction block

case CrIntra8x8ChromaACLevel:

blockInfo.setBlockIndexX(blkIdxX);

blockInfo.setBlockIndexY(blkIdxY);

crChromaAcBlk[blkIdxX][blkIdxY] = blockInfo;



break;

}
}
/**

* Get the Number of Nonzero Coefficients predicted from the neighboring 4x4 blocks.

*

* @param type the {@link ResidualBlockType}.



* @param residualBlock the {@link ResidualBlockInfo}.

* @return the number o nonzero coefficients predicted from the available neighbour

* blocks.

*/

public int getPredictedNonZeroCoeff(

ResidualBlockType type, ResidualBlockInfo residualBlock)

{

int blkIdxX = residualBlock.getBlockIndexX();



int blkIdxY = residualBlock.getBlockIndexY();

Macroblock mbA = null;

Macroblock mbB = null;

boolean isUpperBlockAvailable;

boolean isLeftBlockAvailable;

int nA, nB, nC = 0;
// Check the availability of the left block (block A)

if (blkIdxX == 0) {

if (access.column(mbNr) != 0) {

mbA = access.getMacroblockA();

isLeftBlockAvailable = true;

} else {

isLeftBlockAvailable = false;

}

} else {



mbA = access.getMacroblock(mbNr);

isLeftBlockAvailable = true;

}
// Check the availability of the upper block (block B)

if (blkIdxY == 0) {

if (access.line(mbNr) != 0) {

mbB = access.getMacroblockB();

isUpperBlockAvailable = true;

} else {

isUpperBlockAvailable = false;

}

} else {



mbB = access.getMacroblock(mbNr);

isUpperBlockAvailable = true;

}
// Check the position of blocks A and B

int blkIdxXA = getLeftNeighbourBlockIndex(blkIdxX, type);

int blkIdxYA = blkIdxY;

int blkIdxXB = blkIdxX;

int blkIdxYB = getLeftNeighbourBlockIndex(blkIdxY, type);
// Compute nC

if (!isLeftBlockAvailable && isUpperBlockAvailable) {

ResidualBlockInfo blockB = mbB.getMacroblockInfo().getBlockInfo(blkIdxXB,

blkIdxYB, type);

nB = blockB.getNonZeroCoeff();


// nC = nB, if only the upper block is available

nC = nB;
} else if (isLeftBlockAvailable && !isUpperBlockAvailable) {

ResidualBlockInfo blockA = mbA.getMacroblockInfo().getBlockInfo(blkIdxXA,

blkIdxYA, type);

nA = blockA.getNonZeroCoeff();
// nC = nA, if only the left block is available

nC = nA;
} else if (isLeftBlockAvailable && isUpperBlockAvailable) {

ResidualBlockInfo blockA = mbA.getMacroblockInfo().getBlockInfo(blkIdxXA,

blkIdxYA, type);

ResidualBlockInfo blockB = mbB.getMacroblockInfo().getBlockInfo(blkIdxXB,

blkIdxYB, type);

nA = blockA.getNonZeroCoeff();

nB = blockB.getNonZeroCoeff();


// nC = round((nA + nB)/2), when both blocks are available

nC = (nA + nB + 1) >> 1;


} else {

// nC = 0, when neither block is available

nC = 0;

}
return nC;



}
private int getLeftNeighbourBlockIndex(int blkIdx, ResidualBlockType type) {

int prevBlkIdx = 0;
switch (type) {

case CbIntra8x8ChromaDCLevel:

case CrIntra8x8ChromaDCLevel:

case CbIntra8x8ChromaACLevel:

case CrIntra8x8ChromaACLevel:

prevBlkIdx = (blkIdx != 0) ? blkIdx - 1 : 1;



break;

case Intra16x16LumaDCLevel:

case Intra16x16LumaACLevel:

prevBlkIdx = (blkIdx != 0) ? blkIdx - 1 : 3;



break;

}
return prevBlkIdx;

}

}


      1. A9.4 Classe MacroblockPosition



package br.ufsc.inf.guiga.media.codec.video.h264.vcl.macroblock;
import br.ufsc.inf.guiga.media.codec.video.h264.vcl.Macroblock;
/**

* This class holds macroblock position.

*

* @author Guilherme Ferreira



*/

public class MacroblockPosition {
public int mbX; // current MB horizontal

public int mbY; // current MB vertical

public int pixelX; // macroblock pixel horizontal position

public int pixelY; // macroblock pixel vertical position

public int pixelChromaX; // macroblock chroma pixel horizontal position

public int pixelChromaY; // macroblock chroma pixel vertical position
public MacroblockPosition(Macroblock macroblock) {

int mbNr = macroblock.getMbNr();

int frameWidth = macroblock.getSlice().getPicture().getWidth();

int picWidthInMbs = frameWidth / Macroblock.MB_WIDTH;
// calculate the macroblock (x,y) position within the frame buffer

this.mbX = mbNr % picWidthInMbs;

this.mbY = mbNr / picWidthInMbs;

this.pixelX = mbX * Macroblock.MB_WIDTH;

this.pixelY = mbY * Macroblock.MB_HEIGHT;

this.pixelChromaX = (mbX * Macroblock.MB_CHROMA_WIDTH);

this.pixelChromaY = (mbY * Macroblock.MB_CHROMA_HEIGHT);

}
}





1   ...   13   14   15   16   17   18   19   20   ...   24


©livred.info 2017
enviar mensagem

    Página principal