//--------------------------------------------------------------------------- void File_Ttml::Read_Buffer_Continue() { #if MEDIAINFO_DEMUX Demux(Buffer, Buffer_Size, ContentType_MainStream); #endif //MEDIAINFO_DEMUX // Output #if MEDIAINFO_EVENTS for (; p; p=p->NextSiblingElement()) { //p if (!strcmp(p->Value(), "p")) { const char* Attribute; int64u DTS_Begin=(int64u)-1; Attribute=p->Attribute("begin"); if (Attribute) DTS_Begin=Ttml_str2timecode(Attribute); int64u DTS_End=(int64u)-1; Attribute=p->Attribute("end"); if (Attribute) DTS_End=Ttml_str2timecode(Attribute); Ztring Content; if (p->FirstChild()) Content.From_UTF8(p->FirstChild()->Value()); Frame_Count++; } } #endif MEDIAINFO_EVENTS Buffer_Offset=Buffer_Size; }
//--------------------------------------------------------------------------- void File_Sdp::Data_Parse() { Element_Name("Packet"); for (int8u Pos=0; Pos<5; Pos++) { if (FieldLines[Pos]) { Element_Code=FieldLines[Pos]; stream &Stream=Streams[FieldLines[Pos]]; if (Stream.Parser==NULL) { Stream.Parser=new File_Teletext(); Stream.Parser->IsSubtitle=true; Open_Buffer_Init(Stream.Parser); } if (Stream.Parser->PTS_DTS_Needed) Stream.Parser->FrameInfo=FrameInfo; Demux(Buffer+Buffer_Offset+Element_Offset, 45, ContentType_MainStream); Open_Buffer_Continue(Stream.Parser, Buffer+Buffer_Offset+Element_Offset, 45); Element_Offset+=45; } } Element_Begin1("SDP Footer"); Skip_B1( "Footer ID"); Skip_B2( "Footer Sequence number"); Skip_B2( "SDP Cheksum"); Skip_B2( "SMPTE 291 Cheksum"); Element_End0(); }
//--------------------------------------------------------------------------- void File_SubRip::Read_Buffer_Continue() { #if MEDIAINFO_DEMUX Demux(Buffer+(HasBOM?3:0), Buffer_Size-((HasBOM && Buffer_Size>=3)?3:0), ContentType_MainStream); #endif //MEDIAINFO_DEMUX Buffer_Offset=Buffer_Size; }
bool BufDemuxer::Demux(MpegPlayer& plyr) { io::stream& strm = *plyr.inpStrm; int cnt = strm.raw_read(rawBuf, ARR_SIZE(rawBuf)); // пока поток (файл) не закончился bool res = strm; if( res ) res = Demux((uint8_t*)rawBuf, (uint8_t*)rawBuf+cnt, plyr) ? false : true ; return res; }
//--------------------------------------------------------------------------- void File_Cdxa::Data_Parse() { if (MI==NULL) { //Where is the header? --> Problem Reject("CDXA"); return; } //CRC or not? int64u CRC_Size=4; if (Element_Size!=2328) CRC_Size=0; //Parsing Skip_XX(Element_Size-CRC_Size, "Data"); if (CRC_Size>0) Skip_B4( "CRC"); //Preparing to fill MediaInfo with a buffer MI->Open_Buffer_Position_Set(File_Offset+Buffer_Offset); //Sending the buffer to MediaInfo MI->Open_Buffer_Continue(Buffer+Buffer_Offset, (size_t)(Element_Size-CRC_Size)); //Testing if filled if (MI->Info->Status[IsFilled]) { } //Testing if MediaInfo always need data File_GoTo=MI->Open_Buffer_Continue_GoTo_Get(); if (File_GoTo==(int64u)-1 && MI->Info->Status[IsFilled] && File_Size!=(int64u)-1 && File_Offset+Buffer_Size<File_Size/2) GoToFromEnd(File_Offset+Buffer_Size); if (File_GoTo!=(int64u)-1) Info("CDXA, Jumping to end of file"); //Details #if MEDIAINFO_TRACE if (Config_Trace_Level) { if (!MI->Inform().empty()) Element_Show_Add(MI->Inform()); } #endif //MEDIAINFO_TRACE //Demux Demux(Buffer+Buffer_Offset, (size_t)(Element_Size-CRC_Size), ContentType_MainStream); }
//--------------------------------------------------------------------------- void File_Cdxa::Data_Parse() { if (MI==NULL) { //Where is the header? --> Problem Finnished(); return; } //CRC or not? int64u CRC_Size=4; if (Element_Size!=2328) CRC_Size=0; //Parsing Skip_XX(Element_Size-CRC_Size, "Data"); if (CRC_Size>0) Skip_B4( "CRC"); //Preparing to fill MediaInfo with a buffer MI->Open_Buffer_Init(File_Size, File_Offset+Buffer_Offset); //Sending the buffer to MediaInfo if (MI->Open_Buffer_Continue(Buffer+Buffer_Offset, (size_t)(Element_Size-CRC_Size))==0) Finnished(); //Get out of the loop, there was an error during the parsing //Testing if MediaInfo always need data File_GoTo=MI->Open_Buffer_Continue_GoTo_Get(); if (File_GoTo!=(int64u)-1) Info("CDXA, Jumping to end of file"); //Details #ifndef MEDIAINFO_MINIMIZESIZE if (Config.Details_Get()) { if (!MI->Inform().empty()) Element_Show_Add(MI->Inform()); } #endif //MEDIAINFO_MINIMIZESIZE //Demux Demux(Buffer+Buffer_Offset, (size_t)(Element_Size-CRC_Size), _T("xxx")); }
//--------------------------------------------------------------------------- void File_Mpeg4_Descriptors::Descriptor_05() { if (ObjectTypeId==0x00 && Parser==NULL) //If no ObjectTypeId detected { switch (KindOfStream) { case Stream_Video : #if defined(MEDIAINFO_MPEG4V_YES) delete Parser; Parser=new File_Mpeg4v; ((File_Mpeg4v*)Parser)->FrameIsAlwaysComplete=true; #endif break; case Stream_Audio : #if defined(MEDIAINFO_AAC_YES) delete Parser; Parser=new File_Aac; ((File_Aac*)Parser)->Mode=File_Aac::Mode_AudioSpecificConfig; #endif break; default: ; } Element_Code=(int64u)-1; Open_Buffer_Init(Parser); } if (Parser==NULL) { Skip_XX(Element_Size, "Unknown"); return; } //Parser configuration before the parsing switch (ObjectTypeId) { case 0x60 : case 0x61 : case 0x62 : case 0x63 : case 0x64 : case 0x65 : case 0x6A : //MPEG Video #if defined(MEDIAINFO_MPEGV_YES) ((File_Mpegv*)Parser)->TimeCodeIsNotTrustable=true; #endif break; default: ; } //Parsing Open_Buffer_Continue(Parser); //Demux #if MEDIAINFO_DEMUX if (ObjectTypeId!=0x21 || !Config->Demux_Avc_Transcode_Iso14496_15_to_Iso14496_10_Get()) //0x21 is AVC switch (Config->Demux_InitData_Get()) { case 0 : //In demux event Demux_Level=2; //Container Demux(Buffer+Buffer_Offset, (size_t)Element_Size, ContentType_Header); break; case 1 : //In field { std::string Data_Raw((const char*)(Buffer+Buffer_Offset), (size_t)Element_Size); std::string Data_Base64(Base64::encode(Data_Raw)); Parser->Fill(KindOfStream, PosOfStream, "Demux_InitBytes", Data_Base64); if (PosOfStream<(*Parser->Stream_More)[KindOfStream].size()) (*Parser->Stream_More)[KindOfStream][PosOfStream](Ztring().From_Local("Demux_InitBytes"), Info_Options)=__T("N NT"); } break; default : ; } #endif //MEDIAINFO_DEMUX //Parser configuration after the parsing switch (ObjectTypeId) { case 0x60 : case 0x61 : case 0x62 : case 0x63 : case 0x64 : case 0x65 : case 0x6A : //MPEG Video #if defined(MEDIAINFO_MPEGV_YES) ((File_Mpegv*)Parser)->TimeCodeIsNotTrustable=false; #endif break; default: ; } //Positionning Element_Offset=Element_Size; }
//--------------------------------------------------------------------------- void File_Ttml::Read_Buffer_Continue() { tinyxml2::XMLDocument document; if (!FileHeader_Begin_XML(document)) return; XMLElement* Root=document.FirstChildElement("tt"); if (!Root) { Reject(); return; } if (!Status[IsAccepted]) { Accept(); #if MEDIAINFO_EVENTS MuxingMode=(int8u)-1; if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mpeg4) MuxingMode=11; //MPEG-4 #endif MEDIAINFO_EVENTS } tinyxml2::XMLElement* div=NULL; #if MEDIAINFO_EVENTS tinyxml2::XMLElement* p=NULL; #endif //MEDIAINFO_EVENTS for (XMLElement* tt_element=Root->FirstChildElement(); tt_element; tt_element=tt_element->NextSiblingElement()) { //body if (!strcmp(tt_element->Value(), "body")) { for (XMLElement* body_element=tt_element->FirstChildElement(); body_element; body_element=body_element->NextSiblingElement()) { //div if (!strcmp(body_element->Value(), "div")) { for (XMLElement* div_element=body_element->FirstChildElement(); div_element; div_element=div_element->NextSiblingElement()) { //p if (!strcmp(div_element->Value(), "p")) { div=body_element; #if MEDIAINFO_EVENTS p=div_element; #endif //MEDIAINFO_EVENTS break; } } if (div) break; } } if (div) break; } } #if MEDIAINFO_DEMUX Demux(Buffer, Buffer_Size, ContentType_MainStream); #endif //MEDIAINFO_DEMUX // Output #if MEDIAINFO_EVENTS for (; p; p=p->NextSiblingElement()) { //p if (!strcmp(p->Value(), "p")) { const char* Attribute; int64u DTS_Begin=(int64u)-1; Attribute=p->Attribute("begin"); if (Attribute) DTS_Begin=Ttml_str2timecode(Attribute); int64u DTS_End=(int64u)-1; Attribute=p->Attribute("end"); if (Attribute) DTS_End=Ttml_str2timecode(Attribute); Ztring Content; if (p->FirstChild()) Content.From_UTF8(p->FirstChild()->Value()); Frame_Count++; } } #endif MEDIAINFO_EVENTS Buffer_Offset=Buffer_Size; }
//--------------------------------------------------------------------------- void File_Pcm_Vob::Read_Buffer_Continue() { if (Buffer_Size==0) return; //Parsing Skip_B1( "Frame number"); Skip_B2( "Bytes to skip (+1?)"); Skip_B1( "Unknown"); BS_Begin(); Get_S1 (2, BitDepth, "Bit depth"); Param_Info1(Pcm_VOB_BitDepth[BitDepth]); Get_S1 (2, Frequency, "Frequency"); Param_Info1(Pcm_VOB_Frequency[Frequency]); Skip_SB( "Unknown"); Get_S1 (3, NumberOfChannelsMinusOne, "Number of channels (minus 1)"); BS_End(); Skip_B1( "Start code"); #if MEDIAINFO_DEMUX if (Config->Demux_PCM_20bitTo16bit_Get() && BitDepth==1) //20-bit { int8u* Info=new int8u[(size_t)((Element_Size-6)*4/5)]; size_t Info_Offset=0; while (Element_Offset+5*(NumberOfChannelsMinusOne+1)<=Element_Size) { size_t Buffer_Pos=Buffer_Offset+(size_t)Element_Offset; std::memcpy(Info+Info_Offset, Buffer+Buffer_Pos, 4*(NumberOfChannelsMinusOne+1)); Info_Offset+=4*(NumberOfChannelsMinusOne+1); Element_Offset+=5*(NumberOfChannelsMinusOne+1); } Element_Offset=6; FrameInfo.PTS=FrameInfo.DTS; if (Pcm_VOB_Frequency[Frequency]) FrameInfo.DUR=(Element_Size-6)/5*1000000000/Pcm_VOB_Frequency[Frequency]; Demux_random_access=true; Element_Code=(int64u)-1; Demux(Info, Info_Offset, ContentType_MainStream); delete[] Info; } else { Demux_Offset=Buffer_Offset+(size_t)Element_Size; Buffer_Offset+=6; //Header is dropped Demux_UnpacketizeContainer_Demux(); Buffer_Offset-=6; } #endif //MEDIAINFO_DEMUX Skip_XX(Element_Size-6, "Data"); FILLING_BEGIN(); Frame_Count++; Frame_Count_InThisBlock++; if (Frame_Count_NotParsedIncluded!=(int64u)-1) Frame_Count_NotParsedIncluded++; if (FrameInfo.DTS!=(int64u)-1 && FrameInfo.DUR!=(int64u)-1) { FrameInfo.DTS+=FrameInfo.DUR; FrameInfo.PTS=FrameInfo.DTS; } if (!Status[IsAccepted]) { Accept(); Finish(); } FILLING_END(); }
//--------------------------------------------------------------------------- void File_Cdp::ccdata_section() { //Parsing int8u cc_count; Element_Begin1("ccdata_section"); Skip_B1( "ccdata_id"); BS_Begin(); Mark_1(); Mark_1(); Mark_1(); Get_S1 (5, cc_count, "cc_count"); BS_End(); for (int8u Pos=0; Pos<cc_count; Pos++) { Element_Begin1("cc"); int8u cc_type; bool cc_valid; BS_Begin(); Mark_1(); Mark_1(); Mark_1(); Mark_1(); Mark_1(); Get_SB ( cc_valid, "cc_valid"); Get_S1 (2, cc_type, "cc_type"); Param_Info1(Cdp_cc_type(cc_type)); BS_End(); if (cc_valid) { Element_Begin1("cc_data"); //Calculating the parser position int8u Parser_Pos=cc_type==3?2:cc_type; //cc_type 2 and 3 are for the same text //Parsing #if MEDIAINFO_DEMUX Element_Code=Parser_Pos; #endif //MEDIAINFO_DEMUX if (Streams[Parser_Pos]==NULL) Streams[Parser_Pos]=new stream; if (Streams[Parser_Pos]->Parser==NULL) { #if defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES) if (cc_type<2) { #if defined(MEDIAINFO_EIA608_YES) Streams[Parser_Pos]->Parser=new File_Eia608(); ((File_Eia608*)Streams[Parser_Pos]->Parser)->cc_type=cc_type; #else //defined(MEDIAINFO_EIA608_YES) Streams[Parser_Pos]->Parser=new File__Analyze(); #endif //defined(MEDIAINFO_EIA608_YES) } else { #if defined(MEDIAINFO_EIA708_YES) Streams[Parser_Pos]->Parser=new File_Eia708(); #else //defined(MEDIAINFO_EIA708_YES) Streams[Parser_Pos]->Parser=new File__Analyze(); #endif //defined(MEDIAINFO_EIA708_YES) } #else //defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES) Streams[Parser_Pos]->Parser=new File__Analyze(); #endif //defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES) Open_Buffer_Init(Streams[Parser_Pos]->Parser); } Demux(Buffer+(size_t)(Buffer_Offset+Element_Offset), 2, ContentType_MainStream); if (!Streams[Parser_Pos]->Parser->Status[IsFinished]) { if (Streams[Parser_Pos]->Parser->PTS_DTS_Needed) { Streams[Parser_Pos]->Parser->FrameInfo.PCR=FrameInfo.PCR; Streams[Parser_Pos]->Parser->FrameInfo.PTS=FrameInfo.PTS; Streams[Parser_Pos]->Parser->FrameInfo.DTS=FrameInfo.DTS; } if (Parser_Pos==2) { #if defined(MEDIAINFO_EIA708_YES) ((File_Eia708*)Streams[2]->Parser)->cc_type=cc_type; if (AspectRatio) ((File_Eia708*)Streams[2]->Parser)->AspectRatio=AspectRatio; #endif //defined(MEDIAINFO_EIA708_YES) } Open_Buffer_Continue(Streams[Parser_Pos]->Parser, Buffer+(size_t)(Buffer_Offset+Element_Offset), 2); Element_Offset+=2; //Filled if (!Streams[Parser_Pos]->IsFilled && Streams[Parser_Pos]->Parser->Status[IsFilled]) { if (Count_Get(Stream_General)==0) Accept("CDP"); Streams_Count++; if (Streams_Count==3) Fill("CDP"); Streams[Parser_Pos]->IsFilled=true; } } else Skip_XX(2, "Data"); Element_End0(); } else Skip_XX(2, "Junk"); Element_End0(); } Element_End0(); Frame_Count++; Frame_Count_InThisBlock++; if (Frame_Count_NotParsedIncluded!=(int64u)-1) Frame_Count_NotParsedIncluded++; }
//--------------------------------------------------------------------------- void File_DtvccTransport::Read_Buffer_Continue() { //Parsing Element_Begin1(Format==Format_DVD?"DVD Captions":"DTVCC Transport"); int8u cc_count; bool process_cc_data_flag, additional_data_flag; BS_Begin(); if (Format==Format_DVD) { //Modified DTVCC Transport from DVD Skip_SB( "field 1 then field 2"); Get_S1 (7, cc_count, "cc_count"); process_cc_data_flag=true; additional_data_flag=false; } else { //Normal DTVCC Transport bool process_em_data_flag; Get_SB (process_em_data_flag, "process_em_data_flag"); Get_SB (process_cc_data_flag, "process_cc_data_flag"); Get_SB (additional_data_flag, "additional_data_flag"); Get_S1 (5, cc_count, "cc_count"); Skip_S1(8, process_em_data_flag?"em_data":"reserved"); //Emergency message } BS_End(); if (process_cc_data_flag) { for (int8u Pos=0; Pos<cc_count; Pos++) { if (Element_Offset+3>Element_Size) break; //Found one stream with bad cc_count, we discard cc_count without flagging the stream as untrusted for the moment Element_Begin1("cc"); int8u cc_type; bool cc_valid; BS_Begin(); Mark_1(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); if (Format==Format_DVD) { //Modified DTVCC Transport from DVD Mark_1(); Mark_1(); Get_S1 (1, cc_type, "cc_type"); Param_Info1(DtvccTransport_cc_type(cc_type)); cc_valid=true; } else { //Normal DTVCC Transport Get_SB ( cc_valid, "cc_valid"); Get_S1 (2, cc_type, "cc_type"); Param_Info1(DtvccTransport_cc_type(cc_type)); } BS_End(); #if MEDIAINFO_ADVANCED if (cc_type>=2 && !Streams[2] && Config->File_Eia708_DisplayEmptyStream_Get()) CreateStream(2); #endif //MEDIAINFO_ADVANCED if (cc_valid) { Element_Begin1("cc_data"); //Calculating the parser position int8u Parser_Pos=cc_type==3?2:cc_type; //cc_type 2 and 3 are for the same text //Stream creation if (Streams[Parser_Pos]==NULL) CreateStream(Parser_Pos); //Parsing #if MEDIAINFO_DEMUX Element_Code=Parser_Pos; Demux(Buffer+(size_t)(Buffer_Offset+Element_Offset), 2, ContentType_MainStream); #endif //MEDIAINFO_DEMUX if (!Streams[Parser_Pos]->Parser->Status[IsFinished]) { //Parsing if (Streams[Parser_Pos]->Parser->PTS_DTS_Needed) { Streams[Parser_Pos]->Parser->FrameInfo.PCR=FrameInfo.PCR; Streams[Parser_Pos]->Parser->FrameInfo.PTS=FrameInfo.PTS; Streams[Parser_Pos]->Parser->FrameInfo.DTS=FrameInfo.DTS; } if (Parser_Pos==2) { #if defined(MEDIAINFO_EIA708_YES) ((File_Eia708*)Streams[2]->Parser)->cc_type=cc_type; if (AspectRatio) ((File_Eia708*)Streams[2]->Parser)->AspectRatio=AspectRatio; #endif if (cc_type==3) { ((File_Eia708*)Streams[2]->Parser)->cc_type=4; //Magic value saying that the buffer must be kept (this is only a point of synchro from the undelying layer) Open_Buffer_Continue(Streams[Parser_Pos]->Parser, Buffer+(size_t)(Buffer_Offset+Element_Offset), 0); ((File_Eia708*)Streams[2]->Parser)->cc_type=3; } } else { } #if defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES) Streams[Parser_Pos]->Parser->ServiceDescriptors=ServiceDescriptors; #endif Open_Buffer_Continue(Streams[Parser_Pos]->Parser, Buffer+(size_t)(Buffer_Offset+Element_Offset), 2); Element_Show(); Element_Offset+=2; } else Skip_XX(2, "Data"); Element_End0(); } else Skip_XX(2, "Junk"); Element_End0(); } FILLING_BEGIN(); if (!Status[IsAccepted]) Accept("DTVCC Transport"); FILLING_END(); } else Skip_XX(cc_count*2, "Junk"); if (Format==Format_A53_4_GA94_03) { //Normal DTVCC Transport BS_Begin(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); BS_End(); if (additional_data_flag) { Skip_XX(Element_Size-Element_Offset, "additional_user_data"); } while (Element_Offset<Element_Size) { Skip_B1( "Zero"); //TODO: test Zero } } Element_End0(); }
//--------------------------------------------------------------------------- void File_Ancillary::Read_Buffer_Continue() { if (!Cdp_Data.empty() && AspectRatio && FrameRate) { ((File_Cdp*)Cdp_Parser)->AspectRatio=AspectRatio; for (size_t Pos=0; Pos<Cdp_Data.size(); Pos++) { if (Cdp_Parser->PTS_DTS_Needed) Cdp_Parser->FrameInfo.DTS=FrameInfo.DTS-(Cdp_Data.size()-Pos)*FrameInfo.DUR; Open_Buffer_Continue(Cdp_Parser, Cdp_Data[Pos]->Data, Cdp_Data[Pos]->Size); delete Cdp_Data[Pos]; //Cdp_Data[0]=NULL; } Cdp_Data.clear(); } if (Element_Size==0) { //Keeping only one, TODO: parse it without video stream for (size_t Pos=1; Pos<AfdBarData_Data.size(); Pos++) delete AfdBarData_Data[Pos]; //AfdBarData_Data[0]=NULL; if (!AfdBarData_Data.empty()) AfdBarData_Data.resize(1); return; } if (!Status[IsAccepted]) Accept(); //Parsing int8u DataID, SecondaryDataID, DataCount; Get_L1 (DataID, "Data ID"); if (WithTenBit) Skip_L1( "Parity+Unused"); //even:1, odd:2 Get_L1 (SecondaryDataID, "Secondary Data ID"); Param_Info(Ancillary_DataID(DataID, SecondaryDataID)); if (WithTenBit) Skip_L1( "Parity+Unused"); //even:1, odd:2 Get_L1 (DataCount, "Data count"); if (WithTenBit) Skip_L1( "Parity+Unused"); //even:1, odd:2 //Buffer int8u* Payload=new int8u[DataCount]; for(int8u Pos=0; Pos<DataCount; Pos++) { Get_L1 (Payload[Pos], "Data"); if (WithTenBit) Skip_L1( "Parity+Unused"); //even:1, odd:2 } //Parsing if (WithChecksum) Skip_L1( "Checksum"); if (WithTenBit) Skip_L1( "Parity+Unused"); //even:1, odd:2 Element_End(); FILLING_BEGIN(); switch (DataID) { case 0x41 : // (from SMPTE 2016-3) switch (SecondaryDataID) { case 0x05 : //Bar Data (from SMPTE 2016-3), saving data for future use #if defined(MEDIAINFO_AFDBARDATA_YES) { buffered_data* AfdBarData=new buffered_data; AfdBarData->Data=new int8u[(size_t)DataCount]; std::memcpy(AfdBarData->Data, Payload, (size_t)DataCount); AfdBarData->Size=(size_t)DataCount; AfdBarData_Data.push_back(AfdBarData); } #endif //MEDIAINFO_AFDBARDATA_YES break; default : ; ; } break; case 0x45 : // (from SMPTE 2020-1) switch (SecondaryDataID) { case 0x01 : //No association case 0x02 : //Channel pair 1/2 case 0x03 : //Channel pair 3/4 case 0x04 : //Channel pair 5/6 case 0x05 : //Channel pair 7/8 case 0x06 : //Channel pair 9/10 case 0x07 : //Channel pair 11/12 case 0x08 : //Channel pair 13/14 case 0x09 : //Channel pair 15/16 break; default : ; ; } break; case 0x61 : //Defined data services (from SMPTE 331-1) switch (SecondaryDataID) { case 0x01 : //CDP (from SMPTE 331-1) #if defined(MEDIAINFO_CDP_YES) { if (Cdp_Parser==NULL) { Cdp_Parser=new File_Cdp; Open_Buffer_Init(Cdp_Parser); } Demux(Payload, (size_t)DataCount, ContentType_MainStream); if (AspectRatio && FrameRate) { if (!Cdp_Parser->Status[IsFinished]) { if (Cdp_Parser->PTS_DTS_Needed) Cdp_Parser->FrameInfo.DTS=FrameInfo.DTS; ((File_Cdp*)Cdp_Parser)->AspectRatio=AspectRatio; Open_Buffer_Continue(Cdp_Parser, Payload, (size_t)DataCount); } } else { //Saving data for future use buffered_data* Cdp=new buffered_data; Cdp->Data=new int8u[(size_t)DataCount]; std::memcpy(Cdp->Data, Payload, (size_t)DataCount); Cdp->Size=(size_t)DataCount; Cdp_Data.push_back(Cdp); } } #endif //MEDIAINFO_CDP_YES break; case 0x02 : //CEA-608 (from SMPTE 331-1) #if defined(MEDIAINFO_EIA608_YES) if (DataCount==3) //This must be 3-byte data { //CEA-608 in video presentation order } #endif //MEDIAINFO_EIA608_YES break; default : ; ; } break; case 0x62 : //Variable-format data services (from SMPTE 331-1) switch (SecondaryDataID) { case 0x01 : //Program description (from SMPTE 331-1), break; case 0x02 : //Data broadcast (from SMPTE 331-1) break; case 0x03 : //VBI data (from SMPTE 331-1) break; default : ; ; } break; default : ; } FILLING_END(); delete[] Payload; //Payload=NULL }
//--------------------------------------------------------------------------- void File_Ttml::Read_Buffer_Continue() { tinyxml2::XMLDocument document; if (!FileHeader_Begin_XML(document)) return; XMLElement* Root=document.FirstChildElement("tt"); if (!Root) { Reject(); return; } if (!Status[IsAccepted]) { Accept(); #if MEDIAINFO_EVENTS MuxingMode=(int8u)-1; if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mpeg4) MuxingMode=11; //MPEG-4 if (StreamIDs_Size>2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mxf) //Only if referenced MXF MuxingMode=13; //MXF #endif //MEDIAINFO_EVENTS #if MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET if (Config->NextPacket_Get() && Config->Event_CallBackFunction_IsSet()) return; // Waiting for NextPacket #endif //MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET } tinyxml2::XMLElement* div=NULL; #if MEDIAINFO_EVENTS tinyxml2::XMLElement* p=NULL; #endif //MEDIAINFO_EVENTS for (XMLElement* tt_element=Root->FirstChildElement(); tt_element; tt_element=tt_element->NextSiblingElement()) { //body if (!strcmp(tt_element->Value(), "body")) { for (XMLElement* body_element=tt_element->FirstChildElement(); body_element; body_element=body_element->NextSiblingElement()) { //div if (!strcmp(body_element->Value(), "div")) { for (XMLElement* div_element=body_element->FirstChildElement(); div_element; div_element=div_element->NextSiblingElement()) { //p if (!strcmp(div_element->Value(), "p")) { div=body_element; #if MEDIAINFO_EVENTS p=div_element; #endif //MEDIAINFO_EVENTS break; } } if (div) break; } } if (div) break; } } #if MEDIAINFO_DEMUX Demux(Buffer, Buffer_Size, ContentType_MainStream); #endif //MEDIAINFO_DEMUX // Output #if MEDIAINFO_EVENTS for (; p; p=p->NextSiblingElement()) { //p if (!strcmp(p->Value(), "p")) { int64u DTS_Begin=(int64u)-1; const char* Attribute=p->Attribute("begin"); if (Attribute) DTS_Begin=Ttml_str2timecode(Attribute); int64u DTS_End=(int64u)-1; Attribute=p->Attribute("end"); if (Attribute) DTS_End=Ttml_str2timecode(Attribute); string ContentUtf8; XMLPrinter printer; p->Accept(&printer); ContentUtf8+=printer.CStr(); while (!ContentUtf8.empty() && (ContentUtf8[ContentUtf8.size()-1]=='\r' || ContentUtf8[ContentUtf8.size()-1]=='\n')) ContentUtf8.resize(ContentUtf8.size()-1); Ztring Content; Content.From_UTF8(ContentUtf8.c_str()); Frame_Count_NotParsedIncluded=Frame_Count; EVENT_BEGIN (Global, SimpleText, 0) //Hack: remove "p", "span", "br" Content.FindAndReplace(__T("\r"), Ztring(), 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("\n"), Ztring(), 0, ZenLib::Ztring_Recursive); for (;;) { size_t Span_Begin=Content.find(__T("<p")); if (Span_Begin==string::npos) break; size_t Span_End=Content.find(__T(">"), Span_Begin+5); if (Span_End==string::npos) break; size_t ShlashSpan_Begin=Content.find(__T("</p>"), Span_End+1); if (ShlashSpan_Begin==string::npos) break; Content.erase(ShlashSpan_Begin, 7); Content.erase(Span_Begin, Span_End-Span_Begin+1); } for (;;) { size_t Span_Begin=Content.find(__T("<span")); if (Span_Begin==string::npos) break; size_t Span_End=Content.find(__T(">"), Span_Begin+5); if (Span_End==string::npos) break; size_t ShlashSpan_Begin=Content.find(__T("</span>"), Span_End+1); if (ShlashSpan_Begin==string::npos) break; Content.erase(ShlashSpan_Begin, 7); Content.erase(Span_Begin, Span_End-Span_Begin+1); } Content.FindAndReplace(__T("<br>"), EOL, 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("<br/>"), EOL, 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("<br />"), EOL, 0, ZenLib::Ztring_Recursive); Event.DTS=DTS_Begin; Event.PTS=Event.DTS; Event.DUR=DTS_End-DTS_Begin; Event.Content=Content.c_str(); Event.Flags=0; Event.MuxingMode=MuxingMode; Event.Service=(int8u)Element_Code; Event.Row_Max=0; Event.Column_Max=0; Event.Row_Values=NULL; Event.Row_Attributes=NULL; EVENT_END () EVENT_BEGIN (Global, SimpleText, 0) Event.DTS=DTS_End; Event.PTS=Event.DTS; Event.DUR=0; Event.Content=__T(""); Event.Flags=0; Event.MuxingMode=MuxingMode; Event.Service=(int8u)Element_Code; Event.Row_Max=0; Event.Column_Max=0; Event.Row_Values=NULL; Event.Row_Attributes=NULL; EVENT_END () Frame_Count++; } } #endif //MEDIAINFO_EVENTS Buffer_Offset=Buffer_Size; }
//--------------------------------------------------------------------------- void File_ChannelGrouping::Read_Buffer_Continue() { //Handling of multiple frames in one block if (Buffer_Size-Buffer_Offset_AlreadyInCommon==0) { if (Common->Parser && Common->Parser->Buffer_Size) Open_Buffer_Continue(Common->Parser, Common->MergedChannel.Buffer+Common->MergedChannel.Buffer_Offset, 0); Element_WaitForMoreData(); return; } //If basic PCM is already detected if (Common->IsPcm) { if (Buffer_Size==Buffer_Offset_AlreadyInCommon) { Element_WaitForMoreData(); return; } Buffer_Offset_AlreadyInCommon=0; #if MEDIAINFO_DEMUX Demux_Level=2; //Container Demux_Offset=Buffer_Size; FrameInfo.PTS=FrameInfo.DTS; if (IsPcm_Frame_Count) FrameInfo.DUR*=IsPcm_Frame_Count+1; Demux_UnpacketizeContainer_Demux(); #endif //MEDIAINFO_DEMUX Skip_XX(Element_Size, "Data"); if (IsPcm_Frame_Count) { Frame_Count+=IsPcm_Frame_Count; IsPcm_Frame_Count=0; } Frame_Count++; if (!Status[IsFilled]) { Finish(); } return; } else if (Buffer_Size && Buffer_Size>Buffer_Offset_AlreadyInCommon && !Common->IsAes3) IsPcm_Frame_Count++; //Demux #if MEDIAINFO_DEMUX if (Demux_UnpacketizeContainer) { Common->Parser->Demux_UnpacketizeContainer=true; Common->Parser->Demux_Level=2; //Container Demux_Level=4; //Intermediate } Demux(Common->MergedChannel.Buffer+Common->MergedChannel.Buffer_Offset, Common->MergedChannel.Buffer_Size-Common->MergedChannel.Buffer_Offset, ContentType_MainStream); #endif //MEDIAINFO_EVENTS //Copying to Channel buffer if (Common->Channels[Channel_Pos]->Buffer_Size+Buffer_Size-Buffer_Offset_AlreadyInCommon>Common->Channels[Channel_Pos]->Buffer_Size_Max) Common->Channels[Channel_Pos]->resize(Common->Channels[Channel_Pos]->Buffer_Size+Buffer_Size-Buffer_Offset_AlreadyInCommon); memcpy(Common->Channels[Channel_Pos]->Buffer+Common->Channels[Channel_Pos]->Buffer_Size, Buffer+Buffer_Offset_AlreadyInCommon, Buffer_Size-Buffer_Offset_AlreadyInCommon); Common->Channels[Channel_Pos]->Buffer_Size+=Buffer_Size-Buffer_Offset_AlreadyInCommon; if (!Common->IsAes3) Buffer_Offset_AlreadyInCommon=Buffer_Size; else Buffer_Offset_AlreadyInCommon=0; Common->Channel_Current++; if (Common->Channel_Current>=Channel_Total) Common->Channel_Current=0; //Copying to merged channel size_t Minimum=(size_t)-1; for (size_t Pos=0; Pos<Common->Channels.size(); Pos++) if (Minimum>Common->Channels[Pos]->Buffer_Size-Common->Channels[Pos]->Buffer_Offset) Minimum=Common->Channels[Pos]->Buffer_Size-Common->Channels[Pos]->Buffer_Offset; while (Minimum>=ByteDepth) { for (size_t Pos=0; Pos<Common->Channels.size(); Pos++) { if (Common->MergedChannel.Buffer_Size+Minimum>Common->MergedChannel.Buffer_Size_Max) Common->MergedChannel.resize(Common->MergedChannel.Buffer_Size+Minimum); memcpy(Common->MergedChannel.Buffer+Common->MergedChannel.Buffer_Size, Common->Channels[Pos]->Buffer+Common->Channels[Pos]->Buffer_Offset, ByteDepth); Common->Channels[Pos]->Buffer_Offset+=ByteDepth; Common->MergedChannel.Buffer_Size+=ByteDepth; } Minimum-=ByteDepth; } if (Common->MergedChannel.Buffer_Size-Common->MergedChannel.Buffer_Offset) { if (FrameInfo_Next.DTS!=(int64u)-1) Common->Parser->FrameInfo=FrameInfo_Next; //AES3 parse has its own buffer management else Common->Parser->FrameInfo=FrameInfo; Open_Buffer_Continue(Common->Parser, Common->MergedChannel.Buffer+Common->MergedChannel.Buffer_Offset, Common->MergedChannel.Buffer_Size-Common->MergedChannel.Buffer_Offset); Common->MergedChannel.Buffer_Offset=Common->MergedChannel.Buffer_Size; } if (!Common->IsAes3) { if (!Status[IsFilled] && Common->Parser->Status[IsAccepted]) { if (Common->Parser->Get(Stream_Audio, 0, Audio_Format)==_T("PCM")) Common->IsPcm=true; else { Common->IsAes3=true; if (Common->Channel_Master==(size_t)-1) Common->Channel_Master=Channel_Pos; Buffer_Offset_AlreadyInCommon=0; Fill(); } } else if (Common->MergedChannel.Buffer_Size==0 && IsPcm_Frame_Count>=2) Common->IsPcm=true; } if (Common->IsAes3) Buffer_Offset=Buffer_Size; else Element_WaitForMoreData(); if (Common->Parser->Status[IsFinished]) Finish(); //Optimize buffer for (size_t Pos=0; Pos<Common->Channels.size(); Pos++) Common->Channels[Pos]->optimize(); Common->MergedChannel.optimize(); }
//--------------------------------------------------------------------------- void File_DtvccTransport::Read_Buffer_Continue() { //Parsing Element_Begin(Format==Format_DVD?"DVD Captions":"DTVCC Transport"); int8u cc_count; bool process_cc_data_flag, additional_data_flag; BS_Begin(); if (Format==Format_DVD) { //Modified DTVCC Transport from DVD Skip_SB( "field 1 then field 2"); Get_S1 (7, cc_count, "cc_count"); process_cc_data_flag=true; additional_data_flag=false; } else { //Normal DTVCC Transport bool process_em_data_flag; Get_SB (process_em_data_flag, "process_em_data_flag"); Get_SB (process_cc_data_flag, "process_cc_data_flag"); Get_SB (additional_data_flag, "additional_data_flag"); Get_S1 (5, cc_count, "cc_count"); Skip_S1(8, process_em_data_flag?"em_data":"reserved"); //Emergency message } BS_End(); if (process_cc_data_flag) { for (int8u Pos=0; Pos<cc_count; Pos++) { Element_Begin("cc"); int8u cc_type; bool cc_valid; BS_Begin(); Mark_1(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); if (Format==Format_DVD) { //Modified DTVCC Transport from DVD Mark_1(); Mark_1(); Get_S1 (1, cc_type, "cc_type"); Param_Info(DtvccTransport_cc_type(cc_type)); cc_valid=true; } else { //Normal DTVCC Transport Get_SB ( cc_valid, "cc_valid"); Get_S1 (2, cc_type, "cc_type"); Param_Info(DtvccTransport_cc_type(cc_type)); } BS_End(); if (cc_valid) { Element_Begin("cc_data"); //Calculating the parser position int8u Parser_Pos=cc_type==3?2:cc_type; //cc_type 2 and 3 are for the same text //Parsing #if MEDIAINFO_DEMUX Element_Code=Parser_Pos; #endif //MEDIAINFO_DEMUX if (Streams[Parser_Pos]==NULL) Streams[Parser_Pos]=new stream; if (Streams[Parser_Pos]->Parser==NULL) { if (cc_type<2) { #if defined(MEDIAINFO_EIA608_YES) Streams[Parser_Pos]->Parser=new File_Eia608(); #else Streams[Parser_Pos]->Parser=new File__Analyze(); #endif } else { #if defined(MEDIAINFO_EIA708_YES) Streams[Parser_Pos]->Parser=new File_Eia708(); #else Streams[Parser_Pos]->Parser=new File__Analyze(); #endif } Open_Buffer_Init(Streams[Parser_Pos]->Parser); } Demux(Buffer+(size_t)(Buffer_Offset+Element_Offset), 2, ContentType_MainStream); if (!Streams[Parser_Pos]->Parser->Status[IsFinished]) { //Parsing if (Streams[Parser_Pos]->Parser->PTS_DTS_Needed) { Streams[Parser_Pos]->Parser->FrameInfo.PCR=FrameInfo.PCR; Streams[Parser_Pos]->Parser->FrameInfo.PTS=FrameInfo.PTS; Streams[Parser_Pos]->Parser->FrameInfo.DTS=FrameInfo.DTS; } if (Parser_Pos==2) { #if defined(MEDIAINFO_EIA708_YES) ((File_Eia708*)Streams[2]->Parser)->cc_type=cc_type; ((File_Eia708*)Streams[2]->Parser)->AspectRatio=AspectRatio; #endif if (cc_type==3) Streams[2]->Parser->Open_Buffer_Unsynch(); } else { } Open_Buffer_Continue(Streams[Parser_Pos]->Parser, Buffer+(size_t)(Buffer_Offset+Element_Offset), 2); Element_Show(); Element_Offset+=2; //Filled if (!Streams[Parser_Pos]->IsFilled && Streams[Parser_Pos]->Parser->Status[IsFilled]) { if (Count_Get(Stream_General)==0) Accept("DTVCC Transport"); Streams_Count++; if (Streams_Count==3) Fill("DTVCC Transport"); Streams[Parser_Pos]->IsFilled=true; } } else Skip_XX(2, "Data"); Element_End(); } else Skip_XX(2, "Junk"); Element_End(); } } else Skip_XX(cc_count*2, "Junk"); if (Format==Format_A53_4_GA94_03) { //Normal DTVCC Transport BS_Begin(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); BS_End(); if (additional_data_flag) { Skip_XX(Element_Size-Element_Offset, "additional_user_data"); } while (Element_Offset<Element_Size) { Skip_B1( "Zero"); //TODO: test Zero } } Element_End(); }