void ClientSideResponse::DebugPrintRequest()
{
    XString method = GetHeader(XString("method"));
    XString response_code = GetHeader(XString("response_code"));
    XString http_version = GetHeader(XString("http_version"));
    printf("method = %s\n", method.c_str());
    printf("response_code = %s\n", response_code.c_str());
    printf("http_version = %s\n", http_version.c_str());
    fflush(stdout);
}
	bool createdirs(const char* _dir)
	{
		assert(_dir);
		if(!_dir) return false;
		XString dir(_dir);
		Trim(dir);
		if(dir.empty()) return false;
		std::replace(dir.begin(),dir.end(),'\\','/');
		while('/' == *dir.rbegin())
			dir.erase(dir.end() -1);

		XString::size_type pos = dir.find('/');
		if(XString::npos == pos)
			return false;

		XString path;
		while (true)
		{
			pos = dir.find('/', pos + 1);
			if (pos == XString::npos)
			{
				path = dir;
#if _WIN32
				_mkdir(path.c_str());
#else
				mkdir(path.c_str(), S_IRWXU);
#endif
				break;
			}
			path = dir.substr(0, pos);
#if _WIN32
			_mkdir(path.c_str());
#else
			mkdir(path.c_str(), S_IRWXU);
#endif
			if (pos >= dir.size())
				break;
		}
		return true;
	}
