/* 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_EIA708_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Text/File_Eia708.h" #include "MediaInfo/MediaInfo_Config_MediaInfo.h" #if MEDIAINFO_EVENTS #include "MediaInfo/MediaInfo_Config_MediaInfo.h" #include "MediaInfo/MediaInfo_Events_Internal.h" #endif //MEDIAINFO_EVENTS //--------------------------------------------------------------------------- namespace MediaInfoLib { //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_Eia708::File_Eia708() :File__Analyze() { //Config PTS_DTS_Needed=true; MustSynchronize=true; //In cc_type=(int8u)-1; AspectRatio=((float32)4)/3; //Default to 4:3 #if MEDIAINFO_EVENTS MuxingMode=(int8u)-1; #endif //MEDIAINFO_EVENTS ParserName="EIA-708"; //Stream service_number=(int8u)-1; //Temp StandAloneCommand=false; HasContent=false; } //--------------------------------------------------------------------------- File_Eia708::~File_Eia708() { for (size_t Pos=0; PosFile_DisplayCaptions_Get(); if (DisplayCaptions==DisplayCaptions_Stream && Streams.size()<2) Streams.resize(2); if (ServiceDescriptors) { for (servicedescriptors708::iterator ServiceDescriptor=ServiceDescriptors->ServiceDescriptors708.begin(); ServiceDescriptor!=ServiceDescriptors->ServiceDescriptors708.end(); ++ServiceDescriptor) { service_number=ServiceDescriptor->first; block_size=0; Service(); } } for (size_t Pos=1; PosHasContent(); if (!HasContent && DisplayCaptions==DisplayCaptions_Content) continue; Stream_Prepare(Stream_Text); Fill(Stream_Text, StreamPos_Last, Text_ID, Pos); Fill(Stream_Text, StreamPos_Last, "CaptionServiceName", Pos); Fill_SetOptions(StreamKind_Last, StreamPos_Last, "CaptionServiceName", "N NT"); Fill(Stream_Text, StreamPos_Last, Text_Format, "EIA-708"); Fill(Stream_Text, StreamPos_Last, Text_StreamSize, 0); Fill(Stream_Text, StreamPos_Last, Text_BitRate_Mode, "CBR"); if (Config->ParseSpeed>=1.0) { Fill(Stream_Text, StreamPos_Last, "CaptionServiceContent_IsPresent", HasContent?"Yes":"No", Unlimited, true, true); Fill_SetOptions(Stream_Text, StreamPos_Last, "CaptionServiceContent_IsPresent", "N NT"); } if (ServiceDescriptors) { servicedescriptors708::iterator ServiceDescriptor=ServiceDescriptors->ServiceDescriptors708.find((int8u)Pos); if (ServiceDescriptor!=ServiceDescriptors->ServiceDescriptors708.end()) { Fill(Stream_Text, StreamPos_Last, Text_Language, ServiceDescriptor->second.language, true); if (ServiceDescriptor->second.wide_aspect_ratio[0]) Fill(Stream_Text, StreamPos_Last, Text_DisplayAspectRatio, ServiceDescriptor->second.wide_aspect_ratio[1]?(16.0/9.0):(4.0/3.0), 3, true); Fill(Stream_Text, StreamPos_Last, "CaptionServiceDescriptor_IsPresent", "Yes", Unlimited, true, true); Fill_SetOptions(Stream_Text, StreamPos_Last, "CaptionServiceDescriptor_IsPresent", "N NT"); } else //ServiceDescriptors pointer is for the support by the transport layer of the info { Fill(Stream_Text, StreamPos_Last, "CaptionServiceDescriptor_IsPresent", "No", Unlimited, true, true); Fill_SetOptions(Stream_Text, StreamPos_Last, "CaptionServiceDescriptor_IsPresent", "N NT"); } } if (!HasContent) { Fill(Stream_Text, StreamPos_Last, "InternalDetectionKind", HasCommand?"Command":"Stream", Unlimited, true, true); Fill_SetOptions(Stream_Text, StreamPos_Last, "InternalDetectionKind", "N NT"); } } } } //--------------------------------------------------------------------------- void File_Eia708::Streams_Finish() { } //*************************************************************************** // Buffer - Synchro //*************************************************************************** //--------------------------------------------------------------------------- bool File_Eia708::Synchronize() { if (IsSub && cc_type!=3) return false; //Waiting for sync from underlying layer if (!Status[IsAccepted]) Accept("EIA-708"); //Synched is OK return true; } //--------------------------------------------------------------------------- bool File_Eia708::Synched_Test() { if (cc_type==4) //Magic value saying that the buffer must be kept (this is only a point of synchro from the undelying layer) Buffer_Offset=Buffer_Size; //Sync point //We continue return true; } //*************************************************************************** // Buffer - Global //*************************************************************************** //--------------------------------------------------------------------------- void File_Eia708::Read_Buffer_Init() { #if MEDIAINFO_EVENTS if (MuxingMode==(int8u)-1) { if (StreamIDs_Size>=3 && ParserIDs[StreamIDs_Size-3]==MediaInfo_Parser_Mpegv && StreamIDs[StreamIDs_Size-3]==0x4741393400000003LL) MuxingMode=0; //A/53 / DTVCC Transport if (StreamIDs_Size>=3 && ParserIDs[StreamIDs_Size-3]==MediaInfo_Parser_Mpegv && StreamIDs[StreamIDs_Size-3]==0x0000000300000000LL) MuxingMode=1; //SCTE 20 if (StreamIDs_Size>=3 && ParserIDs[StreamIDs_Size-3]==MediaInfo_Parser_Mpegv && StreamIDs[StreamIDs_Size-3]==0x434301F800000000LL) MuxingMode=2; //DVD-Video if (StreamIDs_Size>=4 && (ParserIDs[StreamIDs_Size-4]==MediaInfo_Parser_Gxf || ParserIDs[StreamIDs_Size-4]==MediaInfo_Parser_Lxf || ParserIDs[StreamIDs_Size-4]==MediaInfo_Parser_Mxf) && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Cdp) MuxingMode=3; //Ancillary data / CDP if (StreamIDs_Size>=3 && ParserIDs[StreamIDs_Size-3]==MediaInfo_Parser_Avc) MuxingMode=4; //SCTE 128 / DTVCC Transport if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_DvDif) MuxingMode=5; //DV if (StreamIDs_Size>=3 && ParserIDs[StreamIDs_Size-3]==MediaInfo_Parser_Mpeg4 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Cdp) MuxingMode=6; //Final Cut / CDP if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Scc) MuxingMode=7; //SCC } #endif //MEDIAINFO_EVENTS } //--------------------------------------------------------------------------- void File_Eia708::Read_Buffer_Continue() { FrameInfo.PTS=FrameInfo.DTS; } //--------------------------------------------------------------------------- void File_Eia708::Read_Buffer_Unsynched() { for (service_number=1; service_numberWindows.size(); WindowID++) { window* Window=Streams[service_number]->Windows[WindowID]; if (Window) for (size_t Pos_Y=0; Pos_YMinimal.CC.size(); Pos_Y++) { for (size_t Pos_X=0; Pos_XMinimal.CC[Pos_Y].size(); Pos_X++) { Window->Minimal.CC[Pos_Y][Pos_X].Value=L' '; Window->Minimal.CC[Pos_Y][Pos_X].Attribute=0; } } } //Global display for (size_t Pos_Y=0; Pos_YMinimal.CC.size(); Pos_Y++) { for (size_t Pos_X=0; Pos_XMinimal.CC[Pos_Y].size(); Pos_X++) { Streams[service_number]->Minimal.CC[Pos_Y][Pos_X].Value=L' '; Streams[service_number]->Minimal.CC[Pos_Y][Pos_X].Attribute=0; } } } #if MEDIAINFO_EVENTS for (service_number=1; service_number=Streams.size()) Streams.resize(service_number+1); if (Streams[service_number]==NULL) { Streams[service_number]=new stream; Streams[service_number]->Minimal.CC.resize(15); for (int8u Pos_Y=0; Pos_Y<15; Pos_Y++) Streams[service_number]->Minimal.CC[Pos_Y].resize((size_t)(24*AspectRatio)); Streams[service_number]->Windows.resize(8); } for (int8u Pos=0; Pos=0x08 && cc_data_2<0x10) { Skip_B1( "EXT1 1 byte"); Pos++; } else if (cc_data_2>=0x10 && cc_data_2<0x18) { Skip_B2( "EXT1 2 byte"); Pos+=2; } else if (cc_data_2>=0x18 && cc_data_2<0x20) { Skip_B3( "EXT1 3 byte"); Pos+=3; } //CEA-708-D, Section 7.1.11 (C3) else if (cc_data_2>=0x80 && cc_data_2<0x88) { Skip_B4( "EXT1 4 byte"); Pos+=4; } else if (cc_data_2>=0x88 && cc_data_2<0x90) { Skip_B5( "EXT1 5 byte"); Pos+=5; } else if (cc_data_2>=0x90 && cc_data_2<0xA0) { //CEA-708-D, Section 7.1.11.2 (Variable Length Codes) int8u Length; BS_Begin(); Skip_S1(2, "Type"); Mark_0(); Get_S1 (5, Length, "Length"); Skip_XX(Length, "Data"); Pos+=1+Length; } //CEA-708-D, Section 7.1.9 (G3) else Character_Fill(L'_' ); } } break; case 0x11 : case 0x12 : case 0x13 : case 0x14 : case 0x15 : case 0x16 : case 0x17 : //2-byte long undefined { Skip_B1( "Undefined"); Pos++; } break; case 0x18 : //P16 { Skip_B2( "P16"); Pos+=2; } break; case 0x19 : case 0x1A : case 0x1B : case 0x1C : case 0x1D : case 0x1E : case 0x1F : //3-byte long undefined { Skip_B2( "Undefined"); Pos+=2; } break; //CEA-708-D, Section 7.1.6 (G0) case 0x20 : Character_Fill(L' ' ); break; case 0x21 : Character_Fill(L'!' ); break; case 0x22 : Character_Fill(L'"' ); break; case 0x23 : Character_Fill(L'#' ); break; case 0x24 : Character_Fill(L'$' ); break; case 0x25 : Character_Fill(L'%' ); break; case 0x26 : Character_Fill(L'&' ); break; case 0x27 : Character_Fill(L'\'' ); break; case 0x28 : Character_Fill(L'(' ); break; case 0x29 : Character_Fill(L')' ); break; case 0x2A : Character_Fill(L'*' ); break; case 0x2B : Character_Fill(L'+' ); break; case 0x2C : Character_Fill(L',' ); break; case 0x2D : Character_Fill(L'-' ); break; case 0x2E : Character_Fill(L'.' ); break; case 0x2F : Character_Fill(L'/' ); break; case 0x30 : Character_Fill(L'0' ); break; case 0x31 : Character_Fill(L'1' ); break; case 0x32 : Character_Fill(L'2' ); break; case 0x33 : Character_Fill(L'3' ); break; case 0x34 : Character_Fill(L'4' ); break; case 0x35 : Character_Fill(L'5' ); break; case 0x36 : Character_Fill(L'6' ); break; case 0x37 : Character_Fill(L'7' ); break; case 0x38 : Character_Fill(L'8' ); break; case 0x39 : Character_Fill(L'9' ); break; case 0x3A : Character_Fill(L':' ); break; case 0x3B : Character_Fill(L';' ); break; case 0x3C : Character_Fill(L'<' ); break; case 0x3E : Character_Fill(L'>' ); break; case 0x3F : Character_Fill(L'?' ); break; case 0x40 : Character_Fill(L'@' ); break; case 0x41 : Character_Fill(L'A' ); break; case 0x42 : Character_Fill(L'B' ); break; case 0x43 : Character_Fill(L'C' ); break; case 0x44 : Character_Fill(L'D' ); break; case 0x45 : Character_Fill(L'E' ); break; case 0x46 : Character_Fill(L'F' ); break; case 0x47 : Character_Fill(L'G' ); break; case 0x48 : Character_Fill(L'H' ); break; case 0x49 : Character_Fill(L'I' ); break; case 0x4A : Character_Fill(L'J' ); break; case 0x4B : Character_Fill(L'K' ); break; case 0x4C : Character_Fill(L'L' ); break; case 0x4D : Character_Fill(L'M' ); break; case 0x4E : Character_Fill(L'N' ); break; case 0x4F : Character_Fill(L'O' ); break; case 0x50 : Character_Fill(L'P' ); break; case 0x51 : Character_Fill(L'Q' ); break; case 0x52 : Character_Fill(L'R' ); break; case 0x53 : Character_Fill(L'S' ); break; case 0x54 : Character_Fill(L'T' ); break; case 0x55 : Character_Fill(L'U' ); break; case 0x56 : Character_Fill(L'V' ); break; case 0x57 : Character_Fill(L'W' ); break; case 0x58 : Character_Fill(L'X' ); break; case 0x59 : Character_Fill(L'Y' ); break; case 0x5A : Character_Fill(L'Z' ); break; case 0x5B : Character_Fill(L'[' ); break; case 0x5C : Character_Fill(L'\\' ); break; case 0x5D : Character_Fill(L']' ); break; case 0x5E : Character_Fill(L'^' ); break; case 0x5F : Character_Fill(L'_' ); break; case 0x60 : Character_Fill(L'`' ); break; case 0x61 : Character_Fill(L'a' ); break; case 0x62 : Character_Fill(L'b' ); break; case 0x63 : Character_Fill(L'c' ); break; case 0x64 : Character_Fill(L'd' ); break; case 0x65 : Character_Fill(L'e' ); break; case 0x66 : Character_Fill(L'f' ); break; case 0x67 : Character_Fill(L'g' ); break; case 0x68 : Character_Fill(L'h' ); break; case 0x69 : Character_Fill(L'i' ); break; case 0x6A : Character_Fill(L'j' ); break; case 0x6B : Character_Fill(L'k' ); break; case 0x6C : Character_Fill(L'l' ); break; case 0x6D : Character_Fill(L'm' ); break; case 0x6E : Character_Fill(L'n' ); break; case 0x6F : Character_Fill(L'o' ); break; case 0x70 : Character_Fill(L'p' ); break; case 0x71 : Character_Fill(L'q' ); break; case 0x72 : Character_Fill(L'r' ); break; case 0x73 : Character_Fill(L's' ); break; case 0x74 : Character_Fill(L't' ); break; case 0x75 : Character_Fill(L'u' ); break; case 0x76 : Character_Fill(L'v' ); break; case 0x77 : Character_Fill(L'w' ); break; case 0x78 : Character_Fill(L'x' ); break; case 0x79 : Character_Fill(L'y' ); break; case 0x7A : Character_Fill(L'z' ); break; case 0x7B : Character_Fill(L'{' ); break; case 0x7C : Character_Fill(L'|' ); break; case 0x7D : Character_Fill(L'}' ); break; case 0x7E : Character_Fill(L'~' ); break; case 0x7F : Character_Fill(L'\x266A'); break; //CEA-708-D, Section 7.1.5 (C1) case 0x80 : //CW0 case 0x81 : //CW1 case 0x82 : //CW2 case 0x83 : //CW3 case 0x84 : //CW4 case 0x85 : //CW5 case 0x86 : //CW6 case 0x87 : //CW7 CWx(cc_data_1-0x80); break; //SetCurrentWindow case 0x88 : CLW(); Pos+=1; break; //ClearWindows case 0x89 : DSW(); Pos+=1; break; //DisplayWindows case 0x8A : HDW(); Pos+=1; break; //HideWindows case 0x8B : TGW(); Pos+=1; break; //ToggleWindows case 0x8C : DLW(); Pos+=1; break; //DeleteWindows case 0x8D : DLY(); Pos+=1; break; //Delay case 0x8E : DLC(); break; //Delay Cancel case 0x8F : RST(); break; //Reset case 0x90 : SPA(); Pos+=2; break; //SetPenAttributes case 0x91 : SPC(); Pos+=3; break; //SetPenColor case 0x92 : SPL(); Pos+=2; break; //SetPenLocation case 0x97 : SWA(); Pos+=5; break; //SetWindowAttributes case 0x98 : //DF0 case 0x99 : //DF1 case 0x9A : //DF2 case 0x9B : //DF3 case 0x9C : //DF4 case 0x9D : //DF5 case 0x9E : //DF6 case 0x9F : //DF7 DFx(cc_data_1-0x98); Pos+=6; break; //DefineWindow //CEA-708-D, Section 7.1.6 (G1) case 0xA0 : Character_Fill(L'\xA0' ); break; case 0xA1 : Character_Fill(L'\xA1' ); break; case 0xA2 : Character_Fill(L'\xA2' ); break; case 0xA3 : Character_Fill(L'\xA3' ); break; case 0xA4 : Character_Fill(L'\xA4' ); break; case 0xA5 : Character_Fill(L'\xA5' ); break; case 0xA6 : Character_Fill(L'\xA6' ); break; case 0xA7 : Character_Fill(L'\xA7' ); break; case 0xA8 : Character_Fill(L'\xA8' ); break; case 0xA9 : Character_Fill(L'\xA9' ); break; case 0xAA : Character_Fill(L'\xAA' ); break; case 0xAB : Character_Fill(L'\xAB' ); break; case 0xAC : Character_Fill(L'\xAC' ); break; case 0xAD : Character_Fill(L'\xAD' ); break; case 0xAE : Character_Fill(L'\xAE' ); break; case 0xAF : Character_Fill(L'\xAF' ); break; case 0xB0 : Character_Fill(L'\xB0' ); break; case 0xB1 : Character_Fill(L'\xB1' ); break; case 0xB2 : Character_Fill(L'\xB2' ); break; case 0xB3 : Character_Fill(L'\xB3' ); break; case 0xB4 : Character_Fill(L'\xB4' ); break; case 0xB5 : Character_Fill(L'\xB5' ); break; case 0xB6 : Character_Fill(L'\xB6' ); break; case 0xB7 : Character_Fill(L'\xB7' ); break; case 0xB8 : Character_Fill(L'\xB8' ); break; case 0xB9 : Character_Fill(L'\xB9' ); break; case 0xBA : Character_Fill(L'\xBA' ); break; case 0xBB : Character_Fill(L'\xBB' ); break; case 0xBC : Character_Fill(L'\xBC' ); break; case 0xBD : Character_Fill(L'\xBD' ); break; case 0xBE : Character_Fill(L'\xBE' ); break; case 0xBF : Character_Fill(L'\xBF' ); break; case 0xC0 : Character_Fill(L'\xC0' ); break; case 0xC1 : Character_Fill(L'\xC1' ); break; case 0xC2 : Character_Fill(L'\xC2' ); break; case 0xC3 : Character_Fill(L'\xC3' ); break; case 0xC4 : Character_Fill(L'\xC4' ); break; case 0xC5 : Character_Fill(L'\xC5' ); break; case 0xC6 : Character_Fill(L'\xC6' ); break; case 0xC7 : Character_Fill(L'\xC7' ); break; case 0xC8 : Character_Fill(L'\xC8' ); break; case 0xC9 : Character_Fill(L'\xC9' ); break; case 0xCA : Character_Fill(L'\xCA' ); break; case 0xCB : Character_Fill(L'\xCB' ); break; case 0xCC : Character_Fill(L'\xCC' ); break; case 0xCD : Character_Fill(L'\xCD' ); break; case 0xCE : Character_Fill(L'\xCE' ); break; case 0xCF : Character_Fill(L'\xCF' ); break; case 0xD0 : Character_Fill(L'\xD0' ); break; case 0xD1 : Character_Fill(L'\xD1' ); break; case 0xD2 : Character_Fill(L'\xD2' ); break; case 0xD3 : Character_Fill(L'\xD3' ); break; case 0xD4 : Character_Fill(L'\xD4' ); break; case 0xD5 : Character_Fill(L'\xD5' ); break; case 0xD6 : Character_Fill(L'\xD6' ); break; case 0xD7 : Character_Fill(L'\xD7' ); break; case 0xD8 : Character_Fill(L'\xD8' ); break; case 0xD9 : Character_Fill(L'\xD9' ); break; case 0xDA : Character_Fill(L'\xDA' ); break; case 0xDB : Character_Fill(L'\xDB' ); break; case 0xDC : Character_Fill(L'\xDC' ); break; case 0xDD : Character_Fill(L'\xDD' ); break; case 0xDE : Character_Fill(L'\xDE' ); break; case 0xDF : Character_Fill(L'\xDF' ); break; case 0xE0 : Character_Fill(L'\xE0' ); break; case 0xE1 : Character_Fill(L'\xE1' ); break; case 0xE2 : Character_Fill(L'\xE2' ); break; case 0xE3 : Character_Fill(L'\xE3' ); break; case 0xE4 : Character_Fill(L'\xE4' ); break; case 0xE5 : Character_Fill(L'\xE5' ); break; case 0xE6 : Character_Fill(L'\xE6' ); break; case 0xE7 : Character_Fill(L'\xE7' ); break; case 0xE8 : Character_Fill(L'\xE8' ); break; case 0xE9 : Character_Fill(L'\xE9' ); break; case 0xEA : Character_Fill(L'\xEA' ); break; case 0xEB : Character_Fill(L'\xEB' ); break; case 0xEC : Character_Fill(L'\xEC' ); break; case 0xED : Character_Fill(L'\xED' ); break; case 0xEE : Character_Fill(L'\xEE' ); break; case 0xEF : Character_Fill(L'\xEF' ); break; case 0xF0 : Character_Fill(L'\xF0' ); break; case 0xF1 : Character_Fill(L'\xF1' ); break; case 0xF2 : Character_Fill(L'\xF2' ); break; case 0xF3 : Character_Fill(L'\xF3' ); break; case 0xF4 : Character_Fill(L'\xF4' ); break; case 0xF5 : Character_Fill(L'\xF5' ); break; case 0xF6 : Character_Fill(L'\xF6' ); break; case 0xF7 : Character_Fill(L'\xF7' ); break; case 0xF8 : Character_Fill(L'\xF8' ); break; case 0xF9 : Character_Fill(L'\xF9' ); break; case 0xFA : Character_Fill(L'\xFA' ); break; case 0xFB : Character_Fill(L'\xFB' ); break; case 0xFC : Character_Fill(L'\xFC' ); break; case 0xFD : Character_Fill(L'\xFD' ); break; case 0xFE : Character_Fill(L'\xFE' ); break; case 0xFF : Character_Fill(L'\xFF' ); break; default : Illegal(1, cc_data_1); } } } //*************************************************************************** // Elements //*************************************************************************** //--------------------------------------------------------------------------- //NUL void File_Eia708::NUL() { } //--------------------------------------------------------------------------- //End Of Text void File_Eia708::ETX() { } //--------------------------------------------------------------------------- //Backspace void File_Eia708::BS() { Param_Info1("Backspace"); int8u WindowID=Streams[service_number]->WindowID; if (WindowID==(int8u)-1) return; //Must wait for the corresponding CWx window* Window=Streams[service_number]->Windows[WindowID]; if (Window==NULL) return; //Must wait for the corresponding DFx if (Window->Minimal.x) { //Clearing window Window->Minimal.x--; Window->Minimal.CC[Window->Minimal.y][Window->Minimal.x]=character(); if (Window->visible) { //Clearing global area if (Window->Minimal.Window_y+Window->Minimal.y<(int8u)Streams[service_number]->Minimal.CC.size() && Window->Minimal.Window_x+Window->Minimal.x<(int8u)Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Window->Minimal.y].size()) Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Window->Minimal.y][Window->Minimal.Window_x+Window->Minimal.x]=character(); //Has changed Window_HasChanged(); HasChanged(); } } } //--------------------------------------------------------------------------- //Form Feed void File_Eia708::FF() { Param_Info1("Form Feed"); int8u WindowID=Streams[service_number]->WindowID; if (WindowID==(int8u)-1) return; //Must wait for the corresponding CWx window* Window=Streams[service_number]->Windows[WindowID]; if (Window==NULL) return; //Must wait for the corresponding DFx for (size_t Pos_Y=0; Pos_Yrow_count; Pos_Y++) for (size_t Pos_X=0; Pos_Xcolumn_count; Pos_X++) { //Clearing window Streams[service_number]->Windows[Streams[service_number]->WindowID]->Minimal.CC[Pos_Y][Pos_X]=character(); if (Window->visible) { //Clearing global area if (Window->Minimal.Window_y+Pos_YMinimal.CC.size() && Window->Minimal.Window_x+Pos_XMinimal.CC[Window->Minimal.Window_y+Pos_Y].size()) Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Pos_Y][Window->Minimal.Window_x+Pos_X]=character(); } } if (Window->visible) { //Has changed Window_HasChanged(); HasChanged(); } //SetPenLocation Window->Minimal.x=0; Window->Minimal.y=0; } //--------------------------------------------------------------------------- //Carriage return void File_Eia708::CR() { Param_Info1("Carriage return"); int8u WindowID=Streams[service_number]->WindowID; if (WindowID==(int8u)-1) return; //Must wait for the corresponding CWx window* Window=Streams[service_number]->Windows[WindowID]; if (Window==NULL) return; //Must wait for the corresponding DFx int8u y=Window->Minimal.y; y++; if (y>=Window->row_count-1) { //Rolling up window for (int8u Pos_Y=0; Pos_Yrow_count-1; Pos_Y++) Window->Minimal.CC[Pos_Y]=Window->Minimal.CC[Pos_Y+1]; //SetPenLocation y=Window->row_count-1; //Clearing last line of window for (int8u Pos_X=0; Pos_Xcolumn_count; Pos_X++) Window->Minimal.CC[y][Pos_X]=character(); if (Window->visible) { //Updating global area for (int8u Pos_Y=0; Pos_Yrow_count; Pos_Y++) for (int8u Pos_X=0; Pos_Xcolumn_count; Pos_X++) if (Window->Minimal.Window_y+Pos_Y<(int8u)Streams[service_number]->Minimal.CC.size() && Window->Minimal.Window_x+Pos_X<(int8u)Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Pos_Y].size()) Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Pos_Y][Window->Minimal.Window_x+Pos_X]=Window->Minimal.CC[Pos_Y][Pos_X]; //Has changed Window_HasChanged(); HasChanged(); } } //SetPenLocation Window->Minimal.x=0; Window->Minimal.y=y; } //--------------------------------------------------------------------------- //Horizontal Carriage Return void File_Eia708::HCR() { Param_Info1("Horizontal Carriage Return"); int8u WindowID=Streams[service_number]->WindowID; if (WindowID==(int8u)-1) return; //Must wait for the corresponding CWx window* Window=Streams[service_number]->Windows[WindowID]; if (Window==NULL) return; //Must wait for the corresponding DFx int8u y=Window->Minimal.y; for (int8u Pos_X=0; Pos_Xcolumn_count; Pos_X++) { //Clearing window Streams[service_number]->Windows[Streams[service_number]->WindowID]->Minimal.CC[y][Pos_X]=character(); if (Window->visible) { //Clearing global area if (Window->Minimal.Window_y+y<(int8u)Streams[service_number]->Minimal.CC.size() && Window->Minimal.Window_x+Pos_X<(int8u)Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Window->Minimal.y].size()) Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+y][Window->Minimal.Window_x+Pos_X]=character(); //Has changed Window_HasChanged(); HasChanged(); } } //SetPenLocation Window->Minimal.x=0; } //--------------------------------------------------------------------------- //SetCurrentWindow void File_Eia708::CWx(int8u WindowID) { Param_Info1("SetCurrentWindow"); Param_Info1(WindowID); Streams[service_number]->WindowID=WindowID; } //--------------------------------------------------------------------------- //ClearWindows void File_Eia708::CLW() { Param_Info1("ClearWindows"); int8u Save_WindowID=Streams[service_number]->WindowID; bool Save_StandAloneCommand=StandAloneCommand; StandAloneCommand=false; Element_Begin1("ClearWindows"); BS_Begin(); int8u WindowID=8; bool HasChanged_=false; do { WindowID--; bool IsSet; Get_SB ( IsSet, Ztring(__T("window ")+Ztring::ToZtring(WindowID)).To_Local().c_str()); if (IsSet) { Streams[service_number]->WindowID=WindowID; window* Window=Streams[service_number]->Windows[WindowID]; //ClearWindow is like Form Feed FF(); if (Window && Window->visible) { //Has changed HasChanged_=true; Window_HasChanged(); } } } while (WindowID>0); BS_End(); Element_End0(); Streams[service_number]->WindowID=Save_WindowID; StandAloneCommand=Save_StandAloneCommand; if (HasChanged_) { //Has changed HasChanged(); } } //--------------------------------------------------------------------------- //DisplayWindows void File_Eia708::DSW() { Param_Info1("DisplayWindows"); int8u Save_WindowID=Streams[service_number]->WindowID; bool Save_StandAloneCommand=StandAloneCommand; StandAloneCommand=false; Element_Begin1("DisplayWindows"); BS_Begin(); int8u WindowID=8; bool HasChanged_=false; do { WindowID--; bool IsSet; Get_SB ( IsSet, Ztring(__T("window ")+Ztring::ToZtring(WindowID)).To_Local().c_str()); if (IsSet) { window* Window=Streams[service_number]->Windows[WindowID]; if (Window && !Window->visible) { Window->visible=true; //Filling global area for (size_t Pos_Y=0; Pos_Yrow_count; Pos_Y++) for (size_t Pos_X=0; Pos_Xcolumn_count; Pos_X++) { if (Window->Minimal.Window_y+Pos_YMinimal.CC.size() && Window->Minimal.Window_x+Pos_XMinimal.CC[Window->Minimal.Window_y+Pos_Y].size()) Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Pos_Y][Window->Minimal.Window_x+Pos_X]=Window->Minimal.CC[Pos_Y][Pos_X]; } //Has changed HasChanged_=true; Window_HasChanged(); } } } while (WindowID>0); BS_End(); Element_End0(); Streams[service_number]->WindowID=Save_WindowID; StandAloneCommand=Save_StandAloneCommand; if (HasChanged_) { //Has changed HasChanged(); } } //--------------------------------------------------------------------------- //HideWindows void File_Eia708::HDW() { #if MEDIAINFO_TRACE Param_Info1("HideWindows"); Element_Level--; Element_Info1("HideWindows"); Element_Level++; #endif //MEDIAINFO_TRACE int8u Save_WindowID=Streams[service_number]->WindowID; bool Save_StandAloneCommand=StandAloneCommand; StandAloneCommand=false; Element_Begin1("HideWindows"); BS_Begin(); int8u WindowID=8; bool HasChanged_=false; do { WindowID--; bool IsSet; Get_SB ( IsSet, Ztring(__T("window ")+Ztring::ToZtring(WindowID)).To_Local().c_str()); if (IsSet) { window* Window=Streams[service_number]->Windows[WindowID]; if (Window && Window->visible) { Window->visible=false; for (size_t Pos_Y=0; Pos_Yrow_count; Pos_Y++) for (size_t Pos_X=0; Pos_Xcolumn_count; Pos_X++) { //Clearing window Window->Minimal.CC[Pos_Y][Pos_X]=character(); //Filling global area if (Window->Minimal.Window_y+Pos_YMinimal.CC.size() && Window->Minimal.Window_x+Pos_XMinimal.CC[Window->Minimal.Window_y+Pos_Y].size()) Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Pos_Y][Window->Minimal.Window_x+Pos_X]=character(); } //Has changed HasChanged_=true; Window_HasChanged(); } } } while (WindowID>0); BS_End(); Element_End0(); Streams[service_number]->WindowID=Save_WindowID; StandAloneCommand=Save_StandAloneCommand; if (HasChanged_) { //Has changed HasChanged(); } } //--------------------------------------------------------------------------- //ToggleWindows void File_Eia708::TGW() { #if MEDIAINFO_TRACE Param_Info1("ToggleWindows"); Element_Level--; Element_Info1("ToggleWindows"); Element_Level++; #endif //MEDIAINFO_TRACE int8u Save_WindowID=Streams[service_number]->WindowID; bool Save_StandAloneCommand=StandAloneCommand; StandAloneCommand=false; Element_Begin1("ToggleWindows"); BS_Begin(); int8u WindowID=8; bool HasChanged_=false; do { WindowID--; bool IsSet; Get_SB ( IsSet, Ztring(__T("window ")+Ztring::ToZtring(WindowID)).To_Local().c_str()); if (IsSet) { window* Window=Streams[service_number]->Windows[WindowID]; if (Window) { Window->visible=!Window->visible; //Filling global area for (size_t Pos_Y=0; Pos_Yrow_count; Pos_Y++) for (size_t Pos_X=0; Pos_Xcolumn_count; Pos_X++) { if (Window->Minimal.Window_y+Pos_YMinimal.CC.size() && Window->Minimal.Window_x+Pos_XMinimal.CC[Window->Minimal.Window_y+Pos_Y].size()) Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Pos_Y][Window->Minimal.Window_x+Pos_X]=Window->visible?Window->Minimal.CC[Pos_Y][Pos_X]:character(); } //Has changed HasChanged_=true; Window_HasChanged(); } } } while (WindowID>0); BS_End(); Element_End0(); Streams[service_number]->WindowID=Save_WindowID; StandAloneCommand=Save_StandAloneCommand; if (HasChanged_) { //Has changed HasChanged(); } } //--------------------------------------------------------------------------- //DeleteWindows void File_Eia708::DLW() { #if MEDIAINFO_TRACE Param_Info1("DeleteWindows"); Element_Level--; Element_Info1("DeleteWindows"); Element_Level++; #endif //MEDIAINFO_TRACE int8u Save_WindowID=Streams[service_number]->WindowID; bool Save_StandAloneCommand=StandAloneCommand; StandAloneCommand=false; //Bug in some files //bool Bug_WindowOffset=false; Element_Begin1("DeleteWindows"); BS_Begin(); int8u WindowID=8; bool HasChanged_=false; do { WindowID--; bool IsSet; Get_SB ( IsSet, Ztring(__T("window ")+Ztring::ToZtring(WindowID)).To_Local().c_str()); //Bug in some files //if (IsSet && WindowID==1 && Streams[service_number]->Windows[0]!=NULL && Streams[service_number]->Windows[1]==NULL) //Mix between Windows 0 and 1 //{ // Bug_WindowOffset=true; // //Fill(Stream_Text, 0, "Bug", "WindowID_Bug", Unlimited, true, true); //} //if (!IsSet && WindowID==0 && Bug_WindowOffset) // IsSet=true; if (IsSet) { window* Window=Streams[service_number]->Windows[WindowID]; if (Window && Window->visible) { //Filling global area for (size_t Pos_Y=0; Pos_Yrow_count; Pos_Y++) for (size_t Pos_X=0; Pos_Xcolumn_count; Pos_X++) { //Clearing window Window->Minimal.CC[Pos_Y][Pos_X]=character(); //Filling global area if (Window->Minimal.Window_y+Pos_YMinimal.CC.size() && Window->Minimal.Window_x+Pos_XMinimal.CC[Window->Minimal.Window_y+Pos_Y].size()) Streams[service_number]->Minimal.CC[Window->Minimal.Window_y+Pos_Y][Window->Minimal.Window_x+Pos_X]=character(); } //Has changed HasChanged_=true; Window_HasChanged(); } //Removing the window delete Streams[service_number]->Windows[WindowID]; Streams[service_number]->Windows[WindowID]=NULL; if (WindowID==Save_WindowID) Save_WindowID=(int8u)-1; } } while (WindowID>0); BS_End(); Element_End0(); Streams[service_number]->WindowID=Save_WindowID; StandAloneCommand=Save_StandAloneCommand; if (HasChanged_) { //Has changed HasChanged(); } } //--------------------------------------------------------------------------- //Delay void File_Eia708::DLY() { Param_Info1("Delay"); Element_Begin1("Delay"); Skip_B1( "tenths of seconds"); Element_End0(); } //--------------------------------------------------------------------------- //Delay Cancel void File_Eia708::DLC() { Param_Info1("Delay Cancel"); } //--------------------------------------------------------------------------- //Reset void File_Eia708::RST() { //TODO: Should clear all buffers Param_Info1("Reset"); } //--------------------------------------------------------------------------- //Set Pen Attributes void File_Eia708::SPA() { #if MEDIAINFO_TRACE Param_Info1("Set Pen Attributes"); Element_Level--; Element_Info1("Set Pen Attributes"); Element_Level++; #endif //MEDIAINFO_TRACE Element_Begin1("Set Pen Attributes"); BS_Begin(); Skip_S1(4, "text tag"); Skip_S1(2, "offset"); Skip_S1(2, "pen size"); Skip_SB( "italics"); Skip_SB( "underline"); Skip_S1(3, "edge type"); Skip_S1(3, "font style"); BS_End(); Element_End0(); } //--------------------------------------------------------------------------- //Set Pen Color void File_Eia708::SPC() { #if MEDIAINFO_TRACE Param_Info1("Set Pen Color"); Element_Level--; Element_Info1("Set Pen Color"); Element_Level++; #endif //MEDIAINFO_TRACE Element_Begin1("Set Pen Color"); BS_Begin(); Skip_S1(2, "foreground opacity"); Skip_S1(2, "foreground red"); Skip_S1(2, "foreground green"); Skip_S1(2, "foreground blue"); Skip_S1(2, "background opacity"); Skip_S1(2, "background red"); Skip_S1(2, "background green"); Skip_S1(2, "background blue"); Mark_0(); Mark_0(); Skip_S1(2, "edge red"); Skip_S1(2, "edge green"); Skip_S1(2, "edge blue"); BS_End(); Element_End0(); } //--------------------------------------------------------------------------- //SetPenLocation void File_Eia708::SPL() { #if MEDIAINFO_TRACE Param_Info1("SetPenLocation"); Element_Level--; Element_Info1("SetPenLocation"); Element_Level++; #endif //MEDIAINFO_TRACE Element_Begin1("SetPenLocation"); int8u row, column; BS_Begin(); Mark_0(); Mark_0(); Mark_0(); Mark_0(); Get_S1 (4, row, "row"); Mark_0(); Mark_0(); Get_S1 (6, column, "column"); BS_End(); Element_End0(); int8u WindowID=Streams[service_number]->WindowID; if (WindowID==(int8u)-1) return; //Must wait for the corresponding CWx window* Window=Streams[service_number]->Windows[WindowID]; if (Window==NULL) return; //Must wait for the corresponding DFx if (rowMinimal.CC.size() && columnMinimal.CC[Window->Minimal.y].size()) { Window->Minimal.x=column; Window->Minimal.y=row; } else { // There is a problem, resetting pen location Window->Minimal.x=0; Window->Minimal.y=0; } } //--------------------------------------------------------------------------- //SetWindowAttributes void File_Eia708::SWA() { #if MEDIAINFO_TRACE Param_Info1("SetWindowAttributes"); Element_Level--; Element_Info1("SetWindowAttributes"); Element_Level++; #endif //MEDIAINFO_TRACE Element_Begin1("SetWindowAttributes"); BS_Begin(); Skip_S1(2, "fill opacity"); Skip_S1(2, "fill red"); Skip_S1(2, "fill green"); Skip_S1(2, "fill blue"); Skip_S1(2, "border type (low)"); Skip_S1(2, "border red"); Skip_S1(2, "border green"); Skip_S1(2, "border blue"); Skip_SB( "border type (high)"); Skip_SB( "wordwrap"); Skip_S1(2, "print direction"); Skip_S1(2, "scroll direction"); Skip_S1(2, "justify"); Skip_S1(4, "effect speed"); Skip_S1(2, "effect direction"); Skip_S1(2, "display effect"); Mark_0_NoTrustError(); Mark_0_NoTrustError(); Skip_S1(2, "edge red"); Skip_S1(2, "edge green"); Skip_S1(2, "edge blue"); BS_End(); Element_End0(); } //--------------------------------------------------------------------------- //DefineWindow void File_Eia708::DFx(int8u WindowID) { #if MEDIAINFO_TRACE Param_Info1("DefineWindow"); Param_Info1(WindowID); Element_Level--; Element_Info1("DefineWindow"); Element_Level++; #endif //MEDIAINFO_TRACE Element_Begin1("DefineWindow"); int8u anchor_vertical, anchor_horizontal, anchor_point, row_count, column_count; bool visible, relative_positioning; BS_Begin(); Mark_0(); Mark_0(); Get_SB ( visible, "visible"); Skip_SB( "row lock"); Skip_SB( "column lock"); Skip_S1(3, "priority"); Get_SB ( relative_positioning, "relative positioning"); Get_S1 (7, anchor_vertical, "anchor vertical"); //Top left Get_S1 (8, anchor_horizontal, "anchor horizontal"); //Top left Get_S1 (4, anchor_point, "anchor point"); Get_S1 (4, row_count, "row count"); //Maximum=14 Mark_0(); Mark_0(); Get_S1 (6, column_count, "column count"); //Maximum=31 Mark_0(); Mark_0(); Skip_S1(4, "window style"); Skip_S1(2, "pen style ID"); BS_End(); Element_End0(); Streams[service_number]->WindowID=WindowID; if (Streams[service_number]->Windows[WindowID]==NULL) Streams[service_number]->Windows[WindowID]=new window; window* Window=Streams[service_number]->Windows[WindowID]; Window->visible=visible; Window->relative_positioning=relative_positioning; if (relative_positioning) { Window->Minimal.Window_y=(int8u)(((float)15)*anchor_vertical/100); Window->Minimal.Window_x=(int8u)(24*AspectRatio*anchor_horizontal/100); } else { Window->Minimal.Window_y=anchor_vertical/5; Window->Minimal.Window_x=anchor_horizontal/5; } int8u offset_y; switch (anchor_point) { case 0 : case 1 : case 2 : offset_y=0; break; case 3 : case 4 : case 5 : offset_y=(row_count+1)/2; break; case 6 : case 7 : case 8 : offset_y=(row_count+1); break; default: offset_y=0; //Not valid } if (offset_yMinimal.Window_y) Window->Minimal.Window_y-=offset_y; int8u offset_x; switch (anchor_point) { case 0 : case 3 : case 6 : offset_x=0; break; case 1 : case 4 : case 7 : offset_x=(column_count+1)/2; break; case 2 : case 5 : case 8 : offset_x=(column_count+1); break; default: offset_x=0; //Not valid } if (offset_xMinimal.Window_x) Window->Minimal.Window_x-=offset_x; Window->row_count=row_count+1; Window->column_count=column_count+1; Window->Minimal.x=0; Window->Minimal.y=0; if (Window->row_count>15) { Window->row_count=15; //Limitation of specifications } if (AspectRatio && Window->column_count>(int8u)(24*AspectRatio)) { Window->column_count=(int8u)(24*AspectRatio); //Limitation of specifications } Window->Minimal.CC.resize(Window->row_count); for (int8u Pos_Y=0; Pos_Yrow_count; Pos_Y++) Window->Minimal.CC[Pos_Y].resize(Window->column_count); if (Window->Minimal.Window_y+Window->row_count>15 || (AspectRatio && Window->Minimal.Window_x+Window->column_count>(int8u)(24*AspectRatio))) { //Correcting if (Window->Minimal.Window_y+Window->row_count>15) Window->Minimal.Window_y=15-Window->row_count; if (AspectRatio && Window->Minimal.Window_x+Window->column_count>(int8u)(24*AspectRatio)) Window->Minimal.Window_x=(int8u)(24*AspectRatio)-Window->column_count; } } //*************************************************************************** // Helpers //*************************************************************************** //--------------------------------------------------------------------------- void File_Eia708::Character_Fill(wchar_t Character) { Element_Level-=1; Element_Info1(Ztring().From_Unicode(&Character, 1)); Element_Level+=1; Param_Info1(Ztring().From_Unicode(&Character, 1)); //(Character) after new ZenLib release int8u WindowID=Streams[service_number]->WindowID; if (WindowID==(int8u)-1) return; //Must wait for the corresponding CWx window* Window=Streams[service_number]->Windows[WindowID]; if (Window==NULL) return; //Must wait for the corresponding DFx int8u x=Window->Minimal.x; int8u y=Window->Minimal.y; int8u Window_x=Window->Minimal.Window_x; int8u Window_y=Window->Minimal.Window_y; if (xcolumn_count && yrow_count) { //Filling window Window->Minimal.CC[y][x].Value=Character; if (Window->visible) { //Filling global area if (Window_y+y<(int8u)Streams[service_number]->Minimal.CC.size() && Window_x+x<(int8u)Streams[service_number]->Minimal.CC[Window_y+y].size()) Streams[service_number]->Minimal.CC[Window_y+y][Window_x+x].Value=Character; //Has changed Window_HasChanged(); HasChanged(); } x++; Window->Minimal.x=x; } if (!HasContent) HasContent=true; } //--------------------------------------------------------------------------- void File_Eia708::Window_HasChanged() { int8u WindowID=Streams[service_number]->WindowID; if (WindowID==(int8u)-1) return; //Must wait for the corresponding CWx window* Window=Streams[service_number]->Windows[WindowID]; if (Window==NULL) return; //Must wait for the corresponding DFx #if MEDIAINFO_EVENTS EVENT_BEGIN (DtvccCaption, Window_Content_Minimal, 0) Event.MuxingMode=MuxingMode; Event.Service=service_number; Event.Window=Streams[service_number]->WindowID; for (size_t Pos_Y=0; Pos_YMinimal.CC.size(); Pos_Y++) { size_t Width=Window->Minimal.CC[Pos_Y].size(); if (Width>32) Width=32; //TODO: this is a limitation of the event structure, hardcoded limit set to 32, and it should be replaced, without such limit for (size_t Pos_X=0; Pos_X< Width; Pos_X++) { Event.Row_Values[Pos_Y][Pos_X]=Window->Minimal.CC[Pos_Y][Pos_X].Value; Event.Row_Attributes[Pos_Y][Pos_X]=Window->Minimal.CC[Pos_Y][Pos_X].Attribute; } Event.Row_Values[Pos_Y][Width]=L'\0'; } for (size_t Pos_Y=Window->Minimal.CC.size(); Pos_Y<15; Pos_Y++) Event.Row_Values[Pos_Y][0]=L'\0'; EVENT_END () #endif //MEDIAINFO_EVENTS } //--------------------------------------------------------------------------- void File_Eia708::HasChanged() { #if MEDIAINFO_EVENTS EVENT_BEGIN (DtvccCaption, Content_Minimal, 0) Event.MuxingMode=MuxingMode; Event.Service=service_number; Event.StreamIDs[Event.StreamIDs_Size-1]=Event.Service; for (size_t Pos_Y=0; Pos_YMinimal.CC.size(); Pos_Y++) { for (size_t Pos_X=0; Pos_XMinimal.CC[Pos_Y].size(); Pos_X++) { Event.Row_Values[Pos_Y][Pos_X]=Streams[service_number]->Minimal.CC[Pos_Y][Pos_X].Value; Event.Row_Attributes[Pos_Y][Pos_X]=Streams[service_number]->Minimal.CC[Pos_Y][Pos_X].Attribute; } Event.Row_Values[Pos_Y][(size_t)(24*AspectRatio)]=L'\0'; } EVENT_END () #endif //MEDIAINFO_EVENTS } //--------------------------------------------------------------------------- void File_Eia708::Illegal(int8u Size, int8u cc_data_1, int8u cc_data_2, int8u cc_data_3, int8u cc_data_4, int8u cc_data_5, int8u cc_data_6) { } //*************************************************************************** // C++ //*************************************************************************** } //NameSpace #endif //MEDIAINFO_EIA708_YES