12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273 |
- /*
- The MIT License (MIT)
- Copyright (c) 2013-2015 SRS(ossrs)
- Permission is hereby granted, free of charge, to any person obtaining a copy of
- this software and associated documentation files (the "Software"), to deal in
- the Software without restriction, including without limitation the rights to
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- the Software, and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- /**
- g++ -o ts_info ts_info.cc -g -O0 -ansi
- */
- #if 1
- // for int64_t print using PRId64 format.
- #ifndef __STDC_FORMAT_MACROS
- #define __STDC_FORMAT_MACROS
- #endif
- #include <inttypes.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <vector>
- #include <map>
- #define trace(msg, ...) printf(msg"\n", ##__VA_ARGS__);
- #define srs_freep(p) delete p; p = NULL
- #define srs_assert(p) assert(p)
- #define srs_min(a, b) ((a)<(b)? (a):(b))
- #endif
- /**
- ISO/IEC 13818-1:2000(E)
- Introduction
- Intro. 1 Transport Stream
- Intro. 2 Program Stream
- Intro. 4 Packetized Elementary Stream
- SECTION 2 – TECHNICAL ELEMENTS
- 2.4 Transport Stream bitstream requirements
- 2.4.1 Transport Stream coding structure and parameters
- 2.4.2 Transport Stream system target decoder
- 2.4.3 Specification of the Transport Stream syntax and semantics
- 2.4.3.1 Transport Stream
- 2.4.3.2 Transport Stream packet layer
- 2.4.3.3 Semantic definition of fields in Transport Stream packet layer
- 2.4.3.5 Semantic definition of fields in adaptation field
- 2.4.3.6 PES packet
- 2.4.3.7 Semantic definition of fields in PES packet
- 2.4.4 Program specific information
- 2.4.4.5 Semantic definition of fields in program association section
- 2.4.4.6 Conditional access Table
- 2.5 Program Stream bitstream requirements
- 2.6 Program and program element descriptors
- 2.7 Restrictions on the multiplexed stream semantics
- Annex A CRC Decoder Model
- */
- #if 1
- // Transport Stream packets are 188 bytes in length.
- #define TS_PACKET_SIZE 188
- enum TSPidTable
- {
- // Program Association Table(see Table 2-25).
- TSPidTablePAT = 0x00,
- // Conditional Access Table (see Table 2-27).
- TSPidTableCAT = 0x01,
- // Transport Stream Description Table
- TSPidTableTSDT = 0x02,
- // null packets (see Table 2-3)
- TSPidTableNULL = 0x01FFF,
- };
- /*adaptation_field_control*/
- /**
- * Table 2-5 – Adaptation field control values, page 38.
- */
- enum TSAdaptionType
- {
- // Reserved for future use by ISO/IEC
- TSAdaptionTypeReserved = 0x00,
- // No adaptation_field, payload only
- TSAdaptionTypePayloadOnly = 0x01,
- // Adaptation_field only, no payload
- TSAdaptionTypeAdaptionOnly = 0x02,
- // Adaptation_field followed by payload
- TSAdaptionTypeBoth = 0x03,
- };
- #endif
- // Table 2-29 – Stream type assignments. page 66.
- enum TSStreamType
- {
- // ITU-T | ISO/IEC Reserved
- TSStreamTypeReserved = 0x00,
- /*defined by ffmpeg*/
- TSStreamTypeVideoMpeg1 = 0x01,
- TSStreamTypeVideoMpeg2 = 0x02,
- TSStreamTypeAudioMpeg1 = 0x03,
- TSStreamTypeAudioMpeg2 = 0x04,
- TSStreamTypePrivateSection = 0x05,
- TSStreamTypePrivateData = 0x06,
- TSStreamTypeAudioAAC = 0x0f,
- TSStreamTypeVideoMpeg4 = 0x10,
- TSStreamTypeVideoH264 = 0x1b,
- TSStreamTypeAudioAC3 = 0x81,
- TSStreamTypeAudioDTS = 0x8a,
- };
- /**
- * the actually parsed type.
- */
- enum TSPidType
- {
- TSPidTypeReserved = 0, // TSPidTypeReserved, nothing parsed, used reserved.
-
- TSPidTypePAT, // Program associtate table
- TSPidTypePMT, // Program map table.
-
- TSPidTypeVideo, // only for H264 video
- TSPidTypeAudio, // only for AAC audio
- };
- // forward declares.
- class TSHeader;
- class TSAdaptionField;
- class TSPayload;
- class TSPayloadReserved;
- class TSPayloadPAT;
- class TSPayloadPMT;
- class TSPayloadPES;
- class TSContext;
- class TSMessage;
- // TSPacket declares.
- class TSPacket
- {
- public:
- TSHeader* header;
- TSAdaptionField* adaption_field;
- TSPayload* payload;
-
- TSPacket();
- virtual ~TSPacket();
- int demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg);
- int finish();
- };
- /**
- * 2.4.3.2 Transport Stream packet layer. page 36.
- */
- class TSHeader
- {
- public:
- // 1B
- int8_t sync_byte; //8bits
- // 2B
- int8_t transport_error_indicator; //1bit
- int8_t payload_unit_start_indicator; //1bit
- int8_t transport_priority; //1bit
- TSPidTable pid; //13bits
- // 1B
- int8_t transport_scrambling_control; //2bits
- TSAdaptionType adaption_field_control; //2bits
- u_int8_t continuity_counter; //4bits
-
- TSHeader();
- virtual ~TSHeader();
- int get_size();
- int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg);
- };
- // variant ts packet adation field. page 40.
- class TSAdaptionField
- {
- public:
- // 1B
- u_int8_t adaption_field_length; //8bits
- // 1B
- int8_t discontinuity_indicator; //1bit
- int8_t random_access_indicator; //1bit
- int8_t elementary_stream_priority_indicator; //1bit
- int8_t PCR_flag; //1bit
- int8_t OPCR_flag; //1bit
- int8_t splicing_point_flag; //1bit
- int8_t transport_private_data_flag; //1bit
- int8_t adaptation_field_extension_flag; //1bit
-
- // if PCR_flag, 6B
- int64_t program_clock_reference_base; //33bits
- //6bits reserved.
- int16_t program_clock_reference_extension; //9bits
-
- // if OPCR_flag, 6B
- int64_t original_program_clock_reference_base; //33bits
- //6bits reserved.
- int16_t original_program_clock_reference_extension; //9bits
-
- // if splicing_point_flag, 1B
- int8_t splice_countdown; //8bits
-
- // if transport_private_data_flag, 1+p[0] B
- u_int8_t transport_private_data_length; //8bits
- char* transport_private_data; //[transport_private_data_length]bytes
-
- // if adaptation_field_extension_flag, 2+x bytes
- u_int8_t adaptation_field_extension_length; //8bits
- int8_t ltw_flag; //1bit
- int8_t piecewise_rate_flag; //1bit
- int8_t seamless_splice_flag; //1bit
- //5bits reserved
- // if ltw_flag, 2B
- int8_t ltw_valid_flag; //1bit
- int16_t ltw_offset; //15bits
- // if piecewise_rate_flag, 3B
- //2bits reserved
- int32_t piecewise_rate; //22bits
- // if seamless_splice_flag, 5B
- int8_t splice_type; //4bits
- int8_t DTS_next_AU0; //3bits
- int8_t marker_bit0; //1bit
- int16_t DTS_next_AU1; //15bits
- int8_t marker_bit1; //1bit
- int16_t DTS_next_AU2; //15bits
- int8_t marker_bit2; //1bit
- // left bytes.
- char* af_ext_reserved;
-
- // left bytes.
- char* af_reserved;
-
- // user defined total adaption field size.
- int __field_size;
- // logic pcr/original_pcr
- int64_t pcr;
- int64_t original_pcr;
-
- TSAdaptionField();
- virtual ~TSAdaptionField();
- int get_size();
- int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg);
- };
- // variant ts packet payload.
- // PES packet or PSI table.
- // TSPayloadPAT: page 61.
- class TSPayload
- {
- public:
- /**
- * the size of payload(payload plush the 1byte pointer_field).
- */
- int size;
- int pointer_field_size;
-
- TSPidType type;
-
- /**
- * 2.4.4.2 Semantics definition of fields in pointer syntax
- */
- u_int8_t pointer_field;
-
- TSPayloadReserved* reserved;
- TSPayloadPAT* pat;
- TSPayloadPMT* pmt;
- TSPayloadPES* pes;
-
- /**
- * 2.4.3.6 PES packet. page 49.
- */
-
- TSPayload();
- virtual ~TSPayload();;
- void read_pointer_field(TSPacket* pkt, u_int8_t*& p);
- int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg);
- };
- /**
- * 2.4.4.3 Program association Table. page 61.
- */
- class TSPayloadPAT
- {
- public:
- // 1B
- u_int8_t table_id; //8bits
-
- // 2B
- int8_t section_syntax_indicator; //1bit
- int8_t const0_value; //1bit
- // 2bits reserved.
- u_int16_t section_length; //12bits
-
- // 2B
- u_int16_t transport_stream_id; //16bits
-
- // 1B
- // 2bits reerverd.
- int8_t version_number; //5bits
- int8_t current_next_indicator; //1bit
-
- // 1B
- u_int8_t section_number; //8bits
-
- // 1B
- u_int8_t last_section_number; //8bits
-
- // multiple 4B program data.
- // program_number 16bits
- // reserved 2bits
- // 13bits data: 0x1FFF
- // if program_number program_map_PID 13bits
- // else network_PID 13bytes.
- int program_size;
- int32_t* programs; //32bits
-
- // 4B
- int32_t CRC_32; //32bits
-
- TSPayloadPAT();
- virtual ~TSPayloadPAT();
- int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg);
- };
- class TSPMTESInfo
- {
- public:
- // 1B
- u_int8_t stream_type; //8bits
-
- // 2B
- // 3bits reserved
- int16_t elementary_PID; //13bits
-
- // 2B
- // 4bits reserved
- int16_t ES_info_length; //12bits
-
- char* ES_info; //[ES_info_length] bytes.
-
- TSPMTESInfo();
- virtual ~TSPMTESInfo();
- };
- /**
- * 2.4.4.8 Program Map Table. page 64.
- */
- class TSPayloadPMT
- {
- public:
- // 1B
- u_int8_t table_id; //8bits
-
- // 2B
- int8_t section_syntax_indicator; //1bit
- int8_t const0_value; //1bit
- // 2bits reserved.
- u_int16_t section_length; //12bits
-
- // 2B
- u_int16_t program_number; //16bits
-
- // 1B
- // 2bits reerverd.
- int8_t version_number; //5bits
- int8_t current_next_indicator; //1bit
-
- // 1B
- u_int8_t section_number; //8bits
-
- // 1B
- u_int8_t last_section_number; //8bits
-
- // 2B
- // 2bits reserved.
- int16_t PCR_PID; //16bits
-
- // 2B
- // 4bits reserved.
- int16_t program_info_length; //12bits
- char* program_info_desc; //[program_info_length]bytes
-
- // array of TSPMTESInfo.
- std::vector<TSPMTESInfo*> ES_info;
-
- // 4B
- int32_t CRC_32; //32bits
-
- TSPayloadPMT();
- virtual ~TSPayloadPMT();
- TSPMTESInfo* at(int index);
- int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg);
- };
- /**
- * Table 2-18 – Stream_id assignments. page 52.
- */
- enum TSPESStreamId
- {
- PES_program_stream_map = 0xbc, // 0b10111100
- PES_private_stream_1 = 0xbd, // 0b10111101
- PES_padding_stream = 0xbe, // 0b10111110
- PES_private_stream_2 = 0xbf, // 0b10111111
-
- // 110x xxxx
- // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
- // 14496-3 audio stream number x xxxx
- // (stream_id>>5)&0x07 == PES_audio_prefix
- PES_audio_prefix = 0x06, // 0b110
-
- // 1110 xxxx
- // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
- // 14496-2 video stream number xxxx
- // (stream_id>>4)&0x0f == PES_audio_prefix
- PES_video_prefix = 0x0e, // 0b1110
-
- PES_ECM_stream = 0xf0, // 0b11110000
- PES_EMM_stream = 0xf1, // 0b11110001
- PES_DSMCC_stream = 0xf2, // 0b11110010
- PES_13522_stream = 0xf3, // 0b11110011
- PES_H_222_1_type_A = 0xf4, // 0b11110100
- PES_H_222_1_type_B = 0xf5, // 0b11110101
- PES_H_222_1_type_C = 0xf6, // 0b11110110
- PES_H_222_1_type_D = 0xf7, // 0b11110111
- PES_H_222_1_type_E = 0xf8, // 0b11111000
- PES_ancillary_stream = 0xf9, // 0b11111001
- PES_SL_packetized_stream = 0xfa, // 0b11111010
- PES_FlexMux_stream = 0xfb, // 0b11111011
- // reserved data stream
- // 1111 1100 … 1111 1110
- PES_program_stream_directory= 0xff, // 0b11111111
- };
- /**
- * 2.4.3.7 Semantic definition of fields in PES packet. page 49.
- */
- class TSPayloadPES
- {
- public:
- // 3B
- int32_t packet_start_code_prefix; //24bits
- // 1B
- u_int8_t stream_id; //8bits
- // 2B
- u_int16_t PES_packet_length; //16bits
- // 1B
- // 2bits const '10'
- int8_t PES_scrambling_control; //2bits
- int8_t PES_priority; //1bit
- int8_t data_alignment_indicator; //1bit
- int8_t copyright; //1bit
- int8_t original_or_copy; //1bit
-
- // 1B
- int8_t PTS_DTS_flags; //2bits
- int8_t ESCR_flag; //1bit
- int8_t ES_rate_flag; //1bit
- int8_t DSM_trick_mode_flag; //1bit
- int8_t additional_copy_info_flag; //1bit
- int8_t PES_CRC_flag; //1bit
- int8_t PES_extension_flag; //1bit
-
- // 1B
- u_int8_t PES_header_data_length; //8bits
-
- int64_t pts; // 33bits
- int64_t dts; // 33bits
-
- int16_t ESCR_extension; //9bits
- int64_t ESCR_base; //33bits
- int32_t ES_rate; //22bits
-
- int8_t trick_mode_control; //3bits
- int8_t trick_mode_value; //5bits
-
- int8_t additional_copy_info; //7bits
- int16_t previous_PES_packet_CRC; //16bits
-
- int8_t PES_private_data_flag; //1bit
- int8_t pack_header_field_flag; //1bit
- int8_t program_packet_sequence_counter_flag; //1bit
- int8_t P_STD_buffer_flag; //1bit
- // reserved 3bits
- int8_t PES_extension_flag_2; //1bit
-
- // 16B
- char* PES_private_data; //128bits
-
- int8_t pack_field_length; //8bits
- char* pack_field; //[pack_field_length] bytes
-
- int8_t program_packet_sequence_counter; //7bits
- int8_t MPEG1_MPEG2_identifier; //1bit
- int8_t original_stuff_length; //6bits
-
- int8_t P_STD_buffer_scale; //1bit
- int16_t P_STD_buffer_size; //13bits
-
- int8_t PES_extension_field_length; //7bits
- char* PES_extension_field; //[PES_extension_field_length] bytes
-
- int stuffing_size;
- char* stuffing_byte;
-
- TSPayloadPES();
- virtual ~TSPayloadPES();
- int64_t decode_33bits_int(u_int8_t*& p, int64_t& temp);
- int64_t decode_33bits_int(int64_t& temp);
- int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg);
- };
- class TSPayloadReserved
- {
- public:
- int size;
- char* bytes;
-
- TSPayloadReserved();
- virtual ~TSPayloadReserved();
- int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg);
- };
- /**
- * logic ts pid.
- */
- struct TSPid
- {
- TSPidType type;
- // page 66.
- TSStreamType stream_type;
- // page 36
- TSPidTable pid;
- // page 36
- u_int8_t continuity_counter;
- };
- /**
- * logic audio/video message
- */
- class TSMessage
- {
- public:
- // 2.4.3.2 Transport Stream packet layer. page 36
- // the pid of PES packet.
- TSPidTable pid;
-
- // the type of pid.
- TSPidType type;
- // the type of stream, codec type.
- TSStreamType stream_type;
- // page 36
- u_int8_t continuity_counter;
-
- // 2.4.3.7 Semantic definition of fields in PES packet. page 49
- // PES packet header size plus data size.
- u_int16_t PES_packet_length; //16bits
- // the stream id.
- u_int8_t stream_id;
-
- // 2.4.3.7 Semantic definition of fields in PES packet. page 49.
- int32_t packet_start_code_prefix;
-
- int64_t pts; // 33bits
- int64_t dts; // 33bits
- int64_t pcr;
-
- // header size.
- int packet_header_size;
-
- // the parsed packet size.
- int parsed_packet_size;
-
- // total packet size.
- int packet_data_size;
- char* packet_data;
-
- // for avc.
- u_int8_t nal_ref_idc;
- u_int8_t nal_unit_type;
-
- TSMessage();
- virtual ~TSMessage();
-
- void append(u_int8_t*& p, int size);
- void detach(TSContext* ctx, TSMessage*& pmsg);
-
- bool is_video();
- };
- // ts context
- class TSContext
- {
- public:
- /**
- * consumed pids.
- */
- int pid_size;
- TSPid* pids;
- int64_t ts_packet_count;
- std::map<TSPidTable, TSMessage*> msgs;
-
- TSContext();
- virtual ~TSContext();
- bool exists(TSPidTable pid);
- TSPid* get(TSPidTable pid);
- void push(TSPidTable pid, TSStreamType stream_type, TSPidType type, u_int8_t continuity_counter);
-
- TSMessage* get_msg(TSPidTable pid);
- void detach(TSMessage* msg);
- };
- TSContext::TSContext()
- {
- pid_size = 0;
- ts_packet_count = 0;
- pids = NULL;
- }
- TSContext::~TSContext()
- {
- srs_freep(pids);
-
- std::map<TSPidTable, TSMessage*>::iterator it;
- for (it = msgs.begin(); it != msgs.end(); ++it) {
- TSMessage* msg = it->second;
- srs_freep(msg);
- }
- msgs.clear();
- }
- bool TSContext::exists(TSPidTable pid)
- {
- for (int i = 0; i < pid_size; i++) {
- if (pid == pids[i].pid) {
- return true;
- }
- }
-
- return false;
- }
- TSPid* TSContext::get(TSPidTable pid)
- {
- for (int i = 0; i < pid_size; i++) {
- if (pid == pids[i].pid) {
- return &pids[i];
- }
- }
-
- return NULL;
- }
- void TSContext::push(TSPidTable pid, TSStreamType stream_type, TSPidType type, u_int8_t continuity_counter)
- {
- TSPid* p = get(pid);
-
- if (!p) {
- p = new TSPid[pid_size + 1];
- memcpy(p, pids, sizeof(TSPid) * pid_size);
-
- p[pid_size] = (TSPid){type, stream_type, pid, continuity_counter};
- pid_size++;
-
- srs_freep(pids);
- pids = p;
- }
-
- p->continuity_counter = continuity_counter;
- }
- TSMessage* TSContext::get_msg(TSPidTable pid)
- {
- if (msgs[pid] == NULL) {
- TSMessage* msg = new TSMessage();
- msg->pid = pid;
- msgs[pid] = msg;
- }
-
- return msgs[pid];
- }
- void TSContext::detach(TSMessage* msg)
- {
- msgs[msg->pid] = NULL;
- }
- TSMessage::TSMessage()
- {
- pid = TSPidTablePAT;
- type = TSPidTypeReserved;
- stream_type = TSStreamTypeReserved;
- stream_id = 0;
- packet_start_code_prefix = 0;
- pts = dts = pcr = 0;
- PES_packet_length = 0;
- packet_header_size = 0;
- parsed_packet_size = 0;
- packet_data_size = 0;
- packet_data = NULL;
-
- nal_ref_idc = 0;
- nal_unit_type = 0;
- }
- TSMessage::~TSMessage()
- {
- srs_freep(packet_data);
- }
- void TSMessage::append(u_int8_t*& p, int size)
- {
- if (size <= 0) {
- return;
- }
-
- // for PES_packet_length is 0, the size is varient.
- if (packet_data_size - parsed_packet_size < size) {
- int realloc_size = size - (packet_data_size - parsed_packet_size);
- packet_data = (char*)realloc(packet_data, packet_data_size + realloc_size);
-
- packet_data_size += realloc_size;
- }
-
- memcpy(packet_data + parsed_packet_size, p, size);
- p += size;
- parsed_packet_size += size;
- }
- void TSMessage::detach(TSContext* ctx, TSMessage*& pmsg)
- {
- if (parsed_packet_size >= packet_data_size) {
- ctx->detach(this);
- pmsg = this;
- }
- }
- bool TSMessage::is_video()
- {
- return type == TSPidTypeVideo;
- }
- TSAdaptionField::TSAdaptionField()
- {
- adaption_field_length = 0;
- discontinuity_indicator = 0;
- random_access_indicator = 0;
- elementary_stream_priority_indicator = 0;
- PCR_flag = 0;
- OPCR_flag = 0;
- splicing_point_flag = 0;
- transport_private_data_flag = 0;
- adaptation_field_extension_flag = 0;
- program_clock_reference_base = 0;
- program_clock_reference_extension = 0;
- original_program_clock_reference_base = 0;
- original_program_clock_reference_extension = 0;
- splice_countdown = 0;
- transport_private_data_length = 0;
- transport_private_data = NULL;
- adaptation_field_extension_length = 0;
- ltw_flag = 0;
- piecewise_rate_flag = 0;
- seamless_splice_flag = 0;
- ltw_valid_flag = 0;
- ltw_offset = 0;
- piecewise_rate = 0;
- splice_type = 0;
- DTS_next_AU0 = 0;
- marker_bit0 = 0;
- DTS_next_AU1 = 0;
- marker_bit1 = 0;
- DTS_next_AU2 = 0;
- marker_bit2 = 0;
- af_ext_reserved = NULL;
- af_reserved = NULL;
- __field_size = 0;
- pcr = 0;
- original_pcr = 0;
- }
- TSAdaptionField::~TSAdaptionField()
- {
- srs_freep(transport_private_data);
- srs_freep(af_ext_reserved);
- srs_freep(af_reserved);
- }
- int TSAdaptionField::get_size()
- {
- return __field_size;
- }
- int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
- {
- int ret = 0;
- adaption_field_length = *p++;
- u_int8_t* pos_af = p;
- __field_size = 1 + adaption_field_length;
-
- if (adaption_field_length <= 0) {
- trace("ts+af empty af decoded.");
- return ret;
- }
-
- int8_t value = *p++;
-
- discontinuity_indicator = (value >> 7) & 0x01;
- random_access_indicator = (value >> 6) & 0x01;
- elementary_stream_priority_indicator = (value >> 5) & 0x01;
- PCR_flag = (value >> 4) & 0x01;
- OPCR_flag = (value >> 3) & 0x01;
- splicing_point_flag = (value >> 2) & 0x01;
- transport_private_data_flag = (value >> 1) & 0x01;
- adaptation_field_extension_flag = (value >> 0) & 0x01;
-
- char* pp = NULL;
- if (PCR_flag) {
- pp = (char*)&program_clock_reference_base;
- pp[5] = *p++;
- pp[4] = *p++;
- pp[3] = *p++;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- program_clock_reference_extension = program_clock_reference_base & 0x1ff;
- program_clock_reference_base = (program_clock_reference_base >> 15) & 0x1ffffffffLL;
-
- // high 9bits
- pcr = program_clock_reference_extension;
- pcr = (pcr << 33) & 0x3fe00000000LL;
- // low 33bits
- pcr |= program_clock_reference_base;
- }
- if (OPCR_flag) {
- pp = (char*)&original_program_clock_reference_base;
- pp[5] = *p++;
- pp[4] = *p++;
- pp[3] = *p++;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- original_program_clock_reference_extension = original_program_clock_reference_base & 0x1ff;
- original_program_clock_reference_base = (original_program_clock_reference_base >> 15) & 0x1ffffffffLL;
-
- // high 9bits
- original_pcr = program_clock_reference_extension;
- original_pcr = (original_pcr << 33) & 0x3fe00000000LL;
- // low 33bits
- original_pcr |= program_clock_reference_base;
- }
- if (splicing_point_flag) {
- splice_countdown = *p++;
- }
- if (transport_private_data_flag) {
- transport_private_data_length = *p++;
- transport_private_data = new char[transport_private_data_length];
- for (int i = 0; i < transport_private_data_length; i++) {
- transport_private_data[i] = *p++;
- }
- }
- if (adaptation_field_extension_flag) {
- adaptation_field_extension_length = *p++;
- u_int8_t* pos_af_ext = p;
-
- ltw_flag = *p++;
-
- piecewise_rate_flag = (ltw_flag >> 6) & 0x01;
- seamless_splice_flag = (ltw_flag >> 5) & 0x01;
- ltw_flag = (ltw_flag >> 7) & 0x01;
-
- if (ltw_flag) {
- pp = (char*)<w_offset;
- pp[1] = *p++;
- pp[0] = *p++;
-
- ltw_valid_flag = (ltw_offset >> 15) &0x01;
- ltw_offset &= 0x7FFF;
- }
- if (piecewise_rate_flag) {
- pp = (char*)&piecewise_rate;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- piecewise_rate &= 0x3FFFFF;
- }
- if (seamless_splice_flag) {
- // 1B
- marker_bit0 = *p++;
-
- splice_type = (marker_bit0 >> 4) & 0x0F;
- DTS_next_AU0 = (marker_bit0 >> 1) & 0x07;
- marker_bit0 &= 0x01;
-
- // 2B
- pp = (char*)&DTS_next_AU1;
- pp[1] = *p++;
- pp[0] = *p++;
-
- marker_bit1 = DTS_next_AU1 & 0x01;
- DTS_next_AU1 = (DTS_next_AU1 >> 1) & 0x7FFF;
-
- // 2B
- pp = (char*)&DTS_next_AU2;
- pp[1] = *p++;
- pp[0] = *p++;
-
- marker_bit2 = DTS_next_AU2 & 0x01;
- DTS_next_AU2 = (DTS_next_AU2 >> 1) & 0x7FFF;
- }
-
- // af_ext_reserved
- int ext_size = adaptation_field_extension_length - (p - pos_af_ext);
- if (ext_size > 0) {
- af_ext_reserved = new char[ext_size];
- memcpy(af_ext_reserved, p, ext_size);
- p += ext_size;
- }
- }
-
- // af_reserved
- int af_size = adaption_field_length - (p - pos_af);
- if (af_size > 0) {
- af_reserved = new char[af_size];
- memcpy(af_reserved, p, af_size);
- p += af_size;
- }
-
- trace("ts+af af flags parsed, discontinuity: %d random: %d priority: %d PCR: %d OPCR: %d slicing: %d private: %d extension: %d pcr: %"PRId64" opcr: %"PRId64"",
- discontinuity_indicator, random_access_indicator, elementary_stream_priority_indicator, PCR_flag, OPCR_flag, splicing_point_flag,
- transport_private_data_flag, adaptation_field_extension_flag, pcr, original_pcr);
-
- return ret;
- }
- TSPayloadReserved::TSPayloadReserved()
- {
- size = 0;
- bytes = NULL;
- }
- TSPayloadReserved::~TSPayloadReserved()
- {
- srs_freep(bytes);
- }
- int TSPayloadReserved::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
- {
- int ret = 0;
-
- size = pkt->payload->size - pkt->payload->pointer_field_size;
- // not parsed bytes.
- if (size > 0) {
- bytes = new char[size];
- memcpy(bytes, p, size);
- p += size;
- }
- return ret;
- }
- TSPayloadPAT::TSPayloadPAT()
- {
- table_id = 0;
- section_syntax_indicator = 0;
- const0_value = 0;
- section_length = 0;
- transport_stream_id = 0;
- version_number = 0;
- current_next_indicator = 0;
- section_number = 0;
- last_section_number = 0;
- program_size = 0;
- programs = NULL;
- CRC_32 = 0;
- }
- TSPayloadPAT::~TSPayloadPAT()
- {
- srs_freep(programs);
- }
- int TSPayloadPAT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
- {
- int ret = 0;
-
- table_id = *p++;
-
- char* pp = (char*)§ion_length;
- pp[1] = *p++;
- pp[0] = *p++;
- u_int8_t* pos = p;
-
- section_syntax_indicator = (section_length >> 15) & 0x01;
- const0_value = (section_length >> 14) & 0x01;
- section_length &= 0x0FFF;
-
- pp = (char*)&transport_stream_id;
- pp[1] = *p++;
- pp[0] = *p++;
-
- current_next_indicator = *p++;
- version_number = (current_next_indicator >> 1) & 0x1F;
- current_next_indicator &= 0x01;
-
- section_number = *p++;
- last_section_number = *p++;
-
- // 4 is crc size.
- int program_bytes = section_length - 4 - (p - pos);
- program_size = program_bytes / 4;
- if (program_size > 0) {
- programs = new int32_t[program_size];
- for (int i = 0; i < program_size; i++) {
- pp = (char*)&programs[i];
- pp[3] = *p++;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- int16_t pid = programs[i] & 0x1FFF;
- ctx->push((TSPidTable)pid, TSStreamTypeReserved, TSPidTypePMT, pkt->header->continuity_counter);
- }
- }
-
- pp = (char*)&CRC_32;
- pp[3] = *p++;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- return ret;
- }
- TSPMTESInfo::TSPMTESInfo()
- {
- stream_type = 0;
- elementary_PID = 0;
- ES_info_length = 0;
- ES_info = NULL;
- }
- TSPMTESInfo::~TSPMTESInfo()
- {
- srs_freep(ES_info);
- }
- TSPayloadPMT::TSPayloadPMT()
- {
- table_id = 0;
- section_syntax_indicator = 0;
- const0_value = 0;
- section_length = 0;
- program_number = 0;
- version_number = 0;
- current_next_indicator = 0;
- section_number = 0;
- last_section_number = 0;
- PCR_PID = 0;
- program_info_length = 0;
- program_info_desc = NULL;
- CRC_32 = 0;
- }
- TSPayloadPMT::~TSPayloadPMT()
- {
- srs_freep(program_info_desc);
-
- for (std::vector<TSPMTESInfo*>::iterator it = ES_info.begin(); it != ES_info.end(); ++it) {
- TSPMTESInfo* info = *it;
- srs_freep(info);
- }
- ES_info.clear();
- }
- TSPMTESInfo* TSPayloadPMT::at(int index)
- {
- return ES_info.at(index);
- }
- int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
- {
- int ret = 0;
-
- table_id = *p++;
-
- char* pp = (char*)§ion_length;
- pp[1] = *p++;
- pp[0] = *p++;
- u_int8_t* pos = p;
-
- section_syntax_indicator = (section_length >> 15) & 0x01;
- const0_value = (section_length >> 14) & 0x01;
- section_length &= 0x0FFF;
-
- pp = (char*)&program_number;
- pp[1] = *p++;
- pp[0] = *p++;
-
- current_next_indicator = *p++;
- version_number = (current_next_indicator >> 1) & 0x1F;
- current_next_indicator &= 0x01;
-
- section_number = *p++;
- last_section_number = *p++;
-
- pp = (char*)&PCR_PID;
- pp[1] = *p++;
- pp[0] = *p++;
-
- PCR_PID &= 0x1FFF;
-
- pp = (char*)&program_info_length;
- pp[1] = *p++;
- pp[0] = *p++;
-
- program_info_length &= 0xFFF;
-
- if (program_info_length > 0) {
- program_info_desc = new char[program_info_length];
- memcpy(program_info_desc, p, program_info_length);
- p += program_info_length;
- }
-
- // [section_length] - 4(CRC) - 9B - [program_info_length]
- int ES_bytes = section_length - 4 - 9 - program_info_length;
- while (ES_bytes > 0) {
- TSPMTESInfo* info = new TSPMTESInfo();
-
- info->stream_type = *p++;
- ES_bytes--;
-
- pp = (char*)&info->elementary_PID;
- pp[1] = *p++;
- pp[0] = *p++;
- ES_bytes -= 2;
-
- info->elementary_PID &= 0x1FFF;
-
- pp = (char*)&info->ES_info_length;
- pp[1] = *p++;
- pp[0] = *p++;
- ES_bytes -= 2;
-
- info->ES_info_length &= 0x0FFF;
-
- if (info->ES_info_length > 0) {
- info->ES_info = new char[info->ES_info_length];
- memcpy(info->ES_info, p, info->ES_info_length);
-
- p += info->ES_info_length;
- ES_bytes -= info->ES_info_length;
- }
-
- ES_info.push_back(info);
-
- if (info->stream_type == TSStreamTypeVideoH264) {
- // TODO: support more video type.
- ctx->push((TSPidTable)info->elementary_PID, (TSStreamType)info->stream_type, TSPidTypeVideo, pkt->header->continuity_counter);
- trace("ts+pmt add pid: %d, type: H264 video", info->elementary_PID);
- } else if (info->stream_type == TSStreamTypeAudioAAC) {
- // TODO: support more audio type.
- // see aac: 6.2 Audio Data Transport Stream, ADTS
- ctx->push((TSPidTable)info->elementary_PID, (TSStreamType)info->stream_type, TSPidTypeAudio, pkt->header->continuity_counter);
- trace("ts+pmt add pid: %d, type: AAC audio", info->elementary_PID);
- } else {
- trace("ts+pmt ignore the stream type: %d", info->stream_type);
- }
- }
-
- pp = (char*)&CRC_32;
- pp[3] = *p++;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- return ret;
- }
- TSPayloadPES::TSPayloadPES()
- {
- packet_start_code_prefix = 0;
- stream_id = 0;
- PES_packet_length = 0;
- PES_scrambling_control = 0;
- PES_priority = 0;
- data_alignment_indicator = 0;
- copyright = 0;
- original_or_copy = 0;
- PTS_DTS_flags = 0;
- ESCR_flag = 0;
- ES_rate_flag = 0;
- DSM_trick_mode_flag = 0;
- additional_copy_info_flag = 0;
- PES_CRC_flag = 0;
- PES_extension_flag = 0;
- PES_header_data_length = 0;
- pts = 0;
- dts = 0;
- ESCR_extension = 0;
- ESCR_base = 0;
- ES_rate = 0;
- trick_mode_control = 0;
- trick_mode_value = 0;
- additional_copy_info = 0;
- previous_PES_packet_CRC = 0;
- PES_private_data_flag = 0;
- pack_header_field_flag = 0;
- program_packet_sequence_counter_flag = 0;
- P_STD_buffer_flag = 0;
- PES_extension_flag_2 = 0;
- PES_private_data = NULL;
- pack_field_length = 0;
- pack_field = NULL;
- program_packet_sequence_counter = 0;
- MPEG1_MPEG2_identifier = 0;
- original_stuff_length = 0;
- P_STD_buffer_scale = 0;
- P_STD_buffer_size = 0;
- PES_extension_field_length = 0;
- PES_extension_field = NULL;
- stuffing_size = 0;
- stuffing_byte = NULL;
- }
- TSPayloadPES::~TSPayloadPES()
- {
- srs_freep(PES_private_data);
- srs_freep(pack_field);
- srs_freep(PES_extension_field);
- srs_freep(stuffing_byte);
- }
- int64_t TSPayloadPES::decode_33bits_int(u_int8_t*& p, int64_t& temp)
- {
- char* pp = (char*)&temp;
- pp[4] = *p++;
- pp[3] = *p++;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- return decode_33bits_int(temp);
- }
- int64_t TSPayloadPES::decode_33bits_int(int64_t& temp)
- {
- int64_t ret = 0;
-
- // marker_bit 1bit
- temp = temp >> 1;
- // PTS [14..0] 15bits
- ret |= temp & 0x7fff;
- // marker_bit 1bit
- temp = temp >> 1;
- // PTS [29..15] 15bits, 15zero, 29-15+1one
- ret |= temp & 0x3fff8000LL;
- // marker_bit 1bit
- temp = temp >> 1;
- // PTS [32..30] 3bits
- ret |= temp & 0x1c0000000LL;
-
- temp = temp >> 33;
-
- return ret;
- }
- int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
- {
- int ret = 0;
-
- char* pp = (char*)&packet_start_code_prefix;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- packet_start_code_prefix &= 0xFFFFFF;
- if (packet_start_code_prefix != 0x01) {
- trace("ts+pes decode unit start packet error, msg is empty.");
- return -1;
- }
- stream_id = *p++;
-
- pp = (char*)&PES_packet_length;
- pp[1] = *p++;
- pp[0] = *p++;
- u_int8_t* pos_packet = p;
-
- if (stream_id != PES_program_stream_map
- && stream_id != PES_padding_stream
- && stream_id != PES_private_stream_2
- && stream_id != PES_ECM_stream
- && stream_id != PES_EMM_stream
- && stream_id != PES_program_stream_directory
- && stream_id != PES_DSMCC_stream
- && stream_id != PES_H_222_1_type_E
- ) {
- original_or_copy = *p++;
-
- //int8_t const2bits = (original_or_copy >> 6) & 0x03;
- PES_scrambling_control = (original_or_copy >> 4) & 0x03;
- PES_priority = (original_or_copy >> 3) & 0x01;
- data_alignment_indicator = (original_or_copy >> 2) & 0x01;
- copyright = (original_or_copy >> 1) & 0x01;
- original_or_copy &= 0x01;
-
- PES_extension_flag = *p++;
-
- PTS_DTS_flags = (PES_extension_flag >> 6) & 0x03;
- ESCR_flag = (PES_extension_flag >> 5) & 0x01;
- ES_rate_flag = (PES_extension_flag >> 4) & 0x01;
- DSM_trick_mode_flag = (PES_extension_flag >> 3) & 0x01;
- additional_copy_info_flag = (PES_extension_flag >> 2) & 0x01;
- PES_CRC_flag = (PES_extension_flag >> 1) & 0x01;
- PES_extension_flag &= 0x01;
-
- PES_header_data_length = *p++;
- u_int8_t* pos_header = p;
- int64_t temp = 0;
- if (PTS_DTS_flags == 0x2) {
- pts = decode_33bits_int(p, temp);
- // '0010' 4bits
- //int8_t const4bits = temp & 0x0F;
- }
- if (PTS_DTS_flags == 0x3) {
- pts = decode_33bits_int(p, temp);
- // '0011' 4bits
- //int8_t const4bits = temp & 0x0F;
-
- dts = decode_33bits_int(p, temp);
- // '0001' 4bits
- //int8_t const4bits = temp & 0x0F;
- }
-
- if (ESCR_flag) {
- pp = (char*)&temp;
- pp[5] = *p++;
- pp[4] = *p++;
- pp[3] = *p++;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- // marker_bit 1bit
- temp = temp >> 1;
- // ESCR_extension 9bits
- ESCR_extension = temp & 0x1f;
- temp = temp >> 9;
-
- ESCR_base = decode_33bits_int(temp);
-
- // reserved 2bits
- //int8_t reserved2bits = temp & 0x03;
- }
-
- if (ES_rate_flag) {
- pp = (char*)&ES_rate;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- ES_rate = ES_rate >> 1;
- ES_rate &= 0x3FFFFF;
- }
- if (DSM_trick_mode_flag) {
- trick_mode_control = *p++;
- trick_mode_value = trick_mode_control & 0x1f;
- trick_mode_control = (trick_mode_control >> 5) & 0x03;
- }
-
- if (additional_copy_info_flag) {
- additional_copy_info = *p++;
- additional_copy_info &= 0x7f;
- }
-
- if (PES_CRC_flag) {
- pp = (char*)&previous_PES_packet_CRC;
- pp[1] = *p++;
- pp[0] = *p++;
- }
- if (PES_extension_flag) {
- PES_extension_flag_2 = *p++;
-
- PES_private_data_flag = (PES_extension_flag_2 >> 7) & 0x01;
- pack_header_field_flag = (PES_extension_flag_2 >> 6) & 0x01;
- program_packet_sequence_counter_flag = (PES_extension_flag_2 >> 5) & 0x01;
- P_STD_buffer_flag = (PES_extension_flag_2 >> 4) & 0x01;
- PES_extension_flag_2 &= PES_extension_flag_2 & 0x01;
-
- if (PES_private_data_flag) {
- PES_private_data = new char[16];
- memcpy(PES_private_data, p, 16);
- p += 16;
- }
-
- if (pack_header_field_flag) {
- pack_field_length = *p++;
- if (pack_field_length > 0) {
- pack_field = new char[pack_field_length];
- memcpy(pack_field, p, pack_field_length);
- p += pack_field_length;
- }
- }
-
- if (program_packet_sequence_counter_flag) {
- program_packet_sequence_counter = *p++;
- program_packet_sequence_counter &= 0x7f;
-
- original_stuff_length = *p++;
- MPEG1_MPEG2_identifier = (original_stuff_length >> 6) & 0x01;
- original_stuff_length &= 0x3f;
- }
-
- if (P_STD_buffer_flag) {
- pp = (char*)&P_STD_buffer_size;
- pp[1] = *p++;
- pp[0] = *p++;
-
- // '01'
- //int8_t const2bits = (P_STD_buffer_scale >>14) & 0x03;
- P_STD_buffer_scale = (P_STD_buffer_scale >>13) & 0x01;
- P_STD_buffer_size &= 0x1FFF;
- }
-
- if (PES_extension_flag_2) {
- PES_extension_field_length = *p++;
- PES_extension_field_length &= 0x07;
-
- if (PES_extension_field_length > 0) {
- PES_extension_field = new char[PES_extension_field_length];
- memcpy(PES_extension_field, p, PES_extension_field_length);
- p += PES_extension_field_length;
- }
- }
- }
-
- // stuffing_byte
- int stuffing_size = PES_header_data_length - (p - pos_header);
- if (stuffing_size > 0) {
- stuffing_byte = new char[stuffing_size];
- memcpy(stuffing_byte, p, stuffing_size);
- p += stuffing_size;
- }
-
- // get the pid.
- TSPid* pid = ctx->get(pkt->header->pid);
- if (!pid) {
- trace("ts+pes pid: %d type is invalid.", pkt->header->pid);
- }
-
- // get the message to build from the chunks(PES packets).
- TSMessage* msg = ctx->get_msg(pid->pid);
- msg->type = pid->type;
- msg->stream_type = pid->stream_type;
- msg->continuity_counter = pid->continuity_counter;
- msg->stream_id = stream_id;
- msg->packet_start_code_prefix = packet_start_code_prefix;
- msg->dts = dts;
- msg->pts = pts;
-
- // PES_packet_data_byte, page58.
- // the packet size contains the header size.
- // The number of PES_packet_data_bytes, N, is specified by the
- // PES_packet_length field. N shall be equal to the value
- // indicated in the PES_packet_length minus the number of bytes
- // between the last byte of the PES_packet_length field and the
- // first PES_packet_data_byte.
- msg->PES_packet_length = PES_packet_length;
- msg->packet_header_size = p - pos_packet;
- msg->packet_data_size = PES_packet_length - msg->packet_header_size;
-
- /**
- * when actual packet length > 0xffff(65535),
- * which exceed the max u_int16_t packet length,
- * use 0 packet length, the next unit start indicates the end of packet.
- */
- if (PES_packet_length == 0) {
- msg->packet_data_size = last - p - msg->packet_header_size;
- }
-
- if (msg->packet_data_size > 0) {
- msg->packet_data = new char[msg->packet_data_size];
- }
-
- // PES_packet_data_byte
- int size = srs_min(msg->packet_data_size, last - p);
- if (size > 0) {
- msg->append(p, size);
- }
-
- if (PES_packet_length > 0) {
- msg->detach(ctx, pmsg);
- }
-
- trace("ts+pes stream_id: %d size: %d pts: %"PRId64" dts: %"PRId64" total: %d header: %d packet_size: %d parsed_size: %d",
- stream_id, PES_packet_length, pts, dts, msg->PES_packet_length, msg->packet_header_size, msg->packet_data_size, msg->parsed_packet_size);
- } else if (stream_id == PES_program_stream_map
- || stream_id == PES_private_stream_2
- || stream_id == PES_ECM_stream
- || stream_id == PES_EMM_stream
- || stream_id == PES_program_stream_directory
- || stream_id == PES_DSMCC_stream
- || stream_id == PES_H_222_1_type_E
- ) {
- // for (i = 0; i < PES_packet_length; i++) {
- // PES_packet_data_byte
- // }
- // TODO: FIXME: implements it.
- } else if (stream_id == PES_padding_stream) {
- // for (i = 0; i < PES_packet_length; i++) {
- // padding_byte
- // }
- }
-
- return ret;
- }
- /**
- * 2.4.3.6 PES packet. page 49.
- */
- TSPayload::TSPayload()
- {
- size = 0;
- pointer_field_size = 0;
- type = TSPidTypeReserved;
- pointer_field = 0;
- reserved = NULL;
- pat = NULL;
- pmt = NULL;
- pes = NULL;
-
- }
- TSPayload::~TSPayload()
- {
- srs_freep(reserved);
- srs_freep(pat);
- srs_freep(pmt);
- srs_freep(pes);
- }
- void TSPayload::read_pointer_field(TSPacket* pkt, u_int8_t*& p)
- {
- if (pkt->header->payload_unit_start_indicator) {
- pointer_field = *p++;
- pointer_field_size = 1;
- }
- }
- int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
- {
- int ret = 0;
-
- if (pkt->header->pid == TSPidTablePAT) {
- read_pointer_field(pkt, p);
-
- type = TSPidTypePAT;
- pat = new TSPayloadPAT();
- return pat->demux(ctx, pkt, start, last, p, pmsg);
- }
-
- TSPid* pid = ctx->get(pkt->header->pid);
- if (pid && pid->type == TSPidTypePMT) {
- read_pointer_field(pkt, p);
-
- type = pid->type;
- pmt = new TSPayloadPMT();
- return pmt->demux(ctx, pkt, start, last, p, pmsg);
- }
- if (pid && (pid->type == TSPidTypeVideo || pid->type == TSPidTypeAudio)) {
- TSMessage* msg = ctx->get_msg(pkt->header->pid);
- if (pkt->adaption_field->pcr > 0) {
- msg->pcr = pkt->adaption_field->pcr;
- }
-
- // flush previous PES_packet_length(0) packets.
- if (msg->packet_start_code_prefix == 0x01
- && pkt->header->payload_unit_start_indicator == 1
- && msg->PES_packet_length == 0
- ) {
- msg->detach(ctx, pmsg);
- // reparse current message
- p = start;
- return ret;
- }
-
- // parse continous packet.
- if (!pkt->header->payload_unit_start_indicator) {
- if (msg->packet_start_code_prefix != 0x01) {
- trace("ts+pes decode continous packet error, msg is empty.");
- return -1;
- }
- msg->append(p, last - p);
-
- // for PES_packet_length is 0, donot attach it.
- if (msg->PES_packet_length > 0) {
- msg->detach(ctx, pmsg);
- }
- return ret;
- }
-
- type = pid->type;
- pes = new TSPayloadPES();
- return pes->demux(ctx, pkt, start, last, p, pmsg);
- }
-
- // not parsed bytes.
- type = TSPidTypeReserved;
- reserved = new TSPayloadReserved();
- if ((ret = reserved->demux(ctx, pkt, start, last, p, pmsg)) != 0) {
- return ret;
- }
-
- return ret;
- }
- TSPacket::TSPacket()
- {
- header = new TSHeader();
- adaption_field = new TSAdaptionField();
- payload = new TSPayload();
- }
- TSPacket::~TSPacket()
- {
- srs_freep(header);
- srs_freep(adaption_field);
- srs_freep(payload);
- }
- int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
- {
- int ret = 0;
-
- if ((ret = header->demux(ctx, this, start, last, p, pmsg)) != 0) {
- return ret;
- }
- if (header->adaption_field_control == TSAdaptionTypeAdaptionOnly || header->adaption_field_control == TSAdaptionTypeBoth) {
- if ((ret = adaption_field->demux(ctx, this, start, last, p, pmsg)) != 0) {
- trace("ts+header af(adaption field) decode error. ret=%d", ret);
- return ret;
- }
- trace("ts+header af(adaption field) decoded.");
- }
-
- // calc the user defined data size for payload.
- payload->size = TS_PACKET_SIZE - header->get_size() - adaption_field->get_size();
-
- if (header->adaption_field_control == TSAdaptionTypePayloadOnly || header->adaption_field_control == TSAdaptionTypeBoth) {
- // parse new packet.
- if ((ret = payload->demux(ctx, this, start, last, p, pmsg)) != 0) {
- trace("ts+header payload decode error. ret=%d", ret);
- return ret;
- }
- trace("ts+header payload decoded.");
- }
-
- ctx->ts_packet_count++;
- trace("ts+header parsed %"PRId64" packets finished. parsed: %d left: %d header: %d payload: %d(%d+%d)",
- ctx->ts_packet_count, (int)(p - start), (int)(last - p), header->get_size(), payload->size, payload->pointer_field_size,
- payload->size - payload->pointer_field_size);
-
- return finish();
- }
- int TSPacket::finish()
- {
- return 0;
- }
-
- TSHeader::TSHeader()
- {
- sync_byte = 0;
- transport_error_indicator = 0;
- payload_unit_start_indicator = 0;
- transport_priority = 0;
- pid = TSPidTablePAT;
- transport_scrambling_control = 0;
- adaption_field_control = TSAdaptionTypeReserved;
- continuity_counter = 0;
- }
- TSHeader::~TSHeader()
- {
- }
- int TSHeader::get_size()
- {
- return 4;
- }
- int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
- {
- int ret = 0;
- // ts packet header.
- sync_byte = *p++;
- if (sync_byte != 0x47) {
- trace("ts+sync_bytes invalid sync_bytes: %#x, expect is 0x47", sync_byte);
- return -1;
- }
-
- int16_t _pid = 0;
- char* pp = (char*)&_pid;
- pp[1] = *p++;
- pp[0] = *p++;
-
- transport_error_indicator = (_pid >> 15) & 0x01;
- payload_unit_start_indicator = (_pid >> 14) & 0x01;
- transport_priority = (_pid >> 13) & 0x01;
- _pid &= 0x1FFF;
-
- pid = (TSPidTable)_pid;
-
- continuity_counter = *p++;
-
- transport_scrambling_control = (continuity_counter >> 6) & 0x03;
- int8_t _adaption_field_control = (continuity_counter >> 4) & 0x03;
- adaption_field_control = (TSAdaptionType)_adaption_field_control;
- continuity_counter &= 0x0F;
-
- ctx->push(pid, TSStreamTypeReserved, TSPidTypePAT, continuity_counter);
-
- trace("ts+header sync: %#x error: %d unit_start: %d priotiry: %d pid: %d scrambling: %d adaption: %d counter: %d",
- sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid,
- transport_scrambling_control, adaption_field_control, continuity_counter);
-
- return ret;
- }
- /**
- * Annex B Byte stream format, in page 211.
- */
- class TSH264Codec
- {
- public:
- u_int8_t* raw_data;
- int size;
-
- TSH264Codec()
- {
- size = 0;
- raw_data = NULL;
- }
-
- u_int8_t at(int index)
- {
- if (index >= size) {
- return 0;
- }
- return raw_data[index];
- }
-
- int parse(TSMessage* msg, char* last, char*& p)
- {
- int ret = 0;
-
- srs_assert(p);
-
- while (next_start_code_prefix(p) != 0x000001) {
- char ch = *p++;
- if (ch != 0x00) {
- trace("ts+h264 parse msg failed, "
- "expect 0x00 before start-code. actual is: %#x", (u_int8_t)ch);
- return -1;
- }
- }
-
- if (p >= last) {
- trace("ts+h264 parse msg finished, no start-code.");
- return ret;
- }
-
- // start_code_prefix_one_3bytes /* equal to 0x000001 */
- p += 3;
-
- if (p < last) {
- raw_data = (u_int8_t*)p;
- }
- while (p < last - 3) {
- if (match_start_code_prefix(p)) {
- break;
- }
- p++;
- }
-
- if (raw_data) {
- size = (u_int8_t*)p - raw_data;
- if (p == last - 3) {
- size = (u_int8_t*)last - raw_data;
- p = last;
- }
- }
-
- trace("ts+h264 parse msg finished");
- return ret;
- }
-
- bool match_start_code_prefix(char*p)
- {
- return p[0] == 0x00 && p[1] == 0x00 && (p[2] == 0x00 || p[2] == 0x01);
- }
-
- int32_t next_start_code_prefix(char* p)
- {
- int32_t value = 0;
- char* pp = (char*)&value;
-
- pp[2] = p[0];
- pp[1] = p[1];
- pp[0] = p[2];
- return value;
- }
- };
- /**
- * Table 35 – Sampling frequency dependent on
- * sampling_frequency_index. in page 46.
- */
- enum TSAacSampleFrequency
- {
- TSAacSampleFrequency96000 = 0x00,
- TSAacSampleFrequency88200 = 0x01,
- TSAacSampleFrequency64000 = 0x02,
- TSAacSampleFrequency48000 = 0x03,
- TSAacSampleFrequency44100 = 0x04,
- TSAacSampleFrequency32000 = 0x05,
- TSAacSampleFrequency24000 = 0x06,
- TSAacSampleFrequency22050 = 0x07,
- TSAacSampleFrequency16000 = 0x08,
- TSAacSampleFrequency12000 = 0x09,
- TSAacSampleFrequency11025 = 0x0a,
- TSAacSampleFrequency8000 = 0x0b,
- TSAacSampleFrequencyReserved0 = 0x0c,
- TSAacSampleFrequencyReserved1 = 0x0d,
- TSAacSampleFrequencyReserved2 = 0x0e,
- TSAacSampleFrequencyReserved3 = 0x0f,
- };
- /**
- * 6.2 Audio Data Transport Stream, ADTS, in page 26.
- */
- class TSAacAdts
- {
- public:
- // adts_fixed_header
- // 2B, 16bits
- int16_t syncword; //12bits
- int8_t ID; //1bit
- int8_t layer; //2bits
- int8_t protection_absent; //1bit
- // 12bits
- int8_t profile; //2bit
- TSAacSampleFrequency sampling_frequency_index; //4bits
- int8_t private_bit; //1bit
- int8_t channel_configuration; //3bits
- int8_t original_or_copy; //1bit
- int8_t home; //1bit
-
- // adts_variable_header
- // 28bits
- int8_t copyright_identification_bit; //1bit
- int8_t copyright_identification_start; //1bit
- int16_t frame_length; //13bits
- int16_t adts_buffer_fullness; //11bits
- int8_t number_of_raw_data_blocks_in_frame; //2bits
-
- u_int8_t* raw_data;
- int size;
-
- TSAacAdts()
- {
- syncword = 0;
- ID = 0;
- layer = 0;
- protection_absent = 0;
- profile = 0;
- sampling_frequency_index = TSAacSampleFrequencyReserved0;
- private_bit = 0;
- channel_configuration = 0;
- original_or_copy = 0;
- home = 0;
- copyright_identification_bit = 0;
- copyright_identification_start = 0;
- frame_length = 0;
- adts_buffer_fullness = 0;
- number_of_raw_data_blocks_in_frame = 0;
-
- size = 0;
- raw_data = NULL;
- }
-
- u_int8_t at(int index)
- {
- if (index >= size) {
- return 0;
- }
- return raw_data[index];
- }
-
- int parse(TSMessage* msg, char*& p)
- {
- int ret = 0;
-
- srs_assert(p);
-
- char* start = p;
-
- // adts_fixed_header
- char* pp = (char*)&syncword;
- pp[1] = *p++;
- pp[0] = *p++;
-
- protection_absent = syncword & 0x01;
- layer = (syncword >> 1) & 0x03;
- ID = (syncword >> 3) & 0x01;
- syncword = (syncword >> 4) & 0x0FFF;
- if (syncword != 0xfff) {
- trace("ts+aac invalid sync word. expect 0xfff, actual %#x", syncword);
- return -1;
- }
- // adts_variable_header
- int64_t temp = 0;
- pp = (char*)&temp;
- pp[4] = *p++;
- pp[3] = *p++;
- pp[2] = *p++;
- pp[1] = *p++;
- pp[0] = *p++;
-
- number_of_raw_data_blocks_in_frame = temp & 0x03;
- temp = temp >> 2;
- adts_buffer_fullness = temp & 0x7FF;
- temp = temp >> 11;
- frame_length = temp & 0x1FFF;
- temp = temp >> 13;
-
- copyright_identification_start = temp & 0x01;
- temp = temp >> 1;
-
- copyright_identification_bit = temp & 0x01;
- temp = temp >> 1;
-
- // adts_fixed_header
- home = temp & 0x01;
- temp = temp >> 1;
-
- original_or_copy = temp & 0x01;
- temp = temp >> 1;
-
- channel_configuration = temp & 0x07;
- temp = temp >> 3;
-
- private_bit = temp & 0x01;
- temp = temp >> 1;
-
- sampling_frequency_index = (TSAacSampleFrequency)(temp & 0x0F);
- temp = temp >> 4;
-
- profile = temp & 0x03;
- temp = temp >> 2;
- if (!number_of_raw_data_blocks_in_frame) {
- // adts_error_check
- if (!protection_absent) {
- // crc_check
- trace("ts+aac TODO: crc_check.");
- }
- // raw_data_block
- raw_data = (u_int8_t*)p;
- size = frame_length - (p - start);
- p += size;
- } else {
- trace("ts+aac TODO: parse multiple blocks.");
- }
-
- return ret;
- }
- };
- class AacMuxer
- {
- public:
- int fd;
- const char* file;
- AacMuxer()
- {
- file = NULL;
- fd = 0;
- }
-
- virtual ~AacMuxer()
- {
- if (fd > 0) {
- close(fd);
- }
- }
- int open(const char* _file)
- {
- file = _file;
- if ((fd = ::open(file, O_CREAT|O_WRONLY|O_TRUNC,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)) < 0
- ) {
- return -1;
- }
-
- return 0;
- }
- int write_audio(char* data, int size)
- {
- if (size > 0 && write(fd, data, size) != size) {
- return -1;
- }
-
- return 0;
- }
- int write_video(char* data, int size)
- {
- return 0;
- }
- };
- int consume(TSMessage* msg, AacMuxer* aac_muxer)
- {
- int ret = 0;
-
- char* p = msg->packet_data;
- if (!p) {
- trace("ts+aac+h264 ignore empty message.");
- return ret;
- }
-
- char* last = msg->packet_data + msg->packet_data_size;
-
- if (!msg->is_video()) {
- // write AAC raw audio.
- if (aac_muxer && (ret = aac_muxer->write_audio((char*)msg->packet_data, msg->packet_data_size)) != 0) {
- return ret;
- }
-
- // parse AAC audio.
- int64_t dts = -1;
- while (p < last) {
- TSAacAdts aac;
- if ((ret = aac.parse(msg, p)) != 0) {
- return ret;
- }
- trace("ts+aac audio raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x",
- aac.size, aac.at(0), aac.at(1), aac.at(2), aac.at(3));
-
- if (dts == -1) {
- dts = (msg->dts == 0)? msg->pts : msg->dts;
- } else {
- // see ffmpeg: avpriv_aac_parse_header
- // rdb = get_bits(gbc, 2); /* number_of_raw_data_blocks_in_frame */
- // hdr->samples = (rdb + 1) * 1024;
- int samples = (aac.number_of_raw_data_blocks_in_frame + 1) * 1024;
- static int sample_rates[] = {
- 96000, 88200, 64000, 48000, 44100, 32000,
- 24000, 22050, 16000, 12000, 11025, 8000,
- 1, 1, 1, 1
- };
- int sample_rate = sample_rates[aac.sampling_frequency_index];
-
- dts += samples * 90000 / sample_rate;
- }
-
- trace("ts+aac+h264+data %s pts:%"PRId64" dts:%"PRId64" size: %d",
- (msg->type == TSPidTypeVideo)? "video":"audio", dts, dts, aac.frame_length);
-
- // TODO: process audio.
- }
- } else {
- trace("ts+aac+h264+data %s pts:%"PRId64" dts:%"PRId64" size: %d",
- (msg->type == TSPidTypeVideo)? "video":"audio", msg->pts,
- (msg->dts == 0)? msg->pts : msg->dts, msg->packet_data_size);
-
- // parse H264 video.
- bool first = true;
- while (p < last) {
- TSH264Codec h264;
- if ((ret = h264.parse(msg, last, p)) != 0) {
- return ret;
- }
- trace("ts+h264 video raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x",
- h264.size, h264.at(0), h264.at(1), h264.at(2), h264.at(3));
-
- // first?
- if (!first) {
- continue;
- }
- first = false;
-
- // TODO: process video.
-
- // directly check the sequence header for test_22m.flv
- if (h264.at(0) == 0x67 && h264.at(1) == 0x00 && h264.at(2) == 0x1f && h264.at(3) == 0xac) {
- trace("ts+h264 directly find the sequence header for test_22m.flv");
- }
- // 7.3.1 NAL unit syntax, hls-mpeg-ts-iso13818-1.pdf, page 44
- char* pp = (char*)h264.raw_data;
- int8_t nal_unit_type = *pp++;
- int8_t nal_ref_idc = (nal_unit_type >> 5) & 0x03;
- nal_unit_type &= 0x1f;
-
- msg->nal_ref_idc = nal_ref_idc;
- msg->nal_unit_type = nal_unit_type;
-
- if (nal_ref_idc != 0) {
- trace("ts+h264 got an SPS or PPS.");
- }
- if (nal_unit_type == 7) {
- trace("ts+h264 got an SPS.");
- } else if (nal_unit_type == 5) {
- trace("ts+h264 got an Coded slice of an IDR picture.");
- } else if (nal_unit_type == 8) {
- trace("ts+h264 got an PPS.");
- } else if (nal_unit_type == 9) {
- trace("ts+h264 got an Picture delimiter.");
- int8_t pic_type = *pp++;
- pic_type = (pic_type >> 6) & 0x07;
- if (pic_type == 0) {
- trace("ts+h264 got an I picture.");
- } else if (pic_type == 1) {
- trace("ts+h264 got an I,P picture.");
- } else if (pic_type == 2) {
- trace("ts+h264 got an I,P,B picture.");
- } else if (pic_type == 3) {
- trace("ts+h264 got an SI picture.");
- } else if (pic_type == 4) {
- trace("ts+h264 got an SI,SP picture.");
- } else if (pic_type == 5) {
- trace("ts+h264 got an I,SI picture.");
- } else if (pic_type == 6) {
- trace("ts+h264 got an I,SI,P,SP picture.");
- } else if (pic_type == 7) {
- trace("ts+h264 got an I,SI,P,SP,B picture.");
- }
- } else {
- trace("ts+h264 got an unknown unit type: %d.", nal_unit_type);
- }
- }
- }
-
- return ret;
- }
- int main(int argc, char** argv)
- {
- const char* file = "livestream-1347.ts";
- const char* output_aac_file = "output.aac";
- if (argc > 2) {
- file = argv[1];
- output_aac_file = argv[2];
- }
-
- int fd = open(file, O_RDONLY);
- AacMuxer aac_muxer;
-
- int ret = 0;
- if ((ret = aac_muxer.open(output_aac_file)) != 0) {
- trace("aac_muxer+open open flv file failed.");
- return ret;
- }
-
- trace("demuxer+read packet count offset T+0 T+1 T+2 T+3 T+x T+L2 T+L1 T+L0");
-
- TSContext ctx;
- for (int i = 0, offset = 0; ; i++) {
- u_int8_t ts_packet[TS_PACKET_SIZE];
- memset(ts_packet, 0, sizeof(ts_packet));
-
- int nread = read(fd, ts_packet, sizeof(ts_packet));
- if (nread == 0) {
- trace("demuxer+read got EOF, read completed, offset: %07d.", offset);
- break;
- }
- if (nread != TS_PACKET_SIZE) {
- trace("demuxer+read error to read ts packet. nread=%d", nread);
- break;
- }
- trace("demuxer+read packet %04d %07d 0x%02x 0x%02x 0x%02x 0x%02x ... 0x%02x 0x%02x 0x%02x",
- i, offset, ts_packet[0], ts_packet[1], ts_packet[2], ts_packet[3],
- ts_packet[TS_PACKET_SIZE - 3], ts_packet[TS_PACKET_SIZE - 2], ts_packet[TS_PACKET_SIZE - 1]);
-
- u_int8_t* p = ts_packet;
- u_int8_t* start = ts_packet;
- u_int8_t* last = ts_packet + TS_PACKET_SIZE;
-
- // maybe need to parse multiple times for the PES_packet_length(0) packets.
- while (p == start) {
- TSPacket pkt;
- TSMessage* msg = NULL;
- if ((ret = pkt.demux(&ctx, start, last, p, msg)) != 0) {
- trace("demuxer+read decode ts packet error. ret=%d", ret);
- return ret;
- }
-
- offset += nread;
- if (!msg) {
- continue;
- }
-
- if ((ret = consume(msg, &aac_muxer)) != 0) {
- trace("demuxer+consume parse and consume message failed. ret=%d", ret);
- return -1;
- }
-
- int64_t pts = msg->pts;
- int64_t dts = (msg->dts == 0)? msg->pts : msg->dts;
- int64_t pcr = msg->pcr;
- static int64_t last_pcr_dts = 0;
- trace("demuxer+report id=%d, type=%s, size=%d, dts=%d, pts=%d, cts=%d, pcr=%d, dts-pcr=%d, ref=%d, unit=%d, dts(diff-pcr)=%d",
- (int)ctx.ts_packet_count, (msg->type == TSPidTypeVideo)? "video":"audio",
- (int)msg->parsed_packet_size, (int)dts, (int)pts, (int)(pts - dts), (int)pcr, (int)(pcr? dts - pcr : 0),
- (int)msg->nal_ref_idc, (int)msg->nal_unit_type, (int)(pcr? dts - last_pcr_dts: 0));
- if (pcr > 0) {
- last_pcr_dts = dts;
- }
-
- srs_freep(msg);
- }
- }
-
- close(fd);
- return ret;
- }
|