diff -r 951a5db380a0 -r e0b5df5c0969 videoeditorengine/h263decoder/src/vdeti.cpp --- a/videoeditorengine/h263decoder/src/vdeti.cpp Fri Jan 29 14:08:33 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,445 +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: -* Frame decoding function. -* -*/ - - - -/* - * Includes - */ - -#include "h263dconfig.h" -#include "vdeti.h" -#include "debug.h" -#include "sync.h" -#include "vde.h" -#include "vdemain.h" -#include "core.h" -/* MVE */ -#include "MPEG4Transcoder.h" - -/* - * Local function prototype - */ - -static int vdeSeekNextValidDecodingStartPosition( - vdeInstance_t *instance, CMPEG4Transcoder *hTranscoder); - - -/* - * Functions visible outside this module - */ - -/* {{-output"vdeDecodeFrame.txt"}} */ -/* - * vdeDecodeFrame - * - * Parameters: - * hInstance instance data - * - * Function: - * This function decodes the bitstream by using - * vdcDecodeFrame until it gets at least one decoded frame. It also shows - * the resulting frames (by calling renDraw). - * In addition, the function handles the parameter updating synchronization - * by calling the VDE Queue module. - * - * This function is intended to be called from the thread main function. - * It won't return until it gets a new decoded frame. If the bitstream - * is totally corrupted, this feature might cause a considerable delay - * in the execution of the thread main function. - * - * Returns: - * VDE_OK if the function was successful - * VDE_OK_EOS if the end of stream has been reached - * VDE_OK_BUT_FRAME_USELESS if the function behaved normally, but no - * decoding output was produced due to too - * corrupted input frame - * VDE_ERROR if a fatal error, from which the decoder - * cannot be restored, has occured - * VDE_ERROR_HALTED the instance is halted, it should be closed - * - * - */ - - -int vdeDecodeFrame(vdeHInstance_t hInstance, int /*aStartByteIndex*/, int /*aStartBitIndex*/, CMPEG4Transcoder *hTranscoder) -/* {{-output"vdeDecodeFrame.txt"}} */ -{ - int - sncCode, /* sync code from which to start decoding */ - numOutputFrames, /* number of output frames, 2 for PB-frames, - 1 otherwise */ - fOutputUseless, /* 1 if frame(s) too corrupted to display, - 0 otherwise */ - i, /* loop variable */ - vdcStatus, /* return value of vdcDecodeFrame or - vdcDecodeMPEGVop */ - fFullPictureFreeze = 0; /* set to 1 if full-picture freeze is - going on as described in section L.4 - of the H.263 recommendation */ - - vdeInstance_t - *instance = (vdeInstance_t *) hInstance; - /* pointer to instance structure */ - - /* MVE */ - int StartByteIndex ; - int StartBitIndex ; - - instance->fPrevFrameDecoded = 0; - - /* If the instance is in the EOS state */ - if (instance->state == VDE_STATE_EOS) { - - /* If MPEG-4 stream, visual_object_sequence_end_code terminates - a visual session, and therefore we return. - If H.263 stream, EOS (End of Sequence) has no semantics, and - therefore we return only if MoVi buffers wrapper indicates so. */ - if (instance->fMPEG4) - /* Return an indication that the stream has ended */ - return VDE_OK_EOS; - } - - /* If the instance is in the "Halted" state */ - if (instance->state == VDE_STATE_HALTED) { - - /* If the current frame is INTRA */ - if (vdcIsINTRA(instance->vdcHInstance, instance->inBuffer->baseAddr, 20)) { - /* Reset the state and try to decode */ - instance->state = VDE_STATE_MIDDLE; - deb("vdeDecodeFrame: Trying to recover from halted state.\n"); - } - - else { - deb("vdeDecodeFrame: ERROR - already halted.\n"); - /* Return an indication that the stream cannot be decoded further */ - return VDE_ERROR_HALTED; - } - } - - /* If the instance state indicates that we should resynchronize to INTRA - frame */ - if (instance->state == VDE_STATE_RESYNC) { - - /* If the current frame is INTRA */ - if (vdcIsINTRA(instance->vdcHInstance, instance->inBuffer->baseAddr, 20)) { - /* Reset the state and continue decoding */ - instance->state = VDE_STATE_MIDDLE; - } - - else - return VDE_OK; - } - - /* Read a synchronization code from the current position of the - bitstream or seek the next valid sync code to start decoding */ - sncCode = vdeSeekNextValidDecodingStartPosition(instance, hTranscoder); - - /* If error in seeking sync code */ - if (sncCode < 0) - /* Return error */ - return sncCode; - - /* Else if sync code not found - Note: Can only happen in "one frame per one input bit buffer" case, - i.e. not in videophone */ - else if (sncCode == SNC_NO_SYNC) - /* Note: One could send a INTRA picture request if such a service is - available. However, it is assumed that the service is not available - in this non-videophone application, and therefore no update is - requested. */ - - /* Return indication of useless (too corrupted) frame */ - return VDE_OK_BUT_FRAME_USELESS; - - /* Set the instance to the "Middle" state */ - instance->state = VDE_STATE_MIDDLE; - - /* If the synchronization code == EOS */ - if (sncCode == SNC_EOS) { - - /* Set the instance to the EOS state */ - instance->state = VDE_STATE_EOS; - - /* Return an indication that the stream ended */ - return VDE_OK_EOS; - } - - /* MVE */ - StartByteIndex = instance->inBuffer->getIndex; - StartBitIndex = instance->inBuffer->bitIndex; - - - - - /* Decode a frame */ - - if (instance->fMPEG4) { - - vdcStatus = vdcDecodeMPEGVop(instance->vdcHInstance, instance->inBuffer, - instance->outBuffer, instance->bufEdit, instance->iColorEffect, instance->iGetDecodedFrame, - StartByteIndex, StartBitIndex, hTranscoder); - } - else - { - - - vdcStatus = vdcDecodeFrame(instance->vdcHInstance, instance->inBuffer, - instance->outBuffer, instance->bufEdit, instance->iColorEffect,instance->iGetDecodedFrame, hTranscoder); - - } - - - if (vdcStatus < 0) { - deb("vdeDecodeFrame: ERROR - vdcDecodeFrame failed.\n"); - - instance->state = VDE_STATE_HALTED; - - if (vdcStatus == VDC_ERR_NO_INTRA) - return VDE_ERROR_NO_INTRA; - - return VDE_ERROR_HALTED; - } - - /* If EOS occured */ - if (vdcIsEOSReached(instance->vdcHInstance)) - instance->state = VDE_STATE_EOS; - - /* If the decoded frame is totally corrupted */ - if ((vdcStatus == VDC_OK_BUT_FRAME_USELESS) || (vdcStatus == VDC_OK_BUT_NOT_CODED)) { - - /* If continuous input buffer */ - - fOutputUseless = 1; - } - - else { - fOutputUseless = 0; - instance->fPrevFrameDecoded = 1; - } - - - /* If H.263 bitstream and decoding (partially) successful */ - if (!instance->fMPEG4 && !fOutputUseless) { - } - - /* - * Return decoded images to the image store and - * send them to Video Renderer if needed - */ - - numOutputFrames = vdcGetNumberOfOutputFrames(instance->vdcHInstance); - - /* Loop to handle each output frame separately */ - for (i = 0; i < numOutputFrames; i++) { - vdeImsItem_t *imsItem; - - imsItem = vdcGetImsItem(instance->vdcHInstance, i); - - vdeAssert(imsItem); - - /* If the frame is useless */ - if (fOutputUseless) { - - /* Return the image buffer to the "Free" store */ - if (vdeImsPutFree(&instance->imageStore, imsItem) < 0) { - deb("vdeDecodeFrame: ERROR - vdeImsPutFree failed.\n"); - instance->state = VDE_STATE_HALTED; - return VDE_ERROR_HALTED; - } - } - - /* Else the frame is ok */ - else { - - vdeImb_t *imb; - - vdeImsStoreItemToImageBuffer(imsItem, &imb); - - - /* If full-picture freeze requested */ - if (fFullPictureFreeze) { - - /* Return the image buffer to the image buffer store - but don't send it to the renderer */ - if (vdeImsPut(&instance->imageStore, imsItem) < 0) { - deb("vdeDecodeFrame: ERROR - vdeImsPut failed.\n"); - instance->state = VDE_STATE_HALTED; - return VDE_ERROR_HALTED; - } - } - - /* Else normal displaying */ - else { - h263dFrameType_t frameType; - int renStatus; - u_int32 renHandle; - - /* Get renderer for the output frame */ - frameType.scope = H263D_FTYPE_NDEF; - frameType.width = renDriBitmapWidth(imb->drawItem); - frameType.height = renDriBitmapHeight(imb->drawItem); - - renStatus = vdeFrtGetItem(&instance->renStore, &frameType, &renHandle); - - if (renStatus == VDE_OK_NOT_AVAILABLE) - renHandle = 0; - - - if (renStatus >= 0) { - /* Return the image buffer to the image buffer store - and send it to the renderer (if possible) */ - if (vdeImsPut(&instance->imageStore, imsItem) < 0) { - deb("vdeDecodeFrame: ERROR - vdeImsPut failed.\n"); - instance->state = VDE_STATE_HALTED; - return VDE_ERROR_HALTED; - } - } - - else { - deb("vdeDecodeFrame: ERROR - vdeFrtGetItem failed.\n"); - instance->state = VDE_STATE_HALTED; - return VDE_ERROR_HALTED; - } - } - - } - } - - // fatal errors were returned already earlier - switch ( vdcStatus ) - { - case VDC_OK_BUT_FRAME_USELESS: - { - return VDE_OK_BUT_FRAME_USELESS; - } -// break; - case VDC_OK_BUT_NOT_CODED: - { - return VDE_OK_BUT_NOT_CODED; - } -// break; - default: - { - break; -// return VDE_OK; - } - } - -return VDE_OK; -} - - -/* - * Local functions - */ - -/* - * vdeSeekNextValidDecodingStartPosition - * - * Parameters: - * instance instance data - * - * Function: - * This function seeks the next synchronization position from the bitstream - * (starting from the current position) from which the decoder can start - * decoding. - * - * Returns: - * VDE_ERROR if a fatal error, from which the decoder - * cannot be restored, has occured - * - * SNC_NO_SYNC if no suitable sync code was found - * (can happen only in non-videophone case - * where only one frame is in one bit input - * buffer) - * - * SNC_PSC H.263 Picture Start Code found - * - * SNC_EOS H.263 End of Sequence found or - * MPEG-4 EOB found - * - * SNC_GBSC H.263 GBSC found - * - * SNC_VOP MPEG-4 VOP - * SNC_GOV MPEG-4 GOV - * - * - */ - -static int vdeSeekNextValidDecodingStartPosition( - vdeInstance_t *instance, CMPEG4Transcoder *hTranscoder) -{ - int - sncCode = SNC_NO_SYNC; /* sync code in current position */ - int16 - error = 0; /* error code returned from sync module */ - - /* Note: For the first INTRA of the stream, - do the H.263 vs. non-H.263 stream decision in a higher level, - now assume that there has simply been a bit error in the header, - and one should try from the next PSC */ - - if (instance->fMPEG4) { - vdcInstance_t* vdcinst = (vdcInstance_t *) instance->vdcHInstance; - int fcode = vdcinst->pictureParam.fcode_forward; - - while (sncCode != SNC_VOP && - sncCode != SNC_GOV && - sncCode != SNC_EOB && - sncCode != SNC_VIDPACK) { - - sncCode = sncSeekMPEGStartCode(instance->inBuffer, (fcode ? fcode : 1), 1 /* VPs not relevant at this stage */, 0, &error); - if (error == ERR_BIB_NOT_ENOUGH_DATA) - return SNC_NO_SYNC; - else if (error) - return VDE_ERROR; - else if (sncCode == SNC_VOS) - { - /* Visual Object Sequence start code found, VOS + VO + VOL headers have to be parsed now.. */ - /* (The bitstream may contain multiple instances of VOS start codes before Visual - Object Sequence end code) */ - if (vdcDecodeMPEGVolHeader(vdcinst, instance->inBuffer, hTranscoder) != 0) - return VDE_ERROR; - } - } - - if (sncCode == SNC_EOB) - sncCode = SNC_EOS; - } - else - { - while ( - sncCode != SNC_PSC && - sncCode != SNC_EOS && - sncCode != SNC_GBSC ) { - - sncCode = sncSeekSync(instance->inBuffer, &error); - if (error == ERR_BIB_NOT_ENOUGH_DATA) - return SNC_NO_SYNC; - else if (error) - return VDE_ERROR; - } - } - - return sncCode; -} - - -// End of file