/* Copyright (c) MediaArea.net SARL. All Rights Reserved. * * Use of this source code is governed by a BSD-style license that can * be found in the License.html file in the root of the source tree. */ //--------------------------------------------------------------------------- // Pre-compilation #include "MediaInfo/PreComp.h" #ifdef __BORLANDC__ #pragma hdrstop #endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Setup.h" //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #if defined(MEDIAINFO_DVBSUBTITLE_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Text/File_DvbSubtitle.h" #include "MediaInfo/MediaInfo_Config_MediaInfo.h" //--------------------------------------------------------------------------- namespace MediaInfoLib { //*************************************************************************** // Info //*************************************************************************** static const int8u DvbSubtitle_region_depth[8]= { 0, 2, 4, 8, 0, 0, 0, 0, }; //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_DvbSubtitle::File_DvbSubtitle() :File__Analyze() { //Configuration ParserName="DVB Subtitle"; #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_DvbSubtitle; #endif //MEDIAINFO_EVENTS #if MEDIAINFO_TRACE Trace_Layers_Update(8); //Stream #endif //MEDIAINFO_TRACE PTS_DTS_Needed=true; StreamSource=IsStream; MustSynchronize=true; //In Frame_Count_Valid=0; //Temp MustFindDvbHeader=true; } //--------------------------------------------------------------------------- File_DvbSubtitle::~File_DvbSubtitle() { } //*************************************************************************** // Streams management //*************************************************************************** //--------------------------------------------------------------------------- void File_DvbSubtitle::Streams_Fill() { Stream_Prepare(Stream_Text); Fill(Stream_Text, 0, Text_Format, "DVB Subtitle"); for (std::map::iterator subtitle_stream=subtitle_streams.begin(); subtitle_stream!=subtitle_streams.end(); ++subtitle_stream) for (std::map::iterator page=subtitle_stream->second.pages.begin(); page!=subtitle_stream->second.pages.end(); ++page) for (std::map::iterator region=page->second.regions.begin(); region!=page->second.regions.end(); ++region) { Fill(Stream_Text, 0, "subtitle_stream_id", subtitle_stream->first); Fill_SetOptions(Stream_Text, 0, "subtitle_stream_id", "N NI"); Fill(Stream_Text, 0, "page_id", page->first); Fill_SetOptions(Stream_Text, 0, "page_id", "N NI"); Fill(Stream_Text, 0, "region_id", region->first); Fill_SetOptions(Stream_Text, 0, "region_id", "N NI"); Fill(Stream_Text, 0, "region_horizontal_address", region->second.page_composition_segment?Ztring::ToZtring(region->second.region_horizontal_address):Ztring()); Fill_SetOptions(Stream_Text, 0, "region_horizontal_address", "N NI"); Fill(Stream_Text, 0, "region_vertical_address", region->second.page_composition_segment?Ztring::ToZtring(region->second.region_vertical_address):Ztring()); Fill_SetOptions(Stream_Text, 0, "region_vertical_address", "N NI"); Fill(Stream_Text, 0, "region_width", region->second.region_composition_segment?Ztring::ToZtring(region->second.region_width):Ztring()); Fill_SetOptions(Stream_Text, 0, "region_width", "N NI"); Fill(Stream_Text, 0, "region_height", region->second.region_composition_segment?Ztring::ToZtring(region->second.region_height):Ztring()); Fill_SetOptions(Stream_Text, 0, "region_height", "N NI"); Fill(Stream_Text, 0, "region_depth", region->second.region_composition_segment?Ztring::ToZtring(DvbSubtitle_region_depth[region->second.region_depth]):Ztring()); Fill_SetOptions(Stream_Text, 0, "region_depth", "N NI"); } } //--------------------------------------------------------------------------- void File_DvbSubtitle::Streams_Finish() { } //*************************************************************************** // Buffer - Synchro //*************************************************************************** //--------------------------------------------------------------------------- bool File_DvbSubtitle::Synchronize() { //Synchronizing if (MustFindDvbHeader) { while(Buffer_Offset+3<=Buffer_Size) { if (Buffer[Buffer_Offset]==0x20 && Buffer[Buffer_Offset+1]==0x00 && (Buffer[Buffer_Offset+2]==0x0F || Buffer[Buffer_Offset+1]==0xFF)) break; Buffer_Offset++; } if (Buffer_Offset+3>Buffer_Size) return false; Accept(); } else { while(Buffer_Offset=Buffer_Size) return false; } //Synched is OK Synched=true; if (!Frame_Count_Valid) Frame_Count_Valid=Config->ParseSpeed>=0.3?32:2; return true; } //--------------------------------------------------------------------------- bool File_DvbSubtitle::Synched_Test() { if (MustFindDvbHeader) { //Must have enough buffer for having header if (Buffer_Offset+1>Buffer_Size) return false; if (CC2(Buffer+Buffer_Offset)!=0x2000) { Synched=false; return true; } //Displaying it Element_Size=2; Skip_B1( "data_identifier"); Get_B1 (subtitle_stream_id, "subtitle_stream_id"); Buffer_Offset+=2; MustFindDvbHeader=false; } //Must have enough buffer for having header if (Buffer_Offset+1>Buffer_Size) return false; //Quick test of synchro if (Buffer[Buffer_Offset]!=0x0F && Buffer[Buffer_Offset]!=0xFF) { Synched=false; return true; } //We continue return true; } //--------------------------------------------------------------------------- void File_DvbSubtitle::Read_Buffer_Unsynched() { MustParseTheHeaderFile=true; Synched=false; } //*************************************************************************** // Buffer - Demux //*************************************************************************** //--------------------------------------------------------------------------- #if MEDIAINFO_DEMUX bool File_DvbSubtitle::Demux_UnpacketizeContainer_Test() { if (Demux_Offset==0) { Demux_Offset=Buffer_Offset; } while (Demux_OffsetBuffer_Size) return false; //No complete frame int16u segment_length=BigEndian2int16u(Buffer+Demux_Offset+4); Demux_Offset+=6+segment_length; if (Demux_Offset>=Buffer_Size) return false; //No complete frame } if (Demux_Offset>=Buffer_Size) return false; //No complete frame Demux_UnpacketizeContainer_Demux(); Demux_TotalBytes++; //0xFF is not demuxed return true; } #endif //MEDIAINFO_DEMUX //*************************************************************************** // Buffer - Per element //*************************************************************************** //--------------------------------------------------------------------------- void File_DvbSubtitle::Header_Parse() { //Parsing int8u sync_byte; Get_B1 (sync_byte, "sync_byte"); switch (sync_byte) { case 0xFF : //Stuffing MustFindDvbHeader=true; //Filling Header_Fill_Code(0xFF, "end of PES data field marker"); Header_Fill_Size(1); return; default : ; //Normal (0x0F) } int16u segment_length; int8u segment_type; Get_B1 (segment_type, "segment_type"); Get_B2 (page_id, "page_id"); Get_B2 (segment_length, "segment_length"); //Filling Header_Fill_Code(segment_type); Header_Fill_Size(Element_Offset+segment_length); } //--------------------------------------------------------------------------- void File_DvbSubtitle::Data_Parse() { switch (Element_Code) { case 0x10 : page_composition_segment(); break; case 0x11 : region_composition_segment(); break; case 0x12 : CLUT_definition_segment(); break; case 0x13 : object_data_segment(); break; case 0x14 : display_definition_segment(); break; case 0x80 : end_of_display_set_segment(); break; case 0xFF : end_of_PES_data_field_marker(); return; default : if (Element_Code>=0x40 && Element_Code<=0x7F) reserved_for_future_use(); else if (Element_Code>=0x81 && Element_Code<=0xEF) private_data(); else if (Element_Size) Skip_XX(Element_Size, "Unknown"); } } //*************************************************************************** // Elements //*************************************************************************** //--------------------------------------------------------------------------- void File_DvbSubtitle::page_composition_segment() { Element_Name("page composition segment"); //Parsing Skip_B1( "page_time_out"); BS_Begin(); Skip_S1(4, "page_version_number"); Skip_S1(2, "page_state"); Skip_S1(2, "reserved"); BS_End(); while(Element_OffsetFrame_Count_Valid) { Fill(); Finish(); } } //*************************************************************************** // C++ //*************************************************************************** } //NameSpace #endif //MEDIAINFO_DVBSUBTITLE_YES