/* * Copyright (c) 2011 Intel Corporation. All Rights Reserved. * Copyright (c) Imagination Technologies Limited, UK * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Edward Lin <edward.lin@intel.com> * */ #include <unistd.h> #include <stdio.h> #include <memory.h> #include "psb_drv_video.h" #include "tng_hostheader.h" #include "tng_slotorder.h" static unsigned long long displayingOrder2EncodingOrder( unsigned long long displaying_order, int bframes, int intracnt, int idrcnt) { int poc; if (idrcnt != 0) poc = displaying_order % (intracnt * idrcnt + 1); else poc = displaying_order; if (poc == 0) //IDR return displaying_order; else if ((poc % (bframes + 1)) == 0) //I or P return (displaying_order - bframes); else return (displaying_order + 1); //B } static int getSlotIndex( int bframes, int intracnt, int idrcnt, int displaying_order, int encoding_count, FRAME_ORDER_INFO *last_info) { int i, slot_idx = 0; if (displaying_order == 0) { for (i = 0; i < (bframes + 2); i++) { //encoding order if (i == 0) last_info->slot_consume_enc_order[0] = 0; else if (i == 1) last_info->slot_consume_enc_order[bframes + 2 - 1] = 1; else last_info->slot_consume_enc_order[i - 1] = i; last_info->slot_consume_dpy_order[i] = i; //displaying order } last_info->slot_consume_dpy_order[0] = bframes + 2; last_info->slot_consume_enc_order[0] = displayingOrder2EncodingOrder(bframes + 2, bframes, intracnt, idrcnt); last_info->max_dpy_num = bframes + 2; } else { for (i = 0; i < (bframes + 2); i++) { if (last_info->slot_consume_enc_order[i] == encoding_count) { slot_idx = i; break; } } last_info->max_dpy_num++; last_info->slot_consume_dpy_order[slot_idx] = last_info->max_dpy_num; last_info->slot_consume_enc_order[slot_idx] = displayingOrder2EncodingOrder(last_info->max_dpy_num, bframes, intracnt, idrcnt); } return slot_idx; } int getFrameDpyOrder( unsigned long long encoding_count, /*Input, the encoding order, start from 0*/ int bframes, /*Input, The number of B frames between P and I */ int intracnt, /*Input, Intra period*/ int idrcnt, /*INput, IDR period. 0: only one IDR; */ FRAME_ORDER_INFO *p_last_info, /*Input & Output. Reset to 0 on first call*/ unsigned long long *displaying_order) /* Output. The displaying order */ { IMG_FRAME_TYPE frame_type; /*Output. Frame type. 0: I frame. 1: P frame. 2: B frame*/ int slot; /*Output. The corresponding slot index */ // int i; unsigned long long disp_index; unsigned long long val; if ((intracnt % (bframes + 1)) != 0 || bframes == 0) return -1; val = ((idrcnt == 0) ? encoding_count : encoding_count % (intracnt * idrcnt + 1)); if ((idrcnt == 0 && encoding_count == 0) || (idrcnt != 0 && (encoding_count % (intracnt * idrcnt + 1) == 0))) { frame_type = IMG_INTRA_IDR; disp_index = encoding_count; } else if (((val - 1) % (bframes + 1)) != 0) { frame_type = IMG_INTER_B; disp_index = encoding_count - 1; } else if (p_last_info->last_frame_type == IMG_INTRA_IDR || ((val - 1) / (bframes + 1) % (intracnt / (bframes + 1))) != 0) { frame_type = IMG_INTER_P; disp_index = encoding_count + bframes; } else { frame_type = IMG_INTRA_FRAME; disp_index = encoding_count + bframes; } *displaying_order = disp_index; slot = getSlotIndex(bframes, intracnt, idrcnt, disp_index, encoding_count, p_last_info); p_last_info->last_frame_type = frame_type; p_last_info->last_slot = slot; return 0; } #if 0 int main(int argc, char **argv) { int bframes, intracnt, frame_num; int i; int displaying_order, frame_type, slot; int j; char ac_frame_type[] = {'I', 'P', 'B'}; FRAME_ORDER_INFO last_info; if (argc != 4) { printf("%s [bframe_number] [intra period] [frame_number]\n", argv[0]); return 0; } else { bframes = atoi(argv[1]); intracnt = atoi(argv[2]); frame_num = atoi(argv[3]); } if (intracnt % (bframes + 1) != 0) { printf(" intra count must be a muliple of (bframe_number + 1)\n"); return 0; } memset(&last_info, 0, sizeof(FRAME_ORDER_INFO)); last_info.slot_consume_dpy_order = (int *)malloc((bframes + 2) * sizeof(int)); last_info.slot_consume_enc_order = (int *)malloc((bframes + 2) * sizeof(int)); printf("encodingorder displaying order frame_type slot index\n"); for (i = 0; i < frame_num; i++) { getFrameDpyOrder(i, bframes, intracnt, &last_info, &displaying_order, &frame_type, &slot); printf("%5d\t%5d\t%c\t%d\n", i, displaying_order, ac_frame_type[frame_type], slot); } free(last_info.slot_consume_dpy_order); free(last_info.slot_consume_enc_order); return 0; } #endif //test routine