1 /* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * Copyright (c) Imagination Technologies Limited, UK 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Edward Lin <edward.lin (at) intel.com> 27 * 28 */ 29 30 #include <unistd.h> 31 #include <stdio.h> 32 #include <memory.h> 33 #include "psb_drv_video.h" 34 #include "tng_hostheader.h" 35 #include "tng_slotorder.h" 36 37 static unsigned long long displayingOrder2EncodingOrder( 38 unsigned long long displaying_order, 39 int bframes, 40 int intracnt, 41 int idrcnt) 42 { 43 int poc; 44 if (idrcnt != 0) 45 poc = displaying_order % (intracnt * idrcnt + 1); 46 else 47 poc = displaying_order; 48 49 if (poc == 0) //IDR 50 return displaying_order; 51 else if ((poc % (bframes + 1)) == 0) //I or P 52 return (displaying_order - bframes); 53 else 54 return (displaying_order + 1); //B 55 } 56 57 58 static int getSlotIndex( 59 int bframes, int intracnt, int idrcnt, 60 int displaying_order, int encoding_count, 61 FRAME_ORDER_INFO *last_info) 62 { 63 int i, slot_idx = 0; 64 if (displaying_order == 0) { 65 for (i = 0; i < (bframes + 2); i++) { 66 //encoding order 67 if (i == 0) 68 last_info->slot_consume_enc_order[0] = 0; 69 else if (i == 1) 70 last_info->slot_consume_enc_order[bframes + 2 - 1] = 1; 71 else 72 last_info->slot_consume_enc_order[i - 1] = i; 73 last_info->slot_consume_dpy_order[i] = i; //displaying order 74 } 75 last_info->slot_consume_dpy_order[0] = bframes + 2; 76 last_info->slot_consume_enc_order[0] = displayingOrder2EncodingOrder(bframes + 2, bframes, intracnt, idrcnt); 77 last_info->max_dpy_num = bframes + 2; 78 } else { 79 for (i = 0; i < (bframes + 2); i++) { 80 if (last_info->slot_consume_enc_order[i] == encoding_count) { 81 slot_idx = i; 82 break; 83 } 84 } 85 last_info->max_dpy_num++; 86 last_info->slot_consume_dpy_order[slot_idx] = last_info->max_dpy_num; 87 last_info->slot_consume_enc_order[slot_idx] = 88 displayingOrder2EncodingOrder(last_info->max_dpy_num, 89 bframes, intracnt, idrcnt); 90 } 91 92 return slot_idx; 93 } 94 95 int getFrameDpyOrder( 96 unsigned long long encoding_count, /*Input, the encoding order, start from 0*/ 97 int bframes, /*Input, The number of B frames between P and I */ 98 int intracnt, /*Input, Intra period*/ 99 int idrcnt, /*INput, IDR period. 0: only one IDR; */ 100 FRAME_ORDER_INFO *p_last_info, /*Input & Output. Reset to 0 on first call*/ 101 unsigned long long *displaying_order) /* Output. The displaying order */ 102 { 103 IMG_FRAME_TYPE frame_type; /*Output. Frame type. 0: I frame. 1: P frame. 2: B frame*/ 104 int slot; /*Output. The corresponding slot index */ 105 106 // int i; 107 unsigned long long disp_index; 108 unsigned long long val; 109 110 if ((intracnt % (bframes + 1)) != 0 || bframes == 0) 111 return -1; 112 113 val = ((idrcnt == 0) ? encoding_count : encoding_count % (intracnt * idrcnt + 1)); 114 if ((idrcnt == 0 && encoding_count == 0) || 115 (idrcnt != 0 && (encoding_count % (intracnt * idrcnt + 1) == 0))) { 116 frame_type = IMG_INTRA_IDR; 117 disp_index = encoding_count; 118 } else if (((val - 1) % (bframes + 1)) != 0) { 119 frame_type = IMG_INTER_B; 120 disp_index = encoding_count - 1; 121 } else if (p_last_info->last_frame_type == IMG_INTRA_IDR || 122 ((val - 1) / (bframes + 1) % (intracnt / (bframes + 1))) != 0) { 123 frame_type = IMG_INTER_P; 124 disp_index = encoding_count + bframes; 125 } else { 126 frame_type = IMG_INTRA_FRAME; 127 disp_index = encoding_count + bframes; 128 } 129 130 *displaying_order = disp_index; 131 slot = getSlotIndex(bframes, intracnt, idrcnt, 132 disp_index, encoding_count, p_last_info); 133 134 p_last_info->last_frame_type = frame_type; 135 p_last_info->last_slot = slot; 136 return 0; 137 } 138 139 #if 0 140 int main(int argc, char **argv) { 141 int bframes, intracnt, frame_num; 142 int i; 143 int displaying_order, frame_type, slot; 144 int j; 145 char ac_frame_type[] = {'I', 'P', 'B'}; 146 FRAME_ORDER_INFO last_info; 147 148 if (argc != 4) 149 { 150 printf("%s [bframe_number] [intra period] [frame_number]\n", argv[0]); 151 return 0; 152 } 153 else { 154 bframes = atoi(argv[1]); 155 intracnt = atoi(argv[2]); 156 frame_num = atoi(argv[3]); 157 } 158 if (intracnt % (bframes + 1) != 0) { 159 printf(" intra count must be a muliple of (bframe_number + 1)\n"); 160 return 0; 161 } 162 163 memset(&last_info, 0, sizeof(FRAME_ORDER_INFO)); 164 last_info.slot_consume_dpy_order = (int *)malloc((bframes + 2) * sizeof(int)); 165 last_info.slot_consume_enc_order = (int *)malloc((bframes + 2) * sizeof(int)); 166 167 printf("encodingorder displaying order frame_type slot index\n"); 168 for (i = 0; i < frame_num; i++) { 169 getFrameDpyOrder(i, bframes, intracnt, &last_info, &displaying_order, &frame_type, &slot); 170 printf("%5d\t%5d\t%c\t%d\n", i, displaying_order, ac_frame_type[frame_type], slot); 171 } 172 free(last_info.slot_consume_dpy_order); 173 free(last_info.slot_consume_enc_order); 174 175 return 0; 176 } 177 #endif //test routine 178