videoeditorengine/h263decoder/src/vdeims.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 7 4c409de21d23
equal deleted inserted replaced
0:951a5db380a0 3:e0b5df5c0969
     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 * Frame memory organization module.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 /*
       
    24  * Includes
       
    25  */
       
    26 
       
    27 
       
    28 #include "h263dConfig.h"
       
    29 #include "vdeims.h"
       
    30 
       
    31 #include "debug.h"
       
    32 #include "vde.h"
       
    33 #include "vdeimb.h"
       
    34 
       
    35 
       
    36 /*
       
    37  * Structs and typedefs
       
    38  */
       
    39 
       
    40 /* Structure for a single "Free" store */
       
    41 typedef struct {
       
    42    LST_ITEM_SKELETON
       
    43 
       
    44    lifo_t freeStore;    /* a stack of free image store items */
       
    45    int lumWidth;        /* width of the items in freeStore */
       
    46    int lumHeight;       /* height of the items in freeStore
       
    47                            (in luminance pixels) */
       
    48    int fYuvNeeded;                            
       
    49 } vdeImsFreeStore_t;
       
    50 
       
    51 
       
    52 /*
       
    53  * Local function prototypes
       
    54  */
       
    55 
       
    56 static vdeImsItem_t *vdeImsAllocItem(int lumWidth, int lumHeight, int fYuvNeeded);
       
    57 
       
    58 static vdeImsFreeStore_t *vdeImsAllocFreeStore(int numFreeItems, 
       
    59    int lumWidth, int lumHeight, int fYuvNeeded);
       
    60 
       
    61 static int vdeImsDeallocFreeStore(vdeImsFreeStore_t *store);
       
    62 
       
    63 static int vdeImsGetFreeStore(lst_t *freeStoreList, int lumWidth, int lumHeight,
       
    64    vdeImsFreeStore_t **freeStore);
       
    65 
       
    66 
       
    67 /*
       
    68  * Global functions
       
    69  */
       
    70 
       
    71 /* {{-output"vdeImsChangeReference.txt"}} */
       
    72 /*
       
    73  * vdeImsChangeReference
       
    74  *    
       
    75  *
       
    76  * Parameters:
       
    77  *    store                      a pointer to an image store
       
    78  *    newItem                    new reference frame to replace a corresponding
       
    79  *                               reference frame in the image store
       
    80  *
       
    81  * Function:
       
    82  *    This function is used to change a reference frame in the image store.
       
    83  *    The function is passed a new reference frame. Then, the function
       
    84  *    searches for a reference frame with the same TR as the passed frame
       
    85  *    (from the image store). If such a frame is found, the function
       
    86  *    takes the old referece frame away from the reference store and puts
       
    87  *    it to the free or idle store depending on whether the frame has already
       
    88  *    been displayed or not. The new reference frame is placed into 
       
    89  *    the reference store. If a corresponding reference frame is not found
       
    90  *    from the image store, the function returns VDE_OK_NOT_AVAILABLE.
       
    91  *
       
    92  *    This function is intended to be used together with error concealment
       
    93  *    methods capable of repairing past frames.
       
    94  *
       
    95  * Returns:
       
    96  *    VDE_OK                     if the function was successful
       
    97  *    VDE_OK_NOT_AVAILABLE       the function behaved as expected but
       
    98  *                               a requested frame was not found
       
    99  *    VDE_ERROR                  if an error occured
       
   100  *
       
   101  *    
       
   102  */
       
   103 
       
   104 int vdeImsChangeReference(vdeIms_t *store, vdeImsItem_t *newItem)
       
   105 /* {{-output"vdeImsChangeReference.txt"}} */
       
   106 {
       
   107    vdeImsItem_t *oldItem; /* old reference frame */
       
   108 
       
   109     /* Note: This case may not be ever used, but it is supported for 
       
   110      consistency */
       
   111 
       
   112     /* If the TRs of the reference frames do not match */
       
   113     if (store->refFrame->imb->tr == newItem->imb->tr)
       
   114      /* Return with not found indication */
       
   115      return VDE_OK_NOT_AVAILABLE;
       
   116 
       
   117     /* Store the new reference to the image store */
       
   118     oldItem = store->refFrame;
       
   119     store->refFrame = newItem;
       
   120 
       
   121     /* Add the old reference to the "Free" store */
       
   122     if (vdeImsPutFree(store, oldItem) < 0)
       
   123          return VDE_ERROR;
       
   124 
       
   125    return VDE_OK;
       
   126 }
       
   127 
       
   128 
       
   129 /* {{-output"vdeImsClose.txt"}} */
       
   130 /*
       
   131  * vdeImsClose
       
   132  *    
       
   133  *
       
   134  * Parameters:
       
   135  *    store                      a pointer to an image store
       
   136  *
       
   137  * Function:
       
   138  *    This function closes the given image store.
       
   139  *    Notice that the memory pointed by the given image store pointer is not
       
   140  *    deallocated but rather it is assumed that this memory is either static
       
   141  *    or externally deallocated.
       
   142  *
       
   143  * Returns:
       
   144  *    VDE_OK                     if the function was successful
       
   145  *    VDE_ERROR                  if an error occured
       
   146  *
       
   147  *    
       
   148  */
       
   149 
       
   150 int vdeImsClose(vdeIms_t *store)
       
   151 /* {{-output"vdeImsClose.txt"}} */
       
   152 {
       
   153    vdeImb_t *imb;
       
   154    vdeImsFreeStore_t *freeStore;
       
   155    vdeImsItem_t *pItem;
       
   156 
       
   157    /* freeStoreList */
       
   158    if (lstHead(&store->freeStoreList, (void **) &freeStore) < 0)
       
   159       return VDE_ERROR;
       
   160 
       
   161    do {
       
   162       if (lstRemove(&store->freeStoreList, (void **) &freeStore) < 0)
       
   163          return VDE_ERROR;
       
   164       
       
   165       if (freeStore) {
       
   166          if (vdeImsDeallocFreeStore(freeStore) < 0)
       
   167             return VDE_ERROR;
       
   168       }
       
   169    } while (freeStore);
       
   170 
       
   171    if (lstClose(&store->freeStoreList) < 0)
       
   172       return VDE_ERROR;
       
   173 
       
   174    if (store->refFrame) {
       
   175      vdeImbDealloc(store->refFrame->imb);
       
   176      vdeDealloc(store->refFrame);
       
   177    }
       
   178 
       
   179    /* idleStore */
       
   180    if (lstHead(&store->idleStore, (void **) &pItem) < 0)
       
   181       return VDE_ERROR;
       
   182 
       
   183    do {
       
   184       if (lstRemove(&store->idleStore, (void **) &pItem) < 0)
       
   185          return VDE_ERROR;
       
   186 
       
   187       if (pItem) {
       
   188          imb = pItem->imb;
       
   189          vdeDealloc(pItem);
       
   190          vdeImbDealloc(imb);
       
   191       }
       
   192    } while (pItem);
       
   193 
       
   194    if (lstClose(&store->idleStore) < 0)
       
   195       return VDE_ERROR;
       
   196 
       
   197    return VDE_OK;
       
   198 }
       
   199 
       
   200 
       
   201 
       
   202 /* {{-output"vdeImsGetFree.txt"}} */
       
   203 /*
       
   204  * vdeImsGetFree
       
   205  *    
       
   206  *
       
   207  * Parameters:
       
   208  *    store                      a pointer to an image store
       
   209  *    lumWidth                   width of the luminance image (in pixels)
       
   210  *    lumHeight                  height of the luminance image (in pixels)
       
   211  *    item                       a free image store item
       
   212  *
       
   213  * Function:
       
   214  *    This function is used to get a free frame memory (of requested size).
       
   215  *    If a free frame memory (image store item) does not exist, a new one
       
   216  *    is allocated and initialized.
       
   217  *
       
   218  * Returns:
       
   219  *    VDE_OK                     if the function was successful
       
   220  *    VDE_ERROR                  if an error occured
       
   221  *
       
   222  *    
       
   223  */
       
   224 
       
   225 int vdeImsGetFree(vdeIms_t *store, int lumWidth, int lumHeight, 
       
   226    vdeImsItem_t **item)
       
   227 /* {{-output"vdeImsGetFree.txt"}} */
       
   228 {
       
   229    vdeImsFreeStore_t *freeStore, *tmpFreeStore;
       
   230    vdeImsItem_t *pItem;
       
   231 
       
   232    if (vdeImsGetFreeStore(&store->freeStoreList, lumWidth, lumHeight, 
       
   233       &freeStore) < 0)
       
   234       return VDE_ERROR;
       
   235 
       
   236    if (freeStore) {
       
   237       if (lifoGet(&freeStore->freeStore, (void **) &pItem) < 0)
       
   238          return VDE_ERROR;
       
   239       if (pItem) {
       
   240          *item = pItem;
       
   241          return VDE_OK;
       
   242       }
       
   243       else {
       
   244          *item = vdeImsAllocItem(lumWidth, lumHeight, store->fYuvNeeded);
       
   245          return VDE_OK;
       
   246       }
       
   247    }
       
   248 
       
   249    else {
       
   250       freeStore = vdeImsAllocFreeStore(0, lumWidth, lumHeight, store->fYuvNeeded);
       
   251       if (freeStore == NULL)
       
   252          return VDE_ERROR;
       
   253 
       
   254       if (lstHead(&store->freeStoreList, (void **) &tmpFreeStore) < 0) {
       
   255          vdeImsDeallocFreeStore(freeStore);
       
   256          return VDE_ERROR;
       
   257       }
       
   258 
       
   259       if (lstAdd(&store->freeStoreList, freeStore) < 0) {
       
   260          vdeImsDeallocFreeStore(freeStore);
       
   261          return VDE_ERROR;
       
   262       }
       
   263 
       
   264       *item = vdeImsAllocItem(lumWidth, lumHeight, store->fYuvNeeded);
       
   265       return VDE_OK;
       
   266    }
       
   267 }
       
   268 
       
   269 
       
   270 /* {{-output"vdeImsGetReference.txt"}} */
       
   271 /*
       
   272  * vdeImsGetReference
       
   273  *    
       
   274  *
       
   275  * Parameters:
       
   276  *    store                      a pointer to an image store
       
   277  *    mode                       VDEIMS_REF_LATEST = latest reference frame
       
   278  *                               VDEIMS_REF_OLDEST = oldest reference frame
       
   279  *                               VDEIMS_REF_TR = frame specified by tr,
       
   280  *                                  see also the explation for
       
   281  *                                  VDEIMS_GET_CLOSEST_REFERENCE
       
   282  *                                  in the module description at the beginning
       
   283  *                                  of this file
       
   284  *    tr                         if mode is equal to VDEIMS_REF_TR,
       
   285  *                               this parameter specifies the TR (temporal
       
   286  *                               reference) of the reference frame
       
   287  *    item                       used to return the specified reference frame
       
   288  *
       
   289  * Function:
       
   290  *    This function is used to get a reference frame memory (image store item).
       
   291  *    One can either query for the latest reference frame or for a frame
       
   292  *    having a certain temporal reference value.
       
   293  *
       
   294  * Returns:
       
   295  *    VDE_OK                     if the function was successful
       
   296  *    VDE_ERROR                  if an error occured
       
   297  *
       
   298  *    
       
   299  */
       
   300 
       
   301 int vdeImsGetReference(vdeIms_t *store, int mode, int tr, vdeImsItem_t **item)
       
   302 /* {{-output"vdeImsGetReference.txt"}} */
       
   303 {
       
   304    vdeAssert(
       
   305       mode == VDEIMS_REF_LATEST || 
       
   306       mode == VDEIMS_REF_OLDEST || 
       
   307       mode == VDEIMS_REF_TR);
       
   308 
       
   309    switch (mode) {
       
   310       case VDEIMS_REF_LATEST:
       
   311          *item = store->refFrame;
       
   312          break;
       
   313 
       
   314       case VDEIMS_REF_OLDEST:
       
   315          *item = store->refFrame;
       
   316          break;
       
   317 
       
   318       case VDEIMS_REF_TR:
       
   319          /* This section of code returns the reference frame having the same
       
   320             TR as requested. If there is no such TR, the code returns a NULL
       
   321             frame. */
       
   322          if (store->refFrame->imb->tr == tr)
       
   323              *item = store->refFrame;
       
   324          else
       
   325              *item = NULL;
       
   326          break;
       
   327    }        
       
   328 
       
   329    return VDE_OK;
       
   330 }
       
   331 
       
   332 
       
   333 /* {{-output"vdeImsOpen.txt"}} */
       
   334 /*
       
   335  * vdeImsOpen
       
   336  *    
       
   337  *
       
   338  * Parameters:
       
   339  *    store                      a pointer to an image store
       
   340  *    numFreeItems               number of initial free image store items
       
   341  *    lumWidth                   width of the luminance image (in pixels)
       
   342  *                               for free items
       
   343  *    lumHeight                  height of the luminance image (in pixels)
       
   344  *                               for free items
       
   345  *
       
   346  * Function:
       
   347  *    This function initializes the given image store. The function allocates
       
   348  *    and initializes a given number of free image store items of given size.
       
   349  *    The Reference image store is initialized to carry multiple image store
       
   350  *    items, if the Reference Picture Selection mode is indicated. Otherwise,
       
   351  *    the Reference image store carries only one image store item at a time.
       
   352  *
       
   353  * Returns:
       
   354  *    VDE_OK                     if the function was successful
       
   355  *    VDE_ERROR                  if an error occured
       
   356  *
       
   357  *    
       
   358  */
       
   359 
       
   360 int vdeImsOpen(vdeIms_t *store, int /*numFreeItems*/, int /*lumWidth*/, int /*lumHeight*/)
       
   361 {
       
   362    vdeImsFreeStore_t *freeStore;
       
   363 
       
   364    store->refFrame = 0;
       
   365 
       
   366    if (lstOpen(&store->idleStore) < 0)
       
   367       goto errIdleStore;
       
   368    
       
   369 // not ready to open freeStore yet
       
   370     freeStore = NULL;
       
   371 
       
   372    if (lstOpen(&store->freeStoreList) < 0)
       
   373       goto errOpenFreeStoreList;
       
   374 
       
   375 
       
   376    return VDE_OK;
       
   377 
       
   378    /* Error cases */
       
   379    errOpenFreeStoreList:
       
   380 
       
   381    vdeImsDeallocFreeStore(freeStore);
       
   382 
       
   383    lstClose(&store->idleStore);
       
   384    errIdleStore:
       
   385 
       
   386    return VDE_ERROR;
       
   387 }
       
   388 
       
   389 void vdeImsSetYUVNeed(vdeIms_t *store, int fYuvNeeded)
       
   390 {
       
   391     store->fYuvNeeded = fYuvNeeded;
       
   392 }
       
   393     
       
   394 /* {{-output"vdeImsPut.txt"}} */
       
   395 /*
       
   396  * vdeImsPut
       
   397  *    
       
   398  *
       
   399  * Parameters:
       
   400  *    store                      a pointer to an image store
       
   401  *    item                       image store item to put into the image store
       
   402  *
       
   403  * Function:
       
   404  *    This function is used to return a filled image store item into
       
   405  *    the image store. If the item is possibly referenced later on, it is
       
   406  *    stored into the Reference store. If the item is not referenced but
       
   407  *    it is going to be displayed, it is put into the Idle store.
       
   408  *    Otherwise, the item is put into the Free store. 
       
   409  *
       
   410  * Returns:
       
   411  *    VDE_OK                     if the function was successful
       
   412  *    VDE_ERROR                  if an error occured
       
   413  *
       
   414  *    
       
   415  */
       
   416 
       
   417 int vdeImsPut(vdeIms_t *store, vdeImsItem_t *item)
       
   418 /* {{-output"vdeImsPut.txt"}} */
       
   419 {
       
   420    vdeImb_t *imb;
       
   421 
       
   422    imb = item->imb;
       
   423 
       
   424    /* If the item is referenced */
       
   425    if (imb->fReferenced) {
       
   426 
       
   427      /* If an old reference exists */
       
   428      if (store->refFrame) {
       
   429        /* Add the old reference to the "Free" store */
       
   430        if (vdeImsPutFree(store, store->refFrame) < 0)
       
   431           return VDE_ERROR;
       
   432      }
       
   433 
       
   434      store->refFrame = item;
       
   435    }
       
   436 
       
   437    /* Else (the item is not referenced) */
       
   438    else {
       
   439      /* Add the item to the "Free" store */
       
   440      if (vdeImsPutFree(store, item) < 0)
       
   441         return VDE_ERROR;
       
   442    }
       
   443 
       
   444    return VDE_OK;
       
   445 }
       
   446 
       
   447 
       
   448 /* {{-output"vdeImsPutFree.txt"}} */
       
   449 /*
       
   450  * vdeImsPutFree
       
   451  *    
       
   452  *
       
   453  * Parameters:
       
   454  *    store                      a pointer to an image store
       
   455  *    item                       image store item to put into the Free store
       
   456  *
       
   457  * Function:
       
   458  *    This function puts an image store item to a suitable Free store
       
   459  *    of the passed image store. It selects the Free store according to 
       
   460  *    the image size or creates a new Free store if a suitable Free store 
       
   461  *    does not already exist.
       
   462  *
       
   463  *    One can use this function instead of vdeImsPut to explicitly discard
       
   464  *    an image store item (whereas for vdeImsPut, one would have to set
       
   465  *    the correct flags and pass a NULL renderer handle to get the same
       
   466  *    effect).
       
   467  *
       
   468  * Returns:
       
   469  *    VDE_OK                     if the function was successful
       
   470  *    VDE_ERROR                  if an error occured
       
   471  *
       
   472  *    
       
   473  */
       
   474 
       
   475 int vdeImsPutFree(vdeIms_t *store, vdeImsItem_t *item)
       
   476 /* {{-output"vdeImsPutFree.txt"}} */
       
   477 {
       
   478    vdeImsFreeStore_t *freeStore, *tmpFreeStore;
       
   479    int 
       
   480       lumWidth = renDriBitmapWidth(item->imb->drawItem),
       
   481       lumHeight = renDriBitmapHeight(item->imb->drawItem);
       
   482 
       
   483    if (vdeImsGetFreeStore(&store->freeStoreList, lumWidth, 
       
   484       lumHeight, &freeStore) < 0)
       
   485       return VDE_ERROR;
       
   486 
       
   487    if (freeStore == NULL) {
       
   488       /* The same algorithm as in vdeImsGetFree */
       
   489       freeStore = vdeImsAllocFreeStore(0, lumWidth, lumHeight, store->fYuvNeeded);
       
   490       if (freeStore == NULL)
       
   491          return VDE_ERROR;
       
   492 
       
   493       if (lstHead(&store->freeStoreList, (void **) &tmpFreeStore) < 0) {
       
   494          vdeImsDeallocFreeStore(freeStore);
       
   495          return VDE_ERROR;
       
   496       }
       
   497 
       
   498       if (lstAdd(&store->freeStoreList, freeStore) < 0) {
       
   499          vdeImsDeallocFreeStore(freeStore);
       
   500          return VDE_ERROR;
       
   501       }
       
   502    }
       
   503 
       
   504    if (lifoPut(&freeStore->freeStore, item) < 0)
       
   505       return VDE_ERROR;
       
   506 
       
   507    return VDE_OK;
       
   508 }
       
   509 
       
   510 
       
   511 
       
   512 
       
   513 /*
       
   514  * Local functions
       
   515  */
       
   516 
       
   517 /*
       
   518  * vdeImsAllocItem
       
   519  *    This function allocates and initializes a new image store item
       
   520  *    of given size.
       
   521  */
       
   522 
       
   523 static vdeImsItem_t *vdeImsAllocItem(int lumWidth, int lumHeight, int fYuvNeeded)
       
   524 {
       
   525    vdeImb_t *imb;
       
   526    vdeImsItem_t *pItem;
       
   527 
       
   528    imb = vdeImbAlloc(lumWidth, lumHeight, fYuvNeeded);
       
   529    if (imb == NULL)
       
   530       return NULL;
       
   531 
       
   532    pItem = (vdeImsItem_t *) vdeMalloc(sizeof(vdeImsItem_t));
       
   533    if (pItem == NULL) {
       
   534       vdeImbDealloc(imb);
       
   535       return NULL;
       
   536    }
       
   537 
       
   538    pItem->imb = imb;
       
   539 
       
   540    return pItem;
       
   541 }
       
   542 
       
   543 
       
   544 /*
       
   545  * vdeImsAllocFreeStore
       
   546  *    This function allocates and initializes a new Free store.
       
   547  *    In addition, it allocates a given number of free image store items
       
   548  *    of given size and puts these items into the created Free store.
       
   549  */
       
   550 
       
   551 static vdeImsFreeStore_t *vdeImsAllocFreeStore(int numFreeItems, 
       
   552    int lumWidth, int lumHeight, int fYuvNeeded)
       
   553 {
       
   554    int i;
       
   555    vdeImsFreeStore_t *store;
       
   556    vdeImsItem_t *pItem;
       
   557 
       
   558    store = (vdeImsFreeStore_t *) vdeMalloc(sizeof(vdeImsFreeStore_t));
       
   559    if (store == NULL)
       
   560       return NULL;
       
   561 
       
   562    store->lumWidth = lumWidth;
       
   563    store->lumHeight = lumHeight;
       
   564    store->fYuvNeeded = fYuvNeeded;
       
   565 
       
   566    if (lifoOpen(&store->freeStore) < 0) {
       
   567       vdeDealloc(store);
       
   568       return NULL;
       
   569    }
       
   570 
       
   571    for (i = 0; i < numFreeItems; i++) {
       
   572       pItem = vdeImsAllocItem(lumWidth, lumHeight, fYuvNeeded);
       
   573       if (pItem == NULL)
       
   574          goto error;
       
   575 
       
   576       if (lifoPut(&store->freeStore, pItem) < 0)
       
   577          goto error;
       
   578    }
       
   579 
       
   580    return store;
       
   581 
       
   582    error:
       
   583    if (pItem)
       
   584       vdeDealloc(pItem);
       
   585    vdeImsDeallocFreeStore(store);
       
   586    return NULL;
       
   587 }
       
   588 
       
   589 
       
   590 /*
       
   591  * vdeImsDeallocFreeStore
       
   592  *    This function deallocates a given Free store and all image store items
       
   593  *    which were in the store.
       
   594  */
       
   595 
       
   596 static int vdeImsDeallocFreeStore(vdeImsFreeStore_t *store)
       
   597 {
       
   598    vdeImb_t *imb;
       
   599    vdeImsItem_t *pItem;
       
   600 
       
   601    do {
       
   602       if (lifoGet(&store->freeStore, (void **) &pItem) < 0)
       
   603          return VDE_ERROR;
       
   604       
       
   605       if (pItem) {
       
   606          imb = pItem->imb;
       
   607          vdeDealloc(pItem);
       
   608          vdeImbDealloc(imb);
       
   609       }
       
   610    } while (pItem);
       
   611 
       
   612    if (lifoClose(&store->freeStore) < 0)
       
   613       return VDE_ERROR;
       
   614 
       
   615    vdeDealloc(store);
       
   616 
       
   617    return VDE_OK;
       
   618 }
       
   619 
       
   620 
       
   621 
       
   622 
       
   623 /*
       
   624  * vdeImsGetFreeStore
       
   625  *    This function returns a pointer to a Free store which contains frames of
       
   626  *    requested size. The Free store is searched from a list of Free stores.
       
   627  */
       
   628 
       
   629 static int vdeImsGetFreeStore(lst_t *freeStoreList, int lumWidth, int lumHeight,
       
   630    vdeImsFreeStore_t **freeStore)
       
   631 {
       
   632    if (lstHead(freeStoreList, (void **) freeStore) < 0)
       
   633       return VDE_ERROR;
       
   634 
       
   635    while (*freeStore && 
       
   636       ((*freeStore)->lumWidth != lumWidth || (*freeStore)->lumHeight != lumHeight)) {
       
   637       if (lstNext(freeStoreList, (void **) freeStore) < 0)
       
   638          return VDE_ERROR;
       
   639    }
       
   640 
       
   641    return VDE_OK;
       
   642 }
       
   643 // End of File