UINT String::GetLinePos(UINT dwLine) { assert(lpString); if(!lpString) return 0; if(!dwLine) return 0; TSTR lpTemp = lpString; for(UINT i=0; i<dwLine; i++) { TSTR lpNewLine = schr(lpTemp, '\n'); if(!lpNewLine) break; lpTemp = lpNewLine+1; } return UINT(lpTemp-lpString); }
//проверка на запрещённые символы int chk_err_sym(char str[]) { char err_sym[] = { '?', '<', '>', '|', '"', '@', '+', ',', '*', '#', ';', '$', '%', '^', '&', '(', ')', '\0' }; int len = slen(err_sym), i; int flg = -1; for (i = 0; i < len; i++) { flg = schr(str, err_sym[i]); if (flg != -1) { break; } } int j, len_str = slen(str); for (j = 0; j < len_str; j++) { if (((str[j] == '\\') && (str[j + 1] == '\\')) || ((str[j] == '/') && (str[j + 1] == '/'))) { flg = j; } } return flg; }
bool XConfig::ReadFileData(XElement *curElement, int level, TSTR &lpTemp) { while(*lpTemp) { if(*lpTemp == '}') return level != 0; if(*lpTemp == '{') //unnamed object, usually only happens at the start of the file, ignore { ++lpTemp; if(!ReadFileData(curElement, level+1, lpTemp)) return false; } else if(*lpTemp != ' ' && *lpTemp != L' ' && *lpTemp != '\t' && *lpTemp != '\r' && *lpTemp != '\n' && *lpTemp != ',') { String strName; if(*lpTemp == '"') strName = ProcessString(lpTemp); else { TSTR lpDataStart = lpTemp; lpTemp = schr(lpTemp, ':'); if(!lpTemp) return false; *lpTemp = 0; strName = lpDataStart; *lpTemp = ':'; strName.KillSpaces(); } //--------------------------- lpTemp = schr(lpTemp, ':'); if(!lpTemp) return false; ++lpTemp; while( *lpTemp == ' ' || *lpTemp == L' ' || *lpTemp == '\t' ) { ++lpTemp; } //--------------------------- if(*lpTemp == '{') //element { ++lpTemp; XElement *newElement = curElement->CreateElement(strName); if(!ReadFileData(newElement, level+1, lpTemp)) return false; } else //item { String data; if(*lpTemp == '"') data = ProcessString(lpTemp); else { TSTR lpDataStart = lpTemp; lpTemp = schr(lpTemp, '\n'); if(!lpTemp) return false; if(lpTemp[-1] == '\r') --lpTemp; if(lpTemp != lpDataStart) { TCHAR oldChar = *lpTemp; *lpTemp = 0; data = lpDataStart; *lpTemp = oldChar; data.KillSpaces(); } } lpTemp = schr(lpTemp, '\n'); if(!lpTemp && curElement != RootElement) return false; curElement->SubItems << new XDataItem(strName, data); } } ++lpTemp; } return (curElement == RootElement); }
void XConfig::WriteFileItem(XFile &file, int indent, XBaseItem *baseItem) { int j; if(baseItem->IsData()) { XDataItem *item = static_cast<XDataItem*>(baseItem); String strItem; for(j=0; j<indent; j++) strItem << TEXT(" "); if( item->strName.IsValid() && ( item->strName[0] == ' ' || item->strName[0] == '\t' || item->strName[0] == '{' || item->strName[item->strName.Length()-1] == ' ' || item->strName[item->strName.Length()-1] == '\t' || schr(item->strName, '\n') || schr(item->strName, '"') || schr(item->strName, ':') )) { strItem << ConvertToTextString(item->strName); } else strItem << item->strName; strItem << TEXT(" : "); if( item->strData.IsValid() && ( item->strData[0] == ' ' || item->strData[0] == '\t' || item->strData[0] == '{' || item->strData[item->strData.Length()-1] == ' ' || item->strData[item->strData.Length()-1] == '\t' || schr(item->strData, '\n') || schr(item->strData, '"') || schr(item->strData, ':') )) { strItem << ConvertToTextString(item->strData); } else strItem << item->strData; strItem << TEXT("\r\n"); file.WriteAsUTF8(strItem); } else if(baseItem->IsElement()) { XElement *element = static_cast<XElement*>(baseItem); String strElement; for(j=0; j<indent; j++) strElement << TEXT(" "); if( element->strName.IsValid() && ( element->strName[0] == ' ' || element->strName[0] == '\t' || element->strName[0] == '{' || element->strName[element->strName.Length()-1] == ' ' || element->strName[element->strName.Length()-1] == '\t' || schr(element->strName, '\n') || schr(element->strName, '"') || schr(element->strName, ':') )) { strElement << ConvertToTextString(element->strName); } else strElement << element->strName; strElement << TEXT(" : {\r\n"); file.WriteAsUTF8(strElement); strElement.Clear(); WriteFileData(file, indent+1, element); for(j=0; j<indent; j++) strElement << TEXT(" "); strElement << TEXT("}\r\n"); file.WriteAsUTF8(strElement); } }
QSVEncoder(int fps_, int width, int height, int quality, CTSTR preset, bool bUse444, ColorDescription &colorDesc, int maxBitrate, int bufferSize, bool bUseCFR_) : bFirstFrameProcessed(false), width(width), height(height), max_bitrate(maxBitrate) { fps = fps_; bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR")) != 0; bUseCFR = bUseCFR_; UINT keyframeInterval = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), 6); int keyint = fps*keyframeInterval; int bframes = 7; bool bHaveCustomImpl = false; impl_parameters custom = { 0 }; BOOL bUseCustomParams = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCustomSettings")) && AppConfig->GetInt(TEXT("Video Encoding"), TEXT("QSVUseVideoEncoderSettings")); if(bUseCustomParams) { StringList paramList; String strCustomParams = AppConfig->GetString(TEXT("Video Encoding"), TEXT("CustomSettings")); strCustomParams.KillSpaces(); if(strCustomParams.IsValid()) { Log(TEXT("Using custom encoder settings: \"%s\""), strCustomParams.Array()); strCustomParams.GetTokenList(paramList, ' ', FALSE); for(UINT i=0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if(!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if(strParamName == "keyint") { int keyint_ = strParamVal.ToInt(); if(keyint_ < 0) continue; keyint = keyint_; } else if(strParamName == "bframes") { int bframes_ = strParamVal.ToInt(); if(bframes_ < 0) continue; bframes = bframes_; } else if(strParamName == "qsvimpl") { StringList bits; strParamVal.GetTokenList(bits, ',', true); if(bits.Num() < 3) continue; StringList version; bits[2].GetTokenList(version, '.', false); if(version.Num() != 2) continue; custom.type = bits[0].ToInt(); if(custom.type == 0) custom.type = MFX_IMPL_HARDWARE_ANY; auto &intf = bits[1].MakeLower(); custom.intf = intf == "d3d11" ? MFX_IMPL_VIA_D3D11 : (intf == "d3d9" ? MFX_IMPL_VIA_D3D9 : MFX_IMPL_VIA_ANY); custom.version.Major = version[0].ToInt(); custom.version.Minor = version[1].ToInt(); bHaveCustomImpl = true; } } } } if(!spawn_helper(event_prefix, qsvhelper_process, qsvhelper_thread, process_waiter)) CrashError(TEXT("Couldn't launch QSVHelper: %u"), GetLastError()); ipc_init_request request((event_prefix + INIT_REQUEST).Array()); request->mode = request->MODE_ENCODE; request->obs_process_id = GetCurrentProcessId(); request->fps = fps_; request->keyint = keyint; request->bframes = bframes; request->width = width; request->height = height; request->max_bitrate = maxBitrate; request->buffer_size = bufferSize; request->use_cbr = bUseCBR; request->full_range = colorDesc.fullRange; request->matrix = colorDesc.matrix; request->primaries = colorDesc.primaries; request->transfer = colorDesc.transfer; request->use_custom_impl = bHaveCustomImpl; request->custom_impl = custom.type; request->custom_intf = custom.intf; request->custom_version = custom.version; request.signal(); ipc_init_response response((event_prefix + INIT_RESPONSE).Array()); IPCWaiter response_waiter = process_waiter; response_waiter.push_back(response.signal_); if(response_waiter.wait_for_two(0, 1, INFINITE)) { DWORD code = 0; if(!GetExitCodeProcess(qsvhelper_process.h, &code)) CrashError(TEXT("Failed to initialize QSV session.")); switch(code) { case EXIT_INCOMPATIBLE_CONFIGURATION: CrashError(TEXT("QSVHelper.exe has exited because of an incompatible qsvimpl custom parameter (before response)")); case EXIT_NO_VALID_CONFIGURATION: if(OSGetVersion() < 8) CrashError(TEXT("QSVHelper.exe could not find a valid configuration. Make sure you have a (virtual) display connected to your iGPU")); CrashError(TEXT("QSVHelper.exe could not find a valid configuration")); default: CrashError(TEXT("QSVHelper.exe has exited with code %i (before response)"), code); } } Log(TEXT("------------------------------------------")); if(bHaveCustomImpl && !response->using_custom_impl) AppWarning(TEXT("Could not initialize QSV session using custom settings")); ver = response->version; auto intf_str = qsv_intf_str(response->requested_impl), actual_intf_str = qsv_intf_str(response->actual_impl); auto length = std::distance(std::begin(implStr), std::end(implStr)); auto impl = response->requested_impl & (MFX_IMPL_VIA_ANY - 1); if(impl > length) impl = static_cast<mfxIMPL>(length-1); Log(TEXT("QSV version %u.%u using %s%s (actual: %s%s)"), ver.Major, ver.Minor, implStr[impl], intf_str, implStr[response->actual_impl & (MFX_IMPL_VIA_ANY - 1)], actual_intf_str); target_usage = response->target_usage; encode_tasks.SetSize(response->bitstream_num); bs_buff = ipc_bitstream_buff((event_prefix + BITSTREAM_BUFF).Array(), response->bitstream_size*response->bitstream_num); if(!bs_buff) CrashError(TEXT("Failed to initialize QSV bitstream buffer (%u)"), GetLastError()); mfxU8 *bs_start = (mfxU8*)(((size_t)&bs_buff + 31)/32*32); for(unsigned i = 0; i < encode_tasks.Num(); i++) { zero(encode_tasks[i].surf); mfxBitstream &bs = encode_tasks[i].bs; zero(bs); bs.Data = bs_start + i*response->bitstream_size; bs.MaxLength = response->bitstream_size; idle_tasks << i; } frames.SetSize(response->frame_num); frame_buff = ipc_frame_buff((event_prefix + FRAME_BUFF).Array(), response->frame_size*response->frame_num); if(!frame_buff) CrashError(TEXT("Failed to initialize QSV frame buffer (%u)"), GetLastError()); mfxU8 *frame_start = (mfxU8*)(((size_t)&frame_buff + 15)/16*16); for(unsigned i = 0; i < frames.Num(); i++) { mfxFrameData& frame = frames[i]; zero(frame); frame.Y = frame_start + i * response->frame_size; frame.UV = frame_start + i * response->frame_size + response->UV_offset; frame.V = frame_start + i * response->frame_size + response->V_offset; frame.Pitch = response->frame_pitch; } Log(TEXT("Using %u bitstreams and %u frame buffers"), encode_tasks.Num(), frames.Num()); Log(TEXT("------------------------------------------")); Log(GetInfoString()); Log(TEXT("------------------------------------------")); DataPacket packet; GetHeaders(packet); frame_queue = ipc_frame_queue((event_prefix + FRAME_QUEUE).Array(), frames.Num()); if(!frame_queue) CrashError(TEXT("Failed to initialize frame queue (%u)"), GetLastError()); frame_buff_status = ipc_frame_buff_status((event_prefix + FRAME_BUFF_STATUS).Array(), frames.Num()); if(!frame_buff_status) CrashError(TEXT("Failed to initialize QSV frame buffer status (%u)"), GetLastError()); bs_info = ipc_bitstream_info((event_prefix + BITSTREAM_INFO).Array(), response->bitstream_num); if(!bs_info) CrashError(TEXT("Failed to initialize QSV bitstream info (%u)"), GetLastError()); filled_bitstream = ipc_filled_bitstream((event_prefix + FILLED_BITSTREAM).Array()); if(!filled_bitstream) CrashError(TEXT("Failed to initialize bitstream signal (%u)"), GetLastError()); stop = ipc_stop((event_prefix + STOP_REQUEST).Array()); if(!stop) CrashError(TEXT("Failed to initialize QSV stop signal (%u)"), GetLastError()); filled_bitstream_waiter = process_waiter; filled_bitstream_waiter.push_back(filled_bitstream.signal_); }
/* Add cache configuration to the route. This can be called multiple times. Uris, extensions and methods may optionally provide a space or comma separated list of items. If URI is NULL or "*", cache all URIs for this route. Otherwise, cache only the given URIs. The URIs may contain an ordered set of request parameters. For example: "/user/show?name=john&posts=true" Note: the URI should not include the route prefix (scriptName) The extensions should not contain ".". The methods may contain "*" for all methods. */ void httpAddCache(HttpRoute *route, cchar *methods, cchar *uris, cchar *extensions, cchar *types, MprTime clientLifespan, MprTime serverLifespan, int flags) { HttpCache *cache; char *item, *tok; cache = 0; if (!route->caching) { httpAddRouteHandler(route, "cacheHandler", ""); httpAddRouteFilter(route, "cacheFilter", "", HTTP_STAGE_TX); route->caching = mprCreateList(0, 0); } else if (flags & HTTP_CACHE_RESET) { route->caching = mprCreateList(0, 0); } else if (route->parent && route->caching == route->parent->caching) { route->caching = mprCloneList(route->parent->caching); } if ((cache = mprAllocObj(HttpCache, manageHttpCache)) == 0) { return; } if (extensions) { cache->extensions = mprCreateHash(0, 0); for (item = stok(sclone(extensions), " \t,", &tok); item; item = stok(0, " \t,", &tok)) { if (smatch(item, "*")) { extensions = 0; } else { mprAddKey(cache->extensions, item, cache); } } } else if (types) { cache->types = mprCreateHash(0, 0); for (item = stok(sclone(types), " \t,", &tok); item; item = stok(0, " \t,", &tok)) { if (smatch(item, "*")) { extensions = 0; } else { mprAddKey(cache->types, item, cache); } } } if (methods) { cache->methods = mprCreateHash(0, MPR_HASH_CASELESS); for (item = stok(sclone(methods), " \t,", &tok); item; item = stok(0, " \t,", &tok)) { if (smatch(item, "*")) { methods = 0; } else { mprAddKey(cache->methods, item, cache); } } } if (uris) { cache->uris = mprCreateHash(0, 0); for (item = stok(sclone(uris), " \t,", &tok); item; item = stok(0, " \t,", &tok)) { if (flags & HTTP_CACHE_ONLY && route->prefix && !scontains(item, sfmt("prefix=%s", route->prefix))) { /* Auto-add ?prefix=ROUTE_NAME if there is no query */ if (!schr(item, '?')) { item = sfmt("%s?prefix=%s", item, route->prefix); } } mprAddKey(cache->uris, item, cache); } } if (clientLifespan <= 0) { clientLifespan = route->lifespan; } cache->clientLifespan = clientLifespan; if (serverLifespan <= 0) { serverLifespan = route->lifespan; } cache->serverLifespan = serverLifespan; cache->flags = flags; mprAddItem(route->caching, cache); #if UNUSED && KEEP mprLog(3, "Caching route %s for methods %s, URIs %s, extensions %s, types %s, client lifespan %d, server lifespan %d", route->name, (methods) ? methods: "*", (uris) ? uris: "*", (extensions) ? extensions: "*", (types) ? types: "*", cache->clientLifespan / MPR_TICKS_PER_SEC); cache->serverLifespan / MPR_TICKS_PER_SEC); #endif }
bool UploadLogGitHub(String filename, String logData, LogUploadResult &result) { String description = FormattedString(OBS_VERSION_STRING L" log file uploaded at %s (local time).", CurrentDateTimeString().Array()); String age = LogFileAge(filename); if (age.IsValid()) description << FormattedString(L" The log file was approximately %s old at the time it was uploaded.", age.Array()); StringEscapeJson(description); StringEscapeJson(filename); StringEscapeJson(logData); String json = FormattedString(L"{ \"public\": false, \"description\": \"%s\", \"files\": { \"%s\": { \"content\": \"%s\" } } }", description.Array(), filename.Array(), logData.Array()); int response = 0; List<BYTE> body; if (!HTTPPostData(String(L"https://api.github.com/gists"), json, response, &body)) { result.errors << Str("LogUpload.CommunicationError"); return false; } if (response != 201) { result.errors << FormattedString(Str("LogUpload.ServiceReturnedError"), response) << FormattedString(Str("LogUpload.ServiceExpectedResponse"), 201); return false; } auto invalid_response = [&]() -> bool { result.errors << Str("LogUpload.ServiceReturnedInvalidResponse"); return false; }; if (body.Num() < 1) return invalid_response(); //make sure it's null terminated since we run string ops on it below body.Add (0); TSTR wideBody = utf8_createTstr((char const*)body.Array()); String bodyStr(wideBody); Free(wideBody); TSTR pos = sstr(bodyStr.Array(), L"\"html_url\""); if (!pos) return invalid_response(); pos = schr(pos + slen(L"\"html_url\""), '"'); if (!pos) return invalid_response(); pos += 1; TSTR end = schr(pos, '"'); if (!end) return invalid_response(); if ((end - pos) < 4) return invalid_response(); result.url = bodyStr.Mid((UINT)(pos - bodyStr.Array()), (UINT)(end - bodyStr.Array())); if (!HTTPFindRedirect(result.url, result.analyzerURL)) //the basic url doesn't work with the analyzer, so query the fully redirected url result.analyzerURL = result.url; return true; }
static bool inRange(MprVersion *vp, cchar *expr) { char *cp, *ver, *op, *base, *pre, *all; cchar *high, *low; uint64 factor, min, max, num; while (isspace((uchar) *expr)) expr++; if (srmatch(expr, semExpr, &all, &op, &ver, NULL) <= 0) { mprLog("error", 5, "Bad version expression: %s", expr); return 0; } if (smatch(op, "~")) { /* ~VER Compatible with VER at the level of specificity given. ~1.2.3 == (>=1.2.3 <1.3.0) Compatible at the patch level ~1.2 == 1.2.x Compatible at the minor level ~1 == 1.x Compatible at the major level */ if (partCount(ver) == 3 && (cp = srchr(ver, '.')) != 0) { high = sjoin(snclone(ver, cp - ver), ".", MAX_VER_STR, NULL); if ((cp = schr(ver, '-')) != 0) { high = sjoin(high, cp, NULL); } return inRange(vp, sjoin(">=", ver, NULL)) && inRange(vp, sjoin("<", high, NULL)); } return inRange(vp, completeVersion(ver, "x")); } if (smatch(op, "^")) { /* ^VER Compatible with VER at the most significant level. ^0.2.3 == 0.2.3 <= VER < 0.3.0 ^1.2.3 == 1.2.3 <= VER < 2.0.0 So convert to a range */ high = ver; for (cp = ver, factor = VER_FACTOR * VER_FACTOR; *cp; cp++) { if (*cp == '.') { factor /= VER_FACTOR; } else if (isdigit((uchar) *cp) && *cp != '0') { num = (stoi(cp) + 1) * factor; high = numberToVersion(num); if ((cp = schr(ver, '-')) != 0) { high = sjoin(high, cp, NULL); } break; } } return inRange(vp, sjoin(">=", ver, NULL)) && inRange(vp, sjoin("<", high, NULL)); } ver = completeVersion(ver, "x"); if (srmatch(ver, semCriteria, &all, &base, &pre, NULL) <= 0) { mprLog("error", 5, "Cannot match version %s", ver); return 0; } if (vp->preVersion) { if (!pre) { return 0; } if (snumber(vp->preVersion)) { if (stoi(pre) < stoi(vp->preVersion)) { return 0; } } else { if (scmp(pre, vp->preVersion) < 0 && !smatch(pre, "-")) { return 0; } } } min = 0; max = MAX_VER * VER_FACTOR * VER_FACTOR; if (schr(ver, 'x')) { if (smatch(op, ">=")) { // 1.2.3 >= 2.x.x ... 1.2.3 >= 2.0.0 low = sreplace(ver, "x", "0"); min = versionToNumber(low); } else if (smatch(op, "<=")) { // 1.2.3 < 2.x.x ... 1.2.3 <2.MAX.MAX high = sreplace(ver, "x", MAX_VER_STR); max = versionToNumber(high); } else if (*op == '>') { // 1.2.3 > 2.x.x ... 1.2.3 > 2.0.0 low = sreplace(ver, "x", "0"); min = versionToNumber(low) + 1; } else if (*op == '<') { // 1.2.3 < 2.x.x ... 1.2.3 <2.MAX.MAX high = sreplace(ver, "x", MAX_VER_STR); max = versionToNumber(high) - 1; } else { low = sreplace(ver, "x", "0"); high = sreplace(ver, "x", MAX_VER_STR); return inRange(vp, sjoin(">=", low, NULL)) && inRange(vp, sjoin("<", high, NULL)); } } else if (smatch(op, ">=")) { min = versionToNumber(base); } else if (smatch(op, "<=")) { max = versionToNumber(base); } else if (*op == '>') { min = versionToNumber(base) + 1; } else if (*op == '<') { max = versionToNumber(base) - 1; } else { min = max = versionToNumber(base); } if (min <= vp->numberVersion && vp->numberVersion <= max) { return 1; } return 0; }
void ConfigFile::SetKey(CTSTR lpSection, CTSTR lpKey, CTSTR newvalue) { assert(lpSection); assert(lpKey); TSTR lpTemp = lpFileData, lpEnd = &lpFileData[dwLength], lpSectionStart; DWORD dwSectionNameSize = slen(lpSection), dwKeyNameSize = slen(lpKey); BOOL bInSection = 0; do { lpTemp = sstr(lpTemp, TEXT("\n[")); if(!lpTemp) break; lpTemp += 2; if((scmpi_n(lpTemp, lpSection, dwSectionNameSize) == 0) && (lpTemp[dwSectionNameSize] == ']')) { bInSection = 1; lpSectionStart = lpTemp = schr(lpTemp, '\n')+1; break; } }while(lpTemp < lpEnd); if(!bInSection) { lpTemp -= 2; XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], dwLength-4); file.Write("\r\n[", 3); file.WriteAsUTF8(lpSection, dwSectionNameSize); file.Write("]\r\n", 3); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } do { if(*lpTemp == '[') { XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], DWORD(lpSectionStart-lpFileData-2)); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.WriteAsUTF8(lpSectionStart, slen(lpSectionStart)-2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } else if(*(LPWORD)lpTemp == '//') { lpTemp = schr(lpTemp, '\n')+1; continue; } else if(bInSection) { if((scmpi_n(lpTemp, lpKey, dwKeyNameSize) == 0) && (lpTemp[dwKeyNameSize] == '=')) { lpTemp = &lpTemp[dwKeyNameSize+1]; TSTR lpNextLine = schr(lpTemp, '\r'); int newlen = slen(newvalue); if ((*lpTemp == '\r' && *newvalue == '\0') || (lpNextLine - lpTemp == newlen && !scmp_n(lpTemp, newvalue, newlen))) return; String tmpFileName = strFileName; tmpFileName += TEXT(".tmp"); XFile file; if (file.Open(tmpFileName, XFILE_WRITE, XFILE_CREATEALWAYS)) { if (file.Write("\xEF\xBB\xBF", 3) != 3) return; if (!file.WriteAsUTF8(&lpFileData[2], DWORD(lpTemp - lpFileData - 2))) return; if (!file.WriteAsUTF8(newvalue, slen(newvalue))) return; if (!file.WriteAsUTF8(lpNextLine, slen(lpNextLine) - 2)) return; file.Close(); if (!OSRenameFile(tmpFileName, strFileName)) Log(TEXT("ConfigFile::SetKey: Unable to move new config file %s to %s"), tmpFileName.Array(), strFileName.Array()); } if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } } lpTemp = schr(lpTemp, '\n')+1; }while(lpTemp < lpEnd); XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], DWORD(lpSectionStart-lpFileData-2)); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.WriteAsUTF8(lpSectionStart, slen(lpSectionStart)-2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); }
void ConfigFile::LoadData() { TSTR lpCurLine = lpFileData, lpNextLine; ConfigSection *lpCurSection=NULL; DWORD i; lpNextLine = schr(lpCurLine, '\r'); while(*(lpCurLine = (lpNextLine+2))) { lpNextLine = schr(lpCurLine, '\r'); if (!lpNextLine) CrashError(TEXT("Your %s file is corrupt, please delete it and re-launch OBS."), strFileName.Array()); *lpNextLine = 0; if((*lpCurLine == '[') && (*(lpNextLine-1) == ']')) { lpCurSection = Sections.CreateNew(); lpCurSection->name = sfix(sdup(lpCurLine+1)); lpCurSection->name[lpNextLine-lpCurLine-2] = 0; } else if(lpCurSection && *lpCurLine && (*(LPWORD)lpCurLine != '//')) { TSTR lpValuePtr = schr(lpCurLine, '='); if (!lpValuePtr) CrashError(TEXT("Your %s file is corrupt, please delete it and re-launch OBS."), strFileName.Array()); if(lpValuePtr[1] != 0) { ConfigKey *key=NULL; *lpValuePtr = 0; for(i=0; i<lpCurSection->Keys.Num(); i++) { if(scmpi(lpCurLine, lpCurSection->Keys[i].name) == 0) { key = &lpCurSection->Keys[i]; break; } } if(!key) { key = lpCurSection->Keys.CreateNew(); key->name = sfix(sdup(lpCurLine)); } *lpValuePtr = '='; lpCurLine = lpValuePtr+1; TSTR value = sfix(sdup(lpCurLine)); key->ValueList << value; } } *lpNextLine = '\r'; } }
/* Create and initialize a URI. This accepts full URIs with schemes (http:) and partial URLs Support IPv4 and [IPv6]. Supported forms: SCHEME://[::]:PORT/URI SCHEME://HOST:PORT/URI [::]:PORT/URI :PORT/URI HOST:PORT/URI PORT/URI /URI URI NOTE: HOST/URI is not supported and requires a scheme prefix. This is because it is ambiguous with a relative uri path. Missing fields are null or zero. */ PUBLIC HttpUri *httpCreateUri(cchar *uri, int flags) { HttpUri *up; char *tok, *next; if ((up = mprAllocObj(HttpUri, manageUri)) == 0) { return 0; } tok = sclone(uri); /* [scheme://][hostname[:port]][/path[.ext]][#ref][?query] First trim query and then reference from the end */ if ((next = schr(tok, '?')) != 0) { *next++ = '\0'; up->query = sclone(next); } if ((next = schr(tok, '#')) != 0) { *next++ = '\0'; up->reference = sclone(next); } /* [scheme://][hostname[:port]][/path] */ if ((next = scontains(tok, "://")) != 0) { up->scheme = snclone(tok, (next - tok)); if (smatch(up->scheme, "http")) { if (flags & HTTP_COMPLETE_URI) { up->port = 80; } } else if (smatch(up->scheme, "ws")) { if (flags & HTTP_COMPLETE_URI) { up->port = 80; } up->webSockets = 1; } else if (smatch(up->scheme, "https")) { if (flags & HTTP_COMPLETE_URI) { up->port = 443; } up->secure = 1; } else if (smatch(up->scheme, "wss")) { if (flags & HTTP_COMPLETE_URI) { up->port = 443; } up->secure = 1; up->webSockets = 1; } tok = &next[3]; } /* [hostname[:port]][/path] */ if (*tok == '[' && ((next = strchr(tok, ']')) != 0)) { /* IPv6 [::]:port/uri */ up->host = snclone(&tok[1], (next - tok) - 1); tok = ++next; } else if (*tok && *tok != '/' && *tok != ':' && (up->scheme || strchr(tok, ':'))) { /* Supported forms: scheme://hostname hostname:port */ if ((next = spbrk(tok, ":/")) == 0) { next = &tok[slen(tok)]; } up->host = snclone(tok, next - tok); tok = next; } assert(tok); /* [:port][/path] */ if (*tok == ':') { up->port = atoi(++tok); if ((tok = schr(tok, '/')) == 0) { tok = ""; } } assert(tok); /* [/path] */ if (*tok) { up->path = sclone(tok); /* path[.ext[/extra]] */ if ((tok = srchr(up->path, '.')) != 0) { if (tok[1]) { if ((next = srchr(up->path, '/')) != 0) { if (next < tok) { up->ext = sclone(++tok); } } else { up->ext = sclone(++tok); } } } } if (flags & (HTTP_COMPLETE_URI | HTTP_COMPLETE_URI_PATH)) { if (up->path == 0 || *up->path == '\0') { up->path = sclone("/"); } } up->secure = smatch(up->scheme, "https") || smatch(up->scheme, "wss"); up->webSockets = (smatch(up->scheme, "ws") || smatch(up->scheme, "wss")); if (flags & HTTP_COMPLETE_URI) { if (!up->scheme) { up->scheme = sclone("http"); } if (!up->host) { up->host = sclone("localhost"); } if (!up->port) { up->port = up->secure ? 443 : 80; } } up->valid = httpValidUriChars(uri); return up; }
Color4 ConfigFile::GetColor(CTSTR lpSection, CTSTR lpKey) { assert(lpSection); assert(lpKey); DWORD i,j; for(i=0; i<Sections.Num(); i++) { ConfigSection §ion = Sections[i]; if(scmpi(lpSection, section.name) == 0) { for(j=0; j<section.Keys.Num(); j++) { ConfigKey &key = section.Keys[j]; if(scmpi(lpKey, key.name) == 0) { TSTR strValue = key.ValueList[0]; if(*strValue == '{') { Color4 ret; ret.x = float(tstof(++strValue)); if(!(strValue = schr(strValue, ','))) break; ret.y = float(tstof(++strValue)); if(!(strValue = schr(strValue, ','))) break; ret.z = float(tstof(++strValue)); if(!(strValue = schr(strValue, ','))) { ret.w = 1.0f; return ret; } ret.w = float(tstof(++strValue)); return ret; } else if(*strValue == '[') { Color4 ret; ret.x = (float(tstoi(++strValue))/255.0f)+0.001f; if(!(strValue = schr(strValue, ','))) break; ret.y = (float(tstoi(++strValue))/255.0f)+0.001f; if(!(strValue = schr(strValue, ','))) break; ret.z = (float(tstoi(++strValue))/255.0f)+0.001f; if(!(strValue = schr(strValue, ','))) { ret.w = 1.0f; return ret; } ret.w = (float(tstoi(++strValue))/255.0f)+0.001f; return ret; } else if( (*LPWORD(strValue) == 'x0') || (*LPWORD(strValue) == 'X0') ) { return RGBA_to_Vect4(tstring_base_to_int(strValue+2, NULL, 16)); } } } } } return Color4(0.0f, 0.0f, 0.0f, 0.0f); }
/* Format a string URI from parts */ PUBLIC char *httpFormatUri(cchar *scheme, cchar *host, int port, cchar *path, cchar *reference, cchar *query, int flags) { char *uri; cchar *portStr, *hostDelim, *portDelim, *pathDelim, *queryDelim, *referenceDelim, *cp; portDelim = ""; portStr = ""; hostDelim = ""; if (flags & HTTP_COMPLETE_URI) { if (scheme == 0 || *scheme == '\0') { scheme = "http"; } if (host == 0 || *host == '\0') { if (port || path || reference || query) { host = "localhost"; } } } if (scheme) { hostDelim = "://"; } if (!host) { host = ""; } if (mprIsIPv6(host)) { if (*host != '[') { host = sfmt("[%s]", host); } else if ((cp = scontains(host, "]:")) != 0) { port = 0; } } else if (schr(host, ':')) { port = 0; } if (port != 0 && port != getDefaultPort(scheme)) { portStr = itos(port); portDelim = ":"; } if (scheme == 0) { scheme = ""; } if (path && *path) { if (*host) { pathDelim = (*path == '/') ? "" : "/"; } else { pathDelim = ""; } } else { pathDelim = path = ""; } if (reference && *reference) { referenceDelim = "#"; } else { referenceDelim = reference = ""; } if (query && *query) { queryDelim = "?"; } else { queryDelim = query = ""; } if (*portDelim) { uri = sjoin(scheme, hostDelim, host, portDelim, portStr, pathDelim, path, referenceDelim, reference, queryDelim, query, NULL); } else { uri = sjoin(scheme, hostDelim, host, pathDelim, path, referenceDelim, reference, queryDelim, query, NULL); } return uri; }
/* Create and initialize a URI. This accepts full URIs with schemes (http:) and partial URLs */ PUBLIC HttpUri *httpCreateUriFromParts(cchar *scheme, cchar *host, int port, cchar *path, cchar *reference, cchar *query, int flags) { HttpUri *up; char *cp, *tok; if ((up = mprAllocObj(HttpUri, manageUri)) == 0) { up->valid = 0; return 0; } if (!httpValidUriChars(scheme) || !httpValidUriChars(host) || !httpValidUriChars(path) || !httpValidUriChars(reference) || !httpValidUriChars(query)) { up->valid = 0; return up; } if (scheme) { up->scheme = sclone(scheme); up->secure = (smatch(up->scheme, "https") || smatch(up->scheme, "wss")); up->webSockets = (smatch(up->scheme, "ws") || smatch(up->scheme, "wss")); } else if (flags & HTTP_COMPLETE_URI) { up->scheme = "http"; } if (host) { if (*host == '[' && ((cp = strchr(host, ']')) != 0)) { up->host = snclone(&host[1], (cp - host) - 2); if ((cp = schr(++cp, ':')) && port == 0) { port = (int) stoi(++cp); } } else { up->host = sclone(host); if ((cp = schr(up->host, ':')) && port == 0) { port = (int) stoi(++cp); } } } else if (flags & HTTP_COMPLETE_URI) { up->host = sclone("localhost"); } if (port) { up->port = port; } if (path) { while (path[0] == '/' && path[1] == '/') { path++; } up->path = sclone(path); } if (flags & (HTTP_COMPLETE_URI | HTTP_COMPLETE_URI_PATH)) { if (up->path == 0 || *up->path == '\0') { up->path = sclone("/"); } } if (reference) { up->reference = sclone(reference); } if (query) { up->query = sclone(query); } if ((tok = srchr(up->path, '.')) != 0) { if ((cp = srchr(up->path, '/')) != 0) { if (cp <= tok) { up->ext = sclone(&tok[1]); } } else { up->ext = sclone(&tok[1]); } } up->valid = 1; return up; }
/* Run an action (may yield) */ static int runAction(HttpConn *conn) { HttpRx *rx; HttpRoute *route; EspRoute *eroute; EspReq *req; EspAction action; rx = conn->rx; req = conn->reqData; route = rx->route; eroute = route->eroute; assert(eroute); if (eroute->edi && eroute->edi->flags & EDI_PRIVATE) { cloneDatabase(conn); } else { req->edi = eroute->edi; } if (route->sourceName == 0 || *route->sourceName == '\0') { if (eroute->commonController) { (eroute->commonController)(conn); } return 1; } #if !ME_STATIC if (!eroute->combine && (route->update || !mprLookupKey(eroute->actions, rx->target))) { cchar *errMsg, *controllers, *controller; if ((controllers = httpGetDir(route, "CONTROLLERS")) == 0) { controllers = "."; } controllers = mprJoinPath(route->home, controllers); controller = schr(route->sourceName, '$') ? stemplateJson(route->sourceName, rx->params) : route->sourceName; controller = controllers ? mprJoinPath(controllers, controller) : mprJoinPath(route->home, controller); if (espLoadModule(route, conn->dispatcher, "controller", controller, &errMsg) < 0) { if (mprPathExists(controller, R_OK)) { httpError(conn, HTTP_CODE_NOT_FOUND, "%s", errMsg); return 0; } } } #endif /* !ME_STATIC */ assert(eroute->top); action = mprLookupKey(eroute->top->actions, rx->target); if (route->flags & HTTP_ROUTE_XSRF && !(rx->flags & HTTP_GET)) { if (!httpCheckSecurityToken(conn)) { httpSetStatus(conn, HTTP_CODE_UNAUTHORIZED); if (smatch(route->responseFormat, "json")) { httpTrace(conn, "esp.xsrf.error", "error", 0); espRenderString(conn, "{\"retry\": true, \"success\": 0, \"feedback\": {\"error\": \"Security token is stale. Please retry.\"}}"); espFinalize(conn); } else { httpError(conn, HTTP_CODE_UNAUTHORIZED, "Security token is stale. Please reload page."); } return 0; } } if (action) { httpAuthenticate(conn); setupFlash(conn); if (eroute->commonController) { (eroute->commonController)(conn); } if (!httpIsFinalized(conn)) { (action)(conn); } } return 1; }
X264Encoder(int fps, int width, int height, int quality, CTSTR preset, CTSTR ProFile, bool bUse444, ColorDescription &colorDesc, int maxBitrate, int bufferSize, bool bUseCFR, bool bUesBackConfig) { frameShift = 0; curPreset = preset; FPS = fps; fps_ms = 1000 / fps; StringList paramList; curProfile = ProFile; zero(¶mData, sizeof(paramData)); LPSTR lpPreset = curPreset.CreateUTF8String(); LPSTR lpTune = curTune.CreateUTF8String(); if (x264_param_default_preset(¶mData, lpPreset, lpTune)) Log::writeError(LOG_RTSPSERV,1,"LiveSDK_Log:Failed to set x264 defaults: %s/%s", curPreset.Array(), curTune.Array()); Free(lpTune); Free(lpPreset); this->width = width; this->height = height; paramData.b_deterministic = false; //分主次直播 if (bUesBackConfig) { bUseCBR = CSLiveManager::GetInstance()->BSParam.LiveSetting.bUseCBRSec; } else { bUseCBR = CSLiveManager::GetInstance()->BSParam.LiveSetting.bUseCBR; } bPadCBR = true; this->bUseCFR = bUseCFR; SetBitRateParams(maxBitrate, bufferSize); if (bUseCBR) { if (bPadCBR) paramData.rc.b_filler = 1; //if(bPadCBR) paramData.i_nal_hrd = X264_NAL_HRD_CBR; paramData.rc.i_rc_method = X264_RC_ABR; paramData.rc.f_rf_constant = 0.0f; } else { paramData.i_frame_reference = 5; paramData.rc.i_rc_method = X264_RC_CRF; paramData.rc.f_rf_constant = baseCRF + float(10 - quality); } //分主次直播 UINT keyframeInterval = CSLiveManager::GetInstance()->BSParam.LiveSetting.KeyFrame; if (bUesBackConfig) { keyframeInterval = CSLiveManager::GetInstance()->BSParam.LiveSetting.KeyFrameSec; } paramData.b_vfr_input = !bUseCFR; paramData.i_width = width; paramData.i_height = height; paramData.vui.b_fullrange = colorDesc.fullRange; paramData.vui.i_colorprim = colorDesc.primaries; paramData.vui.i_transfer = colorDesc.transfer; paramData.vui.i_colmatrix = colorDesc.matrix; if (keyframeInterval) paramData.i_keyint_max = fps*keyframeInterval; paramData.i_fps_num = fps; paramData.i_fps_den = 1; paramData.i_timebase_num = 1; paramData.i_timebase_den = 1000; paramData.pf_log = get_x264_log; paramData.i_log_level = X264_LOG_WARNING; //分主次直播 int nBFrameCount = CSLiveManager::GetInstance()->BSParam.LiveSetting.BFrameCount; if (bUesBackConfig) { nBFrameCount = CSLiveManager::GetInstance()->BSParam.LiveSetting.BFrameCountSec; } if (-1 != nBFrameCount) { paramData.i_bframe = nBFrameCount; } //录制高品质不能播放 paramData.b_vfr_input = 0; if (0 == nBFrameCount) { // http://bbs.csdn.net/topics/390922653 paramData.rc.i_lookahead = 0; paramData.i_sync_lookahead = 0; paramData.i_bframe = 0; paramData.b_sliced_threads = 1; paramData.rc.b_mb_tree = 0; } if (scmpi(curProfile, L"main") == 0) paramData.i_level_idc = 41; // to ensure compatibility with portable devices for (UINT i = 0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if (!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if (strParamName.CompareI(TEXT("fps")) || strParamName.CompareI(TEXT("force-cfr"))) { Log(TEXT("The custom x264 command '%s' is unsupported, use the application settings instead"), strParam.Array()); continue; } else { LPSTR lpParam = strParamName.CreateUTF8String(); LPSTR lpVal = strParamVal.CreateUTF8String(); if (x264_param_parse(¶mData, lpParam, lpVal) != 0) Log(TEXT("The custom x264 command '%s' failed"), strParam.Array()); Free(lpParam); Free(lpVal); } } if (bUse444) paramData.i_csp = X264_CSP_I444; else paramData.i_csp = X264_CSP_I420; colorDesc.fullRange = paramData.vui.b_fullrange; colorDesc.primaries = paramData.vui.i_colorprim; colorDesc.transfer = paramData.vui.i_transfer; colorDesc.matrix = paramData.vui.i_colmatrix; if (curProfile) { LPSTR lpProfile = curProfile.CreateUTF8String(); if (x264_param_apply_profile(¶mData, lpProfile)) Log::writeMessage(LOG_RTSPSERV,1,"LiveSDK_Log:Failed to set x264 profile: %s", curProfile.Array()); Free(lpProfile); } }
/* Redirect the user to another web page. The targetUri may or may not have a scheme. */ PUBLIC void httpRedirect(HttpConn *conn, int status, cchar *targetUri) { HttpTx *tx; HttpRx *rx; HttpUri *target, *base; HttpEndpoint *endpoint; cchar *msg; char *dir, *cp; assert(targetUri); rx = conn->rx; tx = conn->tx; if (tx->finalized) { /* A response has already been formulated */ return; } tx->status = status; if (schr(targetUri, '$')) { targetUri = httpExpandUri(conn, targetUri); } mprLog(3, "redirect %d %s", status, targetUri); msg = httpLookupStatus(conn->http, status); if (300 <= status && status <= 399) { if (targetUri == 0) { targetUri = "/"; } target = httpCreateUri(targetUri, 0); base = rx->parsedUri; /* Support URIs without a host: https:///path. This is used to redirect onto the same host but with a different scheme. So find a suitable local endpoint to supply the port for the scheme. */ if (!target->port && (!target->host || smatch(base->host, target->host)) && (target->scheme && !smatch(target->scheme, base->scheme))) { endpoint = smatch(target->scheme, "https") ? conn->host->secureEndpoint : conn->host->defaultEndpoint; if (endpoint) { target->port = endpoint->port; } else { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot find endpoint for scheme %s", target->scheme); return; } } if (target->path && target->path[0] != '/') { /* Relative file redirection to a file in the same directory as the previous request. */ dir = sclone(rx->pathInfo); if ((cp = strrchr(dir, '/')) != 0) { /* Remove basename */ *cp = '\0'; } target->path = sjoin(dir, "/", target->path, NULL); } target = httpCompleteUri(target, base); targetUri = httpUriToString(target, 0); httpSetHeader(conn, "Location", "%s", targetUri); httpFormatResponse(conn, "<!DOCTYPE html>\r\n" "<html><head><title>%s</title></head>\r\n" "<body><h1>%s</h1>\r\n<p>The document has moved <a href=\"%s\">here</a>.</p></body></html>\r\n", msg, msg, targetUri); } else { httpFormatResponse(conn, "<!DOCTYPE html>\r\n" "<html><head><title>%s</title></head>\r\n" "<body><h1>%s</h1>\r\n</body></html>\r\n", msg, msg); } httpFinalize(conn); }
BOOL ConfigFile::GetColorList(CTSTR lpSection, CTSTR lpKey, List<Color4> &ColorList) { assert(lpSection); assert(lpKey); DWORD i,j,k; BOOL bFoundKey = 0; for(i=0; i<Sections.Num(); i++) { ConfigSection §ion = Sections[i]; if(scmpi(lpSection, section.name) == 0) { for(j=0; j<section.Keys.Num(); j++) { ConfigKey &key = section.Keys[j]; if(scmpi(lpKey, key.name) == 0) { for(k=0; k<key.ValueList.Num(); k++) { TSTR strValue = key.ValueList[k]; if(*strValue == '{') { Color4 ret; ret.x = float(tstof(++strValue)); if(!(strValue = schr(strValue, ','))) break; ret.y = float(tstof(++strValue)); if(!(strValue = schr(strValue, ','))) break; ret.z = float(tstof(++strValue)); if(!(strValue = schr(strValue, ','))) ret.w = 0.0f; else ret.w = float(tstof(++strValue)); ColorList << ret; } else if(*strValue == '[') { Color4 ret; ret.x = float(tstoi(++strValue))/255.0f; if(!(strValue = schr(strValue, ','))) break; ret.y = float(tstoi(++strValue))/255.0f; if(!(strValue = schr(strValue, ','))) break; ret.z = float(tstoi(++strValue))/255.0f; if(!(strValue = schr(strValue, ','))) ret.w = 0.0f; else ret.w = float(tstoi(++strValue))/255.0f; ColorList << ret; } else if( (*LPWORD(strValue) == 'x0') || (*LPWORD(strValue) == 'X0') ) { ColorList << RGBA_to_Vect4(tstring_base_to_int(strValue+2, NULL, 16)); } } bFoundKey = 1; } } } } return bFoundKey; }
X264Encoder(int fps, int width, int height, int quality, CTSTR preset, bool bUse444, ColorDescription &colorDesc, int maxBitrate, int bufferSize, bool bUseCFR) { curPreset = preset; fps_ms = 1000/fps; StringList paramList; curProfile = AppConfig->GetString(TEXT("Video Encoding"), TEXT("X264Profile"), TEXT("high")); BOOL bUseCustomParams = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCustomSettings")); if(bUseCustomParams) { String strCustomParams = AppConfig->GetString(TEXT("Video Encoding"), TEXT("CustomSettings")); strCustomParams.KillSpaces(); if(strCustomParams.IsValid()) { Log(TEXT("Using custom x264 settings: \"%s\""), strCustomParams.Array()); strCustomParams.GetTokenList(paramList, ' ', FALSE); for(UINT i=0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if(!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if(strParamName.CompareI(TEXT("preset"))) { if(valid_x264_string(strParamVal, (const char**)x264_preset_names)) curPreset = strParamVal; else Log(TEXT("invalid preset: %s"), strParamVal.Array()); paramList.Remove(i--); } else if(strParamName.CompareI(TEXT("tune"))) { if(valid_x264_string(strParamVal, (const char**)x264_tune_names)) curTune = strParamVal; else Log(TEXT("invalid tune: %s"), strParamVal.Array()); paramList.Remove(i--); } else if(strParamName.CompareI(TEXT("profile"))) { if(valid_x264_string(strParamVal, (const char **)x264_profile_names)) curProfile = strParamVal; else Log(TEXT("invalid profile: %s"), strParamVal.Array()); paramList.Remove(i--); } } } } zero(¶mData, sizeof(paramData)); LPSTR lpPreset = curPreset.CreateUTF8String(); LPSTR lpTune = curTune.CreateUTF8String(); if (x264_param_default_preset(¶mData, lpPreset, lpTune)) Log(TEXT("Failed to set x264 defaults: %s/%s"), curPreset.Array(), curTune.Array()); Free(lpTune); Free(lpPreset); this->width = width; this->height = height; paramData.b_deterministic = false; bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR"), 1) != 0; bPadCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("PadCBR"), 1) != 0; this->bUseCFR = bUseCFR; SetBitRateParams(maxBitrate, bufferSize); if(bUseCBR) { if(bPadCBR) paramData.i_nal_hrd = X264_NAL_HRD_CBR; paramData.rc.i_rc_method = X264_RC_ABR; paramData.rc.f_rf_constant = 0.0f; } else { paramData.rc.i_rc_method = X264_RC_CRF; paramData.rc.f_rf_constant = baseCRF+float(10-quality); } UINT keyframeInterval = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), 0); paramData.b_vfr_input = !bUseCFR; paramData.i_width = width; paramData.i_height = height; paramData.vui.b_fullrange = colorDesc.fullRange; paramData.vui.i_colorprim = colorDesc.primaries; paramData.vui.i_transfer = colorDesc.transfer; paramData.vui.i_colmatrix = colorDesc.matrix; if (keyframeInterval) paramData.i_keyint_max = fps*keyframeInterval; paramData.i_fps_num = fps; paramData.i_fps_den = 1; paramData.i_timebase_num = 1; paramData.i_timebase_den = 1000; paramData.pf_log = get_x264_log; paramData.i_log_level = X264_LOG_WARNING; for(UINT i=0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if(!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if( strParamName.CompareI(TEXT("fps")) || strParamName.CompareI(TEXT("force-cfr"))) { Log(TEXT("The custom x264 command '%s' is unsupported, use the application settings instead"), strParam.Array()); continue; } else { LPSTR lpParam = strParamName.CreateUTF8String(); LPSTR lpVal = strParamVal.CreateUTF8String(); if(x264_param_parse(¶mData, lpParam, lpVal) != 0) Log(TEXT("The custom x264 command '%s' failed"), strParam.Array()); Free(lpParam); Free(lpVal); } } if(bUse444) paramData.i_csp = X264_CSP_I444; else paramData.i_csp = X264_CSP_I420; colorDesc.fullRange = paramData.vui.b_fullrange; colorDesc.primaries = paramData.vui.i_colorprim; colorDesc.transfer = paramData.vui.i_transfer; colorDesc.matrix = paramData.vui.i_colmatrix; if (curProfile) { LPSTR lpProfile = curProfile.CreateUTF8String(); if (x264_param_apply_profile (¶mData, lpProfile)) Log(TEXT("Failed to set x264 profile: %s"), curProfile.Array()); Free(lpProfile); } x264 = x264_encoder_open(¶mData); if(!x264) CrashError(TEXT("Could not initialize x264")); Log(TEXT("------------------------------------------")); Log(TEXT("%s"), GetInfoString().Array()); Log(TEXT("------------------------------------------")); DataPacket packet; GetHeaders(packet); }
void ConfigFile::AddKey(CTSTR lpSection, CTSTR lpKey, CTSTR newvalue) { assert(lpSection); assert(lpKey); TSTR lpTemp = lpFileData, lpEnd = &lpFileData[dwLength], lpSectionStart; DWORD dwSectionNameSize = slen(lpSection), dwKeyNameSize = slen(lpKey); BOOL bInSection = 0; do { lpTemp = sstr(lpTemp, TEXT("\n[")); if(!lpTemp) break; lpTemp += 2; if((scmpi_n(lpTemp, lpSection, dwSectionNameSize) == 0) && (lpTemp[dwSectionNameSize] == ']')) { bInSection = 1; lpSectionStart = lpTemp = schr(lpTemp, '\n')+1; break; } }while(lpTemp < lpEnd); if(!bInSection) { XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], dwLength-4); file.Write("\r\n[", 3); file.WriteAsUTF8(lpSection, dwSectionNameSize); file.Write("]\r\n", 3); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } TSTR lpLastItem = NULL; do { if(*lpTemp == '[') { XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], DWORD(lpSectionStart-lpFileData-2)); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.WriteAsUTF8(lpSectionStart, slen(lpSectionStart)-2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } else if(*(LPWORD)lpTemp == '//') { lpTemp = schr(lpTemp, '\n')+1; continue; } else if(bInSection) { if((scmpi_n(lpTemp, lpKey, dwKeyNameSize) == 0) && (lpTemp[dwKeyNameSize] == '=')) { lpLastItem = schr(lpTemp, '\n')+1; } else if(lpLastItem) { lpTemp = lpLastItem; XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], DWORD(lpTemp-lpFileData-2)); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.WriteAsUTF8(lpTemp, slen(lpTemp)-2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } } lpTemp = schr(lpTemp, '\n')+1; }while(lpTemp < lpEnd); XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], DWORD(lpSectionStart-lpFileData-2)); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.WriteAsUTF8(lpSectionStart, slen(lpSectionStart)-2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); }
//ugh yet more string parsing, you think you escape it for one minute and then bam! you discover yet more string parsing code needs to be written BOOL LocaleStringLookup::LoadStringFile(CTSTR lpFile, bool bClear) { if(bClear) { cache.Clear(); delete top; top = new StringLookupNode; } else if(!top) top = new StringLookupNode; //------------------------ XFile file; if(!file.Open(lpFile, XFILE_READ, XFILE_OPENEXISTING)) return FALSE; String fileString; file.ReadFileToString(fileString); file.Close(); if(fileString.IsEmpty()) return FALSE; //------------------------ fileString.FindReplace(TEXT("\r"), TEXT(" ")); TSTR lpTemp = fileString.Array()-1; TSTR lpNextLine; do { ++lpTemp; lpNextLine = schr(lpTemp, '\n'); while(*lpTemp == ' ' || *lpTemp == L' ' || *lpTemp == '\t') ++lpTemp; if(!*lpTemp || *lpTemp == '\n') continue; if(lpNextLine) *lpNextLine = 0; //---------- TSTR lpValueStart = lpTemp; while(*lpValueStart && *lpValueStart != ' ' && *lpValueStart != L' ' && *lpValueStart != '\t') ++lpValueStart; String lookupVal, strVal; TCHAR prevChar = *lpValueStart; *lpValueStart = 0; lookupVal = lpTemp; *lpValueStart = prevChar; String value = lpValueStart; value.KillSpaces(); if(value.IsValid() && value[0] == '"') { value = String::RepresentationToString(value); strVal = value; } else strVal = value; if(lookupVal.IsValid()) AddLookupString(lookupVal, strVal); //---------- if(lpNextLine) *lpNextLine = '\n'; }while(lpTemp = lpNextLine); //------------------------ return TRUE; }
BOOL CodeTokenizer::GetNextToken(String &token, BOOL bPeek) { TSTR lpStart = lpTemp; TSTR lpTokenStart = NULL; BOOL bAlphaNumeric = FALSE; while(*lpTemp) { if(mcmp(lpTemp, TEXT("//"), 2*sizeof(TCHAR))) { lpTemp = schr(lpTemp, '\n'); if(!lpTemp) return FALSE; } else if(mcmp(lpTemp, TEXT("/*"), 2*sizeof(TCHAR))) { lpTemp = sstr(lpTemp+2, TEXT("*/")); if(!lpTemp) return FALSE; lpTemp += 2; } if((*lpTemp == '_') || iswalnum(*lpTemp)) { if(lpTokenStart) { if(!bAlphaNumeric) break; } else { lpTokenStart = lpTemp; bAlphaNumeric = TRUE; } } else { if(lpTokenStart) { if(bAlphaNumeric) break; if(*lpTokenStart == '>' || *lpTokenStart == '<') { if((*lpTemp != '=') && (*lpTemp != '>') && (*lpTemp != '<')) break; } if( ((*lpTokenStart == '=') && (*lpTemp != '=')) || (*lpTokenStart == ';') || (*lpTemp == ' ') || (*lpTemp == L'�@') || (*lpTemp == '\'') || (*lpTemp == '"') || (*lpTemp == ';') || (*lpTemp == '(') || (*lpTemp == ')') || (*lpTemp == '[') || (*lpTemp == ']') || (*lpTemp == '{') || (*lpTemp == '}') || (*lpTemp == '\r') || (*lpTemp == '\t') || (*lpTemp == '\n') ) { break; } } else { if(*lpTemp == '"') { lpTokenStart = lpTemp; BOOL bFoundEnd = TRUE; while(*++lpTemp != '"') { if(!*lpTemp) { bFoundEnd = FALSE; break; } } if(!bFoundEnd) return FALSE; ++lpTemp; break; } if(*lpTemp == ';') { lpTokenStart = lpTemp; ++lpTemp; break; } if(*lpTemp == '\'') { lpTokenStart = lpTemp; BOOL bFoundEnd = TRUE; while(*++lpTemp != '\'') { if(!*lpTemp) { bFoundEnd = FALSE; break; } } if(!bFoundEnd) return FALSE; ++lpTemp; break; } else if((*lpTemp == '(') || (*lpTemp == ')') || (*lpTemp == '[') || (*lpTemp == ']') || (*lpTemp == '{') || (*lpTemp == '}')) { lpTokenStart = lpTemp++; break; } if( (*lpTemp != ' ') && (*lpTemp != L'�@') && (*lpTemp != '\r') && (*lpTemp != '\t') && (*lpTemp != '\n') ) { lpTokenStart = lpTemp; bAlphaNumeric = FALSE; } } } ++lpTemp; } if(!lpTokenStart) return FALSE; TCHAR oldCH = *lpTemp; *lpTemp = 0; token = lpTokenStart; *lpTemp = oldCH; if(bAlphaNumeric && iswdigit(*lpTokenStart)) //handle floating points { if( (token.Length() > 2) && (lpTokenStart[0] == '0') && (lpTokenStart[1] == 'x')) //convert hex { unsigned int val = tstring_base_to_uint(lpTokenStart, NULL, 0); token = FormattedString(TEXT("%d"), val); } else { String nextToken; TSTR lpPos = lpTemp; if(!GetNextToken(nextToken)) return FALSE; if(nextToken[0] == '.') { lpPos = lpTemp; token << nextToken; if(!GetNextToken(nextToken)) return FALSE; if(iswdigit(nextToken[0]) || nextToken == TEXT("f")) token << nextToken; else lpTemp = lpPos; } else lpTemp = lpPos; if(token[token.Length()-1] == 'e') { if(*lpTemp == '-') { TSTR lpPos = lpTemp++; if(!GetNextToken(nextToken)) return FALSE; if(!iswdigit(nextToken[0])) lpTemp = lpPos; else token << TEXT("-") << nextToken; } } lpPos = lpTemp; if(!GetNextToken(nextToken)) return FALSE; if(nextToken[0] == '.') { lpPos = lpTemp; token << nextToken; if(!GetNextToken(nextToken)) return FALSE; if(iswdigit(nextToken[0]) || nextToken == TEXT("f")) token << nextToken; else lpTemp = lpPos; } else lpTemp = lpPos; } } if(bPeek) lpTemp = lpStart; return TRUE; }
bool XConfig::ReadFileData2(XElement *curElement, int level, TSTR &lpTemp, bool isJSON) { while(*lpTemp) { if(*lpTemp == '}') return level != 0; if(*lpTemp == '{') //unnamed object, usually only happens at the start of the file, ignore { ++lpTemp; if(!ReadFileData2(curElement, level+1, lpTemp, true)) return false; } else if(*lpTemp != ' ' && *lpTemp != L' ' && *lpTemp != '\t' && *lpTemp != '\r' && *lpTemp != '\n' && *lpTemp != ',') { String strName; if(*lpTemp == '"') strName = ProcessString(lpTemp); else { TSTR lpDataStart = lpTemp; lpTemp = schr(lpTemp, ':'); if(!lpTemp) return false; *lpTemp = 0; strName = lpDataStart; *lpTemp = ':'; strName.KillSpaces(); } //--------------------------- lpTemp = schr(lpTemp, ':'); if(!lpTemp) return false; ++lpTemp; while( *lpTemp == ' ' || *lpTemp == L' ' || *lpTemp == '\t' ) { ++lpTemp; } //--------------------------- if(*lpTemp == '{') //element { ++lpTemp; XElement *newElement = curElement->CreateElement(strName); if (!ReadFileData2(newElement, level + 1, lpTemp, isJSON)) return false; } else //item { String data; if(*lpTemp == '"') data = ProcessString(lpTemp); else { TSTR lpDataStart = lpTemp; if (!GetNextLine(lpTemp, isJSON)) return false; if(lpTemp[-1] == '\r') --lpTemp; if(lpTemp != lpDataStart) { TCHAR oldChar = *lpTemp; *lpTemp = 0; data = lpDataStart; *lpTemp = oldChar; data.KillSpaces(); } } if (!GetNextLine(lpTemp, isJSON) && curElement != RootElement) return false; if (*lpTemp == '}') lpTemp--; curElement->SubItems << new XDataItem(strName, data); } } // A ++lpTemp above can step off the end of the string causing // the condition on while to go a bit crazy. // Making sure we preserve the end of string. if (*lpTemp != 0) { ++lpTemp; } } return (curElement == RootElement); }