videoeditorengine/h263decoder/src/decpich_mpeg.cpp
changeset 9 d87d32eab1a9
parent 0 951a5db380a0
equal deleted inserted replaced
0:951a5db380a0 9:d87d32eab1a9
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * Picture header decoding functions (MPEG-4).
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 #include "h263dConfig.h"
       
    23 #include "mpegcons.h"
       
    24 #include "sync.h"
       
    25 #include "decpich.h"
       
    26 #include "debug.h"
       
    27 #include "vdeims.h"
       
    28 #include "vdeimb.h"
       
    29 #include "viddemux.h"
       
    30 
       
    31 
       
    32 /*
       
    33  * Global functions
       
    34  */
       
    35 
       
    36 /*
       
    37  * dphGetMPEGVolHeader
       
    38  *    
       
    39  *
       
    40  * Parameters:
       
    41  *    hInstance                  instance data
       
    42  *
       
    43  * Function:
       
    44  *   This function decodes the Video Object Header and the VOL Header
       
    45  *   and initializes the fields of vdcInstance which are set in these
       
    46  *   headers. Check and reports (generating error messages) if the header
       
    47  *   shows a configuration on feature which is not supported by the
       
    48  *   Simple Video Object Profile of MPEG4
       
    49  *
       
    50  * Returns:
       
    51  *    VDE_OK                     if the function was successful
       
    52  *    VDE_ERROR                  if a fatal error, from which the decoder
       
    53  *                               cannot be restored, has occured
       
    54  *
       
    55  */
       
    56 
       
    57 int dphGetMPEGVolHeader(dphInOutParam_t *inOutParam, CMPEG4Transcoder *hTranscoder)
       
    58 {
       
    59    vdcInstance_t *instance = inOutParam->vdcInstance;
       
    60    bibBuffer_t *inBuffer = inOutParam->inBuffer;
       
    61    int bitErrorIndication = 0;
       
    62    vdxVolHeader_t volHeader;   
       
    63 
       
    64    /* read the Stream headers from the bitstream */
       
    65    if ((vdxGetVolHeader(inBuffer, &volHeader, &bitErrorIndication, 0, 0, 0, hTranscoder) != VDX_OK) ||
       
    66        (bitErrorIndication != 0)) {
       
    67       return DPH_ERR;
       
    68    }   
       
    69 
       
    70    /* copy the useful VOL parameters to pictureParam or the core data structure */
       
    71    instance->pictureParam.vo_id = volHeader.vo_id;
       
    72    instance->pictureParam.vol_id = volHeader.vol_id;
       
    73    instance->pictureParam.time_increment_resolution = volHeader.time_increment_resolution;
       
    74 
       
    75      /* MVE */
       
    76    instance->pictureParam.fixed_vop_rate = volHeader.fixed_vop_rate;
       
    77 
       
    78    instance->pictureParam.lumWidth = volHeader.lumWidth;
       
    79    instance->pictureParam.lumHeight = volHeader.lumHeight;
       
    80 
       
    81    if (volHeader.lumWidth%16)
       
    82        instance->pictureParam.lumMemWidth = (((volHeader.lumWidth >>4/*/16*/) + 1) <<4/** 16*/);
       
    83    else
       
    84        instance->pictureParam.lumMemWidth = volHeader.lumWidth;
       
    85    
       
    86    if (volHeader.lumHeight%16)
       
    87        instance->pictureParam.lumMemHeight = (((volHeader.lumHeight >>4/*/16*/) + 1) <<4/** 16*/);
       
    88    else
       
    89        instance->pictureParam.lumMemHeight = volHeader.lumHeight;
       
    90    
       
    91    instance->pictureParam.error_res_disable = volHeader.error_res_disable;
       
    92    instance->pictureParam.data_partitioned = volHeader.data_partitioned;
       
    93    instance->pictureParam.reversible_vlc = volHeader.reversible_vlc;
       
    94 
       
    95    /* copy the got user data to the core data structure */
       
    96    if (volHeader.user_data != NULL) {
       
    97        instance->user_data = (char *) malloc(MAX_USER_DATA_LENGTH);
       
    98    
       
    99        volHeader.user_data_length = 
       
   100            ((instance->user_data_length + volHeader.user_data_length) >= MAX_USER_DATA_LENGTH) ?
       
   101            (MAX_USER_DATA_LENGTH - instance->user_data_length) : volHeader.user_data_length;
       
   102        
       
   103        memcpy(
       
   104            instance->user_data + instance->user_data_length, 
       
   105            volHeader.user_data, 
       
   106            volHeader.user_data_length);
       
   107 
       
   108        instance->user_data_length += volHeader.user_data_length;
       
   109 
       
   110        free(volHeader.user_data);
       
   111    }
       
   112 
       
   113    return DPH_OK;
       
   114 }
       
   115 
       
   116 /* {{-output"dphGetMPEGVopHeader.txt"}} */
       
   117 /*
       
   118  * dphGetMPEGVopHeader
       
   119  *    
       
   120  *
       
   121  * Parameters:
       
   122  *    inOutParam                 input/output parameters, these parameters
       
   123  *                               may be modified in the function
       
   124  *    outParam                   output parameters
       
   125  *    bitErrorIndication         bit error indication, see biterr.h for
       
   126  *                               the possible values
       
   127  *
       
   128  * Function:
       
   129  *    This function gets and decodes an MPEG Vop header which should start
       
   130  *    with a VOP start_code at the current position of the bit buffer.
       
   131  *    At first, the function reads the picture header fields from the bitstream.
       
   132  *    Then, it checks whether the values of the fields are supported.
       
   133  *    An unsupported value is interpreted as a bit error. Finally,
       
   134  *    the function updates VDC instance data and output parameters
       
   135  *    (according to the new picture header).
       
   136  *
       
   137  * Returns:
       
   138  *    >= 0                       the function was successful
       
   139  *    < 0                        an error occured
       
   140  *
       
   141  */
       
   142 
       
   143 int dphGetMPEGVopHeader(
       
   144    const dphInParam_t *inParam,
       
   145    dphInOutParam_t *inOutParam,
       
   146    dphOutParam_t *outParam,
       
   147    int *bitErrorIndication)
       
   148 /* {{-output"dphGetMPEGVopHeader.txt"}} */
       
   149 {
       
   150    bibBuffer_t *inBuffer = inOutParam->inBuffer;
       
   151    u_char fPrevIntraGot;         /* Non-zero if an INTRA frame has been decoded
       
   152                                     before the current frame */
       
   153    vdxGetVopHeaderInputParam_t picHdrIn;
       
   154    vdxVopHeader_t picHeader;
       
   155    vdcInstance_t *instance = inOutParam->vdcInstance;
       
   156    vdcPictureParam_t *pictureParam = &instance->pictureParam;
       
   157    int fInterFrame;              /* non-zero = INTER frame, 0 = INTRA frame */
       
   158    int ret = DPH_OK, curr_mod_time_base=0;
       
   159    int16 error = 0;
       
   160    int32 currFrameNum=0;
       
   161 
       
   162    /* In normal case read the picture header from the bitstream. 
       
   163       This function can be also called just to initialize the default 
       
   164       picture header parameters and allocate image buffers, but not read
       
   165       the picture header from bitstream. This is used when the picture
       
   166       header has been lost (e.g. packet loss) but decoding is continued */
       
   167       
       
   168    if (inParam->fReadBits) {
       
   169 
       
   170    /* 
       
   171     * Get picture header 
       
   172     */
       
   173 
       
   174    picHdrIn.time_increment_resolution = pictureParam->time_increment_resolution;
       
   175 
       
   176      /* MVE */
       
   177    int dummy1, dummy2, dummy3, dummy4; /* not used for processing */
       
   178    ret = vdxGetVopHeader(inBuffer, &picHdrIn, &picHeader, 
       
   179          &dummy1, &dummy2, &dummy3, &dummy4,
       
   180          bitErrorIndication);
       
   181 
       
   182    if ( ret < 0 )
       
   183       return DPH_ERR;
       
   184    else if ( ret > 0 ) {
       
   185      ret = DPH_OK_BUT_BIT_ERROR;
       
   186      goto updateInstanceData;
       
   187    } else {
       
   188      ret = DPH_OK;
       
   189    }
       
   190 
       
   191    /* 
       
   192     * Check picture header validity 
       
   193     */
       
   194 
       
   195    /* Local parameters needed in validity check (and possibly afterwards) */
       
   196    fPrevIntraGot = instance->fIntraGot;
       
   197    fInterFrame = (picHeader.coding_type == VDX_VOP_TYPE_P);
       
   198 
       
   199 
       
   200    if (picHeader.time_base_incr < 0 || picHeader.time_base_incr > 60) {
       
   201       if ( *bitErrorIndication ) {
       
   202          ret = DPH_OK_BUT_BIT_ERROR;
       
   203          goto updateInstanceData;
       
   204       }
       
   205    }
       
   206 
       
   207    curr_mod_time_base = pictureParam->mod_time_base + picHeader.time_base_incr;
       
   208 
       
   209    currFrameNum = (int) ((curr_mod_time_base + 
       
   210       ((double) picHeader.time_inc) / ((double) pictureParam->time_increment_resolution)) *
       
   211       30.0 + 0.001);
       
   212 
       
   213    if ((currFrameNum <= instance->frameNum) && 
       
   214       (instance->frameNum > 0)) {
       
   215       if (*bitErrorIndication) {
       
   216          ret = DPH_OK_BUT_BIT_ERROR;
       
   217          goto updateInstanceData;
       
   218       } else {
       
   219          /* this can happen if a previous picture header is lost and it had
       
   220             mod_time_base increase information. */
       
   221          int i;
       
   222          int32 tryFrameNum=0;
       
   223          for (i=1;i<5;i++) {
       
   224             tryFrameNum = (int) (((curr_mod_time_base+i) + 
       
   225                ((double) picHeader.time_inc) / ((double) pictureParam->time_increment_resolution)) *
       
   226                30.0 + 0.001);
       
   227             if (tryFrameNum > instance->frameNum) {
       
   228                currFrameNum = tryFrameNum;
       
   229                curr_mod_time_base += i;
       
   230                ret = DPH_OK;
       
   231                break;
       
   232             }
       
   233          }
       
   234          if (i==5) {
       
   235             ret = DPH_OK_BUT_BIT_ERROR;
       
   236             goto updateInstanceData;
       
   237          }
       
   238       }
       
   239    }
       
   240 
       
   241    /* If no INTRA frame has ever been decoded and the current frame is INTER */
       
   242    if (!fPrevIntraGot && fInterFrame) {
       
   243       deb("ERROR. No I-vop before a P-vop\n");
       
   244       return DPH_ERR_NO_INTRA;
       
   245 
       
   246    }
       
   247 
       
   248    /* fcode can have only the valid values 1..7 */
       
   249    if(picHeader.fcode_forward == 0) {
       
   250       ret = DPH_OK_BUT_BIT_ERROR;
       
   251       goto updateInstanceData;
       
   252    }
       
   253 
       
   254    /* quant can not be zero */
       
   255    if(picHeader.quant == 0) {
       
   256       ret = DPH_OK_BUT_BIT_ERROR;
       
   257       goto updateInstanceData;
       
   258    }
       
   259 
       
   260    } /* end fReadBits */
       
   261 
       
   262    /* Now, the picture header is considered to be error-free,
       
   263       and its contents are used to manipulate instance data */
       
   264 
       
   265 updateInstanceData:
       
   266 
       
   267    /*
       
   268     * Update instance data and output parameters
       
   269     */
       
   270 
       
   271    /* some parameters need to be set if error has been detected, for initializing */
       
   272    if (!inParam->fReadBits || (ret == DPH_OK_BUT_BIT_ERROR)) {
       
   273       picHeader.rounding_type = 0;
       
   274       picHeader.fcode_forward = 1;
       
   275       picHeader.coding_type = 1;
       
   276    } else {    
       
   277       /* Update frame numbers */
       
   278       pictureParam->time_base_incr = picHeader.time_base_incr;
       
   279       pictureParam->mod_time_base = curr_mod_time_base;
       
   280       pictureParam->time_inc = picHeader.time_inc;
       
   281       instance->frameNum = currFrameNum;
       
   282    }
       
   283 
       
   284    /* Update picture parameters */
       
   285    pictureParam->trd = (instance->frameNum % 256) - pictureParam->tr;
       
   286    pictureParam->tr = instance->frameNum % 256;
       
   287 
       
   288    pictureParam->pictureType = picHeader.coding_type;
       
   289 
       
   290    if (!picHeader.vop_coded) {
       
   291      return DPH_OK_BUT_NOT_CODED;
       
   292    }
       
   293 
       
   294    /* NO reference picture selection */
       
   295    outParam->trp = -1;
       
   296 
       
   297    /* No PB Frames allowed */
       
   298    instance->frameNumForBFrame = -1;
       
   299 
       
   300    /* Note: If no INTRA has been got the function has already returned */
       
   301    instance->fIntraGot = 1;
       
   302 
       
   303    pictureParam->intra_dc_vlc_thr = picHeader.intra_dc_vlc_thr;
       
   304    pictureParam->fcode_forward = picHeader.fcode_forward;
       
   305    
       
   306    outParam->pquant = picHeader.quant;
       
   307 
       
   308    /* Initialize for only 1 GOB */
       
   309    pictureParam->numMBLinesInGOB = pictureParam->lumMemHeight / 16;
       
   310    pictureParam->numMBsInMBLine = pictureParam->lumMemWidth / 16;
       
   311 
       
   312    pictureParam->numGOBs = 1;
       
   313    pictureParam->fLastGOBSizeDifferent = 0;
       
   314    pictureParam->numMBsInGOB = 
       
   315       pictureParam->numMBsInMBLine * pictureParam->numMBLinesInGOB;
       
   316    pictureParam->numMBsInLastGOB = pictureParam->numMBsInGOB;
       
   317 
       
   318    /* Rounding type */
       
   319    pictureParam->rtype = picHeader.rounding_type;
       
   320 
       
   321    /* NO channel Multiplexing */
       
   322    pictureParam->fSplitScreenIndicator = 0;
       
   323    pictureParam->fDocumentCameraIndicator = 0;
       
   324    pictureParam->fFullPictureFreezeRelease = 0;
       
   325    pictureParam->fPLUSPTYPE = 0;
       
   326    pictureParam->cpm = 0;
       
   327 
       
   328    /* All the Annexes are switched off */
       
   329    pictureParam->fSAC = 0;
       
   330    pictureParam->fRPR = 0;
       
   331    pictureParam->fRRU = 0;
       
   332    pictureParam->fCustomSourceFormat = 0;
       
   333    pictureParam->fAIC = 0;
       
   334    pictureParam->fDF = 0;
       
   335    pictureParam->fSS = 0;
       
   336    pictureParam->fRPS = 0;
       
   337    pictureParam->fISD = 0;
       
   338    pictureParam->fAIV = 0;
       
   339    pictureParam->fMQ = 0;
       
   340    pictureParam->fUMVLimited = 0;
       
   341 
       
   342    /* Unrestricted MV allowed
       
   343       OBMC NOT allowed */
       
   344    pictureParam->fUMV = 1;
       
   345    pictureParam->fAP = 0;
       
   346    pictureParam->fMVsOverPictureBoundaries = 1;
       
   347 
       
   348    /* Initialize motion vector count module */
       
   349    mvcStart(   &instance->mvcData, 
       
   350                ((instance->pictureParam.lumMemWidth >>4 /*/ 16*/) - 1), 
       
   351                pictureParam->lumWidth, 
       
   352                pictureParam->lumHeight, &error);
       
   353    /* Note: This assumes that the memory for frame->mvcData is filled with 0
       
   354       in the first time the function is called.
       
   355       (This is ensured by setting the instance data to zero when it is
       
   356       initialized in vdcOpen.) */
       
   357    if (error) {
       
   358       deb("mvcStart failed.\n");
       
   359       return DPH_ERR;
       
   360    }
       
   361 
       
   362    /* Initialize once to count parameters for the mvc module */
       
   363    {
       
   364    int r_size, scale_factor;
       
   365  
       
   366    instance->mvcData.f_code = pictureParam->fcode_forward;
       
   367    r_size = pictureParam->fcode_forward - 1;
       
   368    scale_factor = (1 << r_size);
       
   369    instance->mvcData.range = 160 * scale_factor;
       
   370    }
       
   371 
       
   372    /* Start, initialize the Advanced Intra Coding module */
       
   373    aicStart(&instance->aicData, pictureParam->numMBsInMBLine, &error);
       
   374    if (error) {
       
   375       deb("aicStart failed.\n");
       
   376       return DPH_ERR;
       
   377    }
       
   378 
       
   379    /* Get image buffers */
       
   380    {
       
   381       vdeIms_t *store = instance->imageStore;
       
   382       vdeImsItem_t *imsItem;
       
   383       vdeImb_t *imb;
       
   384       int width, height;
       
   385 
       
   386       vdeImsSetYUVNeed(store, inParam->fNeedDecodedFrame);
       
   387 
       
   388       if (vdeImsGetFree(store, instance->pictureParam.lumMemWidth, 
       
   389          instance->pictureParam.lumMemHeight, 
       
   390          &instance->currFrame) < 0)
       
   391          goto errGetFreeP;
       
   392       imsItem = instance->currFrame;
       
   393 
       
   394       if (vdeImsStoreItemToImageBuffer(imsItem, &imb) < 0)
       
   395          goto errAfterGetFreeP;
       
   396 
       
   397       if (vdeImbYUV(imb, &outParam->currYFrame, 
       
   398          &outParam->currUFrame, &outParam->currVFrame,
       
   399          &width, &height) < 0)
       
   400          goto errAfterGetFreeP;
       
   401    }
       
   402 
       
   403    return ret;
       
   404 
       
   405    /* Error condition handling,
       
   406       release everything in reverse order */
       
   407    errAfterGetFreeP:
       
   408 
       
   409    vdeImsPutFree(instance->imageStore, instance->currFrame);
       
   410    errGetFreeP:
       
   411 
       
   412    instance->currFrame = NULL;
       
   413    instance->bFrame = NULL;
       
   414 
       
   415    return DPH_ERR;
       
   416 }
       
   417 // End of File