PageRenderTime 92ms CodeModel.GetById 16ms app.highlight 69ms RepoModel.GetById 1ms app.codeStats 0ms

/Show/avc/avcdec_api.cpp

http://github.com/mbebenita/Broadway
C++ | 1057 lines | 702 code | 159 blank | 196 comment | 195 complexity | 810609fc52422330431034502903ca95 MD5 | raw file
   1/* ------------------------------------------------------------------
   2 * Copyright (C) 1998-2009 PacketVideo
   3 *
   4 * Licensed under the Apache License, Version 2.0 (the "License");
   5 * you may not use this file except in compliance with the License.
   6 * You may obtain a copy of the License at
   7 *
   8 *      http://www.apache.org/licenses/LICENSE-2.0
   9 *
  10 * Unless required by applicable law or agreed to in writing, software
  11 * distributed under the License is distributed on an "AS IS" BASIS,
  12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  13 * express or implied.
  14 * See the License for the specific language governing permissions
  15 * and limitations under the License.
  16 * -------------------------------------------------------------------
  17 */
  18/**
  19This file contains application function interfaces to the AVC decoder library.
  20@publishedAll
  21*/
  22
  23#include <string.h>
  24#include <stdint.h>
  25#include <stdio.h>
  26#include <stdarg.h>
  27
  28#include "avcdec_api.h"
  29#include "avcdec_lib.h"
  30#include "avcdec_bitstream.h"
  31
  32void trace(const char *format, ...) {
  33    va_list argp;
  34    va_start(argp, format);
  35    vprintf(format, argp);
  36    va_end(argp);
  37}
  38
  39
  40
  41/* ======================================================================== */
  42/*  Function : EBSPtoRBSP()                                                 */
  43/*  Date     : 11/4/2003                                                    */
  44/*  Purpose  : Convert EBSP to RBSP and overwrite it.                       */
  45/*             Assuming that forbidden_zero, nal_ref_idc and nal_unit_type  */
  46/*          (first byte), has been taken out of the nal_unit.               */
  47/*  In/out   :                                                              */
  48/*  Return   :                                                              */
  49/*  Modified :                                                              */
  50/* ======================================================================== */
  51/**
  52@pseudocode "
  53    NumBytesInRBSP = 0;
  54    for(i=0:i< *size; i++){
  55        if(i+2 < *size && next_bits(24)==0x000003){
  56            rbsp_byte[NumBytesInRBSP++];
  57            rbsp_byte[NumBytesInRBSP++];
  58            i+=2;
  59            emulation_prevention_three_byte (0x03)
  60        }
  61        else
  62            rbsp_byte[NumBytesInRBSP++];
  63    }"
  64*/
  65AVCDec_Status EBSPtoRBSP(uint8 *nal_unit, int *size)
  66{
  67    int i, j;
  68    int count = 0;
  69
  70    /* This code is based on EBSPtoRBSP of JM */
  71    j = 0;
  72
  73    for (i = 0; i < *size; i++)
  74    {
  75        if (count == 2 && nal_unit[i] == 0x03)
  76        {
  77            i++;
  78            count = 0;
  79        }
  80        nal_unit[j] = nal_unit[i];
  81        if (nal_unit[i] == 0x00)
  82            count++;
  83        else
  84            count = 0;
  85        j++;
  86    }
  87
  88    *size = j;
  89
  90    return AVCDEC_SUCCESS;
  91}
  92
  93/* ======================================================================== */
  94/*  Function : PVAVCAnnexBGetNALUnit()                                      */
  95/*  Date     : 11/3/2003                                                    */
  96/*  Purpose  : Parse a NAL from byte stream format.                         */
  97/*  In/out   :                                                              */
  98/*  Return   : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail.                 */
  99/*  Modified :                                                              */
 100/* ======================================================================== */
 101/**
 102@pseudocode "
 103    byte_stream_nal_unit(NumBytesInNalunit){
 104    while(next_bits(24) != 0x000001)
 105        zero_byte
 106    if(more_data_in_byte_stream()){
 107        start_code_prefix_one_3bytes // equal 0x000001
 108        nal_unit(NumBytesInNALunit)
 109    }
 110   }"
 111*/
 112OSCL_EXPORT_REF AVCDec_Status PVAVCAnnexBGetNALUnit(uint8 *bitstream, uint8 **nal_unit,
 113        int *size)
 114{
 115    int i, j, FoundStartCode = 0;
 116    int end;
 117
 118    i = 0;
 119    while (bitstream[i] == 0 && i < *size)
 120    {
 121        i++;
 122    }
 123    if (i >= *size)
 124    {
 125        *nal_unit = bitstream;
 126        return AVCDEC_FAIL; /* cannot find any start_code_prefix. */
 127    }
 128    else if (bitstream[i] != 0x1)
 129    {
 130        i = -1;  /* start_code_prefix is not at the beginning, continue */
 131    }
 132
 133    i++;
 134    *nal_unit = bitstream + i; /* point to the beginning of the NAL unit */
 135
 136    j = end = i;
 137    while (!FoundStartCode)
 138    {
 139        while ((j + 1 < *size) && (bitstream[j] != 0 || bitstream[j+1] != 0))  /* see 2 consecutive zero bytes */
 140        {
 141            j++;
 142        }
 143        end = j;   /* stop and check for start code */
 144        while (j + 2 < *size && bitstream[j+2] == 0) /* keep reading for zero byte */
 145        {
 146            j++;
 147        }
 148        if (j + 2 >= *size)
 149        {
 150            *size -= i;
 151            return AVCDEC_NO_NEXT_SC;  /* cannot find the second start_code_prefix */
 152        }
 153        if (bitstream[j+2] == 0x1)
 154        {
 155            FoundStartCode = 1;
 156        }
 157        else
 158        {
 159            /* could be emulation code 0x3 */
 160            j += 2; /* continue the search */
 161        }
 162    }
 163
 164    *size = end - i;
 165
 166    return AVCDEC_SUCCESS;
 167}
 168
 169/* ======================================================================== */
 170/*  Function : PVAVCGetNALType()                                            */
 171/*  Date     : 11/4/2003                                                    */
 172/*  Purpose  : Sniff NAL type from the bitstream                            */
 173/*  In/out   :                                                              */
 174/*  Return   : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail.                 */
 175/*  Modified :                                                              */
 176/* ======================================================================== */
 177OSCL_EXPORT_REF AVCDec_Status PVAVCDecGetNALType(uint8 *bitstream, int size,
 178        int *nal_type, int *nal_ref_idc)
 179{
 180    int forbidden_zero_bit;
 181    if (size > 0)
 182    {
 183        forbidden_zero_bit = bitstream[0] >> 7;
 184        if (forbidden_zero_bit != 0)
 185            return AVCDEC_FAIL;
 186        *nal_ref_idc = (bitstream[0] & 0x60) >> 5;
 187        *nal_type = bitstream[0] & 0x1F;
 188        return AVCDEC_SUCCESS;
 189    }
 190
 191    return AVCDEC_FAIL;
 192}
 193
 194/* ======================================================================== */
 195/*  Function : PVAVCDecSeqParamSet()                                        */
 196/*  Date     : 11/4/2003                                                    */
 197/*  Purpose  : Initialize sequence, memory allocation if necessary.         */
 198/*  In/out   :                                                              */
 199/*  Return   : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail.                 */
 200/*  Modified :                                                              */
 201/* ======================================================================== */
 202
 203OSCL_EXPORT_REF AVCDec_Status   PVAVCDecSeqParamSet(AVCHandle *avcHandle, uint8 *nal_unit,
 204        int nal_size)
 205{
 206    AVCDec_Status status;
 207    AVCDecObject *decvid;
 208    AVCCommonObj *video;
 209    AVCDecBitstream *bitstream;
 210    void *userData = avcHandle->userData;
 211    bool  first_seq = FALSE;
 212    int i;
 213
 214
 215    trace("| + Sequence Parameter Set\n");
 216
 217    DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "PVAVCDecSeqParamSet", -1, -1);
 218
 219    if (avcHandle->AVCObject == NULL)
 220    {
 221        first_seq = TRUE;
 222
 223        //avcHandle->memory_usage = 0;
 224        /* allocate AVCDecObject */
 225        avcHandle->AVCObject = (void*)avcHandle->CBAVC_Malloc(userData, sizeof(AVCDecObject), 0/*DEFAULT_ATTR*/);
 226        if (avcHandle->AVCObject == NULL)
 227        {
 228            return AVCDEC_MEMORY_FAIL;
 229        }
 230
 231        decvid = (AVCDecObject*) avcHandle->AVCObject;
 232
 233        memset(decvid, 0, sizeof(AVCDecObject));
 234
 235        decvid->common = (AVCCommonObj*)avcHandle->CBAVC_Malloc(userData, sizeof(AVCCommonObj), 0);
 236        if (decvid->common == NULL)
 237        {
 238            return AVCDEC_MEMORY_FAIL;
 239        }
 240
 241        video = decvid->common;
 242        memset(video, 0, sizeof(AVCCommonObj));
 243
 244        video->seq_parameter_set_id = 9999; /* set it to some illegal value */
 245
 246        decvid->bitstream = (AVCDecBitstream *) avcHandle->CBAVC_Malloc(userData, sizeof(AVCDecBitstream), 1/*DEFAULT_ATTR*/);
 247        if (decvid->bitstream == NULL)
 248        {
 249            return AVCDEC_MEMORY_FAIL;
 250        }
 251
 252        decvid->bitstream->userData = avcHandle->userData; /* callback for more data */
 253        decvid->avcHandle = avcHandle;
 254        decvid->debugEnable = avcHandle->debugEnable;
 255    }
 256
 257    decvid = (AVCDecObject*) avcHandle->AVCObject;
 258    video = decvid->common;
 259    bitstream = decvid->bitstream;
 260
 261    /* check if we can reuse the memory without re-allocating it. */
 262    /* always check if(first_seq==TRUE) */
 263
 264    /* Conversion from EBSP to RBSP */
 265    video->forbidden_bit = nal_unit[0] >> 7;
 266    if (video->forbidden_bit) return AVCDEC_FAIL;
 267    video->nal_ref_idc = (nal_unit[0] & 0x60) >> 5;
 268    video->nal_unit_type = (AVCNalUnitType)(nal_unit[0] & 0x1F);
 269
 270
 271
 272    if (video->nal_unit_type != AVC_NALTYPE_SPS) /* not a SPS NAL */
 273    {
 274        return AVCDEC_FAIL;
 275    }
 276
 277    /* Initialize bitstream structure*/
 278    BitstreamInit(bitstream, nal_unit + 1, nal_size - 1);
 279
 280    /* if first_seq == TRUE, allocate the following memory  */
 281    if (first_seq == TRUE)
 282    {
 283        video->currSeqParams = NULL; /* initialize it to NULL */
 284        video->currPicParams = NULL;
 285
 286        /* There are 32 pointers to sequence param set, seqParams.
 287                There are 255 pointers to picture param set, picParams.*/
 288        for (i = 0; i < 32; i++)
 289            decvid->seqParams[i] = NULL;
 290
 291        for (i = 0; i < 256; i++)
 292            decvid->picParams[i] = NULL;
 293
 294        video->MbToSliceGroupMap = NULL;
 295
 296        video->mem_mgr_ctrl_eq_5 = FALSE;
 297        video->newPic = TRUE;
 298        video->newSlice = TRUE;
 299        video->currPic = NULL;
 300        video->currFS = NULL;
 301        video->prevRefPic = NULL;
 302
 303        video->mbNum = 0; // MC_Conceal
 304        /*  Allocate sliceHdr. */
 305
 306        video->sliceHdr = (AVCSliceHeader*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCSliceHeader), 5/*DEFAULT_ATTR*/);
 307        if (video->sliceHdr == NULL)
 308        {
 309            return AVCDEC_MEMORY_FAIL;
 310        }
 311
 312        video->decPicBuf = (AVCDecPicBuffer*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCDecPicBuffer), 3/*DEFAULT_ATTR*/);
 313        if (video->decPicBuf == NULL)
 314        {
 315            return AVCDEC_MEMORY_FAIL;
 316        }
 317        memset(video->decPicBuf, 0, sizeof(AVCDecPicBuffer));
 318    }
 319
 320    /* Decode SPS, allocate video->seqParams[i] and assign video->currSeqParams */
 321    status = DecodeSPS(decvid, bitstream);
 322
 323    if (status != AVCDEC_SUCCESS)
 324    {
 325        return status;
 326    }
 327    return AVCDEC_SUCCESS;
 328}
 329
 330/* ======================================================================== */
 331/*  Function : PVAVCDecGetSeqInfo()                                         */
 332/*  Date     : 11/4/2003                                                    */
 333/*  Purpose  : Get sequence parameter info. after SPS NAL is decoded.       */
 334/*  In/out   :                                                              */
 335/*  Return   : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail.                 */
 336/*  Modified :                                                              */
 337/*  12/20/03:  change input argument, use structure instead.                */
 338/* ======================================================================== */
 339
 340OSCL_EXPORT_REF AVCDec_Status PVAVCDecGetSeqInfo(AVCHandle *avcHandle, AVCDecSPSInfo *seqInfo)
 341{
 342    AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
 343    AVCCommonObj *video;
 344    int PicWidthInMbs, PicHeightInMapUnits, FrameHeightInMbs;
 345
 346    if (decvid == NULL || decvid->seqParams[0] == NULL)
 347    {
 348        return AVCDEC_FAIL;
 349    }
 350
 351    video = decvid->common;
 352
 353    PicWidthInMbs = decvid->seqParams[0]->pic_width_in_mbs_minus1 + 1;
 354    PicHeightInMapUnits = decvid->seqParams[0]->pic_height_in_map_units_minus1 + 1 ;
 355    FrameHeightInMbs = (2 - decvid->seqParams[0]->frame_mbs_only_flag) * PicHeightInMapUnits ;
 356
 357    seqInfo->FrameWidth = PicWidthInMbs << 4;
 358    seqInfo->FrameHeight = FrameHeightInMbs << 4;
 359
 360    seqInfo->frame_only_flag = decvid->seqParams[0]->frame_mbs_only_flag;
 361
 362    if (decvid->seqParams[0]->frame_cropping_flag)
 363    {
 364        seqInfo->frame_crop_left = 2 * decvid->seqParams[0]->frame_crop_left_offset;
 365        seqInfo->frame_crop_right = seqInfo->FrameWidth - (2 * decvid->seqParams[0]->frame_crop_right_offset + 1);
 366
 367        if (seqInfo->frame_only_flag)
 368        {
 369            seqInfo->frame_crop_top = 2 * decvid->seqParams[0]->frame_crop_top_offset;
 370            seqInfo->frame_crop_bottom = seqInfo->FrameHeight - (2 * decvid->seqParams[0]->frame_crop_bottom_offset + 1);
 371            /* Note in 7.4.2.1, there is a contraint on the value of frame_crop_left and frame_crop_top
 372            such that they have to be less than or equal to frame_crop_right/2 and frame_crop_bottom/2, respectively. */
 373        }
 374        else
 375        {
 376            seqInfo->frame_crop_top = 4 * decvid->seqParams[0]->frame_crop_top_offset;
 377            seqInfo->frame_crop_bottom = seqInfo->FrameHeight - (4 * decvid->seqParams[0]->frame_crop_bottom_offset + 1);
 378            /* Note in 7.4.2.1, there is a contraint on the value of frame_crop_left and frame_crop_top
 379            such that they have to be less than or equal to frame_crop_right/2 and frame_crop_bottom/4, respectively. */
 380        }
 381    }
 382    else  /* no cropping flag, just give the first and last pixel */
 383    {
 384        seqInfo->frame_crop_bottom = seqInfo->FrameHeight - 1;
 385        seqInfo->frame_crop_right = seqInfo->FrameWidth - 1;
 386        seqInfo->frame_crop_top = seqInfo->frame_crop_left = 0;
 387    }
 388
 389    return AVCDEC_SUCCESS;
 390}
 391
 392/* ======================================================================== */
 393/*  Function : PVAVCDecPicParamSet()                                        */
 394/*  Date     : 11/4/2003                                                    */
 395/*  Purpose  : Initialize picture                                           */
 396/*             create reference picture list.                               */
 397/*  In/out   :                                                              */
 398/*  Return   : AVCDEC_SUCCESS if succeed, AVC_FAIL if fail.                 */
 399/*  Modified :                                                              */
 400/* ======================================================================== */
 401/**
 402Since PPS doesn't contain much data, most of the picture initialization will
 403be done after decoding the slice header in PVAVCDecodeSlice. */
 404OSCL_EXPORT_REF AVCDec_Status   PVAVCDecPicParamSet(AVCHandle *avcHandle, uint8 *nal_unit,
 405        int nal_size)
 406{
 407    AVCDec_Status status;
 408    AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
 409    AVCCommonObj *video;
 410    AVCDecBitstream *bitstream;
 411
 412    trace("| + Picture Parameter Set\n");
 413
 414    if (decvid == NULL)
 415    {
 416        return AVCDEC_FAIL;
 417    }
 418
 419    video = decvid->common;
 420    bitstream = decvid->bitstream;
 421    /* 1. Convert EBSP to RBSP. Create bitstream structure */
 422    video->forbidden_bit = nal_unit[0] >> 7;
 423    video->nal_ref_idc = (nal_unit[0] & 0x60) >> 5;
 424    video->nal_unit_type = (AVCNalUnitType)(nal_unit[0] & 0x1F);
 425
 426    if (video->nal_unit_type != AVC_NALTYPE_PPS) /* not a PPS NAL */
 427    {
 428        return AVCDEC_FAIL;
 429    }
 430
 431
 432    /* 2. Initialize bitstream structure*/
 433    BitstreamInit(bitstream, nal_unit + 1, nal_size - 1);
 434
 435    /* 2. Decode pic_parameter_set_rbsp syntax. Allocate video->picParams[i] and assign to currPicParams */
 436    status = DecodePPS(decvid, video, bitstream);
 437    if (status != AVCDEC_SUCCESS)
 438    {
 439        return status;
 440    }
 441
 442    video->SliceGroupChangeRate = video->currPicParams->slice_group_change_rate_minus1 + 1 ;
 443
 444    return AVCDEC_SUCCESS;
 445}
 446
 447OSCL_EXPORT_REF AVCDec_Status   PVAVCDecSEI(AVCHandle *avcHandle, uint8 *nal_unit,
 448        int nal_size)
 449{
 450    OSCL_UNUSED_ARG(avcHandle);
 451    OSCL_UNUSED_ARG(nal_unit);
 452    OSCL_UNUSED_ARG(nal_size);
 453
 454    return AVCDEC_SUCCESS;
 455}
 456/* ======================================================================== */
 457/*  Function : PVAVCDecodeSlice()                                           */
 458/*  Date     : 11/4/2003                                                    */
 459/*  Purpose  : Decode one NAL unit.                                         */
 460/*  In/out   :                                                              */
 461/*  Return   : See enum AVCDec_Status for return values.                    */
 462/*  Modified :                                                              */
 463/* ======================================================================== */
 464OSCL_EXPORT_REF AVCDec_Status PVAVCDecodeSlice(AVCHandle *avcHandle, uint8 *buffer,
 465        int buf_size)
 466{
 467    AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
 468    AVCCommonObj *video;
 469    AVCDecBitstream *bitstream;
 470    AVCDec_Status status;
 471
 472    if (decvid == NULL)
 473    {
 474        return AVCDEC_FAIL;
 475    }
 476
 477    video = decvid->common;
 478    bitstream = decvid->bitstream;
 479
 480    if (video->mem_mgr_ctrl_eq_5)
 481    {
 482        return AVCDEC_PICTURE_OUTPUT_READY;      // to flushout frame buffers
 483    }
 484
 485    if (video->newSlice)
 486    {
 487        /* 2. Check NAL type  */
 488        if (buffer == NULL)
 489        {
 490            return AVCDEC_FAIL;
 491        }
 492        video->prev_nal_unit_type = video->nal_unit_type;
 493        video->forbidden_bit = buffer[0] >> 7;
 494        video->nal_ref_idc = (buffer[0] & 0x60) >> 5;
 495        video->nal_unit_type = (AVCNalUnitType)(buffer[0] & 0x1F);
 496
 497
 498        if (video->nal_unit_type == AVC_NALTYPE_AUD)
 499        {
 500            return AVCDEC_SUCCESS;
 501        }
 502
 503        if (video->nal_unit_type != AVC_NALTYPE_SLICE &&
 504                video->nal_unit_type != AVC_NALTYPE_IDR)
 505        {
 506            return AVCDEC_FAIL; /* not supported */
 507        }
 508
 509
 510
 511        if (video->nal_unit_type >= 2 && video->nal_unit_type <= 4)
 512        {
 513            return AVCDEC_FAIL; /* not supported */
 514        }
 515        else
 516        {
 517            video->slice_data_partitioning = FALSE;
 518        }
 519
 520        video->newSlice = FALSE;
 521        /*  Initialize bitstream structure*/
 522        BitstreamInit(bitstream, buffer + 1, buf_size - 1);
 523
 524
 525        /* 2.1 Decode Slice Header (separate function)*/
 526        status = DecodeSliceHeader(decvid, video, bitstream);
 527        if (status != AVCDEC_SUCCESS)
 528        {
 529            video->newSlice = TRUE;
 530            return status;
 531        }
 532
 533        if (video->sliceHdr->frame_num != video->prevFrameNum ||
 534            (video->sliceHdr->first_mb_in_slice < (uint)video->mbNum &&
 535             video->currSeqParams->constrained_set1_flag == 1))
 536        {
 537            video->newPic = TRUE;
 538            if (video->numMBs > 0)
 539            {
 540                // Conceal missing MBs of previously decoded frame
 541                ConcealSlice(decvid, video->PicSizeInMbs - video->numMBs, video->PicSizeInMbs);  // Conceal
 542                video->numMBs = 0;
 543
 544                //              DeblockPicture(video);   // No need to deblock
 545
 546                /* 3.2 Decoded frame reference marking. */
 547                /* 3.3 Put the decoded picture in output buffers */
 548                /* set video->mem_mge_ctrl_eq_5 */
 549                AVCNalUnitType temp = video->nal_unit_type;
 550                video->nal_unit_type = video->prev_nal_unit_type;
 551                StorePictureInDPB(avcHandle, video);
 552                video->nal_unit_type = temp;
 553                video->mbNum = 0; // MC_Conceal
 554                return AVCDEC_PICTURE_OUTPUT_READY;
 555            }
 556        }
 557
 558        if (video->nal_unit_type == AVC_NALTYPE_IDR)
 559        {
 560            video->prevFrameNum = 0;
 561            video->PrevRefFrameNum = 0;
 562        }
 563
 564        if (!video->currSeqParams->gaps_in_frame_num_value_allowed_flag)
 565        {   /* no gaps allowed, frame_num has to increase by one only */
 566            /*          if(sliceHdr->frame_num != (video->PrevRefFrameNum + 1)%video->MaxFrameNum) */
 567            if (video->sliceHdr->frame_num != video->PrevRefFrameNum && video->sliceHdr->frame_num != (video->PrevRefFrameNum + 1) % video->MaxFrameNum)
 568            {
 569                // Conceal missing MBs of previously decoded frame
 570                video->numMBs = 0;
 571                video->newPic = TRUE;
 572                video->prevFrameNum++; // FIX
 573                video->PrevRefFrameNum++;
 574                AVCNalUnitType temp = video->nal_unit_type;
 575                video->nal_unit_type = AVC_NALTYPE_SLICE; //video->prev_nal_unit_type;
 576                status = (AVCDec_Status)DPBInitBuffer(avcHandle, video);
 577                if (status != AVCDEC_SUCCESS)
 578                {
 579                    return status;
 580                }
 581                video->currFS->IsOutputted = 0x01;
 582                video->currFS->IsReference = 3;
 583                video->currFS->IsLongTerm = 0;
 584
 585                DecodePOC(video);
 586                /* find an empty memory from DPB and assigned to currPic */
 587                DPBInitPic(video, video->PrevRefFrameNum % video->MaxFrameNum);
 588                RefListInit(video);
 589                ConcealSlice(decvid, 0, video->PicSizeInMbs);  // Conceal
 590                video->currFS->IsOutputted |= 0x02;
 591                //conceal frame
 592                /* 3.2 Decoded frame reference marking. */
 593                /* 3.3 Put the decoded picture in output buffers */
 594                /* set video->mem_mge_ctrl_eq_5 */
 595                video->mbNum = 0; // Conceal
 596                StorePictureInDPB(avcHandle, video);
 597                video->nal_unit_type = temp;
 598
 599                return AVCDEC_PICTURE_OUTPUT_READY;
 600            }
 601        }
 602    }
 603
 604    if (video->newPic == TRUE)
 605    {
 606        status = (AVCDec_Status)DPBInitBuffer(avcHandle, video);
 607        if (status != AVCDEC_SUCCESS)
 608        {
 609            return status;
 610        }
 611    }
 612
 613    video->newSlice = TRUE;
 614
 615    /* function pointer setting at slice-level */
 616    // OPTIMIZE
 617    decvid->residual_block = &residual_block_cavlc;
 618
 619    /* derive picture order count */
 620    if (video->newPic == TRUE)
 621    {
 622        video->numMBs = video->PicSizeInMbs;
 623
 624        if (video->nal_unit_type != AVC_NALTYPE_IDR &&
 625            video->currSeqParams->gaps_in_frame_num_value_allowed_flag)
 626        {
 627            if (video->sliceHdr->frame_num != (video->PrevRefFrameNum + 1) % video->MaxFrameNum)
 628            {
 629                status = fill_frame_num_gap(avcHandle, video);
 630                if (status != AVCDEC_SUCCESS)
 631                {
 632                    video->numMBs = 0;
 633                    return status;
 634                }
 635
 636                status = (AVCDec_Status)DPBInitBuffer(avcHandle, video);
 637                if (status != AVCDEC_SUCCESS)
 638                {
 639                    video->numMBs = 0;
 640                    return status;
 641                }
 642
 643
 644            }
 645        }
 646        /* if there's gap in the frame_num, we have to fill in the gap with
 647            imaginary frames that won't get used for short-term ref. */
 648        /* see fill_frame_num_gap() in JM */
 649
 650
 651        DecodePOC(video);
 652        /* find an empty memory from DPB and assigned to currPic */
 653        DPBInitPic(video, video->CurrPicNum);
 654
 655        video->currPic->isReference = TRUE;  // FIX
 656
 657        if (video->nal_ref_idc == 0)
 658        {
 659            video->currPic->isReference = FALSE;
 660            video->currFS->IsOutputted |= 0x02;     /* The MASK 0x02 means not needed for reference, or returned */
 661            /* node need to check for freeing of this buffer */
 662        }
 663
 664        FMOInit(video);
 665
 666        if (video->currPic->isReference)
 667        {
 668            video->PrevRefFrameNum = video->sliceHdr->frame_num;
 669        }
 670
 671
 672        video->prevFrameNum = video->sliceHdr->frame_num;
 673    }
 674
 675    video->newPic = FALSE;
 676
 677
 678    /* Initialize refListIdx for this picture */
 679    RefListInit(video);
 680
 681    /* Re-order the reference list according to the ref_pic_list_reordering() */
 682    status = (AVCDec_Status)ReOrderList(video);
 683    if (status != AVCDEC_SUCCESS)
 684    {
 685        return AVCDEC_FAIL;
 686    }
 687
 688    /* 2.2 Decode Slice. */
 689    status = (AVCDec_Status)DecodeSlice(decvid);
 690
 691    video->slice_id++;  //  slice
 692
 693    if (status == AVCDEC_PICTURE_READY)
 694    {
 695        /* 3. Check complete picture */
 696#ifndef MB_BASED_DEBLOCK
 697        /* 3.1 Deblock */
 698        DeblockPicture(video);
 699#endif
 700        /* 3.2 Decoded frame reference marking. */
 701        /* 3.3 Put the decoded picture in output buffers */
 702        /* set video->mem_mge_ctrl_eq_5 */
 703        status = (AVCDec_Status)StorePictureInDPB(avcHandle, video);          // CHECK check the retunr status
 704        if (status != AVCDEC_SUCCESS)
 705        {
 706            return AVCDEC_FAIL;
 707        }
 708
 709        if (video->mem_mgr_ctrl_eq_5)
 710        {
 711            video->PrevRefFrameNum = 0;
 712            video->prevFrameNum = 0;
 713            video->prevPicOrderCntMsb = 0;
 714            video->prevPicOrderCntLsb = video->TopFieldOrderCnt;
 715            video->prevFrameNumOffset = 0;
 716        }
 717        else
 718        {
 719            video->prevPicOrderCntMsb = video->PicOrderCntMsb;
 720            video->prevPicOrderCntLsb = video->sliceHdr->pic_order_cnt_lsb;
 721            video->prevFrameNumOffset = video->FrameNumOffset;
 722        }
 723
 724        return AVCDEC_PICTURE_READY;
 725    }
 726    else if (status != AVCDEC_SUCCESS)
 727    {
 728        return AVCDEC_FAIL;
 729    }
 730
 731    return AVCDEC_SUCCESS;
 732}
 733
 734/* ======================================================================== */
 735/*  Function : PVAVCDecGetOutput()                                          */
 736/*  Date     : 11/3/2003                                                    */
 737/*  Purpose  : Get the next picture according to PicOrderCnt.               */
 738/*  In/out   :                                                              */
 739/*  Return   : AVCFrameIO structure                                         */
 740/*  Modified :                                                              */
 741/* ======================================================================== */
 742
 743OSCL_EXPORT_REF AVCDec_Status PVAVCDecGetOutput(AVCHandle *avcHandle, int *indx, int *release, AVCFrameIO *output)
 744{
 745    AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
 746    AVCCommonObj *video;
 747    AVCDecPicBuffer *dpb;
 748    AVCFrameStore *oldestFrame = NULL;
 749    int i, first = 1;
 750    int count_frame = 0;
 751    int index = 0;
 752    int min_poc = 0;
 753
 754    if (decvid == NULL)
 755    {
 756        return AVCDEC_FAIL;
 757    }
 758
 759    video = decvid->common;
 760    dpb = video->decPicBuf;
 761
 762    if (dpb->num_fs == 0)
 763    {
 764        return AVCDEC_FAIL;
 765    }
 766
 767    /* search for the oldest frame_num in dpb */
 768    /* extension to field decoding, we have to search for every top_field/bottom_field within
 769    each frame in the dpb. This code only works for frame based.*/
 770
 771    if (video->mem_mgr_ctrl_eq_5 == FALSE)
 772    {
 773        for (i = 0; i < dpb->num_fs; i++)
 774        {
 775            if ((dpb->fs[i]->IsOutputted & 0x01) == 0)
 776            {
 777                count_frame++;
 778                if (first)
 779                {
 780                    min_poc = dpb->fs[i]->PicOrderCnt;
 781                    first = 0;
 782                    oldestFrame = dpb->fs[i];
 783                    index = i;
 784                }
 785                if (dpb->fs[i]->PicOrderCnt < min_poc)
 786                {
 787                    min_poc = dpb->fs[i]->PicOrderCnt;
 788                    oldestFrame = dpb->fs[i];
 789                    index = i;
 790                }
 791            }
 792        }
 793    }
 794    else
 795    {
 796        for (i = 0; i < dpb->num_fs; i++)
 797        {
 798            if ((dpb->fs[i]->IsOutputted & 0x01) == 0 && dpb->fs[i] != video->currFS)
 799            {
 800                count_frame++;
 801                if (first)
 802                {
 803                    min_poc = dpb->fs[i]->PicOrderCnt;
 804                    first = 0;
 805                    oldestFrame = dpb->fs[i];
 806                    index = i;
 807                }
 808                if (dpb->fs[i]->PicOrderCnt < min_poc)
 809                {
 810                    min_poc = dpb->fs[i]->PicOrderCnt;
 811                    oldestFrame = dpb->fs[i];
 812                    index = i;
 813                }
 814            }
 815        }
 816
 817        if (count_frame < 2 && video->nal_unit_type != AVC_NALTYPE_IDR)
 818        {
 819            video->mem_mgr_ctrl_eq_5 = FALSE;  // FIX
 820        }
 821        else if (count_frame < 1 && video->nal_unit_type == AVC_NALTYPE_IDR)
 822        {
 823            for (i = 0; i < dpb->num_fs; i++)
 824            {
 825                if (dpb->fs[i] == video->currFS && (dpb->fs[i]->IsOutputted & 0x01) == 0)
 826                {
 827                    oldestFrame = dpb->fs[i];
 828                    index = i;
 829                    break;
 830                }
 831            }
 832            video->mem_mgr_ctrl_eq_5 = FALSE;
 833        }
 834    }
 835
 836    if (oldestFrame == NULL)
 837    {
 838
 839        /*      Check for Mem_mgmt_operation_5 based forced output */
 840        for (i = 0; i < dpb->num_fs; i++)
 841        {
 842            /* looking for the one not used or not reference and has been outputted */
 843            if (dpb->fs[i]->IsReference == 0 && dpb->fs[i]->IsOutputted == 3)
 844            {
 845                break;
 846            }
 847        }
 848        if (i < dpb->num_fs)
 849        {
 850            /* there are frames available for decoding */
 851            return AVCDEC_FAIL; /* no frame to be outputted */
 852        }
 853
 854
 855        /* no free frame available, we have to release one to continue decoding */
 856        int MinIdx = 0;
 857        int32 MinFrameNumWrap = 0x7FFFFFFF;
 858
 859        for (i = 0; i < dpb->num_fs; i++)
 860        {
 861            if (dpb->fs[i]->IsReference && !dpb->fs[i]->IsLongTerm)
 862            {
 863                if (dpb->fs[i]->FrameNumWrap < MinFrameNumWrap)
 864                {
 865                    MinFrameNumWrap = dpb->fs[i]->FrameNumWrap;
 866                    MinIdx = i;
 867                }
 868            }
 869        }
 870        /* mark the frame with smallest PicOrderCnt to be unused for reference */
 871        dpb->fs[MinIdx]->IsReference = 0;
 872        dpb->fs[MinIdx]->IsLongTerm = 0;
 873        dpb->fs[MinIdx]->frame.isReference = FALSE;
 874        dpb->fs[MinIdx]->frame.isLongTerm = FALSE;
 875        dpb->fs[MinIdx]->IsOutputted |= 0x02;
 876#ifdef PV_MEMORY_POOL
 877        if (dpb->fs[MinIdx]->IsOutputted == 3)
 878        {
 879            avcHandle->CBAVC_FrameUnbind(avcHandle->userData, MinIdx);
 880        }
 881#endif
 882        return AVCDEC_FAIL;
 883    }
 884    /* MASK 0x01 means the frame is outputted (for display). A frame gets freed when it is
 885    outputted (0x01) and not needed for reference (0x02)   */
 886    oldestFrame->IsOutputted |= 0x01;
 887
 888    if (oldestFrame->IsOutputted == 3)
 889    {
 890        *release = 1; /* flag to release the buffer */
 891    }
 892    else
 893    {
 894        *release = 0;
 895    }
 896    /* do not release buffer here, release it after it is sent to the sink node */
 897
 898    output->YCbCr[0] = oldestFrame->frame.Sl;
 899    output->YCbCr[1] = oldestFrame->frame.Scb;
 900    output->YCbCr[2] = oldestFrame->frame.Scr;
 901    output->height = oldestFrame->frame.height;
 902    output->pitch = oldestFrame->frame.width;
 903    output->disp_order = oldestFrame->PicOrderCnt;
 904    output->coding_order = oldestFrame->FrameNum;
 905    output->id = (uintptr_t) oldestFrame->base_dpb; /* use the pointer as the id */
 906    *indx = index;
 907
 908
 909
 910    return AVCDEC_SUCCESS;
 911}
 912
 913
 914/* ======================================================================== */
 915/*  Function : PVAVCDecReset()                                              */
 916/*  Date     : 03/04/2004                                                   */
 917/*  Purpose  : Reset decoder, prepare it for a new IDR frame.               */
 918/*  In/out   :                                                              */
 919/*  Return   :  void                                                        */
 920/*  Modified :                                                              */
 921/* ======================================================================== */
 922OSCL_EXPORT_REF void    PVAVCDecReset(AVCHandle *avcHandle)
 923{
 924    AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
 925    AVCCommonObj *video;
 926    AVCDecPicBuffer *dpb;
 927    int i;
 928
 929    if (decvid == NULL)
 930    {
 931        return;
 932    }
 933
 934    video = decvid->common;
 935    dpb = video->decPicBuf;
 936
 937    /* reset the DPB */
 938
 939
 940    for (i = 0; i < dpb->num_fs; i++)
 941    {
 942        dpb->fs[i]->IsLongTerm = 0;
 943        dpb->fs[i]->IsReference = 0;
 944        dpb->fs[i]->IsOutputted = 3;
 945        dpb->fs[i]->frame.isReference = 0;
 946        dpb->fs[i]->frame.isLongTerm = 0;
 947    }
 948
 949    video->mem_mgr_ctrl_eq_5 = FALSE;
 950    video->newPic = TRUE;
 951    video->newSlice = TRUE;
 952    video->currPic = NULL;
 953    video->currFS = NULL;
 954    video->prevRefPic = NULL;
 955    video->prevFrameNum = 0;
 956    video->PrevRefFrameNum = 0;
 957    video->prevFrameNumOffset = 0;
 958    video->FrameNumOffset = 0;
 959    video->mbNum = 0;
 960    video->numMBs = 0;
 961
 962    return ;
 963}
 964
 965
 966/* ======================================================================== */
 967/*  Function : PVAVCCleanUpDecoder()                                        */
 968/*  Date     : 11/4/2003                                                    */
 969/*  Purpose  : Clean up the decoder, free all memories allocated.           */
 970/*  In/out   :                                                              */
 971/*  Return   :  void                                                        */
 972/*  Modified :                                                              */
 973/* ======================================================================== */
 974
 975OSCL_EXPORT_REF void PVAVCCleanUpDecoder(AVCHandle *avcHandle)
 976{
 977    AVCDecObject *decvid = (AVCDecObject*) avcHandle->AVCObject;
 978    AVCCommonObj *video;
 979    void *userData = avcHandle->userData;
 980    int i;
 981
 982    DEBUG_LOG(userData, AVC_LOGTYPE_INFO, "PVAVCCleanUpDecoder", -1, -1);
 983
 984    if (decvid != NULL)
 985    {
 986        video = decvid->common;
 987        if (video != NULL)
 988        {
 989            if (video->MbToSliceGroupMap != NULL)
 990            {
 991                avcHandle->CBAVC_Free(userData, (uintptr_t)video->MbToSliceGroupMap);
 992            }
 993
 994#ifdef MB_BASED_DEBLOCK
 995            if (video->intra_pred_top != NULL)
 996            {
 997                avcHandle->CBAVC_Free(userData, (int)video->intra_pred_top);
 998            }
 999            if (video->intra_pred_top_cb != NULL)
1000            {
1001                avcHandle->CBAVC_Free(userData, (int)video->intra_pred_top_cb);
1002            }
1003            if (video->intra_pred_top_cr != NULL)
1004            {
1005                avcHandle->CBAVC_Free(userData, (int)video->intra_pred_top_cr);
1006            }
1007#endif
1008            if (video->mblock != NULL)
1009            {
1010                avcHandle->CBAVC_Free(userData, (uintptr_t)video->mblock);
1011            }
1012
1013            if (video->decPicBuf != NULL)
1014            {
1015                CleanUpDPB(avcHandle, video);
1016                avcHandle->CBAVC_Free(userData, (uintptr_t)video->decPicBuf);
1017            }
1018
1019            if (video->sliceHdr != NULL)
1020            {
1021                avcHandle->CBAVC_Free(userData, (uintptr_t)video->sliceHdr);
1022            }
1023
1024            avcHandle->CBAVC_Free(userData, (uintptr_t)video); /* last thing to do */
1025
1026        }
1027
1028        for (i = 0; i < 256; i++)
1029        {
1030            if (decvid->picParams[i] != NULL)
1031            {
1032                if (decvid->picParams[i]->slice_group_id != NULL)
1033                {
1034                    avcHandle->CBAVC_Free(userData, (uintptr_t)decvid->picParams[i]->slice_group_id);
1035                }
1036                avcHandle->CBAVC_Free(userData, (uintptr_t)decvid->picParams[i]);
1037            }
1038        }
1039        for (i = 0; i < 32; i++)
1040        {
1041            if (decvid->seqParams[i] != NULL)
1042            {
1043                avcHandle->CBAVC_Free(userData, (uintptr_t)decvid->seqParams[i]);
1044            }
1045        }
1046        if (decvid->bitstream != NULL)
1047        {
1048            avcHandle->CBAVC_Free(userData, (uintptr_t)decvid->bitstream);
1049        }
1050
1051
1052        avcHandle->CBAVC_Free(userData, (uintptr_t)decvid);
1053    }
1054
1055
1056    return ;
1057}