/*
* 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