bool CDVDDemuxVobsub::Open(const std::string& filename, int source, const std::string& subfilename) { m_Filename = filename; m_source = source; std::unique_ptr<CDVDSubtitleStream> pStream(new CDVDSubtitleStream()); if(!pStream->Open(filename)) return false; std::string vobsub = subfilename; if ( vobsub == "") { vobsub = filename; vobsub.erase(vobsub.rfind('.'), vobsub.size()); vobsub += ".sub"; } CFileItem item(vobsub, false); item.SetMimeType("video/x-vobsub"); item.SetContentLookup(false); m_Input.reset(CDVDFactoryInputStream::CreateInputStream(NULL, item)); if(!m_Input.get() || !m_Input->Open()) return false; m_Demuxer.reset(new CDVDDemuxFFmpeg()); if(!m_Demuxer->Open(m_Input.get())) return false; CDVDStreamInfo hints; CDVDCodecOptions options; hints.codec = AV_CODEC_ID_DVD_SUBTITLE; char line[2048]; DECLARE_UNUSED(bool,res) SState state; state.delay = 0; state.id = -1; while( pStream->ReadLine(line, sizeof(line)) ) { if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#') continue; else if (strncmp("langidx:", line, 8) == 0) res = ParseLangIdx(state, line + 8); else if (strncmp("delay:", line, 6) == 0) res = ParseDelay(state, line + 6); else if (strncmp("id:", line, 3) == 0) res = ParseId(state, line + 3); else if (strncmp("timestamp:", line, 10) == 0) res = ParseTimestamp(state, line + 10); else if (strncmp("palette:", line, 8) == 0 || strncmp("size:", line, 5) == 0 || strncmp("org:", line, 4) == 0 || strncmp("custom colors:", line, 14) == 0 || strncmp("scale:", line, 6) == 0 || strncmp("alpha:", line, 6) == 0 || strncmp("fadein/out:", line, 11) == 0 || strncmp("forced subs:", line, 12) == 0) res = ParseExtra(state, line); else continue; } struct sorter s; sort(m_Timestamps.begin(), m_Timestamps.end(), s); m_Timestamp = m_Timestamps.begin(); for(unsigned i=0;i<m_Streams.size();i++) { m_Streams[i]->ExtraSize = state.extra.length()+1; m_Streams[i]->ExtraData = new uint8_t[m_Streams[i]->ExtraSize]; strcpy((char*)m_Streams[i]->ExtraData, state.extra.c_str()); } return true; }
// Parse a primitive, apply defaults first, grab any base level // key pairs, then process any sub groups we may contain. //------------------------------------------------------ bool CPrimitiveTemplate::ParsePrimitive( CGPGroup *grp ) { CGPGroup *subGrp; CGPValue *pairs; const char *key; const char *val; // Lets work with the pairs first pairs = grp->GetPairs(); while( pairs ) { // the fields key = pairs->GetName(); val = pairs->GetTopValue(); // Huge stricmp lists suxor if ( !stricmp( key, "count" )) { ParseCount( val ); } else if ( !stricmp( key, "shaders" ) || !stricmp( key, "shader" )) { ParseShaders( pairs ); } else if ( !stricmp( key, "models" ) || !stricmp( key, "model" )) { ParseModels( pairs ); } else if ( !stricmp( key, "sounds" ) || !stricmp( key, "sound" )) { ParseSounds( pairs ); } else if ( !stricmp( key, "impactfx" )) { ParseImpactFxStrings( pairs ); } else if ( !stricmp( key, "deathfx" )) { ParseDeathFxStrings( pairs ); } else if ( !stricmp( key, "emitfx" )) { ParseEmitterFxStrings( pairs ); } else if ( !stricmp( key, "playfx" )) { ParsePlayFxStrings( pairs ); } else if ( !stricmp( key, "life" )) { ParseLife( val ); } else if ( !stricmp( key, "cullrange" )) { mCullRange = atoi( val ); mCullRange *= mCullRange; // Square } else if ( !stricmp( key, "delay" )) { ParseDelay( val ); } else if ( !stricmp( key, "bounce" ) || !stricmp( key, "intensity" )) // me==bad for reusing this...but it shouldn't hurt anything) { ParseElasticity( val ); } else if ( !stricmp( key, "min" )) { ParseMin( val ); } else if ( !stricmp( key, "max" )) { ParseMax( val ); } else if ( !stricmp( key, "angle" ) || !stricmp( key, "angles" )) { ParseAngle( val ); } else if ( !stricmp( key, "angleDelta" )) { ParseAngleDelta( val ); } else if ( !stricmp( key, "velocity" ) || !stricmp( key, "vel" )) { ParseVelocity( val ); } else if ( !stricmp( key, "acceleration" ) || !stricmp( key, "accel" )) { ParseAcceleration( val ); } else if ( !stricmp( key, "gravity" )) { ParseGravity( val ); } else if ( !stricmp( key, "density" )) { ParseDensity( val ); } else if ( !stricmp( key, "variance" )) { ParseVariance( val ); } else if ( !stricmp( key, "origin" )) { ParseOrigin1( val ); } else if ( !stricmp( key, "origin2" )) { ParseOrigin2( val ); } else if ( !stricmp( key, "radius" )) // part of ellipse/cylinder calcs. { ParseRadius( val ); } else if ( !stricmp( key, "height" )) // part of ellipse/cylinder calcs. { ParseHeight( val ); } else if ( !stricmp( key, "rotation" )) { ParseRotation( val ); } else if ( !Q_stricmp( key, "rotationDelta" )) { ParseRotationDelta( val ); } else if ( !stricmp( key, "flags" ) || !stricmp( key, "flag" )) { // these need to get passed on to the primitive ParseFlags( val ); } else if ( !stricmp( key, "spawnFlags" ) || !stricmp( key, "spawnFlag" )) { // these are used to spawn things in cool ways, but don't ever get passed on to prims. ParseSpawnFlags( val ); } else if ( !stricmp( key, "name" )) { if ( val ) { // just stash the descriptive name of the primitive strcpy( mName, val ); } } else { theFxHelper.Print( "Unknown key parsing an effect primitive: %s\n", key ); } pairs = (CGPValue *)pairs->GetNext(); } subGrp = grp->GetSubGroups(); // Lets chomp on the groups now while ( subGrp ) { key = subGrp->GetName(); if ( !stricmp( key, "rgb" )) { ParseRGB( subGrp ); } else if ( !stricmp( key, "alpha" )) { ParseAlpha( subGrp ); } else if ( !stricmp( key, "size" ) || !stricmp( key, "width" )) { ParseSize( subGrp ); } else if ( !stricmp( key, "size2" ) || !stricmp( key, "width2" )) { ParseSize2( subGrp ); } else if ( !stricmp( key, "length" ) || !stricmp( key, "height" )) { ParseLength( subGrp ); } else { theFxHelper.Print( "Unknown group key parsing a particle: %s\n", key ); } subGrp = (CGPGroup *)subGrp->GetNext(); } return true; }