📄 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 <alexis@mobilygen.com, 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;
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;
}
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;
}
}
}
else
{
int GOPlevels = 0;
int Bframes = input->successive_Bframe;
int *curGOPLevelfrm,*curGOPLeveldist ;
int curlevel = GOPlevels ;
int prvlevelrefs = input->successive_Bframe;
int levelrefs = input->successive_Bframe;
int i;
while (Bframes > 2)
{
Bframes /= 2;
GOPlevels ++;
}
curlevel = GOPlevels ;
curGOPLevelfrm = (int*)malloc(GOPlevels*sizeof(int));
curGOPLeveldist= (int*)malloc(GOPlevels*sizeof(int));
for (i=0; i <input->successive_Bframe; i++)
{
gop_structure[i].display_no = 0;
gop_structure[i].slice_type = B_SLICE;
}
while (levelrefs > 2)
{
levelrefs /= 2;
curGOPLevelfrm[ curlevel ] = prvlevelrefs - levelrefs;
curGOPLeveldist[ GOPlevels - curlevel ] = levelrefs+ (levelrefs )% 2;
prvlevelrefs =levelrefs ;
curlevel --;
}
curGOPLevelfrm[ 0] = levelrefs;
curGOPLeveldist[ GOPlevels] = levelrefs + (levelrefs )% 2;
for (j=0; j<curGOPLevelfrm[0]; j++)
{
gop_pyramid(GOPlevels, (j+ 1) * curGOPLeveldist[ 0] - 1, curGOPLeveldist[ 0]-1, gop_structure);
}
for (j=input->successive_Bframe; j>0; j--)
{
for (i=1; i<j; i++)
{
int tempnum;
if (gop_structure[i].pyramid_layer>gop_structure[i-1].pyramid_layer)
{
tempnum=gop_structure[i -1].display_no;
gop_structure[i-1].display_no = gop_structure[i].display_no;
gop_structure[i].display_no = tempnum;
tempnum=gop_structure[i-1].pyramid_layer;
gop_structure[i-1].pyramid_layer = gop_structure[i].pyramid_layer;
gop_structure[i].pyramid_layer = tempnum;
tempnum=gop_structure[i -1].reference_idc;
gop_structure[i-1].reference_idc = gop_structure[i].reference_idc;
gop_structure[i].reference_idc = tempnum;
tempnum=gop_structure[i -1].slice_type;
gop_structure[i-1].slice_type = gop_structure[i].slice_type;
gop_structure[i].slice_type = tempnum;
tempnum=gop_structure[i -1].slice_qp;
gop_structure[i-1].slice_qp = gop_structure[i].slice_qp;
gop_structure[i].slice_qp = tempnum;
tempnum=gop_structure[i -1].pyramidPocDelta;
gop_structure[i-1].pyramidPocDelta = gop_structure[i].pyramidPocDelta;
gop_structure[i].pyramidPocDelta = tempnum;
}
}
}
}
}
/*!
************************************************************************
* \brief
* True Pyramid GOP generation
************************************************************************
*/
void gop_pyramid(int level, int frm_no, int frames, GOP_DATA *pyramid_structure)
{
if (level == 0 )
{
if (frm_no>=0 && frm_no<input->successive_Bframe && pyramid_structure[frm_no].display_no == 0)
{
pyramid_structure[frm_no].slice_type = B_SLICE;
pyramid_structure[frm_no].display_no = frm_no;
pyramid_structure[frm_no].pyramid_layer = 0;
pyramid_structure[frm_no].reference_idc = NALU_PRIORITY_DISPOSABLE;
}
}
else
{
if (frm_no>=0 && frm_no<input->successive_Bframe)
{
pyramid_structure[frm_no].slice_type = B_SLICE;
pyramid_structure[frm_no].display_no = frm_no;
pyramid_structure[frm_no].pyramid_layer = level;
pyramid_structure[frm_no].reference_idc = NALU_PRIORITY_HIGH;
}
gop_pyramid(level - 1, frm_no - (frames+1)/2,(frames+1)/2,pyramid_structure);
gop_pyramid(level - 1, frm_no + (frames+1)/2,(frames+1)/2,pyramid_structure);
}
}
/*!
************************************************************************
* \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, qp, 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -