You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
516 lines
18 KiB
516 lines
18 KiB
/*****************************************************************************
|
|
* h264_slice.c: h264 slice parser
|
|
*****************************************************************************
|
|
* Copyright (C) 2001-17 VLC authors and VideoLAN
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
*****************************************************************************/
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <vlc_common.h>
|
|
#include <vlc_bits.h>
|
|
|
|
#include "h264_nal.h"
|
|
#include "h264_slice.h"
|
|
#include "hxxx_nal.h"
|
|
#include "hxxx_ep3b.h"
|
|
|
|
struct h264_slice_s
|
|
{
|
|
int i_nal_type;
|
|
int i_nal_ref_idc;
|
|
|
|
int type;
|
|
int i_pic_parameter_set_id;
|
|
unsigned i_frame_num;
|
|
|
|
int i_field_pic_flag;
|
|
int i_bottom_field_flag;
|
|
|
|
int i_idr_pic_id;
|
|
|
|
int i_pic_order_cnt_type;
|
|
int i_pic_order_cnt_lsb;
|
|
int i_delta_pic_order_cnt_bottom;
|
|
|
|
int i_delta_pic_order_cnt0;
|
|
int i_delta_pic_order_cnt1;
|
|
|
|
bool no_output_of_prior_pics_flag;
|
|
bool has_mmco5;
|
|
};
|
|
|
|
enum h264_slice_type_e h264_get_slice_type( const h264_slice_t *p_slice )
|
|
{
|
|
return p_slice->type;
|
|
}
|
|
|
|
bool h264_has_mmco5( const h264_slice_t *p_slice )
|
|
{
|
|
return p_slice->has_mmco5;
|
|
}
|
|
|
|
bool h264_is_field_pic( const h264_slice_t *p_slice )
|
|
{
|
|
return p_slice->i_field_pic_flag;
|
|
}
|
|
|
|
int h264_get_slice_pps_id( const h264_slice_t *p_slice )
|
|
{
|
|
return p_slice->i_pic_parameter_set_id;
|
|
}
|
|
|
|
unsigned h264_get_frame_num( const h264_slice_t *p_slice )
|
|
{
|
|
return p_slice->i_frame_num;
|
|
}
|
|
|
|
unsigned h264_get_nal_ref_idc( const h264_slice_t *p_slice )
|
|
{
|
|
return p_slice->i_nal_ref_idc;
|
|
}
|
|
|
|
void h264_slice_release( h264_slice_t *p_slice )
|
|
{
|
|
free( p_slice );
|
|
}
|
|
|
|
void h264_slice_copy_idr_id( const h264_slice_t *src, h264_slice_t *dst )
|
|
{
|
|
if( !src || src->i_nal_type != H264_NAL_SLICE_IDR ) /* value only set on IDR */
|
|
return;
|
|
dst->i_idr_pic_id = src->i_idr_pic_id;
|
|
}
|
|
|
|
h264_slice_t * h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
|
|
void (* get_sps_pps)(uint8_t, void *,
|
|
const h264_sequence_parameter_set_t **,
|
|
const h264_picture_parameter_set_t ** ),
|
|
void *priv )
|
|
{
|
|
h264_slice_t *p_slice = calloc( 1, sizeof(*p_slice) );
|
|
if( !p_slice )
|
|
return NULL;
|
|
|
|
int i_slice_type;
|
|
bs_t s;
|
|
struct hxxx_bsfw_ep3b_ctx_s bsctx;
|
|
hxxx_bsfw_ep3b_ctx_init( &bsctx );
|
|
bs_init_custom( &s, p_buffer, i_buffer, &hxxx_bsfw_ep3b_callbacks, &bsctx );
|
|
|
|
/* nal unit header */
|
|
bs_skip( &s, 1 );
|
|
const uint8_t i_nal_ref_idc = bs_read( &s, 2 );
|
|
const uint8_t i_nal_type = bs_read( &s, 5 );
|
|
|
|
/* first_mb_in_slice */
|
|
/* int i_first_mb = */ bs_read_ue( &s );
|
|
|
|
/* slice_type */
|
|
i_slice_type = bs_read_ue( &s );
|
|
if( i_slice_type > 9 )
|
|
goto error;
|
|
p_slice->type = i_slice_type % 5;
|
|
|
|
/* */
|
|
p_slice->i_nal_type = i_nal_type;
|
|
p_slice->i_nal_ref_idc = i_nal_ref_idc;
|
|
|
|
p_slice->i_pic_parameter_set_id = bs_read_ue( &s );
|
|
if( p_slice->i_pic_parameter_set_id > H264_PPS_ID_MAX )
|
|
goto error;
|
|
|
|
const h264_sequence_parameter_set_t *p_sps;
|
|
const h264_picture_parameter_set_t *p_pps;
|
|
|
|
/* Bind matched/referred PPS and SPS */
|
|
get_sps_pps( p_slice->i_pic_parameter_set_id, priv, &p_sps, &p_pps );
|
|
if( !p_sps || !p_pps )
|
|
goto error;
|
|
|
|
p_slice->i_frame_num = bs_read( &s, p_sps->i_log2_max_frame_num + 4 );
|
|
|
|
if( !p_sps->frame_mbs_only_flag )
|
|
{
|
|
/* field_pic_flag */
|
|
p_slice->i_field_pic_flag = bs_read( &s, 1 );
|
|
if( p_slice->i_field_pic_flag )
|
|
p_slice->i_bottom_field_flag = bs_read( &s, 1 );
|
|
}
|
|
|
|
if( p_slice->i_nal_type == H264_NAL_SLICE_IDR )
|
|
{
|
|
p_slice->i_idr_pic_id = bs_read_ue( &s );
|
|
if( p_slice->i_idr_pic_id > 65535 )
|
|
goto error;
|
|
}
|
|
|
|
p_slice->i_pic_order_cnt_type = p_sps->i_pic_order_cnt_type;
|
|
if( p_sps->i_pic_order_cnt_type == 0 )
|
|
{
|
|
p_slice->i_pic_order_cnt_lsb = bs_read( &s, p_sps->i_log2_max_pic_order_cnt_lsb + 4 );
|
|
if( p_pps->i_pic_order_present_flag && !p_slice->i_field_pic_flag )
|
|
p_slice->i_delta_pic_order_cnt_bottom = bs_read_se( &s );
|
|
}
|
|
else if( (p_sps->i_pic_order_cnt_type == 1) &&
|
|
(!p_sps->i_delta_pic_order_always_zero_flag) )
|
|
{
|
|
p_slice->i_delta_pic_order_cnt0 = bs_read_se( &s );
|
|
if( p_pps->i_pic_order_present_flag && !p_slice->i_field_pic_flag )
|
|
p_slice->i_delta_pic_order_cnt1 = bs_read_se( &s );
|
|
}
|
|
|
|
if( p_pps->i_redundant_pic_present_flag )
|
|
bs_read_ue( &s ); /* redudant_pic_count */
|
|
|
|
uint32_t num_ref_idx_l01_active_minus1[2] = { p_pps->num_ref_idx_l01_default_active_minus1[0],
|
|
p_pps->num_ref_idx_l01_default_active_minus1[1] };
|
|
|
|
if( i_slice_type == 1 || i_slice_type == 6 ) /* B slices */
|
|
bs_skip( &s, 1 ); /* direct_spatial_mv_pred_flag */
|
|
if( i_slice_type == 0 || i_slice_type == 5 ||
|
|
i_slice_type == 3 || i_slice_type == 8 ||
|
|
i_slice_type == 1 || i_slice_type == 6 ) /* P SP B slices */
|
|
{
|
|
if( bs_read1( &s ) ) /* num_ref_idx_active_override_flag */
|
|
{
|
|
num_ref_idx_l01_active_minus1[0] = bs_read_ue( &s );
|
|
if( i_slice_type == 1 || i_slice_type == 6 ) /* B slices */
|
|
num_ref_idx_l01_active_minus1[1] = bs_read_ue( &s );
|
|
}
|
|
}
|
|
|
|
/* BELOW, Further processing up to assert MMCO 5 presence for POC */
|
|
if( p_slice->i_nal_type == 5 || p_slice->i_nal_ref_idc == 0 )
|
|
{
|
|
/* Early END, don't waste parsing below */
|
|
p_slice->has_mmco5 = false;
|
|
return p_slice;
|
|
}
|
|
|
|
/* ref_pic_list_[mvc_]modification() */
|
|
const bool b_mvc = (p_slice->i_nal_type == 20 || p_slice->i_nal_type == 21 );
|
|
unsigned i = 0;
|
|
if( i_slice_type % 5 != 2 && i_slice_type % 5 != 4 )
|
|
i++;
|
|
if( i_slice_type % 5 == 1 )
|
|
i++;
|
|
|
|
for( ; i>0; i-- )
|
|
{
|
|
if( bs_read1( &s ) ) /* ref_pic_list_modification_flag_l{0,1} */
|
|
{
|
|
uint32_t mod;
|
|
do
|
|
{
|
|
mod = bs_read_ue( &s );
|
|
if( mod < 3 || ( b_mvc && (mod == 4 || mod == 5) ) )
|
|
bs_read_ue( &s ); /* abs_diff_pic_num_minus1, long_term_pic_num, abs_diff_view_idx_min1 */
|
|
}
|
|
while( mod != 3 && !bs_eof( &s ) );
|
|
}
|
|
}
|
|
|
|
if( bs_error( &s ) )
|
|
goto error;
|
|
|
|
/* pred_weight_table() */
|
|
if( ( p_pps->weighted_pred_flag && ( i_slice_type == 0 || i_slice_type == 5 || /* P, SP */
|
|
i_slice_type == 3 || i_slice_type == 8 ) ) ||
|
|
( p_pps->weighted_bipred_idc == 1 && ( i_slice_type == 1 || i_slice_type == 6 ) /* B */ ) )
|
|
{
|
|
bs_read_ue( &s ); /* luma_log2_weight_denom */
|
|
if( !p_sps->b_separate_colour_planes_flag ) /* ChromaArrayType != 0 */
|
|
bs_read_ue( &s ); /* chroma_log2_weight_denom */
|
|
|
|
const unsigned i_num_layers = ( i_slice_type % 5 == 1 ) ? 2 : 1;
|
|
for( unsigned j=0; j < i_num_layers; j++ )
|
|
{
|
|
for( unsigned k=0; k<=num_ref_idx_l01_active_minus1[j]; k++ )
|
|
{
|
|
if( bs_read1( &s ) ) /* luma_weight_l{0,1}_flag */
|
|
{
|
|
bs_read_se( &s );
|
|
bs_read_se( &s );
|
|
}
|
|
if( !p_sps->b_separate_colour_planes_flag ) /* ChromaArrayType != 0 */
|
|
{
|
|
if( bs_read1( &s ) ) /* chroma_weight_l{0,1}_flag */
|
|
{
|
|
bs_read_se( &s );
|
|
bs_read_se( &s );
|
|
bs_read_se( &s );
|
|
bs_read_se( &s );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* dec_ref_pic_marking() */
|
|
if( p_slice->i_nal_type == 5 ) /* IdrFlag */
|
|
{
|
|
p_slice->no_output_of_prior_pics_flag = bs_read1( &s );
|
|
bs_skip( &s, 1 ); /* long_term_reference_flag */
|
|
}
|
|
else
|
|
{
|
|
if( bs_read1( &s ) ) /* adaptive_ref_pic_marking_mode_flag */
|
|
{
|
|
uint32_t mmco;
|
|
do
|
|
{
|
|
mmco = bs_read_ue( &s );
|
|
if( mmco > 6 )
|
|
goto error;
|
|
if( mmco == 1 || mmco == 3 )
|
|
bs_read_ue( &s ); /* diff_pics_minus1 */
|
|
if( mmco == 2 )
|
|
bs_read_ue( &s ); /* long_term_pic_num */
|
|
if( mmco == 3 || mmco == 6 )
|
|
bs_read_ue( &s ); /* long_term_frame_idx */
|
|
if( mmco == 4 )
|
|
bs_read_ue( &s ); /* max_long_term_frame_idx_plus1 */
|
|
if( mmco == 5 )
|
|
{
|
|
p_slice->has_mmco5 = true;
|
|
break; /* Early END */
|
|
}
|
|
}
|
|
while( mmco > 0 );
|
|
}
|
|
}
|
|
|
|
/* If you need to store anything else than MMCO presence above, care of "Early END" cases */
|
|
|
|
if(bs_error( &s ))
|
|
goto error;
|
|
return p_slice;
|
|
|
|
error:
|
|
h264_slice_release( p_slice );
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void h264_compute_poc( const h264_sequence_parameter_set_t *p_sps,
|
|
const h264_slice_t *p_slice, h264_poc_context_t *p_ctx,
|
|
int *p_PictureOrderCount, int *p_tFOC, int *p_bFOC )
|
|
{
|
|
*p_tFOC = *p_bFOC = 0;
|
|
|
|
if( p_sps->i_pic_order_cnt_type == 0 )
|
|
{
|
|
unsigned maxPocLSB = 1U << (p_sps->i_log2_max_pic_order_cnt_lsb + 4);
|
|
|
|
/* POC reference */
|
|
if( p_slice->i_nal_type == H264_NAL_SLICE_IDR )
|
|
{
|
|
p_ctx->prevPicOrderCnt.lsb = 0;
|
|
p_ctx->prevPicOrderCnt.msb = 0;
|
|
}
|
|
else if( p_ctx->prevRefPictureHasMMCO5 )
|
|
{
|
|
p_ctx->prevPicOrderCnt.msb = 0;
|
|
if( !p_ctx->prevRefPictureIsBottomField )
|
|
p_ctx->prevPicOrderCnt.lsb = p_ctx->prevRefPictureTFOC;
|
|
else
|
|
p_ctx->prevPicOrderCnt.lsb = 0;
|
|
}
|
|
|
|
/* 8.2.1.1 */
|
|
int pocMSB = p_ctx->prevPicOrderCnt.msb;
|
|
int64_t orderDiff = p_slice->i_pic_order_cnt_lsb - p_ctx->prevPicOrderCnt.lsb;
|
|
if( orderDiff < 0 && -orderDiff >= maxPocLSB / 2 )
|
|
pocMSB += maxPocLSB;
|
|
else if( orderDiff > maxPocLSB / 2 )
|
|
pocMSB -= maxPocLSB;
|
|
|
|
*p_tFOC = *p_bFOC = pocMSB + p_slice->i_pic_order_cnt_lsb;
|
|
if( p_slice->i_field_pic_flag )
|
|
*p_bFOC += p_slice->i_delta_pic_order_cnt_bottom;
|
|
|
|
/* Save from ref picture */
|
|
if( p_slice->i_nal_ref_idc /* Is reference */ )
|
|
{
|
|
p_ctx->prevRefPictureIsBottomField = (p_slice->i_field_pic_flag &&
|
|
p_slice->i_bottom_field_flag);
|
|
p_ctx->prevRefPictureHasMMCO5 = p_slice->has_mmco5;
|
|
p_ctx->prevRefPictureTFOC = *p_tFOC;
|
|
p_ctx->prevPicOrderCnt.lsb = p_slice->i_pic_order_cnt_lsb;
|
|
p_ctx->prevPicOrderCnt.msb = pocMSB;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
unsigned maxFrameNum = 1 << (p_sps->i_log2_max_frame_num + 4);
|
|
unsigned frameNumOffset;
|
|
unsigned expectedPicOrderCnt = 0;
|
|
|
|
if( p_slice->i_nal_type == H264_NAL_SLICE_IDR )
|
|
frameNumOffset = 0;
|
|
else if( p_ctx->prevFrameNum > p_slice->i_frame_num )
|
|
frameNumOffset = p_ctx->prevFrameNumOffset + maxFrameNum;
|
|
else
|
|
frameNumOffset = p_ctx->prevFrameNumOffset;
|
|
|
|
if( p_sps->i_pic_order_cnt_type == 1 )
|
|
{
|
|
unsigned absFrameNum;
|
|
|
|
if( p_sps->i_num_ref_frames_in_pic_order_cnt_cycle > 0 )
|
|
absFrameNum = frameNumOffset + p_slice->i_frame_num;
|
|
else
|
|
absFrameNum = 0;
|
|
|
|
if( p_slice->i_nal_ref_idc == 0 && absFrameNum > 0 )
|
|
absFrameNum--;
|
|
|
|
if( absFrameNum > 0 )
|
|
{
|
|
int32_t expectedDeltaPerPicOrderCntCycle = 0;
|
|
for( int i=0; i<p_sps->i_num_ref_frames_in_pic_order_cnt_cycle; i++ )
|
|
expectedDeltaPerPicOrderCntCycle += p_sps->offset_for_ref_frame[i];
|
|
|
|
unsigned picOrderCntCycleCnt = 0;
|
|
unsigned frameNumInPicOrderCntCycle = 0;
|
|
if( p_sps->i_num_ref_frames_in_pic_order_cnt_cycle )
|
|
{
|
|
picOrderCntCycleCnt = ( absFrameNum - 1 ) / p_sps->i_num_ref_frames_in_pic_order_cnt_cycle;
|
|
frameNumInPicOrderCntCycle = ( absFrameNum - 1 ) % p_sps->i_num_ref_frames_in_pic_order_cnt_cycle;
|
|
}
|
|
|
|
expectedPicOrderCnt = picOrderCntCycleCnt * expectedDeltaPerPicOrderCntCycle;
|
|
for( unsigned i=0; i <= frameNumInPicOrderCntCycle; i++ )
|
|
expectedPicOrderCnt = expectedPicOrderCnt + p_sps->offset_for_ref_frame[i];
|
|
}
|
|
|
|
if( p_slice->i_nal_ref_idc == 0 )
|
|
expectedPicOrderCnt = expectedPicOrderCnt + p_sps->offset_for_non_ref_pic;
|
|
|
|
*p_tFOC = expectedPicOrderCnt + p_slice->i_delta_pic_order_cnt0;
|
|
if( !p_slice->i_field_pic_flag )
|
|
*p_bFOC = *p_tFOC + p_sps->offset_for_top_to_bottom_field + p_slice->i_delta_pic_order_cnt1;
|
|
else if( p_slice->i_bottom_field_flag )
|
|
*p_bFOC = expectedPicOrderCnt + p_sps->offset_for_top_to_bottom_field + p_slice->i_delta_pic_order_cnt0;
|
|
}
|
|
else if( p_sps->i_pic_order_cnt_type == 2 )
|
|
{
|
|
unsigned tempPicOrderCnt;
|
|
|
|
if( p_slice->i_nal_type == H264_NAL_SLICE_IDR )
|
|
tempPicOrderCnt = 0;
|
|
else if( p_slice->i_nal_ref_idc == 0 )
|
|
tempPicOrderCnt = 2 * ( frameNumOffset + p_slice->i_frame_num ) - 1;
|
|
else
|
|
tempPicOrderCnt = 2 * ( frameNumOffset + p_slice->i_frame_num );
|
|
|
|
*p_bFOC = *p_tFOC = tempPicOrderCnt;
|
|
}
|
|
|
|
p_ctx->prevFrameNum = p_slice->i_frame_num;
|
|
if( p_slice->has_mmco5 )
|
|
p_ctx->prevFrameNumOffset = 0;
|
|
else
|
|
p_ctx->prevFrameNumOffset = frameNumOffset;
|
|
}
|
|
|
|
/* 8.2.1 (8-1) */
|
|
if( !p_slice->i_field_pic_flag ) /* progressive or contains both fields */
|
|
*p_PictureOrderCount = __MIN( *p_bFOC, *p_tFOC );
|
|
else /* split top or bottom field */
|
|
if ( p_slice->i_bottom_field_flag )
|
|
*p_PictureOrderCount = *p_bFOC;
|
|
else
|
|
*p_PictureOrderCount = *p_tFOC;
|
|
}
|
|
|
|
static uint8_t h264_infer_pic_struct( const h264_sequence_parameter_set_t *p_sps,
|
|
const h264_slice_t *p_slice,
|
|
uint8_t i_pic_struct, int tFOC, int bFOC )
|
|
{
|
|
/* See D-1 and note 6 */
|
|
if( !p_sps->vui.b_pic_struct_present_flag || i_pic_struct >= 9 )
|
|
{
|
|
if( p_slice->i_field_pic_flag )
|
|
i_pic_struct = 1 + p_slice->i_bottom_field_flag;
|
|
else if( tFOC == bFOC )
|
|
i_pic_struct = 0;
|
|
else if( tFOC < bFOC )
|
|
i_pic_struct = 3;
|
|
else
|
|
i_pic_struct = 4;
|
|
}
|
|
|
|
return i_pic_struct;
|
|
}
|
|
|
|
uint8_t h264_get_num_ts( const h264_sequence_parameter_set_t *p_sps,
|
|
const h264_slice_t *p_slice, uint8_t i_pic_struct,
|
|
int tFOC, int bFOC )
|
|
{
|
|
i_pic_struct = h264_infer_pic_struct( p_sps, p_slice, i_pic_struct, tFOC, bFOC );
|
|
/* !WARN modified with nuit field based multiplier for values 0, 7 and 8 */
|
|
const uint8_t rgi_numclock[9] = { 2, 1, 1, 2, 2, 3, 3, 4, 6 };
|
|
return rgi_numclock[ i_pic_struct ];
|
|
}
|
|
|
|
bool h264_slice_top_field( const h264_slice_t *p_slice )
|
|
{
|
|
return !p_slice->i_bottom_field_flag;
|
|
}
|
|
|
|
bool h264_IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p_cur )
|
|
{
|
|
/* Detection of the first VCL NAL unit of a primary coded picture
|
|
* (cf. 7.4.1.2.4) */
|
|
if( !p_prev )
|
|
return true;
|
|
if( p_cur->i_frame_num != p_prev->i_frame_num ||
|
|
p_cur->i_pic_parameter_set_id != p_prev->i_pic_parameter_set_id ||
|
|
p_cur->i_field_pic_flag != p_prev->i_field_pic_flag ||
|
|
!p_cur->i_nal_ref_idc != !p_prev->i_nal_ref_idc )
|
|
return true;
|
|
if( p_cur->i_field_pic_flag && /* present in both and differs in value */
|
|
p_cur->i_bottom_field_flag != p_prev->i_bottom_field_flag )
|
|
return true;
|
|
if( p_cur->i_pic_order_cnt_type == p_prev->i_pic_order_cnt_type )
|
|
{
|
|
if( p_cur->i_pic_order_cnt_type == 0 &&
|
|
( p_cur->i_pic_order_cnt_lsb != p_prev->i_pic_order_cnt_lsb ||
|
|
p_cur->i_delta_pic_order_cnt_bottom != p_prev->i_delta_pic_order_cnt_bottom ) )
|
|
return true;
|
|
else if( p_cur->i_pic_order_cnt_type == 1 &&
|
|
( p_cur->i_delta_pic_order_cnt0 != p_prev->i_delta_pic_order_cnt0 ||
|
|
p_cur->i_delta_pic_order_cnt1 != p_prev->i_delta_pic_order_cnt1 ) )
|
|
return true;
|
|
}
|
|
if( ( p_cur->i_nal_type == H264_NAL_SLICE_IDR || p_prev->i_nal_type == H264_NAL_SLICE_IDR ) &&
|
|
( p_cur->i_nal_type != p_prev->i_nal_type || p_cur->i_idr_pic_id != p_prev->i_idr_pic_id ) )
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool h264_CanSwapPTSWithDTS( const h264_slice_t *p_slice, const h264_sequence_parameter_set_t *p_sps )
|
|
{
|
|
if( p_slice->i_nal_ref_idc == 0 && p_slice->type == H264_SLICE_TYPE_B )
|
|
return true;
|
|
else if( p_sps->vui_parameters_present_flag )
|
|
return p_sps->vui.i_max_num_reorder_frames == 0;
|
|
else
|
|
return p_sps->i_profile == PROFILE_H264_CAVLC_INTRA;
|
|
}
|
|
|