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