Home | History | Annotate | Download | only in src
      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