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