173
/* Compute Ceil(Log2(v)) */
174
/* Derived from branchless code for integer log2(v) from:
175
<http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog> */
177
ceil_log2 (guint32 v)
182
r = (v > 0xFFFF) << 4;
184
shift = (v > 0xFF) << 3;
187
shift = (v > 0xF) << 2;
190
shift = (v > 0x3) << 1;
197
/****** Nal parser ******/
204
guint n_epb; /* Number of emulation prevention bytes */
205
guint byte; /* Byte position */
206
guint bits_in_cache; /* bitpos in the cache of next bit */
208
guint64 cache; /* cached bytes */
212
nal_reader_init (NalReader * nr, const guint8 * data, guint size)
219
nr->bits_in_cache = 0;
220
/* fill with something other than 0 to detect emulation prevention bytes */
221
nr->first_byte = 0xff;
225
static inline gboolean
226
nal_reader_read (NalReader * nr, guint nbits)
228
if (G_UNLIKELY (nr->byte * 8 + (nbits - nr->bits_in_cache) > nr->size * 8)) {
229
GST_DEBUG ("Can not read %u bits, bits in cache %u, Byte * 8 %u, size in "
230
"bits %u", nbits, nr->bits_in_cache, nr->byte * 8, nr->size * 8);
234
while (nr->bits_in_cache < nbits) {
236
gboolean check_three_byte;
238
check_three_byte = TRUE;
240
if (G_UNLIKELY (nr->byte >= nr->size))
243
byte = nr->data[nr->byte++];
245
/* check if the byte is a emulation_prevention_three_byte */
246
if (check_three_byte && byte == 0x03 && nr->first_byte == 0x00 &&
247
((nr->cache & 0xff) == 0)) {
248
/* next byte goes unconditionally to the cache, even if it's 0x03 */
249
check_three_byte = FALSE;
253
nr->cache = (nr->cache << 8) | nr->first_byte;
254
nr->first_byte = byte;
255
nr->bits_in_cache += 8;
261
static inline gboolean
262
nal_reader_skip (NalReader * nr, guint nbits)
264
if (G_UNLIKELY (!nal_reader_read (nr, nbits)))
267
nr->bits_in_cache -= nbits;
272
static inline gboolean
273
nal_reader_skip_to_byte (NalReader * nr)
275
if (nr->bits_in_cache == 0) {
276
if (G_LIKELY ((nr->size - nr->byte) > 0))
282
nr->bits_in_cache = 0;
288
nal_reader_get_pos (const NalReader * nr)
290
return nr->byte * 8 - nr->bits_in_cache;
294
nal_reader_get_remaining (const NalReader * nr)
296
return (nr->size - nr->byte) * 8 + nr->bits_in_cache;
300
nal_reader_get_epb_count (const NalReader * nr)
305
#define GST_NAL_READER_READ_BITS(bits) \
307
nal_reader_get_bits_uint##bits (NalReader *nr, guint##bits *val, guint nbits) \
311
if (!nal_reader_read (nr, nbits)) \
314
/* bring the required bits down and truncate */ \
315
shift = nr->bits_in_cache - nbits; \
316
*val = nr->first_byte >> shift; \
318
*val |= nr->cache << (8 - shift); \
319
/* mask out required bits */ \
321
*val &= ((guint##bits)1 << nbits) - 1; \
323
nr->bits_in_cache = shift; \
328
GST_NAL_READER_READ_BITS (8);
329
GST_NAL_READER_READ_BITS (16);
330
GST_NAL_READER_READ_BITS (32);
333
nal_reader_get_ue (NalReader * nr, guint32 * val)
339
if (G_UNLIKELY (!nal_reader_get_bits_uint8 (nr, &bit, 1))) {
347
((!nal_reader_get_bits_uint8 (nr, &bit, 1)))
351
if (G_UNLIKELY (i > 32))
354
if (G_UNLIKELY (!nal_reader_get_bits_uint32 (nr, &value, i)))
357
*val = (1 << i) - 1 + value;
362
static inline gboolean
363
nal_reader_get_se (NalReader * nr, gint32 * val)
367
if (G_UNLIKELY (!nal_reader_get_ue (nr, &value)))
371
*val = (value / 2) + 1;
378
#define CHECK_ALLOWED(val, min, max) { \
379
if (val < min || val > max) { \
380
GST_WARNING ("value not in allowed range. value: %d, range %d-%d", \
386
#define READ_UINT8(nr, val, nbits) { \
387
if (!nal_reader_get_bits_uint8 (nr, &val, nbits)) { \
388
GST_WARNING ("failed to read uint8, nbits: %d", nbits); \
393
#define READ_UINT16(nr, val, nbits) { \
394
if (!nal_reader_get_bits_uint16 (nr, &val, nbits)) { \
395
GST_WARNING ("failed to read uint16, nbits: %d", nbits); \
400
#define READ_UINT32(nr, val, nbits) { \
401
if (!nal_reader_get_bits_uint32 (nr, &val, nbits)) { \
402
GST_WARNING ("failed to read uint32, nbits: %d", nbits); \
407
#define READ_UINT64(nr, val, nbits) { \
408
if (!nal_reader_get_bits_uint64 (nr, &val, nbits)) { \
409
GST_WARNING ("failed to read uint32, nbits: %d", nbits); \
414
#define READ_UE(nr, val) { \
415
if (!nal_reader_get_ue (nr, &val)) { \
416
GST_WARNING ("failed to read UE"); \
421
#define READ_UE_ALLOWED(nr, val, min, max) { \
424
CHECK_ALLOWED (tmp, min, max); \
428
#define READ_SE(nr, val) { \
429
if (!nal_reader_get_se (nr, &val)) { \
430
GST_WARNING ("failed to read SE"); \
435
#define READ_SE_ALLOWED(nr, val, min, max) { \
438
CHECK_ALLOWED (tmp, min, max); \
442
/*********** end of nal parser ***************/
444
174
/***** Utils ****/
445
175
#define EXTENDED_SAR 255
474
set_nalu_datas (GstH264NalUnit * nalu)
204
gst_h264_parse_nalu_header (GstH264NalUnit * nalu)
476
206
guint8 *data = nalu->data + nalu->offset;
207
guint8 svc_extension_flag;
478
213
nalu->type = (data[0] & 0x1f);
479
214
nalu->ref_idc = (data[0] & 0x60) >> 5;
480
215
nalu->idr_pic_flag = (nalu->type == 5 ? 1 : 0);
216
nalu->header_bytes = 1;
218
nalu->extension_type = GST_H264_NAL_EXTENSION_NONE;
219
switch (nalu->type) {
220
case GST_H264_NAL_PREFIX_UNIT:
221
case GST_H264_NAL_SLICE_EXT:
224
gst_bit_reader_init (&br, nalu->data + nalu->offset + nalu->header_bytes,
225
nalu->size - nalu->header_bytes);
227
svc_extension_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
228
if (svc_extension_flag) { /* SVC */
230
nalu->extension_type = GST_H264_NAL_EXTENSION_SVC;
233
GstH264NalUnitExtensionMVC *const mvc = &nalu->extension.mvc;
235
nalu->extension_type = GST_H264_NAL_EXTENSION_MVC;
236
mvc->non_idr_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
237
mvc->priority_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
238
mvc->view_id = gst_bit_reader_get_bits_uint16_unchecked (&br, 10);
239
mvc->temporal_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
240
mvc->anchor_pic_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
241
mvc->inter_view_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
243
/* Update IdrPicFlag (H.7.4.1.1) */
244
nalu->idr_pic_flag = !mvc->non_idr_flag;
246
nalu->header_bytes += 3;
482
250
GST_DEBUG ("Nal type %u, ref_idc %u", nalu->type, nalu->ref_idc);
486
scan_for_start_codes (const guint8 * data, guint size)
489
gst_byte_reader_init (&br, data, size);
491
/* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
492
return gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
254
/* Copy MVC-specific data for subset SPS header */
497
gst_h264_parser_more_data (NalReader * nr)
256
gst_h264_sps_mvc_copy (GstH264SPS * dst_sps, const GstH264SPS * src_sps)
500
guint remaining, nbits;
501
guint8 rbsp_stop_one_bit, zero_bits;
503
remaining = nal_reader_get_remaining (nr);
510
if (!nal_reader_get_bits_uint8 (nr, &rbsp_stop_one_bit, 1))
512
if (!rbsp_stop_one_bit)
515
nbits = --remaining % 8;
516
while (remaining > 0) {
517
if (!nal_reader_get_bits_uint8 (nr, &zero_bits, nbits))
258
GstH264SPSExtMVC *const dst_mvc = &dst_sps->extension.mvc;
259
const GstH264SPSExtMVC *const src_mvc = &src_sps->extension.mvc;
262
g_assert (dst_sps->extension_type == GST_H264_NAL_EXTENSION_MVC);
264
dst_mvc->num_views_minus1 = src_mvc->num_views_minus1;
265
dst_mvc->view = g_new0 (GstH264SPSExtMVCView, dst_mvc->num_views_minus1 + 1);
269
dst_mvc->view[0].view_id = src_mvc->view[0].view_id;
271
for (i = 1; i <= dst_mvc->num_views_minus1; i++) {
272
GstH264SPSExtMVCView *const dst_view = &dst_mvc->view[i];
273
const GstH264SPSExtMVCView *const src_view = &src_mvc->view[i];
275
dst_view->view_id = src_view->view_id;
277
dst_view->num_anchor_refs_l0 = src_view->num_anchor_refs_l0;
278
for (j = 0; j < dst_view->num_anchor_refs_l0; j++)
279
dst_view->anchor_ref_l0[j] = src_view->anchor_ref_l0[j];
281
dst_view->num_anchor_refs_l1 = src_view->num_anchor_refs_l1;
282
for (j = 0; j < dst_view->num_anchor_refs_l1; j++)
283
dst_view->anchor_ref_l1[j] = src_view->anchor_ref_l1[j];
285
dst_view->num_non_anchor_refs_l0 = src_view->num_non_anchor_refs_l0;
286
for (j = 0; j < dst_view->num_non_anchor_refs_l0; j++)
287
dst_view->non_anchor_ref_l0[j] = src_view->non_anchor_ref_l0[j];
289
dst_view->num_non_anchor_refs_l1 = src_view->num_non_anchor_refs_l1;
290
for (j = 0; j < dst_view->num_non_anchor_refs_l1; j++)
291
dst_view->non_anchor_ref_l1[j] = src_view->non_anchor_ref_l1[j];
294
dst_mvc->num_level_values_signalled_minus1 =
295
src_mvc->num_level_values_signalled_minus1;
296
dst_mvc->level_value = g_new0 (GstH264SPSExtMVCLevelValue,
297
dst_mvc->num_level_values_signalled_minus1 + 1);
298
if (!dst_mvc->level_value)
301
for (i = 0; i <= dst_mvc->num_level_values_signalled_minus1; i++) {
302
GstH264SPSExtMVCLevelValue *const dst_value = &dst_mvc->level_value[i];
303
const GstH264SPSExtMVCLevelValue *const src_value =
304
&src_mvc->level_value[i];
306
dst_value->level_idc = src_value->level_idc;
308
dst_value->num_applicable_ops_minus1 = src_value->num_applicable_ops_minus1;
309
dst_value->applicable_op = g_new0 (GstH264SPSExtMVCLevelValueOp,
310
dst_value->num_applicable_ops_minus1 + 1);
311
if (!dst_value->applicable_op)
314
for (j = 0; j <= dst_value->num_applicable_ops_minus1; j++) {
315
GstH264SPSExtMVCLevelValueOp *const dst_op = &dst_value->applicable_op[j];
316
const GstH264SPSExtMVCLevelValueOp *const src_op =
317
&src_value->applicable_op[j];
319
dst_op->temporal_id = src_op->temporal_id;
320
dst_op->num_target_views_minus1 = src_op->num_target_views_minus1;
321
dst_op->target_view_id =
322
g_new (guint16, dst_op->num_target_views_minus1 + 1);
323
if (!dst_op->target_view_id)
326
for (k = 0; k <= dst_op->num_target_views_minus1; k++)
327
dst_op->target_view_id[k] = src_op->target_view_id[k];
328
dst_op->num_views_minus1 = src_op->num_views_minus1;
336
* @dst_sps: The destination #GstH264SPS to copy into
337
* @src_sps: The source #GstH264SPS to copy from
339
* Copies @src_sps into @dst_sps.
341
* Returns: %TRUE if everything went fine, %FALSE otherwise
344
gst_h264_sps_copy (GstH264SPS * dst_sps, const GstH264SPS * src_sps)
346
g_return_val_if_fail (dst_sps != NULL, FALSE);
347
g_return_val_if_fail (src_sps != NULL, FALSE);
349
gst_h264_sps_clear (dst_sps);
353
switch (dst_sps->extension_type) {
354
case GST_H264_NAL_EXTENSION_MVC:
355
if (!gst_h264_sps_mvc_copy (dst_sps, src_sps))
364
* @dst_pps: The destination #GstH264PPS to copy into
365
* @src_pps: The source #GstH264PPS to copy from
367
* Copies @src_pps into @dst_pps.
369
* Returns: %TRUE if everything went fine, %FALSE otherwise
372
gst_h264_pps_copy (GstH264PPS * dst_pps, const GstH264PPS * src_pps)
374
g_return_val_if_fail (dst_pps != NULL, FALSE);
375
g_return_val_if_fail (src_pps != NULL, FALSE);
377
gst_h264_pps_clear (dst_pps);
381
if (src_pps->slice_group_id)
382
dst_pps->slice_group_id = g_memdup (src_pps->slice_group_id,
383
src_pps->pic_size_in_map_units_minus1 + 1);
527
388
/****** Parsing functions *****/
1150
1026
return GST_H264_PARSER_ERROR;
1029
/* Parse SEI stereo_video_info() message */
1030
static GstH264ParserResult
1031
gst_h264_parser_parse_stereo_video_info (GstH264NalParser * nalparser,
1032
GstH264StereoVideoInfo * info, NalReader * nr)
1034
GST_DEBUG ("parsing \"Stereo Video info\"");
1036
READ_UINT8 (nr, info->field_views_flag, 1);
1037
if (info->field_views_flag) {
1038
READ_UINT8 (nr, info->top_field_is_left_view_flag, 1);
1040
READ_UINT8 (nr, info->current_frame_is_left_view_flag, 1);
1041
READ_UINT8 (nr, info->next_frame_is_second_view_flag, 1);
1043
READ_UINT8 (nr, info->left_view_self_contained_flag, 1);
1044
READ_UINT8 (nr, info->right_view_self_contained_flag, 1);
1046
return GST_H264_PARSER_OK;
1049
GST_WARNING ("error parsing \"Stereo Video info\"");
1050
return GST_H264_PARSER_ERROR;
1053
/* Parse SEI frame_packing_arrangement() message */
1054
static GstH264ParserResult
1055
gst_h264_parser_parse_frame_packing (GstH264NalParser * nalparser,
1056
GstH264FramePacking * frame_packing, NalReader * nr, guint payload_size)
1058
guint8 frame_packing_extension_flag;
1061
GST_DEBUG ("parsing \"Frame Packing Arrangement\"");
1063
start_pos = nal_reader_get_pos (nr);
1064
READ_UE (nr, frame_packing->frame_packing_id);
1065
READ_UINT8 (nr, frame_packing->frame_packing_cancel_flag, 1);
1067
if (!frame_packing->frame_packing_cancel_flag) {
1068
READ_UINT8 (nr, frame_packing->frame_packing_type, 7);
1069
READ_UINT8 (nr, frame_packing->quincunx_sampling_flag, 1);
1070
READ_UINT8 (nr, frame_packing->content_interpretation_type, 6);
1071
READ_UINT8 (nr, frame_packing->spatial_flipping_flag, 1);
1072
READ_UINT8 (nr, frame_packing->frame0_flipped_flag, 1);
1073
READ_UINT8 (nr, frame_packing->field_views_flag, 1);
1074
READ_UINT8 (nr, frame_packing->current_frame_is_frame0_flag, 1);
1075
READ_UINT8 (nr, frame_packing->frame0_self_contained_flag, 1);
1076
READ_UINT8 (nr, frame_packing->frame1_self_contained_flag, 1);
1078
if (!frame_packing->quincunx_sampling_flag &&
1079
frame_packing->frame_packing_type !=
1080
GST_H264_FRAME_PACKING_TEMPORAL_INTERLEAVING) {
1081
READ_UINT8 (nr, frame_packing->frame0_grid_position_x, 4);
1082
READ_UINT8 (nr, frame_packing->frame0_grid_position_y, 4);
1083
READ_UINT8 (nr, frame_packing->frame1_grid_position_x, 4);
1084
READ_UINT8 (nr, frame_packing->frame1_grid_position_y, 4);
1087
/* Skip frame_packing_arrangement_reserved_byte */
1088
if (!nal_reader_skip (nr, 8))
1091
READ_UE_ALLOWED (nr, frame_packing->frame_packing_repetition_period, 0,
1095
/* All data that follows within a frame packing arrangement SEI message
1096
after the value 1 for frame_packing_arrangement_extension_flag shall
1097
be ignored (D.2.25) */
1098
READ_UINT8 (nr, frame_packing_extension_flag, 1);
1099
if (!frame_packing_extension_flag)
1101
nal_reader_skip_long (nr,
1102
payload_size - (nal_reader_get_pos (nr) - start_pos));
1104
return GST_H264_PARSER_OK;
1107
GST_WARNING ("error parsing \"Frame Packing Arrangement\"");
1108
return GST_H264_PARSER_ERROR;
1111
static GstH264ParserResult
1112
gst_h264_parser_parse_recovery_point (GstH264NalParser * nalparser,
1113
GstH264RecoveryPoint * rp, NalReader * nr)
1115
GstH264SPS *const sps = nalparser->last_sps;
1117
GST_DEBUG ("parsing \"Recovery point\"");
1118
if (!sps || !sps->valid) {
1119
GST_WARNING ("didn't get the associated sequence paramater set for the "
1120
"current access unit");
1124
READ_UE_ALLOWED (nr, rp->recovery_frame_cnt, 0, sps->max_frame_num - 1);
1125
READ_UINT8 (nr, rp->exact_match_flag, 1);
1126
READ_UINT8 (nr, rp->broken_link_flag, 1);
1127
READ_UINT8 (nr, rp->changing_slice_group_idc, 2);
1129
return GST_H264_PARSER_OK;
1132
GST_WARNING ("error parsing \"Recovery point\"");
1133
return GST_H264_PARSER_ERROR;
1136
static GstH264ParserResult
1137
gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser,
1138
NalReader * nr, GstH264SEIMessage * sei)
1140
guint32 payloadSize;
1141
guint8 payload_type_byte, payload_size_byte;
1142
guint remaining, payload_size;
1143
GstH264ParserResult res;
1145
GST_DEBUG ("parsing \"Sei message\"");
1147
sei->payloadType = 0;
1149
READ_UINT8 (nr, payload_type_byte, 8);
1150
sei->payloadType += payload_type_byte;
1151
} while (payload_type_byte == 0xff);
1155
READ_UINT8 (nr, payload_size_byte, 8);
1156
payloadSize += payload_size_byte;
1158
while (payload_size_byte == 0xff);
1160
remaining = nal_reader_get_remaining (nr);
1161
payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
1163
GST_DEBUG ("SEI message received: payloadType %u, payloadSize = %u bits",
1164
sei->payloadType, payload_size);
1166
switch (sei->payloadType) {
1167
case GST_H264_SEI_BUF_PERIOD:
1168
/* size not set; might depend on emulation_prevention_three_byte */
1169
res = gst_h264_parser_parse_buffering_period (nalparser,
1170
&sei->payload.buffering_period, nr);
1172
case GST_H264_SEI_PIC_TIMING:
1173
/* size not set; might depend on emulation_prevention_three_byte */
1174
res = gst_h264_parser_parse_pic_timing (nalparser,
1175
&sei->payload.pic_timing, nr);
1177
case GST_H264_SEI_RECOVERY_POINT:
1178
res = gst_h264_parser_parse_recovery_point (nalparser,
1179
&sei->payload.recovery_point, nr);
1181
case GST_H264_SEI_STEREO_VIDEO_INFO:
1182
res = gst_h264_parser_parse_stereo_video_info (nalparser,
1183
&sei->payload.stereo_video_info, nr);
1185
case GST_H264_SEI_FRAME_PACKING:
1186
res = gst_h264_parser_parse_frame_packing (nalparser,
1187
&sei->payload.frame_packing, nr, payload_size);
1190
/* Just consume payloadSize bytes, which does not account for
1191
emulation prevention bytes */
1192
if (!nal_reader_skip_long (nr, payload_size))
1194
res = GST_H264_PARSER_OK;
1198
/* When SEI message doesn't end at byte boundary,
1199
* check remaining bits fit the specification.
1201
if (!nal_reader_is_byte_aligned (nr)) {
1202
guint8 bit_equal_to_one;
1203
READ_UINT8 (nr, bit_equal_to_one, 1);
1204
if (!bit_equal_to_one)
1205
GST_WARNING ("Bit non equal to one.");
1207
while (!nal_reader_is_byte_aligned (nr)) {
1208
guint8 bit_equal_to_zero;
1209
READ_UINT8 (nr, bit_equal_to_zero, 1);
1210
if (bit_equal_to_zero)
1211
GST_WARNING ("Bit non equal to zero.");
1218
GST_WARNING ("error parsing \"Sei message\"");
1219
return GST_H264_PARSER_ERROR;
1153
1222
/******** API *************/
1399
1485
if (res == GST_H264_PARSER_OK) {
1400
1486
GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1402
nalparser->sps[sps->id] = *sps;
1488
if (!gst_h264_sps_copy (&nalparser->sps[sps->id], sps))
1489
return GST_H264_PARSER_ERROR;
1403
1490
nalparser->last_sps = &nalparser->sps[sps->id];
1412
* gst_h264_parse_sps:
1413
* @nalu: The #GST_H264_NAL_SPS #GstH264NalUnit to parse
1414
* @sps: The #GstH264SPS to fill.
1415
* @parse_vui_params: Whether to parse the vui_params or not
1417
* Parses @data, and fills the @sps structure.
1419
* Returns: a #GstH264ParserResult
1422
gst_h264_parse_sps (GstH264NalUnit * nalu, GstH264SPS * sps,
1495
/* Parse seq_parameter_set_data() */
1497
gst_h264_parse_sps_data (NalReader * nr, GstH264SPS * sps,
1423
1498
gboolean parse_vui_params)
1426
1500
gint width, height;
1427
1501
guint subwc[] = { 1, 2, 2, 1 };
1428
1502
guint subhc[] = { 1, 2, 1, 1 };
1429
1503
GstH264VUIParams *vui = NULL;
1431
INITIALIZE_DEBUG_CATEGORY;
1432
GST_DEBUG ("parsing SPS");
1433
nal_reader_init (&nr, nalu->data + nalu->offset + 1, nalu->size - 1);
1435
1505
/* set default values for fields that might not be present in the bitstream
1436
1506
and have valid defaults */
1507
sps->extension_type = GST_H264_NAL_EXTENSION_NONE;
1437
1508
sps->chroma_format_idc = 1;
1438
1509
sps->separate_colour_plane_flag = 0;
1439
1510
sps->bit_depth_luma_minus8 = 0;
1448
1519
sps->frame_crop_bottom_offset = 0;
1449
1520
sps->delta_pic_order_always_zero_flag = 0;
1451
READ_UINT8 (&nr, sps->profile_idc, 8);
1452
READ_UINT8 (&nr, sps->constraint_set0_flag, 1);
1453
READ_UINT8 (&nr, sps->constraint_set1_flag, 1);
1454
READ_UINT8 (&nr, sps->constraint_set2_flag, 1);
1455
READ_UINT8 (&nr, sps->constraint_set3_flag, 1);
1522
READ_UINT8 (nr, sps->profile_idc, 8);
1523
READ_UINT8 (nr, sps->constraint_set0_flag, 1);
1524
READ_UINT8 (nr, sps->constraint_set1_flag, 1);
1525
READ_UINT8 (nr, sps->constraint_set2_flag, 1);
1526
READ_UINT8 (nr, sps->constraint_set3_flag, 1);
1527
READ_UINT8 (nr, sps->constraint_set4_flag, 1);
1528
READ_UINT8 (nr, sps->constraint_set5_flag, 1);
1457
/* skip reserved_zero_4bits */
1458
if (!nal_reader_skip (&nr, 4))
1530
/* skip reserved_zero_2bits */
1531
if (!nal_reader_skip (nr, 2))
1461
READ_UINT8 (&nr, sps->level_idc, 8);
1534
READ_UINT8 (nr, sps->level_idc, 8);
1463
READ_UE_ALLOWED (&nr, sps->id, 0, GST_H264_MAX_SPS_COUNT - 1);
1536
READ_UE_ALLOWED (nr, sps->id, 0, GST_H264_MAX_SPS_COUNT - 1);
1465
1538
if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
1466
1539
sps->profile_idc == 122 || sps->profile_idc == 244 ||
1467
1540
sps->profile_idc == 44 || sps->profile_idc == 83 ||
1468
sps->profile_idc == 86) {
1469
READ_UE_ALLOWED (&nr, sps->chroma_format_idc, 0, 3);
1541
sps->profile_idc == 86 || sps->profile_idc == 118 ||
1542
sps->profile_idc == 128) {
1543
READ_UE_ALLOWED (nr, sps->chroma_format_idc, 0, 3);
1470
1544
if (sps->chroma_format_idc == 3)
1471
READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
1473
READ_UE_ALLOWED (&nr, sps->bit_depth_luma_minus8, 0, 6);
1474
READ_UE_ALLOWED (&nr, sps->bit_depth_chroma_minus8, 0, 6);
1475
READ_UINT8 (&nr, sps->qpprime_y_zero_transform_bypass_flag, 1);
1477
READ_UINT8 (&nr, sps->scaling_matrix_present_flag, 1);
1545
READ_UINT8 (nr, sps->separate_colour_plane_flag, 1);
1547
READ_UE_ALLOWED (nr, sps->bit_depth_luma_minus8, 0, 6);
1548
READ_UE_ALLOWED (nr, sps->bit_depth_chroma_minus8, 0, 6);
1549
READ_UINT8 (nr, sps->qpprime_y_zero_transform_bypass_flag, 1);
1551
READ_UINT8 (nr, sps->scaling_matrix_present_flag, 1);
1478
1552
if (sps->scaling_matrix_present_flag) {
1479
1553
guint8 n_lists;
1481
1555
n_lists = (sps->chroma_format_idc != 3) ? 8 : 12;
1482
if (!gst_h264_parser_parse_scaling_list (&nr,
1556
if (!gst_h264_parser_parse_scaling_list (nr,
1483
1557
sps->scaling_lists_4x4, sps->scaling_lists_8x8,
1484
1558
default_4x4_inter, default_4x4_intra,
1485
1559
default_8x8_inter, default_8x8_intra, n_lists))
1490
READ_UE_ALLOWED (&nr, sps->log2_max_frame_num_minus4, 0, 12);
1564
READ_UE_ALLOWED (nr, sps->log2_max_frame_num_minus4, 0, 12);
1492
1566
sps->max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
1494
READ_UE_ALLOWED (&nr, sps->pic_order_cnt_type, 0, 2);
1568
READ_UE_ALLOWED (nr, sps->pic_order_cnt_type, 0, 2);
1495
1569
if (sps->pic_order_cnt_type == 0) {
1496
READ_UE_ALLOWED (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 0, 12);
1570
READ_UE_ALLOWED (nr, sps->log2_max_pic_order_cnt_lsb_minus4, 0, 12);
1497
1571
} else if (sps->pic_order_cnt_type == 1) {
1500
READ_UINT8 (&nr, sps->delta_pic_order_always_zero_flag, 1);
1501
READ_SE (&nr, sps->offset_for_non_ref_pic);
1502
READ_SE (&nr, sps->offset_for_top_to_bottom_field);
1503
READ_UE_ALLOWED (&nr, sps->num_ref_frames_in_pic_order_cnt_cycle, 0, 255);
1574
READ_UINT8 (nr, sps->delta_pic_order_always_zero_flag, 1);
1575
READ_SE (nr, sps->offset_for_non_ref_pic);
1576
READ_SE (nr, sps->offset_for_top_to_bottom_field);
1577
READ_UE_ALLOWED (nr, sps->num_ref_frames_in_pic_order_cnt_cycle, 0, 255);
1505
1579
for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
1506
READ_SE (&nr, sps->offset_for_ref_frame[i]);
1580
READ_SE (nr, sps->offset_for_ref_frame[i]);
1509
READ_UE (&nr, sps->num_ref_frames);
1510
READ_UINT8 (&nr, sps->gaps_in_frame_num_value_allowed_flag, 1);
1511
READ_UE (&nr, sps->pic_width_in_mbs_minus1);
1512
READ_UE (&nr, sps->pic_height_in_map_units_minus1);
1513
READ_UINT8 (&nr, sps->frame_mbs_only_flag, 1);
1583
READ_UE (nr, sps->num_ref_frames);
1584
READ_UINT8 (nr, sps->gaps_in_frame_num_value_allowed_flag, 1);
1585
READ_UE (nr, sps->pic_width_in_mbs_minus1);
1586
READ_UE (nr, sps->pic_height_in_map_units_minus1);
1587
READ_UINT8 (nr, sps->frame_mbs_only_flag, 1);
1515
1589
if (!sps->frame_mbs_only_flag)
1516
READ_UINT8 (&nr, sps->mb_adaptive_frame_field_flag, 1);
1590
READ_UINT8 (nr, sps->mb_adaptive_frame_field_flag, 1);
1518
READ_UINT8 (&nr, sps->direct_8x8_inference_flag, 1);
1519
READ_UINT8 (&nr, sps->frame_cropping_flag, 1);
1592
READ_UINT8 (nr, sps->direct_8x8_inference_flag, 1);
1593
READ_UINT8 (nr, sps->frame_cropping_flag, 1);
1520
1594
if (sps->frame_cropping_flag) {
1521
READ_UE (&nr, sps->frame_crop_left_offset);
1522
READ_UE (&nr, sps->frame_crop_right_offset);
1523
READ_UE (&nr, sps->frame_crop_top_offset);
1524
READ_UE (&nr, sps->frame_crop_bottom_offset);
1595
READ_UE (nr, sps->frame_crop_left_offset);
1596
READ_UE (nr, sps->frame_crop_right_offset);
1597
READ_UE (nr, sps->frame_crop_top_offset);
1598
READ_UE (nr, sps->frame_crop_bottom_offset);
1527
READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
1601
READ_UINT8 (nr, sps->vui_parameters_present_flag, 1);
1528
1602
if (sps->vui_parameters_present_flag && parse_vui_params) {
1529
if (!gst_h264_parse_vui_parameters (sps, &nr))
1603
if (!gst_h264_parse_vui_parameters (sps, nr))
1531
1605
vui = &sps->vui_parameters;
1591
1664
GST_LOG ("No VUI, unknown framerate");
1672
/* Parse subset_seq_parameter_set() data for MVC */
1674
gst_h264_parse_sps_mvc_data (NalReader * nr, GstH264SPS * sps,
1675
gboolean parse_vui_params)
1677
GstH264SPSExtMVC *const mvc = &sps->extension.mvc;
1678
guint8 bit_equal_to_one;
1681
READ_UINT8 (nr, bit_equal_to_one, 1);
1682
if (!bit_equal_to_one)
1685
sps->extension_type = GST_H264_NAL_EXTENSION_MVC;
1687
READ_UE_ALLOWED (nr, mvc->num_views_minus1, 0, GST_H264_MAX_VIEW_COUNT - 1);
1689
mvc->view = g_new0 (GstH264SPSExtMVCView, mvc->num_views_minus1 + 1);
1691
goto error_allocation_failed;
1693
for (i = 0; i <= mvc->num_views_minus1; i++)
1694
READ_UE_ALLOWED (nr, mvc->view[i].view_id, 0, GST_H264_MAX_VIEW_ID);
1696
for (i = 1; i <= mvc->num_views_minus1; i++) {
1697
/* for RefPicList0 */
1698
READ_UE_ALLOWED (nr, mvc->view[i].num_anchor_refs_l0, 0, 15);
1699
for (j = 0; j < mvc->view[i].num_anchor_refs_l0; j++) {
1700
READ_UE_ALLOWED (nr, mvc->view[i].anchor_ref_l0[j], 0,
1701
GST_H264_MAX_VIEW_ID);
1704
/* for RefPicList1 */
1705
READ_UE_ALLOWED (nr, mvc->view[i].num_anchor_refs_l1, 0, 15);
1706
for (j = 0; j < mvc->view[i].num_anchor_refs_l1; j++) {
1707
READ_UE_ALLOWED (nr, mvc->view[i].anchor_ref_l1[j], 0,
1708
GST_H264_MAX_VIEW_ID);
1712
for (i = 1; i <= mvc->num_views_minus1; i++) {
1713
/* for RefPicList0 */
1714
READ_UE_ALLOWED (nr, mvc->view[i].num_non_anchor_refs_l0, 0, 15);
1715
for (j = 0; j < mvc->view[i].num_non_anchor_refs_l0; j++) {
1716
READ_UE_ALLOWED (nr, mvc->view[i].non_anchor_ref_l0[j], 0,
1717
GST_H264_MAX_VIEW_ID);
1720
/* for RefPicList1 */
1721
READ_UE_ALLOWED (nr, mvc->view[i].num_non_anchor_refs_l1, 0, 15);
1722
for (j = 0; j < mvc->view[i].num_non_anchor_refs_l1; j++) {
1723
READ_UE_ALLOWED (nr, mvc->view[i].non_anchor_ref_l1[j], 0,
1724
GST_H264_MAX_VIEW_ID);
1728
READ_UE_ALLOWED (nr, mvc->num_level_values_signalled_minus1, 0, 63);
1731
g_new0 (GstH264SPSExtMVCLevelValue,
1732
mvc->num_level_values_signalled_minus1 + 1);
1733
if (!mvc->level_value)
1734
goto error_allocation_failed;
1736
for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) {
1737
GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_value[i];
1739
READ_UINT8 (nr, level_value->level_idc, 8);
1741
READ_UE_ALLOWED (nr, level_value->num_applicable_ops_minus1, 0, 1023);
1742
level_value->applicable_op =
1743
g_new0 (GstH264SPSExtMVCLevelValueOp,
1744
level_value->num_applicable_ops_minus1 + 1);
1745
if (!level_value->applicable_op)
1746
goto error_allocation_failed;
1748
for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) {
1749
GstH264SPSExtMVCLevelValueOp *const op = &level_value->applicable_op[j];
1751
READ_UINT8 (nr, op->temporal_id, 3);
1753
READ_UE_ALLOWED (nr, op->num_target_views_minus1, 0, 1023);
1754
op->target_view_id = g_new (guint16, op->num_target_views_minus1 + 1);
1755
if (!op->target_view_id)
1756
goto error_allocation_failed;
1758
for (k = 0; k <= op->num_target_views_minus1; k++)
1759
READ_UE_ALLOWED (nr, op->target_view_id[k], 0, GST_H264_MAX_VIEW_ID);
1760
READ_UE_ALLOWED (nr, op->num_views_minus1, 0, 1023);
1765
error_allocation_failed:
1766
GST_WARNING ("failed to allocate memory");
1767
gst_h264_sps_clear (sps);
1771
gst_h264_sps_clear (sps);
1776
* gst_h264_parse_sps:
1777
* @nalu: The #GST_H264_NAL_SPS #GstH264NalUnit to parse
1778
* @sps: The #GstH264SPS to fill.
1779
* @parse_vui_params: Whether to parse the vui_params or not
1781
* Parses @data, and fills the @sps structure.
1783
* Returns: a #GstH264ParserResult
1786
gst_h264_parse_sps (GstH264NalUnit * nalu, GstH264SPS * sps,
1787
gboolean parse_vui_params)
1791
INITIALIZE_DEBUG_CATEGORY;
1792
GST_DEBUG ("parsing SPS");
1794
nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1795
nalu->size - nalu->header_bytes);
1797
if (!gst_h264_parse_sps_data (&nr, sps, parse_vui_params))
1594
1800
sps->valid = TRUE;
1811
* gst_h264_parser_parse_subset_sps:
1812
* @nalparser: a #GstH264NalParser
1813
* @nalu: The #GST_H264_NAL_SUBSET_SPS #GstH264NalUnit to parse
1814
* @sps: The #GstH264SPS to fill.
1815
* @parse_vui_params: Whether to parse the vui_params or not
1817
* Parses @data, and fills in the @sps structure.
1819
* This function fully parses @data and allocates all the necessary
1820
* data structures needed for MVC extensions. The resulting @sps
1821
* structure shall be deallocated with gst_h264_sps_clear() when it is
1824
* Note: if the caller doesn't need any of the MVC-specific data, then
1825
* gst_h264_parser_parse_sps() is more efficient because those extra
1826
* syntax elements are not parsed and no extra memory is allocated.
1828
* Returns: a #GstH264ParserResult
1831
gst_h264_parser_parse_subset_sps (GstH264NalParser * nalparser,
1832
GstH264NalUnit * nalu, GstH264SPS * sps, gboolean parse_vui_params)
1834
GstH264ParserResult res;
1836
res = gst_h264_parse_subset_sps (nalu, sps, parse_vui_params);
1837
if (res == GST_H264_PARSER_OK) {
1838
GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1840
if (!gst_h264_sps_copy (&nalparser->sps[sps->id], sps))
1841
return GST_H264_PARSER_ERROR;
1842
nalparser->last_sps = &nalparser->sps[sps->id];
1848
* gst_h264_parse_subset_sps:
1849
* @nalu: The #GST_H264_NAL_SUBSET_SPS #GstH264NalUnit to parse
1850
* @sps: The #GstH264SPS to fill.
1851
* @parse_vui_params: Whether to parse the vui_params or not
1853
* Parses @data, and fills in the @sps structure.
1855
* This function fully parses @data and allocates all the necessary
1856
* data structures needed for MVC extensions. The resulting @sps
1857
* structure shall be deallocated with gst_h264_sps_clear() when it is
1860
* Note: if the caller doesn't need any of the MVC-specific data, then
1861
* gst_h264_parser_parse_sps() is more efficient because those extra
1862
* syntax elements are not parsed and no extra memory is allocated.
1864
* Returns: a #GstH264ParserResult
1867
gst_h264_parse_subset_sps (GstH264NalUnit * nalu, GstH264SPS * sps,
1868
gboolean parse_vui_params)
1872
INITIALIZE_DEBUG_CATEGORY;
1873
GST_DEBUG ("parsing Subset SPS");
1875
nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1876
nalu->size - nalu->header_bytes);
1878
if (!gst_h264_parse_sps_data (&nr, sps, TRUE))
1881
if (sps->profile_idc == GST_H264_PROFILE_MULTIVIEW_HIGH ||
1882
sps->profile_idc == GST_H264_PROFILE_STEREO_HIGH) {
1883
if (!gst_h264_parse_sps_mvc_data (&nr, sps, parse_vui_params))
1888
return GST_H264_PARSER_OK;
1891
GST_WARNING ("error parsing \"Subset sequence parameter set\"");
1893
return GST_H264_PARSER_ERROR;
1605
1897
* gst_h264_parse_pps:
1606
1898
* @nalparser: a #GstH264NalParser
1607
1899
* @nalu: The #GST_H264_NAL_PPS #GstH264NalUnit to parse
1941
2269
* gst_h264_parser_parse_sei:
1942
2270
* @nalparser: a #GstH264NalParser
1943
2271
* @nalu: The #GST_H264_NAL_SEI #GstH264NalUnit to parse
1944
* @sei: The #GstH264SEIMessage to fill.
2272
* @messages: The GArray of #GstH264SEIMessage to fill. The caller must free it when done.
1946
* Parses @data, and fills the @sei structures.
2274
* Parses @data, create and fills the @messages array.
1948
2276
* Returns: a #GstH264ParserResult
1950
2278
GstH264ParserResult
1951
2279
gst_h264_parser_parse_sei (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
1952
GstH264SEIMessage * sei)
1956
guint32 payloadSize;
1957
guint8 payload_type_byte, payload_size_byte;
1958
guint remaining, payload_size;
2283
GstH264SEIMessage sei;
1959
2284
GstH264ParserResult res;
1961
GST_DEBUG ("parsing \"Sei message\"");
1963
nal_reader_init (&nr, nalu->data + nalu->offset + 1, nalu->size - 1);
1966
memset (sei, 0, sizeof (*sei));
1968
sei->payloadType = 0;
1970
READ_UINT8 (&nr, payload_type_byte, 8);
1971
sei->payloadType += payload_type_byte;
1972
} while (payload_type_byte == 0xff);
1976
READ_UINT8 (&nr, payload_size_byte, 8);
1977
payloadSize += payload_size_byte;
1979
while (payload_size_byte == 0xff);
1981
remaining = nal_reader_get_remaining (&nr) * 8;
1982
payload_size = payloadSize < remaining ? payloadSize : remaining;
1984
GST_DEBUG ("SEI message received: payloadType %u, payloadSize = %u bytes",
1985
sei->payloadType, payload_size);
1987
if (sei->payloadType == GST_H264_SEI_BUF_PERIOD) {
1988
/* size not set; might depend on emulation_prevention_three_byte */
1989
res = gst_h264_parser_parse_buffering_period (nalparser,
1990
&sei->payload.buffering_period, &nr);
1991
} else if (sei->payloadType == GST_H264_SEI_PIC_TIMING) {
1992
/* size not set; might depend on emulation_prevention_three_byte */
1993
res = gst_h264_parser_parse_pic_timing (nalparser,
1994
&sei->payload.pic_timing, &nr);
1996
res = GST_H264_PARSER_OK;
2286
GST_DEBUG ("parsing SEI nal");
2287
nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2288
nalu->size - nalu->header_bytes);
2289
*messages = g_array_new (FALSE, FALSE, sizeof (GstH264SEIMessage));
2292
res = gst_h264_parser_parse_sei_message (nalparser, &nr, &sei);
2293
if (res == GST_H264_PARSER_OK)
2294
g_array_append_val (*messages, sei);
2297
} while (nal_reader_has_more_data (&nr));
2001
GST_WARNING ("error parsing \"Sei message\"");
2002
return GST_H264_PARSER_ERROR;
2302
/* Free MVC-specific data from subset SPS header */
2304
gst_h264_sps_mvc_clear (GstH264SPS * sps)
2306
GstH264SPSExtMVC *const mvc = &sps->extension.mvc;
2309
g_assert (sps->extension_type == GST_H264_NAL_EXTENSION_MVC);
2314
for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) {
2315
GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_value[i];
2317
for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) {
2318
g_free (level_value->applicable_op[j].target_view_id);
2319
level_value->applicable_op[j].target_view_id = NULL;
2321
g_free (level_value->applicable_op);
2322
level_value->applicable_op = NULL;
2324
g_free (mvc->level_value);
2325
mvc->level_value = NULL;
2327
/* All meaningful MVC info are now gone, just pretend to be a
2328
* standard AVC struct now */
2329
sps->extension_type = GST_H264_NAL_EXTENSION_NONE;
2333
* gst_h264_sps_clear:
2334
* @sps: The #GstH264SPS to free
2336
* Clears all @sps internal resources.
2339
gst_h264_sps_clear (GstH264SPS * sps)
2341
g_return_if_fail (sps != NULL);
2343
switch (sps->extension_type) {
2344
case GST_H264_NAL_EXTENSION_MVC:
2345
gst_h264_sps_mvc_clear (sps);
2351
* gst_h264_quant_matrix_8x8_get_zigzag_from_raster:
2352
* @out_quant: (out): The resulting quantization matrix
2353
* @quant: The source quantization matrix
2355
* Converts quantization matrix @quant from raster scan order to
2356
* zigzag scan order and store the resulting factors into @out_quant.
2358
* Note: it is an error to pass the same table in both @quant and
2359
* @out_quant arguments.
2364
gst_h264_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
2365
const guint8 quant[64])
2369
g_return_if_fail (out_quant != quant);
2371
for (i = 0; i < 64; i++)
2372
out_quant[i] = quant[zigzag_8x8[i]];
2376
* gst_h264_quant_matrix_8x8_get_raster_from_zigzag:
2377
* @out_quant: (out): The resulting quantization matrix
2378
* @quant: The source quantization matrix
2380
* Converts quantization matrix @quant from zigzag scan order to
2381
* raster scan order and store the resulting factors into @out_quant.
2383
* Note: it is an error to pass the same table in both @quant and
2384
* @out_quant arguments.
2389
gst_h264_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
2390
const guint8 quant[64])
2394
g_return_if_fail (out_quant != quant);
2396
for (i = 0; i < 64; i++)
2397
out_quant[zigzag_8x8[i]] = quant[i];
2401
* gst_h264_quant_matrix_4x4_get_zigzag_from_raster:
2402
* @out_quant: (out): The resulting quantization matrix
2403
* @quant: The source quantization matrix
2405
* Converts quantization matrix @quant from raster scan order to
2406
* zigzag scan order and store the resulting factors into @out_quant.
2408
* Note: it is an error to pass the same table in both @quant and
2409
* @out_quant arguments.
2414
gst_h264_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
2415
const guint8 quant[16])
2419
g_return_if_fail (out_quant != quant);
2421
for (i = 0; i < 16; i++)
2422
out_quant[i] = quant[zigzag_4x4[i]];
2426
* gst_h264_quant_matrix_4x4_get_raster_from_zigzag:
2427
* @out_quant: (out): The resulting quantization matrix
2428
* @quant: The source quantization matrix
2430
* Converts quantization matrix @quant from zigzag scan order to
2431
* raster scan order and store the resulting factors into @out_quant.
2433
* Note: it is an error to pass the same table in both @quant and
2434
* @out_quant arguments.
2439
gst_h264_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
2440
const guint8 quant[16])
2444
g_return_if_fail (out_quant != quant);
2446
for (i = 0; i < 16; i++)
2447
out_quant[zigzag_4x4[i]] = quant[i];
2451
* gst_h264_video_calculate_framerate:
2452
* @sps: Current Sequence Parameter Set
2453
* @field_pic_flag: Current @field_pic_flag, obtained from latest slice header
2454
* @pic_struct: @pic_struct value if available, 0 otherwise
2455
* @fps_num: (out): The resulting fps numerator
2456
* @fps_den: (out): The resulting fps denominator
2458
* Calculate framerate of a video sequence using @sps VUI information,
2459
* @field_pic_flag from a slice header and @pic_struct from #GstH264PicTiming SEI
2462
* If framerate is variable or can't be determined, @fps_num will be set to 0
2463
* and @fps_den to 1.
2466
gst_h264_video_calculate_framerate (const GstH264SPS * sps,
2467
guint field_pic_flag, guint pic_struct, gint * fps_num, gint * fps_den)
2472
/* To calculate framerate, we use this formula:
2474
* fps = ----------------- x --------------- x ------------------------
2475
* num_units_in_tick DeltaTfiDivisor (field_pic_flag ? 2 : 1)
2477
* See H264 specification E2.1 for more details.
2481
if (sps->vui_parameters_present_flag) {
2482
const GstH264VUIParams *vui = &sps->vui_parameters;
2483
if (vui->timing_info_present_flag && vui->fixed_frame_rate_flag) {
2484
int delta_tfi_divisor = 1;
2485
num = vui->time_scale;
2486
den = vui->num_units_in_tick;
2488
if (vui->pic_struct_present_flag) {
2489
switch (pic_struct) {
2492
delta_tfi_divisor = 1;
2497
delta_tfi_divisor = 2;
2501
delta_tfi_divisor = 3;
2504
delta_tfi_divisor = 4;
2507
delta_tfi_divisor = 6;
2511
delta_tfi_divisor = field_pic_flag ? 1 : 2;
2513
den *= delta_tfi_divisor;
2515
/* Picture is two fields ? */
2516
den *= (field_pic_flag ? 2 : 1);