18e9a21e730449c10cac6e6f69d255611c93f63c2hding/*
2430ce5c32361119ed81a62c918be6afbdd053eddhding * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3430ce5c32361119ed81a62c918be6afbdd053eddhding * Copyright (c) Imagination Technologies Limited, UK
48e9a21e730449c10cac6e6f69d255611c93f63c2hding *
5430ce5c32361119ed81a62c918be6afbdd053eddhding * Permission is hereby granted, free of charge, to any person obtaining a
6430ce5c32361119ed81a62c918be6afbdd053eddhding * copy of this software and associated documentation files (the
7430ce5c32361119ed81a62c918be6afbdd053eddhding * "Software"), to deal in the Software without restriction, including
8430ce5c32361119ed81a62c918be6afbdd053eddhding * without limitation the rights to use, copy, modify, merge, publish,
9430ce5c32361119ed81a62c918be6afbdd053eddhding * distribute, sub license, and/or sell copies of the Software, and to
10430ce5c32361119ed81a62c918be6afbdd053eddhding * permit persons to whom the Software is furnished to do so, subject to
11430ce5c32361119ed81a62c918be6afbdd053eddhding * the following conditions:
12430ce5c32361119ed81a62c918be6afbdd053eddhding *
13430ce5c32361119ed81a62c918be6afbdd053eddhding * The above copyright notice and this permission notice (including the
14430ce5c32361119ed81a62c918be6afbdd053eddhding * next paragraph) shall be included in all copies or substantial portions
15430ce5c32361119ed81a62c918be6afbdd053eddhding * of the Software.
16430ce5c32361119ed81a62c918be6afbdd053eddhding *
17430ce5c32361119ed81a62c918be6afbdd053eddhding * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18430ce5c32361119ed81a62c918be6afbdd053eddhding * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19430ce5c32361119ed81a62c918be6afbdd053eddhding * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20430ce5c32361119ed81a62c918be6afbdd053eddhding * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21430ce5c32361119ed81a62c918be6afbdd053eddhding * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22430ce5c32361119ed81a62c918be6afbdd053eddhding * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23430ce5c32361119ed81a62c918be6afbdd053eddhding * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
248e9a21e730449c10cac6e6f69d255611c93f63c2hding *
258e9a21e730449c10cac6e6f69d255611c93f63c2hding * Authors:
268e9a21e730449c10cac6e6f69d255611c93f63c2hding *    Edward Lin <edward.lin@intel.com>
278e9a21e730449c10cac6e6f69d255611c93f63c2hding *
288e9a21e730449c10cac6e6f69d255611c93f63c2hding */
298e9a21e730449c10cac6e6f69d255611c93f63c2hding
308e9a21e730449c10cac6e6f69d255611c93f63c2hding#include <unistd.h>
318e9a21e730449c10cac6e6f69d255611c93f63c2hding#include <stdio.h>
328e9a21e730449c10cac6e6f69d255611c93f63c2hding#include <memory.h>
338e9a21e730449c10cac6e6f69d255611c93f63c2hding#include "psb_drv_video.h"
34430ce5c32361119ed81a62c918be6afbdd053eddhding#include "tng_hostheader.h"
35430ce5c32361119ed81a62c918be6afbdd053eddhding#include "tng_slotorder.h"
368e9a21e730449c10cac6e6f69d255611c93f63c2hding
378e9a21e730449c10cac6e6f69d255611c93f63c2hdingstatic unsigned long long displayingOrder2EncodingOrder(
388e9a21e730449c10cac6e6f69d255611c93f63c2hding    unsigned long long displaying_order,
398e9a21e730449c10cac6e6f69d255611c93f63c2hding    int bframes,
408e9a21e730449c10cac6e6f69d255611c93f63c2hding    int intracnt,
418e9a21e730449c10cac6e6f69d255611c93f63c2hding    int idrcnt)
428e9a21e730449c10cac6e6f69d255611c93f63c2hding{
438e9a21e730449c10cac6e6f69d255611c93f63c2hding    int poc;
448e9a21e730449c10cac6e6f69d255611c93f63c2hding    if (idrcnt != 0)
458e9a21e730449c10cac6e6f69d255611c93f63c2hding        poc = displaying_order % (intracnt * idrcnt + 1);
468e9a21e730449c10cac6e6f69d255611c93f63c2hding    else
478e9a21e730449c10cac6e6f69d255611c93f63c2hding        poc = displaying_order;
488e9a21e730449c10cac6e6f69d255611c93f63c2hding
498e9a21e730449c10cac6e6f69d255611c93f63c2hding    if (poc == 0) //IDR
508e9a21e730449c10cac6e6f69d255611c93f63c2hding        return displaying_order;
518e9a21e730449c10cac6e6f69d255611c93f63c2hding    else if ((poc % (bframes + 1)) == 0) //I or P
528e9a21e730449c10cac6e6f69d255611c93f63c2hding        return (displaying_order - bframes);
538e9a21e730449c10cac6e6f69d255611c93f63c2hding    else
548e9a21e730449c10cac6e6f69d255611c93f63c2hding        return (displaying_order + 1); //B
558e9a21e730449c10cac6e6f69d255611c93f63c2hding}
568e9a21e730449c10cac6e6f69d255611c93f63c2hding
578e9a21e730449c10cac6e6f69d255611c93f63c2hding
588e9a21e730449c10cac6e6f69d255611c93f63c2hdingstatic int getSlotIndex(
598e9a21e730449c10cac6e6f69d255611c93f63c2hding    int bframes, int intracnt, int idrcnt,
608e9a21e730449c10cac6e6f69d255611c93f63c2hding    int displaying_order, int encoding_count,
618e9a21e730449c10cac6e6f69d255611c93f63c2hding    FRAME_ORDER_INFO *last_info)
628e9a21e730449c10cac6e6f69d255611c93f63c2hding{
638e9a21e730449c10cac6e6f69d255611c93f63c2hding    int i, slot_idx = 0;
648e9a21e730449c10cac6e6f69d255611c93f63c2hding    if (displaying_order == 0) {
65e26d82700f9514cc175d2b54733ebdeb8824922ehding        for (i = 0; i < (bframes + 2); i++)  {
66e26d82700f9514cc175d2b54733ebdeb8824922ehding            //encoding order
67e26d82700f9514cc175d2b54733ebdeb8824922ehding            if (i == 0)
68e26d82700f9514cc175d2b54733ebdeb8824922ehding                last_info->slot_consume_enc_order[0] = 0;
69e26d82700f9514cc175d2b54733ebdeb8824922ehding            else if (i == 1)
70e26d82700f9514cc175d2b54733ebdeb8824922ehding                last_info->slot_consume_enc_order[bframes + 2 - 1] = 1;
71e26d82700f9514cc175d2b54733ebdeb8824922ehding            else
72e26d82700f9514cc175d2b54733ebdeb8824922ehding                last_info->slot_consume_enc_order[i - 1] = i;
73e26d82700f9514cc175d2b54733ebdeb8824922ehding            last_info->slot_consume_dpy_order[i] = i; //displaying order
748e9a21e730449c10cac6e6f69d255611c93f63c2hding	}
75e26d82700f9514cc175d2b54733ebdeb8824922ehding        last_info->slot_consume_dpy_order[0] = bframes + 2;
76e26d82700f9514cc175d2b54733ebdeb8824922ehding        last_info->slot_consume_enc_order[0] = displayingOrder2EncodingOrder(bframes + 2, bframes, intracnt, idrcnt);
77e26d82700f9514cc175d2b54733ebdeb8824922ehding        last_info->max_dpy_num = bframes + 2;
788e9a21e730449c10cac6e6f69d255611c93f63c2hding    } else {
79e26d82700f9514cc175d2b54733ebdeb8824922ehding        for (i = 0; i < (bframes + 2); i++) {
80e26d82700f9514cc175d2b54733ebdeb8824922ehding            if (last_info->slot_consume_enc_order[i] == encoding_count) {
81e26d82700f9514cc175d2b54733ebdeb8824922ehding               slot_idx = i;
82e26d82700f9514cc175d2b54733ebdeb8824922ehding               break;
83e26d82700f9514cc175d2b54733ebdeb8824922ehding            }
84e26d82700f9514cc175d2b54733ebdeb8824922ehding        }
85e26d82700f9514cc175d2b54733ebdeb8824922ehding        last_info->max_dpy_num++;
86e26d82700f9514cc175d2b54733ebdeb8824922ehding        last_info->slot_consume_dpy_order[slot_idx] = last_info->max_dpy_num;
87e26d82700f9514cc175d2b54733ebdeb8824922ehding        last_info->slot_consume_enc_order[slot_idx] =
88e26d82700f9514cc175d2b54733ebdeb8824922ehding        displayingOrder2EncodingOrder(last_info->max_dpy_num,
89e26d82700f9514cc175d2b54733ebdeb8824922ehding            bframes, intracnt, idrcnt);
908e9a21e730449c10cac6e6f69d255611c93f63c2hding    }
918e9a21e730449c10cac6e6f69d255611c93f63c2hding
928e9a21e730449c10cac6e6f69d255611c93f63c2hding    return slot_idx;
938e9a21e730449c10cac6e6f69d255611c93f63c2hding}
948e9a21e730449c10cac6e6f69d255611c93f63c2hding
958e9a21e730449c10cac6e6f69d255611c93f63c2hdingint getFrameDpyOrder(
968e9a21e730449c10cac6e6f69d255611c93f63c2hding    unsigned long long encoding_count, /*Input, the encoding order, start from 0*/
978e9a21e730449c10cac6e6f69d255611c93f63c2hding    int bframes, /*Input, The number of B frames between P and I */
988e9a21e730449c10cac6e6f69d255611c93f63c2hding    int intracnt, /*Input, Intra period*/
998e9a21e730449c10cac6e6f69d255611c93f63c2hding    int idrcnt, /*INput, IDR period. 0: only one IDR; */
1008e9a21e730449c10cac6e6f69d255611c93f63c2hding    FRAME_ORDER_INFO *p_last_info, /*Input & Output. Reset to 0 on first call*/
101e26d82700f9514cc175d2b54733ebdeb8824922ehding    unsigned long long *displaying_order) /* Output. The displaying order */
1028e9a21e730449c10cac6e6f69d255611c93f63c2hding{
103e26d82700f9514cc175d2b54733ebdeb8824922ehding    IMG_FRAME_TYPE frame_type; /*Output. Frame type. 0: I frame. 1: P frame. 2: B frame*/
104e26d82700f9514cc175d2b54733ebdeb8824922ehding    int slot; /*Output. The corresponding slot index */
105e26d82700f9514cc175d2b54733ebdeb8824922ehding
106e26d82700f9514cc175d2b54733ebdeb8824922ehding    // int i;
1078e9a21e730449c10cac6e6f69d255611c93f63c2hding    unsigned long long disp_index;
1088e9a21e730449c10cac6e6f69d255611c93f63c2hding    unsigned long long val;
1098e9a21e730449c10cac6e6f69d255611c93f63c2hding
1108e9a21e730449c10cac6e6f69d255611c93f63c2hding    if ((intracnt % (bframes + 1)) != 0 || bframes == 0)
111e26d82700f9514cc175d2b54733ebdeb8824922ehding        return -1;
1128e9a21e730449c10cac6e6f69d255611c93f63c2hding
113e26d82700f9514cc175d2b54733ebdeb8824922ehding    val = ((idrcnt == 0) ? encoding_count : encoding_count % (intracnt * idrcnt + 1));
1148e9a21e730449c10cac6e6f69d255611c93f63c2hding    if ((idrcnt == 0 && encoding_count == 0) ||
115e26d82700f9514cc175d2b54733ebdeb8824922ehding        (idrcnt != 0 && (encoding_count % (intracnt * idrcnt + 1) == 0))) {
116e26d82700f9514cc175d2b54733ebdeb8824922ehding        frame_type = IMG_INTRA_IDR;
117e26d82700f9514cc175d2b54733ebdeb8824922ehding        disp_index = encoding_count;
1188e9a21e730449c10cac6e6f69d255611c93f63c2hding    } else if (((val - 1) % (bframes + 1)) != 0) {
119e26d82700f9514cc175d2b54733ebdeb8824922ehding        frame_type = IMG_INTER_B;
120e26d82700f9514cc175d2b54733ebdeb8824922ehding        disp_index = encoding_count - 1;
121e26d82700f9514cc175d2b54733ebdeb8824922ehding    } else if (p_last_info->last_frame_type == IMG_INTRA_IDR ||
122e26d82700f9514cc175d2b54733ebdeb8824922ehding        ((val - 1) / (bframes + 1) % (intracnt / (bframes + 1))) != 0) {
123e26d82700f9514cc175d2b54733ebdeb8824922ehding        frame_type = IMG_INTER_P;
124e26d82700f9514cc175d2b54733ebdeb8824922ehding        disp_index = encoding_count + bframes;
1258e9a21e730449c10cac6e6f69d255611c93f63c2hding    } else {
126e26d82700f9514cc175d2b54733ebdeb8824922ehding        frame_type = IMG_INTRA_FRAME;
127e26d82700f9514cc175d2b54733ebdeb8824922ehding        disp_index = encoding_count + bframes;
128e26d82700f9514cc175d2b54733ebdeb8824922ehding    }
1298e9a21e730449c10cac6e6f69d255611c93f63c2hding
1308e9a21e730449c10cac6e6f69d255611c93f63c2hding    *displaying_order = disp_index;
131e26d82700f9514cc175d2b54733ebdeb8824922ehding    slot = getSlotIndex(bframes, intracnt, idrcnt,
132e26d82700f9514cc175d2b54733ebdeb8824922ehding                 disp_index, encoding_count, p_last_info);
133e26d82700f9514cc175d2b54733ebdeb8824922ehding
134e26d82700f9514cc175d2b54733ebdeb8824922ehding    p_last_info->last_frame_type = frame_type;
135e26d82700f9514cc175d2b54733ebdeb8824922ehding    p_last_info->last_slot = slot;
1368e9a21e730449c10cac6e6f69d255611c93f63c2hding    return 0;
1378e9a21e730449c10cac6e6f69d255611c93f63c2hding}
1388e9a21e730449c10cac6e6f69d255611c93f63c2hding
1398e9a21e730449c10cac6e6f69d255611c93f63c2hding#if 0
1408e9a21e730449c10cac6e6f69d255611c93f63c2hdingint main(int argc, char **argv) {
1418e9a21e730449c10cac6e6f69d255611c93f63c2hding    int bframes, intracnt, frame_num;
1428e9a21e730449c10cac6e6f69d255611c93f63c2hding    int i;
1438e9a21e730449c10cac6e6f69d255611c93f63c2hding    int displaying_order, frame_type, slot;
1448e9a21e730449c10cac6e6f69d255611c93f63c2hding    int j;
1458e9a21e730449c10cac6e6f69d255611c93f63c2hding     char ac_frame_type[] = {'I', 'P', 'B'};
1468e9a21e730449c10cac6e6f69d255611c93f63c2hding    FRAME_ORDER_INFO last_info;
1478e9a21e730449c10cac6e6f69d255611c93f63c2hding
1488e9a21e730449c10cac6e6f69d255611c93f63c2hding    if (argc != 4)
1498e9a21e730449c10cac6e6f69d255611c93f63c2hding    {
1508e9a21e730449c10cac6e6f69d255611c93f63c2hding	    printf("%s [bframe_number] [intra period] [frame_number]\n", argv[0]);
1518e9a21e730449c10cac6e6f69d255611c93f63c2hding	    return 0;
1528e9a21e730449c10cac6e6f69d255611c93f63c2hding    }
1538e9a21e730449c10cac6e6f69d255611c93f63c2hding    else {
1548e9a21e730449c10cac6e6f69d255611c93f63c2hding		bframes = atoi(argv[1]);
1558e9a21e730449c10cac6e6f69d255611c93f63c2hding		intracnt = atoi(argv[2]);
1568e9a21e730449c10cac6e6f69d255611c93f63c2hding		frame_num = atoi(argv[3]);
1578e9a21e730449c10cac6e6f69d255611c93f63c2hding    }
1588e9a21e730449c10cac6e6f69d255611c93f63c2hding    if (intracnt % (bframes + 1) != 0) {
1598e9a21e730449c10cac6e6f69d255611c93f63c2hding		printf(" intra count must be a muliple of (bframe_number + 1)\n");
1608e9a21e730449c10cac6e6f69d255611c93f63c2hding		return 0;
1618e9a21e730449c10cac6e6f69d255611c93f63c2hding    }
1628e9a21e730449c10cac6e6f69d255611c93f63c2hding
1638e9a21e730449c10cac6e6f69d255611c93f63c2hding    memset(&last_info, 0, sizeof(FRAME_ORDER_INFO));
1648e9a21e730449c10cac6e6f69d255611c93f63c2hding    last_info.slot_consume_dpy_order = (int *)malloc((bframes + 2)  * sizeof(int));
1658e9a21e730449c10cac6e6f69d255611c93f63c2hding    last_info.slot_consume_enc_order = (int *)malloc((bframes + 2)  * sizeof(int));
1668e9a21e730449c10cac6e6f69d255611c93f63c2hding
1678e9a21e730449c10cac6e6f69d255611c93f63c2hding    printf("encodingorder displaying order	frame_type	slot index\n");
1688e9a21e730449c10cac6e6f69d255611c93f63c2hding    for (i = 0; i < frame_num; i++) {
1698e9a21e730449c10cac6e6f69d255611c93f63c2hding		getFrameDpyOrder(i, bframes, intracnt, &last_info, &displaying_order, &frame_type, &slot);
1708e9a21e730449c10cac6e6f69d255611c93f63c2hding		printf("%5d\t%5d\t%c\t%d\n", i, displaying_order, ac_frame_type[frame_type], slot);
1718e9a21e730449c10cac6e6f69d255611c93f63c2hding    }
1728e9a21e730449c10cac6e6f69d255611c93f63c2hding    free(last_info.slot_consume_dpy_order);
1738e9a21e730449c10cac6e6f69d255611c93f63c2hding    free(last_info.slot_consume_enc_order);
1748e9a21e730449c10cac6e6f69d255611c93f63c2hding
1758e9a21e730449c10cac6e6f69d255611c93f63c2hding    return 0;
1768e9a21e730449c10cac6e6f69d255611c93f63c2hding}
1778e9a21e730449c10cac6e6f69d255611c93f63c2hding#endif //test routine
178