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@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
displayingOrder2EncodingOrder(unsigned long long displaying_order,int bframes,int intracnt,int idrcnt)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
getSlotIndex(int bframes,int intracnt,int idrcnt,int displaying_order,int encoding_count,FRAME_ORDER_INFO * last_info)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
getFrameDpyOrder(unsigned long long encoding_count,int bframes,int intracnt,int idrcnt,FRAME_ORDER_INFO * p_last_info,unsigned long long * displaying_order)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