720 lines
20 KiB
C
720 lines
20 KiB
C
|
// ITU-T H.222.0(06/2012)
|
||
|
// Information technology - Generic coding of moving pictures and associated audio information: Systems
|
||
|
// 2.6 Program and program element descriptors(p83)
|
||
|
|
||
|
#include "mpeg-element-descriptor.h"
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <assert.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
/*
|
||
|
2.6 Program and program element descriptors
|
||
|
2.6.1 Semantic definition of fields in program and program element descriptors
|
||
|
Table 2-45 - Program and program element descriptors
|
||
|
tag TS PS Identification
|
||
|
0 n/a n/a reserved
|
||
|
1 n/a X forbidden
|
||
|
2 X X video_stream_descriptor
|
||
|
3 X X audio_stream_descriptor
|
||
|
4 X X hierarchy_descriptor
|
||
|
5 X X registration_descriptor
|
||
|
6 X X data_stream_alignment_descriptor
|
||
|
7 X X target_background_grid_descriptor
|
||
|
8 X X video_window_descriptor
|
||
|
9 X X CA_descriptor
|
||
|
10 X X ISO_639_language_descriptor
|
||
|
11 X X system_clock_descriptor
|
||
|
12 X X multiplex_buffer_utilization_descriptor
|
||
|
13 X X copyright_descriptor
|
||
|
14 X maximum_bitrate_descriptor
|
||
|
15 X X private_data_indicator_descriptor
|
||
|
16 X X smoothing_buffer_descriptor
|
||
|
17 X STD_descriptor
|
||
|
18 X X IBP_descriptor
|
||
|
19-26 X Defined in ISO/IEC 13818-6
|
||
|
27 X X MPEG-4_video_descriptor
|
||
|
28 X X MPEG-4_audio_descriptor
|
||
|
29 X X IOD_descriptor
|
||
|
30 X SL_descriptor
|
||
|
31 X X FMC_descriptor
|
||
|
32 X X external_ES_ID_descriptor
|
||
|
33 X X MuxCode_descriptor
|
||
|
34 X X FmxBufferSize_descriptor
|
||
|
35 X multiplexbuffer_descriptor
|
||
|
36 X X content_labeling_descriptor
|
||
|
37 X X metadata_pointer_descriptor
|
||
|
38 X X metadata_descriptor
|
||
|
39 X X metadata_STD_descriptor
|
||
|
40 X X AVC video descriptor
|
||
|
41 X X IPMP_descriptor (defined in ISO/IEC 13818-11, MPEG-2 IPMP)
|
||
|
42 X X AVC timing and HRD descriptor
|
||
|
43 X X MPEG-2_AAC_audio_descriptor
|
||
|
44 X X FlexMuxTiming_descriptor
|
||
|
45 X X MPEG-4_text_descriptor
|
||
|
46 X X MPEG-4_audio_extension_descriptor
|
||
|
47 X X auxiliary_video_stream_descriptor
|
||
|
48 X X SVC extension descriptor
|
||
|
49 X X MVC extension descriptor
|
||
|
50 X n/a J2K video descriptor
|
||
|
51 X X MVC operation point descriptor
|
||
|
52 X X MPEG2_stereoscopic_video_format_descriptor
|
||
|
53 X X Stereoscopic_program_info_descriptor
|
||
|
54 X X Stereoscopic_video_info_descriptor
|
||
|
55 X n/a Transport_profile_descriptor
|
||
|
56 X n/a HEVC video descriptor
|
||
|
57-63 n/a n/a Rec. ITU-T H.222.0 | ISO/IEC 13818-1 Reserved
|
||
|
64-255 n/a n/a User Private
|
||
|
*/
|
||
|
int mpeg_elment_descriptor(struct mpeg_bits_t* reader)
|
||
|
{
|
||
|
size_t offset;
|
||
|
uint8_t tag = mpeg_bits_read8(reader);
|
||
|
uint8_t len = mpeg_bits_read8(reader);
|
||
|
if (mpeg_bits_error(reader))
|
||
|
return -1;
|
||
|
|
||
|
offset = mpeg_bits_tell(reader);
|
||
|
switch(tag)
|
||
|
{
|
||
|
case 2:
|
||
|
video_stream_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 3:
|
||
|
audio_stream_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 4:
|
||
|
hierarchy_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 5:
|
||
|
registration_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 10:
|
||
|
language_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 11:
|
||
|
system_clock_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 27:
|
||
|
mpeg4_video_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 28:
|
||
|
mpeg4_audio_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 37:
|
||
|
metadata_pointer_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 38:
|
||
|
metadata_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 40:
|
||
|
avc_video_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 42:
|
||
|
avc_timing_hrd_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 43:
|
||
|
mpeg2_aac_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 48:
|
||
|
svc_extension_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 49:
|
||
|
mvc_extension_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 56:
|
||
|
hevc_video_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 57:
|
||
|
vvc_video_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 58:
|
||
|
evc_video_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
case 0x40:
|
||
|
clock_extension_descriptor(reader, len);
|
||
|
break;
|
||
|
|
||
|
//default:
|
||
|
// assert(0);
|
||
|
}
|
||
|
|
||
|
mpeg_bits_seek(reader, offset + len); // read all
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int video_stream_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.2 Video stream descriptor(p85)
|
||
|
|
||
|
uint8_t v;
|
||
|
video_stream_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 1);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.multiple_frame_rate_flag = (v >> 7) & 0x01;
|
||
|
desc.frame_rate_code = (v >> 3) & 0x0F;
|
||
|
desc.MPEG_1_only_flag = (v >> 2) & 0x01;
|
||
|
desc.constrained_parameter_flag = (v >> 1) & 0x01;
|
||
|
desc.still_picture_flag = v & 0x01;
|
||
|
|
||
|
if(0 == desc.MPEG_1_only_flag)
|
||
|
{
|
||
|
desc.profile_and_level_indication = mpeg_bits_read8(reader);
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.chroma_format = (v >> 6) & 0x03;
|
||
|
desc.frame_rate_code = (v >> 5) & 0x01;
|
||
|
assert((0x1F & v) == 0x00); // 'xxx00000'
|
||
|
}
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int audio_stream_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.4 Audio stream descriptor(p86)
|
||
|
|
||
|
uint8_t v;
|
||
|
audio_stream_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 1);
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.free_format_flag = (v >> 7) & 0x01;
|
||
|
desc.ID = (v >> 6) & 0x01;
|
||
|
desc.layer = (v >> 4) & 0x03;
|
||
|
desc.variable_rate_audio_indicator = (v >> 3) & 0x01;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int hierarchy_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.6 Hierarchy descriptor(p86)
|
||
|
|
||
|
uint8_t v;
|
||
|
hierarchy_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 4);
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.no_view_scalability_flag = (v >> 7) & 0x01;
|
||
|
desc.no_temporal_scalability_flag = (v >> 6) & 0x01;
|
||
|
desc.no_spatial_scalability_flag = (v >> 5) & 0x01;
|
||
|
desc.no_quality_scalability_flag = (v >> 4) & 0x01;
|
||
|
desc.hierarchy_type = v & 0x0F;
|
||
|
desc.hierarchy_layer_index = mpeg_bits_read8(reader) & 0x3F;
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.tref_present_flag = (v >> 7) & 0x01;
|
||
|
desc.hierarchy_embedded_layer_index = v & 0x3F;
|
||
|
desc.hierarchy_channel = mpeg_bits_read8(reader) & 0x3F;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int registration_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.8 Registration descriptor(p94)
|
||
|
size_t fourcc;
|
||
|
|
||
|
(void)len; assert(len >= 4);
|
||
|
fourcc = mpeg_bits_read32(reader);
|
||
|
(void)fourcc;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int language_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.18 ISO 639 language descriptor(p92)
|
||
|
uint8_t i;
|
||
|
uint32_t v;
|
||
|
|
||
|
for (i = 0; i + 4 < len; i += 4)
|
||
|
{
|
||
|
language_descriptor_t desc;
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
|
||
|
v = mpeg_bits_read32(reader);
|
||
|
desc.code = v >> 8;
|
||
|
desc.audio = v & 0xFF;
|
||
|
}
|
||
|
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int system_clock_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.20 System clock descriptor(p92)
|
||
|
|
||
|
uint8_t v;
|
||
|
system_clock_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 2);
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.external_clock_reference_indicator = (v >> 7) & 0x01;
|
||
|
desc.clock_accuracy_integer = v & 0x3F;
|
||
|
desc.clock_accuracy_exponent = (mpeg_bits_read8(reader) >> 5) & 0x07;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int mpeg4_video_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.36 MPEG-4 video descriptor(p96)
|
||
|
|
||
|
mpeg4_video_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 1);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.visual_profile_and_level = mpeg_bits_read8(reader);
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int mpeg4_audio_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.38 MPEG-4 audio descriptor(p97)
|
||
|
|
||
|
mpeg4_audio_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 1);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.profile_and_level = mpeg_bits_read8(reader);
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int metadata_pointer_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.58 Metadata pointer descriptor(p112)
|
||
|
|
||
|
uint8_t flags;
|
||
|
metadata_pointer_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 5);
|
||
|
desc.metadata_application_format_identifier = mpeg_bits_read16(reader);
|
||
|
if (0xFFFF == desc.metadata_application_format_identifier)
|
||
|
desc.metadata_application_format_identifier = mpeg_bits_read32(reader);
|
||
|
|
||
|
desc.metadata_format_identifier = mpeg_bits_read8(reader);
|
||
|
if (0xFF == desc.metadata_format_identifier)
|
||
|
desc.metadata_format_identifier = mpeg_bits_read32(reader);
|
||
|
|
||
|
desc.metadata_service_id = mpeg_bits_read8(reader);
|
||
|
flags = mpeg_bits_read8(reader);
|
||
|
desc.MPEG_carriage_flags = (flags >> 5) & 0x03;
|
||
|
|
||
|
if (flags & 0x80) // metadata_locator_record_flag
|
||
|
{
|
||
|
desc.metadata_locator_record_length = mpeg_bits_read8(reader);
|
||
|
mpeg_bits_skip(reader, desc.metadata_locator_record_length); // metadata_locator_record_byte
|
||
|
}
|
||
|
|
||
|
if (desc.MPEG_carriage_flags <= 2)
|
||
|
desc.program_number = mpeg_bits_read16(reader);
|
||
|
|
||
|
if (1 == desc.MPEG_carriage_flags)
|
||
|
{
|
||
|
desc.transport_stream_location = mpeg_bits_read16(reader);
|
||
|
desc.transport_stream_id = mpeg_bits_read16(reader);
|
||
|
}
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int metadata_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.60 Metadata descriptor(p115)
|
||
|
|
||
|
uint8_t flags;
|
||
|
metadata_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 5);
|
||
|
desc.metadata_application_format_identifier = mpeg_bits_read16(reader);
|
||
|
if (0xFFFF == desc.metadata_application_format_identifier)
|
||
|
desc.metadata_application_format_identifier = mpeg_bits_read32(reader);
|
||
|
|
||
|
desc.metadata_format_identifier = mpeg_bits_read8(reader);
|
||
|
if (0xFF == desc.metadata_format_identifier)
|
||
|
desc.metadata_format_identifier = mpeg_bits_read32(reader);
|
||
|
|
||
|
desc.metadata_service_id = mpeg_bits_read8(reader);
|
||
|
flags = mpeg_bits_read8(reader);
|
||
|
desc.decoder_config_flags = (flags >> 5) & 0x07;
|
||
|
if (flags & 0x10) // DSM-CC_flag
|
||
|
{
|
||
|
desc.service_identification_length = mpeg_bits_read8(reader);
|
||
|
mpeg_bits_skip(reader, desc.service_identification_length); // service_identification_record_byte
|
||
|
}
|
||
|
|
||
|
if (0x01 == desc.decoder_config_flags)
|
||
|
{
|
||
|
desc.decoder_config_length = mpeg_bits_read8(reader);
|
||
|
mpeg_bits_skip(reader, desc.decoder_config_length); // decoder_config_byte
|
||
|
}
|
||
|
else if (0x03 == desc.decoder_config_flags)
|
||
|
{
|
||
|
desc.dec_config_identification_record_length = mpeg_bits_read8(reader);
|
||
|
mpeg_bits_skip(reader, desc.dec_config_identification_record_length); // dec_config_identification_record_byte
|
||
|
}
|
||
|
else if (0x04 == desc.decoder_config_flags)
|
||
|
{
|
||
|
desc.decoder_config_metadata_service_id = mpeg_bits_read8(reader);
|
||
|
}
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int avc_video_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.64 AVC video descriptor(p110)
|
||
|
|
||
|
uint8_t v;
|
||
|
avc_video_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 4);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.profile_idc = mpeg_bits_read8(reader);
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.constraint_set0_flag = (v >> 7) & 0x01;
|
||
|
desc.constraint_set1_flag = (v >> 6) & 0x01;
|
||
|
desc.constraint_set2_flag = (v >> 5) & 0x01;
|
||
|
desc.constraint_set3_flag = (v >> 4) & 0x01;
|
||
|
desc.constraint_set4_flag = (v >> 3) & 0x01;
|
||
|
desc.constraint_set5_flag = (v >> 2) & 0x01;
|
||
|
desc.AVC_compatible_flags = v & 0x03;
|
||
|
desc.level_idc = mpeg_bits_read8(reader);
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.AVC_still_present = (v >> 7) & 0x01;
|
||
|
desc.AVC_24_hour_picture_flag = (v >> 6) & 0x01;
|
||
|
desc.frame_packing_SEI_not_present_flag = (v >> 5) & 0x01;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int avc_timing_hrd_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.66 AVC timing and HRD descriptor(p112)
|
||
|
|
||
|
uint8_t v;
|
||
|
avc_timing_hrd_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 2);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.hrd_management_valid_flag = (v >> 7) & 0x01;
|
||
|
desc.picture_and_timing_info_present = (v >> 0) & 0x01;
|
||
|
if(desc.picture_and_timing_info_present)
|
||
|
{
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc._90kHZ_flag = (v >> 7) & 0x01;
|
||
|
if(0 == desc._90kHZ_flag)
|
||
|
{
|
||
|
desc.N = mpeg_bits_read32(reader);
|
||
|
desc.K = mpeg_bits_read32(reader);
|
||
|
}
|
||
|
desc.num_unit_in_tick = mpeg_bits_read32(reader);
|
||
|
}
|
||
|
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.fixed_frame_rate_flag = (v >> 7) & 0x01;
|
||
|
desc.temporal_poc_flag = (v >> 6) & 0x01;
|
||
|
desc.picture_to_display_conversion_flag = (v >> 5) & 0x01;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int mpeg2_aac_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.68 MPEG-2 AAC audio descriptor(p113)
|
||
|
|
||
|
mpeg2_aac_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 3);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.profile = mpeg_bits_read8(reader);
|
||
|
desc.channel_configuration = mpeg_bits_read8(reader);
|
||
|
desc.additional_information = mpeg_bits_read8(reader);
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int svc_extension_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.76 SVC extension descriptor(p116)
|
||
|
|
||
|
uint8_t v;
|
||
|
svc_extension_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 13);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.width = mpeg_bits_read16(reader);
|
||
|
desc.height = mpeg_bits_read16(reader);
|
||
|
desc.frame_rate = mpeg_bits_read16(reader);
|
||
|
desc.average_bitrate = mpeg_bits_read16(reader);
|
||
|
desc.maximum_bitrate = mpeg_bits_read16(reader);
|
||
|
desc.dependency_id = (mpeg_bits_read8(reader) >> 5) & 0x07;
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.quality_id_start = (v >> 4) & 0x0F;
|
||
|
desc.quality_id_end = (v >> 0) & 0x0F;
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.temporal_id_start = (v >> 5) & 0x07;
|
||
|
desc.temporal_id_end = (v >> 2) & 0x07;
|
||
|
desc.no_sei_nal_unit_present = (v >> 1) & 0x01;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int mvc_extension_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.78 MVC extension descriptor(p117)
|
||
|
|
||
|
uint32_t v;
|
||
|
mvc_extension_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 8);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.average_bit_rate = mpeg_bits_read16(reader);
|
||
|
desc.maximum_bitrate = mpeg_bits_read16(reader);
|
||
|
v = mpeg_bits_read32(reader);
|
||
|
desc.view_order_index_min = (v >> 18) & 0x3FF;
|
||
|
desc.view_order_index_max = (v >> 8) & 0x3FF;
|
||
|
desc.temporal_id_start = (v >> 5) & 0x07;
|
||
|
desc.temporal_id_end = (v >> 2) & 0x07;
|
||
|
desc.no_sei_nal_unit_present = (v >> 1) & 0x01;
|
||
|
desc.no_prefix_nal_unit_present = (v >> 0) & 0x01;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int hevc_video_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.95 HEVC video descriptor(p146)
|
||
|
|
||
|
uint64_t v;
|
||
|
hevc_video_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 13);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.profile_space = (v >> 6) & 0x03;
|
||
|
desc.tier_flag = (v >> 5) & 0x01;
|
||
|
desc.profile_idc = (v >> 0) & 0x1F;
|
||
|
desc.profile_compatibility_indication = mpeg_bits_read32(reader);
|
||
|
v = mpeg_bits_read64(reader);
|
||
|
desc.progressive_source_flag = (v >> 63) & 0x01;
|
||
|
desc.interlaced_source_flag = (v >> 62) & 0x01;
|
||
|
desc.non_packed_constraint_flag = (v >> 61) & 0x01;
|
||
|
desc.frame_only_constraint_flag = (v >> 60) & 0x01;
|
||
|
desc.copied_44bits = (v >> 16) & 0xFFFFFFFFFFFULL;
|
||
|
desc.level_idc = (v >> 8) & 0xFF;
|
||
|
desc.temporal_layer_subset_flag = (v >> 7) & 0x01;
|
||
|
desc.HEVC_still_present_flag = (v >> 6) & 0x01;
|
||
|
desc.HEVC_24hr_picture_present_flag = (v >> 5) & 0x01;
|
||
|
desc.sub_pic_hrd_params_not_present_flag = (v >> 4) & 0x01;
|
||
|
desc.HDR_WCG_idc = v & 0x03;
|
||
|
if (desc.temporal_layer_subset_flag) {
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.temporal_id_min = (v >> 5) & 0x07;
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.temporal_id_max = (v >> 5) & 0x07;
|
||
|
}
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int vvc_video_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.129 VVC video descriptor(p172)
|
||
|
|
||
|
int i;
|
||
|
uint8_t v;
|
||
|
vvc_video_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 6);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.profile_idc = (v >> 1) & 0x7F;
|
||
|
desc.tier_flag = v & 0x01;
|
||
|
desc.num_sub_profiles = mpeg_bits_read8(reader);
|
||
|
for(i = 0; i < desc.num_sub_profiles && i < sizeof(desc.sub_profile_idc)/sizeof(desc.sub_profile_idc[0]); i++)
|
||
|
desc.sub_profile_idc[i] = mpeg_bits_read32(reader);
|
||
|
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.progressive_source_flag = (v >> 7) & 0x01;
|
||
|
desc.interlaced_source_flag = (v >> 6) & 0x01;
|
||
|
desc.non_packed_constraint_flag = (v >> 5) & 0x01;
|
||
|
desc.frame_only_constraint_flag = (v >> 4) & 0x01;
|
||
|
desc.reserved_zero_4bits = (v >> 0) & 0x0F;
|
||
|
desc.level_idc = mpeg_bits_read8(reader);
|
||
|
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.temporal_layer_subset_flag = (v >> 7) & 0x01;
|
||
|
desc.VVC_still_present_flag = (v >> 6) & 0x01;
|
||
|
desc.VVC_24hr_picture_present_flag = (v >> 5) & 0x01;
|
||
|
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.HDR_WCG_idc = (v >> 6) & 0x03;
|
||
|
desc.video_properties_tag = v & 0x0F;
|
||
|
|
||
|
if (desc.temporal_layer_subset_flag) {
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.temporal_id_min = v & 0x07;
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.temporal_id_max = v & 0x07;
|
||
|
}
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
int evc_video_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
// 2.6.133 EVC video descriptor(p176)
|
||
|
|
||
|
uint8_t v;
|
||
|
evc_video_descriptor_t desc;
|
||
|
|
||
|
(void)len; assert(len >= 6);
|
||
|
memset(&desc, 0, sizeof(desc));
|
||
|
desc.profile_idc = mpeg_bits_read8(reader);
|
||
|
desc.level_idc = mpeg_bits_read8(reader);
|
||
|
desc.toolset_idc_h = mpeg_bits_read32(reader);
|
||
|
desc.toolset_idc_l = mpeg_bits_read32(reader);
|
||
|
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.progressive_source_flag = (v >> 7) & 0x01;
|
||
|
desc.interlaced_source_flag = (v >> 6) & 0x01;
|
||
|
desc.non_packed_constraint_flag = (v >> 5) & 0x01;
|
||
|
desc.frame_only_constraint_flag = (v >> 4) & 0x01;
|
||
|
desc.reserved = (v >> 3) & 0x01;
|
||
|
desc.temporal_layer_subset_flag = (v >> 2) & 0x01;
|
||
|
desc.EVC_still_present_flag = (v >> 1) & 0x01;
|
||
|
desc.EVC_24hr_picture_present_flag = (v >> 0) & 0x01;
|
||
|
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.HDR_WCG_idc = (v >> 6) & 0x03;
|
||
|
desc.video_properties_tag = v & 0x0F;
|
||
|
|
||
|
if (desc.temporal_layer_subset_flag) {
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.temporal_id_min = v & 0x07;
|
||
|
v = mpeg_bits_read8(reader);
|
||
|
desc.temporal_id_max = v & 0x07;
|
||
|
}
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
size_t service_extension_descriptor_write(uint8_t* data, size_t bytes)
|
||
|
{
|
||
|
uint8_t n;
|
||
|
n = (uint8_t)strlen(SERVICE_NAME);
|
||
|
if (bytes < 2 + n)
|
||
|
return 0;
|
||
|
data[0] = SERVICE_ID;
|
||
|
data[1] = n;
|
||
|
memcpy(data + 2, SERVICE_NAME, n);
|
||
|
return 2 + n;
|
||
|
}
|
||
|
|
||
|
typedef struct _clock_extension_descriptor_t
|
||
|
{
|
||
|
uint8_t year; // base 2000, 8-bit
|
||
|
uint8_t month; // 1-12, 4-bit
|
||
|
uint8_t day; // 1-31, 5-bit
|
||
|
uint8_t hour; // 0-23, 5-bit
|
||
|
uint8_t minute; // 0-59, 6-bit
|
||
|
uint8_t second; // 0-59, 6-bit
|
||
|
uint16_t microsecond; // 14-bit
|
||
|
} clock_extension_descriptor_t;
|
||
|
|
||
|
int clock_extension_descriptor(struct mpeg_bits_t* reader, uint8_t len)
|
||
|
{
|
||
|
uint32_t v;
|
||
|
struct tm t;
|
||
|
time_t clock;
|
||
|
|
||
|
(void)len; assert(len >= 9);
|
||
|
v = mpeg_bits_read32(reader); // skip 4-bytes leading
|
||
|
memset(&t, 0, sizeof(t));
|
||
|
t.tm_year = mpeg_bits_read8(reader) + 2000 - 1900;
|
||
|
v = mpeg_bits_read32(reader);
|
||
|
t.tm_mon = ((v >> 28) & 0x0F) - 1;
|
||
|
t.tm_mday = (v >> 23) & 0x1F;
|
||
|
t.tm_hour = (v >> 18) & 0x1F;
|
||
|
t.tm_min = (v >> 12) & 0x3F;
|
||
|
t.tm_sec = (v >> 6) & 0x3F;
|
||
|
//desc.microsecond = v & 0x3F;
|
||
|
clock = mktime(&t) * 1000;
|
||
|
|
||
|
assert(0 == mpeg_bits_error(reader));
|
||
|
return mpeg_bits_error(reader) ? -1 : 0;
|
||
|
}
|
||
|
|
||
|
size_t clock_extension_descriptor_write(uint8_t* data, size_t bytes, int64_t clock)
|
||
|
{
|
||
|
struct tm* t;
|
||
|
time_t seconds;
|
||
|
if (bytes < 16)
|
||
|
return 0;
|
||
|
|
||
|
seconds = (time_t)(clock / 1000);
|
||
|
t = localtime(&seconds);
|
||
|
|
||
|
data[0] = 0x40;
|
||
|
data[1] = 0x0E;
|
||
|
data[2] = 0x48;
|
||
|
data[3] = 0x4B;
|
||
|
data[4] = 0x01;
|
||
|
data[5] = 0x00;
|
||
|
data[6] = (uint8_t)(t->tm_year + 1900 - 2000); // base 2000
|
||
|
data[7] = (uint8_t)((t->tm_mon + 1) << 4) | ((t->tm_mday >> 1) & 0x0F);
|
||
|
data[8] = (uint8_t)((t->tm_mday & 0x01) << 7) | ((t->tm_hour & 0x1F) << 2) | ((t->tm_min >> 4) & 0x03);
|
||
|
data[9] = (uint8_t)((t->tm_min & 0x0F) << 4) | ((t->tm_sec >> 2) & 0x0F);
|
||
|
data[10] = (uint8_t)((t->tm_sec & 0x03) << 6);
|
||
|
data[11] = 0x00;
|
||
|
data[12] = 0x00;
|
||
|
data[13] = 0xFF;
|
||
|
data[14] = 0xFF;
|
||
|
data[15] = 0xFF;
|
||
|
return 16;
|
||
|
}
|