Example #1
0
void ts_descriptor_dump(uint8_t *desc_data, int desc_data_len) {
	char *pad  = "        * ";
	uint8_t *data = desc_data;
	int data_len = desc_data_len;
	while (data_len >= 2) {
		int i;
		uint8_t tag         = data[0];
		uint8_t this_length = data[1];

//		ts_LOGf("%sDescriptor tag: 0x%02x (%d) size: %d\n", padA, tag, tag, this_length);

		data     += 2;
		data_len -= 2;

		if (this_length > data_len) {
			// Not much we can do - try giving up?
			ts_LOGf("%s!!! Descriptor 0x%02x says length %d, but only %d bytes left\n", pad, tag, this_length, data_len);
			return;
		}

		switch (tag) {
			case  2: { // Video stream descriptor
				char *dump = ts_hex_dump(data, this_length, 0);
				ts_LOGf("%sTag 0x%02x (%02d), sz: %d, Video stream descriptor: %s\n", pad, tag, tag, this_length, dump);
				free(dump);
				struct {
					uint8_t multiple_frame_rate_flag     : 1,
					        frame_rate_code              : 4,
					        mpeg1_only_flag              : 1,
					        constraint_parameter_flag    : 1,
					        still_picture_flag           : 1;
					uint8_t profile_and_level_indication;
					uint8_t chroma_format                : 2,
					        frame_rate_extension_flag    : 1,
					        reserved                     : 5;
					uint8_t escape:1, profile:3, level:4;
				} vs;
				if (this_length >= 1) {
					vs.multiple_frame_rate_flag     = bit_on(data[0], bit_8);
					vs.frame_rate_code              = (data[0] &~ 0x80) >> 3; // 1xxxx111
					vs.mpeg1_only_flag              = bit_on(data[0], bit_3);
					vs.constraint_parameter_flag    = bit_on(data[0], bit_2);
					vs.still_picture_flag           = bit_on(data[0], bit_1);
					ts_LOGf("%s  - multiple_frame_rate_flag     : %d\n", pad, vs.multiple_frame_rate_flag);
					ts_LOGf("%s  - frame_rate_code              : %d (%s)\n", pad, vs.frame_rate_code,
						vs.frame_rate_code == 0 ? "forbidden" :
						vs.frame_rate_code == 1 ? "23.976" :
						vs.frame_rate_code == 2 ? "24.00" :
						vs.frame_rate_code == 3 ? "25.00" :
						vs.frame_rate_code == 4 ? "29.97" :
						vs.frame_rate_code == 5 ? "30.00" :
						vs.frame_rate_code == 6 ? "50.00" :
						vs.frame_rate_code == 7 ? "59.94" :
						vs.frame_rate_code == 8 ? "60.00" : "reserved"
					);
					ts_LOGf("%s  - mpeg1_only_flag              : %d\n", pad, vs.mpeg1_only_flag);
					ts_LOGf("%s  - constraint_parameter_flag    : %d\n", pad, vs.constraint_parameter_flag);
					ts_LOGf("%s  - still_picture_flag           : %d\n", pad, vs.still_picture_flag);
				}
				if (this_length >= 2 && vs.mpeg1_only_flag == 0) {
					vs.profile_and_level_indication = data[1];
					vs.chroma_format                = data[2] >> 6;				// xx111111
					vs.frame_rate_extension_flag    = bit_on(data[2], bit_6);	// 11x11111
					vs.reserved                     = data[2] &~ 0xE0;			// 111xxxxx
					vs.profile                      = (vs.profile_and_level_indication &~ 0x8f) >> 4;	// x111xxxx
					vs.level                        =  vs.profile_and_level_indication &~ 0xf0;			// xxxx1111
					ts_LOGf("%s  - profile_and_level_indication : 0x%02x, Profile: %d (%s), Level: %d (%s)\n", pad,
						vs.profile_and_level_indication,

						vs.profile,
						vs.profile == 1 ? "High"               :
						vs.profile == 2 ? "Spatially Scalable" :
						vs.profile == 3 ? "SNR Scalable"       :
						vs.profile == 4 ? "Main"               :
						vs.profile == 5 ? "Simple"             : "Reserved",

						vs.level,
						vs.level == 4  ? "High"      :
						vs.level == 6  ? "High 1440" :
						vs.level == 8  ? "Main"      :
						vs.level == 10 ? "Low"       : "Reserved"
					);
					ts_LOGf("%s  - chroma_format                : %d (%s)\n", pad, vs.chroma_format,
						vs.chroma_format == 0 ? "reserved" :
						vs.chroma_format == 1 ? "4:2:0" :
						vs.chroma_format == 2 ? "4:2:2" :
						vs.chroma_format == 3 ? "4:4:4" : "unknown"
					);
					ts_LOGf("%s  - frame_rate_extension_flag    : %d\n", pad, vs.frame_rate_extension_flag);
					ts_LOGf("%s  - reserved                     : 0x%x\n", pad, vs.reserved);
				}
				break;
			}
			case  3: { // Audio stream descriptor
				char *dump = ts_hex_dump(data, this_length, 0);
				ts_LOGf("%sTag 0x%02x (%02d), sz: %d, Audio stream descriptor: %s\n", pad, tag, tag, this_length, dump);
				free(dump);
				struct {
					uint8_t free_format_flag : 1,
					        ID               : 1,
					        layer            : 2,
					        vbr_flag         : 1,
					        reserved         : 3;
				} as;
				if (this_length >= 1) {
					as.free_format_flag = bit_on(data[0], bit_8);
					as.ID               = bit_on(data[0], bit_7);
					as.layer            = (data[0] &~ 0xcf) >> 4;	// 11xx1111
					as.vbr_flag         = bit_on(data[0], bit_4);
					as.reserved         = data[0] &~ 0xf0;			// 1111xxxx
					ts_LOGf("%s  - free_format_flag : %d\n", pad, as.free_format_flag);
					ts_LOGf("%s  - ID               : %d (%s)\n", pad, as.ID, as.ID ? "MPEG Audio" : "Other");
					ts_LOGf("%s  - layer            : %d (%s)\n", pad, as.layer,
						as.layer == 0 ? "reserved" :
						as.layer == 1 ? "Layer III" :
						as.layer == 2 ? "Layer II" :
						as.layer == 3 ? "Layer I" : "reserved"
					);
					ts_LOGf("%s  - vbr_audio_flag   : %d\n", pad, as.vbr_flag);
					ts_LOGf("%s  - reserved         : 0x%x\n", pad, as.reserved);
				}
				break;
			}
void ts_print_bytes(char *prefix, uint8_t *d, int size) {
	char *buf = ts_hex_dump(d, size, 0);
	ts_LOGf("%s -> %s\n", prefix, buf);
	free(buf);
}