Beispiel #3
0
XIRef<XTimeZone> XSimpleTimeZone::FromISOString(const XString& isoString)
{
    if(isoString[0] != '-' && isoString[0] != '+')
        X_THROW(("Invalid ISO Extended String: %s", isoString.c_str()));

    const int sign = isoString[0] == '-' ? -1 : 1;
    const XString str = isoString.substr(1);

    if(str.empty())
        X_THROW(("Invalid ISO Extended String: %s", isoString.c_str()));

    const size_t colonDex = str.find(':');
    XString hoursStr;
    XString minutesStr;

    if(colonDex != string::npos)
    {
        hoursStr = str.substr(0, colonDex);
        minutesStr = str.substr(colonDex + 1);

        if(minutesStr.size() != 2)
            X_THROW(("Invalid ISO Extended String: %s", isoString.c_str()));
    }
    else
        hoursStr = str;

    if(count_if(hoursStr.begin(), hoursStr.end(), verifyDigit) != (int)hoursStr.size() ||
       count_if(minutesStr.begin(), minutesStr.end(), verifyDigit) != (int)minutesStr.size())
    {
        X_THROW(("Invalid ISO Extended String: %s", isoString.c_str()));
    }

    const int hours = hoursStr.ToInt();
    const int minutes = minutesStr.empty() ? 0 : minutesStr.ToInt();

    return new XSimpleTimeZone(sign * (int)(convert(HOURS, MINUTES, hours) + minutes));
}
Beispiel #4
0
XString TranscodeExport::_GetTMPName( const XString& fileName ) const
{
    if( !fileName.Contains(".") )
        X_THROW(("No extension in file name!"));

    if( !fileName.Contains(PATH_SLASH) )
        X_THROW(("Need full path to file for export."));

    vector<XString> parts;
    fileName.Split( PATH_SLASH, parts );

    if( parts.size() < 2 )
        X_THROW(("Invalid export path: %s",fileName.c_str()));;

    XString path;

    for( int i = 0; i < ((int)parts.size() - 1); i++ )
        path += XString::Format( "%s%s", PATH_SLASH, parts[i].c_str() );

    XString mediaFileName = parts[parts.size()-1];

    XString fileBaseName = mediaFileName.substr(0, mediaFileName.find("."));
    XString extension = mediaFileName.substr(mediaFileName.find(".")+1);

    XMD5 hash;
    hash.Update( (uint8_t*)fileBaseName.c_str(), fileBaseName.length() );
    hash.Finalize();

    XString fileBaseNameHash = hash.GetAsString();

    return XString::Format( "%s%sexport-tmp-%s.%s",
                            path.c_str(),
                            PATH_SLASH,
                            fileBaseNameHash.c_str(),
                            extension.c_str() );
}
Beispiel #5
0
XIRef<XDomParserNode> SoapArgs::_GetNode( const XString& path, XIRef<XDomParserNode> parent )
{
    const size_t dot = path.find('.');
    XString front = path.substr(0, dot);
    XString rest = dot == string::npos ? "" : path.substr(dot + 1);

    const list<XIRef<XDomParserNode> >::const_iterator end = parent->GetChildren().end();
    list<XIRef<XDomParserNode> >::const_iterator found = end;

    for(list<XIRef<XDomParserNode> >::const_iterator iter = parent->GetChildren().begin();
        iter != end;
        ++iter)
    {
        if((*iter)->GetTagName() == front)
        {
            found = iter;
            break;
        }
    }

    if(found != end)
        return rest.empty() ? *found : _GetNode(rest, *found);

    XIRef<XDomParserNode> node(new XDomParserNode(XString::Format("<%s>", front.c_str())));
    parent->AppendChild(node);

    if(!rest.empty())
        return _GetNode(rest, node);

    return node;


    /*
    // Key - "foo.bar.alpha"
    // In this case, foo and bar are CONTAINER_TYPE and alpha is a VALUE_TYPE

    SoapArgs* existingNode = current->Find( path);

    if(existingNode)
    {
    }

    vector<XString> parts;
    key.Split( ".", parts );

    XHash<SoapArgsNode>* current = &_complex;


    if( !parts.empty() )
    {
        XString currPath = parts[0];
        size_t limit = parts.size() - 1;

        // Loop over all the CONTAINER_TYPE parts of the path...
        for( size_t i = 0; i < limit; ++i )
        {
            SoapArgsNode* found = current->Find( currPath );

            if( found )
            {
                current = &found->_children;
            }
            else
            {
                SoapArgsNode node;
                node._nodeType = CONTAINER_TYPE;
                node._name = parts[i];
                current->Add( currPath, node );
                SoapArgsNode* foundNode = current->Find( currPath );
                current = &foundNode->_children;
            }

            currPath += "." + parts[i];
        }

        SoapArgsNode* found == current->Find( path );

        if(found)
        {
            SoapArgs node = *found;
            current->Remove( parts[i] );

            return found;
        }
    }

    SoapArgsNode node;
    node._nodeType = VALUE_TYPE;
    node._name = !parts.empty() ? parts[i] : key;
    */
}
Beispiel #6
0
void TranscodeExport::Create( XIRef<XMemory> output )
{
    XString tempFileName = _GetTMPName( _fileName );

    // If their is only 1 export in progress (us), but the temp file exists then it means we were interrupted
    // (either a power issue, or a segfault) and we should delete the temporary.
    if( _exportsInProgress == 1 )
    {
        if( XPath::Exists(tempFileName) )
            unlink(tempFileName.c_str());
    }

    if( XPath::Exists(tempFileName) )
        X_THROW(("Export in progress exception: %s", tempFileName.c_str()));

    bool outputToFile = (output.IsEmpty()) ? true : false;
    H264Decoder decoder( GetFastH264DecoderOptions() );
    XRef<YUV420PToARGB24> yuvToARGB = new YUV420PToARGB24;
    XRef<ARGB24ToYUV420P> argbToYUV = new ARGB24ToYUV420P;
    XRef<H264Transcoder> transcoder;
    XRef<H264Encoder> encoder;
    XRef<AVMuxer> muxer;
    XRef<ExportOverlay> ov;
    bool wroteToContainer = false;

    auto lastProgressTime = steady_clock::now();

    // We are going to count how many decoding or encoding exceptions we get... If it
    // ever exceeds some large threshold, we bail on this export.
    int64_t codingExceptions = 0;

    XString recorderURI;
    while( _recorderURLS.GetNextURL( recorderURI ) )
    {
        auto now = steady_clock::now();
        if( wroteToContainer && duration_cast<seconds>(now-lastProgressTime).count() > 2 )
        {
            _progress( _recorderURLS.PercentComplete() );
            lastProgressTime = now;
        }
        
        try
        {
            XIRef<XMemory> responseBuffer = FRAME_STORE_CLIENT::FetchMedia( _config->GetRecorderIP(),
                                                                            _config->GetRecorderPort(),
                                                                            recorderURI );

            ResultParser resultParser;

            resultParser.Parse( responseBuffer );

            FRAME_STORE_CLIENT::ResultStatistics stats = resultParser.GetStatistics();

            // If we are not provided with a bit rate or a frame rate, we use the sources values.
            if( _bitRate == 0 )
                _bitRate = stats.averageBitRate;
            
            if( _maxRate == 0 )
                _maxRate = 2 * stats.averageBitRate;

            if( _bufSize == 0 )
                _bufSize = 2 * stats.averageBitRate;

            if( _frameRate == 0.0 )
                _frameRate = stats.frameRate;

            // Fix for ffmpeg's inability to make files with fps < 6.0. Don't believe me? Try these 2 commands and play
            // output in vlc:
            //
            //   # generate a test movie of the game of life in life.mp4
            //   ffmpeg -f lavfi -i life -frames:v 1000 life.mp4
            //   # transcode and drop framerate of life.mp4 to 1 fps. output.mp4 won't play in vlc and will have a weird
            //   # pause at the beginning for other players.
            //   ffmpeg -i life.mp4 -vf fps=fps=1/1 -vcodec h264 output.mp4
            //
            if( _frameRate < 6.0 )
                _frameRate = 6.0;

            int outputTimeBaseNum = 0;
            int outputTimeBaseDen = 0;
            int inputTimeBaseNum = 0;
            int inputTimeBaseDen = 0;

            AVKit::DToQ( (1/stats.frameRate), inputTimeBaseNum, inputTimeBaseDen );
            AVKit::DToQ( (1/_frameRate), outputTimeBaseNum, outputTimeBaseDen );

            if( transcoder.IsEmpty() )
            {
                transcoder = new H264Transcoder( inputTimeBaseNum, inputTimeBaseDen,
                                                 outputTimeBaseNum, outputTimeBaseDen,
                                                 _speed,
                                                 // if our input is key only, enable decode skipping...
                                                 _recorderURLS.KeyFrameOnly() );
            }

            double secondsPer = AVKit::QToD(inputTimeBaseNum, inputTimeBaseDen) / (AVKit::QToD(inputTimeBaseNum, inputTimeBaseDen) / (AVKit::QToD(outputTimeBaseNum, outputTimeBaseDen) * _speed));
            int traversalNum = 0;
            int traversalDen = 0;

            AVKit::DToQ( secondsPer, traversalNum, traversalDen );

            while( !resultParser.EndOfFile() )
            {
                try
                {
                    if( transcoder->Decode( resultParser, decoder ) )
                    {
                        if( encoder.IsEmpty() )
                            _FinishInit( encoder, muxer, decoder, tempFileName, outputToFile, traversalNum, traversalDen );

                        if( ov.IsEmpty() )
                            ov = new ExportOverlay( _msg,
                                                    _withTime,
                                                    _hAlign,
                                                    _vAlign,
                                                    decoder.GetOutputWidth(),
                                                    decoder.GetOutputHeight(),
                                                    traversalNum,
                                                    traversalDen );

                        yuvToARGB->Transform( decoder.Get(), decoder.GetOutputWidth(), decoder.GetOutputHeight() );

                        XIRef<Packet> rgb = yuvToARGB->Get();

                        XIRef<Packet> withOverlay = ov->Process( rgb, resultParser.GetFrameTS() );

                        argbToYUV->Transform( withOverlay, decoder.GetOutputWidth(), decoder.GetOutputHeight() );

                        transcoder->EncodeYUV420PAndMux( *encoder, *muxer, argbToYUV->Get() );
                        wroteToContainer = true;
                    }
                }
                catch(XException& ex)
                {
                    X_LOG_NOTICE("Coding exception: %s",ex.what());
                    
                    ++codingExceptions;

                    // If we have had a LOT of decoding or encoding exceptions, just give up.
                    if( codingExceptions > 100000 )
                        throw ex;
                }
            }
        }
        catch( XException& ex )
        {
            X_LOG_NOTICE("Exception thrown while processing export. Continuing: %s",ex.what());
        }
    }

	if( wroteToContainer )
        _progress( 1.0 );
    else X_STHROW( HTTP404Exception, ("No video was found during entire export."));

    if( outputToFile )
    {
        muxer->FinalizeFile();
        rename( tempFileName.c_str(), _fileName.c_str() );
    }
    else muxer->FinalizeBuffer( output );
}