3 #include "AudioTools/AudioCodecs/AudioCodecsBase.h"
7 #include "AudioTools/AudioCodecs/AudioEncoded.h"
11 #ifndef MTS_PRINT_PIDS_LEN
12 # define MTS_PRINT_PIDS_LEN (16)
15 #ifndef MTS_UNDERFLOW_LIMIT
16 # define MTS_UNDERFLOW_LIMIT 188
19 #ifndef MTS_WRITE_BUFFER_SIZE
20 # define MTS_WRITE_BUFFER_SIZE 2000
23 #ifndef ALLOC_MEM_INIT
24 # define ALLOC_MEM_INIT 0
54 bool begin()
override {
64 memset(print_pids, 0,
sizeof(print_pids));
67 if (tsd_context_init(&ctx)!=TSD_OK){
74 ctx.malloc = log_malloc;
75 ctx.realloc = log_realloc;
76 ctx.calloc = log_calloc;
81 if (stream_types.empty()){
82 addStreamType(TSD_PMT_STREAM_TYPE_PES_METADATA);
83 addStreamType(TSD_PMT_STREAM_TYPE_AUDIO_AAC);
90 if (tsd_set_event_callback(&ctx, event_cb)!=TSD_OK){
103 tsd_context_destroy(&ctx);
108 virtual operator bool()
override {
return is_active; }
110 const char *mime() {
return "video/MP2T"; }
112 size_t write(
const uint8_t *data,
size_t len)
override {
113 if (!is_active)
return 0;
114 LOGD(
"MTSDecoder1::write: %d", (
int)len);
115 size_t result = buffer.
writeArray((uint8_t*)data, len);
117 demux(underflowLimit);
125 void clearStreamTypes(){
127 stream_types.clear();
130 void addStreamType(TSDPMTStreamType type){
132 stream_types.push_back(type);
135 bool isStreamTypeActive(TSDPMTStreamType type){
136 for (
int j=0;j<stream_types.size();j++){
137 if (stream_types[j]==type)
return true;
149 is_alloc_active = flag;
154 int underflowLimit = MTS_UNDERFLOW_LIMIT;
155 bool is_active =
false;
156 bool is_write_active =
false;
157 bool is_alloc_active =
false;
159 uint16_t print_pids[MTS_PRINT_PIDS_LEN] = {0};
160 SingleBuffer<uint8_t> buffer{MTS_WRITE_BUFFER_SIZE};
161 Vector<TSDPMTStreamType> stream_types;
162 Vector<AllocSize> alloc_vector;
164 void set_write_active(
bool flag){
166 is_write_active = flag;
171 bool payloadUnitStartIndicator = (data[1] & 0x40) >> 6;
172 bool result = data[0]==0x47 && payloadUnitStartIndicator;
176 void demux(
int limit){
178 TSDCode res = TSD_OK;
180 while (res == TSD_OK && buffer.
available() >= limit) {
183 LOGD(
"parsing new file");
187 res = tsd_demux(&ctx, (
void *)buffer.
data(), buffer.
available(), &len);
192 if (res != TSD_OK) logResult(res);
194 LOGD(
"Number of demux calls: %d", count);
197 void logResult(TSDCode code) {
202 case TSD_INVALID_SYNC_BYTE:
203 LOGW(
"TSD_INVALID_SYNC_BYTE");
205 case TSD_INVALID_CONTEXT:
206 LOGW(
"TSD_INVALID_CONTEXT");
208 case TSD_INVALID_DATA:
209 LOGW(
"TSD_INVALID_DATA");
211 case TSD_INVALID_DATA_SIZE:
212 LOGW(
"TSD_INVALID_DATA_SIZE");
214 case TSD_INVALID_ARGUMENT:
215 LOGW(
"TSD_INVALID_ARGUMENT");
217 case TSD_INVALID_START_CODE_PREFIX:
218 LOGW(
"TSD_INVALID_START_CODE_PREFIX");
220 case TSD_OUT_OF_MEMORY:
221 LOGW(
"TSD_OUT_OF_MEMORY");
223 case TSD_INCOMPLETE_TABLE:
224 LOGW(
"TSD_INCOMPLETE_TABLE");
226 case TSD_NOT_A_TABLE_PACKET:
227 LOGW(
"TSD_NOT_A_TABLE_PACKET");
229 case TSD_PARSE_ERROR:
230 LOGW(
"TSD_PARSE_ERROR");
232 case TSD_PID_ALREADY_REGISTERED:
233 LOGW(
"TSD_PID_ALREADY_REGISTERED");
235 case TSD_TSD_MAX_PID_REGS_REACHED:
236 LOGW(
"TSD_TSD_MAX_PID_REGS_REACHED");
238 case TSD_PID_NOT_FOUND:
239 LOGW(
"TSD_PID_NOT_FOUND");
241 case TSD_INVALID_POINTER_FIELD:
242 LOGW(
"TSD_INVALID_POINTER_FIELD");
248 static void event_cb(TSDemuxContext *ctx, uint16_t pid, TSDEventId event_id,
251 if (MTSDecoder1::self !=
nullptr) {
252 MTSDecoder1::self->event_cb_local(ctx, pid, event_id, data);
256 void event_cb_local(TSDemuxContext *ctx, uint16_t pid, TSDEventId event_id,
258 if (event_id == TSD_EVENT_PAT) {
259 set_write_active(
false);
260 print_pat(ctx, data);
261 }
else if (event_id == TSD_EVENT_PMT) {
262 set_write_active(
false);
263 print_pmt(ctx, data);
264 }
else if (event_id == TSD_EVENT_PES) {
265 TSDPESPacket *pes = (TSDPESPacket *)data;
267 LOGD(
"====================");
268 LOGD(
"PID %x PES Packet, Size: %zu, stream_id=%u, pts=%lu, dts=%lu", pid,
269 pes->data_bytes_length, pes->stream_id,(
unsigned long) pes->pts, (
unsigned long) pes->dts);
272 AudioLogger logger = AudioLogger::instance();
273 for (i = 0; i < MTS_PRINT_PIDS_LEN; ++i) {
274 if (print_pids[i] == pid) {
276 if (logger.isLogging(AudioLogger::Debug)) {
277 logger.print(
" PES data");
278 logger.print(is_write_active?
"active:":
"inactive:");
280 while (j < pes->data_bytes_length) {
281 char n = pes->data_bytes[j];
282 logger.printCharHex(n);
285 logger.printChar(
'\n');
288 if (p_print !=
nullptr) {
290 size_t eff = writeSamples<uint8_t>(p_print,(uint8_t*) pes->data_bytes, pes->data_bytes_length);
291 if(eff!=pes->data_bytes_length){
299 }
else if (event_id == TSD_EVENT_ADAP_FIELD_PRV_DATA) {
300 set_write_active(
false);
303 TSDAdaptationField *adap_field = (TSDAdaptationField *)data;
304 TSDDescriptor *descriptors = NULL;
305 size_t descriptors_length = 0;
306 tsd_descriptor_extract(ctx, adap_field->private_data_bytes,
307 adap_field->transport_private_data_length,
308 &descriptors, &descriptors_length);
310 LOGD(
"====================");
311 LOGD(
"Descriptors - Adaptation Fields");
313 for (; i < descriptors_length; ++i) {
314 TSDDescriptor *des = &descriptors[i];
315 LOGD(
" %d) tag: (0x%04X) %s", i, des->tag,
316 descriptor_tag_to_str(des->tag));
317 LOGD(
" length: %d", des->length);
318 print_descriptor_info(des);
323 void print_pat(TSDemuxContext *ctx,
void *data) {
324 LOGD(
"====================");
325 TSDPATData *pat = (TSDPATData *)data;
326 size_t len = pat->length;
328 LOGD(
"PAT, Length %d", (
int)pat->length);
331 LOGD(
"number of progs: %d", (
int)len);
333 for (i = 0; i < len; ++i) {
334 LOGD(
" %d) prog num: 0x%X, pid: 0x%X", (
int)i, pat->program_number[i],
339 void print_pmt(TSDemuxContext *ctx,
void *data) {
340 LOGD(
"====================");
342 TSDPMTData *pmt = (TSDPMTData *)data;
343 LOGD(
"PCR PID: 0x%04X", pmt->pcr_pid);
344 LOGD(
"program info length: %d", (
int)pmt->program_info_length);
345 LOGD(
"descriptors length: %d", (
int)pmt->descriptors_length);
348 for (i = 0; i < pmt->descriptors_length; ++i) {
349 TSDDescriptor *des = &pmt->descriptors[i];
350 LOGD(
" %d) tag: (0x%04X) %s", (
int)i, des->tag,
351 descriptor_tag_to_str(des->tag));
352 LOGD(
" length: %d", des->length);
353 print_descriptor_info(des);
356 LOGD(
"program elements length: %d", (
int)pmt->program_elements_length);
357 for (i = 0; i < pmt->program_elements_length; ++i) {
358 TSDProgramElement *prog = &pmt->program_elements[i];
359 LOGD(
" -----Program #%d", (
int)i);
360 LOGD(
" stream type: (0x%04X) %s", prog->stream_type,
361 stream_type_to_str((TSDPESStreamId)(prog->stream_type)));
362 LOGD(
" elementary pid: 0x%04X", prog->elementary_pid);
363 LOGD(
" es info length: %d", prog->es_info_length);
364 LOGD(
" descriptors length: %d", (
int)prog->descriptors_length);
366 if (isStreamTypeActive((TSDPMTStreamType)prog->stream_type)){
367 set_write_active(
true);
371 for(
int j=0;j<stream_types.size();j++){
372 add_print_pid(prog, stream_types[j]);
376 int reg_types = TSD_REG_PES;
379 for (j = 0; j < prog->descriptors_length; ++j) {
380 TSDDescriptor *des = &prog->descriptors[j];
381 LOGD(
" %d) tag: (0x%04X) %s", (
int)j, des->tag,
382 descriptor_tag_to_str(des->tag));
383 LOGD(
" length: %d", des->length);
384 print_descriptor_info(des);
388 if (des->tag == 0x97) {
389 reg_types |= TSD_REG_ADAPTATION_FIELD;
394 tsd_register_pid(ctx, prog->elementary_pid, reg_types);
398 void add_print_pid(TSDProgramElement *prog, TSDPMTStreamType type) {
399 if (prog->stream_type == type) {
401 for (k = 0; k < MTS_PRINT_PIDS_LEN; ++k) {
403 if (print_pids[k] == 0) {
404 print_pids[k] = prog->elementary_pid;
411 const char *stream_type_to_str(TSDPESStreamId stream_id) {
412 if (stream_id >= 0x1C && stream_id <= 0x7F && stream_id != 0x24 &&
414 stream_id = (TSDPESStreamId)0x1C;
415 }
else if (stream_id >= 0x8A && stream_id <= 0x8F) {
416 stream_id = (TSDPESStreamId)0x8A;
417 }
else if (stream_id >= 0x93 && stream_id <= 0x94) {
418 stream_id = (TSDPESStreamId)0x93;
419 }
else if (stream_id >= 0x96 && stream_id <= 0x9F) {
420 stream_id = (TSDPESStreamId)0x96;
421 }
else if (stream_id >= 0xA1 && stream_id <= 0xBF) {
422 stream_id = (TSDPESStreamId)0xA1;
423 }
else if (stream_id >= 0xC4 && stream_id <= 0xE9) {
424 stream_id = (TSDPESStreamId)0xC4;
425 }
else if (stream_id >= 0xEB && stream_id <= 0xFF) {
426 stream_id = (TSDPESStreamId)0xEB;
429 #pragma GCC diagnostic push
430 #pragma GCC diagnostic ignored "-Wswitch"
433 return "ITU-T | ISO/IEC Reserved";
435 return "ISO/IEC 11172 Video";
437 return "ITU-T Rec. H.262 | ISO/IEC 13818-2 Video";
439 return "ISO/IEC 11172 Audio";
441 return "ISO/IEC 13818-3 Audio";
443 return "ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private sections";
445 return "ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing "
448 return "ISO/IEC 13522 MHEG";
450 return "ITU-T Rec. H.222.0 | ISO/IEC 13818-1 DSM-CC";
452 return "ITU-T Rec. H.222.0 | ISO/IEC 13818-1/11172-1 auxiliary";
454 return "ISO/IEC 13818-6 Multi-protocol Encapsulation";
456 return "ISO/IEC 13818-6 DSM-CC U-N Messages";
458 return "ISO/IEC 13818-6 Stream Descriptors";
460 return "ISO/IEC 13818-6 Sections (any type, including private data)";
462 return "ISO/IEC 13818-1 auxiliary";
464 return "ISO/IEC 13818-7 Audio (AAC) with ADTS transport";
466 return "ISO/IEC 14496-2 Visual";
468 return "ISO/IEC 14496-3 Audio with the LATM transport syntax as "
469 "defined in ISO/IEC 14496-3";
471 return "ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried "
474 return "ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried "
475 "in ISO/IEC 14496_sections";
477 return "ISO/IEC 13818-6 DSM-CC Synchronized Download Protocol";
479 return "Metadata carried in PES packets";
481 return "Metadata carried in metadata_sections";
483 return "Metadata carried in ISO/IEC 13818-6 Data Carousel";
485 return "Metadata carried in ISO/IEC 13818-6 Object Carousel";
487 return "Metadata carried in ISO/IEC 13818-6 Synchronized Download "
490 return "IPMP stream (defined in ISO/IEC 13818-11, MPEG-2 IPMP)";
492 return "AVC video stream as defined in ITU-T Rec. H.264 | ISO/IEC "
495 return "ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved";
497 return "ITU-T Rec. H.265 and ISO/IEC 23008-2 (Ultra HD video) in a "
500 return "Chinese Video Standard in a packetized stream";
502 return "DigiCipher® II video | Identical to ITU-T Rec. H.262 | ISO/IEC "
505 return "ATSC A/53 audio [2] | AC-3 audio";
507 return "SCTE Standard Subtitle";
509 return "SCTE Isochronous Data | Reserved";
511 return "ATSC/SCTE reserved";
513 return "ATSC Program Identifier , SCTE Reserved";
515 return "SCTE 35 splice_information_table | [Cueing]";
519 return "DTS HD Audio";
521 return "ATSC Reserved";
523 return "ATSC Reserved";
525 return "DVB stream_type value for Time Slicing / MPE-FEC";
527 return "IETF Unidirectional Link Encapsulation (ULE)";
529 return "VEI stream_type";
531 return "ATSC Reserved";
533 return "ATSC Data Service Table, Network Resources Table";
535 return "ATSC Reserved";
537 return "SCTE [IP Data] | ATSC Reserved";
539 return "ATSC Reserved";
541 return "DCII (DigiCipher®) Text";
543 return "ATSC Reserved";
545 return "ATSC synchronous data stream | [Isochronous Data]";
547 return "SCTE Asynchronous Data";
549 return "ATSC User Private Program Elements";
551 return "VC-1 Elementary Stream per RP227";
553 return "ATSC User Private Program Elements";
557 #pragma GCC diagnostic pop
560 const char *descriptor_tag_to_str(uint8_t tag) {
561 if (tag >= 0x24 && tag <= 0x27) {
563 }
else if (tag >= 0x29 && tag <= 0x35) {
565 }
else if (tag >= 0x3A && tag <= 0x3F) {
567 }
else if (tag >= 0x40 && tag <= 0x51) {
569 }
else if (tag >= 0x98 && tag <= 0x9F) {
573 #pragma GCC diagnostic push
574 #pragma GCC diagnostic ignored "-Wswitch"
579 return "ISO/IEC 13818 Reserved";
581 return "video_stream_descriptor";
583 return "audio_stream_descriptor";
585 return "hierarchy_descriptor";
587 return "registration_descriptor";
589 return "data_stream_alignment_descriptor";
591 return "target_background_grid_descriptor";
593 return "video_window_descriptor";
595 return "CA_descriptor";
597 return "ISO_639_language_descriptor";
599 return "system_clock_descriptor";
601 return "multiplex_buffer_utilization_descriptor";
603 return "copyright_descriptor";
605 return "Maximum_bitrate_descriptor";
607 return "Private_data_indicator_descriptor";
609 return "smoothing_buffer_descriptor";
611 return "STD_descriptor";
613 return "IBP descriptor";
615 return "DSM-CC carousel_identifier_descriptor";
617 return "DSM-CC association_tag_descriptor";
619 return "DSM-CC deferred_association_tags_descriptor";
621 return "ISO/IEC 13818-6 reserved";
623 return "NPT Reference descriptor";
625 return "NPT Endpoint descriptor";
627 return "Stream Mode descriptor";
629 return "Stream Event descriptor";
631 return "MPEG-4_video_descriptor";
633 return "MPEG-4_audio_descriptor";
635 return "IOD_descriptor";
637 return "SL_descriptor";
639 return "FMC_descriptor";
641 return "External_ES_ID_descriptor";
643 return "MuxCode_descriptor";
645 return "FmxBufferSize_descriptor";
647 return "MultiplexBuffer_descriptor";
649 return "Reserved for ISO/IEC 13818-1 use";
651 return "AVC_video_descriptor()";
653 return "Reserved for ISO/IEC 13818-1 use";
655 return "content_labeling_descriptor";
657 return "Metadata_location_descriptor";
659 return "ISO/IEC 13818 Reserved";
661 return "User Private";
663 return "SCTE 35 Stream Identifier Descriptor";
665 return "ACAP-X Application Descriptor";
667 return "ACAP-X Application Location Descriptor";
669 return "ACAP-X Application Boundary Descriptor";
671 return "Stuffing_descriptor";
673 return "AC3_audio_descriptor";
675 return "SCTE Frame_rate_descriptor";
677 return "SCTE Extended_video_descriptor";
679 return "SCTE Component_name_descriptor";
681 return "ATSC program_identifier";
683 return "Caption_service_descriptor";
685 return "Content_advisory_descriptor";
687 return "ATSC CA_descriptor";
689 return "ATSC Descriptor_tag";
691 return "SCTE 35 cue identifier descriptor";
693 return "ATSC/SCTE Reserved";
695 return "TimeStampDescriptor";
697 return "parameterized_service_descriptor() ";
699 return "Interactive Services Filtering Criteria descriptor";
701 return "Interactive Services NRT Services Summary descriptor";
703 return "SCTE Frequency_spec_descriptor";
705 return "SCTE Modulation_params_descriptor";
707 return "SCTE Transport_stream_id_descriptor";
709 return "SCTE Revision detection descriptor";
711 return "SCTE Two part channel number descriptor";
713 return "SCTE Channel properties descriptor";
715 return "SCTE Daylight Savings Time Descriptor";
717 return "SCTE_adaptation_field_data_descriptor()";
719 return "SCTE Reserved";
721 return "extended_channel_name_descriptor";
723 return "ATSC service_location_descriptor";
725 return "time_shifted_service_descriptor";
727 return "component_name_descriptor";
729 return "ATSC data_service_descriptor";
731 return "ATSC PID Count descriptor";
733 return "ATSC Download descriptor";
735 return "ATSC Multiprotocol Encapsulation descriptor";
737 return "ATSC dcc_departing_request_descriptor";
739 return "ATSC dcc_arriving_request_descriptor";
741 return "ATSC rc_descriptor";
743 return "ATSC Genre descriptor";
745 return "SCTE MAC Address List";
747 return "ATSC private information descriptor";
749 return "ATSC compatibility wrapper descriptor";
751 return "ATSC broadcaster policy descriptor";
753 return "ATSC service name descriptor";
755 return "ATSC URI descriptor";
757 return "ATSC enhanced signaling descriptor";
759 return "ATSC M/H string mapping descriptor";
761 return "ATSC Module Link descriptor";
763 return "ATSC CRC32 descriptor";
765 return "ATSC Content Identifier Descriptor";
767 return "ModuleInfoDescriptor";
769 return "ATSC Group Link descriptor";
771 return "ATSC Time Stamp descriptor";
773 return "ScheduleDescriptor";
775 return "Component list descriptor";
777 return "ATSC M/H component descriptor";
779 return "ATSC M/H rights issuer descriptor";
781 return "ATSC M/H current program descriptor";
783 return "ATSC M/H original service identification descriptor";
785 return "protection_descriptor";
787 return "MH_SG_bootstrap_descriptor";
789 return "Service ID descriptor";
791 return "Protocol Version descriptor";
793 return "NRT Service descriptor";
795 return "Capabilities descriptor";
797 return "Icon descriptor";
799 return "Receiver Targeting descriptor";
801 return "Time Slot descriptor";
803 return "Internet Location Descriptor";
805 return "Associated Service descriptor";
807 return "Eye Identification Descriptor tag";
809 return "E-AC-3 descriptor (A/52 Annex G)";
811 return "2D 3D Corresponding Content Descriptor";
813 return "Multimedia EPG Linkage Descriptor";
815 return "etv_application_information_descriptor()";
817 return "etv_media_time_descriptor()";
819 return "etv_stream_event_descriptor()";
821 return "etv_application_descriptor()";
823 return "RBI_signaling_descriptor()";
825 return "etv_application_metadata_descriptor()";
827 return "etv_bif_platform_descriptor()";
829 return "etv_integrated_signaling_descriptor()";
831 return "3d_MPEG2_descriptor()";
833 return "ebp_descriptor()";
835 return "MPEG_AAC_descriptor";
837 return "IC3D_event_info_descriptor";
839 return "MDTV hybrid stereoscopic service descriptor";
841 #pragma GCC diagnostic pop
845 void print_descriptor_info(TSDDescriptor *desc) {
850 TSDDescriptorRegistration res;
851 if (TSD_OK == tsd_parse_descriptor_registration(
852 desc->data, desc->data_length, &res)) {
853 LOGD(
"\n format identififer: 0x%08X", res.format_identifier);
858 TSDDescriptorISO639Language res;
859 if (TSD_OK == tsd_parse_descriptor_iso639_language(
860 desc->data, desc->data_length, &res)) {
863 for (; i < res.language_length; ++i) {
864 LOGD(
" ISO Language Code: 0x%08X, audio type: 0x%02x",
865 res.iso_language_code[i], res.audio_type[i]);
872 TSDDescriptorMaxBitrate res;
873 if (TSD_OK == tsd_parse_descriptor_max_bitrate(
874 desc->data, desc->data_length, &res)) {
875 LOGD(
" Maximum Bitrate: %d x 50 bytes/second", res.max_bitrate);
879 LOGW(
" Unknown Descriptor: 0x%x ", desc->tag);
884 static void* log_malloc (
size_t size) {
885 void *result = malloc(size);
886 LOGI(
"malloc(%d) -> %p %s", (
int)size,result, result!=NULL?
"OK":
"ERROR");
890 static void* log_calloc(
size_t num,
size_t size){
891 void *result = calloc(num, size);
892 LOGI(
"calloc(%d) -> %p %s", (
int)(num*size),result, result!=NULL?
"OK":
"ERROR");
896 static void* log_realloc(
void *ptr,
size_t size){
897 void *result = realloc(ptr, size);
898 LOGI(
"realloc(%d) -> %p %s", (
int)size, result, result!=NULL?
"OK":
"ERROR");
902 static void log_free (
void *mem){
903 LOGD(
"free(%p)", mem);
966 MTSDecoder1 *MTSDecoder1::self =
nullptr;