📄 explicit_gop.c
字号:
/*!
*************************************************************************************
* \file explicit_gop.c
*
* \brief
* Code for explicit gop support and pyramidal coding.
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Alexis Michael Tourapis <alexismt@ieee.org>
*************************************************************************************
*/
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include "global.h"
#include "contributors.h"
#include "explicit_gop.h"
#include "image.h"
#include "nalucommon.h"
#include "string.h"
/*!
************************************************************************
* \brief
* Generation of Pyramid GOP
************************************************************************
*/
void create_pyramid()
{
int i, j;
int centerB=input->successive_Bframe/2;
GOP_DATA tmp;
if (input->PyramidCoding == 1)
{
for (i=0;i<input->successive_Bframe;i++)
{
if (i < centerB)
{
gop_structure[i].slice_type = B_SLICE;
gop_structure[i].display_no = i * 2 + 1;
gop_structure[i].pyramid_layer = 0;
gop_structure[i].reference_idc = NALU_PRIORITY_HIGH;
gop_structure[i].slice_qp = max(0, (input->qpB + (input->PyramidLevelQPEnable ? -1: input->qpBRSOffset)));
}
else
{
gop_structure[i].slice_type = B_SLICE;
gop_structure[i].display_no = (i - centerB) * 2;
gop_structure[i].pyramid_layer = 1;
gop_structure[i].reference_idc = NALU_PRIORITY_DISPOSABLE;
gop_structure[i].slice_qp = input->qpB;
}
}
}
else
{
int GOPlevels = 1;
int Bframes = input->successive_Bframe;
int *curGOPLevelfrm,*curGOPLeveldist ;
int curlevel = GOPlevels ;
int i;
while (((Bframes + 1 ) >> GOPlevels) > 1)
{
GOPlevels ++;
}
curlevel = GOPlevels ;
if (NULL == (curGOPLevelfrm = (int*)malloc(GOPlevels * sizeof(int)))) no_mem_exit("create_pyramid:curGOPLevelfrm");
if (NULL == (curGOPLeveldist= (int*)malloc(GOPlevels * sizeof(int)))) no_mem_exit("create_pyramid:curGOPLeveldist");
for (i=0; i <input->successive_Bframe; i++)
{
gop_structure[i].display_no = i;
gop_structure[i].slice_type = B_SLICE;
gop_structure[i].pyramid_layer = 0;
gop_structure[i].reference_idc = NALU_PRIORITY_DISPOSABLE;
gop_structure[i].slice_qp = input->qpB;
}
for (j = 1; j < GOPlevels; j++)
{
for (i = (1 << j) - 1; i < Bframes + 1 - (1 << j); i += (1 << j)) {
gop_structure[i].pyramid_layer = j;
gop_structure[i].reference_idc = NALU_PRIORITY_HIGH;
gop_structure[i].slice_qp = max(0, input->qpB + (input->PyramidLevelQPEnable ? -j: input->qpBRSOffset));
}
}
for (i = 1; i < Bframes; i++)
{
j = i;
while (j > 0 && gop_structure[j].pyramid_layer > gop_structure[j-1].pyramid_layer)
{
tmp = gop_structure[j-1];
gop_structure[j-1] = gop_structure[j];
gop_structure[j] = tmp;
j--;
}
}
}
}
/*!
************************************************************************
* \brief
* Initialization of GOP structure.
*
************************************************************************
*/
void init_gop_structure()
{
int max_gopsize = input->PyramidCoding != 3 ? input->successive_Bframe : input->jumpd;
gop_structure = calloc(max(10,max_gopsize), sizeof (GOP_DATA)); // +1 for reordering
if (NULL==gop_structure)
no_mem_exit("init_gop_structure: gop_structure");
}
/*!
************************************************************************
* \brief
* Clear GOP structure
************************************************************************
*/
void clear_gop_structure()
{
if (gop_structure)
free(gop_structure);
}
/*!
************************************************************************
* \brief
* Interpret GOP struct from input parameters
************************************************************************
*/
void interpret_gop_structure()
{
int nLength = strlen(input->ExplicitPyramidFormat);
int i =0, k, dqp, display_no;
int slice_read =0, order_read = 0, stored_read = 0, qp_read =0;
int coded_frame = 0;
if (nLength > 0)
{
for (i = 0; i < nLength ; i++)
{
//! First lets read slice type
if (slice_read == 0)
{
switch (input->ExplicitPyramidFormat[i])
{
case 'P':
case 'p':
gop_structure[coded_frame].slice_type=P_SLICE;
break;
case 'B':
case 'b':
gop_structure[coded_frame].slice_type=B_SLICE;
break;
case 'I':
case 'i':
gop_structure[coded_frame].slice_type=I_SLICE;
break;
default:
snprintf(errortext, ET_SIZE, "Slice Type invalid in ExplicitPyramidFormat param. Please check configuration file.");
error (errortext, 400);
break;
}
slice_read = 1;
}
else
{
//! Next is Display Order
if (order_read == 0)
{
if (isdigit((int)(*(input->ExplicitPyramidFormat+i))))
{
sscanf(input->ExplicitPyramidFormat+i,"%d",&display_no);
gop_structure[coded_frame].display_no = display_no;
order_read = 1;
if (display_no<0 || display_no>=input->jumpd)
{
snprintf(errortext, ET_SIZE, "Invalid Frame Order value. Frame position needs to be in [0,%d] range.",input->jumpd-1);
error (errortext, 400);
}
for (k=0;k<coded_frame;k++)
{
if (gop_structure[k].display_no == display_no)
{
snprintf(errortext, ET_SIZE, "Frame Order value %d in frame %d already used for enhancement frame %d.",display_no,coded_frame,k);
error (errortext, 400);
}
}
}
else
{
snprintf(errortext, ET_SIZE, "Slice Type needs to be followed by Display Order. Please check configuration file.");
error (errortext, 400);
}
}
else if (order_read == 1)
{
if (stored_read == 0 && !(isdigit((int)(*(input->ExplicitPyramidFormat+i)))))
{
switch (input->ExplicitPyramidFormat[i])
{
case 'E':
case 'e':
gop_structure[coded_frame].reference_idc = NALU_PRIORITY_DISPOSABLE;
break;
case 'R':
case 'r':
gop_structure[coded_frame].reference_idc= NALU_PRIORITY_HIGH;
break;
default:
snprintf(errortext, ET_SIZE, "Reference_IDC invalid in ExplicitPyramidFormat param. Please check configuration file.");
error (errortext, 400);
break;
}
stored_read = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -