--- a/videoeditorengine/h263decoder/src/core.cpp Fri Jan 29 14:08:33 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1357 +0,0 @@
-/*
-* Copyright (c) 2010 Ixonos Plc.
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - Initial contribution
-*
-* Contributors:
-* Ixonos Plc
-*
-* Description:
-* H.263 decoder core functions.
-*
-*/
-
-
-/*
- * Includes
- */
-#include "h263dConfig.h"
-#include "vdc263.h"
-#include "core.h"
-#include "debug.h"
-#include "decblock.h" /* for dblFree and dblLoad */
-#include "decgob.h"
-#include "decpich.h"
-#include "h263dapi.h" /* for H263D_BC_MUX_MODE_SEPARATE_CHANNEL and H263D_ERD_ */
-#include "stckheap.h"
-#include "sync.h"
-#include "vdeims.h"
-#include "vdeimb.h"
-#include "viddemux.h"
-#include "biblin.h"
-#include "MPEG4Transcoder.h"
-
-
-/*
- * Typedefs and structs
- */
-
-/* This structure is used to indicate the expected decoding position. */
-typedef enum {
- EDP_START_OF_FRAME,
- EDP_START_OF_GOB_SEGMENT,
- EDP_START_OF_SLICE_SEGMENT,
- EDP_END_OF_FRAME
-} vdcExpectedDecodingPosition_t;
-
-
-/*
- * Local function prototypes
- */
-
-int vdcFillImageBuffers(
- vdcInstance_t *instance,
- int numOfCodedMBs,
- vdeImb_t *imbP);
-
-
-/*
- * Global functions
- */
-
-/* {{-output"vdcClose.txt"}} */
-/*
- * vdcClose
- *
- *
- * Parameters:
- * hInstance handle of instance data
- *
- * Function:
- * This function closes the instance. The function frees all the resources
- * allocated for the instance. The instance handle is no longer valid
- * after calling this function.
- *
- * Returns:
- * >= 0 if the function was successful
- * < 0 if an error occured
- *
- */
-
-int vdcClose(vdcHInstance_t hInstance)
-/* {{-output"vdcClose.txt"}} */
-{
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
- int retValue = VDC_OK;
-
- if (instance == NULL)
- return retValue;
-
- mvcFree(&instance->mvcData);
-
- if ( instance->prevPicHeader != NULL )
- free( instance->prevPicHeader );
-
- aicFree(&instance->aicData);
-
-
- if ( instance->user_data != NULL )
- free( instance->user_data );
-
-
- vdcDealloc(instance);
-
- return retValue;
-}
-
-
-/* {{-output"vdcDecodeFrame.txt"}} */
-/*
- * vdcDecodeFrame
- *
- *
- * Parameters:
- * hInstance handle of instance data
- *
- * inBuffer pointer to bit buffer, the current position
- * of the buffer must start with a PSC
- *
- * Function:
- * The vdcDecodeFrame function implements the decoding process described
- * in the H.263 recommendation (version 2). However, it does not support
- * the following features of the recommendation:
- * decoding using the H.261 standard (bit 2 in PTYPE),
- * source format changes during a video sequence.
- *
- * The function decodes the next frame in
- * the buffer (inBuffer) meaning that the decoding continues until the next
- * PSC or EOS is found or until the end of the buffer is not reached.
- *
- * Returns:
- * VDC_OK if the function was succesful
- * VDC_OK_BUT_BIT_ERROR if bit errors were detected but
- * decoded frames are provided by concealing
- * the errors
- * VDC_OK_BUT_FRAME_USELESS if severe bit errors were detected
- * (no concealment was possible) or
- * the bitstream ended unexpectedly
- * VDC_ERR if a processing error occured,
- * the instance should be closed
- *
- */
-
-
-int vdcDecodeFrame(vdcHInstance_t hInstance, bibBuffer_t *inBuffer, bibBuffer_t *outBuffer,
- bibBufferEdit_t *bufEdit, int aColorEffect, TBool aGetDecodedFrame,
- CMPEG4Transcoder *hTranscoder)
-
-/* {{-output"vdcDecodeFrame.txt"}} */
-{
- int prevGN = -1; /* GOB number of the latest decoded GOB */
- int prevGNWithHeader = -1; /* GOB number of the latest decoded GOB with
- a GOB header */
-
- int numStuffBits; /* Number of stuffing bits before the sync code */
-
- int sncCode; /* the latest synchronization code, see
- sncCheckSync for the possible values */
-
- int rtr = -1; /* reference tr, 0.. */
- int trp = -1; /* tr for prediction, -1 if not indicated in
- the bitstream */
-
- int retValue = VDC_OK; /* return value of this function */
-
-
- int16 error = 0; /* Used to pass error codes from the sync module */
-
- u_char
- *currYFrame = NULL, /* current P frame */
- *currUFrame = NULL,
- *currVFrame = NULL,
- *refYFrame = NULL, /* reference frame */
- *refUFrame = NULL,
- *refVFrame = NULL;
-
- u_char *fCodedMBs = NULL; /* Pointer to table, which indicates coded \
- macroblocks by non-zero value */
- int numOfCodedMBs = 0; /* The number of coded macroblocks */
-
- int *quantParams = NULL; /* Pointer to table, in which the quantization
- parameter for each macroblock is stored */
-
- int decStatus = 0; /* Decoding status, returned from decgob.c */
- int corruptedSegments = 0; /* counter for corrupted segments */
- int decodedSegments = 0; /* counter for decoded segments (used in slice mode) */
- int headerSuccess = 0; /* success of picture header */
- int numDecodedMBs = 0; /* Total number of decoded MBs */
- int numMBsInFrame = 0; /* Number of MBs in frame */
-
-
- vdcExpectedDecodingPosition_t expectedDecodingPosition;
- /* Tells in which part of the bitstream
- the decoding should be */
-
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
- /* instance data */
-
- vdcAssert(instance != NULL);
-
- /* Initializations */
-
- instance->currFrame = NULL;
- expectedDecodingPosition = EDP_START_OF_FRAME;
- instance->pictureParam.prevTR = instance->pictureParam.tr;
-
- /* Main loop */
- for (;;) {
- int bitErrorIndication = 0;
-
- sncCode = sncCheckSync(inBuffer, &numStuffBits, &error);
-
- /* If sncCheckSync failed */
- if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
- deb1p("vdcDecodeFrame: ERROR - sncCheckSync returned %d.\n", error);
- retValue = VDC_ERR;
- goto exitFunction;
- }
-
- /* If EOS was got */
- if (sncCode == SNC_EOS)
- instance->fEOS = 1;
-
- /* If frame ends appropriately */
- if (expectedDecodingPosition == EDP_END_OF_FRAME &&
- (sncCode == SNC_PSC || sncCode == SNC_EOS ||
- sncCode == SNC_STUFFING || error == ERR_BIB_NOT_ENOUGH_DATA )) {
- goto exitFunction;
- }
-
- /* Else if frame (or stream) data ends suddenly */
- else if (error == ERR_BIB_NOT_ENOUGH_DATA) {
- retValue = VDC_OK_BUT_BIT_ERROR;
- goto exitFunction;
- }
-
- /* Else if EOS was reached */
- else if (sncCode == SNC_EOS) {
- /* The current frame is useless since it ends before it is complete.
- On the other hand, there is no point in concealing it since
- it is the last frame of the sequence. */
- retValue = VDC_OK_BUT_FRAME_USELESS;
- goto exitFunction;
- }
-
- /* Else if frame starts as expected */
- else if (expectedDecodingPosition == EDP_START_OF_FRAME &&
- sncCode == SNC_PSC) {
-
- dphInParam_t pichIn;
- dphInOutParam_t pichInOut;
- dphOutParam_t pichOut;
-
- pichIn.numStuffBits = numStuffBits;
- pichIn.fNeedDecodedFrame = aGetDecodedFrame | hTranscoder->NeedDecodedYUVFrame();
-
- pichIn.fReadBits = 1;
- pichInOut.vdcInstance = instance;
- pichInOut.inBuffer = inBuffer;
-
- if ( instance->fRPS ) {
- /* Store the previous TR for VRC needs */
- if ( instance->nOfDecodedFrames > 0 )
- trp = instance->pictureParam.tr;
- else
- trp = -1;
- }
- /* Get picture header */
- headerSuccess = dphGetPictureHeader(&pichIn, &pichInOut, &pichOut, &bitErrorIndication);
-
- if (headerSuccess != DPH_OK) {
-
- deb("vdcDecodeFrame: Header decoding unsuccessful due to errors, picture will be discarded.\n");
- retValue = VDC_OK_BUT_FRAME_USELESS;
- goto exitFunction;
- }
-
- numMBsInFrame = renDriNumOfMBs(instance->currFrame->imb->drawItem);
-
- currYFrame = pichOut.currYFrame;
- currUFrame = pichOut.currUFrame;
- currVFrame = pichOut.currVFrame;
-
- numOfCodedMBs = 0;
- fCodedMBs = renDriCodedMBs(instance->currFrame->imb->drawItem);
- memset(fCodedMBs, 0, numMBsInFrame * sizeof(u_char));
-
- /* Initialize quantization parameter array */
- quantParams = instance->currFrame->imb->yQuantParams;
- memset(quantParams, 0, numMBsInFrame * sizeof(int));
-
- /* If this is the first frame and callback function has been set, report frame size */
- if (instance->nOfDecodedFrames == 0 && instance->reportPictureSizeCallback) {
- h263dReportPictureSizeCallback_t cb =
- (h263dReportPictureSizeCallback_t)instance->reportPictureSizeCallback;
- cb(instance->hParent, instance->pictureParam.lumWidth, instance->pictureParam.lumHeight);
- }
-
- /* If picture header was ok */
- if (headerSuccess == DPH_OK)
- {
- /* Get and decode Supplemental Enhancement Information */
- int seiSuccess = dphGetSEI(instance, inBuffer, &bitErrorIndication);
-
- /* If fatal error while reading SEI */
- if (seiSuccess < 0) {
- retValue = VDC_ERR;
- deb("vdcDecodeFrame: dphGetSEI failed.\n");
- goto exitFunction;
- }
-
- /* Else if bit error while reading SEI */
- else if (seiSuccess == DPH_OK_BUT_BIT_ERROR) {
- /* We can't trust that the 1st segment can be decoded.
- Thus, let's continue with the 2nd segment. */
- if ( instance->pictureParam.fSS )
- expectedDecodingPosition = EDP_START_OF_SLICE_SEGMENT;
- else
- expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
- sncCode = sncSeekSync(inBuffer, &error);
- if (error && error != ERR_BIB_NOT_ENOUGH_DATA) {
- retValue = VDC_ERR;
- deb("vdcDecodeFrame: sncSeekSync failed.\n");
- goto exitFunction;
- }
- continue;
- }
-
-
- }
-
- if ( hTranscoder->H263PictureHeaderEnded(&pichOut, &pichInOut) != VDC_OK )
- {
- retValue = VDC_ERR;
- goto exitFunction;
- }
-
- if (instance->pictureParam.fSS)
- /* Decode the 1st Slice segment - not supported */
- {
- retValue = VDC_OK_BUT_FRAME_USELESS;
- goto exitFunction;
- }
- else
- /* Decode the 1st GOB segment */
- {
- dgobGOBSegmentInParam_t dgobi;
- dgobGOBSegmentInOutParam_t dgobio;
-
- dgobi.numStuffBits = 0;
- dgobi.pictParam = &instance->pictureParam;
- dgobi.inBuffer = inBuffer;
-
- dgobi.outBuffer = outBuffer;
- dgobi.bufEdit = bufEdit;
-
- dgobi.iColorEffect = aColorEffect;
- dgobi.iGetDecodedFrame=aGetDecodedFrame;
- dgobio.StartByteIndex=0;
- dgobio.StartBitIndex=7;
-
- /* fGFIDShouldChange not relevant here */
-
- dgobio.prevGNWithHeader = 0;
- dgobio.prevGN = 0;
- /* dgobio.gfid, not relevant here */
- dgobio.fCodedMBs = fCodedMBs;
- dgobio.numOfCodedMBs = numOfCodedMBs;
- dgobio.quantParams = quantParams;
- dgobio.mvcData = &instance->mvcData;
- dgobio.imageStore = instance->imageStore;
- dgobio.trp = pichOut.trp;
- dgobio.rtr = 0; /* not relevant since no reference frame exists yet */
- dgobio.refY = refYFrame;
- dgobio.refU = refUFrame;
- dgobio.refV = refVFrame;
- dgobio.currPY = currYFrame;
- dgobio.currPU = currUFrame;
- dgobio.currPV = currVFrame;
-
- /* the first GOB doesn't have a header */
- hTranscoder->H263GOBSliceHeaderBegin();
- hTranscoder->H263GOBSliceHeaderEnded(NULL, NULL);
-
- decStatus = dgobGetAndDecodeGOBSegmentContents(&dgobi,
- instance->pictureParam.pictureType != VDX_PIC_TYPE_I,
- pichOut.pquant, &dgobio, hTranscoder);
-
- if (decStatus < 0) {
- retValue = VDC_ERR;
- goto exitFunction;
- }
-
- hTranscoder->H263OneGOBSliceWithHeaderEnded();
-
- prevGNWithHeader = dgobio.prevGNWithHeader;
- prevGN = dgobio.prevGN;
- numOfCodedMBs = dgobio.numOfCodedMBs;
- trp = dgobio.trp;
- rtr = dgobio.rtr;
- refYFrame = dgobio.refY;
- refUFrame = dgobio.refU;
- refVFrame = dgobio.refV;
- if (prevGN == instance->pictureParam.numGOBs - 1)
- expectedDecodingPosition = EDP_END_OF_FRAME;
- else
- expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
- }
- }
-
- /* Else if GOB segment starts as expected */
- else if (expectedDecodingPosition == EDP_START_OF_GOB_SEGMENT &&
- sncCode == SNC_GBSC) {
-
- dgobGOBSegmentInParam_t dgobi;
- dgobGOBSegmentInOutParam_t dgobio;
-
- dgobi.numStuffBits = numStuffBits;
- dgobi.pictParam = &instance->pictureParam;
- dgobi.inBuffer = inBuffer;
-
- dgobi.outBuffer = outBuffer;
- dgobi.bufEdit = bufEdit;
-
- dgobi.iColorEffect = aColorEffect;
- dgobi.iGetDecodedFrame= aGetDecodedFrame;
- if(prevGN==-1)
- {
- dgobio.StartByteIndex=0;
- dgobio.StartBitIndex=7;
- }
- else
- {
- dgobio.StartByteIndex=dgobi.inBuffer->getIndex;
- dgobio.StartBitIndex=dgobi.inBuffer->bitIndex;
- }
-
-
- /* fGFIDShouldChange, see below */
-
- dgobio.prevGNWithHeader = prevGNWithHeader;
- dgobio.prevGN = prevGN;
- /* dgobio.gfid, see below */
- dgobio.fCodedMBs = fCodedMBs;
- dgobio.numOfCodedMBs = numOfCodedMBs;
- dgobio.quantParams = quantParams;
- dgobio.mvcData = &instance->mvcData;
- dgobio.imageStore = instance->imageStore;
- dgobio.trp = trp;
- dgobio.rtr = rtr;
- dgobio.refY = refYFrame;
- dgobio.refU = refUFrame;
- dgobio.refV = refVFrame;
- dgobio.currPY = currYFrame;
- dgobio.currPU = currUFrame;
- dgobio.currPV = currVFrame;
-
- dgobi.fGFIDShouldChange = instance->fGFIDShouldChange;
- dgobio.gfid = instance->gfid;
-
- /* Get and decode GOB segment */
- decStatus = dgobGetAndDecodeGOBSegment(&dgobi, &dgobio, hTranscoder);
-
- if (decStatus == DGOB_ERR) {
- retValue = VDC_ERR;
- goto exitFunction;
- }
- if ( instance->fGFIDShouldChange ) {
- instance->gfid = dgobio.gfid;
- instance->fGFIDShouldChange = 0;
- }
-
- prevGNWithHeader = dgobio.prevGNWithHeader;
- prevGN = dgobio.prevGN;
- numOfCodedMBs = dgobio.numOfCodedMBs;
- trp = dgobio.trp;
-
-
- rtr = dgobio.rtr;
-
- refYFrame = dgobio.refY;
- refUFrame = dgobio.refU;
- refVFrame = dgobio.refV;
-
- if (prevGN == instance->pictureParam.numGOBs - 1)
- expectedDecodingPosition = EDP_END_OF_FRAME;
- else
- expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
- }
-
- /* Else if Slice segment starts as expected */
- else if (expectedDecodingPosition == EDP_START_OF_SLICE_SEGMENT &&
- sncCode == SNC_GBSC) {
- /* slides not supported */
- retValue = VDC_OK_BUT_FRAME_USELESS;
- goto exitFunction;
-
- }
-
- /* Else decoding is out of sync */
- else {
- switch (expectedDecodingPosition) {
-
- case EDP_START_OF_FRAME:
- /* No PSC */
- /* Check if GFID could be used to recover the picture header */
- {
- dphInParam_t pichIn;
- dphInOutParam_t pichInOut;
- dphOutParam_t pichOut;
-
- pichIn.numStuffBits = numStuffBits;
- pichIn.fReadBits = 0;
-
- pichInOut.vdcInstance = instance;
- pichInOut.inBuffer = inBuffer;
-
- headerSuccess = dphGetPictureHeader(&pichIn, &pichInOut, &pichOut, &bitErrorIndication);
- if ( headerSuccess == DPH_OK) {
- /* Header recovery was successful, start decoding from the next GOB available */
- if ( instance->pictureParam.fSS ) {
- expectedDecodingPosition = EDP_START_OF_SLICE_SEGMENT;
- /* decSlice does not increment these */
- decodedSegments++;
- corruptedSegments++;
- }
- else
- expectedDecodingPosition = EDP_START_OF_GOB_SEGMENT;
- deb1p("vdcDecodeFrame: Header successfully recovered after PSC loss. FrameNum %d\n",instance->frameNum);
- currYFrame = pichOut.currYFrame;
- currUFrame = pichOut.currUFrame;
- currVFrame = pichOut.currVFrame;
- numMBsInFrame = renDriNumOfMBs(instance->currFrame->imb->drawItem);
- numOfCodedMBs = 0;
- numDecodedMBs = 0;
- fCodedMBs = renDriCodedMBs(instance->currFrame->imb->drawItem);
- memset(fCodedMBs, 0, numMBsInFrame * sizeof(u_char));
-
- /* Initialize quantization parameter array */
- quantParams = instance->currFrame->imb->yQuantParams;
- memset(quantParams, 0, numMBsInFrame * sizeof(int));
-
- /* If this is the first frame and callback function has been set, report frame size */
- if (instance->nOfDecodedFrames == 0 && instance->reportPictureSizeCallback) {
- h263dReportPictureSizeCallback_t cb =
- (h263dReportPictureSizeCallback_t)instance->reportPictureSizeCallback;
- cb(instance->hParent, instance->pictureParam.lumWidth, instance->pictureParam.lumHeight);
- }
-
- continue;
- }
- else {
- retValue = VDC_OK_BUT_FRAME_USELESS;
- deb1p("vdcDecodeFrame: Header recovery unsuccessful after PSC loss. FrameNum %d\n",instance->frameNum);
- goto exitFunction;
- }
- }
- case EDP_START_OF_GOB_SEGMENT:
- if ( sncCode == SNC_PSC ) {
- retValue = VDC_OK_BUT_BIT_ERROR;
- goto exitFunction;
- }
- else {
- /*
- * Picture header recovery used next picture header
- * => we are not at the position of GBSC => search the next one
- * This is caused by a erdRestorePictureHeader that does not synchronize
- * bit buffer to GOB headers that have bitErrorIndication != 0.
- * This may be considered as a , and it might be good to change it later on.
- * This seeking should solve the problem, although maybe not in the most elegant way
- */
- sncSeekSync( inBuffer, &error );
- continue;
- }
- default :
- {
-
- retValue = VDC_OK_BUT_FRAME_USELESS;
- goto exitFunction;
- }
-
- }
- }
- }
-
- exitFunction:
-
-
- /* If frame(s) not useless */
- if (retValue == VDC_OK || retValue == VDC_OK_BUT_BIT_ERROR) {
-
- if (!corruptedSegments && (numDecodedMBs > 0 || prevGN > 0 || instance->pictureParam.numGOBs == 1))
- retValue = VDC_OK;
- else {
- retValue = VDC_OK_BUT_FRAME_USELESS;
- deb1p("vdcDecodeFrame: Frame useless, too many corrupted segments. FrameNum %d\n",instance->frameNum);
- }
- }
-
- /* If decoding ok and frame not useless */
- if ( retValue == VDC_OK || retValue == VDC_OK_BUT_BIT_ERROR ) {
-
-
- /* stuff bits here 'END OF FRAME' -->*/
- bibStuffBits(outBuffer);
- /* <-- */
-
- if ( instance->nOfDecodedFrames < 0xffffffff )
- instance->nOfDecodedFrames++;
-
- if (vdcFillImageBuffers(
- instance,
- numOfCodedMBs,
- instance->currFrame->imb) < 0)
- retValue = VDC_ERR;
-
-
-
- }
- if ( retValue == VDC_OK_BUT_FRAME_USELESS ) {
- /* GFID of the next frame can be whatever, since this frame was useless */
- instance->gfid = -1;
- }
- if ( instance->fGFIDShouldChange
- && ( (instance->pictureParam.fSS && decodedSegments == 1)
- || (!instance->pictureParam.fSS && prevGNWithHeader <= 0)
- )
- )
- {
- /* GFID of the next frame can be whatever, since this frame didn't have any GFID's and GFID was supposed to change */
- instance->gfid = -1;
- }
-
- /* If a fatal error occurred */
- if (retValue < 0) {
- /* Return frame buffers for decoded output images,
- as they are useless for the caller and
- as the caller cannot get a handle to return them */
- if (instance->currFrame)
- vdeImsPutFree(instance->imageStore, instance->currFrame);
- }
-
- return retValue;
-}
-
-
-/* {{-output"vdcDecodePictureHeader.txt"}} */
-/*
- * vdcDecodePictureHeader
- *
- * Parameters:
- * hInstance I: handle of instance data
- * (May set instance->errorVar if bit errors.)
- *
- * Function:
- *
- *
- * Note:
- * This function does not recover corrupted picture headers (by means of
- * GFID or redundant picture header copies).
- *
- * Returns:
- * See above.
- */
-
-int vdcDecodePictureHeader(
- vdcHInstance_t hInstance,
- bibBuffer_t *inBuffer,
- vdxPictureHeader_t *header,
- vdxSEI_t *sei)
-{
- int
- retValue = VDC_OK,
- sncCode,
- numStuffBits,
- bitErrorIndication = 0;
-
- int16
- error = 0;
-
- u_int32
- pictureStartPosition;
-
- vdcInstance_t
- *instance = (vdcInstance_t *) hInstance;
-
- /* The function is implemented by calling stateless Video Demultiplexer
- (vdx) functions. Consequently, the function does not have sophisticated
- logic to track illegal/corrupted parameters based on the previous
- picture header. It cannot recover corrupted picture headers either.
-
- Alternatively, the function could have been implemented by creating
- an identical copy of the Video Decoder Core instance and by using
- "Decode Picture Header" (dph) module functions. However, as there is
- no instance copying functions implemented, the former alternative
- was chosen.
-
- This function was targeted for getting the picture type and
- Nokia-proprietary Annex N scalability layer information encapsulated
- in Supplemental Enhancement Information in an error-free situation.
- For this purpose, the former and simpler solution is more than
- adequate. */
-
- pictureStartPosition = bibNumberOfFlushedBits(inBuffer);
- sncCode = sncCheckSync(inBuffer, &numStuffBits, &error);
-
- /* If sncCheckSync failed */
- if (error) {
- deb1p("vdcDecodeFrame: ERROR - sncCheckSync returned %d.\n", error);
- retValue = VDC_ERR;
- goto exitFunction;
- }
-
- /* Else if EOS was got */
- else if (sncCode == SNC_EOS) {
- retValue = VDC_OK_BUT_FRAME_USELESS;
- goto exitFunction;
- }
-
- /* Else if frame starts as expected */
- else if (sncCode == SNC_PSC) {
- int
- picHdrStatus,
- seiStatus;
-
- vdxGetPictureHeaderInputParam_t
- picHdrIn;
-
- picHdrIn.numStuffBits = numStuffBits;
- picHdrIn.fCustomPCF = 0;
- picHdrIn.fScalabilityMode = 0;
- picHdrIn.fRPS = instance->fRPS;
- picHdrIn.flushBits = bibFlushBits;
- picHdrIn.getBits = bibGetBits;
- picHdrIn.showBits = bibShowBits;
-
- /* Get picture header */
- picHdrStatus = vdxGetPictureHeader(
- inBuffer,
- &picHdrIn,
- header,
- &bitErrorIndication);
-
- /* If the header was not successfully retrieved */
- if (picHdrStatus < 0) {
- retValue = VDC_ERR;
- goto exitFunction;
- }
- else if (picHdrStatus != VDX_OK) {
- retValue = VDC_OK_BUT_BIT_ERROR;
- goto exitFunction;
- }
-
- /* Get and decode Supplemental Enhancement Information */
- seiStatus = vdxGetAndParseSEI(
- inBuffer,
- instance->pictureParam.fPLUSPTYPE,
- instance->numAnnexNScalabilityLayers,
- sei,
- &bitErrorIndication);
-
- /* If error while reading SEI */
- if (seiStatus < 0) {
- retValue = VDC_ERR;
- goto exitFunction;
- }
- else if (seiStatus != VDX_OK) {
- retValue = VDC_OK_BUT_BIT_ERROR;
- goto exitFunction;
- }
- }
-
- /* Else no valid frame start */
- else
- retValue = VDC_OK_BUT_FRAME_USELESS;
-
- exitFunction:
-
- /* Reset the bit buffer to its original position */
- bibRewindBits(
- bibNumberOfFlushedBits(inBuffer) - pictureStartPosition,
- inBuffer, &error);
-
- if (error)
- retValue = VDC_ERR;
-
- return retValue;
-}
-
-
-/* {{-output"vdcFree.txt"}} */
-/*
- * vdcFree
- *
- *
- * Parameters:
- * None.
- *
- * Function:
- * This function deinitializes the Video Decoder Core module.
- * Any functions of this module must not be called after vdcFree (except
- * vdcLoad).
- *
- * Returns:
- * >= 0 if succeeded
- * < 0 if failed
- *
- *
- */
-
-int vdcFree(void)
-/* {{-output"vdcFree.txt"}} */
-{
- if (dblFree() < 0)
- return VDC_ERR;
-
- return VDC_OK;
-}
-
-
-/* {{-output"vdcGetImsItem.txt"}} */
-/*
- * vdcGetImsItem
- *
- *
- * Parameters:
- * hInstance handle of instance data
- * index output frame number,
- * should be 0 for I and P frames
- *
- * Function:
- * This function returns a pointer to the requested output frame.
- *
- * Returns:
- * a pointer to a image store item which corresponds to the passed output
- * frame index, or
- * NULL if the function fails
- *
- */
-
-vdeImsItem_t *vdcGetImsItem(vdcHInstance_t hInstance, int index)
-/* {{-output"vdcGetImsItem.txt"}} */
-{
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
- int numOutputFrames = vdcGetNumberOfOutputFrames(hInstance);
-
- vdcAssert(instance);
- vdcAssert(index >= 0);
-
- if (index >= numOutputFrames)
- return NULL;
-
- return instance->currFrame;
-}
-
-
-/* {{-output"vdcGetNumberOfAnnexNScalabilityLayers.txt"}} */
-/*
- * vdcGetNumberOfAnnexNScalabilityLayers
- *
- * Parameters:
- * hInstance I: handle of instance data
- *
- * Function:
- * Returns the number of Nokia-proprietary Annex N temporal scalability
- * layers.
- *
- * Returns:
- * See above.
- */
-
-int vdcGetNumberOfAnnexNScalabilityLayers(
- vdcHInstance_t hInstance)
-/* {{-output"vdcGetNumberOfAnnexNScalabilityLayers.txt"}} */
-{
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
- vdcAssert(instance);
-
- return instance->numAnnexNScalabilityLayers;
-}
-
-
-/* {{-output"vdcGetNumberOfOutputFrames.txt"}} */
-/*
- * vdcGetNumberOfOutputFrames
- *
- *
- * Parameters:
- * hInstance handle of instance data
- *
- * Function:
- * This function returns the number of output frames which were produced
- * during the latest vdcDecodeFrame.
- *
- * Returns:
- * 0 if vdcDecodeFrame failed to produce any output frames
- * 1 for I and P frames
- *
- */
-
-int vdcGetNumberOfOutputFrames(vdcHInstance_t hInstance)
-/* {{-output"vdcGetNumberOfOutputFrames.txt"}} */
-{
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
- vdcAssert(instance);
-
- return ((instance->currFrame) ? 1 : 0);
-}
-
-
-/* {{-output"vdcGetTR.txt"}} */
-/*
- * vdcGetTR
- *
- *
- * Parameters:
- * inpBuffer buffer containing the frame data,
- * must start with a PSC
- * tr temporal reference
- *
- * Function:
- * Gets the temporal reference field from the input buffer.
- * Notice that the validity of the bitstream is not checked.
- * This function does not support enhanced temporal reference
- * (ETR) defined in section 5.1.8 of the H.263 recommendation.
- *
- * Returns:
- * Nothing
- *
- *
- */
-
-void vdcGetTR(void *inpBuffer, u_int8 *tr)
-/* {{-output"vdcGetTR.txt"}} */
-{
- const u_char
- *tmpBuffer = (u_char *) inpBuffer;
-
- *tr = (u_int8) (((tmpBuffer[2] & 2) << 6) | ((tmpBuffer[3] & 252) >> 2));
-}
-
-
-/* {{-output"vdcIsEOSReached.txt"}} */
-/*
- * vdcIsEOSReached
- *
- *
- * Parameters:
- * hInstance handle of instance data
- *
- * Function:
- * This function returns 1 if the EOS code has been reached during
- * the decoding. Otherwise, it returns 0.
- *
- * Returns:
- * See above.
- *
- */
-
-int vdcIsEOSReached(vdcHInstance_t hInstance)
-/* {{-output"vdcIsEOSReached.txt"}} */
-{
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
- vdcAssert(instance);
-
- return instance->fEOS;
-}
-
-
-/* {{-output"vdcIsINTRA.txt"}} */
-/*
- * vdcIsINTRA
- *
- *
- * Parameters:
- * hInstance handle of instance data
- * frameStart pointer to memory chunk containing a frame
- * frameLength number of bytes in frame
- *
- * Function:
- * This function returns 1 if the passed frame is an INTRA frame.
- * Otherwise the function returns 0.
- *
- * Returns:
- * See above.
- *
- *
- */
-
-int vdcIsINTRA(
- vdcHInstance_t hInstance,
- void *frameStart,
- unsigned frameLength)
-/* {{-output"vdcIsINTRA.txt"}} */
-{
- bibBuffer_t *tmpBitBuffer;
- int fINTRA = 0, bitErrorIndication, syncCode, vdxStatus;
- int16 error = 0;
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
- vdxGetPictureHeaderInputParam_t vdxIn;
- vdxPictureHeader_t vdxOut;
-
- vdcAssert(instance);
-
- tmpBitBuffer = bibCreate(frameStart, frameLength, &error);
- if (!tmpBitBuffer || error)
- return 0;
-
- syncCode = sncCheckSync(tmpBitBuffer, &(vdxIn.numStuffBits), &error);
-
- if (syncCode == SNC_PSC && error == 0) {
-
- /* Note: Needs to be changed when support for custom PCF or scalability mode
- is added */
- vdxIn.fCustomPCF = 0;
- vdxIn.fScalabilityMode = 0;
- vdxIn.fRPS = instance->fRPS;
- vdxIn.flushBits = bibFlushBits;
- vdxIn.getBits = bibGetBits;
- vdxIn.showBits = bibShowBits;
-
- vdxStatus = vdxGetPictureHeader(tmpBitBuffer, &vdxIn, &vdxOut,
- &bitErrorIndication);
-
- if (vdxStatus >= 0 && bitErrorIndication == 0)
- fINTRA = (vdxOut.pictureType == VDX_PIC_TYPE_I);
- }
-
- bibDelete(tmpBitBuffer, &error);
-
- return fINTRA;
-}
-
-
-/* {{-output"vdcIsINTRAGot.txt"}} */
-/*
- * vdcIsINTRAGot
- *
- *
- * Parameters:
- * hInstance handle of instance data
- *
- * Function:
- * This function returns 1 if the an INTRA frame has been decoded
- * during the lifetime of the instance. Otherwise, it returns 0.
- *
- * Returns:
- * See above.
- *
- *
- */
-
-int vdcIsINTRAGot(vdcHInstance_t hInstance)
-/* {{-output"vdcIsEOSReached.txt"}} */
-{
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
- vdcAssert(instance);
-
- return instance->fIntraGot;
-}
-
-
-/* {{-output"vdcLoad.txt"}} */
-/*
- * vdcLoad
- *
- *
- * Parameters:
- * None.
- *
- * Function:
- * This function initializes the Video Decoder Core module meaning
- * all the data common to all Video Decoder Core instances.
- * vdcLoad has to be called before any other function of this module
- * is used.
- *
- * Returns:
- * >= 0 if succeeded
- * < 0 if failed
- *
- *
- */
-
-int vdcLoad(void)
-/* {{-output"vdcLoad.txt"}} */
-{
- if (dblLoad() < 0)
- return VDC_ERR;
-
- return VDC_OK;
-}
-
-
-/* {{-output"vdcOpen.txt"}} */
-/*
- * vdcOpen
- *
- *
- * Parameters:
- * imageStore pointer to image store instance
- * numReferenceFrames 1 if the Reference Picture Selection (RPS)
- * mode (Annex N) should not be used,
- * >1 tells how many reference images
- * are stored in the RPS mode
- * fudInstance pointer to Fast Update module instance
- * hParent handle of Video Decoder Engine instance
- * that created this VDC instance
- *
- * Function:
- * This function creates and initializes a new Video Decoder Core instance.
- *
- * Returns:
- * a handle to the created instance,
- * or NULL if the function fails
- *
- *
- */
-
-vdcHInstance_t vdcOpen(
- vdeIms_t *imageStore,
- int numReferenceFrames,
- void *hParent)
-{
- vdcInstance_t *instance;
-
- vdcAssert(numReferenceFrames >= 1);
-
- instance = (vdcInstance_t *) vdcMalloc(sizeof(vdcInstance_t));
- if (!instance)
- return NULL;
- memset(instance, 0, sizeof(vdcInstance_t));
-
- instance->prevPicHeader = (vdxPictureHeader_t *)vdcMalloc( sizeof( vdxPictureHeader_t ));
- if ( instance->prevPicHeader == NULL ) {
- deb("vdcOpen, MALLOC for prevPicHeader failed.\n");
- goto errPHOpen;
- }
- instance->fPrevPicHeaderReliable = 1;
-
- instance->imageStore = imageStore;
-
- instance->numAnnexNScalabilityLayers = -1; /* Indicates no decoded frames */
-
- instance->fGFIDShouldChange = 0;
- instance->gfid = -1;
-
- instance->nOfDecodedFrames = 0;
-
- instance->hParent = hParent;
- instance->snapshotStatus = -1;
-
- return (vdcHInstance_t) instance;
-
- /* Error cases: release everything in reverse order */
- errPHOpen:
-
- vdcDealloc(instance);
- return NULL;
-}
-/* {{-output"vdcOpen.txt"}} */
-
-
-/* {{-output"vdcRestartVideo.txt"}} */
-/*
- * vdcRestartVideo
- *
- *
- * Parameters:
- * hInstance handle of instance data
- *
- * Function:
- * Resets the instance data but does not deallocate the allocated buffers.
- * After this function vdcDecodeFrame can be called as if no data for this
- * instance has been decoded.
- *
- * Note:
- * This function is obsolete and not used anymore. If it is needed again,
- * it should be re-implemented.
- *
- * Returns:
- * Nothing
- *
- *
- */
-
-void vdcRestartVideo(vdcHInstance_t hInstance)
-/* {{-output"vdcRestartVideo.txt"}} */
-{
- vdcInstance_t *instance = (vdcInstance_t *) hInstance;
-
- if (instance)
- memset(instance, 0, sizeof(vdcInstance_t));
-}
-
-
-
-
-
-/*
- * Local functions
- */
-
-/*
- * vdcFillCommonPartsOfImb
- *
- *
- * Parameters:
- * instance instance data
- * numOfCodedMBs number of coded macroblocks
- * imb pointer to image buffer to fill
- *
- * Function:
- * This function fills the passed image buffer according to the latest
- * decoding results. Only those parts of the image buffer are filled
- * which can be composed with the presence of another image buffer,
- * e.g. the P image buffer corresponding to the B image buffer.
- *
- * Returns:
- * Nothing
- *
- *
- */
-
-static void vdcFillCommonPartsOfImb(
- vdcInstance_t *instance,
- int numOfCodedMBs,
- vdeImb_t *imb)
-{
- vdcAssert(imb);
- vdcAssert(instance);
-
- imb->drawItem->param.dwFlags = 0;
- imb->drawItem->param.lTime = instance->frameNum;
-
- /* Note: for now, convert whole frame */
- imb->drawItem->extParam.flags = 0;
- /* Else one could convert just coded MBs as follows: */
- /* imb->drawItem->extParam.flags = (fBPart) ? 0 : REN_EXTDRAW_NEW_SOURCE; */
-
- imb->drawItem->extParam.rate = 30000;
- imb->drawItem->extParam.scale = 1001;
- imb->drawItem->extParam.numOfCodedMBs = numOfCodedMBs;
-
- /* imb->drawItem->retFrame and imb->drawItem->retFrameParam are set by
- the caller */
-
- imb->fReferenced = 1;
- imb->tr = instance->pictureParam.tr;
-}
-
-
-/*
- * vdcFillImageBuffers
- *
- *
- * Parameters:
- * instance instance data
- * numOfCodedMBs number of coded macroblocks
- * imbP pointer to image buffer of P or I frame
- *
- * Function:
- * This function fills the passed image buffers according to the latest
- * decoding results.
- *
- * Returns:
- * >= 0 if the function was successful
- * < 0 if an error occured
- *
- *
- */
-
-/* Codec and renderer dependent */
-int vdcFillImageBuffers(
- vdcInstance_t *instance,
- int numOfCodedMBs,
- vdeImb_t *imbP)
-{
- /* Table to convert from lumiance quantization parameter to chrominance
- quantization parameter if Modified Quantization (Annex T) is in use. */
- static const int yToUVQuantizer[32] =
- {0,1,2,3,4,5,6,6,7,8,9,9,10,10,11,11,12,
- 12,12,13,13,13,14,14,14,14,14,15,15,15,
- 15,15};
-
- int
- firstQPIndex, /* the index of the first non-zero quantizer */
-
- *yQuantParams = imbP->yQuantParams,
- /* array of Y quantizers in scan-order */
-
- *uvQuantParams = imbP->uvQuantParams,
- /* array of UV quantizers in scan-order */
-
- numMBsInPicture, /* number of macroblocks in the image */
-
- i; /* loop variable */
-
- vdcAssert(imbP);
- vdcAssert(instance);
-
- /*
- * Fill basic stuff
- */
-
- vdcFillCommonPartsOfImb(instance, numOfCodedMBs, imbP);
-
- /*
- * Calculate quantizer arrays for loop/post-filtering
- */
-
- numMBsInPicture = instance->pictureParam.lumMemWidth *
- instance->pictureParam.lumMemHeight / 256;
-
- /* Get the index of the first non-zero quantizer in scan-order */
- for (firstQPIndex = 0; firstQPIndex < numMBsInPicture; firstQPIndex++) {
- if (yQuantParams[firstQPIndex] > 0)
- break;
- }
-
- /* Assert that at least one macroblock is decoded successfully */
- vdcAssert(firstQPIndex < numMBsInPicture);
-
- /* Replace the first zero quantizers with the first non-zero quantizer
- (in scan-order) */
- for (i = 0; i < firstQPIndex; i++)
- yQuantParams[i] = yQuantParams[firstQPIndex];
-
- /* Replace all other zero quantizers with the predecessor (in scan-order) */
- for (i = firstQPIndex; i < numMBsInPicture; i++) {
- if (yQuantParams[i] == 0)
- yQuantParams[i] = yQuantParams[i - 1];
- }
-
- /* If Modified Quantization is in use */
- if (instance->pictureParam.fMQ) {
- /* Convert Y quantizers to UV quantizers */
- for (i = 0; i < numMBsInPicture; i++)
- uvQuantParams[i] = yToUVQuantizer[yQuantParams[i]];
- }
- else
- /* Copy Y quantizers to UV quantizers */
- memcpy(uvQuantParams, yQuantParams, numMBsInPicture * sizeof(int));
-
-
- return VDC_OK;
-}
-
-// End of File