/* 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_SCC_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Text/File_Scc.h" #include "MediaInfo/MediaInfo_Config_MediaInfo.h" #include "MediaInfo/Text/File_Eia608.h" //--------------------------------------------------------------------------- namespace MediaInfoLib { //*************************************************************************** // Utils //*************************************************************************** //--------------------------------------------------------------------------- static unsigned char Char2Hex (unsigned char Char) { if (Char<='9' && Char>='0') Char-='0'; else if (Char<='f' && Char>='a') Char-='a'-10; else if (Char<='F' && Char>='A') Char-='A'-10; else Char =0; return Char; } //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_Scc::File_Scc() :File__Analyze() { //Configuration ParserName="SCC"; #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_Scc; #endif //MEDIAINFO_EVENTS #if MEDIAINFO_TRACE Trace_Layers_Update(8); //Stream #endif //MEDIAINFO_TRACE PTS_DTS_Needed=true; //Temp Parser=NULL; } //--------------------------------------------------------------------------- File_Scc::~File_Scc() { delete Parser; //Parser=NULL; } //*************************************************************************** // Buffer - Global //*************************************************************************** //--------------------------------------------------------------------------- #if MEDIAINFO_SEEK size_t File_Scc::Read_Buffer_Seek (size_t Method, int64u Value, int64u ID) { GoTo(0); Open_Buffer_Unsynch(); return 1; } #endif //MEDIAINFO_SEEK //--------------------------------------------------------------------------- #if MEDIAINFO_SEEK void File_Scc::Read_Buffer_Unsynched() { if (Parser) Parser->Open_Buffer_Unsynch(); } #endif //MEDIAINFO_SEEK //--------------------------------------------------------------------------- #if MEDIAINFO_SEEK void File_Scc::Read_Buffer_AfterParsing() { } #endif //MEDIAINFO_SEEK //*************************************************************************** // Streams management //*************************************************************************** //--------------------------------------------------------------------------- void File_Scc::Streams_Finish() { if (TimeCode_FirstFrame.GetFramesMax() && Frame_Count_NotParsedIncluded!=(int64u)-1) Fill(Stream_Text, 0, Text_TimeCode_LastFrame, (TimeCode_FirstFrame+(Frame_Count_NotParsedIncluded-1)).ToString()); if (Parser && Parser->Status[IsAccepted]) { Finish(Parser); for (size_t Pos2=0; Pos2Count_Get(Stream_Text); Pos2++) { Stream_Prepare(Stream_Text); Merge(*Parser, Stream_Text, StreamPos_Last, Pos2); Fill(Stream_Text, StreamPos_Last, Text_ID, Parser->Retrieve(Stream_Text, Pos2, Text_ID), true); if (Pos2) { Fill(Stream_Text, StreamPos_Last, Text_TimeCode_FirstFrame, Retrieve_Const(Stream_Text, 0, Text_TimeCode_FirstFrame)); Fill(Stream_Text, StreamPos_Last, Text_TimeCode_LastFrame, Retrieve_Const(Stream_Text, 0, Text_TimeCode_LastFrame)); } } } } //*************************************************************************** // Buffer - File header //*************************************************************************** //--------------------------------------------------------------------------- bool File_Scc::FileHeader_Begin() { //Element_Size if (File_Size<22) { Reject("N19"); return false; } if (Buffer_Size<22) return false; //Must wait for more data if (Buffer[ 0]!=0x53 || Buffer[ 1]!=0x63 || Buffer[ 2]!=0x65 || Buffer[ 3]!=0x6E || Buffer[ 4]!=0x61 || Buffer[ 5]!=0x72 || Buffer[ 6]!=0x69 || Buffer[ 7]!=0x73 || Buffer[ 8]!=0x74 || Buffer[ 9]!=0x5F || Buffer[10]!=0x53 || Buffer[11]!=0x43 || Buffer[12]!=0x43 || Buffer[13]!=0x20 || Buffer[14]!=0x56 || Buffer[15]!=0x31 || Buffer[16]!=0x2E || Buffer[17]!=0x30 ) { Reject("SCC"); return false; } //Element_Size if (Buffer_Size TimeCodes; vector FrameRates; FrameRates.push_back(24); FrameRates.push_back(25); FrameRates.push_back(30); int8u FrameRateSlowDown[2]; FrameRateSlowDown[0]=6; FrameRateSlowDown[1]=5; int8u HighestFrame=0; int8u HighestFrame_Adapted=0; size_t Begin=Buffer_Offset+(size_t)Element_Offset; for (size_t End=Begin; End=11) { size_t Space=Begin; while (Space6-i) { FrameRateSlowDown[i]=0; continue; } } TimeCodes[i]++; } } } } while (EndFile_DefaultFrameRate_Get()); if (!FrameRate_F) FrameRate_F=30/1.001; #else //MEDIAINFO_ADVANCED const float64 FrameRate_F=30/1.001; #endif //MEDIAINFO_ADVANCED FrameDurationNanoSeconds=float64_int64s(1000000000/FrameRate_F); if (FrameRate_F>0 && FrameRate_F<0x100) { FrameRate=(int8u)float64_int64s(FrameRate_F); FrameRate_Is1001=FrameRate_F!=FrameRate; } else FrameRate=0; Fill(Stream_Text, 0, Text_FrameRate, FrameRate_F); TimeCode_FirstFrame.SetFramesMax(FrameRate-1); TimeCode_FirstFrame.Set1001fps(FrameRate_Is1001); Fill(Stream_Text, 0, Text_Delay, (int64s)TimeCode_FirstFrame.ToMilliseconds()); } //*************************************************************************** // Buffer - Per element //*************************************************************************** //--------------------------------------------------------------------------- void File_Scc::Header_Parse() { size_t End=Buffer_Offset; //Content while (EndFrameInfo.DTS=Temp.ToMilliseconds()*1000000; Parser->FrameInfo.DUR=FrameDurationNanoSeconds; while (Element_Offset+5<=Element_Size) { int8u Buffer_Temp[2]; Buffer_Temp[0]=Char2Hex(Buffer[Buffer_Offset+(size_t)Element_Offset+1])<<4 | Char2Hex(Buffer[Buffer_Offset+(size_t)Element_Offset+2]); Buffer_Temp[1]=Char2Hex(Buffer[Buffer_Offset+(size_t)Element_Offset+3])<<4 | Char2Hex(Buffer[Buffer_Offset+(size_t)Element_Offset+4]); Open_Buffer_Continue(Parser, Buffer_Temp, 2); Element_Offset+=5; Frame_Count_NotParsedIncluded=Parser->Frame_Count_NotParsedIncluded; } } //*************************************************************************** // C++ //*************************************************************************** } //NameSpace #endif //MEDIAINFO_SCC_YES