1609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* ------------------------------------------------------------------
2609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * Copyright (C) 1998-2009 PacketVideo
3609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber *
4609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * you may not use this file except in compliance with the License.
6609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * You may obtain a copy of the License at
7609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber *
8609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber *
10609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * Unless required by applicable law or agreed to in writing, software
11609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * express or implied.
14609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * See the License for the specific language governing permissions
15609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * and limitations under the License.
16609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber * -------------------------------------------------------------------
17609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber */
18609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#include "avclib_common.h"
19609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
20609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#define DPB_MEM_ATTR 0
21609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
22609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberAVCStatus InitDPB(AVCHandle *avcHandle, AVCCommonObj *video, int FrameHeightInMbs, int PicWidthInMbs, bool padding)
23609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
24609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCDecPicBuffer *dpb = video->decPicBuf;
25609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int level, framesize, num_fs;
26609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    void *userData = avcHandle->userData;
27609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifndef PV_MEMORY_POOL
28609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    uint32 addr;
29609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
30609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    uint16 refIdx = 0;
31609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    level = video->currSeqParams->level_idc;
32609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
33609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (num_fs = 0; num_fs < MAX_FS; num_fs++)
34609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
35609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs] = NULL;
36609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
37609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
38609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    framesize = (int)(((FrameHeightInMbs * PicWidthInMbs) << 7) * 3);
39609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (padding)
40609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
41609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->padded_size = (int)((((FrameHeightInMbs + 2) * (PicWidthInMbs + 2)) << 7) * 3) - framesize;
42609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
43609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    else
44609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
45609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->padded_size = 0;
46609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
47609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
48609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifndef PV_MEMORY_POOL
49609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (dpb->decoded_picture_buffer)
50609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
51609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        avcHandle->CBAVC_Free(userData, (int)dpb->decoded_picture_buffer);
52609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->decoded_picture_buffer = NULL;
53609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
54609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
55609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* need to allocate one extra frame for current frame, DPB only defines for reference frames */
56609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
57609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    dpb->num_fs = (uint32)(MaxDPBX2[mapLev2Idx[level]] << 2) / (3 * FrameHeightInMbs * PicWidthInMbs) + 1;
58609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (dpb->num_fs > MAX_FS)
59609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
60609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->num_fs = MAX_FS;
61609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
62609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
63609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (video->currSeqParams->num_ref_frames + 1 > (uint32)dpb->num_fs)
64609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
65609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->num_fs = video->currSeqParams->num_ref_frames + 1;
66609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
67609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
68609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    dpb->dpb_size = dpb->num_fs * (framesize + video->padded_size);
69609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber//  dpb->dpb_size = (uint32)MaxDPBX2[mapLev2Idx[level]]*512 + framesize;
70609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
71609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifndef PV_MEMORY_POOL
72609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    dpb->decoded_picture_buffer = (uint8*) avcHandle->CBAVC_Malloc(userData, dpb->dpb_size, 100/*DPB_MEM_ATTR*/);
73609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
74609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (dpb->decoded_picture_buffer == NULL || dpb->decoded_picture_buffer&0x3) // not word aligned
75609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        return AVC_MEMORY_FAIL;
76609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
77609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    dpb->used_size = 0;
78609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    num_fs = 0;
79609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
80609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    while (num_fs < dpb->num_fs)
81609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
82609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /*  fs is an array pointers to AVCDecPicture */
83609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs] = (AVCFrameStore*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCFrameStore), 101/*DEFAULT_ATTR*/);
84609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[num_fs] == NULL)
85609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
86609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            return AVC_MEMORY_FAIL;
87609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
88609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifndef PV_MEMORY_POOL
89609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /* assign the actual memory for Sl, Scb, Scr */
90609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->base_dpb = dpb->decoded_picture_buffer + dpb->used_size;
91609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
92609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->IsReference = 0;
93609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->IsLongTerm = 0;
94609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->IsOutputted = 3;
95609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->frame.RefIdx = refIdx++; /* this value will remain unchanged through out the encoding session */
96609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->frame.picType = AVC_FRAME;
97609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->frame.isLongTerm = 0;
98609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->frame.isReference = 0;
99609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->RefPicList0[num_fs] = &(dpb->fs[num_fs]->frame);
100609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[num_fs]->frame.padded = 0;
101609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->used_size += (framesize + video->padded_size);
102609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        num_fs++;
103609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
104609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
105609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return AVC_SUCCESS;
106609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
107609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
108609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberOSCL_EXPORT_REF AVCStatus AVCConfigureSequence(AVCHandle *avcHandle, AVCCommonObj *video, bool padding)
109609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
110609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    void *userData = avcHandle->userData;
111609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCDecPicBuffer *dpb = video->decPicBuf;
112609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int framesize, ii; /* size of one frame */
113609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    uint PicWidthInMbs, PicHeightInMapUnits, FrameHeightInMbs, PicSizeInMapUnits;
114609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    uint num_fs;
115609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* derived variables from SPS */
116609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    PicWidthInMbs = video->currSeqParams->pic_width_in_mbs_minus1 + 1;
117609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    PicHeightInMapUnits = video->currSeqParams->pic_height_in_map_units_minus1 + 1 ;
118609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    FrameHeightInMbs = (2 - video->currSeqParams->frame_mbs_only_flag) * PicHeightInMapUnits ;
119609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits ;
120609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
121609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (video->PicSizeInMapUnits != PicSizeInMapUnits || video->currSeqParams->level_idc != video->level_idc)
122609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
123609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /* make sure you mark all the frames as unused for reference for flushing*/
124609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        for (ii = 0; ii < dpb->num_fs; ii++)
125609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
126609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            dpb->fs[ii]->IsReference = 0;
127609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            dpb->fs[ii]->IsOutputted |= 0x02;
128609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
129609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
130609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        num_fs = (uint32)(MaxDPBX2[(uint32)mapLev2Idx[video->currSeqParams->level_idc]] << 2) / (3 * PicSizeInMapUnits) + 1;
131609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (num_fs >= MAX_FS)
132609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
133609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            num_fs = MAX_FS;
134609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
135609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifdef PV_MEMORY_POOL
136609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (padding)
137609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
138609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            avcHandle->CBAVC_DPBAlloc(avcHandle->userData,
139609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                                      PicSizeInMapUnits + ((PicWidthInMbs + 2) << 1) + (PicHeightInMapUnits << 1), num_fs);
140609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
141609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        else
142609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
143609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            avcHandle->CBAVC_DPBAlloc(avcHandle->userData, PicSizeInMapUnits, num_fs);
144609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
145609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
146609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        CleanUpDPB(avcHandle, video);
147609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (InitDPB(avcHandle, video, FrameHeightInMbs, PicWidthInMbs, padding) != AVC_SUCCESS)
148609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
149609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            return AVC_FAIL;
150609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
151609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /*  Allocate video->mblock upto PicSizeInMbs and populate the structure  such as the neighboring MB pointers.   */
152609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        framesize = (FrameHeightInMbs * PicWidthInMbs);
153609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->mblock)
154609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
15523da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo            avcHandle->CBAVC_Free(userData, video->mblock);
156609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->mblock = NULL;
157609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
158609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->mblock = (AVCMacroblock*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCMacroblock) * framesize, DEFAULT_ATTR);
159609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->mblock == NULL)
160609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
161609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            return AVC_FAIL;
162609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
163609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        for (ii = 0; ii < framesize; ii++)
164609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
165609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->mblock[ii].slice_id = -1;
166609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
167609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /* Allocate memory for intra prediction */
168609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifdef MB_BASED_DEBLOCK
169609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->intra_pred_top = (uint8*) avcHandle->CBAVC_Malloc(userData, PicWidthInMbs << 4, FAST_MEM_ATTR);
170609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->intra_pred_top == NULL)
171609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
172609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            return AVC_FAIL;
173609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
174609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->intra_pred_top_cb = (uint8*) avcHandle->CBAVC_Malloc(userData, PicWidthInMbs << 3, FAST_MEM_ATTR);
175609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->intra_pred_top_cb == NULL)
176609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
177609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            return AVC_FAIL;
178609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
179609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->intra_pred_top_cr = (uint8*) avcHandle->CBAVC_Malloc(userData, PicWidthInMbs << 3, FAST_MEM_ATTR);
180609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->intra_pred_top_cr == NULL)
181609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
182609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            return AVC_FAIL;
183609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
184609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
185609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
186609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /*  Allocate slice group MAP map */
187609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
188609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->MbToSliceGroupMap)
189609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
19023da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo            avcHandle->CBAVC_Free(userData, video->MbToSliceGroupMap);
191609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->MbToSliceGroupMap = NULL;
192609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
193609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->MbToSliceGroupMap = (int*) avcHandle->CBAVC_Malloc(userData, sizeof(uint) * PicSizeInMapUnits * 2, 7/*DEFAULT_ATTR*/);
194609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->MbToSliceGroupMap == NULL)
195609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
196609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            return AVC_FAIL;
197609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
198609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->PicSizeInMapUnits = PicSizeInMapUnits;
199609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->level_idc = video->currSeqParams->level_idc;
200609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
201609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
202609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return AVC_SUCCESS;
203609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
204609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
205609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberOSCL_EXPORT_REF AVCStatus CleanUpDPB(AVCHandle *avcHandle, AVCCommonObj *video)
206609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
207609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCDecPicBuffer *dpb = video->decPicBuf;
208609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii;
209609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    void *userData = avcHandle->userData;
210609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
211609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < MAX_FS; ii++)
212609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
213609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii] != NULL)
214609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
21523da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo            avcHandle->CBAVC_Free(userData, dpb->fs[ii]);
216609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            dpb->fs[ii] = NULL;
217609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
218609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
219609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifndef PV_MEMORY_POOL
220609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (dpb->decoded_picture_buffer)
221609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
22223da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo        avcHandle->CBAVC_Free(userData, dpb->decoded_picture_buffer);
223609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->decoded_picture_buffer = NULL;
224609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
225609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
226609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    dpb->used_size = 0;
227609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    dpb->dpb_size = 0;
228609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
229609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return AVC_SUCCESS;
230609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
231609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
232609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberOSCL_EXPORT_REF AVCStatus DPBInitBuffer(AVCHandle *avcHandle, AVCCommonObj *video)
233609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
234609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCDecPicBuffer *dpb = video->decPicBuf;
235609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii, status;
236609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
237609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* Before doing any decoding, check if there's a frame memory available */
238609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* look for next unused dpb->fs, or complementary field pair */
239609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* video->currPic is assigned to this */
240609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
241609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* There's also restriction on the frame_num, see page 59 of JVT-I1010.doc. */
242609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
243609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++)
244609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
245609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /* looking for the one not used or not reference and has been outputted */
246609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii]->IsReference == 0 && dpb->fs[ii]->IsOutputted == 3)
247609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
248609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->currFS = dpb->fs[ii];
249609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifdef PV_MEMORY_POOL
250609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            status = avcHandle->CBAVC_FrameBind(avcHandle->userData, ii, &(video->currFS->base_dpb));
251609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (status == AVC_FAIL)
252609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
253609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                return AVC_NO_BUFFER; /* this should not happen */
254609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
255609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
256609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            break;
257609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
258609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
259609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (ii == dpb->num_fs)
260609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
261609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        return AVC_PICTURE_OUTPUT_READY; /* no empty frame available */
262609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
263609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return AVC_SUCCESS;
264609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
265609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
266609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberOSCL_EXPORT_REF void DPBInitPic(AVCCommonObj *video, int CurrPicNum)
267609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
268609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int offset = 0;
269609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int offsetc = 0;
270609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int luma_framesize;
271609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* this part has to be set here, assuming that slice header and POC have been decoded. */
272609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* used in GetOutput API */
273609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->PicOrderCnt = video->PicOrderCnt;
274609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->FrameNum = video->sliceHdr->frame_num;
275609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->FrameNumWrap = CurrPicNum;    // MC_FIX
276609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* initialize everything to zero */
277609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->IsOutputted = 0;
278609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->IsReference = 0;
279609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->IsLongTerm = 0;
280609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->frame.isReference = FALSE;
281609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->frame.isLongTerm = FALSE;
282609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
283609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* initialize the pixel pointer to NULL */
284609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->frame.Sl = video->currFS->frame.Scb = video->currFS->frame.Scr = NULL;
285609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
286609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* determine video->currPic */
287609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* assign dbp->base_dpb to fs[i]->frame.Sl, Scb, Scr .*/
288609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* For PicSizeInMbs, see DecodeSliceHeader() */
289609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
290609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic = &(video->currFS->frame);
291609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
292609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->padded = 0; // reset this flag to not-padded
293609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
294609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (video->padded_size)
295609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
296609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        offset = ((video->PicWidthInSamplesL + 32) << 4) + 16; // offset to the origin
297609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        offsetc = (offset >> 2) + 4;
298609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        luma_framesize = (int)((((video->FrameHeightInMbs + 2) * (video->PicWidthInMbs + 2)) << 8));
299609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
300609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    else
301609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        luma_framesize = video->PicSizeInMbs << 8;
302609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
303609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
304609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->Sl = video->currFS->base_dpb + offset;
305609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->Scb = video->currFS->base_dpb  + luma_framesize + offsetc;
306609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->Scr = video->currPic->Scb + (luma_framesize >> 2);
307609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->pitch = video->PicWidthInSamplesL + (video->padded_size == 0 ? 0 : 32);
308609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
309609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
310609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->height = video->PicHeightInSamplesL;
311609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->width = video->PicWidthInSamplesL;
312609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->PicNum = CurrPicNum;
313609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
314609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
315609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* to release skipped frame after encoding */
316609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberOSCL_EXPORT_REF void DPBReleaseCurrentFrame(AVCHandle *avcHandle, AVCCommonObj *video)
317609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
318609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCDecPicBuffer *dpb = video->decPicBuf;
319609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii;
320609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
321609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->IsOutputted = 3; // return this buffer.
322609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
323609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifdef PV_MEMORY_POOL /* for non-memory pool, no need to do anything */
324609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
325609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* search for current frame index */
326609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    ii = dpb->num_fs;
327609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    while (ii--)
328609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
329609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii] == video->currFS)
330609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
331609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            avcHandle->CBAVC_FrameUnbind(avcHandle->userData, ii);
332609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            break;
333609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
334609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
335609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
336609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
337609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return ;
338609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
339609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
340609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* see subclause 8.2.5.1 */
341609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberOSCL_EXPORT_REF AVCStatus StorePictureInDPB(AVCHandle *avcHandle, AVCCommonObj *video)
342609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
343609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCStatus status;
344609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCDecPicBuffer *dpb = video->decPicBuf;
345609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCSliceHeader *sliceHdr = video->sliceHdr;
346609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii, num_ref;
347609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
348609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* number 1 of 8.2.5.1, we handle gaps in frame_num differently without using the memory */
349609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* to be done!!!! */
350609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
351609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* number 3 of 8.2.5.1 */
352609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (video->nal_unit_type == AVC_NALTYPE_IDR)
353609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
354609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        for (ii = 0; ii < dpb->num_fs; ii++)
355609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
356609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (dpb->fs[ii] != video->currFS) /* not current frame */
357609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
358609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                dpb->fs[ii]->IsReference = 0; /* mark as unused for reference */
359609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                dpb->fs[ii]->IsLongTerm = 0;  /* but still used until output */
360609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                dpb->fs[ii]->IsOutputted |= 0x02;
361609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifdef PV_MEMORY_POOL
362609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                if (dpb->fs[ii]->IsOutputted == 3)
363609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                {
364609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                    avcHandle->CBAVC_FrameUnbind(avcHandle->userData, ii);
365609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                }
366609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
367609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
368609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
369609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
370609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->currPic->isReference = TRUE;
371609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->currFS->IsReference = 3;
372609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
373609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (sliceHdr->long_term_reference_flag == 0)
374609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
375609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->currPic->isLongTerm = FALSE;
376609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->currFS->IsLongTerm = 0;
377609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->MaxLongTermFrameIdx = -1;
378609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
379609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        else
380609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
381609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->currPic->isLongTerm = TRUE;
382609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->currFS->IsLongTerm = 3;
383609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->currFS->LongTermFrameIdx = 0;
384609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->MaxLongTermFrameIdx = 0;
385609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
386609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (sliceHdr->no_output_of_prior_pics_flag)
387609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
388609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            for (ii = 0; ii < dpb->num_fs; ii++)
389609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
390609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                if (dpb->fs[ii] != video->currFS) /* not current frame */
391609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                {
392609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                    dpb->fs[ii]->IsOutputted = 3;
393609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifdef PV_MEMORY_POOL
394609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                    avcHandle->CBAVC_FrameUnbind(avcHandle->userData, ii);
395609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
396609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                }
397609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
398609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
399609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->mem_mgr_ctrl_eq_5 = TRUE;    /* flush reference frames MC_FIX */
400609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
401609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    else
402609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
403609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->currPic->isReference == TRUE)
404609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
405609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (sliceHdr->adaptive_ref_pic_marking_mode_flag == 0)
406609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
407609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                status = sliding_window_process(avcHandle, video, dpb); /* we may have to do this after adaptive_memory_marking */
408609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
409609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            else
410609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
411609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                status = adaptive_memory_marking(avcHandle, video, dpb, sliceHdr);
412609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
413609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (status != AVC_SUCCESS)
414609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
415609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                return status;
416609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
417609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
418609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
419609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* number 4 of 8.2.5.1 */
420609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* This basically says every frame must be at least used for short-term ref. */
421609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* Need to be revisited!!! */
422609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* look at insert_picture_in_dpb() */
423609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
424609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
425609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
426609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (video->nal_unit_type != AVC_NALTYPE_IDR && video->currPic->isLongTerm == FALSE)
427609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
428609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (video->currPic->isReference)
429609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
430609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->currFS->IsReference = 3;
431609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
432609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        else
433609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
434609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            video->currFS->IsReference = 0;
435609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
436609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        video->currFS->IsLongTerm = 0;
437609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
438609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
439609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* check if number of reference frames doesn't exceed num_ref_frames */
440609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    num_ref = 0;
441609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++)
442609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
443609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii]->IsReference)
444609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
445609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            num_ref++;
446609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
447609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
448609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
449609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (num_ref > (int)video->currSeqParams->num_ref_frames)
450609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
451609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        return AVC_FAIL; /* out of range */
452609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
453609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
454609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return AVC_SUCCESS;
455609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
456609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
457609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
458609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberAVCStatus sliding_window_process(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb)
459609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
460609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii, numShortTerm, numLongTerm;
461609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int32 MinFrameNumWrap;
462609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int MinIdx;
463609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
464609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
465609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    numShortTerm = 0;
466609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    numLongTerm = 0;
467609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++)
468609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
469609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii] != video->currFS) /* do not count the current frame */
470609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
471609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (dpb->fs[ii]->IsLongTerm)
472609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
473609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                numLongTerm++;
474609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
475609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            else if (dpb->fs[ii]->IsReference)
476609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
477609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                numShortTerm++;
478609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
479609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
480609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
481609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
482609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    while (numShortTerm + numLongTerm >= (int)video->currSeqParams->num_ref_frames)
483609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
484609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /* get short-term ref frame with smallest PicOrderCnt */
485609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /* this doesn't work for all I-slice clip since PicOrderCnt will not be initialized */
486609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
487609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        MinFrameNumWrap = 0x7FFFFFFF;
488609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        MinIdx = -1;
489609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        for (ii = 0; ii < dpb->num_fs; ii++)
490609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
491609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (dpb->fs[ii]->IsReference && !dpb->fs[ii]->IsLongTerm)
492609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
493609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                if (dpb->fs[ii]->FrameNumWrap < MinFrameNumWrap)
494609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                {
495609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                    MinFrameNumWrap = dpb->fs[ii]->FrameNumWrap;
496609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                    MinIdx = ii;
497609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                }
498609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
499609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
500609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (MinIdx < 0) /* something wrong, impossible */
501609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
502609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            return AVC_FAIL;
503609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
504609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
505609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        /* mark the frame with smallest PicOrderCnt to be unused for reference */
506609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[MinIdx]->IsReference = 0;
507609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[MinIdx]->IsLongTerm = 0;
508609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[MinIdx]->frame.isReference = FALSE;
509609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[MinIdx]->frame.isLongTerm = FALSE;
510609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        dpb->fs[MinIdx]->IsOutputted |= 0x02;
511609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifdef PV_MEMORY_POOL
512609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[MinIdx]->IsOutputted == 3)
513609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
514609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            avcHandle->CBAVC_FrameUnbind(avcHandle->userData, MinIdx);
515609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
516609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
517609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        numShortTerm--;
518609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
519609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return AVC_SUCCESS;
520609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
521609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
522609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* see subclause 8.2.5.4 */
523609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberAVCStatus adaptive_memory_marking(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, AVCSliceHeader *sliceHdr)
524609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
525609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii;
526609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
527609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    ii = 0;
528609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    while (ii < MAX_DEC_REF_PIC_MARKING && sliceHdr->memory_management_control_operation[ii] != 0)
529609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
530609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        switch (sliceHdr->memory_management_control_operation[ii])
531609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
532609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            case 1:
533609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                MemMgrCtrlOp1(avcHandle, video, dpb, sliceHdr->difference_of_pic_nums_minus1[ii]);
534609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                //      update_ref_list(dpb);
535609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                break;
536609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            case 2:
537609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                MemMgrCtrlOp2(avcHandle, dpb, sliceHdr->long_term_pic_num[ii]);
538609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                break;
539609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            case 3:
540609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                MemMgrCtrlOp3(avcHandle, video, dpb, sliceHdr->difference_of_pic_nums_minus1[ii], sliceHdr->long_term_frame_idx[ii]);
541609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                break;
542609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            case 4:
543609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                MemMgrCtrlOp4(avcHandle, video, dpb, sliceHdr->max_long_term_frame_idx_plus1[ii]);
544609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                break;
545609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            case 5:
546609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                MemMgrCtrlOp5(avcHandle, video, dpb);
547609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                video->currFS->FrameNum = 0;    //
548609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                video->currFS->PicOrderCnt = 0;
549609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                break;
550609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            case 6:
551609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                MemMgrCtrlOp6(avcHandle, video, dpb, sliceHdr->long_term_frame_idx[ii]);
552609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                break;
553609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
554609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        ii++;
555609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
556609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
557609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (ii == MAX_DEC_REF_PIC_MARKING)
558609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
559609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        return AVC_FAIL; /* exceed the limit */
560609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
561609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
562609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return AVC_SUCCESS;
563609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
564609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
565609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
566609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* see subclause 8.2.5.4.1, mark short-term picture as "unused for reference" */
567609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Hubervoid MemMgrCtrlOp1(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, int difference_of_pic_nums_minus1)
568609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
569609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int picNumX, ii;
570609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
571609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    picNumX = video->CurrPicNum - (difference_of_pic_nums_minus1 + 1);
572609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
573609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++)
574609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
575609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii]->IsReference == 3 && dpb->fs[ii]->IsLongTerm == 0)
576609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
577609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (dpb->fs[ii]->frame.PicNum == picNumX)
578609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
579609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                unmark_for_reference(avcHandle, dpb, ii);
580609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                return ;
581609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
582609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
583609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
584609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
585609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return ;
586609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
587609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
588609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* see subclause 8.2.5.4.2 mark long-term picture as "unused for reference" */
589609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Hubervoid MemMgrCtrlOp2(AVCHandle *avcHandle, AVCDecPicBuffer *dpb, int long_term_pic_num)
590609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
591609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii;
592609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
593609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++)
594609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
595609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii]->IsLongTerm == 3)
596609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
597609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (dpb->fs[ii]->frame.LongTermPicNum == long_term_pic_num)
598609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
599609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                unmark_for_reference(avcHandle, dpb, ii);
600609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
601609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
602609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
603609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
604609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
605609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* see subclause 8.2.5.4.3 assign LongTermFrameIdx to a short-term ref picture */
606609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Hubervoid MemMgrCtrlOp3(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, uint difference_of_pic_nums_minus1,
607609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                   uint long_term_frame_idx)
608609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
609609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int picNumX, ii;
610609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
611609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    picNumX = video->CurrPicNum - (difference_of_pic_nums_minus1 + 1);
612609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
613609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* look for fs[i] with long_term_frame_idx */
614609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
615609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    unmark_long_term_frame_for_reference_by_frame_idx(avcHandle, dpb, long_term_frame_idx);
616609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
617609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
618609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* now mark the picture with picNumX to long term frame idx */
619609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
620609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++)
621609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
622609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii]->IsReference == 3)
623609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
624609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if ((dpb->fs[ii]->frame.isLongTerm == FALSE) && (dpb->fs[ii]->frame.PicNum == picNumX))
625609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
626609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                dpb->fs[ii]->LongTermFrameIdx = long_term_frame_idx;
627609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                dpb->fs[ii]->frame.LongTermPicNum = long_term_frame_idx;
628609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
629609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                dpb->fs[ii]->frame.isLongTerm = TRUE;
630609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
631609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                dpb->fs[ii]->IsLongTerm = 3;
632609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                return;
633609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
634609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
635609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
636609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
637609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
638609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
639609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* see subclause 8.2.5.4.4, MaxLongTermFrameIdx */
640609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Hubervoid MemMgrCtrlOp4(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, uint max_long_term_frame_idx_plus1)
641609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
642609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii;
643609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
644609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->MaxLongTermFrameIdx = max_long_term_frame_idx_plus1 - 1;
645609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
646609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    /* then mark long term frame with exceeding LongTermFrameIdx to unused for reference. */
647609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++)
648609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
649609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii]->IsLongTerm && dpb->fs[ii] != video->currFS)
650609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
651609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            if (dpb->fs[ii]->LongTermFrameIdx > video->MaxLongTermFrameIdx)
652609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            {
653609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber                unmark_for_reference(avcHandle, dpb, ii);
654609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            }
655609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
656609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
657609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
658609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
659609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* see subclause 8.2.5.4.5 mark all reference picture as "unused for reference" and setting
660609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas HuberMaxLongTermFrameIdx to "no long-term frame indices" */
661609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Hubervoid MemMgrCtrlOp5(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb)
662609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
663609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii;
664609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
665609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->MaxLongTermFrameIdx = -1;
666609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++) /* including the current frame ??????*/
667609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
668609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii] != video->currFS) // MC_FIX
669609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
670609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            unmark_for_reference(avcHandle, dpb, ii);
671609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
672609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
673609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
674609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->mem_mgr_ctrl_eq_5 = TRUE;
675609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
676609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
677609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber/* see subclause 8.2.5.4.6 assing long-term frame index to the current picture */
678609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Hubervoid MemMgrCtrlOp6(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, uint long_term_frame_idx)
679609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
680609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
681609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    unmark_long_term_frame_for_reference_by_frame_idx(avcHandle, dpb, long_term_frame_idx);
682609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->IsLongTerm = 3;
683609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->IsReference = 3;
684609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
685609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->isLongTerm = TRUE;
686609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currPic->isReference = TRUE;
687609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    video->currFS->LongTermFrameIdx = long_term_frame_idx;
688609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
689609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
690609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
691609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Hubervoid unmark_for_reference(AVCHandle *avcHandle, AVCDecPicBuffer *dpb, uint idx)
692609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
693609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
694609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    AVCFrameStore *fs = dpb->fs[idx];
695609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    fs->frame.isReference = FALSE;
696609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    fs->frame.isLongTerm = FALSE;
697609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
698609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    fs->IsLongTerm = 0;
699609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    fs->IsReference = 0;
700609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    fs->IsOutputted |= 0x02;
701609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#ifdef PV_MEMORY_POOL
702609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    if (fs->IsOutputted == 3)
703609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
704609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        avcHandle->CBAVC_FrameUnbind(avcHandle->userData, idx);
705609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
706609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber#endif
707609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    return ;
708609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
709609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
710609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Hubervoid unmark_long_term_frame_for_reference_by_frame_idx(AVCHandle *avcHandle, AVCDecPicBuffer *dpb, uint long_term_frame_idx)
711609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber{
712609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    int ii;
713609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    for (ii = 0; ii < dpb->num_fs; ii++)
714609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    {
715609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
716609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        if (dpb->fs[ii]->IsLongTerm && (dpb->fs[ii]->LongTermFrameIdx == (int)long_term_frame_idx))
717609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        {
718609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber            unmark_for_reference(avcHandle, dpb, ii);
719609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber        }
720609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
721609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber    }
722609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber}
723609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
724609f1a00c96cf5605f4614e7bb6d0487c98969c5Andreas Huber
725