New upstream version 23.2.1+dfsg1
This commit is contained in:
parent
cdc9a9fc87
commit
b14f9eae6d
1017 changed files with 37232 additions and 11111 deletions
|
|
@ -13,6 +13,7 @@ set(obs-ffmpeg_HEADERS
|
|||
obs-ffmpeg-formats.h
|
||||
obs-ffmpeg-compat.h
|
||||
closest-pixel-format.h)
|
||||
|
||||
set(obs-ffmpeg_SOURCES
|
||||
obs-ffmpeg.c
|
||||
obs-ffmpeg-audio-encoders.c
|
||||
|
|
@ -21,6 +22,21 @@ set(obs-ffmpeg_SOURCES
|
|||
obs-ffmpeg-mux.c
|
||||
obs-ffmpeg-source.c)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
list(APPEND obs-ffmpeg_SOURCES
|
||||
obs-ffmpeg-vaapi.c)
|
||||
LIST(APPEND obs-ffmpeg_PLATFORM_DEPS
|
||||
${LIBVA_LBRARIES})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND obs-ffmpeg_SOURCES
|
||||
jim-nvenc.c
|
||||
jim-nvenc-helpers.c)
|
||||
list(APPEND obs-ffmpeg_HEADERS
|
||||
jim-nvenc.h)
|
||||
endif()
|
||||
|
||||
add_library(obs-ffmpeg MODULE
|
||||
${obs-ffmpeg_HEADERS}
|
||||
${obs-ffmpeg_SOURCES})
|
||||
|
|
|
|||
|
|
@ -4,15 +4,11 @@ Bitrate="معدل النقل"
|
|||
Preset="الإعداد المسبق"
|
||||
|
||||
|
||||
NVENC.Preset.default="الإفتراضي"
|
||||
NVENC.Preset.hq="جودة عالية"
|
||||
NVENC.Preset.hp="أداء عالي"
|
||||
NVENC.Preset.bd="بلوراي Bluray"
|
||||
NVENC.Level="المستوى"
|
||||
|
||||
FFmpegSource="مصدر وسائط"
|
||||
LocalFile="ملف محلي"
|
||||
Looping="تكرار حلقي"
|
||||
ClearOnMediaEnd="عدم إظهار شيء عند انتهاء التشغيل"
|
||||
Advanced="متقدم"
|
||||
ColorRange="نطاق ألوان YUV"
|
||||
ColorRange.Auto="تلقائي"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,38 @@
|
|||
FFmpegOutput="FFmpeg изход"
|
||||
FFmpegAAC="Основен кодек FFmpeg AAC"
|
||||
FFmpegOpus="Кодек FFmpeg Opus"
|
||||
Bitrate="Битрейт"
|
||||
|
||||
|
||||
|
||||
MaxBitrate="Максимален битрейт"
|
||||
Preset="Шаблон"
|
||||
RateControl="Управление на битрейт"
|
||||
KeyframeIntervalSec="Интервал на ключови кадри (секунди, 0=автоматично)"
|
||||
Lossless="Без загуба на качество"
|
||||
|
||||
|
||||
NVENC.Preset.default="Производителност"
|
||||
NVENC.Preset.hq="Качество"
|
||||
NVENC.Preset.hp="Максимална производителност"
|
||||
NVENC.Preset.mq="Максимално качество"
|
||||
NVENC.Preset.ll="Ниска латентност"
|
||||
NVENC.Preset.llhq="Ниска латенност, високо качество"
|
||||
NVENC.Preset.llhp="Ниска латентност, висока производителност"
|
||||
NVENC.LookAhead="Предопределяне"
|
||||
NVENC.CQLevel="Ниво CQ"
|
||||
|
||||
FFmpegSource="Източник на медия"
|
||||
LocalFile="Локален файл"
|
||||
Looping="Преповтаряне"
|
||||
Input="Вход"
|
||||
InputFormat="Формат за вход"
|
||||
BufferingMB="Мрежова буферизация (MB)"
|
||||
HardwareDecode="Използване на хардуерно декодиране, ако е налично"
|
||||
Advanced="Разширено"
|
||||
RestartWhenActivated="Възобновява възпроизвеждането когато източникът е активен"
|
||||
CloseFileWhenInactive="Затваряне на файла при неактивност"
|
||||
ColorRange.Auto="Автоматично"
|
||||
ColorRange.Partial="Частично"
|
||||
ColorRange.Full="Пълно"
|
||||
SpeedPercentage="Скорост (процент)"
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,9 @@ FFmpegAAC="পূর্ব-নির্ধারিত FFmpeg AAC এনকো
|
|||
Preset="পূর্ব-নির্ধারিত"
|
||||
RateControl="হার নিয়ন্ত্রণ"
|
||||
|
||||
BFrames="বি-ফ্রেম"
|
||||
|
||||
NVENC.Use2Pass="দুই পাসে এনকোডিং ব্যবহার করো"
|
||||
NVENC.Preset.default="পূর্ব-নির্ধারিত"
|
||||
NVENC.Preset.ll="লো-সুপ্ত"
|
||||
NVENC.Preset.llhq="উচ্চ মান নিম্ন-সুপ্ত"
|
||||
NVENC.Preset.llhp="লো-সুপ্ত উচ্চ কার্যক্ষমতা"
|
||||
NVENC.Level="শ্রেনী"
|
||||
|
||||
FFmpegSource="মিডিয়া উৎস"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,28 @@
|
|||
FFmpegOutput="Sortida FFmpeg"
|
||||
FFmpegAAC="Codificador FFmpeg AAC predeterminat"
|
||||
FFmpegAAC="Codificador FFmpeg AAC per defecte"
|
||||
FFmpegOpus="Codificador Opus FFmpeg"
|
||||
Bitrate="Taxa de bits"
|
||||
MaxBitrate="Taxa de bits màxima"
|
||||
Preset="Valors predefinits"
|
||||
RateControl="Control de freqüència"
|
||||
KeyframeIntervalSec="Interval de fotograma clau (en segons, 0 = automàtic)"
|
||||
Lossless="Sense pèrdues"
|
||||
|
||||
BFrames="B-frames"
|
||||
BFrames="Fotogrames-B màxims"
|
||||
|
||||
NVENC.Use2Pass="Utilitza codificació en dues passades"
|
||||
NVENC.Preset.default="Per defecte"
|
||||
NVENC.Preset.hq="Alta Qualitat"
|
||||
NVENC.Preset.hp="Alt rendiment"
|
||||
NVENC.Preset.bd="BluRay"
|
||||
NVENC.Preset.default="Rendiment"
|
||||
NVENC.Preset.hq="Qualitat"
|
||||
NVENC.Preset.hp="Rendiment màxim"
|
||||
NVENC.Preset.mq="Qualitat màxima"
|
||||
NVENC.Preset.ll="Latencia baixa"
|
||||
NVENC.Preset.llhq="Latència baixa Alta Qualitat"
|
||||
NVENC.Preset.llhp="Latència baixa alt rendiment"
|
||||
NVENC.Level="Nivell"
|
||||
NVENC.Preset.llhq="Qualitat de latència baixa"
|
||||
NVENC.Preset.llhp="Rendiment de latència baixa"
|
||||
NVENC.LookAhead="Previsió"
|
||||
NVENC.LookAhead.ToolTip="Habilita els Fotogrames-B dinàmics.\n\nEn inhabilitar-ho, el codificador utilitzarà sempre el nombre de Fotogrames-B indicat a l'opció «Fotogrames-B màxims».\n\nEn habilitar-ho, augmentarà la qualitat visual només utilitzant els Fotogrames-B necessaris,\nfins el màxim permès per l'ús de la GPU."
|
||||
NVENC.PsychoVisualTuning="Ajust psico visual"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Permet la configuració del codificador que optimitza l'ús de la taxa de bits per millorar la qualitat visual percebuda,\nespecialment en situacions amb gran moviment, a costa d'una major utilització de la GPU."
|
||||
NVENC.CQLevel="Nivell de quantificació constant"
|
||||
|
||||
FFmpegSource="Font multimèdia"
|
||||
LocalFile="Fitxer local"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Entrada"
|
|||
InputFormat="Format d'entrada"
|
||||
BufferingMB="Memòria intermèdia de xarxa (MB)"
|
||||
HardwareDecode="Usa la descodificació per maquinari si és disponible"
|
||||
ClearOnMediaEnd="Amaga l'origen en acabar la reproducció"
|
||||
ClearOnMediaEnd="No mostris res quan acabi la reproducció"
|
||||
Advanced="Avançat"
|
||||
RestartWhenActivated="Reinicia la reproducció quan la font estigui activa"
|
||||
CloseFileWhenInactive="Tanca el fitxer quan estigui inactiu"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Desa la repetició"
|
|||
|
||||
HelperProcessFailed="No s'ha pogut iniciar el procés d'assistència de gravació. Comproveu que els arxius d'OBS no han estat bloquejats o eliminats per qualsevol programa de seguretat de tercers."
|
||||
UnableToWritePath="No s'ha pogut escriure a %1. Assegureu-vos que utilitzeu una ruta de gravació a la qual el vostre compte d'usuari tingui permisos per escriure i que hi hagi prou espai al disc."
|
||||
WarnWindowsDefender="Si la protecció contra Ransomware del Windows 10 està activada, també pot causar aquest error. Proveu inhabilitant la protecció contra amenaces del Windows a la configuració de seguretat/virus i protecció."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="Výstup FFmpegu"
|
|||
FFmpegAAC="Výchozí FFmpeg AAC enkodér"
|
||||
FFmpegOpus="FFmpeg Opus enkodér"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="Maximální bitrate"
|
||||
Preset="Předvolba"
|
||||
RateControl="Řízení toku"
|
||||
KeyframeIntervalSec="Interval klíč. snímků (vteřiny, 0=auto)"
|
||||
Lossless="Lossless"
|
||||
|
||||
BFrames="B-frames"
|
||||
BFrames="Maximum B-snímků"
|
||||
|
||||
NVENC.Use2Pass="Použít dvoustupňové enkódování"
|
||||
NVENC.Preset.default="Výchozí"
|
||||
NVENC.Preset.hq="Vysoká kvalita"
|
||||
NVENC.Preset.hp="Vysoký výkon"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Výkon"
|
||||
NVENC.Preset.hq="Kvalita"
|
||||
NVENC.Preset.hp="Maximální výkon"
|
||||
NVENC.Preset.mq="Maximální kvalita"
|
||||
NVENC.Preset.ll="Nízká odezva"
|
||||
NVENC.Preset.llhq="Nízká odezva, vysoká kvalita"
|
||||
NVENC.Preset.llhp="Nízká odezva, vysoký výkon"
|
||||
NVENC.Level="Úrověň"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Zapne dynamické B-snímky.\n\nPokud vypnuto, enkodér vždy použije číslo uvedené v nastavení 'Maximum B-snímků'.\n\nPokud zapnuto, zvýší se vizuální kvalita použitím tolika B-smínků, jak je potřeba, až do maxima,\nale za cenu zvýšení využití GPU."
|
||||
NVENC.PsychoVisualTuning="Psycho Visual Tuning"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Povolí nastavení enkodéru, které optimalizuje využití bitratu pro zvýšení vnímané vizuální kvality,\npředevším v situacích s velkým množstvím pohybu, ale za cenu zvýšení využití GPU."
|
||||
NVENC.CQLevel="CQ úroveň"
|
||||
|
||||
FFmpegSource="Médium"
|
||||
LocalFile="Místní soubor"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Vstup"
|
|||
InputFormat="Formát vstupu"
|
||||
BufferingMB="Vyrovnávací paměť pro síť (MB)"
|
||||
HardwareDecode="Použít hardwarové dekódování, pokud je k dispozici"
|
||||
ClearOnMediaEnd="Skrýt zdroj po skončení přehrávání"
|
||||
ClearOnMediaEnd="Po skončení přehrávání nezobrazovat nic"
|
||||
Advanced="Pokročilé"
|
||||
RestartWhenActivated="Restartovat přehrávání poté, co je zdroj aktivován"
|
||||
CloseFileWhenInactive="Zavřít soubor při neaktivitě"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Uložit záznam"
|
|||
|
||||
HelperProcessFailed="Nelze spustit pomocný proces nahrávání. Zkontrolujte prosím, zda nejsou soubory OBS blokovány či odstraněny některý z antivirových programů třetích stran."
|
||||
UnableToWritePath="Nelze zapsat do %1. Zkontrolujte prosím, zda používáte úložiště, do kterého může váš uživatelský účet zapisovat a je zde dostatek volného místa."
|
||||
WarnWindowsDefender="Pokud je zapnuta ochrana proti ransomwaru (Windows 10), může to také způsobit tuto chybu. Zkuste vypnout funkci kontrolovaných složek v nastavení Zabezpečení Windows / Ochrana proti virům."
|
||||
|
||||
|
|
|
|||
|
|
@ -1,43 +1,48 @@
|
|||
FFmpegOutput="FFmpeg output"
|
||||
FFmpegOutput="FFmpeg-output"
|
||||
FFmpegAAC="FFmpeg Standard AAC Encoder"
|
||||
FFmpegOpus="FFmpeg Opus-encoder"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="Maks. bithastighed"
|
||||
Preset="Forudindstillet"
|
||||
RateControl="Tempokontrol"
|
||||
KeyframeIntervalSec="Keyframe-interval (sekunder, 0= auto)"
|
||||
Lossless="Tabsfri"
|
||||
|
||||
BFrames="B-rammer"
|
||||
BFrames="Maks. B-billeder"
|
||||
|
||||
NVENC.Use2Pass="Benyt to-trins kodning"
|
||||
NVENC.Preset.default="Standard"
|
||||
NVENC.Preset.hq="Høj kvalitet"
|
||||
NVENC.Preset.hp="Høj ydeevne"
|
||||
NVENC.Preset.bd="BluRay"
|
||||
NVENC.Preset.ll="Lav latens"
|
||||
NVENC.Preset.llhq="Lav-latens høj kvalitet"
|
||||
NVENC.Preset.llhp="Lav latens høj ydeevne"
|
||||
NVENC.Level="Niveau"
|
||||
NVENC.Preset.default="Ydeevne"
|
||||
NVENC.Preset.hq="Kvalitet"
|
||||
NVENC.Preset.hp="Maks. ydeevne"
|
||||
NVENC.Preset.mq="Maks. kvalitet"
|
||||
NVENC.Preset.ll="Lavlatens"
|
||||
NVENC.Preset.llhq="Lavlatenskvalitet"
|
||||
NVENC.Preset.llhp="Lavlatensydeevne"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Aktiverer dynamiske B-frames.\n\nHvis deaktiveret, benytter encoderen altid antallet af B-frames angivet i indstillingen 'Maks. B-frames'.\n\nHvis aktiveret, forøges den visuelle kvalitet ved kun at benytte det nødvendige antal B-frames op til maksimum\npå bekostning af forøget GPU-forbrug."
|
||||
NVENC.PsychoVisualTuning="Psychovisuel tuning"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Aktiverer encoderindstillinger, som optimerer brugen af bithastighed for øget opfattet visuel kvalitet,\nisær i situationer med megen bevægelse, på bekostning af forøget GPU-forbrug."
|
||||
NVENC.CQLevel="CQ-niveau"
|
||||
|
||||
FFmpegSource="Mediekilde"
|
||||
LocalFile="Lokal fil"
|
||||
Looping="Gentagelse"
|
||||
Input="Input"
|
||||
InputFormat="Input format"
|
||||
InputFormat="Inputformat"
|
||||
BufferingMB="Netværksbuffering (MB)"
|
||||
HardwareDecode="Brug hardwareafkodning når tilgængelige"
|
||||
ClearOnMediaEnd="Skjul kilde når afspilning slutter"
|
||||
HardwareDecode="Benyt hardwareafkodning, når tilgængelig"
|
||||
ClearOnMediaEnd="Vis intet, når afspilning afsluttes"
|
||||
Advanced="Avanceret"
|
||||
RestartWhenActivated="Genstart afspilning når kilde bliver aktiv"
|
||||
CloseFileWhenInactive="Luk fil når inaktiv"
|
||||
CloseFileWhenInactive.ToolTip="Lukker filen, når kilden ikke vises i streamen ellerr\noptagelsen. Dette muliggør at filen kan ændres, når kilden er ikke aktiv, \nmen der kan være noget opstartsforsinkelse, når kilden genaktiveres."
|
||||
RestartWhenActivated="Genstart afspilning, når kilde bliver aktiv"
|
||||
CloseFileWhenInactive="Luk fil, når inaktiv"
|
||||
CloseFileWhenInactive.ToolTip="Lukker filen, når kilden ikke vises i streamen ellerr\noptagelsen. Dette muliggør at filen kan ændres, når kilden er ikke aktiv,\nmen nogen opstartsforsinkelse kan forekomme, når kilden genaktiveres."
|
||||
ColorRange="YUV-farveområde"
|
||||
ColorRange.Auto="Auto"
|
||||
ColorRange.Partial="Delvis"
|
||||
ColorRange.Full="Fuld"
|
||||
RestartMedia="Genstart Media"
|
||||
SpeedPercentage="Hastighed (procent)"
|
||||
Seekable="Seekable"
|
||||
Seekable="Søgbar"
|
||||
|
||||
MediaFileFilter.AllMediaFiles="Alle mediefiler"
|
||||
MediaFileFilter.VideoFiles="Videofiler"
|
||||
|
|
@ -47,6 +52,7 @@ MediaFileFilter.AllFiles="Alle filer"
|
|||
ReplayBuffer="Genafspilningsbuffer"
|
||||
ReplayBuffer.Save="Gem Genafspilning"
|
||||
|
||||
HelperProcessFailed="Kan ikke starte optagelseshjælperprocessen. Tjek at OBS-filer ikke blokeres eller er fjernet af noget 3. parts antivirus-/sikkerhedssoftware."
|
||||
UnableToWritePath="Kan ikke skrive til %1. Tjek at du benytter en optagelsessti, som din brugerkonto har skriverettighed til, og at der er tilstrækkelig ledig diskplads."
|
||||
HelperProcessFailed="Kan ikke starte optagelseshjælperprocessen. Tjek, at OBS-filer ikke blokeres eller er fjernet af 3. parts antivirus-/sikkerhedssoftware."
|
||||
UnableToWritePath="Kan ikke skrive til %1. Tjek, at du benytter en optagelsessti, som din brugerkonto har skriverettighed til, og at der er tilstrækkelig ledig diskplads."
|
||||
WarnWindowsDefender="Er Windows 10 Ransomware-beskyttelse aktiveret, kan dette også medføre denne fejl. Prøv at deaktivere kontrolleret mappeadgang i Windows-indstillingen Sikkerhed/Virus- og Trusselsbeskyttelse."
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,28 @@
|
|||
FFmpegOutput="FFmpeg Ausgabe"
|
||||
FFmpegAAC="FFmpeg Standard AAC Codierer"
|
||||
FFmpegOpus="FFmpeg Opus Codierer"
|
||||
FFmpegOutput="FFmpeg-Ausgabe"
|
||||
FFmpegAAC="FFmpeg-Standard-AAC-Kodierer"
|
||||
FFmpegOpus="FFmpeg-Opus-Kodierer"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="Max. Bitrate"
|
||||
Preset="Voreinstellung"
|
||||
RateControl="Qualitäts Regulierungsmethode"
|
||||
KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)"
|
||||
KeyframeIntervalSec="Keyframeintervall in Sek. (0 = auto)"
|
||||
Lossless="Verlustfrei"
|
||||
|
||||
BFrames="B-frames"
|
||||
BFrames="Max. B-Frames"
|
||||
|
||||
NVENC.Use2Pass="Benutze Two-Pass Codierung"
|
||||
NVENC.Preset.default="Standard"
|
||||
NVENC.Preset.hq="Hohe Qualität"
|
||||
NVENC.Preset.hp="Hohe Leistung"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Use2Pass="Two-Pass-Kodierung verwenden"
|
||||
NVENC.Preset.default="Leistung"
|
||||
NVENC.Preset.hq="Qualität"
|
||||
NVENC.Preset.hp="Max. Leistung"
|
||||
NVENC.Preset.mq="Max. Qualität"
|
||||
NVENC.Preset.ll="Niedrige Latenz"
|
||||
NVENC.Preset.llhq="Niedrige Latenz, Hohe Qualität"
|
||||
NVENC.Preset.llhp="Niedrige Latenz, Hohe Leistung"
|
||||
NVENC.Level="Level"
|
||||
NVENC.Preset.llhq="Niedrige Latenz + Qualität"
|
||||
NVENC.Preset.llhp="Niedrige Latenz + Leistung"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Aktiviert dynamische B-Frames.\n\nWenn deaktiviert, wird der Kodierer immer die Anzahl der B-Frames verwenden, die in der „Max B-Frames“-Einstellung angegeben sind.\n\nWenn aktiviert, wird er die visuelle Qualität erhöhen, indem nur so viele B-Frames verwendet werden wie benötigt, bis zum Maximum,\nzu den Kosten einer erhöhten GPU-Nutzung."
|
||||
NVENC.PsychoVisualTuning="Psycho-visuelle Optimierung"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Aktiviert Kodierereinstellungen, die die Verwendung der Bitrate für eine erhöhte wahrgenommene visuelle Qualität optimieren,\ninsbesondere in Situationen mit hoher Bewegung, zu Kosten einer erhöhten GPU-Nutzung."
|
||||
NVENC.CQLevel="CQ-Level"
|
||||
|
||||
FFmpegSource="Medienquelle"
|
||||
LocalFile="Lokale Datei"
|
||||
|
|
@ -25,17 +30,17 @@ Looping="Endlosschleife"
|
|||
Input="Eingabe"
|
||||
InputFormat="Eingabeformat"
|
||||
BufferingMB="Netzwerkpufferung (MB)"
|
||||
HardwareDecode="Verwende Hardwaredecodierung, falls verfügbar"
|
||||
ClearOnMediaEnd="Quelle verbergen, wenn Wiedergabe endet"
|
||||
HardwareDecode="Hardwaredekodierung verwenden, falls verfügbar"
|
||||
ClearOnMediaEnd="Nichts anzeigen, wenn Wiedergabe endet"
|
||||
Advanced="Erweitert"
|
||||
RestartWhenActivated="Wiedergabe erneut starten, wenn Quelle aktiviert wird"
|
||||
CloseFileWhenInactive="Datei schließen, wenn inaktiv"
|
||||
CloseFileWhenInactive.ToolTip="Schließt die Datei, wenn die Quelle im Stream oder der Aufnahme nicht angezeigt wird.\n Dies ermöglicht, dass die Datei geändert wird, wenn die Quelle nicht aktiv ist,\n aber es gibt wahrscheinlich etwas Starverzögerung, wenn die Quelle reaktiviert wird."
|
||||
CloseFileWhenInactive.ToolTip="Schließt die Datei, wenn die Quelle im Stream oder der Aufnahme nicht angezeigt wird.\nDies ermöglicht, dass die Datei geändert werden kann, wenn die Quelle nicht aktiv ist,\n aber es gibt wahrscheinlich etwas Startverzögerung, wenn die Quelle reaktiviert wird."
|
||||
ColorRange="YUV-Farbmatrix"
|
||||
ColorRange.Auto="Automatisch"
|
||||
ColorRange.Partial="Teilweise"
|
||||
ColorRange.Full="Voll"
|
||||
RestartMedia="Medium neu starten"
|
||||
RestartMedia="Medium neustarten"
|
||||
SpeedPercentage="Geschwindigkeit (Prozent)"
|
||||
Seekable="Durchsuchbar"
|
||||
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Replay speichern"
|
|||
|
||||
HelperProcessFailed="Der Aufnahmehelferprozeß kann nicht gestartet werden. Überprüfen Sie, ob OBS-Dateien nicht von einer Drittanbieter Antiviren- / Sicherheitssoftware blockiert oder entfernt wurden."
|
||||
UnableToWritePath="Kann nicht zu %1 schreiben. Vergewissern Sie sich, dass Sie einen Aufnahmepfad verwenden, für das Ihr Benutzerkonto Schreibrechte hat und dass genügend Speicherplatz zur Verfügung steht."
|
||||
WarnWindowsDefender="Wenn Windows-10-Ransomware-Schutz aktiviert ist, kann dies auch den Fehler auslösen. Versuchen Sie, den überwachten Ordnerzugriff in Windows-Sicherheit → Viren- & Bedrohungsschutz auszuschalten."
|
||||
|
||||
|
|
|
|||
|
|
@ -7,17 +7,9 @@ RateControl="Έλεγχος ρυθμού"
|
|||
KeyframeIntervalSec="Συχνότητα Καρέ-Κλειδιού (δευτερόλεπτα, 0=αυτόματο)"
|
||||
Lossless="Χωρίς απώλειες"
|
||||
|
||||
BFrames="Β-πλαίσια"
|
||||
|
||||
NVENC.Use2Pass="Χρήση κωδικοποίησης δύο περασμάτων"
|
||||
NVENC.Preset.default="Προεπιλογή"
|
||||
NVENC.Preset.hq="Υψηλή Ποιότητα"
|
||||
NVENC.Preset.hp="Υψηλές Επιδόσεις"
|
||||
NVENC.Preset.bd="BluRay"
|
||||
NVENC.Preset.ll="Χαμηλή Καθυστέρηση"
|
||||
NVENC.Preset.llhq="Χαμηλή Καθυστέρηση Υψηλή Ποιότητα"
|
||||
NVENC.Preset.llhp="Χαμηλή Καθυστέρηση Υψηλές Επιδόσεις"
|
||||
NVENC.Level="Επίπεδο"
|
||||
|
||||
FFmpegSource="Πηγή Πολυμέσων"
|
||||
LocalFile="Τοπικό αρχείο"
|
||||
|
|
@ -26,7 +18,6 @@ Input="Είσοδος"
|
|||
InputFormat="Μορφή Εισόδου"
|
||||
BufferingMB="Μέγεθος προσωρινης αποθήκευσης Δικτύου (MB)"
|
||||
HardwareDecode="Χρήση αποκωδικοποίησης υλικού όταν είναι διαθέσιμη"
|
||||
ClearOnMediaEnd="Απόκρυψη πηγής όταν τελειώνει η αναπαραγωγή"
|
||||
Advanced="Σύνθετες επιλογές"
|
||||
RestartWhenActivated="Επανεκκίνηση της αναπαραγωγής όταν η πηγή γίνεται ξανά ενεργή"
|
||||
CloseFileWhenInactive="Κλείσιμο του αρχείου όταν η πηγή είναι ανενεργή"
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg Output"
|
|||
FFmpegAAC="FFmpeg Default AAC Encoder"
|
||||
FFmpegOpus="FFmpeg Opus Encoder"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="Max Bitrate"
|
||||
Preset="Preset"
|
||||
RateControl="Rate Control"
|
||||
KeyframeIntervalSec="Keyframe Interval (seconds, 0=auto)"
|
||||
Lossless="Lossless"
|
||||
|
||||
BFrames="B-frames"
|
||||
BFrames="Max B-frames"
|
||||
|
||||
NVENC.Use2Pass="Use Two-Pass Encoding"
|
||||
NVENC.Preset.default="Default"
|
||||
NVENC.Preset.hq="High Quality"
|
||||
NVENC.Preset.hp="High Performance"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Performance"
|
||||
NVENC.Preset.hq="Quality"
|
||||
NVENC.Preset.hp="Max Performance"
|
||||
NVENC.Preset.mq="Max Quality"
|
||||
NVENC.Preset.ll="Low-Latency"
|
||||
NVENC.Preset.llhq="Low-Latency High Quality"
|
||||
NVENC.Preset.llhp="Low-Latency High Performance"
|
||||
NVENC.Level="Level"
|
||||
NVENC.Preset.llhq="Low-Latency Quality"
|
||||
NVENC.Preset.llhp="Low-Latency Performance"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Enables dynamic B-frames.\n\nIf disabled, the encoder will always use the number of B-frames specified in the 'Max B-frames' setting.\n\nIf enabled, it will increase visual quality by only using however many B-frames are necessary, up to the maximum,\nat the cost of increased GPU utilization."
|
||||
NVENC.PsychoVisualTuning="Psycho Visual Tuning"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Enables encoder settings that optimize the use of bitrate for increased perceived visual quality,\nespecially in situations with high motion, at the cost of increased GPU utilization."
|
||||
NVENC.CQLevel="CQ Level"
|
||||
|
||||
FFmpegSource="Media Source"
|
||||
LocalFile="Local File"
|
||||
|
|
@ -26,11 +31,11 @@ Input="Input"
|
|||
InputFormat="Input Format"
|
||||
BufferingMB="Network Buffering (MB)"
|
||||
HardwareDecode="Use hardware decoding when available"
|
||||
ClearOnMediaEnd="Hide source when playback ends"
|
||||
ClearOnMediaEnd="Show nothing when playback ends"
|
||||
Advanced="Advanced"
|
||||
RestartWhenActivated="Restart playback when source becomes active"
|
||||
CloseFileWhenInactive="Close file when inactive"
|
||||
CloseFileWhenInactive.ToolTip="Closes the file when the source is not being displayed on the stream or\nrecording. This allows the file to be changed when the source isn't active,\nbut there may be some startup delay when the source reactivates."
|
||||
CloseFileWhenInactive.ToolTip="Closes the file when the source is not being displayed on the stream or\nrecording. This allows the file to be changed when the source isn't active,\nbut there may be some startup delay when the source reactivates."
|
||||
ColorRange="YUV Color Range"
|
||||
ColorRange.Auto="Auto"
|
||||
ColorRange.Partial="Partial"
|
||||
|
|
@ -49,3 +54,4 @@ ReplayBuffer.Save="Save Replay"
|
|||
|
||||
HelperProcessFailed="Unable to start the recording helper process. Check that OBS files have not been blocked or removed by any 3rd party antivirus / security software."
|
||||
UnableToWritePath="Unable to write to %1. Make sure you're using a recording path which your user account is allowed to write to and that there is sufficient disk space."
|
||||
WarnWindowsDefender="If Windows 10 Ransomware Protection is enabled it can also cause this error. Try turning off controlled folder access in Windows Security / Virus & threat protection settings."
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="Salida de FFmpeg"
|
|||
FFmpegAAC="Codificador AAC FFmpeg predeterminado"
|
||||
FFmpegOpus="Codificador Opus de FFmpeg"
|
||||
Bitrate="Tasa de bits"
|
||||
MaxBitrate="Tasa de bits máxima"
|
||||
Preset="Preajuste"
|
||||
RateControl="Control de la frecuencia"
|
||||
KeyframeIntervalSec="Intervalo de keyframes (segundos, 0=auto)"
|
||||
Lossless="Sin pérdidas"
|
||||
|
||||
BFrames="B-Frames"
|
||||
BFrames="Máximos B-frames"
|
||||
|
||||
NVENC.Use2Pass="Usar codificación en dos pasadas"
|
||||
NVENC.Preset.default="Por defecto"
|
||||
NVENC.Preset.hq="Alta Calidad"
|
||||
NVENC.Preset.hp="Alto rendimiento"
|
||||
NVENC.Preset.bd="BluRay"
|
||||
NVENC.Preset.default="Rendimiento"
|
||||
NVENC.Preset.hq="Calidad"
|
||||
NVENC.Preset.hp="Rendimiento Máximo"
|
||||
NVENC.Preset.mq="Máxima Calidad"
|
||||
NVENC.Preset.ll="Baja latencia"
|
||||
NVENC.Preset.llhq="Baja latencia alta calidad"
|
||||
NVENC.Preset.llhp="Baja latencia alto rendimiento"
|
||||
NVENC.Level="Nivel"
|
||||
NVENC.Preset.llhq="Calidad de baja Latencia"
|
||||
NVENC.Preset.llhp="Rendimiento de baja Latencia"
|
||||
NVENC.LookAhead="\"Look-Ahead\""
|
||||
NVENC.LookAhead.ToolTip="Habilita B-frames dinámicos.\n\nSi se deshabilita, el codificador siempre usará el número de B-frames especificado en el ajuste 'B-frames máximos'.\n\nSi se habilita, incrementará la calidad visual haciendo uso solo de la cantidad de B-frames necesaria, hasta el máximo,\na costa de incrementar el uso de la GPU."
|
||||
NVENC.PsychoVisualTuning="Psycho Visual Tuning"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Activa ajustes del codificador que optimizan el uso del bitrate para aumentar la calidad visual percibida,\nespecialmente en situaciones con alto movimiento, a costa de una mayor utilización de la GPU."
|
||||
NVENC.CQLevel="Nivel de CQ"
|
||||
|
||||
FFmpegSource="Fuente multimedia"
|
||||
LocalFile="Archivo local"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Entrada"
|
|||
InputFormat="Formato de entrada"
|
||||
BufferingMB="Almacenamiento búfer de Red (MB)"
|
||||
HardwareDecode="Utilizar la decodificación por hardware cuando esté disponible"
|
||||
ClearOnMediaEnd="Ocultar la fuente cuando finaliza la reproducción"
|
||||
ClearOnMediaEnd="No mostrar nada al terminar la reproducción"
|
||||
Advanced="Avanzado"
|
||||
RestartWhenActivated="Reiniciar la reproducción cuando la fuente esté activa"
|
||||
CloseFileWhenInactive="Cerrar archivo cuando esté inactivo"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Guardar repetición"
|
|||
|
||||
HelperProcessFailed="No se pudo iniciar el proceso ayudante de grabación. Compruebe que los archivos de OBS no han sido bloqueados o eliminados por cualquier programa de seguridad externo."
|
||||
UnableToWritePath="No se pudo escribir a %1. Asegúrese de que utiliza una ruta de grabación que su cuenta de usuario tenga permisos para escribir y que haya suficiente espacio en disco."
|
||||
WarnWindowsDefender="Si la protección del Ransomware de Windows 10 está activada, también puede causar este error. Intenta desactivar el acceso controlado a la carpeta en la configuración de protección de virus y virus de Windows."
|
||||
|
||||
|
|
|
|||
|
|
@ -7,21 +7,13 @@ Lossless="Kadudeta"
|
|||
|
||||
|
||||
NVENC.Use2Pass="Kasuta Two-Pass kodeeringut"
|
||||
NVENC.Preset.default="Vaikimisi"
|
||||
NVENC.Preset.hq="Kõrge kvaliteet"
|
||||
NVENC.Preset.hp="Suur jõudlus"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.ll="Madal-viivitus"
|
||||
NVENC.Preset.llhq="Madal-viivitus Kõrge kvaliteediga"
|
||||
NVENC.Preset.llhp="Madal-viivitus suure jõudlusega"
|
||||
NVENC.Level="Tase"
|
||||
|
||||
FFmpegSource="Meedia allikas"
|
||||
LocalFile="Kohalik fail"
|
||||
Looping="Korda"
|
||||
Input="Sisend"
|
||||
InputFormat="Sisestus formaat"
|
||||
ClearOnMediaEnd="Peida allikas kui taasesitus lõppeb"
|
||||
RestartWhenActivated="Taaskäivita taasesitus, kui allikas muutub aktiivseks"
|
||||
ColorRange="YUV värviruumi vahemik"
|
||||
ColorRange.Auto="Automaatne"
|
||||
|
|
|
|||
|
|
@ -1,23 +1,28 @@
|
|||
FFmpegOutput="FFmpeg irteera"
|
||||
FFmpegAAC="FFmpeg lehenetsitako AAC Kodetzailea"
|
||||
FFmpegOpus="FFmpeg Opus kodetzailea"
|
||||
Bitrate="Bit-tasa"
|
||||
Preset="Aurrezarpena"
|
||||
Bitrate="Bit-emaria"
|
||||
MaxBitrate="Bit-emari maximoa"
|
||||
Preset="Aurre-ezarpena"
|
||||
RateControl="Tasaren kontrola"
|
||||
KeyframeIntervalSec="Gako-fotogramen tartea (segundoak, 0=auto)"
|
||||
Lossless="Galerarik gabe"
|
||||
|
||||
BFrames="B-fotogramak"
|
||||
BFrames="B-fotogramen maximoa"
|
||||
|
||||
NVENC.Use2Pass="Erabili bi urratseko kodeketa"
|
||||
NVENC.Preset.default="Lehenetsia"
|
||||
NVENC.Preset.hq="Kalitate handia"
|
||||
NVENC.Preset.hp="Eraginkortasun handia"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Use2Pass="Erabili bi pasaldiko kodeketa"
|
||||
NVENC.Preset.default="Errendimendua"
|
||||
NVENC.Preset.hq="Kalitatea"
|
||||
NVENC.Preset.hp="Errendimendu maximoa"
|
||||
NVENC.Preset.mq="Kalitate maximoa"
|
||||
NVENC.Preset.ll="Latentzia txikia"
|
||||
NVENC.Preset.llhq="Latentzia txikia kalitate handia"
|
||||
NVENC.Preset.llhp="Latentzia txikia eraginkortasun handia"
|
||||
NVENC.Level="Maila"
|
||||
NVENC.Preset.llhq="Latentzia txikiko kalitatea"
|
||||
NVENC.Preset.llhp="Latentzia txikiko errendimendua"
|
||||
NVENC.LookAhead="Aurrera begira"
|
||||
NVENC.LookAhead.ToolTip="Gaitu B-fotograma dinamikoak.\n\nGalerazita badaude, kodetzaileak beti erabiliko du 'Max B-fotogramak' ezarpenetan zehazten den B-fotogramen kopurua.\n\nGaituta badaude, ikusmen kalitatea hobetuko du beharrezkoak diren B-fotogramen kopurua erabiliz, maximora iritsi arte\nordainez GPUren erabilera handituko bada ere."
|
||||
NVENC.PsychoVisualTuning="Psycho Visual Tuning"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Aukera ematen du kodetzailea konfiguratzeko optimizatzeko bit-ratioaren erabilera antzemandako ikusmen kalitatea hobetzeko,\nbatez ere mugimendu handiko egoeretan, ordainean GPUren erabilera handituz."
|
||||
NVENC.CQLevel="CQ maila"
|
||||
|
||||
FFmpegSource="Multimedia iturburua"
|
||||
LocalFile="Tokiko fitxategia"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Sarrera"
|
|||
InputFormat="Sarrera formatua"
|
||||
BufferingMB="Sareko bufferreratzea (MB)"
|
||||
HardwareDecode="Erabili hardware deskodeketa eskuragarri dagoenean"
|
||||
ClearOnMediaEnd="Ezkutatu iturburua erreprodukzioa amaitzean"
|
||||
ClearOnMediaEnd="Erreprodukzioa bukatzean ez erakutsi ezer"
|
||||
Advanced="Aurreratua"
|
||||
RestartWhenActivated="Berrabiarazi erreprodukzioa iturburua aktiboa dagoenean"
|
||||
CloseFileWhenInactive="Itxi fitxategia inaktibo dagoenean"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Gorde erreprodukzioa"
|
|||
|
||||
HelperProcessFailed="Ezin izan da grabaziorako laguntza prozesua hasi. Begiratu hirugarren beten antibirusa edo seguritate-softwareak ez duela OBS fitxategiak blokeatzen edo ezabatzen."
|
||||
UnableToWritePath="Ezin izan da idatzi %1-ean. Egiaztatu grabazio-tokian idazteko baimena duzula eta diskoan leku libre nahikoa dagoela."
|
||||
WarnWindowsDefender="Windows 10 Ransomware Protection aktibatuta egoteak errore hori ere sor dezake. Gehitu OBS Windows segurtasuna/ birus eta mehatxuen babeserako ezarpenen kontrolpeko karpeten sarbide-zerrendara."
|
||||
|
||||
|
|
|
|||
43
plugins/obs-ffmpeg/data/locale/fa-IR.ini
Normal file
43
plugins/obs-ffmpeg/data/locale/fa-IR.ini
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
FFmpegOutput="خروجی FFmpeg"
|
||||
FFmpegAAC="پیش فرض FFmpeg تخمین AAC"
|
||||
FFmpegOpus="اپوس FFmpeg تخمین"
|
||||
Bitrate="نرخ بیت"
|
||||
MaxBitrate="حداکثر میزان نرخ بیت"
|
||||
Preset="پیش فرض"
|
||||
RateControl="کنترل نرخ"
|
||||
KeyframeIntervalSec="فاصله Keyframe (ثانیه 0 = خودکار)"
|
||||
Lossless="بدون تلف"
|
||||
|
||||
BFrames="حد اکثر فریم های B"
|
||||
|
||||
NVENC.Use2Pass="استفاده از کدگذاری 2 گذر"
|
||||
NVENC.Preset.default="اجرا (کارایی)"
|
||||
NVENC.Preset.hq="کیفیت"
|
||||
NVENC.Preset.hp="حد اکثر اجرا (کارایی)"
|
||||
NVENC.Preset.mq="حداکثر کیفیت"
|
||||
NVENC.Preset.ll="زمان تاخیر کم"
|
||||
NVENC.Preset.llhq="کیفیت پایین و زمان تاخیر"
|
||||
NVENC.Preset.llhp="زمان تاخیر کم عملکرد"
|
||||
NVENC.LookAhead="پیش رو نگاه"
|
||||
|
||||
LocalFile="فایل محلی"
|
||||
Looping="چرخه"
|
||||
Input="ورودی"
|
||||
InputFormat="فرمت های ورودی"
|
||||
BufferingMB="شبکه بافری (مگابایت)"
|
||||
ColorRange.Auto="خودکار"
|
||||
ColorRange.Partial="جزئی"
|
||||
ColorRange.Full="کامل"
|
||||
RestartMedia="راه اندازی مجدد رسانه ها"
|
||||
SpeedPercentage="سرعت (درصد)"
|
||||
Seekable="جستجوگر"
|
||||
|
||||
MediaFileFilter.AllMediaFiles="تمامی فایل های رسانه"
|
||||
MediaFileFilter.VideoFiles="فایلهای ویدئویی"
|
||||
MediaFileFilter.AudioFiles="فایلهای صوتی"
|
||||
MediaFileFilter.AllFiles="همهی فایل ها"
|
||||
|
||||
ReplayBuffer="پخش مجدد بافر"
|
||||
ReplayBuffer.Save="ذخیره پخش مجدد"
|
||||
|
||||
|
||||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg-ulostulo"
|
|||
FFmpegAAC="FFmpeg oletus AAC-enkooderi"
|
||||
FFmpegOpus="FFmpeg Opus -enkooderi"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="Maksimi bitrate"
|
||||
Preset="Esiasetus"
|
||||
RateControl="Rate Control -tila"
|
||||
KeyframeIntervalSec="Keyframe-väli (sekunteina, 0=automaattinen)"
|
||||
Lossless="Häviötön"
|
||||
|
||||
BFrames="B-kehykset"
|
||||
BFrames="Maksimi B-kehykset"
|
||||
|
||||
NVENC.Use2Pass="Käytä Two-Pass enkoodausta"
|
||||
NVENC.Preset.default="Oletusarvo"
|
||||
NVENC.Preset.hq="Korkea laatu"
|
||||
NVENC.Preset.hp="Korkea suorituskyky"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Suorituskyky"
|
||||
NVENC.Preset.hq="Laatu"
|
||||
NVENC.Preset.hp="Korkein suorituskyky"
|
||||
NVENC.Preset.mq="Korkein laatu"
|
||||
NVENC.Preset.ll="Alhainen latenssi"
|
||||
NVENC.Preset.llhq="Alhainen latenssi, korkea laatu"
|
||||
NVENC.Preset.llhp="Alhainen latenssi, korkea suorituskyky"
|
||||
NVENC.Level="Taso"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Käytä dynaamisia B-kehyksiä.\n\nPois päältä pidettäessä enkooderi käyttää aina B-kehysten lukumäärää joka on asetettu 'Maksimi B-kehykset' -kohdassa.\n\nKäytössä ollessaan se parantaa visuaalista laatua käyttäen vain tarvittavan määrän B-kehyksiä maksimiin asti,\nGPU:n käytön kustannuksella."
|
||||
NVENC.PsychoVisualTuning="Psykovisuaalinen viritys"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Ottaa käyttöön enkooderin asetuksen GPU:n kustannuksella joka optimoi bitraten käytön\nkorkeampaan visuaaliseen laatuun varsinkin tilanteissa joissa liike on nopeaa."
|
||||
NVENC.CQLevel="CQ-taso"
|
||||
|
||||
FFmpegSource="Lisää media"
|
||||
LocalFile="Paikallinen tiedosto"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Sisääntulo"
|
|||
InputFormat="Sisääntulon muoto"
|
||||
BufferingMB="Verkon puskurointi (MB)"
|
||||
HardwareDecode="Käytä laitteistotason purkua, kun mahdollista"
|
||||
ClearOnMediaEnd="Piilota lähde kun toisto päättyy"
|
||||
ClearOnMediaEnd="Älä näytä mitään kun toisto päättyy"
|
||||
Advanced="Lisäasetukset"
|
||||
RestartWhenActivated="Aloita toisto uudelleen kun lähde aktivoituu"
|
||||
CloseFileWhenInactive="Sulje tiedosto, kun toimeton"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Tallenna uusinta"
|
|||
|
||||
HelperProcessFailed="Nauhoitusavustaja-prosessin käynnistäminen ei onnistunut. Tarkista, että OBS-tiedostoja ei ole estetty tai poistettu virustutkan tai muun turvallisuusohjelman johdosta."
|
||||
UnableToWritePath="Ei voida kirjoittaa %1. Tarkista, että käytät oikeaa tiedostopolkua johon käyttäjätililläsi on kirjoitusoikeus. Tarkista myös, että levyllä on tarpeeksi tilaa."
|
||||
WarnWindowsDefender="Tämä virhe saattaa aiheutua myös jos Windowsin Hyökkäysten esto on käytössä. Yritä kytkeä valvottujen kansioiden seuranta pois päältä Windowsin suojaus / Virusten ja uhkien torjunta -asetuksissa."
|
||||
|
||||
|
|
|
|||
|
|
@ -7,17 +7,9 @@ RateControl="Kontrolin ang Antas"
|
|||
KeyframeIntervalSec="Ang pagitan ng Keyframe (segundos, 0=auto)"
|
||||
Lossless="Lossless"
|
||||
|
||||
BFrames="B-frames"
|
||||
|
||||
NVENC.Use2Pass="Gamitin ang Two-Pass Encoding"
|
||||
NVENC.Preset.default="I-Default"
|
||||
NVENC.Preset.hq="Itaas ang Kalidad"
|
||||
NVENC.Preset.hp="Itaas ang Pagganap"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.ll="Mababa na Latency"
|
||||
NVENC.Preset.llhq="Mababa na Latency Mataas na kalidad"
|
||||
NVENC.Preset.llhp="Mababa na Latency Mataas na pagganap"
|
||||
NVENC.Level="Lebel"
|
||||
|
||||
FFmpegSource="Pagkunan ng Media"
|
||||
LocalFile="Ang File na lokal"
|
||||
|
|
@ -26,7 +18,6 @@ Input="Ang Input"
|
|||
InputFormat="Ang Format ng Input"
|
||||
BufferingMB="Nag buffering ang Network (MB)"
|
||||
HardwareDecode="Gamitin ang hardware decoding kapag magagamit"
|
||||
ClearOnMediaEnd="Itago ang pinagmulan kung tapos ang playback"
|
||||
Advanced="I-Advanced"
|
||||
RestartWhenActivated="Simulan mulang ang playback kapag aktibo ang pinagmulan"
|
||||
CloseFileWhenInactive="Isarado ang file pag di aktibo"
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="Sortie FFmpeg"
|
|||
FFmpegAAC="Encodeur AAC FFmpeg par défaut"
|
||||
FFmpegOpus="Encodeur FFmpeg Opus"
|
||||
Bitrate="Débit"
|
||||
Preset="Préréglage"
|
||||
MaxBitrate="Débit maximal"
|
||||
Preset="Pré-réglage"
|
||||
RateControl="Contrôle du débit"
|
||||
KeyframeIntervalSec="Intervalle d'image-clé (en secondes, 0 = auto)"
|
||||
Lossless="Sans perte"
|
||||
|
||||
BFrames="B-frames"
|
||||
BFrames="Nombre maximal de B-frames"
|
||||
|
||||
NVENC.Use2Pass="Utiliser l'encodage double passe"
|
||||
NVENC.Preset.default="Défaut"
|
||||
NVENC.Preset.hq="Haute qualité"
|
||||
NVENC.Preset.hp="Haute performance"
|
||||
NVENC.Preset.bd="Blu-ray"
|
||||
NVENC.Preset.ll="Faible latence"
|
||||
NVENC.Preset.llhq="Faible latence haute qualité"
|
||||
NVENC.Preset.llhp="Faible latence haute performance"
|
||||
NVENC.Level="Niveau"
|
||||
NVENC.Preset.default="Performances"
|
||||
NVENC.Preset.hq="Qualité"
|
||||
NVENC.Preset.hp="Performances maximales"
|
||||
NVENC.Preset.mq="Qualité maximale"
|
||||
NVENC.Preset.ll="Faible Latence"
|
||||
NVENC.Preset.llhq="Qualité avec Faible Latence"
|
||||
NVENC.Preset.llhp="Performance avec Faible Latence"
|
||||
NVENC.LookAhead="Prédiction (Look-ahead)"
|
||||
NVENC.LookAhead.ToolTip="Active les B-frames dynamiques.\n\nSi désactivé, l'encodeur utilisera toujours le nombre de B-frames dans le paramètre \"Nombre maximal de B-frames\".\n\nSi activé, il augmentera la qualité visuelle en n'utilisant que le nombre de B-frames nécessaire, inférieur au maximum,\nau prix d'une utilisation accrue de la carte graphique."
|
||||
NVENC.PsychoVisualTuning="Améliorations psycho-visuelles"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Active des paramètres de l'encodeur qui optimisent l'utilisation du débit afin d'avoir une meilleure qualité visuelle perçue,\nen particulier lors de scènes comportant beaucoup de mouvement, au prix d'une utilisation accrue de la carte graphique."
|
||||
NVENC.CQLevel="Niveau CQ"
|
||||
|
||||
FFmpegSource="Source média"
|
||||
LocalFile="Fichier local"
|
||||
|
|
@ -26,17 +31,17 @@ Input="Entrée"
|
|||
InputFormat="Format d'entrée"
|
||||
BufferingMB="Mémoire tampon réseau (Mo)"
|
||||
HardwareDecode="Utiliser le décodage matériel si possible"
|
||||
ClearOnMediaEnd="Cacher la source lorsque la lecture est finie"
|
||||
ClearOnMediaEnd="Ne rien afficher lorsque la lecture se termine"
|
||||
Advanced="Options avancées"
|
||||
RestartWhenActivated="Reprendre la lecture quand la source est active"
|
||||
CloseFileWhenInactive="Fermer fichier lorsqu’il est inactif"
|
||||
CloseFileWhenInactive.ToolTip="Ferme le fichier lorsque la source ne s'affiche pas sur le flux ou \nl'enregistrement. Cela permet de modifier le fichier lorsque la source n'est pas active, \nmais il peut y avoir un délai de démarrage lorsque la source se réactive."
|
||||
CloseFileWhenInactive.ToolTip="Ferme le fichier lorsque la source ne s'affiche pas sur le stream ou \nl'enregistrement. Cela permet de modifier le fichier lorsque la source n'est pas active, \nmais il peut y avoir un délai de démarrage lorsque la source se réactive."
|
||||
ColorRange="Gamme de couleurs YUV"
|
||||
ColorRange.Auto="Auto"
|
||||
ColorRange.Partial="Partielle"
|
||||
ColorRange.Full="Complète"
|
||||
RestartMedia="Redémarrez Media"
|
||||
SpeedPercentage="Vitesse (pourcent)"
|
||||
RestartMedia="Reprendre depuis le début"
|
||||
SpeedPercentage="Vitesse (pourcentage)"
|
||||
Seekable="Navigable"
|
||||
|
||||
MediaFileFilter.AllMediaFiles="Tous les fichiers multimédias"
|
||||
|
|
@ -47,6 +52,7 @@ MediaFileFilter.AllFiles="Tous les fichiers"
|
|||
ReplayBuffer="Tampon de relecture"
|
||||
ReplayBuffer.Save="Sauvegarder la relecture"
|
||||
|
||||
HelperProcessFailed="Impossible de démarrer le processus d’assistance pour l’enregistrement. Vérifiez que les fichiers de OBS ne sont pas bloqués/supprimés par n’importe quel antivirus/logiciel de sécurité."
|
||||
UnableToWritePath="Impossible d’écrire dans %1. Assurez-vous que vous utilisez un chemin d’enregistrement dont votre compte d’utilisateur est autorisé à écrire et qu’il y a suffisamment d’espace disque."
|
||||
HelperProcessFailed="Impossible de démarrer le processus compagnon pour l’enregistrement. Vérifiez que les fichiers d'OBS ne sont pas bloqués/supprimés par un quelconque antivirus/logiciel de sécurité."
|
||||
UnableToWritePath="Impossible d’écrire dans %1. Assurez-vous que vous utilisez un chemin d’enregistrement où votre compte d’utilisateur est autorisé à écrire et qu’il y a suffisamment d’espace disque."
|
||||
WarnWindowsDefender="Si la Protection contre les ransomware de Windows 10 est activée, cela peut causer cette erreur. Essayez de désactiver le Dispositif d'accès contrôlé aux dossiers dans \"Sécurité Windows\" / \"Protection contre les virus et menaces\"."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,23 @@ FFmpegOutput="Às-chur FFmpeg"
|
|||
FFmpegAAC="Inneal-còdachaidh AAC tùsail airson FFmpeg"
|
||||
FFmpegOpus="Inneal-còdachaidh Opus airson FFmpeg"
|
||||
Bitrate="Reat bhiotaichean"
|
||||
MaxBitrate="Reat bhiotaichean as motha"
|
||||
Preset="Ro-sheata"
|
||||
RateControl="Smachd air an reat"
|
||||
KeyframeIntervalSec="Eadaramh nam frèamaichean-iuchrach (diog, fèin-obrachail)"
|
||||
Lossless="Gun chall càileachd"
|
||||
|
||||
BFrames="Frèamaichean-B"
|
||||
BFrames="Frèamaichean-B as motha"
|
||||
|
||||
NVENC.Use2Pass="Cleachd còdachadh dà phas"
|
||||
NVENC.Preset.default="Bun-roghainn"
|
||||
NVENC.Preset.hq="Càileachd àrd"
|
||||
NVENC.Preset.hp="Dèanadas àrd"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Dèanadas"
|
||||
NVENC.Preset.hq="Càileachd"
|
||||
NVENC.Preset.hp="Dèanadas as àirde"
|
||||
NVENC.Preset.mq="Càileachd as àirde"
|
||||
NVENC.Preset.ll="Foillidheachd ìosal"
|
||||
NVENC.Preset.llhq="Foillidheachd ìosal ⁊ càileachd àrd"
|
||||
NVENC.Preset.llhp="Foillidheachd ìosal ⁊ dèanadas àrd"
|
||||
NVENC.Level="Leibheil"
|
||||
NVENC.Preset.llhq="Càileachd foillidheachd ìosail"
|
||||
NVENC.Preset.llhp="Dèanadas foillidheachd ìosail"
|
||||
NVENC.LookAhead="Coimhead roimhe"
|
||||
|
||||
FFmpegSource="Tùs a’ mheadhain"
|
||||
LocalFile="Faidhle ionadail"
|
||||
|
|
@ -26,7 +27,6 @@ Input="Ion-chur"
|
|||
InputFormat="Fòrmat an ion-chuir"
|
||||
BufferingMB="Bufair an lìonraidh (MB)"
|
||||
HardwareDecode="Cleachd dì-chòdachadh bathair-chruaidh ma bhios e ri fhaighinn"
|
||||
ClearOnMediaEnd="Falaich an tùs nuair a bhios a’ chluiche deiseil"
|
||||
Advanced="Adhartach"
|
||||
RestartWhenActivated="Ath-thòisich a’ chluiche nuair a thig gnìomh on tùs"
|
||||
CloseFileWhenInactive="Dùin am faidhle mur eil gnìomh ann"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ FFmpegAAC="Codificador AAC FFmpeg predefinido"
|
|||
Bitrate="Velocidade de bits"
|
||||
|
||||
|
||||
NVENC.Level="Nivel"
|
||||
|
||||
FFmpegSource="Fonte multimedia"
|
||||
LocalFile="Ficheiro local"
|
||||
|
|
@ -11,7 +10,6 @@ Looping="Bucle"
|
|||
Input="Entrada"
|
||||
InputFormat="Formato de entrada"
|
||||
HardwareDecode="Utilizar a descodificación por hárdware cando estiver dispoñible"
|
||||
ClearOnMediaEnd="Agochar a fonte cando a reprodución remata"
|
||||
Advanced="Avanzado"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,7 @@ Lossless="ללא אובדן נתונים"
|
|||
|
||||
|
||||
NVENC.Use2Pass="השתמש בקידוד שני מעברים"
|
||||
NVENC.Preset.default="ברירת מחדל"
|
||||
NVENC.Preset.hq="איכות גבוהה"
|
||||
NVENC.Preset.hp="ביצועים גבוהים"
|
||||
NVENC.Preset.bd="בלוריי"
|
||||
NVENC.Preset.ll="השהיה נמוכה"
|
||||
NVENC.Preset.llhq="השהיה נמוכה איכות גבוהה"
|
||||
NVENC.Preset.llhp="השהיה נמוכה ביצועים גבוהים"
|
||||
NVENC.Level="רמה"
|
||||
|
||||
FFmpegSource="מקור מדיה"
|
||||
LocalFile="קובץ מקומי"
|
||||
|
|
@ -23,7 +16,6 @@ Looping="לולאה"
|
|||
Input="קלט"
|
||||
InputFormat="תבנית קלט"
|
||||
HardwareDecode="השתמש בפענוח חומרה כאשר היא זמין"
|
||||
ClearOnMediaEnd="הסתר את מקור כאשר ההשמעה מסתיימת"
|
||||
Advanced="מתקדם"
|
||||
RestartWhenActivated="הפעל מחדש השמעה כאשר מקור הופך לפעיל"
|
||||
ColorRange="טווח צבעים YUV"
|
||||
|
|
|
|||
|
|
@ -8,14 +8,7 @@ Lossless="Bez gubitka"
|
|||
|
||||
|
||||
NVENC.Use2Pass="Koristi enkoding duplog prolaza"
|
||||
NVENC.Preset.default="Podrazumevani"
|
||||
NVENC.Preset.hq="Visoki kvalitet"
|
||||
NVENC.Preset.hp="Visoke performanse"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.ll="Nisko kašnjenje"
|
||||
NVENC.Preset.llhq="Visoki kvalitet niskog kašnjenja"
|
||||
NVENC.Preset.llhp="Visoke performanse niskog kašnjenja"
|
||||
NVENC.Level="Nivo"
|
||||
|
||||
FFmpegSource="Medija izvor"
|
||||
LocalFile="Lokalna datoteka"
|
||||
|
|
@ -23,7 +16,6 @@ Looping="Ponavljanje"
|
|||
Input="Ulaz"
|
||||
InputFormat="Format ulaza"
|
||||
HardwareDecode="Koristi hardversko enkodiranje kada je dostupno"
|
||||
ClearOnMediaEnd="Sakrij izvor kada se reprodukcija završi"
|
||||
Advanced="Napredno"
|
||||
RestartWhenActivated="Ponovi reprodukciju kada izvor postane aktivan"
|
||||
ColorRange="YUV opseg boja"
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg kimenet"
|
|||
FFmpegAAC="FFmpeg alapértelmezett AAC kódoló"
|
||||
FFmpegOpus="FFmpeg Opus kódoló"
|
||||
Bitrate="Bitsebesség"
|
||||
MaxBitrate="Max bitsebesség"
|
||||
Preset="Készlet"
|
||||
RateControl="Sebesség Vezérlés"
|
||||
KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)"
|
||||
Lossless="Veszteségmentes"
|
||||
|
||||
BFrames="B képkocka"
|
||||
BFrames="Max B-kockák"
|
||||
|
||||
NVENC.Use2Pass="Kétmenetes kódolás"
|
||||
NVENC.Preset.default="Alapértelmezett"
|
||||
NVENC.Preset.hq="Kiváló minőség"
|
||||
NVENC.Preset.hp="Nagy teljesítmény"
|
||||
NVENC.Preset.bd="BluRay"
|
||||
NVENC.Preset.default="Teljesítménycentrikus"
|
||||
NVENC.Preset.hq="Minőségcentrikus"
|
||||
NVENC.Preset.hp="Maximális teljesítmény"
|
||||
NVENC.Preset.mq="Maximális minőség"
|
||||
NVENC.Preset.ll="Alacsony-késleltetés"
|
||||
NVENC.Preset.llhq="Alacsony-késleltetés kiváló minőséggel"
|
||||
NVENC.Preset.llhp="Alacsony-késleltetés nagy teljesítménnyel"
|
||||
NVENC.Level="Szint"
|
||||
NVENC.Preset.llhq="Alacsony késleltetés minőséggel"
|
||||
NVENC.Preset.llhp="Alacsony késleltetés nagyobb teljesítménnyel"
|
||||
NVENC.LookAhead="Előretekintés"
|
||||
NVENC.LookAhead.ToolTip="Lehetővé teszi a dinamikus B-kockákat.\n\nHa le van tiltva, a kódoló mindig a \"Max B-kockák\" beállításnál megadott értéket használja.\n\nHa engedélyezve van, az növeli vizuális minőséget és annyi B-kockát használ a kódoló, amennyire szükség van, akár a maximumot is,\nmegnövekedett GPU kihasználtság árán."
|
||||
NVENC.PsychoVisualTuning="Psichovizuális Tuning"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Lehetővé teszi a kódoló beállításait bitráta optimalizáláshoz az érzékelhető vizuális minőség megnöveléséhez,\nkülönösen olyan helyzetekben ahol sok a mozgás, megnövekedett GPU kihasználtság árán."
|
||||
NVENC.CQLevel="CQ szint"
|
||||
|
||||
FFmpegSource="Médiaforrás"
|
||||
LocalFile="Helyi fájl"
|
||||
|
|
@ -26,11 +31,11 @@ Input="Bemenet"
|
|||
InputFormat="Bemeneti formátum"
|
||||
BufferingMB="Hálózati pufferelés (MB)"
|
||||
HardwareDecode="Hardveres dekódolás használata, ha rendelkezésre áll"
|
||||
ClearOnMediaEnd="Forrás elrejtése a lejátszás végeztével"
|
||||
ClearOnMediaEnd="Semmit se mutasson, a lejátszás végeztével"
|
||||
Advanced="Haladó"
|
||||
RestartWhenActivated="Lejátszás újraindítása, ha a forrás aktivizálódik"
|
||||
CloseFileWhenInactive="Fájl bezárása ha tétlen"
|
||||
CloseFileWhenInactive.ToolTip="Bezárja a fájlt, ha a forrás nem aktív streamen vagy\nfelvételen. Ez lehetővé teszi, hogy a fájlt meg kell változtatni, ha a forrás nem aktív, a \nviszont felléphet némi indítási késés, ha a forrás reaktiválódik."
|
||||
CloseFileWhenInactive.ToolTip="Bezárja a fájlt, ha a forrás nem aktív streamen vagy\nfelvételen. Ez lehetővé teszi, hogy a fájlt meg kell változtatni, ha a forrás nem aktív, a \nviszont felléphet némi indítási késés, ha a forrás reaktiválódik."
|
||||
ColorRange="YUV színtartomány"
|
||||
ColorRange.Auto="Auto"
|
||||
ColorRange.Partial="Részleges"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Visszajátszás mentése"
|
|||
|
||||
HelperProcessFailed="Nem lehet indítani a felvétel segítő folyamatot. Ellenőrizze, hogy az OBS fájlok nincsenek e blokkolva vagy eltávolítva bármilyen harmadik féltől származó antivírus / biztonsági szoftver által."
|
||||
UnableToWritePath="Nem lehet megírni a %1. Győződjön meg róla, hogy a felhasználói fiókjának megvannak a szükséges engedélyei az íráshoz vagy rendelkezésre áll az elegendő lemezterület."
|
||||
WarnWindowsDefender="Amennyiben a Windows 10 Ransomware Védelem aktiválva van, úgy az is képes ezt a hibát generálni. Adja hozzá a kontrollált könyvtárlistához a Windows Biztonság / Vírus és fenyegetésvédelem beállítások között."
|
||||
|
||||
|
|
|
|||
|
|
@ -1,52 +1,58 @@
|
|||
FFmpegOutput="Uscita FFmpeg"
|
||||
FFmpegAAC="Codificatore FFmpeg predefinito AAC"
|
||||
FFmpegOpus="FFmpeg Opus Encoder"
|
||||
Bitrate="Bitrate"
|
||||
FFmpegAAC="Codifica FFmpeg predefinita per AAC"
|
||||
FFmpegOpus="Codifica FFmpeg Opus"
|
||||
Bitrate="Velocità in bit"
|
||||
MaxBitrate="Velocità in bit massima"
|
||||
Preset="Preset"
|
||||
RateControl="Controllo frequenza"
|
||||
KeyframeIntervalSec="Intervallo Keyframe (secondi, 0=automatico)"
|
||||
RateControl="Tipo di controllo della frequenza"
|
||||
KeyframeIntervalSec="Intervallo dei fotogrammi chiave (in secondi, 0=automatico)"
|
||||
Lossless="Lossless"
|
||||
|
||||
BFrames="B-frames"
|
||||
BFrames="B-frame massimi"
|
||||
|
||||
NVENC.Use2Pass="Usa codifica in due passaggi"
|
||||
NVENC.Preset.default="Predefinito"
|
||||
NVENC.Preset.hq="Alta Qualità"
|
||||
NVENC.Preset.hp="Alte Prestazioni"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Use2Pass="Utilizza la codifica in due passaggi"
|
||||
NVENC.Preset.default="Prestazioni"
|
||||
NVENC.Preset.hq="Qualità"
|
||||
NVENC.Preset.hp="Massime prestazioni"
|
||||
NVENC.Preset.mq="Massima qualità"
|
||||
NVENC.Preset.ll="Bassa latenza"
|
||||
NVENC.Preset.llhq="Bassa latenza Alta Qualità"
|
||||
NVENC.Preset.llhp="Bassa latenza ad Alte Prestazioni"
|
||||
NVENC.Level="Livello"
|
||||
NVENC.Preset.llhq="Bassa latenza e qualità"
|
||||
NVENC.Preset.llhp="Bassa latenza e prestazioni"
|
||||
NVENC.LookAhead="Previsione (look-ahead)"
|
||||
NVENC.LookAhead.ToolTip="Attiva i B-frame dinamici.\n\nSe disattivato, la codifica utilizzerà sempre il numero di B-frame specificato nell'impostazione «B-frame massimi».\n\nSe attivato, aumenterà la qualità visiva utilizzando comunque solo i B-frame necessari,\nfino al massimo, al costo di un maggiore utilizzo della GPU."
|
||||
NVENC.PsychoVisualTuning="Ottimizzazione visiva di Psycho"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Attiva le impostazioni di codifica che ottimizzano l'utilizzo della velocità in bit per ottenere una maggiore qualità visiva,\nsoprattutto in situazioni con molti movimenti, al costo di un maggiore utilizzo della GPU."
|
||||
NVENC.CQLevel="Livello di quantificazione costante"
|
||||
|
||||
FFmpegSource="Origine multimediale"
|
||||
FFmpegSource="Fonte multimediale"
|
||||
LocalFile="File locale"
|
||||
Looping="Ripeti"
|
||||
Input="Input"
|
||||
InputFormat="Formato di input"
|
||||
BufferingMB="Rete Buffering (MB)"
|
||||
InputFormat="Formato dell'input"
|
||||
BufferingMB="Buffering della rete (in MB)"
|
||||
HardwareDecode="Utilizza la decodifica hardware quando disponibile"
|
||||
ClearOnMediaEnd="Nascondi la fonte quando termina la riproduzione"
|
||||
ClearOnMediaEnd="Non mostrare nulla quando la riproduzione finisce"
|
||||
Advanced="Avanzate"
|
||||
RestartWhenActivated="Riattiva playback quando la fonte torna attiva"
|
||||
CloseFileWhenInactive="Chiudi file quando inattivo"
|
||||
CloseFileWhenInactive.ToolTip="Chiude il file quando l'origine non viene visualizzato sullo stream o\nrecording il flusso. In questo modo permette di modificare il file quando la fonte non è attiva, \nma ci può essere qualche ritardo di avvio quando si riattiva l'origine."
|
||||
RestartWhenActivated="Riavvia la riproduzione quando la fonte torna attiva"
|
||||
CloseFileWhenInactive="Chiudi il file quando la fonte diventa inattiva"
|
||||
CloseFileWhenInactive.ToolTip="Chiude il file quando la fonte non viene più visualizzata nell'inquadratura.\nQuesto permette di modificare il file quando la fonte non è attiva,\nma potrebbe esserci un po' di ritardo all'avvio quando si riattiva la fonte."
|
||||
ColorRange="Gamma di colore YUV"
|
||||
ColorRange.Auto="Autom."
|
||||
ColorRange.Auto="Automatico"
|
||||
ColorRange.Partial="Parziale"
|
||||
ColorRange.Full="Intero"
|
||||
RestartMedia="Riavvia Media"
|
||||
SpeedPercentage="Velocità (percentuale)"
|
||||
RestartMedia="Riavvia media dall'inizio"
|
||||
SpeedPercentage="Velocità (in percentuale)"
|
||||
Seekable="Ricercabile"
|
||||
|
||||
MediaFileFilter.AllMediaFiles="Tutti i file media"
|
||||
MediaFileFilter.AllMediaFiles="Tutti i file multimediali"
|
||||
MediaFileFilter.VideoFiles="File video"
|
||||
MediaFileFilter.AudioFiles="File audio"
|
||||
MediaFileFilter.AllFiles="Tutti i file"
|
||||
|
||||
ReplayBuffer="Buffer di Replay"
|
||||
ReplayBuffer.Save="Salva Replay"
|
||||
ReplayBuffer="Buffer di replay"
|
||||
ReplayBuffer.Save="Salva il replay"
|
||||
|
||||
HelperProcessFailed="Impossibile avviare il processo di supporto di registrazione. Verifica che i file di OBS non siano stati bloccati o rimossi da software di sicurezza od antivirus di terze parti."
|
||||
UnableToWritePath="Impossibile scrivere su %1. Assicurati che il tuo account possa accedere al percorso di registrazione, e che ci sia spazio sufficiente su disco."
|
||||
HelperProcessFailed="Impossibile avviare il processo di assistenza alla registrazione. Controlla che i file di OBS non siano stati bloccati o rimossi da software di sicurezza di terze parti o antivirus."
|
||||
UnableToWritePath="Impossibile scrivere su %1. Assicurati che il tuo account utente possa accedere al percorso di registrazione, e che ci sia spazio sufficiente sul disco."
|
||||
WarnWindowsDefender="Se la protezione ransomware di Windows 10 è attivata, può causare questo errore. Prova a disattivare l'accesso alle cartelle controllato, lo puoi trovare in Sicurezza di Windows → Protezione da virus e minacce → Gestisci protezione ransomware."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg の出力"
|
|||
FFmpegAAC="FFmpeg 既定のAAC エンコーダ"
|
||||
FFmpegOpus="FFmpeg Opus エンコーダ"
|
||||
Bitrate="ビットレート"
|
||||
MaxBitrate="最大ビットレート"
|
||||
Preset="プリセット"
|
||||
RateControl="レート制御"
|
||||
KeyframeIntervalSec="キーフレーム間隔 (秒, 0=自動)"
|
||||
Lossless="無損失"
|
||||
|
||||
BFrames="B-フレーム"
|
||||
BFrames="最大 B フレーム"
|
||||
|
||||
NVENC.Use2Pass="2パスエンコードを使用"
|
||||
NVENC.Preset.default="既定"
|
||||
NVENC.Preset.hq="高品質"
|
||||
NVENC.Preset.hp="高性能"
|
||||
NVENC.Preset.bd="ブルーレイ"
|
||||
NVENC.Preset.ll="低遅延"
|
||||
NVENC.Preset.llhq="低遅延高品質"
|
||||
NVENC.Preset.llhp="低遅延高性能"
|
||||
NVENC.Level="レベル"
|
||||
NVENC.Preset.default="Performance"
|
||||
NVENC.Preset.hq="Quality"
|
||||
NVENC.Preset.hp="Max Performance"
|
||||
NVENC.Preset.mq="Max Quality"
|
||||
NVENC.Preset.ll="Low-Latency"
|
||||
NVENC.Preset.llhq="Low-Latency Quality"
|
||||
NVENC.Preset.llhp="Low-Latency Performance"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="動的Bフレームを有効にします。 \n\n無効にすると、エンコーダは常に’最大Bフレーム数’設定で指定されたBフレーム数を使用します。 \n\n有効にした場合、GPU使用率の増加を犠牲にして、\n\n最大数まで、必要な分だけ多くのBフレームを使用することで視覚的品質を向上させます。"
|
||||
NVENC.PsychoVisualTuning="心理視覚チューニング"
|
||||
NVENC.PsychoVisualTuning.ToolTip="GPU使用率の増加を犠牲にして、特に動きの激しい状況で、\n視覚品質の向上のためにビットレートの使用を最適化するエンコーダ設定を有効にします。"
|
||||
NVENC.CQLevel="CQ レベル"
|
||||
|
||||
FFmpegSource="メディアソース"
|
||||
LocalFile="ローカルファイル"
|
||||
|
|
@ -26,7 +31,7 @@ Input="入力"
|
|||
InputFormat="入力フォーマット"
|
||||
BufferingMB="ネットワークバッファリング (MB)"
|
||||
HardwareDecode="可能な場合ハードウェアデコードを使用"
|
||||
ClearOnMediaEnd="再生終了時にソースを非表示にする"
|
||||
ClearOnMediaEnd="再生終了時に何も表示しない"
|
||||
Advanced="高度な設定"
|
||||
RestartWhenActivated="ソースがアクティブになったときに再生を再開する"
|
||||
CloseFileWhenInactive="アクティブでないときにファイルを閉じる"
|
||||
|
|
@ -44,9 +49,10 @@ MediaFileFilter.VideoFiles="ビデオファイル"
|
|||
MediaFileFilter.AudioFiles="オーディオファイル"
|
||||
MediaFileFilter.AllFiles="すべてのファイル"
|
||||
|
||||
ReplayBuffer="リプレイバッファー"
|
||||
ReplayBuffer="リプレイバッファ"
|
||||
ReplayBuffer.Save="リプレイ保存"
|
||||
|
||||
HelperProcessFailed="録画の補助プロセスを開始できません。 OBSのファイルがサードパーティ製のアンチウイルス/セキュリティソフトウェアによってブロックまたは削除されていないことを確認してください。"
|
||||
UnableToWritePath="%1 に書き込めません。 あなたのユーザーアカウントが書き込みを許可されている録画のパスを使用していることと十分なディスク容量があることを確認してください。"
|
||||
WarnWindowsDefender="Windows 10 ランサムウェア保護が有効になっていると、このエラーが発生する可能性があります。Windowsのセキュリティ/ウイルス対策と脅威対策の設定で、フォルダへのアクセス制御を無効にしてみてください。"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,28 @@
|
|||
FFmpegOutput="FFmpeg გამომავალი სიგნალი"
|
||||
FFmpegOutput="FFmpeg-გამოტანა"
|
||||
FFmpegAAC="FFmpeg ნაგულისხმევი AAC დამშიფრავი"
|
||||
FFmpegOpus="FFmpeg Opus დამშიფრავი"
|
||||
Bitrate="ბიტური სიხშირე"
|
||||
MaxBitrate="უმაღლესი დასაშვები ბიტური სიხშირე"
|
||||
Preset="მზა პარამეტრები"
|
||||
RateControl="სიხშირის მართვა"
|
||||
KeyframeIntervalSec="საკვანძო კადრებს შორის შუალედი (წამი, 0=თვითშერჩევა)"
|
||||
Lossless="უდანაკარგო"
|
||||
|
||||
BFrames="B-კადრები"
|
||||
BFrames="B-კადრების დასაშვები რაოდენობა"
|
||||
|
||||
NVENC.Use2Pass="ორმაგი დაშიფვრის გამოყენება"
|
||||
NVENC.Preset.default="ნაგულისხმევი"
|
||||
NVENC.Preset.hq="მაღალი ხარისხი"
|
||||
NVENC.Preset.hp="მაღალი წარმადობა"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="წარმადობა"
|
||||
NVENC.Preset.hq="ხარისხი"
|
||||
NVENC.Preset.hp="უმაღლესი წარმადობა"
|
||||
NVENC.Preset.mq="უმაღლესი ხარისხი"
|
||||
NVENC.Preset.ll="მცირე დაყოვნება"
|
||||
NVENC.Preset.llhq="მცირე დაყოვნება, მაღალი ხარისხი"
|
||||
NVENC.Preset.llhp="მცირე დაყოვნება, მაღალი წარმადობა"
|
||||
NVENC.Level="საფეხური"
|
||||
NVENC.Preset.llhq="მცირე დაყოვნება მაღალი ხარისხით"
|
||||
NVENC.Preset.llhp="მცირე დაყოვნება მაღალი წარმადობით"
|
||||
NVENC.LookAhead="თვითგანსაზღვრა"
|
||||
NVENC.LookAhead.ToolTip="ჩაირთვება ცვალებადი რაოდენობის B-კადრები.\n\nგამორთვის შემთხვევაში, დამშიფრავი ყოველთვის „B-კადრების დასაშვები რაოდენობის“ ველში მითითებულს გამოიყენებს.\n\nჩართვის შედეგად, გაიზრდება გამოსახულების ხარისხი საჭირო რაოდენობის B-კადრების დამატებით, უმაღლეს დასაშვებ რაოდენობამდე,\nგრაფიკული პროცესორის გაზრდილი დატვირთვის ხარჯზე."
|
||||
NVENC.PsychoVisualTuning="ფსიქოვიზუალური გამართვა"
|
||||
NVENC.PsychoVisualTuning.ToolTip="საშუალებას აძლევს დამშიფრავს, საუკეთესოდ შეარჩიოს ბიტური სიხშირე გამოსახულების ხარისხის უკეთ აღქმისთვის,\nგანსაკუთრებით მოძრავ სცენებში, გრაფიკული პროცესორის გაზრდილი დატვირთვის ხარჯზე."
|
||||
NVENC.CQLevel="CQ-დონე (მუდმივ ნაწილაკებად დაყოფა)"
|
||||
|
||||
FFmpegSource="მასალის წყარო"
|
||||
LocalFile="ადგილობრივი ფაილი"
|
||||
|
|
@ -26,11 +31,11 @@ Input="შეტანა"
|
|||
InputFormat="შეტანის ფორმატი"
|
||||
BufferingMB="ქსელის ბუფერიზაცია (მბაიტი)"
|
||||
HardwareDecode="აპარატურული დაშიფვრის გამოყენება, ხელმისაწვდომობის შემთხვევაში"
|
||||
ClearOnMediaEnd="წყაროს დამალვა, გაშვების დამთავრებისას"
|
||||
ClearOnMediaEnd="აღარაფერი გამოჩნდეს, ჩვენების დასრულების შემდგომ"
|
||||
Advanced="გაფართოებული"
|
||||
RestartWhenActivated="ხელახლა გაშვება წყაროს ამოქმედებისას"
|
||||
CloseFileWhenInactive="ფაილის დახურვა უმოქმედობისას"
|
||||
CloseFileWhenInactive.ToolTip="ფაილი დაიხურება, თუ წყარო არ იქნება ეთერში ან\nჩაწერაზე გაშვებული. ეს საშუალებას იძლევა შეიცვალოს ფაილი, როცა წყარო არაა მოქმედი,\nთუმცა ხელახლა ამოქმედებისას, შესაძლოა გარკვეული დროით დაყოვნებას ჰქონდეს ადგილი."
|
||||
CloseFileWhenInactive.ToolTip="ფაილი დაიხურება, თუ წყარო არ იქნება ეთერში ან\nჩაწერაზე გაშვებული. ეს საშუალებას იძლევა შეიცვალოს ფაილი, როცა წყარო არაა მოქმედი,\nთუმცა ხელახლა ამოქმედებისას, შესაძლოა გარკვეული დროით დაყოვნებას ჰქონდეს ადგილი."
|
||||
ColorRange="YUV ფერთა გამა"
|
||||
ColorRange.Auto="ავტომატური"
|
||||
ColorRange.Partial="ნაწილობრივი"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="გადახვევის შენახვა"
|
|||
|
||||
HelperProcessFailed="ჩაწერის პროცესის გაშვება ვერ ხერხდება. გადაამოწმეთ, ხომ არ არის OBS ფაილები შეზღუდული ან წაშლილი ანტივირუსის / უსაფრთხოების სხვა პროგრამების მიერ."
|
||||
UnableToWritePath="%1-ში ჩაწერა ვერ ხერხდება. დარწმუნდით, რომ ჩაწერისთვის ისეთი მისამართი გაქვთ მითითებული, სადაც ჩაწერის ნებართვაც გააჩნია თქვენს ანგარიშს და ამასთან, არის საკმარისი ადგილი დისკზე."
|
||||
WarnWindowsDefender="თუ ჩართულია Windows 10-ის დაცვა ფაილების მიმტაცებელი პროგრამებისგან (Ransomware), ამ შეცდომას ეგეც შეიძლება იწვევდეს. სცადეთ საქაღალდეებთან წვდომის შეზღუდვის მოხსნა, Windows-ის უსაფრთხოების ან ანტივირუსის პარამეტრებიდან."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg 출력"
|
|||
FFmpegAAC="FFmpeg 기본 AAC 인코더"
|
||||
FFmpegOpus="FFmpeg Opus 인코더"
|
||||
Bitrate="비트레이트"
|
||||
MaxBitrate="최대 비트레이트"
|
||||
Preset="사전 설정"
|
||||
RateControl="데이터율 제어"
|
||||
KeyframeIntervalSec="키프레임 간격 (초 단위, 0=자동)"
|
||||
Lossless="무손실"
|
||||
|
||||
BFrames="B-화면"
|
||||
BFrames="최대 B-프레임"
|
||||
|
||||
NVENC.Use2Pass="2 패스 인코딩 사용"
|
||||
NVENC.Preset.default="기본"
|
||||
NVENC.Preset.hq="우수한 품질"
|
||||
NVENC.Preset.hp="우수한 성능"
|
||||
NVENC.Preset.bd="블루레이"
|
||||
NVENC.Preset.default="성능 우선"
|
||||
NVENC.Preset.hq="품질 우선"
|
||||
NVENC.Preset.hp="최대 성능"
|
||||
NVENC.Preset.mq="최대 품질"
|
||||
NVENC.Preset.ll="낮은 지연 시간"
|
||||
NVENC.Preset.llhq="낮은 지연 시간 우수한 품질"
|
||||
NVENC.Preset.llhp="낮은 지연 시간 우수한 성능"
|
||||
NVENC.Level="수준"
|
||||
NVENC.Preset.llhq="낮은 지연 시간 및 품질"
|
||||
NVENC.Preset.llhp="낮은 지연 시간 및 성능"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="동적 B-프레임을 활성화합니다.\n\n이 설정을 사용하지 않으면 인코더는 항상 지정한 수 만큼만 B-프레임을 사용합니다.\n\n이 설정을 켜면 B-프레임을 품질을 올리는데 필요한 만큼 사용하지만,\nGPU사용률이 증가합니다."
|
||||
NVENC.PsychoVisualTuning="Psycho Visual Tuning"
|
||||
NVENC.PsychoVisualTuning.ToolTip="비트레이트 사용을 최적화하여 영상 품질을 높일 수 있습니다.\n특히 영상 내 빠른 동작을 처리할 때 도움이 됩니다. 다만 GPU 사용률이 증가합니다."
|
||||
NVENC.CQLevel="CQ 수준"
|
||||
|
||||
FFmpegSource="미디어 소스"
|
||||
LocalFile="로컬 파일"
|
||||
|
|
@ -26,7 +31,7 @@ Input="입력"
|
|||
InputFormat="입력 형식"
|
||||
BufferingMB="네트워크 버퍼링 (MB)"
|
||||
HardwareDecode="가능한 경우 하드웨어 디코딩 사용"
|
||||
ClearOnMediaEnd="재생이 끝나면 소스를 숨기기"
|
||||
ClearOnMediaEnd="재생이 끝나면 아무 것도 표시하지 않기"
|
||||
Advanced="고급"
|
||||
RestartWhenActivated="소스가 활성화될 때 재생을 다시 시작"
|
||||
CloseFileWhenInactive="비활성화 상태일 때 파일 닫기"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="리플레이 저장"
|
|||
|
||||
HelperProcessFailed="녹화 도우미를 시작할 수 없습니다. 백신이나 보안 소프트웨어가 OBS 파일을 차단 혹은 제거하지 않았는지 확인하십시오."
|
||||
UnableToWritePath="%1에 기록할 수 없습니다. 사용자 계정이 녹화 계정에 접근할 수 있는지 혹은 저장 공간이 충분한지 확인하십시오."
|
||||
WarnWindowsDefender="윈도우 10에서 제공하는 랜섬웨어 보호 기능이 켜져 있으면 이 오류가 일어날 수 있습니다. 윈도우 설정에서 '보호된 폴더' 기능을 검색하여 꺼주세요."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg utdata"
|
|||
FFmpegAAC="Standard FFmpeg AAC-koder"
|
||||
FFmpegOpus="FFmpeg Opus enkoder"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="Maks bitrate"
|
||||
Preset="Forhåndsinnstilling"
|
||||
RateControl="Hastighetskontroll"
|
||||
KeyframeIntervalSec="Nøkkelbildeintervall (sekunder, 0 = automatisk)"
|
||||
Lossless="Tapsfri"
|
||||
|
||||
BFrames="B-bilder"
|
||||
BFrames="Maksimalt antall B-frames"
|
||||
|
||||
NVENC.Use2Pass="Bruk tostegskoding"
|
||||
NVENC.Preset.default="Standard"
|
||||
NVENC.Preset.hq="Høy kvalitet"
|
||||
NVENC.Preset.hp="Høy ytelse"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Ytelse"
|
||||
NVENC.Preset.hq="Kvalitet"
|
||||
NVENC.Preset.hp="Best ytelse"
|
||||
NVENC.Preset.mq="Best kvalitet"
|
||||
NVENC.Preset.ll="Lav latens"
|
||||
NVENC.Preset.llhq="Lav latens, høy kvalitet"
|
||||
NVENC.Preset.llhp="Lav latens, høy ytelse"
|
||||
NVENC.Level="Nivå"
|
||||
NVENC.Preset.llhq="Lav latens og kvalitet"
|
||||
NVENC.Preset.llhp="Lav latens og ytelse"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Aktiverer dynamiske B-frames. \n\nHvis deaktivert, vil koderen alltid bruke nummeret spesifisert i \"Maks B-frames\" instillingen. \n\nHvis aktivert, vil bildekvaliteten forbedres ved å bare bruke antallet nødvendige B-frames, opp til maksimum antallet,\npå bekostning av økt GPU-forbruk."
|
||||
NVENC.PsychoVisualTuning="Psykovisuell justering"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Aktiverer kodingsinstillinger som optimerer bruken av bitrate for forbedret oppfattet bildekvalitet,\nspesielt i situasjonen med mye bevegelse, på bekostning av økt GPU-forbruk."
|
||||
NVENC.CQLevel="QC-nivå"
|
||||
|
||||
FFmpegSource="Mediekilde"
|
||||
LocalFile="Lokal fil"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Inngang"
|
|||
InputFormat="Inngangsformat"
|
||||
BufferingMB="Nettverksbuffer (Mb)"
|
||||
HardwareDecode="Bruk maskinvaredekoding når tilgjengelig"
|
||||
ClearOnMediaEnd="Skjul kilde når avspilling ender"
|
||||
ClearOnMediaEnd="Vis ingenting når avspillingen slutter"
|
||||
Advanced="Avansert"
|
||||
RestartWhenActivated="Start avspilling omigjen når kilde blir aktiv"
|
||||
CloseFileWhenInactive="Lukk fil når inaktiv"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Lagre replay"
|
|||
|
||||
HelperProcessFailed="Kan ikke starte prosess for opptakshjelper. Sjekk at OBS ikke har noen blokkerte filer, eller at tredjeparts antivirus/sikkerhetsprogramvare har slettet noen filer."
|
||||
UnableToWritePath="Kan ikke skrive til %1. Kontroller at du bruker en filbane som kontoen din har rettigheter til å skrive på, og at du har nok diskplass tilgjengelig."
|
||||
WarnWindowsDefender="Hvis Windows 10 Ransomvare-beskyttelse er aktivert, kan dette medføre denne feilen. Forsøk å deaktivere kontrollert mappetilgang i Windows-instillingen Sikkerhet > Virus- og Trusselbeskyttelse."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg-uitvoer"
|
|||
FFmpegAAC="FFmpeg Standaard AAC Encoder"
|
||||
FFmpegOpus="FFmpeg Opus Encoder"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="Maximale bitrate"
|
||||
Preset="Preset"
|
||||
RateControl="Rate Control"
|
||||
KeyframeIntervalSec="Tijd tussen keyframes (seconden, 0=auto)"
|
||||
Lossless="Lossless"
|
||||
|
||||
BFrames="B-frames"
|
||||
BFrames="Max B-frames"
|
||||
|
||||
NVENC.Use2Pass="Gebruik two-pass encoding"
|
||||
NVENC.Preset.default="Standaard"
|
||||
NVENC.Preset.hq="Hoge kwaliteit"
|
||||
NVENC.Preset.hp="Hoge prestaties"
|
||||
NVENC.Preset.bd="Blu-ray"
|
||||
NVENC.Preset.default="Prestaties"
|
||||
NVENC.Preset.hq="Kwaliteit"
|
||||
NVENC.Preset.hp="Hoogste Prestaties"
|
||||
NVENC.Preset.mq="Hoogste Kwaliteit"
|
||||
NVENC.Preset.ll="Lage Latency"
|
||||
NVENC.Preset.llhq="Lage latency, hoge kwaliteit"
|
||||
NVENC.Preset.llhp="Lage latency, hoge prestaties"
|
||||
NVENC.Level="Niveau"
|
||||
NVENC.Preset.llhq="Lage Latency Kwaliteit"
|
||||
NVENC.Preset.llhp="Lage Latency Prestaties"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Maakt dynamische B-frames mogelijk.\n\nIndien uitgeschakeld, zal de encoder altijd het aantal B-frames gebruiken dat is opgegeven in de instelling 'Max B-frames'.\n\nIndien ingeschakeld, zal het de visuele kwaliteit verhogen door alleen het aantal B-frames te gebruiken dat nodig is, tot het maximum,\nten koste van een verhoogd GPU-gebruik."
|
||||
NVENC.PsychoVisualTuning="Psycho Visuele Stemming"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Maakt encoderinstellingen mogelijk die het gebruik van de bitsnelheid optimaliseren voor een hogere waargenomen visuele kwaliteit,\nvooral in situaties met veel beweging, ten koste van een hoger GPU-gebruik."
|
||||
NVENC.CQLevel="CQ effen"
|
||||
|
||||
FFmpegSource="Mediabron"
|
||||
LocalFile="Lokaal bestand"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Invoer"
|
|||
InputFormat="Invoerformaat"
|
||||
BufferingMB="Netwerk Buffering (MB)"
|
||||
HardwareDecode="Gebruik hardware-decoding wanneer mogelijk"
|
||||
ClearOnMediaEnd="Verberg de bron na het afspelen"
|
||||
ClearOnMediaEnd="Toon niets wanneer het afspelen eindigt"
|
||||
Advanced="Geavanceerd"
|
||||
RestartWhenActivated="Opnieuw starten met afspelen zodra de bron actief wordt"
|
||||
CloseFileWhenInactive="Sluit bestand wanneer niet actief"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Replay Opslaan"
|
|||
|
||||
HelperProcessFailed="Kan het opnamehulp-proces niet starten. Controleer of er geen OBS bestanden geblokkeerd of verwijderd zijn door antivirus of beveiligingssoftware."
|
||||
UnableToWritePath="Kan niet naar %1 schrijven. Controller of je een opnamepad gebruikt waar je gebruikersaccount naartoe kan schrijven, en dat er voldoende schijfruimte beschikbaar is."
|
||||
WarnWindowsDefender="Als Windows 10 Ransomware Protection is ingeschakeld, kan dit ook deze fout veroorzaken. Probeer gecontroleerde toegang tot mappen uit te schakelen in de instellingen van Windows Security / Virus & Threat Protection."
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,28 @@
|
|||
FFmpegOutput="Wyjście FFmpeg"
|
||||
FFmpegAAC="Domyślny enkoder AAC w FFmpeg"
|
||||
FFmpegOpus="Enkoder FFmpeg Opus"
|
||||
Bitrate="Przepływność bitowa"
|
||||
Bitrate="Przepływność (bitrate)"
|
||||
MaxBitrate="Maksymalna przepływność (bitrate)"
|
||||
Preset="Profil ustawień"
|
||||
RateControl="Typ przepływności"
|
||||
KeyframeIntervalSec="Odstęp między klatkami kluczowymi (sekundy, 0=automatyczny)"
|
||||
Lossless="Bezstratny"
|
||||
|
||||
BFrames="B-ramki"
|
||||
BFrames="Maksymalna liczba klatek B-frame"
|
||||
|
||||
NVENC.Use2Pass="Użyj enkodowania dwuprzebiegowego"
|
||||
NVENC.Preset.default="Domyślny"
|
||||
NVENC.Preset.hq="Wysoka jakość"
|
||||
NVENC.Preset.hp="Wysoka wydajność"
|
||||
NVENC.Preset.bd="Blu-ray"
|
||||
NVENC.Preset.default="Wydajność"
|
||||
NVENC.Preset.hq="Jakość"
|
||||
NVENC.Preset.hp="Najlepsza wydajność"
|
||||
NVENC.Preset.mq="Najlepsza jakość"
|
||||
NVENC.Preset.ll="Niskie opóźnienie"
|
||||
NVENC.Preset.llhq="Niskie opóźnienie - wysoka jakość"
|
||||
NVENC.Preset.llhp="Niskie opóźnienie - wysoka wydajność"
|
||||
NVENC.Level="Poziom"
|
||||
NVENC.Preset.llhq="Niskie opóźnienie - jakość"
|
||||
NVENC.Preset.llhp="Niskie opóźnienie - wydajność"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Umożliwia dynamiczne klatki B.\n\nJeśli jest wyłączony, koder będzie zawsze używać liczbę klatek B określonego w ustawieniach 'Maksymalnych klatkach B'.\n\nJeśli włączony, zwiększy jakość obrazu przy użyciu jakkolwiek wiele klatek B które są konieczne, do maksymum\nkosztem zwiększenia wykorzystania procesora graficznego."
|
||||
NVENC.PsychoVisualTuning="Psycho Visual Tuning"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Umożliwia ustawienia kodera, które optymalizują użycie bitratów dla zwiększonej jakość wizualnej,\n, zwłaszcza w sytuacjach z wysokim ruchem, kosztem zwiększonego wykorzystania procesora graficznego."
|
||||
NVENC.CQLevel="Poziom CQ"
|
||||
|
||||
FFmpegSource="Źródło danych"
|
||||
LocalFile="Plik lokalny"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Wejście"
|
|||
InputFormat="Format wejściowy"
|
||||
BufferingMB="Bufor sieciowy (MB)"
|
||||
HardwareDecode="Użyj sprzętowego dekodowania gdy to możliwe"
|
||||
ClearOnMediaEnd="Ukryj źródło po zakończeniu odtwarzania"
|
||||
ClearOnMediaEnd="Po zakończeniu odtwarzania nie pokazuj nic"
|
||||
Advanced="Zaawansowane"
|
||||
RestartWhenActivated="Zrestartuj odtwarzanie, gdy źródła będą aktywne"
|
||||
CloseFileWhenInactive="Zamknij plik, gdy niekatywne"
|
||||
|
|
@ -44,9 +49,10 @@ MediaFileFilter.VideoFiles="Pliki video"
|
|||
MediaFileFilter.AudioFiles="Pliki audio"
|
||||
MediaFileFilter.AllFiles="Wszystkie pliki"
|
||||
|
||||
ReplayBuffer="Bufor replay"
|
||||
ReplayBuffer.Save="Zapisz replay"
|
||||
ReplayBuffer="Nagrywanie powtórek"
|
||||
ReplayBuffer.Save="Zapisz nagraną powtórkę"
|
||||
|
||||
HelperProcessFailed="Nie można uruchomić procesu nagrywania. Sprawdź, czy pliki OBS nie są blokowane lub usunięte przez oprogramowanie zewnętrzne, np. antywirusowe lub chroniące system."
|
||||
UnableToWritePath="Nie można zapisać do %1. Sprawdź poprawność ścieżki zapisu, prawa dostępu do niej oraz wolne miejsce na dysku."
|
||||
WarnWindowsDefender="Błąd ten może być spowodowany również włączoną ochroną Windows 10 przed ransomware. Prosimy spróbować wyłączyć \"Kontrolowany dostęp do folderu\" w sekcji Ochrona przed wirusami i zagrożeniami."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="Saída do FFmpeg"
|
|||
FFmpegAAC="Codificador AAC Padrão do FFmpeg"
|
||||
FFmpegOpus="Codificador FFmpeg Optus"
|
||||
Bitrate="Taxa de Bits"
|
||||
MaxBitrate="Taxa de Bits Máxima"
|
||||
Preset="Predefinição"
|
||||
RateControl="Controle da Taxa de Bits"
|
||||
KeyframeIntervalSec="Intervalo de Keyframe (segundos, 0=auto)"
|
||||
Lossless="Sem perdas"
|
||||
|
||||
BFrames="B-frames"
|
||||
BFrames="B-Frames Máximo"
|
||||
|
||||
NVENC.Use2Pass="Utilizar a codificação em dois passos"
|
||||
NVENC.Preset.default="Padrão"
|
||||
NVENC.Preset.hq="Alta Qualidade"
|
||||
NVENC.Preset.hp="Alta Performance"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Desempenho"
|
||||
NVENC.Preset.hq="Qualidade"
|
||||
NVENC.Preset.hp="Alto Desempenho"
|
||||
NVENC.Preset.mq="Qualidade Máxima"
|
||||
NVENC.Preset.ll="Baixa Latência"
|
||||
NVENC.Preset.llhq="Baixa Latência e Alta Qualidade"
|
||||
NVENC.Preset.llhp="Baixa latência e Alta Performance"
|
||||
NVENC.Level="Nível"
|
||||
NVENC.Preset.llhq="Qualidade com Baixa Latência"
|
||||
NVENC.Preset.llhp="Desempenho com Baixa Latência"
|
||||
NVENC.LookAhead="Olhar quadros futuros"
|
||||
NVENC.LookAhead.ToolTip="Habilita B-Frames dinâmicos.\n\nSe desabilitado, o codificador sempre usará o número de B-Frames especificados na configuração de 'B-Frames Máximo'.\n\nSe habilitado, aumentará a qualidade visual usando apenas B-Frames necessários, até o máximo,\nao custo de uma maior utilização da GPU."
|
||||
NVENC.PsychoVisualTuning="Ajuste Psico-Visual"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Permite configurações do codificador que otimizam o uso da taxa de bits para uma melhoria\n perceptível na qualidade - especialmente em situações com muitos movimentos - com o custo de mais utilização da GPU."
|
||||
NVENC.CQLevel="Nível de CQ"
|
||||
|
||||
FFmpegSource="Fonte de mídia"
|
||||
LocalFile="Arquivo Local"
|
||||
|
|
@ -26,11 +31,11 @@ Input="Entrada"
|
|||
InputFormat="Formato de entrada"
|
||||
BufferingMB="Buffer de Rede (MB)"
|
||||
HardwareDecode="Utilizar descodificação de hardware quando disponível"
|
||||
ClearOnMediaEnd="Ocultar fonte quando a reprodução terminar"
|
||||
ClearOnMediaEnd="Não mostrar nada quando terminar a reprodução"
|
||||
Advanced="Avançado"
|
||||
RestartWhenActivated="Reiniciar reprodução quando a fonte se tornar ativa"
|
||||
CloseFileWhenInactive="Fechar arquivo quando inativo"
|
||||
CloseFileWhenInactive.ToolTip="Fechar o arquivo quando a fonte não estiver sendo exibida na transmissão\n ou gravação. Isto permite alterar o arquivo quando a fonte não está ativa,\nmas pode ter algum atraso de inicialização quando a fonte for reativada."
|
||||
CloseFileWhenInactive.ToolTip="Fechar o arquivo quando a fonte não estiver sendo exibida na transmissão\n ou gravação. Isto permite alterar o arquivo quando a fonte não está ativa,\nmas pode ter algum atraso de inicialização quando a fonte for reativada."
|
||||
ColorRange="Intervalo de Cores YUV"
|
||||
ColorRange.Auto="Auto"
|
||||
ColorRange.Partial="Parcial"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Salvar Replay"
|
|||
|
||||
HelperProcessFailed="Não foi possível iniciar o processo auxiliar de gravação. Verifique se os arquivos do OBS não foram bloqueados ou removidos por qualquer outro software (Ex: antivírus)."
|
||||
UnableToWritePath="Não foi possível escrever em %1. Certifique-se de que você está usando um caminho de gravação que sua conta de usuário possui permissão para gravar e que há espaço suficiente no disco."
|
||||
WarnWindowsDefender="Este erro pode acontecer também por causa da Proteção contra Ransomware do Windows 10. Experimente desligar o acesso controlado a pastas em: Configurações do Windows Defender > Proteção contra vírus e ameaças."
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
FFmpegOutput="Saída de FFmpeg"
|
||||
FFmpegAAC="Codificador AAC padrão do FFmpeg"
|
||||
FFmpegOpus="FFmpeg Opus Encoder"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="Bitrate Máximo"
|
||||
Preset="Predefinição"
|
||||
RateControl="Controle de Taxa"
|
||||
KeyframeIntervalSec="Intervalo do keyframe (segundos, 0=automático)"
|
||||
Lossless="Sem perdas"
|
||||
|
||||
BFrames="B-frames Máximas"
|
||||
|
||||
NVENC.Preset.default="Predefinido"
|
||||
NVENC.Preset.hq="Alta Qualidade"
|
||||
NVENC.Preset.hp="Alto Desempenho"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Use2Pass="Usar codificação a dois passos"
|
||||
NVENC.Preset.default="Desempenho"
|
||||
NVENC.Preset.hq="Qualidade"
|
||||
NVENC.Preset.hp="Máximo Desempenho"
|
||||
NVENC.Preset.mq="Qualidade Máxima"
|
||||
NVENC.Preset.ll="Baixa latência"
|
||||
NVENC.Preset.llhq="Baixa latência Alta Qualidade"
|
||||
NVENC.Preset.llhp="Baixa latência Alto Desempenho"
|
||||
NVENC.Level="Nível"
|
||||
|
||||
FFmpegSource="Fonte de multimédia"
|
||||
LocalFile="Ficheiro local"
|
||||
|
|
@ -22,13 +23,14 @@ Looping="Repetir"
|
|||
Input="Entrada"
|
||||
InputFormat="Formato de entrada"
|
||||
HardwareDecode="Utilizar descodificação de hardware quando disponível"
|
||||
ClearOnMediaEnd="Ocultar fonte quando a reprodução terminar"
|
||||
Advanced="Avançado"
|
||||
RestartWhenActivated="Reiniciar reprodução quando a fonte se torna ativo"
|
||||
CloseFileWhenInactive="Fechar ficheiro quando inativo"
|
||||
ColorRange="Gama de cor YUV"
|
||||
ColorRange.Auto="Auto"
|
||||
ColorRange.Partial="Parcial"
|
||||
ColorRange.Full="Completo"
|
||||
SpeedPercentage="Velocidade (percentagem)"
|
||||
|
||||
MediaFileFilter.AllMediaFiles="Todos os Arquivos de Media"
|
||||
MediaFileFilter.VideoFiles="Arquivos de Vídeo"
|
||||
|
|
|
|||
|
|
@ -2,19 +2,25 @@ FFmpegOutput="Ieșire FFmpeg"
|
|||
FFmpegAAC="Codificator AAC implicit FFmpeg"
|
||||
Bitrate="Rată de biți"
|
||||
Preset="Presetare"
|
||||
RateControl="Controlul ratei"
|
||||
KeyframeIntervalSec="Interval de cadre cheie (secunde, 0=auto)"
|
||||
|
||||
|
||||
NVENC.Preset.default="Implicită"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Level="Nivel"
|
||||
NVENC.Preset.default="Performanță"
|
||||
NVENC.Preset.hq="Calitate"
|
||||
NVENC.Preset.hp="Performanță maximă"
|
||||
NVENC.Preset.mq="Calitate maximă"
|
||||
NVENC.Preset.ll="Latență redusă"
|
||||
NVENC.Preset.llhq="Calitate cu latență redusă"
|
||||
NVENC.Preset.llhp="Performanță cu latență redusă"
|
||||
|
||||
FFmpegSource="Sursă media"
|
||||
LocalFile="Fișier local"
|
||||
Looping="Buclă"
|
||||
Input="Intrare"
|
||||
InputFormat="Format de intrare"
|
||||
BufferingMB="Zonă tampon pentru rețea (MB)"
|
||||
HardwareDecode="Folosește decodarea hardware când este disponibilă"
|
||||
ClearOnMediaEnd="Ascunde sursa atunci când se termină redarea"
|
||||
Advanced="Avansat"
|
||||
RestartWhenActivated="Repornește redarea când sursa devine activă"
|
||||
ColorRange="Gamă de culori YUV"
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="Вывод FFmpeg"
|
|||
FFmpegAAC="Стандартный AAC-кодер FFmpeg"
|
||||
FFmpegOpus="Кодировщик FFmpeg Opus"
|
||||
Bitrate="Битрейт"
|
||||
MaxBitrate="Макс. битрейт"
|
||||
Preset="Пресет"
|
||||
RateControl="Управление битрейтом"
|
||||
KeyframeIntervalSec="Интервал ключевых кадров (сек, 0=авто)"
|
||||
Lossless="Без потерь"
|
||||
|
||||
BFrames="B-Кадры"
|
||||
BFrames="Макс. кол-во B-кадров"
|
||||
|
||||
NVENC.Use2Pass="Использовать двухпроходное кодирование"
|
||||
NVENC.Preset.default="По умолчанию"
|
||||
NVENC.Preset.hq="Высокое качество"
|
||||
NVENC.Preset.hp="Высокая производительность"
|
||||
NVENC.Preset.bd="Blu-ray"
|
||||
NVENC.Preset.default="Производительность"
|
||||
NVENC.Preset.hq="Качество"
|
||||
NVENC.Preset.hp="Макс. производительность"
|
||||
NVENC.Preset.mq="Макс. качество"
|
||||
NVENC.Preset.ll="Малая задержка"
|
||||
NVENC.Preset.llhq="Малая задержка, высокое качество"
|
||||
NVENC.Preset.llhp="Малая задержка, высокая производительность"
|
||||
NVENC.Level="Уровень"
|
||||
NVENC.LookAhead="Предугадывание"
|
||||
NVENC.LookAhead.ToolTip="Включает динамические B-кадры.\n\nЕсли отключено, кодировщик всегда будет использовать количество B-кадров, указанное в параметре 'Макс. кол-во B-кадров'.\n\nЕсли включено, то это увеличит визуальное качество изображения путем использования любого количества B-кадров, вплоть до максимума,\nза счет увеличения использования GPU."
|
||||
NVENC.PsychoVisualTuning="Психовизуальная корректировка"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Включает настройки кодировщика, которые оптимизируют использование битрейта для повышенного восприятия визуального качества,\nособенно в ситуациях с высоким движением, за счет увеличения использования GPU."
|
||||
NVENC.CQLevel="Уровень QC"
|
||||
|
||||
FFmpegSource="Источник медиа"
|
||||
LocalFile="Локальный файл"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Ввод"
|
|||
InputFormat="Формат ввода"
|
||||
BufferingMB="Сетевая буферизация (МБ)"
|
||||
HardwareDecode="Использовать аппаратное декодирование при наличии"
|
||||
ClearOnMediaEnd="Скрывать источник, когда воспроизведение заканчивается"
|
||||
ClearOnMediaEnd="Ничего не показывать, когда воспроизведение заканчивается"
|
||||
Advanced="Дополнительно"
|
||||
RestartWhenActivated="Перезапустить воспроизведение, когда источник становится активным"
|
||||
CloseFileWhenInactive="Закрыть файл при отсутствии активности"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Сохранить повтор"
|
|||
|
||||
HelperProcessFailed="Невозможно запустить вспомогательный процесс для записи. Проверьте, не были ли заблокированы или удалены файлы OBS сторонним антивирусом / защитным ПО."
|
||||
UnableToWritePath="Невозможно записать в %1. Убедитесь, что для вашей учетной записи разрешена запись по этому пути, и что на диске достаточно свободного пространства."
|
||||
WarnWindowsDefender="Если включена Защита от программ-шантажистов Windows 10, это так же может вызывать эту ошибку. Попробуйте выключить контролируемый доступ к папкам в параметрах Безопасности Windows / Защита от вирусов и угроз."
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ FFmpegAAC="Predvolený FFmpeg AAC enkodér"
|
|||
FFmpegOpus="FFmpeg Opus enkodér"
|
||||
Bitrate="Bitrate"
|
||||
Preset="Predvoľba"
|
||||
RateControl="Riadenie toku"
|
||||
KeyframeIntervalSec="Interval kľúčových snímok (sekúnd, 0 = automaticky)"
|
||||
Lossless="Bezstratová"
|
||||
|
||||
|
||||
NVENC.Preset.default="Predvolená"
|
||||
NVENC.Preset.hq="Vysoká kvalita"
|
||||
NVENC.Preset.hp="Vysoký výkon"
|
||||
NVENC.Preset.bd="BluRay"
|
||||
NVENC.Level="Úroveň"
|
||||
NVENC.Use2Pass="Použiť dvojfázové enkódovanie"
|
||||
NVENC.Preset.ll="Nízka odozva"
|
||||
|
||||
FFmpegSource="Zdroj médií"
|
||||
LocalFile="Lokálny súbor"
|
||||
|
|
@ -19,15 +19,25 @@ InputFormat="Vstupný formát"
|
|||
BufferingMB="Sieťové zapisovanie do medzipamäte (MB)"
|
||||
HardwareDecode="Použiť hardvérové dekódovanie podľa dostupnosti"
|
||||
Advanced="Rozšírené"
|
||||
RestartWhenActivated="Obnoviť prehrávanie pri aktivovaní zdroja"
|
||||
CloseFileWhenInactive="Zatvoriť súbor pri neaktivite"
|
||||
CloseFileWhenInactive.ToolTip="Zatvorí súbor, ak zdroj nie je práve zobrazovaný vo vysielaní\nalebo nahrávaní. Toto umožní zmeny súboru pri neaktivite zdroja,\nale môže spôsobiť oneskorenie pri opätovnom použití zdroja."
|
||||
ColorRange="Rozsah farieb YUV"
|
||||
ColorRange.Auto="Automaticky"
|
||||
ColorRange.Partial="Čiastočný"
|
||||
ColorRange.Full="Plný"
|
||||
RestartMedia="Reštartuj mediálny zdroj"
|
||||
SpeedPercentage="Rýchlosť (v percentách)"
|
||||
Seekable="Posúvateľný"
|
||||
|
||||
MediaFileFilter.AllMediaFiles="Všetky mediálne súbory"
|
||||
MediaFileFilter.VideoFiles="Video súbory"
|
||||
MediaFileFilter.AudioFiles="Zvukové súbory"
|
||||
MediaFileFilter.AllFiles="Všetky súbory"
|
||||
|
||||
ReplayBuffer="Medzipamäť znovuprehratia"
|
||||
ReplayBuffer.Save="Uložiť záznam"
|
||||
|
||||
HelperProcessFailed="Nepodarilo sa spustiť pomocný proces nahrávania. Skontrolujte, či neboli súbory OBS zablokované alebo odstránené zabezpečovacím softvérom/antivírusom tretej strany."
|
||||
UnableToWritePath="Nedá sa zapisovať do %1. Uistite sa, že v ceste nahrávania má váš používateľský účet právo na zápis a že máte dostatok miesta na disku."
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ Looping="Ponavljaj"
|
|||
Input="Vhod"
|
||||
InputFormat="Format vnosa"
|
||||
HardwareDecode="Uporabi strojno pospeševanje, ko je na voljo"
|
||||
ClearOnMediaEnd="Skri vir, ko se predvajanje konča"
|
||||
Advanced="Napredno"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,40 +1,57 @@
|
|||
FFmpegOutput="FFmpeg izlaz"
|
||||
FFmpegAAC="FFmpeg podrazumevani AAC enkoder"
|
||||
FFmpegOpus="FFmpeg Opus enkoder"
|
||||
Bitrate="Protok"
|
||||
MaxBitrate="Maksimalni protok"
|
||||
Preset="Šablon"
|
||||
RateControl="Kontrola protoka"
|
||||
KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)"
|
||||
Lossless="Bez gubitka"
|
||||
|
||||
BFrames="Maksimalni B-frejmovi"
|
||||
|
||||
NVENC.Use2Pass="Koristi enkoding duplog prolaza"
|
||||
NVENC.Preset.default="Podrazumevani"
|
||||
NVENC.Preset.hq="Visoki kvalitet"
|
||||
NVENC.Preset.hp="Visoke performanse"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.ll="Nisko kašnjenje"
|
||||
NVENC.Preset.llhq="Visoki kvalitet niskog kašnjenja"
|
||||
NVENC.Preset.llhp="Visoke performanse niskog kašnjenja"
|
||||
NVENC.Level="Nivo"
|
||||
NVENC.Preset.default="Performanse"
|
||||
NVENC.Preset.hq="Kvalitet"
|
||||
NVENC.Preset.hp="Maksimalne performanse"
|
||||
NVENC.Preset.mq="Maksimalni kvalitet"
|
||||
NVENC.Preset.ll="Malo kašnjenje"
|
||||
NVENC.Preset.llhq="Kvalitet malog kašnjenja"
|
||||
NVENC.Preset.llhp="Performanse malog kašnjenja"
|
||||
NVENC.LookAhead="Gledanje unapred"
|
||||
NVENC.LookAhead.ToolTip="Uključuje dinamičke B-frejmove.\n\n Ako je isključeno, enkoder će uvek koristiti broj B-frejmova naveden u 'Maksimalni B-frejmovi' delu.\n\nUkoliko je uključeno, povećaće vizuelni kvalitet korišćenjem onoliko B-frejmova koliko je potrebno, do maksimalnog broja,\npo cenu povećane upotrebe GPU-a."
|
||||
NVENC.PsychoVisualTuning="Psiho vizuelna podešavanja"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Uključuje podešavanja enkodera koja optimizuju korišćenje protoka za povećani vizuelni kvalitet,\nposebno u situacijama sa ubrzanim pokretima, po cenu povećane upotrebe GPU-a."
|
||||
NVENC.CQLevel="CQ Nivo"
|
||||
|
||||
FFmpegSource="Medija izvor"
|
||||
LocalFile="Lokalna datoteka"
|
||||
Looping="Ponavljanje"
|
||||
Input="Ulaz"
|
||||
InputFormat="Format ulaza"
|
||||
BufferingMB="Baferovanje mreže (MB)"
|
||||
HardwareDecode="Koristi hardversko enkodiranje kada je dostupno"
|
||||
ClearOnMediaEnd="Sakrij izvor kada se reprodukcija završi"
|
||||
Advanced="Napredno"
|
||||
RestartWhenActivated="Ponovi reprodukciju kada izvor postane aktivan"
|
||||
CloseFileWhenInactive="Zatvori fajl kada je neaktivan"
|
||||
CloseFileWhenInactive.ToolTip="Zatvorite fajl kada izvor nije prikazan tokom strimovanja ili\nna snimku. Ovo omogućava fajlu da bude izmenjen kada izvor nije aktivan,\nali je moguće da se javi određeno kašnjenje kada se izvor ponovo aktivira."
|
||||
ColorRange="YUV opseg boja"
|
||||
ColorRange.Auto="Automatski"
|
||||
ColorRange.Partial="Delimični"
|
||||
ColorRange.Full="Potpuni"
|
||||
RestartMedia="Restartuj medij"
|
||||
SpeedPercentage="Brzina (procenat)"
|
||||
Seekable="Pretraživanje"
|
||||
|
||||
MediaFileFilter.AllMediaFiles="Sve medija datoteke"
|
||||
MediaFileFilter.VideoFiles="Video datoteke"
|
||||
MediaFileFilter.AudioFiles="Zvučne datoteke"
|
||||
MediaFileFilter.AllFiles="Sve datoteke"
|
||||
|
||||
ReplayBuffer="Bafer za ponovno reprodukovanje"
|
||||
ReplayBuffer.Save="Sačuvaj ponovno reprodukovanje"
|
||||
|
||||
HelperProcessFailed="Nemoguće je pokrenuti pomoć za snimanje. Proverite da li su OBS fajlovi blokirani ili premešteni od strane nekog antivirus softvera/softvera za zaštitu."
|
||||
UnableToWritePath="Nemoguće je pisati na %1. Proverite da li koristite putanju kojoj vaš nalog ima pravo da pristupi i da li imate dovoljno prostora na disku."
|
||||
WarnWindowsDefender="Ova greška takođe može da nastane ako je Windows 10 Ransomware Protection uključen. Pokušajte da isključite kontrolisani pristup folderu u podešavanjima za Windows Sigurnost/Zaštitu od virusa."
|
||||
|
||||
|
|
|
|||
|
|
@ -1,40 +1,57 @@
|
|||
FFmpegOutput="FFmpeg излаз"
|
||||
FFmpegAAC="FFmpeg подразумевани AAC енкодер"
|
||||
FFmpegOpus="FFmpeg Opus енкодер"
|
||||
Bitrate="Проток"
|
||||
MaxBitrate="Максимални проток"
|
||||
Preset="Шаблон"
|
||||
RateControl="Контрола протока"
|
||||
KeyframeIntervalSec="Интервал кључних фрејмова (секунде, 0=аутоматски)"
|
||||
Lossless="Без губитка"
|
||||
|
||||
BFrames="Максимални Б-фрејм"
|
||||
|
||||
NVENC.Use2Pass="Користи енкодинг дуплог пролаза"
|
||||
NVENC.Preset.default="Подразумевани"
|
||||
NVENC.Preset.hq="Високи квалитет"
|
||||
NVENC.Preset.hp="Високе перформансе"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.ll="Ниско кашњење"
|
||||
NVENC.Preset.llhq="Високи квалитет ниског кашњења"
|
||||
NVENC.Preset.llhp="Високе перформансе ниског кашњења"
|
||||
NVENC.Level="Ниво"
|
||||
NVENC.Preset.default="Перформансе"
|
||||
NVENC.Preset.hq="Квалитет"
|
||||
NVENC.Preset.hp="Максималне перформансе"
|
||||
NVENC.Preset.mq="Максимални квалитет"
|
||||
NVENC.Preset.ll="Мало кашњење"
|
||||
NVENC.Preset.llhq="Квалитет малог кашњења"
|
||||
NVENC.Preset.llhp="Перформансе малог кашњења"
|
||||
NVENC.LookAhead="Гледање унапред"
|
||||
NVENC.LookAhead.ToolTip="Укључује динамичке Б-фрејмове..\n\n Ако је искључено, енкодер ће увек користити број Б-фрејмова наведен у 'Максимални Б-фрејмови' делу.\n\nУколико је укључено, повећаће визуелни квалитет коришћењем онолико Б-фрејмова колико је потребно, до максималног броја,\nпо цену повећане употребе GPU-a."
|
||||
NVENC.PsychoVisualTuning="Психо визуелна подешавања"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Укључује подешавања енкодера која оптимизују коришћење протока за повећани визуелни квалитет,\nпосебно у ситуацијама са убрзаним покретима, по цену повећане употребе GPU-а."
|
||||
NVENC.CQLevel="CQ Ниво"
|
||||
|
||||
FFmpegSource="Медија извор"
|
||||
LocalFile="Локална датотека"
|
||||
Looping="Понављање"
|
||||
Input="Улаз"
|
||||
InputFormat="Формат улаза"
|
||||
BufferingMB="Баферовање мреже (мегабајти)"
|
||||
HardwareDecode="Користи хардверско енкодирање када је доступно"
|
||||
ClearOnMediaEnd="Сакриј извор када се репродукција заврши"
|
||||
Advanced="Напредно"
|
||||
RestartWhenActivated="Понови репродукцију када извор постане активан"
|
||||
CloseFileWhenInactive="Затвори фајл када је неактиван"
|
||||
CloseFileWhenInactive.ToolTip="Затворите фајл када извор није приказан током стримовања или\nна снимку. Ово омогућава фајлу да буде измењен када извор није активан, \nали је могуће да се јави одређено кашњење када се извор поново активира."
|
||||
ColorRange="YUV опсег боја"
|
||||
ColorRange.Auto="Аутоматски"
|
||||
ColorRange.Partial="Делимични"
|
||||
ColorRange.Full="Потпуни"
|
||||
RestartMedia="Рестартуј медиј"
|
||||
SpeedPercentage="Брзина (проценат)"
|
||||
Seekable="Претраживање"
|
||||
|
||||
MediaFileFilter.AllMediaFiles="Све медија датотеке"
|
||||
MediaFileFilter.VideoFiles="Видео датотеке"
|
||||
MediaFileFilter.AudioFiles="Звучне датотеке"
|
||||
MediaFileFilter.AllFiles="Све датотеке"
|
||||
|
||||
ReplayBuffer="Бафер за поновно репродуковање"
|
||||
ReplayBuffer.Save="Сачувај поновно репродуковање"
|
||||
|
||||
HelperProcessFailed="Немогуће је покренути помоћ за снимање. Проверите да ли су OBS фајлови блокирани или премештени од стране неког антивирус софтвера/софтвера за заштиту."
|
||||
UnableToWritePath="Немогуће је писати на %1. Проверите да ли користите путању којој ваш налог има право да приступи и да ли имате довољно простора на диску."
|
||||
WarnWindowsDefender="Ова грешка такође може да настане ако је Windows 10 Ransomware Protection укључен. Покушајте да искључите контролисани приступ фолдеру у подешавањима за Windows Сигурност/Заштиту од вируса."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg-utmatning"
|
|||
FFmpegAAC="AAC-kodare (FFmpeg standard)"
|
||||
FFmpegOpus="FFmpeg Opus-kodare"
|
||||
Bitrate="Bithastighet"
|
||||
MaxBitrate="Max bithastighet"
|
||||
Preset="Förinställning"
|
||||
RateControl="Hastighetskontroll"
|
||||
KeyframeIntervalSec="Intervall för keyframes (sekunder, 0=automatisk)"
|
||||
Lossless="Förlustfri"
|
||||
|
||||
BFrames="B-bildrutor"
|
||||
BFrames="Maximalt antal B-frames"
|
||||
|
||||
NVENC.Use2Pass="Använd tvåpassavkodning"
|
||||
NVENC.Preset.default="Standard"
|
||||
NVENC.Preset.hq="Hög kvalitet"
|
||||
NVENC.Preset.hp="Hög prestanda"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Prestanda"
|
||||
NVENC.Preset.hq="Kvalitet"
|
||||
NVENC.Preset.hp="Maximal prestanda"
|
||||
NVENC.Preset.mq="Maximal kvalitet"
|
||||
NVENC.Preset.ll="Låg latens"
|
||||
NVENC.Preset.llhq="Låg latens, hög kvalitet"
|
||||
NVENC.Preset.llhp="Låg latens, hög prestanda"
|
||||
NVENC.Level="Nivå"
|
||||
NVENC.Preset.llhq="Kvalitet med låg latens"
|
||||
NVENC.Preset.llhp="Prestanda med låg latens"
|
||||
NVENC.LookAhead="Look-ahead"
|
||||
NVENC.LookAhead.ToolTip="Aktiverar dynamiska B-frames.\n\nOm detta inaktiveras kommer kodaren alltid använda antalet B-frames som anges i inställningen \"Max B-frames\".\n\nOm detta aktiveras kommer det öka den visuella kvaliteten genom att endast använda så många B-frames som är nödvändigt, upp till det som är möjligt\npå bekostnad av ökad användning av grafikprocessorn."
|
||||
NVENC.PsychoVisualTuning="Psykovisuell justering"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Aktiverar kodarinställningar som optimerar hur bithastigheten används för förbättrad visuell kvalitet,\nspeciellt i situationer med snabba rörelser på bekostnad av ökad användning av grafikprocessorn."
|
||||
NVENC.CQLevel="CQ-nivå"
|
||||
|
||||
FFmpegSource="Mediakälla"
|
||||
LocalFile="Lokal fil"
|
||||
|
|
@ -26,7 +31,7 @@ Input="Infoga"
|
|||
InputFormat="Inmatningsformat"
|
||||
BufferingMB="Nätverksbuffring (MB)"
|
||||
HardwareDecode="Använda hårdvareavkodning när tillgängligt"
|
||||
ClearOnMediaEnd="Dölja källa när uppspelningen slutar"
|
||||
ClearOnMediaEnd="Visa ingenting när uppspelningen slutar"
|
||||
Advanced="Avancerat"
|
||||
RestartWhenActivated="Starta om uppspelning när källa blir aktiv"
|
||||
CloseFileWhenInactive="Stäng filen vid inaktivitet"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Spara repris"
|
|||
|
||||
HelperProcessFailed="Kan inte spela in hjälpprocessen. Kontrollera att OBS-filer inte har blockerats eller tagits bort av antivirus-/säkerhetsprogram från tredjepart."
|
||||
UnableToWritePath="Kan inte skriva till %1. Se till att du använder en inspelningssökväg som ditt användarkonto har tillåtelse att skriva till och att det finns tillräckligt mycket diskutrymme."
|
||||
WarnWindowsDefender="Om skyddet mot ransomware i Windows 10 är aktiverat kan det också orsaka detta fel. Försök att inaktivera kontrollerad mappåtkomst i Windows-säkerhet / Inställningar för skydd mot virus & hot."
|
||||
|
||||
|
|
|
|||
|
|
@ -7,17 +7,9 @@ RateControl="Kontrolin ang Rate"
|
|||
KeyframeIntervalSec="Ang Pagitan ng Keyframe (segundo, 0=awto)"
|
||||
Lossless="Walang Pagkawala"
|
||||
|
||||
BFrames="Ang mga B-frame"
|
||||
|
||||
NVENC.Use2Pass="Gamitin ang Dalawang Pass ng Encoding"
|
||||
NVENC.Preset.default="I-default"
|
||||
NVENC.Preset.hq="Mataas na Kalidad"
|
||||
NVENC.Preset.hp="Mataas na Pagganap"
|
||||
NVENC.Preset.bd="Ang Bluray"
|
||||
NVENC.Preset.ll="Mababang Pagkawalang kilos"
|
||||
NVENC.Preset.llhq="Mababang-Pagkawalang kilos na Mataas ang Kalidad"
|
||||
NVENC.Preset.llhp="Mababang-Pagkawalang kilos na Mataan ang Pagganap"
|
||||
NVENC.Level="Antas"
|
||||
|
||||
FFmpegSource="Pinagmulan ng Media"
|
||||
LocalFile="Ang Lokal na File"
|
||||
|
|
@ -26,7 +18,6 @@ Input="Pampasok"
|
|||
InputFormat="Pampasok na Format"
|
||||
BufferingMB="Ang Network Buffering (MB)"
|
||||
HardwareDecode="Gamitin ang hardware sa pag-decode kapag itong magagamit na"
|
||||
ClearOnMediaEnd="Itago ang pinagmulan kapag ang playback ay natapos"
|
||||
Advanced="Nauuna"
|
||||
RestartWhenActivated="I-restart ang playback kapag ang pinagmulan ay naging aktibo na"
|
||||
CloseFileWhenInactive="Isarado ang file kapag hindi ito aktibo"
|
||||
|
|
|
|||
|
|
@ -2,22 +2,23 @@ FFmpegOutput="FFmpeg Çıkışı"
|
|||
FFmpegAAC="FFmpeg Varsayılan AAC Kodlayıcı"
|
||||
FFmpegOpus="FFmpeg Opus Kodlayıcı"
|
||||
Bitrate="Bit hızı"
|
||||
MaxBitrate="Maksimum Bit Hızı"
|
||||
Preset="Ön Tanımlı"
|
||||
RateControl="Oran Kontrolü"
|
||||
KeyframeIntervalSec="Anahtar Kare Aralığı (saniye, 0=otomatik)"
|
||||
Lossless="Kayıpsız"
|
||||
|
||||
BFrames="B-Kareleri"
|
||||
BFrames="Maksimum B-kareleri"
|
||||
|
||||
NVENC.Use2Pass="İki Taramalı Kodlama Kullan"
|
||||
NVENC.Preset.default="Varsayılan"
|
||||
NVENC.Preset.hq="Yüksek Kalite"
|
||||
NVENC.Preset.hp="Yüksek Performans"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Performans"
|
||||
NVENC.Preset.hq="Kalite"
|
||||
NVENC.Preset.hp="Maksimum Performans"
|
||||
NVENC.Preset.mq="Maksimum Kalite"
|
||||
NVENC.Preset.ll="Düşük Gecikme"
|
||||
NVENC.Preset.llhq="Düşük Gecikme Yüksek Kalite"
|
||||
NVENC.Preset.llhp="Düşük Gecikme Yüksek Performans"
|
||||
NVENC.Level="Seviye"
|
||||
NVENC.Preset.llhq="Düşük Gecikme, Düşük Kalite"
|
||||
NVENC.Preset.llhp="Düşük Gecikme, Düşük Performans"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Bit hızı kullanımını, arttırılmış algılanan görsel kalite için optimize eden ayarları etkinleştirir,\nÖzellikle yüksek haraketli durumlarda, arttırılmış GPU kullanımı pahasına."
|
||||
|
||||
FFmpegSource="Ortam Kaynağı"
|
||||
LocalFile="Yerel Dosya"
|
||||
|
|
@ -26,7 +27,6 @@ Input="Giriş"
|
|||
InputFormat="Giriş Biçimi"
|
||||
BufferingMB="Ağ Arabelleğe Alma (MB)"
|
||||
HardwareDecode="Kullanılabilir ise, donanım kod çözmeyi kullan"
|
||||
ClearOnMediaEnd="Kayıttan yürütme bittiğinde kaynağı gizle"
|
||||
Advanced="Gelişmiş"
|
||||
RestartWhenActivated="Yeniden oynatmayı kaynak etkin olduğunda yeniden başlat"
|
||||
CloseFileWhenInactive="Etkin değilken dosyayı kapat"
|
||||
|
|
@ -49,4 +49,5 @@ ReplayBuffer.Save="Yeniden Oynatmayı Kaydet"
|
|||
|
||||
HelperProcessFailed="Kayıt yardımcısı işlemi başlatılamadı. OBS dosyalarının herhangi bir 3. taraf antivirüs / güvenlik yazılımı tarafından engellenmediğini veya kaldırılmadığını kontrol edin."
|
||||
UnableToWritePath="%1 yazılamadı. Kullanıcı hesabınızın yazmasına izin verilen bir kayıt konumu kullanıyor olduğunuzdan ve yeterli disk alanı olduğundan emin olun."
|
||||
WarnWindowsDefender="Eğer Windows 10 Fidye Virüsü koruması etkinse bu hataya neden olabilir. Windows Güvenlik / Virüs & tehdit koruması ayarlarından kontrollü klasör erişimini kapatmayı dene."
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="Вивід FFmpeg"
|
|||
FFmpegAAC="FFmpeg AAC енкодер за замовчанням"
|
||||
FFmpegOpus="FFmpeg Opus енкодер"
|
||||
Bitrate="Бітрейт"
|
||||
MaxBitrate="Максимальний бітрейт"
|
||||
Preset="Шаблон"
|
||||
RateControl="Керування потоком"
|
||||
KeyframeIntervalSec="Інтервал ключових кадрів (секунд, 0 = авто)"
|
||||
Lossless="Без втрат"
|
||||
|
||||
BFrames="B-кадри"
|
||||
BFrames="B-кадрів, максимально"
|
||||
|
||||
NVENC.Use2Pass="Використовувати двопрохідне кодування"
|
||||
NVENC.Preset.default="Стандартний"
|
||||
NVENC.Preset.hq="Висока якість"
|
||||
NVENC.Preset.hp="Висока продуктивність"
|
||||
NVENC.Preset.bd="Blu-ray"
|
||||
NVENC.Preset.default="Продуктивність"
|
||||
NVENC.Preset.hq="Якість"
|
||||
NVENC.Preset.hp="Максимальна продуктивність"
|
||||
NVENC.Preset.mq="Максимальна якість"
|
||||
NVENC.Preset.ll="З низькою затримкою"
|
||||
NVENC.Preset.llhq="З низькою затримкою, висока Якість"
|
||||
NVENC.Preset.llhp="З низькою затримкою, висока Продуктивність"
|
||||
NVENC.Level="Рівень"
|
||||
NVENC.Preset.llhq="З низькою затримкою, Якість"
|
||||
NVENC.Preset.llhp="З низькою затримкою, Продуктивність"
|
||||
NVENC.LookAhead="Передбачення"
|
||||
NVENC.LookAhead.ToolTip="Дозволяє використовувати динамічні B-кадри.\n\nЯкщо вимкнено, енкодер завжди буде використовувати кількість B-кадрів,\nвказаних у налаштуванні: B-кадрів, максимально.\n\nЯкщо увімкнено, це поліпшить якість завдяки використанню необхідної\nта достатньої кількості B-кадрів (не більше вказаного максимуму), однак це відбудеться\nза рахунок збільшення навантаження на графічний процессор."
|
||||
NVENC.PsychoVisualTuning="Психо-візуальні спрощення"
|
||||
NVENC.PsychoVisualTuning.ToolTip="Дозволяє енкодеру використовувати методи оптимізації з розподілення бітрейту\nдля підвищення візуального сприйняття якості, особливо в сценах з швидким рухом.\nВідбувається за рахунок збільшення навантаження на графічний процесор."
|
||||
NVENC.CQLevel="CQ (постійне квантування), рівень"
|
||||
|
||||
FFmpegSource="Мультимедіа"
|
||||
LocalFile="Локальний файл"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="Зберегти Повтор"
|
|||
|
||||
HelperProcessFailed="Не вдалося розпочати допоміжний процес для запису. Перевірте, що OBS файли не було заблоковано чи видалено антивірусом або будь-яким іншим програмним забезпеченням з безпеки."
|
||||
UnableToWritePath="Не вдалося записати до %1. Переконайтеся, що ви використовуєте для запису шлях, до якого ваш обліковий запис має дозвіл на запис, і що там є достатньо вільного місця."
|
||||
WarnWindowsDefender="Якщо Windows 10 Ransomware Protection (захист від програм-вимагачів) увімкнуто у системі - це також може бути причиною появи цієї помилки. Спробуйте вимкнути контроль за доступом до папок у Безпека Windows Захист від вірусів та загроз."
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
FFmpegOutput="FFmpeg đầu ra"
|
||||
FFmpegAAC="FFmpeg AAC Encoder mặc định"
|
||||
Bitrate="Bitrate"
|
||||
MaxBitrate="'Tốc độ bit' tối đa"
|
||||
Preset="Mẫu thiết lập"
|
||||
RateControl="Cách kiểm soát bitrate"
|
||||
KeyframeIntervalSec="Thời gian đặt Keyframe (giây, 0=tự động)"
|
||||
Lossless="Lossless"
|
||||
|
||||
BFrames="B-Frames"
|
||||
|
||||
NVENC.Use2Pass="Sử dụng 2-Pass Encoding"
|
||||
NVENC.Preset.default="Mặc định"
|
||||
NVENC.Preset.hq="Chất lượng cao"
|
||||
NVENC.Preset.hp="Hiệu suất cao"
|
||||
NVENC.Preset.bd="Bluray"
|
||||
NVENC.Preset.default="Hiệu suất"
|
||||
NVENC.Preset.hq="Chất lượng"
|
||||
NVENC.Preset.hp="Hiệu suất tối đa"
|
||||
NVENC.Preset.mq="Chất lượng tối đa"
|
||||
NVENC.Preset.ll="Độ trễ thấp"
|
||||
NVENC.Preset.llhq="Độ trễ thấp chất lượng cao"
|
||||
NVENC.Preset.llhp="Độ trễ thấp hiệu suất cao"
|
||||
NVENC.Level="Cấp độ"
|
||||
NVENC.Preset.llhq="Chất lượng \"độ trễ thấp\""
|
||||
NVENC.Preset.llhp="Hiệu suất \"độ trễ thấp\""
|
||||
|
||||
FFmpegSource="Nguồn media"
|
||||
LocalFile="Tập tin cục bộ"
|
||||
|
|
@ -38,5 +37,6 @@ MediaFileFilter.AudioFiles="Tập tin âm thanh"
|
|||
MediaFileFilter.AllFiles="Tất cả tập tin"
|
||||
|
||||
ReplayBuffer="Replay Buffer"
|
||||
ReplayBuffer.Save="Lưu bản phát lại"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg 输出"
|
|||
FFmpegAAC="FFmpeg 默认 AAC 编码器"
|
||||
FFmpegOpus="FFmpeg Opus 编码器"
|
||||
Bitrate="比特率"
|
||||
MaxBitrate="最大比特率"
|
||||
Preset="预设"
|
||||
RateControl="速率控制"
|
||||
KeyframeIntervalSec="关键帧间隔(秒, 0=自动)"
|
||||
Lossless="无损"
|
||||
|
||||
BFrames="B 帧"
|
||||
BFrames="最大B帧"
|
||||
|
||||
NVENC.Use2Pass="使用 Two-Pass 编码"
|
||||
NVENC.Preset.default="默认"
|
||||
NVENC.Preset.hq="高质量"
|
||||
NVENC.Preset.hp="高性能"
|
||||
NVENC.Preset.bd="蓝光"
|
||||
NVENC.Preset.default="性能"
|
||||
NVENC.Preset.hq="质量"
|
||||
NVENC.Preset.hp="最大性能"
|
||||
NVENC.Preset.mq="最高质量"
|
||||
NVENC.Preset.ll="低延迟"
|
||||
NVENC.Preset.llhq="低延迟高质量"
|
||||
NVENC.Preset.llhp="低延迟高性能"
|
||||
NVENC.Level="等级"
|
||||
NVENC.Preset.llhq="低延迟质量"
|
||||
NVENC.Preset.llhp="低延迟性能"
|
||||
NVENC.LookAhead="前向考虑"
|
||||
NVENC.LookAhead.ToolTip="启用动态B帧。\n\n如果禁用,编码器将始终使用“最大B帧”设置中指定的B帧数。\n\n如果启用,它将通过仅使用足够多的B帧来提高视觉质量,直到最大,\n但以增加 GPU 使用率为代价。"
|
||||
NVENC.PsychoVisualTuning="心理视觉调整"
|
||||
NVENC.PsychoVisualTuning.ToolTip="启用编码器设置以优化比特率使用,以提高 GPU 使用率为代价,\n可在快速运动场景下提高人眼感知的视频质量。"
|
||||
NVENC.CQLevel="CQ 级别"
|
||||
|
||||
FFmpegSource="媒体源"
|
||||
LocalFile="本地文件"
|
||||
|
|
@ -26,11 +31,11 @@ Input="输入"
|
|||
InputFormat="输入格式"
|
||||
BufferingMB="网络缓冲 (MB)"
|
||||
HardwareDecode="在可用时使用硬件解码"
|
||||
ClearOnMediaEnd="当播放结束时隐藏源"
|
||||
ClearOnMediaEnd="播放结束时不显示任何内容"
|
||||
Advanced="高级"
|
||||
RestartWhenActivated="当源变为活动状态时重新启动播放"
|
||||
CloseFileWhenInactive="非活跃状态时关闭文件"
|
||||
CloseFileWhenInactive.ToolTip="当源没有显示在推流或者\n录像时关闭文件。这使得在源不活跃状态时可以更改文件,\n但是当当源重新激活时, 可能有一些启动延迟。"
|
||||
CloseFileWhenInactive.ToolTip="当源没有被用以串流或录像时关闭文件。\n这允许在源未被使用时更改文件,\n但在重新启动源时可能会有些许的启动延迟。"
|
||||
ColorRange="YUV 颜色范围"
|
||||
ColorRange.Auto="自动"
|
||||
ColorRange.Partial="局部"
|
||||
|
|
@ -47,6 +52,7 @@ MediaFileFilter.AllFiles="所有文件"
|
|||
ReplayBuffer="回放缓存"
|
||||
ReplayBuffer.Save="保存回放"
|
||||
|
||||
HelperProcessFailed="无法启动录音助手进程。检查 OBS 文件未被任何第三方防病毒 / 安全软件阻止或删除。"
|
||||
UnableToWritePath="无法写入到 %1。请确保您使用的录制路径您的用户帐户允许写入,并有足够的磁盘空间。"
|
||||
HelperProcessFailed="无法启动录制助手进程。检查 OBS 文件未被任何第三方防病毒 / 安全软件阻止或删除。"
|
||||
UnableToWritePath="无法写入到 %1。请确保您使用的录像路径允许您的用户帐户写入,并且磁盘空间充足。"
|
||||
WarnWindowsDefender="Windows 10 的勒索软件防护机制也可能导致该错误的发生。请尝试关闭 Windows 安全中心 - 勒索软件防护中的文件夹限制访问。"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg 輸出"
|
|||
FFmpegAAC="FFmpeg 預設 AAC 編碼器"
|
||||
FFmpegOpus="FFmpeg Opus 編碼器"
|
||||
Bitrate="位元率"
|
||||
MaxBitrate="最大位元率"
|
||||
Preset="預置"
|
||||
RateControl="位元率控制"
|
||||
KeyframeIntervalSec="關鍵訊框間隔 (秒,0 = 自動)"
|
||||
Lossless="無損"
|
||||
|
||||
BFrames="B 訊框"
|
||||
BFrames="最大 B 畫格數"
|
||||
|
||||
NVENC.Use2Pass="使用 Two-Pass 編碼"
|
||||
NVENC.Preset.default="預設"
|
||||
NVENC.Preset.hq="高品質"
|
||||
NVENC.Preset.hp="高性能"
|
||||
NVENC.Preset.bd="藍光"
|
||||
NVENC.Preset.default="效能"
|
||||
NVENC.Preset.hq="畫質"
|
||||
NVENC.Preset.hp="效能最高"
|
||||
NVENC.Preset.mq="品質最高"
|
||||
NVENC.Preset.ll="低延遲"
|
||||
NVENC.Preset.llhq="低延遲高品質"
|
||||
NVENC.Preset.llhp="低延遲高性能"
|
||||
NVENC.Level="级别"
|
||||
NVENC.Preset.llhq="低延遲品質"
|
||||
NVENC.Preset.llhp="低延遲效能"
|
||||
NVENC.LookAhead="編碼緩衝預測"
|
||||
NVENC.LookAhead.ToolTip="啟用動態B幀。 \n\n如果禁用,編碼器將始終使用“最大B幀”設置中指定的B幀數。 \n\n如果啟用,它將僅通過使用盡可能多的B幀來提高視覺品質,直到最大,\n但以增加 GPU 使用率為代價。"
|
||||
NVENC.PsychoVisualTuning="心理視覺調整"
|
||||
NVENC.PsychoVisualTuning.ToolTip="啟用優化比特率使用的編碼器設置,以提高感知的視覺品質,\n特別是在高運動的情況下,以提高 GPU 使用率為代價。"
|
||||
NVENC.CQLevel="固定量化等級"
|
||||
|
||||
FFmpegSource="媒體來源"
|
||||
LocalFile="本機檔案"
|
||||
|
|
@ -26,7 +31,7 @@ Input="輸入"
|
|||
InputFormat="輸入格式"
|
||||
BufferingMB="網路緩衝 (MB)"
|
||||
HardwareDecode="盡可能使用硬體解碼"
|
||||
ClearOnMediaEnd="當播放結束時隱藏來源"
|
||||
ClearOnMediaEnd="播放結束時不顯示任何內容"
|
||||
Advanced="進階"
|
||||
RestartWhenActivated="當來源可使用時重新播放"
|
||||
CloseFileWhenInactive="非使用狀態時關閉檔案"
|
||||
|
|
@ -49,4 +54,5 @@ ReplayBuffer.Save="儲存重播"
|
|||
|
||||
HelperProcessFailed="無法啟動錄影協助程式。請確定 OBS 檔案沒有被防毒/安全軟體所阻擋或移除。"
|
||||
UnableToWritePath="無法寫入到 %1。請確定使用者帳戶可以寫入錄影檔路徑以及有足夠的磁碟空間。"
|
||||
WarnWindowsDefender="如果啟用了 windows 10 勒索軟體保護, 也可能導致此錯誤。請嘗試將 obs 從 windows 安全/病毒和威脅防護設置中的受控資料夾訪問清單中移除。"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,20 @@
|
|||
project(ffmpeg-mux)
|
||||
project(obs-ffmpeg-mux)
|
||||
|
||||
find_package(FFmpeg REQUIRED
|
||||
COMPONENTS avcodec avutil avformat)
|
||||
include_directories(${FFMPEG_INCLUDE_DIRS})
|
||||
|
||||
set(ffmpeg-mux_SOURCES
|
||||
set(obs-ffmpeg-mux_SOURCES
|
||||
ffmpeg-mux.c)
|
||||
|
||||
set(ffmpeg-mux_HEADERS
|
||||
set(obs-ffmpeg-mux_HEADERS
|
||||
ffmpeg-mux.h)
|
||||
|
||||
add_executable(ffmpeg-mux
|
||||
${ffmpeg-mux_SOURCES}
|
||||
${ffmpeg-mux_HEADERS})
|
||||
add_executable(obs-ffmpeg-mux
|
||||
${obs-ffmpeg-mux_SOURCES}
|
||||
${obs-ffmpeg-mux_HEADERS})
|
||||
|
||||
target_link_libraries(ffmpeg-mux
|
||||
target_link_libraries(obs-ffmpeg-mux
|
||||
${FFMPEG_LIBRARIES})
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(ffmpeg-mux
|
||||
PROPERTIES
|
||||
OUTPUT_NAME "ffmpeg-mux${_output_suffix}")
|
||||
endif()
|
||||
|
||||
install_obs_datatarget(ffmpeg-mux "obs-plugins/obs-ffmpeg")
|
||||
install_obs_core(obs-ffmpeg-mux)
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ static bool new_stream(struct ffmpeg_mux *ffm, AVStream **stream,
|
|||
AVCodec *codec;
|
||||
|
||||
if (!desc) {
|
||||
printf("Couldn't find encoder '%s'\n", name);
|
||||
fprintf(stderr, "Couldn't find encoder '%s'\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -276,13 +276,13 @@ static bool new_stream(struct ffmpeg_mux *ffm, AVStream **stream,
|
|||
|
||||
codec = avcodec_find_encoder(desc->id);
|
||||
if (!codec) {
|
||||
printf("Couldn't create encoder");
|
||||
fprintf(stderr, "Couldn't create encoder");
|
||||
return false;
|
||||
}
|
||||
|
||||
*stream = avformat_new_stream(ffm->output, codec);
|
||||
if (!*stream) {
|
||||
printf("Couldn't create stream for encoder '%s'\n", name);
|
||||
fprintf(stderr, "Couldn't create stream for encoder '%s'\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -469,7 +469,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
|
|||
ret = avio_open(&ffm->output->pb, ffm->params.file,
|
||||
AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
printf("Couldn't open '%s', %s",
|
||||
fprintf(stderr, "Couldn't open '%s', %s",
|
||||
ffm->params.file, av_err2str(ret));
|
||||
return FFM_ERROR;
|
||||
}
|
||||
|
|
@ -482,7 +482,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
|
|||
AVDictionary *dict = NULL;
|
||||
if ((ret = av_dict_parse_string(&dict, ffm->params.muxer_settings,
|
||||
"=", " ", 0))) {
|
||||
printf("Failed to parse muxer settings: %s\n%s",
|
||||
fprintf(stderr, "Failed to parse muxer settings: %s\n%s",
|
||||
av_err2str(ret), ffm->params.muxer_settings);
|
||||
|
||||
av_dict_free(&dict);
|
||||
|
|
@ -501,7 +501,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
|
|||
|
||||
ret = avformat_write_header(ffm->output, &dict);
|
||||
if (ret < 0) {
|
||||
printf("Error opening '%s': %s",
|
||||
fprintf(stderr, "Error opening '%s': %s",
|
||||
ffm->params.file, av_err2str(ret));
|
||||
|
||||
av_dict_free(&dict);
|
||||
|
|
@ -521,7 +521,7 @@ static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm)
|
|||
|
||||
output_format = av_guess_format(NULL, ffm->params.file, NULL);
|
||||
if (output_format == NULL) {
|
||||
printf("Couldn't find an appropriate muxer for '%s'\n",
|
||||
fprintf(stderr, "Couldn't find an appropriate muxer for '%s'\n",
|
||||
ffm->params.file);
|
||||
return FFM_ERROR;
|
||||
}
|
||||
|
|
@ -529,7 +529,7 @@ static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm)
|
|||
ret = avformat_alloc_output_context2(&ffm->output, output_format,
|
||||
NULL, NULL);
|
||||
if (ret < 0) {
|
||||
printf("Couldn't initialize output context: %s\n",
|
||||
fprintf(stderr, "Couldn't initialize output context: %s\n",
|
||||
av_err2str(ret));
|
||||
return FFM_ERROR;
|
||||
}
|
||||
|
|
@ -679,7 +679,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
ret = ffmpeg_mux_init(&ffm, argc, argv);
|
||||
if (ret != FFM_SUCCESS) {
|
||||
puts("Couldn't initialize muxer");
|
||||
fprintf(stderr, "Couldn't initialize muxer\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
149
plugins/obs-ffmpeg/jim-nvenc-helpers.c
Normal file
149
plugins/obs-ffmpeg/jim-nvenc-helpers.c
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#include "jim-nvenc.h"
|
||||
#include <util/platform.h>
|
||||
#include <util/threading.h>
|
||||
|
||||
static void *nvenc_lib = NULL;
|
||||
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
NV_ENCODE_API_FUNCTION_LIST nv = {NV_ENCODE_API_FUNCTION_LIST_VER};
|
||||
NV_CREATE_INSTANCE_FUNC nv_create_instance = NULL;
|
||||
|
||||
#define error(format, ...) \
|
||||
blog(LOG_ERROR, "[jim-nvenc] " format, ##__VA_ARGS__)
|
||||
|
||||
static inline bool nv_failed(NVENCSTATUS err, const char *func, const char *call)
|
||||
{
|
||||
if (err == NV_ENC_SUCCESS)
|
||||
return false;
|
||||
|
||||
error("%s: %s failed: %d (%s)", func, call, (int)err,
|
||||
nv_error_name(err));
|
||||
return true;
|
||||
}
|
||||
|
||||
#define NV_FAILED(x) nv_failed(x, __FUNCTION__, #x)
|
||||
|
||||
bool load_nvenc_lib(void)
|
||||
{
|
||||
if (sizeof(void*) == 8) {
|
||||
nvenc_lib = os_dlopen("nvEncodeAPI64.dll");
|
||||
} else {
|
||||
nvenc_lib = os_dlopen("nvEncodeAPI.dll");
|
||||
}
|
||||
|
||||
return !!nvenc_lib;
|
||||
}
|
||||
|
||||
static void *load_nv_func(const char *func)
|
||||
{
|
||||
void *func_ptr = os_dlsym(nvenc_lib, func);
|
||||
if (!func_ptr) {
|
||||
error("Could not load function: %s", func);
|
||||
}
|
||||
return func_ptr;
|
||||
}
|
||||
|
||||
typedef NVENCSTATUS (NVENCAPI *NV_MAX_VER_FUNC)(uint32_t*);
|
||||
|
||||
const char *nv_error_name(NVENCSTATUS err)
|
||||
{
|
||||
#define RETURN_CASE(x) \
|
||||
case x: return #x
|
||||
|
||||
switch (err) {
|
||||
RETURN_CASE(NV_ENC_SUCCESS);
|
||||
RETURN_CASE(NV_ENC_ERR_NO_ENCODE_DEVICE);
|
||||
RETURN_CASE(NV_ENC_ERR_UNSUPPORTED_DEVICE);
|
||||
RETURN_CASE(NV_ENC_ERR_INVALID_ENCODERDEVICE);
|
||||
RETURN_CASE(NV_ENC_ERR_INVALID_DEVICE);
|
||||
RETURN_CASE(NV_ENC_ERR_DEVICE_NOT_EXIST);
|
||||
RETURN_CASE(NV_ENC_ERR_INVALID_PTR);
|
||||
RETURN_CASE(NV_ENC_ERR_INVALID_EVENT);
|
||||
RETURN_CASE(NV_ENC_ERR_INVALID_PARAM);
|
||||
RETURN_CASE(NV_ENC_ERR_INVALID_CALL);
|
||||
RETURN_CASE(NV_ENC_ERR_OUT_OF_MEMORY);
|
||||
RETURN_CASE(NV_ENC_ERR_ENCODER_NOT_INITIALIZED);
|
||||
RETURN_CASE(NV_ENC_ERR_UNSUPPORTED_PARAM);
|
||||
RETURN_CASE(NV_ENC_ERR_LOCK_BUSY);
|
||||
RETURN_CASE(NV_ENC_ERR_NOT_ENOUGH_BUFFER);
|
||||
RETURN_CASE(NV_ENC_ERR_INVALID_VERSION);
|
||||
RETURN_CASE(NV_ENC_ERR_MAP_FAILED);
|
||||
RETURN_CASE(NV_ENC_ERR_NEED_MORE_INPUT);
|
||||
RETURN_CASE(NV_ENC_ERR_ENCODER_BUSY);
|
||||
RETURN_CASE(NV_ENC_ERR_EVENT_NOT_REGISTERD);
|
||||
RETURN_CASE(NV_ENC_ERR_GENERIC);
|
||||
RETURN_CASE(NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY);
|
||||
RETURN_CASE(NV_ENC_ERR_UNIMPLEMENTED);
|
||||
RETURN_CASE(NV_ENC_ERR_RESOURCE_REGISTER_FAILED);
|
||||
RETURN_CASE(NV_ENC_ERR_RESOURCE_NOT_REGISTERED);
|
||||
RETURN_CASE(NV_ENC_ERR_RESOURCE_NOT_MAPPED);
|
||||
}
|
||||
#undef RETURN_CASE
|
||||
|
||||
return "Unknown Error";
|
||||
}
|
||||
|
||||
static inline bool init_nvenc_internal(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
static bool success = false;
|
||||
|
||||
if (initialized)
|
||||
return success;
|
||||
initialized = true;
|
||||
|
||||
NV_MAX_VER_FUNC nv_max_ver = (NV_MAX_VER_FUNC)
|
||||
load_nv_func("NvEncodeAPIGetMaxSupportedVersion");
|
||||
if (!nv_max_ver) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t ver = 0;
|
||||
if (NV_FAILED(nv_max_ver(&ver))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t cur_ver =
|
||||
(NVENCAPI_MAJOR_VERSION << 4) | NVENCAPI_MINOR_VERSION;
|
||||
if (cur_ver > ver) {
|
||||
error("Current driver version does not support this NVENC "
|
||||
"version, please upgrade your driver");
|
||||
return false;
|
||||
}
|
||||
|
||||
nv_create_instance = (NV_CREATE_INSTANCE_FUNC)
|
||||
load_nv_func("NvEncodeAPICreateInstance");
|
||||
if (!nv_create_instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NV_FAILED(nv_create_instance(&nv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool init_nvenc(void)
|
||||
{
|
||||
bool success;
|
||||
|
||||
pthread_mutex_lock(&init_mutex);
|
||||
success = init_nvenc_internal();
|
||||
pthread_mutex_unlock(&init_mutex);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
extern struct obs_encoder_info nvenc_info;
|
||||
|
||||
void jim_nvenc_load(void)
|
||||
{
|
||||
pthread_mutex_init(&init_mutex, NULL);
|
||||
obs_register_encoder(&nvenc_info);
|
||||
}
|
||||
|
||||
void jim_nvenc_unload(void)
|
||||
{
|
||||
pthread_mutex_destroy(&init_mutex);
|
||||
}
|
||||
945
plugins/obs-ffmpeg/jim-nvenc.c
Normal file
945
plugins/obs-ffmpeg/jim-nvenc.c
Normal file
|
|
@ -0,0 +1,945 @@
|
|||
#include "jim-nvenc.h"
|
||||
#include <util/circlebuf.h>
|
||||
#include <util/darray.h>
|
||||
#include <util/dstr.h>
|
||||
#include <obs-avc.h>
|
||||
#define INITGUID
|
||||
#include <dxgi.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3d11_1.h>
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#define EXTRA_BUFFERS 5
|
||||
|
||||
#define do_log(level, format, ...) \
|
||||
blog(level, "[jim-nvenc: '%s'] " format, \
|
||||
obs_encoder_get_name(enc->encoder), ##__VA_ARGS__)
|
||||
|
||||
#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__)
|
||||
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
|
||||
#define error_hr(msg) \
|
||||
error("%s: %s: 0x%08lX", __FUNCTION__, msg, (uint32_t)hr);
|
||||
|
||||
struct nv_bitstream;
|
||||
struct nv_texture;
|
||||
|
||||
struct handle_tex {
|
||||
uint32_t handle;
|
||||
ID3D11Texture2D *tex;
|
||||
IDXGIKeyedMutex *km;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Main Implementation Structure */
|
||||
|
||||
struct nvenc_data {
|
||||
obs_encoder_t *encoder;
|
||||
|
||||
void *session;
|
||||
NV_ENC_INITIALIZE_PARAMS params;
|
||||
NV_ENC_CONFIG config;
|
||||
size_t buf_count;
|
||||
size_t output_delay;
|
||||
size_t buffers_queued;
|
||||
size_t next_bitstream;
|
||||
size_t cur_bitstream;
|
||||
bool encode_started;
|
||||
bool first_packet;
|
||||
bool can_change_bitrate;
|
||||
bool bframes;
|
||||
|
||||
DARRAY(struct nv_bitstream) bitstreams;
|
||||
DARRAY(struct nv_texture) textures;
|
||||
DARRAY(struct handle_tex) input_textures;
|
||||
struct circlebuf dts_list;
|
||||
|
||||
DARRAY(uint8_t) packet_data;
|
||||
int64_t packet_pts;
|
||||
bool packet_keyframe;
|
||||
|
||||
ID3D11Device *device;
|
||||
ID3D11DeviceContext *context;
|
||||
|
||||
uint32_t cx;
|
||||
uint32_t cy;
|
||||
|
||||
uint8_t *header;
|
||||
size_t header_size;
|
||||
|
||||
uint8_t *sei;
|
||||
size_t sei_size;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Bitstream Buffer */
|
||||
|
||||
struct nv_bitstream {
|
||||
void *ptr;
|
||||
HANDLE event;
|
||||
};
|
||||
|
||||
static inline bool nv_failed(struct nvenc_data *enc, NVENCSTATUS err,
|
||||
const char *func, const char *call)
|
||||
{
|
||||
if (err == NV_ENC_SUCCESS)
|
||||
return false;
|
||||
|
||||
error("%s: %s failed: %d (%s)", func, call, (int)err,
|
||||
nv_error_name(err));
|
||||
return true;
|
||||
}
|
||||
|
||||
#define NV_FAILED(x) nv_failed(enc, x, __FUNCTION__, #x)
|
||||
|
||||
static bool nv_bitstream_init(struct nvenc_data *enc, struct nv_bitstream *bs)
|
||||
{
|
||||
NV_ENC_CREATE_BITSTREAM_BUFFER buf = {NV_ENC_CREATE_BITSTREAM_BUFFER_VER};
|
||||
NV_ENC_EVENT_PARAMS params = {NV_ENC_EVENT_PARAMS_VER};
|
||||
HANDLE event = NULL;
|
||||
|
||||
if (NV_FAILED(nv.nvEncCreateBitstreamBuffer(enc->session, &buf))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
event = CreateEvent(NULL, true, true, NULL);
|
||||
if (!event) {
|
||||
error("%s: %s", __FUNCTION__, "Failed to create event");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
params.completionEvent = event;
|
||||
if (NV_FAILED(nv.nvEncRegisterAsyncEvent(enc->session, ¶ms))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs->ptr = buf.bitstreamBuffer;
|
||||
bs->event = event;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if (event) {
|
||||
CloseHandle(event);
|
||||
}
|
||||
if (buf.bitstreamBuffer) {
|
||||
nv.nvEncDestroyBitstreamBuffer(enc->session,
|
||||
buf.bitstreamBuffer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void nv_bitstream_free(struct nvenc_data *enc, struct nv_bitstream *bs)
|
||||
{
|
||||
if (bs->ptr) {
|
||||
nv.nvEncDestroyBitstreamBuffer(enc->session, bs->ptr);
|
||||
|
||||
NV_ENC_EVENT_PARAMS params = {NV_ENC_EVENT_PARAMS_VER};
|
||||
params.completionEvent = bs->event;
|
||||
nv.nvEncUnregisterAsyncEvent(enc->session, ¶ms);
|
||||
CloseHandle(bs->event);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Texture Resource */
|
||||
|
||||
struct nv_texture {
|
||||
void *res;
|
||||
ID3D11Texture2D *tex;
|
||||
void *mapped_res;
|
||||
};
|
||||
|
||||
static bool nv_texture_init(struct nvenc_data *enc, struct nv_texture *nvtex)
|
||||
{
|
||||
ID3D11Device *device = enc->device;
|
||||
ID3D11Texture2D *tex;
|
||||
HRESULT hr;
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc = {0};
|
||||
desc.Width = enc->cx;
|
||||
desc.Height = enc->cy;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_NV12;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||
|
||||
hr = device->lpVtbl->CreateTexture2D(device, &desc, NULL, &tex);
|
||||
if (FAILED(hr)) {
|
||||
error_hr("Failed to create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
tex->lpVtbl->SetEvictionPriority(tex, DXGI_RESOURCE_PRIORITY_MAXIMUM);
|
||||
|
||||
NV_ENC_REGISTER_RESOURCE res = {NV_ENC_REGISTER_RESOURCE_VER};
|
||||
res.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX;
|
||||
res.resourceToRegister = tex;
|
||||
res.width = enc->cx;
|
||||
res.height = enc->cy;
|
||||
res.bufferFormat = NV_ENC_BUFFER_FORMAT_NV12;
|
||||
|
||||
if (NV_FAILED(nv.nvEncRegisterResource(enc->session, &res))) {
|
||||
tex->lpVtbl->Release(tex);
|
||||
return false;
|
||||
}
|
||||
|
||||
nvtex->res = res.registeredResource;
|
||||
nvtex->tex = tex;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nv_texture_free(struct nvenc_data *enc, struct nv_texture *nvtex)
|
||||
{
|
||||
if (nvtex->res) {
|
||||
if (nvtex->mapped_res) {
|
||||
nv.nvEncUnmapInputResource(enc->session,
|
||||
nvtex->mapped_res);
|
||||
}
|
||||
nv.nvEncUnregisterResource(enc->session, nvtex->res);
|
||||
nvtex->tex->lpVtbl->Release(nvtex->tex);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Implementation */
|
||||
|
||||
static const char *nvenc_get_name(void *type_data)
|
||||
{
|
||||
UNUSED_PARAMETER(type_data);
|
||||
return "NVIDIA NVENC H.264 (new)";
|
||||
}
|
||||
|
||||
static inline int nv_get_cap(struct nvenc_data *enc, NV_ENC_CAPS cap)
|
||||
{
|
||||
if (!enc->session)
|
||||
return 0;
|
||||
|
||||
NV_ENC_CAPS_PARAM param = {NV_ENC_CAPS_PARAM_VER};
|
||||
int v;
|
||||
|
||||
param.capsToQuery = cap;
|
||||
nv.nvEncGetEncodeCaps(enc->session, NV_ENC_CODEC_H264_GUID, ¶m, &v);
|
||||
return v;
|
||||
}
|
||||
|
||||
static bool nvenc_update(void *data, obs_data_t *settings)
|
||||
{
|
||||
struct nvenc_data *enc = data;
|
||||
|
||||
/* Only support reconfiguration of CBR bitrate */
|
||||
if (enc->can_change_bitrate) {
|
||||
int bitrate = (int)obs_data_get_int(settings, "bitrate");
|
||||
|
||||
enc->config.rcParams.averageBitRate = bitrate * 1000;
|
||||
enc->config.rcParams.maxBitRate = bitrate * 1000;
|
||||
|
||||
NV_ENC_RECONFIGURE_PARAMS params = {0};
|
||||
params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
|
||||
params.reInitEncodeParams = enc->params;
|
||||
|
||||
if (FAILED(nv.nvEncReconfigureEncoder(enc->session, ¶ms))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static HANDLE get_lib(struct nvenc_data *enc, const char *lib)
|
||||
{
|
||||
HMODULE mod = GetModuleHandleA(lib);
|
||||
if (mod)
|
||||
return mod;
|
||||
|
||||
mod = LoadLibraryA(lib);
|
||||
if (!mod)
|
||||
error("Failed to load %s", lib);
|
||||
return mod;
|
||||
}
|
||||
|
||||
typedef HRESULT (WINAPI *CREATEDXGIFACTORY1PROC)(REFIID, void **);
|
||||
|
||||
static bool init_d3d11(struct nvenc_data *enc, obs_data_t *settings)
|
||||
{
|
||||
HMODULE dxgi = get_lib(enc, "DXGI.dll");
|
||||
HMODULE d3d11 = get_lib(enc, "D3D11.dll");
|
||||
CREATEDXGIFACTORY1PROC create_dxgi;
|
||||
PFN_D3D11_CREATE_DEVICE create_device;
|
||||
IDXGIFactory1 *factory;
|
||||
IDXGIAdapter *adapter;
|
||||
ID3D11Device *device;
|
||||
ID3D11DeviceContext *context;
|
||||
HRESULT hr;
|
||||
|
||||
if (!dxgi || !d3d11) {
|
||||
return false;
|
||||
}
|
||||
|
||||
create_dxgi = (CREATEDXGIFACTORY1PROC)GetProcAddress(dxgi,
|
||||
"CreateDXGIFactory1");
|
||||
create_device = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11,
|
||||
"D3D11CreateDevice");
|
||||
|
||||
if (!create_dxgi || !create_device) {
|
||||
error("Failed to load D3D11/DXGI procedures");
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = create_dxgi(&IID_IDXGIFactory1, &factory);
|
||||
if (FAILED(hr)) {
|
||||
error_hr("CreateDXGIFactory1 failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = factory->lpVtbl->EnumAdapters(factory, 0, &adapter);
|
||||
factory->lpVtbl->Release(factory);
|
||||
if (FAILED(hr)) {
|
||||
error_hr("EnumAdapters failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0,
|
||||
NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context);
|
||||
adapter->lpVtbl->Release(adapter);
|
||||
if (FAILED(hr)) {
|
||||
error_hr("D3D11CreateDevice failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
enc->device = device;
|
||||
enc->context = context;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_session(struct nvenc_data *enc)
|
||||
{
|
||||
NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params =
|
||||
{NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER};
|
||||
params.device = enc->device;
|
||||
params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX;
|
||||
params.apiVersion = NVENCAPI_VERSION;
|
||||
|
||||
if (NV_FAILED(nv.nvEncOpenEncodeSessionEx(¶ms, &enc->session))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings)
|
||||
{
|
||||
const char *rc = obs_data_get_string(settings, "rate_control");
|
||||
int bitrate = (int)obs_data_get_int(settings, "bitrate");
|
||||
int max_bitrate = (int)obs_data_get_int(settings, "max_bitrate");
|
||||
int cqp = (int)obs_data_get_int(settings, "cqp");
|
||||
int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
|
||||
const char *preset = obs_data_get_string(settings, "preset");
|
||||
const char *profile = obs_data_get_string(settings, "profile");
|
||||
bool psycho_aq = obs_data_get_bool(settings, "psycho_aq");
|
||||
bool lookahead = obs_data_get_bool(settings, "lookahead");
|
||||
int bf = (int)obs_data_get_int(settings, "bf");
|
||||
bool vbr = astrcmpi(rc, "VBR") == 0;
|
||||
NVENCSTATUS err;
|
||||
|
||||
video_t *video = obs_encoder_video(enc->encoder);
|
||||
const struct video_output_info *voi = video_output_get_info(video);
|
||||
|
||||
enc->cx = voi->width;
|
||||
enc->cy = voi->height;
|
||||
|
||||
/* -------------------------- */
|
||||
/* get preset */
|
||||
|
||||
GUID nv_preset = NV_ENC_PRESET_DEFAULT_GUID;
|
||||
bool twopass = false;
|
||||
bool hp = false;
|
||||
bool ll = false;
|
||||
|
||||
if (astrcmpi(preset, "hq") == 0) {
|
||||
nv_preset = NV_ENC_PRESET_HQ_GUID;
|
||||
|
||||
} else if (astrcmpi(preset, "mq") == 0) {
|
||||
nv_preset = NV_ENC_PRESET_HQ_GUID;
|
||||
twopass = true;
|
||||
|
||||
} else if (astrcmpi(preset, "hp") == 0) {
|
||||
nv_preset = NV_ENC_PRESET_HP_GUID;
|
||||
hp = true;
|
||||
|
||||
} else if (astrcmpi(preset, "ll") == 0) {
|
||||
nv_preset = NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID;
|
||||
ll = true;
|
||||
|
||||
} else if (astrcmpi(preset, "llhq") == 0) {
|
||||
nv_preset = NV_ENC_PRESET_LOW_LATENCY_HQ_GUID;
|
||||
ll = true;
|
||||
|
||||
} else if (astrcmpi(preset, "llhp") == 0) {
|
||||
nv_preset = NV_ENC_PRESET_LOW_LATENCY_HP_GUID;
|
||||
hp = true;
|
||||
ll = true;
|
||||
}
|
||||
|
||||
if (astrcmpi(rc, "lossless") == 0) {
|
||||
nv_preset = hp
|
||||
? NV_ENC_PRESET_LOSSLESS_HP_GUID
|
||||
: NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID;
|
||||
}
|
||||
|
||||
/* -------------------------- */
|
||||
/* get preset default config */
|
||||
|
||||
NV_ENC_PRESET_CONFIG preset_config =
|
||||
{NV_ENC_PRESET_CONFIG_VER, {NV_ENC_CONFIG_VER}};
|
||||
|
||||
err = nv.nvEncGetEncodePresetConfig(enc->session,
|
||||
NV_ENC_CODEC_H264_GUID, nv_preset, &preset_config);
|
||||
if (nv_failed(enc, err, __FUNCTION__, "nvEncGetEncodePresetConfig")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------- */
|
||||
/* main configuration */
|
||||
|
||||
enc->config = preset_config.presetCfg;
|
||||
|
||||
uint32_t gop_size = (keyint_sec)
|
||||
? keyint_sec * voi->fps_num / voi->fps_den
|
||||
: 250;
|
||||
|
||||
NV_ENC_INITIALIZE_PARAMS *params = &enc->params;
|
||||
NV_ENC_CONFIG *config = &enc->config;
|
||||
NV_ENC_CONFIG_H264 *h264_config = &config->encodeCodecConfig.h264Config;
|
||||
NV_ENC_CONFIG_H264_VUI_PARAMETERS *vui_params =
|
||||
&h264_config->h264VUIParameters;
|
||||
|
||||
memset(params, 0, sizeof(*params));
|
||||
params->version = NV_ENC_INITIALIZE_PARAMS_VER;
|
||||
params->encodeGUID = NV_ENC_CODEC_H264_GUID;
|
||||
params->presetGUID = nv_preset;
|
||||
params->encodeWidth = voi->width;
|
||||
params->encodeHeight = voi->height;
|
||||
params->darWidth = voi->width;
|
||||
params->darHeight = voi->height;
|
||||
params->frameRateNum = voi->fps_num;
|
||||
params->frameRateDen = voi->fps_den;
|
||||
params->enableEncodeAsync = 1;
|
||||
params->enablePTD = 1;
|
||||
params->encodeConfig = &enc->config;
|
||||
params->maxEncodeWidth = voi->width;
|
||||
params->maxEncodeHeight = voi->height;
|
||||
config->gopLength = gop_size;
|
||||
config->frameIntervalP = 1 + bf;
|
||||
h264_config->idrPeriod = gop_size;
|
||||
vui_params->videoSignalTypePresentFlag = 1;
|
||||
vui_params->videoFullRangeFlag = (voi->range == VIDEO_RANGE_FULL);
|
||||
vui_params->colourDescriptionPresentFlag = 1;
|
||||
vui_params->colourMatrix = (voi->colorspace == VIDEO_CS_709) ? 1 : 5;
|
||||
vui_params->colourPrimaries = 1;
|
||||
vui_params->transferCharacteristics = 1;
|
||||
|
||||
enc->bframes = bf > 0;
|
||||
|
||||
/* lookahead */
|
||||
if (lookahead && nv_get_cap(enc, NV_ENC_CAPS_SUPPORT_LOOKAHEAD)) {
|
||||
config->rcParams.lookaheadDepth = 8;
|
||||
config->rcParams.enableLookahead = 1;
|
||||
}
|
||||
|
||||
/* psycho aq */
|
||||
if (nv_get_cap(enc, NV_ENC_CAPS_SUPPORT_TEMPORAL_AQ)) {
|
||||
config->rcParams.enableAQ = psycho_aq;
|
||||
config->rcParams.enableTemporalAQ = psycho_aq;
|
||||
}
|
||||
|
||||
/* -------------------------- */
|
||||
/* rate control */
|
||||
|
||||
enc->can_change_bitrate =
|
||||
nv_get_cap(enc, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
|
||||
|
||||
config->rcParams.rateControlMode = twopass
|
||||
? NV_ENC_PARAMS_RC_VBR_HQ
|
||||
: NV_ENC_PARAMS_RC_VBR;
|
||||
|
||||
if (astrcmpi(rc, "cqp") == 0 || astrcmpi(rc, "lossless") == 0) {
|
||||
if (astrcmpi(rc, "lossless") == 0)
|
||||
cqp = 0;
|
||||
|
||||
config->rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
|
||||
config->rcParams.constQP.qpInterP = cqp;
|
||||
config->rcParams.constQP.qpInterB = cqp;
|
||||
config->rcParams.constQP.qpIntra = cqp;
|
||||
enc->can_change_bitrate = false;
|
||||
|
||||
bitrate = 0;
|
||||
max_bitrate = 0;
|
||||
|
||||
} else if (astrcmpi(rc, "vbr") != 0) { /* CBR by default */
|
||||
h264_config->outputBufferingPeriodSEI = 1;
|
||||
config->rcParams.rateControlMode = twopass
|
||||
? NV_ENC_PARAMS_RC_2_PASS_QUALITY
|
||||
: NV_ENC_PARAMS_RC_CBR;
|
||||
}
|
||||
|
||||
h264_config->outputPictureTimingSEI = 1;
|
||||
config->rcParams.averageBitRate = bitrate * 1000;
|
||||
config->rcParams.maxBitRate = vbr ? max_bitrate * 1000 : bitrate * 1000;
|
||||
|
||||
/* -------------------------- */
|
||||
/* profile */
|
||||
|
||||
if (astrcmpi(profile, "main") == 0) {
|
||||
config->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
|
||||
} else if (astrcmpi(profile, "baseline") == 0) {
|
||||
config->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
|
||||
} else {
|
||||
config->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
|
||||
}
|
||||
|
||||
/* -------------------------- */
|
||||
/* initialize */
|
||||
|
||||
if (NV_FAILED(nv.nvEncInitializeEncoder(enc->session, params))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
enc->buf_count = config->frameIntervalP +
|
||||
config->rcParams.lookaheadDepth + EXTRA_BUFFERS;
|
||||
enc->output_delay = enc->buf_count - 1;
|
||||
|
||||
info("settings:\n"
|
||||
"\trate_control: %s\n"
|
||||
"\tbitrate: %d\n"
|
||||
"\tcqp: %d\n"
|
||||
"\tkeyint: %d\n"
|
||||
"\tpreset: %s\n"
|
||||
"\tprofile: %s\n"
|
||||
"\twidth: %d\n"
|
||||
"\theight: %d\n"
|
||||
"\t2-pass: %s\n"
|
||||
"\tb-frames: %d\n"
|
||||
"\tlookahead: %s\n"
|
||||
"\tpsycho_aq: %s\n",
|
||||
rc, bitrate, cqp, gop_size,
|
||||
preset, profile,
|
||||
enc->cx, enc->cy,
|
||||
twopass ? "true" : "false",
|
||||
bf,
|
||||
lookahead ? "true" : "false",
|
||||
psycho_aq ? "true" : "false");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_bitstreams(struct nvenc_data *enc)
|
||||
{
|
||||
da_reserve(enc->bitstreams, enc->buf_count);
|
||||
for (size_t i = 0; i < enc->buf_count; i++) {
|
||||
struct nv_bitstream bitstream;
|
||||
if (!nv_bitstream_init(enc, &bitstream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
da_push_back(enc->bitstreams, &bitstream);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_textures(struct nvenc_data *enc)
|
||||
{
|
||||
da_reserve(enc->bitstreams, enc->buf_count);
|
||||
for (size_t i = 0; i < enc->buf_count; i++) {
|
||||
struct nv_texture texture;
|
||||
if (!nv_texture_init(enc, &texture)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
da_push_back(enc->textures, &texture);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nvenc_destroy(void *data);
|
||||
|
||||
static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
|
||||
{
|
||||
NV_ENCODE_API_FUNCTION_LIST init = {NV_ENCODE_API_FUNCTION_LIST_VER};
|
||||
struct nvenc_data *enc = bzalloc(sizeof(*enc));
|
||||
enc->encoder = encoder;
|
||||
enc->first_packet = true;
|
||||
|
||||
/* this encoder requires shared textures, this cannot be used on a
|
||||
* gpu other than the one OBS is currently running on. */
|
||||
int gpu = (int)obs_data_get_int(settings, "gpu");
|
||||
if (gpu != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!obs_nv12_tex_active()) {
|
||||
goto fail;
|
||||
}
|
||||
if (!init_nvenc()) {
|
||||
goto fail;
|
||||
}
|
||||
if (NV_FAILED(nv_create_instance(&init))) {
|
||||
goto fail;
|
||||
}
|
||||
if (!init_d3d11(enc, settings)) {
|
||||
goto fail;
|
||||
}
|
||||
if (!init_session(enc)) {
|
||||
goto fail;
|
||||
}
|
||||
if (!init_encoder(enc, settings)) {
|
||||
goto fail;
|
||||
}
|
||||
if (!init_bitstreams(enc)) {
|
||||
goto fail;
|
||||
}
|
||||
if (!init_textures(enc)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return enc;
|
||||
|
||||
fail:
|
||||
nvenc_destroy(enc);
|
||||
return obs_encoder_create_rerouted(encoder, "ffmpeg_nvenc");
|
||||
}
|
||||
|
||||
static bool get_encoded_packet(struct nvenc_data *enc, bool finalize);
|
||||
|
||||
static void nvenc_destroy(void *data)
|
||||
{
|
||||
struct nvenc_data *enc = data;
|
||||
|
||||
if (enc->encode_started) {
|
||||
size_t next_bitstream = enc->next_bitstream;
|
||||
HANDLE next_event = enc->bitstreams.array[next_bitstream].event;
|
||||
|
||||
NV_ENC_PIC_PARAMS params = {NV_ENC_PIC_PARAMS_VER};
|
||||
params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
|
||||
params.completionEvent = next_event;
|
||||
nv.nvEncEncodePicture(enc->session, ¶ms);
|
||||
get_encoded_packet(enc, true);
|
||||
}
|
||||
for (size_t i = 0; i < enc->textures.num; i++) {
|
||||
nv_texture_free(enc, &enc->textures.array[i]);
|
||||
}
|
||||
for (size_t i = 0; i < enc->bitstreams.num; i++) {
|
||||
nv_bitstream_free(enc, &enc->bitstreams.array[i]);
|
||||
}
|
||||
if (enc->session) {
|
||||
nv.nvEncDestroyEncoder(enc->session);
|
||||
}
|
||||
for (size_t i = 0; i < enc->input_textures.num; i++) {
|
||||
ID3D11Texture2D *tex = enc->input_textures.array[i].tex;
|
||||
IDXGIKeyedMutex *km = enc->input_textures.array[i].km;
|
||||
tex->lpVtbl->Release(tex);
|
||||
km->lpVtbl->Release(km);
|
||||
}
|
||||
if (enc->context) {
|
||||
enc->context->lpVtbl->Release(enc->context);
|
||||
}
|
||||
if (enc->device) {
|
||||
enc->device->lpVtbl->Release(enc->device);
|
||||
}
|
||||
|
||||
bfree(enc->header);
|
||||
bfree(enc->sei);
|
||||
circlebuf_free(&enc->dts_list);
|
||||
da_free(enc->textures);
|
||||
da_free(enc->bitstreams);
|
||||
da_free(enc->input_textures);
|
||||
da_free(enc->packet_data);
|
||||
bfree(enc);
|
||||
}
|
||||
|
||||
static ID3D11Texture2D *get_tex_from_handle(struct nvenc_data *enc,
|
||||
uint32_t handle, IDXGIKeyedMutex **km_out)
|
||||
{
|
||||
ID3D11Device *device = enc->device;
|
||||
IDXGIKeyedMutex *km;
|
||||
ID3D11Texture2D *input_tex;
|
||||
HRESULT hr;
|
||||
|
||||
for (size_t i = 0; i < enc->input_textures.num; i++) {
|
||||
struct handle_tex *ht = &enc->input_textures.array[i];
|
||||
if (ht->handle == handle) {
|
||||
*km_out = ht->km;
|
||||
return ht->tex;
|
||||
}
|
||||
}
|
||||
|
||||
hr = device->lpVtbl->OpenSharedResource(device,
|
||||
(HANDLE)(uintptr_t)handle,
|
||||
&IID_ID3D11Texture2D, &input_tex);
|
||||
if (FAILED(hr)) {
|
||||
error_hr("OpenSharedResource failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hr = input_tex->lpVtbl->QueryInterface(input_tex, &IID_IDXGIKeyedMutex,
|
||||
&km);
|
||||
if (FAILED(hr)) {
|
||||
error_hr("QueryInterface(IDXGIKeyedMutex) failed");
|
||||
input_tex->lpVtbl->Release(input_tex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input_tex->lpVtbl->SetEvictionPriority(input_tex,
|
||||
DXGI_RESOURCE_PRIORITY_MAXIMUM);
|
||||
|
||||
*km_out = km;
|
||||
|
||||
struct handle_tex new_ht = {handle, input_tex, km};
|
||||
da_push_back(enc->input_textures, &new_ht);
|
||||
return input_tex;
|
||||
}
|
||||
|
||||
static bool get_encoded_packet(struct nvenc_data *enc, bool finalize)
|
||||
{
|
||||
void *s = enc->session;
|
||||
|
||||
da_resize(enc->packet_data, 0);
|
||||
|
||||
if (!enc->buffers_queued)
|
||||
return true;
|
||||
if (!finalize && enc->buffers_queued < enc->output_delay)
|
||||
return true;
|
||||
|
||||
size_t count = finalize ? enc->buffers_queued : 1;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
size_t cur_bs_idx = enc->cur_bitstream;
|
||||
struct nv_bitstream *bs = &enc->bitstreams.array[cur_bs_idx];
|
||||
struct nv_texture *nvtex = &enc->textures.array[cur_bs_idx];
|
||||
|
||||
/* ---------------- */
|
||||
|
||||
NV_ENC_LOCK_BITSTREAM lock = {NV_ENC_LOCK_BITSTREAM_VER};
|
||||
lock.outputBitstream = bs->ptr;
|
||||
lock.doNotWait = false;
|
||||
|
||||
if (NV_FAILED(nv.nvEncLockBitstream(s, &lock))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enc->first_packet) {
|
||||
uint8_t *new_packet;
|
||||
size_t size;
|
||||
|
||||
enc->first_packet = false;
|
||||
obs_extract_avc_headers(
|
||||
lock.bitstreamBufferPtr,
|
||||
lock.bitstreamSizeInBytes,
|
||||
&new_packet, &size,
|
||||
&enc->header, &enc->header_size,
|
||||
&enc->sei, &enc->sei_size);
|
||||
|
||||
da_copy_array(enc->packet_data, new_packet, size);
|
||||
bfree(new_packet);
|
||||
} else {
|
||||
da_copy_array(enc->packet_data,
|
||||
lock.bitstreamBufferPtr,
|
||||
lock.bitstreamSizeInBytes);
|
||||
}
|
||||
|
||||
enc->packet_pts = (int64_t)lock.outputTimeStamp;
|
||||
enc->packet_keyframe = lock.pictureType == NV_ENC_PIC_TYPE_IDR;
|
||||
|
||||
if (NV_FAILED(nv.nvEncUnlockBitstream(s, bs->ptr))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ---------------- */
|
||||
|
||||
if (nvtex->mapped_res) {
|
||||
NVENCSTATUS err;
|
||||
err = nv.nvEncUnmapInputResource(s, nvtex->mapped_res);
|
||||
if (nv_failed(enc, err, __FUNCTION__, "unmap")) {
|
||||
return false;
|
||||
}
|
||||
nvtex->mapped_res = NULL;
|
||||
}
|
||||
|
||||
/* ---------------- */
|
||||
|
||||
if (++enc->cur_bitstream == enc->buf_count)
|
||||
enc->cur_bitstream = 0;
|
||||
|
||||
enc->buffers_queued--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts,
|
||||
uint64_t lock_key, uint64_t *next_key,
|
||||
struct encoder_packet *packet, bool *received_packet)
|
||||
{
|
||||
struct nvenc_data *enc = data;
|
||||
ID3D11Device *device = enc->device;
|
||||
ID3D11DeviceContext *context = enc->context;
|
||||
ID3D11Texture2D *input_tex;
|
||||
ID3D11Texture2D *output_tex;
|
||||
IDXGIKeyedMutex *km;
|
||||
struct nv_texture *nvtex;
|
||||
struct nv_bitstream *bs;
|
||||
NVENCSTATUS err;
|
||||
|
||||
if (handle == GS_INVALID_HANDLE) {
|
||||
error("Encode failed: bad texture handle");
|
||||
*next_key = lock_key;
|
||||
return false;
|
||||
}
|
||||
|
||||
bs = &enc->bitstreams.array[enc->next_bitstream];
|
||||
nvtex = &enc->textures.array[enc->next_bitstream];
|
||||
|
||||
input_tex = get_tex_from_handle(enc, handle, &km);
|
||||
output_tex = nvtex->tex;
|
||||
|
||||
if (!input_tex) {
|
||||
*next_key = lock_key;
|
||||
return false;
|
||||
}
|
||||
|
||||
circlebuf_push_back(&enc->dts_list, &pts, sizeof(pts));
|
||||
|
||||
/* ------------------------------------ */
|
||||
/* wait for output bitstream/tex */
|
||||
|
||||
WaitForSingleObject(bs->event, INFINITE);
|
||||
|
||||
/* ------------------------------------ */
|
||||
/* copy to output tex */
|
||||
|
||||
km->lpVtbl->AcquireSync(km, lock_key, INFINITE);
|
||||
|
||||
context->lpVtbl->CopyResource(context,
|
||||
(ID3D11Resource *)output_tex,
|
||||
(ID3D11Resource *)input_tex);
|
||||
|
||||
km->lpVtbl->ReleaseSync(km, *next_key);
|
||||
|
||||
/* ------------------------------------ */
|
||||
/* map output tex so nvenc can use it */
|
||||
|
||||
NV_ENC_MAP_INPUT_RESOURCE map = {NV_ENC_MAP_INPUT_RESOURCE_VER};
|
||||
map.registeredResource = nvtex->res;
|
||||
if (NV_FAILED(nv.nvEncMapInputResource(enc->session, &map))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nvtex->mapped_res = map.mappedResource;
|
||||
|
||||
/* ------------------------------------ */
|
||||
/* do actual encode call */
|
||||
|
||||
NV_ENC_PIC_PARAMS params = {0};
|
||||
params.version = NV_ENC_PIC_PARAMS_VER;
|
||||
params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
|
||||
params.inputBuffer = nvtex->mapped_res;
|
||||
params.bufferFmt = NV_ENC_BUFFER_FORMAT_NV12;
|
||||
params.inputTimeStamp = (uint64_t)pts;
|
||||
params.inputWidth = enc->cx;
|
||||
params.inputHeight = enc->cy;
|
||||
params.outputBitstream = bs->ptr;
|
||||
params.completionEvent = bs->event;
|
||||
|
||||
err = nv.nvEncEncodePicture(enc->session, ¶ms);
|
||||
if (err != NV_ENC_SUCCESS && err != NV_ENC_ERR_NEED_MORE_INPUT) {
|
||||
nv_failed(enc, err, __FUNCTION__, "nvEncEncodePicture");
|
||||
return false;
|
||||
}
|
||||
|
||||
enc->encode_started = true;
|
||||
enc->buffers_queued++;
|
||||
|
||||
if (++enc->next_bitstream == enc->buf_count) {
|
||||
enc->next_bitstream = 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------ */
|
||||
/* check for encoded packet and parse */
|
||||
|
||||
if (!get_encoded_packet(enc, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------ */
|
||||
/* output encoded packet */
|
||||
|
||||
if (enc->packet_data.num) {
|
||||
int64_t dts;
|
||||
circlebuf_pop_front(&enc->dts_list, &dts, sizeof(dts));
|
||||
|
||||
/* subtract bframe delay from dts */
|
||||
if (enc->bframes)
|
||||
dts -= packet->timebase_num;
|
||||
|
||||
*received_packet = true;
|
||||
packet->data = enc->packet_data.array;
|
||||
packet->size = enc->packet_data.num;
|
||||
packet->type = OBS_ENCODER_VIDEO;
|
||||
packet->pts = enc->packet_pts;
|
||||
packet->dts = dts;
|
||||
packet->keyframe = enc->packet_keyframe;
|
||||
} else {
|
||||
*received_packet = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern void nvenc_defaults(obs_data_t *settings);
|
||||
extern obs_properties_t *nvenc_properties(void *unused);
|
||||
|
||||
static bool nvenc_extra_data(void *data, uint8_t **header, size_t *size)
|
||||
{
|
||||
struct nvenc_data *enc = data;
|
||||
|
||||
if (!enc->header) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*header = enc->header;
|
||||
*size = enc->header_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool nvenc_sei_data(void *data, uint8_t **sei, size_t *size)
|
||||
{
|
||||
struct nvenc_data *enc = data;
|
||||
|
||||
if (!enc->sei) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*sei = enc->sei;
|
||||
*size = enc->sei_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct obs_encoder_info nvenc_info = {
|
||||
.id = "jim_nvenc",
|
||||
.codec = "h264",
|
||||
.type = OBS_ENCODER_VIDEO,
|
||||
.caps = OBS_ENCODER_CAP_PASS_TEXTURE,
|
||||
.get_name = nvenc_get_name,
|
||||
.create = nvenc_create,
|
||||
.destroy = nvenc_destroy,
|
||||
.update = nvenc_update,
|
||||
.encode_texture = nvenc_encode_tex,
|
||||
.get_defaults = nvenc_defaults,
|
||||
.get_properties = nvenc_properties,
|
||||
.get_extra_data = nvenc_extra_data,
|
||||
.get_sei_data = nvenc_sei_data,
|
||||
};
|
||||
14
plugins/obs-ffmpeg/jim-nvenc.h
Normal file
14
plugins/obs-ffmpeg/jim-nvenc.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <obs-module.h>
|
||||
#include "nvEncodeAPI.h"
|
||||
|
||||
typedef NVENCSTATUS (NVENCAPI *NV_CREATE_INSTANCE_FUNC)(NV_ENCODE_API_FUNCTION_LIST*);
|
||||
|
||||
extern const char *nv_error_name(NVENCSTATUS err);
|
||||
extern NV_ENCODE_API_FUNCTION_LIST nv;
|
||||
extern NV_CREATE_INSTANCE_FUNC nv_create_instance;
|
||||
extern bool init_nvenc(void);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This copyright notice applies to this header file only:
|
||||
*
|
||||
* Copyright (c) 2010-2017 NVIDIA Corporation
|
||||
* Copyright (c) 2010-2018 NVIDIA Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
* NVIDIA GPUs - beginning with the Kepler generation - contain a hardware-based encoder
|
||||
* (referred to as NVENC) which provides fully-accelerated hardware-based video encoding.
|
||||
* NvEncodeAPI provides the interface for NVIDIA video encoder (NVENC).
|
||||
* \date 2011-2017
|
||||
* \date 2011-2018
|
||||
* This file contains the interface constants, structure definitions and function prototypes.
|
||||
*/
|
||||
|
||||
|
|
@ -67,17 +67,13 @@ extern "C" {
|
|||
* @{
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define NVENCAPI __stdcall
|
||||
#else
|
||||
#define NVENCAPI
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NVENCAPI __stdcall
|
||||
typedef RECT NVENC_RECT;
|
||||
#else
|
||||
#define NVENCAPI
|
||||
// =========================================================================================
|
||||
#if !defined(GUID) && !defined(GUID_DEFINED)
|
||||
#ifndef GUID
|
||||
/*!
|
||||
* \struct GUID
|
||||
* Abstracts the GUID structure for non-windows platforms.
|
||||
|
|
@ -114,7 +110,7 @@ typedef void* NV_ENC_OUTPUT_PTR; /**< NVENCODE API output buffer*/
|
|||
typedef void* NV_ENC_REGISTERED_PTR; /**< A Resource that has been registered with NVENCODE API*/
|
||||
|
||||
#define NVENCAPI_MAJOR_VERSION 8
|
||||
#define NVENCAPI_MINOR_VERSION 0
|
||||
#define NVENCAPI_MINOR_VERSION 1
|
||||
|
||||
#define NVENCAPI_VERSION (NVENCAPI_MAJOR_VERSION | (NVENCAPI_MINOR_VERSION << 24))
|
||||
|
||||
|
|
@ -262,6 +258,30 @@ typedef enum _NV_ENC_PARAMS_RC_MODE
|
|||
NV_ENC_PARAMS_RC_VBR_HQ = 0x20 /**< VBR, high quality (slower) */
|
||||
} NV_ENC_PARAMS_RC_MODE;
|
||||
|
||||
/**
|
||||
* Emphasis Levels
|
||||
*/
|
||||
typedef enum _NV_ENC_EMPHASIS_MAP_LEVEL
|
||||
{
|
||||
NV_ENC_EMPHASIS_MAP_LEVEL_0 = 0x0, /**< Emphasis Map Level 0, for zero Delta QP value */
|
||||
NV_ENC_EMPHASIS_MAP_LEVEL_1 = 0x1, /**< Emphasis Map Level 1, for very low Delta QP value */
|
||||
NV_ENC_EMPHASIS_MAP_LEVEL_2 = 0x2, /**< Emphasis Map Level 2, for low Delta QP value */
|
||||
NV_ENC_EMPHASIS_MAP_LEVEL_3 = 0x3, /**< Emphasis Map Level 3, for medium Delta QP value */
|
||||
NV_ENC_EMPHASIS_MAP_LEVEL_4 = 0x4, /**< Emphasis Map Level 4, for high Delta QP value */
|
||||
NV_ENC_EMPHASIS_MAP_LEVEL_5 = 0x5 /**< Emphasis Map Level 5, for very high Delta QP value */
|
||||
} NV_ENC_EMPHASIS_MAP_LEVEL;
|
||||
|
||||
/**
|
||||
* QP MAP MODE
|
||||
*/
|
||||
typedef enum _NV_ENC_QP_MAP_MODE
|
||||
{
|
||||
NV_ENC_QP_MAP_DISABLED = 0x0, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap have no effect. */
|
||||
NV_ENC_QP_MAP_EMPHASIS = 0x1, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as Empasis level. Currently this is only supported for H264 */
|
||||
NV_ENC_QP_MAP_DELTA = 0x2, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as QP delta map. */
|
||||
NV_ENC_QP_MAP = 0x3, /**< Currently This is not supported. Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as QP value. */
|
||||
} NV_ENC_QP_MAP_MODE;
|
||||
|
||||
#define NV_ENC_PARAMS_RC_VBR_MINQP (NV_ENC_PARAMS_RC_MODE)0x4 /**< Deprecated */
|
||||
#define NV_ENC_PARAMS_RC_2_PASS_QUALITY NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ /**< Deprecated */
|
||||
#define NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP NV_ENC_PARAMS_RC_CBR_HQ /**< Deprecated */
|
||||
|
|
@ -585,6 +605,15 @@ typedef enum _NV_ENC_MEMORY_HEAP
|
|||
NV_ENC_MEMORY_HEAP_SYSMEM_UNCACHED = 3 /**< Memory heap is in uncached system memory */
|
||||
} NV_ENC_MEMORY_HEAP;
|
||||
|
||||
/**
|
||||
* B-frame used as reference modes
|
||||
*/
|
||||
typedef enum _NV_ENC_BFRAME_REF_MODE
|
||||
{
|
||||
NV_ENC_BFRAME_REF_MODE_DISABLED = 0x0, /**< B frame is not used for reference */
|
||||
NV_ENC_BFRAME_REF_MODE_EACH = 0x1, /**< Each B-frame will be used for reference. currently not supported */
|
||||
NV_ENC_BFRAME_REF_MODE_MIDDLE = 0x2, /**< Only(Number of B-frame)/2 th B-frame will be used for reference */
|
||||
} NV_ENC_BFRAME_REF_MODE;
|
||||
|
||||
/**
|
||||
* H.264 entropy coding modes.
|
||||
|
|
@ -955,7 +984,34 @@ typedef enum _NV_ENC_CAPS
|
|||
*/
|
||||
NV_ENC_CAPS_SUPPORT_WEIGHTED_PREDICTION,
|
||||
|
||||
|
||||
/**
|
||||
* On managed (vGPU) platforms (Windows only), this API, in conjunction with other GRID Management APIs, can be used
|
||||
* to estimate the residual capacity of the hardware encoder on the GPU as a percentage of the total available encoder capacity.
|
||||
* This API can be called at any time; i.e. during the encode session or before opening the encode session.
|
||||
* If the available encoder capacity is returned as zero, applications may choose to switch to software encoding
|
||||
* and continue to call this API (e.g. polling once per second) until capacity becomes available.
|
||||
*
|
||||
* On baremetal (non-virtualized GPU) and linux platforms, this API always returns 100.
|
||||
*/
|
||||
NV_ENC_CAPS_DYNAMIC_QUERY_ENCODER_CAPACITY,
|
||||
|
||||
/**
|
||||
* Indicates B as refererence support.
|
||||
* \n 0 : B as reference is not supported.
|
||||
* \n 1 : each B-Frame as reference is supported.
|
||||
* \n 2 : only Middle B-frame as reference is supported.
|
||||
*/
|
||||
NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE,
|
||||
|
||||
/**
|
||||
* Indicates HW support for Emphasis Level Map based delta QP computation.
|
||||
* \n 0 : Emphasis Level Map based delta QP not supported.
|
||||
* \n 1 : Emphasis Level Map based delta QP is supported.
|
||||
*/
|
||||
NV_ENC_CAPS_SUPPORT_EMPHASIS_LEVEL_MAP,
|
||||
|
||||
/**
|
||||
* Reserved - Not to be used by clients.
|
||||
*/
|
||||
NV_ENC_CAPS_EXPOSED_COUNT
|
||||
|
|
@ -1100,7 +1156,7 @@ typedef struct _NV_ENC_QP
|
|||
uint32_t enableMaxQP :1; /**< [in]: Set this to 1 if maximum QP used for rate control. */
|
||||
uint32_t enableInitialRCQP :1; /**< [in]: Set this to 1 if user suppplied initial QP is used for rate control. */
|
||||
uint32_t enableAQ :1; /**< [in]: Set this to 1 to enable adaptive quantization (Spatial). */
|
||||
uint32_t enableExtQPDeltaMap :1; /**< [in]: Set this to 1 to enable additional QP modifier for each MB supplied by client though signed byte array pointed to by NV_ENC_PIC_PARAMS::qpDeltaMap (Not Supported when AQ(Spatial/Temporal) is enabled) */
|
||||
uint32_t reservedBitField1 :1; /**< [in]: Reserved bitfields and must be set to 0. */
|
||||
uint32_t enableLookahead :1; /**< [in]: Set this to 1 to enable lookahead with depth <lookaheadDepth> (if lookahead is enabled, input frames must remain available to the encoder until encode completion) */
|
||||
uint32_t disableIadapt :1; /**< [in]: Set this to 1 to disable adaptive I-frame insertion at scene cuts (only has an effect when lookahead is enabled) */
|
||||
uint32_t disableBadapt :1; /**< [in]: Set this to 1 to disable adaptive B-frame decision (only has an effect when lookahead is enabled) */
|
||||
|
|
@ -1118,7 +1174,25 @@ typedef struct _NV_ENC_QP
|
|||
uint8_t targetQuality; /**< [in]: Target CQ (Constant Quality) level for VBR mode (range 0-51 with 0-automatic) */
|
||||
uint8_t targetQualityLSB; /**< [in]: Fractional part of target quality (as 8.8 fixed point format) */
|
||||
uint16_t lookaheadDepth; /**< [in]: Maximum depth of lookahead with range 0-32 (only used if enableLookahead=1) */
|
||||
uint32_t reserved[9];
|
||||
uint32_t reserved1;
|
||||
NV_ENC_QP_MAP_MODE qpMapMode; /**< [in]: This flag is used to interpret values in array pecified by NV_ENC_PIC_PARAMS::qpDeltaMap.
|
||||
Set this to NV_ENC_QP_MAP_EMPHASIS to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as Emphasis level Map.
|
||||
Emphasis Level can be assigned any value specified in enum NV_ENC_EMPHASIS_MAP_LEVEL.
|
||||
Emphasis Level Map is used to specify regions to be encoded at varying levels of quality.
|
||||
The hardware encoder adjusts the quantization within the image as per the provided emphasis map,
|
||||
by adjusting the quantization parameter (QP) assigned to each macroblock. This adjustment is commonly called “Delta QP”.
|
||||
The adjustment depends on the absolute QP decided by the rate control algorithm, and is applied after the rate control has decided each macroblock’s QP.
|
||||
Since the Delta QP overrides rate control, enabling emphasis level map may violate bitrate and VBV buffersize constraints.
|
||||
Emphasis level map is useful in situations when client has a priori knowledge of the image complexity (e.g. via use of NVFBC's Classification feature) and encoding those high-complexity areas at higher quality (lower QP) is important, even at the possible cost of violating bitrate/VBV buffersize constraints
|
||||
This feature is not supported when AQ( Spatial/Temporal) is enabled.
|
||||
This feature is only supported for H264 codec currently.
|
||||
|
||||
Set this to NV_ENC_QP_MAP_DELTA to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as QPDelta. This specify QP modifier to be applied on top of the QP chosen by rate control
|
||||
|
||||
Set this to NV_ENC_QP_MAP_DISABLED to ignore NV_ENC_PIC_PARAMS::qpDeltaMap values. In this case, qpDeltaMap should be set to NULL.
|
||||
|
||||
Other values are reserved for future use.*/
|
||||
uint32_t reserved[7];
|
||||
} NV_ENC_RC_PARAMS;
|
||||
|
||||
/** macro for constructing the version field of ::_NV_ENC_RC_PARAMS */
|
||||
|
|
@ -1235,7 +1309,7 @@ typedef struct _NV_ENC_CONFIG_H264
|
|||
is recommended to use a large DPB size so that the encoder can keep old reference frames which can be used if recent
|
||||
frames are invalidated. */
|
||||
uint32_t sliceMode; /**< [in]: This parameter in conjunction with sliceModeData specifies the way in which the picture is divided into slices
|
||||
sliceMode = 0 MB based slices, sliceMode = 1 Byte based slices, sliceMode = 2 MB row based slices, sliceMode = 3, numSlices in Picture
|
||||
sliceMode = 0 MB based slices, sliceMode = 1 Byte based slices, sliceMode = 2 MB row based slices, sliceMode = 3 numSlices in Picture.
|
||||
When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting
|
||||
When sliceMode == 0 and sliceModeData == 0 whole picture will be coded with one slice */
|
||||
uint32_t sliceModeData; /**< [in]: Specifies the parameter needed for sliceMode. For:
|
||||
|
|
@ -1254,11 +1328,11 @@ typedef struct _NV_ENC_CONFIG_H264
|
|||
uint32_t chromaFormatIDC; /**< [in]: Specifies the chroma format. Should be set to 1 for yuv420 input, 3 for yuv444 input.
|
||||
Check support for YUV444 encoding using ::NV_ENC_CAPS_SUPPORT_YUV444_ENCODE caps.*/
|
||||
uint32_t maxTemporalLayers; /**< [in]: Specifies the max temporal layer used for hierarchical coding. */
|
||||
uint32_t reserved1[270]; /**< [in]: Reserved and must be set to 0 */
|
||||
NV_ENC_BFRAME_REF_MODE useBFramesAsRef; /**< [in]: Specifies the B-Frame as reference mode. Check support for useBFramesAsRef mode using ::NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE caps.*/
|
||||
uint32_t reserved1[269]; /**< [in]: Reserved and must be set to 0 */
|
||||
void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
|
||||
} NV_ENC_CONFIG_H264;
|
||||
|
||||
|
||||
/**
|
||||
* \struct _NV_ENC_CONFIG_HEVC
|
||||
* HEVC encoder configuration parameters to be set during initialization.
|
||||
|
|
@ -1312,7 +1386,7 @@ typedef struct _NV_ENC_CONFIG_HEVC
|
|||
Set to 1 to use "LTR Trust" mode of LTR operation. Clients are discouraged to use "LTR Trust" mode as this mode may
|
||||
be deprecated in future releases.
|
||||
Set to 0 when using "LTR Per Picture" mode of LTR operation. */
|
||||
uint32_t reserved1[217]; /**< [in]: Reserved and must be set to 0.*/
|
||||
uint32_t reserved1[217]; /**< [in]: Reserved and must be set to 0.*/
|
||||
void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
|
||||
} NV_ENC_CONFIG_HEVC;
|
||||
|
||||
|
|
@ -1382,7 +1456,7 @@ typedef struct _NV_ENC_CONFIG
|
|||
} NV_ENC_CONFIG;
|
||||
|
||||
/** macro for constructing the version field of ::_NV_ENC_CONFIG */
|
||||
#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(6) | ( 1<<31 ))
|
||||
#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(7) | ( 1<<31 ))
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -1436,7 +1510,21 @@ typedef struct _NV_ENC_INITIALIZE_PARAMS
|
|||
typedef struct _NV_ENC_RECONFIGURE_PARAMS
|
||||
{
|
||||
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_RECONFIGURE_PARAMS_VER. */
|
||||
NV_ENC_INITIALIZE_PARAMS reInitEncodeParams; /**< [in]: Encoder session re-initialization parameters. */
|
||||
NV_ENC_INITIALIZE_PARAMS reInitEncodeParams; /**< [in]: Encoder session re-initialization parameters.
|
||||
If reInitEncodeParams.encodeConfig is NULL and
|
||||
reInitEncodeParams.presetGUID is the same as the preset
|
||||
GUID specified on the call to NvEncInitializeEncoder(),
|
||||
EncodeAPI will continue to use the existing encode
|
||||
configuration.
|
||||
If reInitEncodeParams.encodeConfig is NULL and
|
||||
reInitEncodeParams.presetGUID is different from the preset
|
||||
GUID specified on the call to NvEncInitializeEncoder(),
|
||||
EncodeAPI will try to use the default configuration for
|
||||
the preset specified by reInitEncodeParams.presetGUID.
|
||||
In this case, reconfiguration may fail if the new
|
||||
configuration is incompatible with the existing
|
||||
configuration (e.g. the new configuration results in
|
||||
a change in the GOP structure). */
|
||||
uint32_t resetEncoder :1; /**< [in]: This resets the rate control states and other internal encoder states. This should be used only with an IDR frame.
|
||||
If NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1, encoder will force the frame type to IDR */
|
||||
uint32_t forceIDR :1; /**< [in]: Encode the current picture as an IDR picture. This flag is only valid when Picture type decision is taken by the Encoder
|
||||
|
|
@ -1560,7 +1648,6 @@ typedef struct _NV_ENC_PIC_PARAMS_HEVC
|
|||
void* reserved3[61]; /**< [in]: Reserved and must be set to NULL. */
|
||||
} NV_ENC_PIC_PARAMS_HEVC;
|
||||
|
||||
|
||||
/**
|
||||
* Codec specific per-picture encoding parameters.
|
||||
*/
|
||||
|
|
@ -1599,7 +1686,11 @@ typedef struct _NV_ENC_PIC_PARAMS
|
|||
+ 4*meHintCountsPerBlock[Lx].numCandsPerBlk8x8. For frames using bidirectional ME , the total number of candidates for single macroblock is sum of total number of candidates per MB for each direction (L0 and L1) */
|
||||
uint32_t reserved1[6]; /**< [in]: Reserved and must be set to 0 */
|
||||
void* reserved2[2]; /**< [in]: Reserved and must be set to NULL */
|
||||
int8_t *qpDeltaMap; /**< [in]: Specifies the pointer to signed byte array containing QP delta value per MB in raster scan order in the current picture. This QP modifier is applied on top of the QP chosen by rate control. */
|
||||
int8_t *qpDeltaMap; /**< [in]: Specifies the pointer to signed byte array containing value per MB in raster scan order for the current picture, which will be Interperated depending on NV_ENC_RC_PARAMS::qpMapMode.
|
||||
If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DELTA , This specify QP modifier to be applied on top of the QP chosen by rate control.
|
||||
If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_EMPHASIS, it specifies emphasis level map per MB. This level value along with QP chosen by rate control is used to compute the QP modifier,
|
||||
which in turn is applied on top of QP chosen by rate control.
|
||||
If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DISABLED value in qpDeltaMap will be ignored.*/
|
||||
uint32_t qpDeltaMapSize; /**< [in]: Specifies the size in bytes of qpDeltaMap surface allocated by client and pointed to by NV_ENC_PIC_PARAMS::qpDeltaMap. Surface (array) should be picWidthInMbs * picHeightInMbs */
|
||||
uint32_t reservedBitFields; /**< [in]: Reserved bitfields and must be set to 0 */
|
||||
uint16_t meHintRefPicDist[2]; /**< [in]: Specifies temporal distance for reference picture (NVENC_EXTERNAL_ME_HINT::refidx = 0) used during external ME with NV_ENC_INITALIZE_PARAMS::enablePTD = 1 . meHintRefPicDist[0] is for L0 hints and meHintRefPicDist[1] is for L1 hints.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
#include <util/threading.h>
|
||||
#include "ffmpeg-mux/ffmpeg-mux.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "util/windows/win-version.h"
|
||||
#endif
|
||||
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
#define do_log(level, format, ...) \
|
||||
|
|
@ -109,13 +113,9 @@ static void *ffmpeg_mux_create(obs_data_t *settings, obs_output_t *output)
|
|||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN64
|
||||
#define FFMPEG_MUX "ffmpeg-mux64.exe"
|
||||
#define FFMPEG_MUX "obs-ffmpeg-mux.exe"
|
||||
#else
|
||||
#define FFMPEG_MUX "ffmpeg-mux32.exe"
|
||||
#endif
|
||||
#else
|
||||
#define FFMPEG_MUX "ffmpeg-mux"
|
||||
#define FFMPEG_MUX "obs-ffmpeg-mux"
|
||||
#endif
|
||||
|
||||
static inline bool capturing(struct ffmpeg_muxer *stream)
|
||||
|
|
@ -237,7 +237,7 @@ static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd,
|
|||
num_tracks++;
|
||||
}
|
||||
|
||||
dstr_init_move_array(cmd, obs_module_file(FFMPEG_MUX));
|
||||
dstr_init_move_array(cmd, os_get_executable_path_ptr(FFMPEG_MUX));
|
||||
dstr_insert_ch(cmd, 0, '\"');
|
||||
dstr_cat(cmd, "\" \"");
|
||||
|
||||
|
|
@ -290,6 +290,16 @@ static bool ffmpeg_mux_start(void *data)
|
|||
struct dstr error_message;
|
||||
dstr_init_copy(&error_message,
|
||||
obs_module_text("UnableToWritePath"));
|
||||
#ifdef _WIN32
|
||||
// special warning for Windows 10 users about Defender
|
||||
struct win_version_info ver;
|
||||
get_win_ver(&ver);
|
||||
if (ver.major >= 10) {
|
||||
dstr_cat(&error_message, "\n\n");
|
||||
dstr_cat(&error_message,
|
||||
obs_module_text("WarnWindowsDefender"));
|
||||
}
|
||||
#endif
|
||||
dstr_replace(&error_message, "%1", path);
|
||||
obs_output_set_last_error(stream->output,
|
||||
error_message.array);
|
||||
|
|
@ -321,7 +331,7 @@ static bool ffmpeg_mux_start(void *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int deactivate(struct ffmpeg_muxer *stream)
|
||||
static int deactivate(struct ffmpeg_muxer *stream, int code)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
|
|
@ -335,8 +345,11 @@ static int deactivate(struct ffmpeg_muxer *stream)
|
|||
info("Output of file '%s' stopped", stream->path.array);
|
||||
}
|
||||
|
||||
if (stopping(stream))
|
||||
if (code) {
|
||||
obs_output_signal_stop(stream->output, code);
|
||||
} else if (stopping(stream)) {
|
||||
obs_output_end_data_capture(stream->output);
|
||||
}
|
||||
|
||||
os_atomic_set_bool(&stream->stopping, false);
|
||||
return ret;
|
||||
|
|
@ -355,9 +368,23 @@ static void ffmpeg_mux_stop(void *data, uint64_t ts)
|
|||
|
||||
static void signal_failure(struct ffmpeg_muxer *stream)
|
||||
{
|
||||
int ret = deactivate(stream);
|
||||
char error[1024];
|
||||
int ret;
|
||||
int code;
|
||||
|
||||
size_t len;
|
||||
|
||||
len = os_process_pipe_read_err(stream->pipe, (uint8_t *)error,
|
||||
sizeof(error) - 1);
|
||||
|
||||
if (len > 0) {
|
||||
error[len] = 0;
|
||||
warn ("ffmpeg-mux: %s", error);
|
||||
obs_output_set_last_error (stream->output, error);
|
||||
}
|
||||
|
||||
ret = deactivate(stream, 0);
|
||||
|
||||
switch (ret) {
|
||||
case FFM_UNSUPPORTED: code = OBS_OUTPUT_UNSUPPORTED; break;
|
||||
default: code = OBS_OUTPUT_ERROR;
|
||||
|
|
@ -455,6 +482,12 @@ static void ffmpeg_mux_data(void *data, struct encoder_packet *packet)
|
|||
if (!active(stream))
|
||||
return;
|
||||
|
||||
/* encoder failure */
|
||||
if (!packet) {
|
||||
deactivate(stream, OBS_OUTPUT_ENCODE_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!stream->sent_headers) {
|
||||
if (!send_headers(stream))
|
||||
return;
|
||||
|
|
@ -464,7 +497,7 @@ static void ffmpeg_mux_data(void *data, struct encoder_packet *packet)
|
|||
|
||||
if (stopping(stream)) {
|
||||
if (packet->sys_dts_usec >= stream->stop_ts) {
|
||||
deactivate(stream);
|
||||
deactivate(stream, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -779,10 +812,13 @@ static void replay_buffer_save(struct ffmpeg_muxer *stream)
|
|||
replay_buffer_mux_thread, stream) == 0;
|
||||
}
|
||||
|
||||
static void deactivate_replay_buffer(struct ffmpeg_muxer *stream)
|
||||
static void deactivate_replay_buffer(struct ffmpeg_muxer *stream, int code)
|
||||
{
|
||||
if (stopping(stream))
|
||||
if (code) {
|
||||
obs_output_signal_stop(stream->output, code);
|
||||
} else if (stopping(stream)) {
|
||||
obs_output_end_data_capture(stream->output);
|
||||
}
|
||||
|
||||
os_atomic_set_bool(&stream->active, false);
|
||||
os_atomic_set_bool(&stream->sent_headers, false);
|
||||
|
|
@ -798,9 +834,15 @@ static void replay_buffer_data(void *data, struct encoder_packet *packet)
|
|||
if (!active(stream))
|
||||
return;
|
||||
|
||||
/* encoder failure */
|
||||
if (!packet) {
|
||||
deactivate_replay_buffer(stream, OBS_OUTPUT_ENCODE_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stopping(stream)) {
|
||||
if (packet->sys_dts_usec >= stream->stop_ts) {
|
||||
deactivate_replay_buffer(stream);
|
||||
deactivate_replay_buffer(stream, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ struct nvenc_encoder {
|
|||
static const char *nvenc_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
return "NVENC H.264";
|
||||
return "NVIDIA NVENC H.264";
|
||||
}
|
||||
|
||||
static inline bool valid_format(enum video_format format)
|
||||
|
|
@ -134,8 +134,6 @@ static bool nvenc_update(void *data, obs_data_t *settings)
|
|||
int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
|
||||
const char *preset = obs_data_get_string(settings, "preset");
|
||||
const char *profile = obs_data_get_string(settings, "profile");
|
||||
const char *level = obs_data_get_string(settings, "level");
|
||||
bool twopass = obs_data_get_bool(settings, "2pass");
|
||||
int gpu = (int)obs_data_get_int(settings, "gpu");
|
||||
bool cbr_override = obs_data_get_bool(settings, "cbr");
|
||||
int bf = (int)obs_data_get_int(settings, "bf");
|
||||
|
|
@ -158,6 +156,13 @@ static bool nvenc_update(void *data, obs_data_t *settings)
|
|||
info.colorspace = voi->colorspace;
|
||||
info.range = voi->range;
|
||||
|
||||
bool twopass = false;
|
||||
|
||||
if (astrcmpi(preset, "mq") == 0) {
|
||||
twopass = true;
|
||||
preset = "hq";
|
||||
}
|
||||
|
||||
nvenc_video_info(enc, &info);
|
||||
av_opt_set_int(enc->context->priv_data, "cbr", false, 0);
|
||||
av_opt_set(enc->context->priv_data, "profile", profile, 0);
|
||||
|
|
@ -185,7 +190,7 @@ static bool nvenc_update(void *data, obs_data_t *settings)
|
|||
}
|
||||
|
||||
|
||||
av_opt_set(enc->context->priv_data, "level", level, 0);
|
||||
av_opt_set(enc->context->priv_data, "level", "auto", 0);
|
||||
av_opt_set_int(enc->context->priv_data, "2pass", twopass, 0);
|
||||
av_opt_set_int(enc->context->priv_data, "gpu", gpu, 0);
|
||||
|
||||
|
|
@ -216,14 +221,13 @@ static bool nvenc_update(void *data, obs_data_t *settings)
|
|||
"\tkeyint: %d\n"
|
||||
"\tpreset: %s\n"
|
||||
"\tprofile: %s\n"
|
||||
"\tlevel: %s\n"
|
||||
"\twidth: %d\n"
|
||||
"\theight: %d\n"
|
||||
"\t2-pass: %s\n"
|
||||
"\tb-frames: %d\n"
|
||||
"\tGPU: %d\n",
|
||||
rc, bitrate, cqp, enc->context->gop_size,
|
||||
preset, profile, level,
|
||||
preset, profile,
|
||||
enc->context->width, enc->context->height,
|
||||
twopass ? "true" : "false",
|
||||
enc->context->max_b_frames,
|
||||
|
|
@ -390,16 +394,16 @@ static bool nvenc_encode(void *data, struct encoder_frame *frame,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void nvenc_defaults(obs_data_t *settings)
|
||||
void nvenc_defaults(obs_data_t *settings)
|
||||
{
|
||||
obs_data_set_default_int(settings, "bitrate", 2500);
|
||||
obs_data_set_default_int(settings, "max_bitrate", 5000);
|
||||
obs_data_set_default_int(settings, "keyint_sec", 0);
|
||||
obs_data_set_default_int(settings, "cqp", 23);
|
||||
obs_data_set_default_int(settings, "cqp", 20);
|
||||
obs_data_set_default_string(settings, "rate_control", "CBR");
|
||||
obs_data_set_default_string(settings, "preset", "default");
|
||||
obs_data_set_default_string(settings, "profile", "main");
|
||||
obs_data_set_default_string(settings, "level", "auto");
|
||||
obs_data_set_default_bool(settings, "2pass", true);
|
||||
obs_data_set_default_string(settings, "preset", "hq");
|
||||
obs_data_set_default_string(settings, "profile", "high");
|
||||
obs_data_set_default_bool(settings, "psycho_aq", true);
|
||||
obs_data_set_default_int(settings, "gpu", 0);
|
||||
obs_data_set_default_int(settings, "bf", 2);
|
||||
}
|
||||
|
|
@ -409,11 +413,14 @@ static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
|
|||
{
|
||||
const char *rc = obs_data_get_string(settings, "rate_control");
|
||||
bool cqp = astrcmpi(rc, "CQP") == 0;
|
||||
bool vbr = astrcmpi(rc, "VBR") == 0;
|
||||
bool lossless = astrcmpi(rc, "lossless") == 0;
|
||||
size_t count;
|
||||
|
||||
p = obs_properties_get(ppts, "bitrate");
|
||||
obs_property_set_visible(p, !cqp && !lossless);
|
||||
p = obs_properties_get(ppts, "max_bitrate");
|
||||
obs_property_set_visible(p, vbr);
|
||||
p = obs_properties_get(ppts, "cqp");
|
||||
obs_property_set_visible(p, cqp);
|
||||
|
||||
|
|
@ -421,17 +428,15 @@ static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
|
|||
count = obs_property_list_item_count(p);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
bool compatible = (i == 0 || i == 2);
|
||||
bool compatible = (i == 0 || i == 3);
|
||||
obs_property_list_item_disable(p, i, lossless && !compatible);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static obs_properties_t *nvenc_properties(void *unused)
|
||||
obs_properties_t *nvenc_properties_internal(bool ffmpeg)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
|
||||
obs_properties_t *props = obs_properties_create();
|
||||
obs_property_t *p;
|
||||
|
||||
|
|
@ -439,17 +444,22 @@ static obs_properties_t *nvenc_properties(void *unused)
|
|||
obs_module_text("RateControl"),
|
||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
|
||||
obs_property_list_add_string(p, "CBR", "CBR");
|
||||
obs_property_list_add_string(p, "VBR", "VBR");
|
||||
obs_property_list_add_string(p, "CQP", "CQP");
|
||||
obs_property_list_add_string(p, "VBR", "VBR");
|
||||
obs_property_list_add_string(p, obs_module_text("Lossless"),
|
||||
"lossless");
|
||||
|
||||
obs_property_set_modified_callback(p, rate_control_modified);
|
||||
|
||||
obs_properties_add_int(props, "bitrate",
|
||||
p = obs_properties_add_int(props, "bitrate",
|
||||
obs_module_text("Bitrate"), 50, 300000, 50);
|
||||
obs_property_int_set_suffix(p, " Kbps");
|
||||
p = obs_properties_add_int(props, "max_bitrate",
|
||||
obs_module_text("MaxBitrate"), 50, 300000, 50);
|
||||
obs_property_int_set_suffix(p, " Kbps");
|
||||
|
||||
obs_properties_add_int(props, "cqp", "CQP", 0, 50, 1);
|
||||
obs_properties_add_int(props, "cqp", obs_module_text("NVENC.CQLevel"),
|
||||
1, 30, 1);
|
||||
|
||||
obs_properties_add_int(props, "keyint_sec",
|
||||
obs_module_text("KeyframeIntervalSec"), 0, 10, 1);
|
||||
|
|
@ -460,10 +470,10 @@ static obs_properties_t *nvenc_properties(void *unused)
|
|||
#define add_preset(val) \
|
||||
obs_property_list_add_string(p, obs_module_text("NVENC.Preset." val), \
|
||||
val)
|
||||
add_preset("default");
|
||||
add_preset("mq");
|
||||
add_preset("hq");
|
||||
add_preset("default");
|
||||
add_preset("hp");
|
||||
add_preset("bd");
|
||||
add_preset("ll");
|
||||
add_preset("llhq");
|
||||
add_preset("llhp");
|
||||
|
|
@ -477,38 +487,20 @@ static obs_properties_t *nvenc_properties(void *unused)
|
|||
add_profile("high");
|
||||
add_profile("main");
|
||||
add_profile("baseline");
|
||||
add_profile("high444p");
|
||||
|
||||
p = obs_properties_add_list(props, "level",
|
||||
obs_module_text("NVENC.Level"), OBS_COMBO_TYPE_LIST,
|
||||
OBS_COMBO_FORMAT_STRING);
|
||||
add_profile("auto");
|
||||
add_profile("1" );
|
||||
add_profile("1.0" );
|
||||
add_profile("1b" );
|
||||
add_profile("1.0b");
|
||||
add_profile("1.1" );
|
||||
add_profile("1.2" );
|
||||
add_profile("1.3" );
|
||||
add_profile("2" );
|
||||
add_profile("2.0" );
|
||||
add_profile("2.1" );
|
||||
add_profile("2.2" );
|
||||
add_profile("3" );
|
||||
add_profile("3.0" );
|
||||
add_profile("3.1" );
|
||||
add_profile("3.2" );
|
||||
add_profile("4" );
|
||||
add_profile("4.0" );
|
||||
add_profile("4.1" );
|
||||
add_profile("4.2" );
|
||||
add_profile("5" );
|
||||
add_profile("5.0" );
|
||||
add_profile("5.1" );
|
||||
#undef add_profile
|
||||
|
||||
obs_properties_add_bool(props, "2pass",
|
||||
obs_module_text("NVENC.Use2Pass"));
|
||||
if (!ffmpeg) {
|
||||
p = obs_properties_add_bool(props, "lookahead",
|
||||
obs_module_text("NVENC.LookAhead"));
|
||||
obs_property_set_long_description(p,
|
||||
obs_module_text("NVENC.LookAhead.ToolTip"));
|
||||
|
||||
p = obs_properties_add_bool(props, "psycho_aq",
|
||||
obs_module_text("NVENC.PsychoVisualTuning"));
|
||||
obs_property_set_long_description(p,
|
||||
obs_module_text("NVENC.PsychoVisualTuning.ToolTip"));
|
||||
}
|
||||
|
||||
obs_properties_add_int(props, "gpu", obs_module_text("GPU"), 0, 8, 1);
|
||||
|
||||
obs_properties_add_int(props, "bf", obs_module_text("BFrames"),
|
||||
|
|
@ -517,6 +509,18 @@ static obs_properties_t *nvenc_properties(void *unused)
|
|||
return props;
|
||||
}
|
||||
|
||||
obs_properties_t *nvenc_properties(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
return nvenc_properties_internal(false);
|
||||
}
|
||||
|
||||
obs_properties_t *nvenc_properties_ffmpeg(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
return nvenc_properties_internal(true);
|
||||
}
|
||||
|
||||
static bool nvenc_extra_data(void *data, uint8_t **extra_data, size_t *size)
|
||||
{
|
||||
struct nvenc_encoder *enc = data;
|
||||
|
|
@ -544,7 +548,7 @@ struct obs_encoder_info nvenc_encoder_info = {
|
|||
.destroy = nvenc_destroy,
|
||||
.encode = nvenc_encode,
|
||||
.get_defaults = nvenc_defaults,
|
||||
.get_properties = nvenc_properties,
|
||||
.get_properties = nvenc_properties_ffmpeg,
|
||||
.get_extra_data = nvenc_extra_data,
|
||||
.get_sei_data = nvenc_sei_data,
|
||||
.get_video_info = nvenc_video_info
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ struct ffmpeg_cfg {
|
|||
int audio_encoder_id;
|
||||
const char *video_settings;
|
||||
const char *audio_settings;
|
||||
int audio_mix_count;
|
||||
int audio_tracks;
|
||||
enum AVPixelFormat format;
|
||||
enum AVColorRange color_range;
|
||||
enum AVColorSpace color_space;
|
||||
|
|
@ -56,7 +58,7 @@ struct ffmpeg_cfg {
|
|||
|
||||
struct ffmpeg_data {
|
||||
AVStream *video;
|
||||
AVStream *audio;
|
||||
AVStream **audio_streams;
|
||||
AVCodec *acodec;
|
||||
AVCodec *vcodec;
|
||||
AVFormatContext *output;
|
||||
|
|
@ -68,18 +70,24 @@ struct ffmpeg_data {
|
|||
|
||||
uint64_t start_timestamp;
|
||||
|
||||
int64_t total_samples;
|
||||
int64_t total_samples[MAX_AUDIO_MIXES];
|
||||
uint32_t audio_samplerate;
|
||||
enum audio_format audio_format;
|
||||
size_t audio_planes;
|
||||
size_t audio_size;
|
||||
struct circlebuf excess_frames[MAX_AV_PLANES];
|
||||
uint8_t *samples[MAX_AV_PLANES];
|
||||
AVFrame *aframe;
|
||||
int num_audio_streams;
|
||||
|
||||
/* audio_tracks is a bitmask storing the indices of the mixes */
|
||||
int audio_tracks;
|
||||
struct circlebuf excess_frames[MAX_AUDIO_MIXES][MAX_AV_PLANES];
|
||||
uint8_t *samples[MAX_AUDIO_MIXES][MAX_AV_PLANES];
|
||||
AVFrame *aframe[MAX_AUDIO_MIXES];
|
||||
|
||||
struct ffmpeg_cfg config;
|
||||
|
||||
bool initialized;
|
||||
|
||||
char *last_error;
|
||||
};
|
||||
|
||||
struct ffmpeg_output {
|
||||
|
|
@ -108,6 +116,30 @@ struct ffmpeg_output {
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void ffmpeg_output_set_last_error(struct ffmpeg_data *data,
|
||||
const char *error)
|
||||
{
|
||||
if (data->last_error)
|
||||
bfree(data->last_error);
|
||||
|
||||
data->last_error = bstrdup(error);
|
||||
}
|
||||
|
||||
void ffmpeg_log_error(int log_level, struct ffmpeg_data *data,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char out[4096];
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(out, sizeof(out), format, args);
|
||||
va_end(args);
|
||||
|
||||
ffmpeg_output_set_last_error(data, out);
|
||||
|
||||
blog(log_level, "%s", out);
|
||||
}
|
||||
|
||||
static bool new_stream(struct ffmpeg_data *data, AVStream **stream,
|
||||
AVCodec **codec, enum AVCodecID id, const char *name)
|
||||
{
|
||||
|
|
@ -116,14 +148,14 @@ static bool new_stream(struct ffmpeg_data *data, AVStream **stream,
|
|||
avcodec_find_encoder(id);
|
||||
|
||||
if (!*codec) {
|
||||
blog(LOG_WARNING, "Couldn't find encoder '%s'",
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Couldn't find encoder '%s'",
|
||||
avcodec_get_name(id));
|
||||
return false;
|
||||
}
|
||||
|
||||
*stream = avformat_new_stream(data->output, *codec);
|
||||
if (!*stream) {
|
||||
blog(LOG_WARNING, "Couldn't create stream for encoder '%s'",
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Couldn't create stream for encoder '%s'",
|
||||
avcodec_get_name(id));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -180,14 +212,14 @@ static bool open_video_codec(struct ffmpeg_data *data)
|
|||
|
||||
ret = avcodec_open2(context, data->vcodec, NULL);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "Failed to open video codec: %s",
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Failed to open video codec: %s",
|
||||
av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
data->vframe = av_frame_alloc();
|
||||
if (!data->vframe) {
|
||||
blog(LOG_WARNING, "Failed to allocate video frame");
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate video frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +231,7 @@ static bool open_video_codec(struct ffmpeg_data *data)
|
|||
|
||||
ret = av_frame_get_buffer(data->vframe, base_get_alignment());
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "Failed to allocate vframe: %s",
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate vframe: %s",
|
||||
av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -217,7 +249,7 @@ static bool init_swscale(struct ffmpeg_data *data, AVCodecContext *context)
|
|||
SWS_BICUBIC, NULL, NULL, NULL);
|
||||
|
||||
if (!data->swscale) {
|
||||
blog(LOG_WARNING, "Could not initialize swscale");
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Could not initialize swscale");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +263,7 @@ static bool create_video_stream(struct ffmpeg_data *data)
|
|||
struct obs_video_info ovi;
|
||||
|
||||
if (!obs_get_video_info(&ovi)) {
|
||||
blog(LOG_WARNING, "No active video");
|
||||
ffmpeg_log_error(LOG_WARNING, data, "No active video");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -273,9 +305,9 @@ static bool create_video_stream(struct ffmpeg_data *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool open_audio_codec(struct ffmpeg_data *data)
|
||||
static bool open_audio_codec(struct ffmpeg_data *data, int idx)
|
||||
{
|
||||
AVCodecContext *context = data->audio->codec;
|
||||
AVCodecContext *context = data->audio_streams[idx]->codec;
|
||||
char **opts = strlist_split(data->config.audio_settings, ' ', false);
|
||||
int ret;
|
||||
|
||||
|
|
@ -284,32 +316,32 @@ static bool open_audio_codec(struct ffmpeg_data *data)
|
|||
strlist_free(opts);
|
||||
}
|
||||
|
||||
data->aframe = av_frame_alloc();
|
||||
if (!data->aframe) {
|
||||
blog(LOG_WARNING, "Failed to allocate audio frame");
|
||||
data->aframe[idx] = av_frame_alloc();
|
||||
if (!data->aframe[idx]) {
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate audio frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
data->aframe->format = context->sample_fmt;
|
||||
data->aframe->channels = context->channels;
|
||||
data->aframe->channel_layout = context->channel_layout;
|
||||
data->aframe->sample_rate = context->sample_rate;
|
||||
data->aframe[idx]->format = context->sample_fmt;
|
||||
data->aframe[idx]->channels = context->channels;
|
||||
data->aframe[idx]->channel_layout = context->channel_layout;
|
||||
data->aframe[idx]->sample_rate = context->sample_rate;
|
||||
|
||||
context->strict_std_compliance = -2;
|
||||
|
||||
ret = avcodec_open2(context, data->acodec, NULL);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "Failed to open audio codec: %s",
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Failed to open audio codec: %s",
|
||||
av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
data->frame_size = context->frame_size ? context->frame_size : 1024;
|
||||
|
||||
ret = av_samples_alloc(data->samples, NULL, context->channels,
|
||||
ret = av_samples_alloc(data->samples[idx], NULL, context->channels,
|
||||
data->frame_size, context->sample_fmt, 0);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "Failed to create audio buffer: %s",
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Failed to create audio buffer: %s",
|
||||
av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -317,27 +349,29 @@ static bool open_audio_codec(struct ffmpeg_data *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool create_audio_stream(struct ffmpeg_data *data)
|
||||
static bool create_audio_stream(struct ffmpeg_data *data, int idx)
|
||||
{
|
||||
AVCodecContext *context;
|
||||
AVStream *stream;
|
||||
struct obs_audio_info aoi;
|
||||
|
||||
if (!obs_get_audio_info(&aoi)) {
|
||||
blog(LOG_WARNING, "No active audio");
|
||||
ffmpeg_log_error(LOG_WARNING, data, "No active audio");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!new_stream(data, &data->audio, &data->acodec,
|
||||
if (!new_stream(data, &stream, &data->acodec,
|
||||
data->output->oformat->audio_codec,
|
||||
data->config.audio_encoder))
|
||||
return false;
|
||||
|
||||
context = data->audio->codec;
|
||||
context->bit_rate = data->config.audio_bitrate * 1000;
|
||||
context->time_base = (AVRational){ 1, aoi.samples_per_sec };
|
||||
context->channels = get_audio_channels(aoi.speakers);
|
||||
context->sample_rate = aoi.samples_per_sec;
|
||||
context->channel_layout =
|
||||
data->audio_streams[idx] = stream;
|
||||
context = data->audio_streams[idx]->codec;
|
||||
context->bit_rate = data->config.audio_bitrate * 1000;
|
||||
context->time_base = (AVRational){ 1, aoi.samples_per_sec };
|
||||
context->channels = get_audio_channels(aoi.speakers);
|
||||
context->sample_rate = aoi.samples_per_sec;
|
||||
context->channel_layout =
|
||||
av_get_default_channel_layout(context->channels);
|
||||
|
||||
//AVlib default channel layout for 5 channels is 5.0 ; fix for 4.1
|
||||
|
|
@ -347,7 +381,7 @@ static bool create_audio_stream(struct ffmpeg_data *data)
|
|||
context->sample_fmt = data->acodec->sample_fmts ?
|
||||
data->acodec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
||||
|
||||
data->audio->time_base = context->time_base;
|
||||
data->audio_streams[idx]->time_base = context->time_base;
|
||||
|
||||
data->audio_samplerate = aoi.samples_per_sec;
|
||||
data->audio_format = convert_ffmpeg_sample_format(context->sample_fmt);
|
||||
|
|
@ -357,7 +391,7 @@ static bool create_audio_stream(struct ffmpeg_data *data)
|
|||
if (data->output->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
context->flags |= CODEC_FLAG_GLOBAL_H;
|
||||
|
||||
return open_audio_codec(data);
|
||||
return open_audio_codec(data, idx);
|
||||
}
|
||||
|
||||
static inline bool init_streams(struct ffmpeg_data *data)
|
||||
|
|
@ -368,9 +402,14 @@ static inline bool init_streams(struct ffmpeg_data *data)
|
|||
if (!create_video_stream(data))
|
||||
return false;
|
||||
|
||||
if (format->audio_codec != AV_CODEC_ID_NONE)
|
||||
if (!create_audio_stream(data))
|
||||
return false;
|
||||
if (format->audio_codec != AV_CODEC_ID_NONE && data->num_audio_streams) {
|
||||
data->audio_streams = calloc(1,
|
||||
data->num_audio_streams * sizeof(void*));
|
||||
for (int i = 0; i < data->num_audio_streams; i++) {
|
||||
if (!create_audio_stream(data, i))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -383,7 +422,7 @@ static inline bool open_output_file(struct ffmpeg_data *data)
|
|||
AVDictionary *dict = NULL;
|
||||
if ((ret = av_dict_parse_string(&dict, data->config.muxer_settings,
|
||||
"=", " ", 0))) {
|
||||
blog(LOG_WARNING, "Failed to parse muxer settings: %s\n%s",
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Failed to parse muxer settings: %s\n%s",
|
||||
av_err2str(ret), data->config.muxer_settings);
|
||||
|
||||
av_dict_free(&dict);
|
||||
|
|
@ -406,8 +445,9 @@ static inline bool open_output_file(struct ffmpeg_data *data)
|
|||
ret = avio_open2(&data->output->pb, data->config.url,
|
||||
AVIO_FLAG_WRITE, NULL, &dict);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "Couldn't open '%s', %s",
|
||||
data->config.url, av_err2str(ret));
|
||||
ffmpeg_log_error(LOG_WARNING, data,
|
||||
"Couldn't open '%s', %s", data->config.url,
|
||||
av_err2str(ret));
|
||||
av_dict_free(&dict);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -419,7 +459,7 @@ static inline bool open_output_file(struct ffmpeg_data *data)
|
|||
|
||||
ret = avformat_write_header(data->output, &dict);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "Error opening '%s': %s",
|
||||
ffmpeg_log_error(LOG_WARNING, data, "Error opening '%s': %s",
|
||||
data->config.url, av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -457,12 +497,17 @@ static void close_video(struct ffmpeg_data *data)
|
|||
|
||||
static void close_audio(struct ffmpeg_data *data)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_AV_PLANES; i++)
|
||||
circlebuf_free(&data->excess_frames[i]);
|
||||
for (int idx = 0; idx < data->num_audio_streams; idx++) {
|
||||
for (size_t i = 0; i < MAX_AV_PLANES; i++)
|
||||
circlebuf_free(&data->excess_frames[idx][i]);
|
||||
|
||||
av_freep(&data->samples[0]);
|
||||
avcodec_close(data->audio->codec);
|
||||
av_frame_free(&data->aframe);
|
||||
if (data->samples[idx][0])
|
||||
av_freep(&data->samples[idx][0]);
|
||||
if (data->audio_streams[idx])
|
||||
avcodec_close(data->audio_streams[idx]->codec);
|
||||
if (data->aframe[idx])
|
||||
av_frame_free(&data->aframe[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
static void ffmpeg_data_free(struct ffmpeg_data *data)
|
||||
|
|
@ -472,8 +517,11 @@ static void ffmpeg_data_free(struct ffmpeg_data *data)
|
|||
|
||||
if (data->video)
|
||||
close_video(data);
|
||||
if (data->audio)
|
||||
if (data->audio_streams) {
|
||||
close_audio(data);
|
||||
free(data->audio_streams);
|
||||
data->audio_streams = NULL;
|
||||
}
|
||||
|
||||
if (data->output) {
|
||||
if ((data->output->oformat->flags & AVFMT_NOFILE) == 0)
|
||||
|
|
@ -482,6 +530,9 @@ static void ffmpeg_data_free(struct ffmpeg_data *data)
|
|||
avformat_free_context(data->output);
|
||||
}
|
||||
|
||||
if (data->last_error)
|
||||
bfree(data->last_error);
|
||||
|
||||
memset(data, 0, sizeof(struct ffmpeg_data));
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +579,8 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data,
|
|||
|
||||
memset(data, 0, sizeof(struct ffmpeg_data));
|
||||
data->config = *config;
|
||||
|
||||
data->num_audio_streams = config->audio_mix_count;
|
||||
data->audio_tracks = config->audio_tracks;
|
||||
if (!config->url || !*config->url)
|
||||
return false;
|
||||
|
||||
|
|
@ -543,19 +595,27 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data,
|
|||
is_rtmp ? NULL : data->config.format_mime_type);
|
||||
|
||||
if (output_format == NULL) {
|
||||
blog(LOG_WARNING, "Couldn't find matching output format with "
|
||||
" parameters: name=%s, url=%s, mime=%s",
|
||||
safe_str(is_rtmp ?
|
||||
"flv" : data->config.format_name),
|
||||
safe_str(data->config.url),
|
||||
safe_str(is_rtmp ?
|
||||
NULL : data->config.format_mime_type));
|
||||
ffmpeg_log_error(LOG_WARNING, data,
|
||||
"Couldn't find matching output format with "
|
||||
"parameters: name=%s, url=%s, mime=%s",
|
||||
safe_str(is_rtmp ?
|
||||
"flv" : data->config.format_name),
|
||||
safe_str(data->config.url),
|
||||
safe_str(is_rtmp ?
|
||||
NULL : data->config.format_mime_type));
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
avformat_alloc_output_context2(&data->output, output_format,
|
||||
NULL, NULL);
|
||||
|
||||
if (!data->output) {
|
||||
ffmpeg_log_error(LOG_WARNING, data,
|
||||
"Couldn't create avformat context");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (is_rtmp) {
|
||||
data->output->oformat->video_codec = AV_CODEC_ID_H264;
|
||||
data->output->oformat->audio_codec = AV_CODEC_ID_AAC;
|
||||
|
|
@ -564,11 +624,6 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data,
|
|||
set_encoder_ids(data);
|
||||
}
|
||||
|
||||
if (!data->output) {
|
||||
blog(LOG_WARNING, "Couldn't create avformat context");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!init_streams(data))
|
||||
goto fail;
|
||||
if (!open_output_file(data))
|
||||
|
|
@ -581,7 +636,6 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data,
|
|||
|
||||
fail:
|
||||
blog(LOG_WARNING, "ffmpeg_data_init failed");
|
||||
ffmpeg_data_free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -736,6 +790,7 @@ static void receive_video(void *param, struct video_data *frame)
|
|||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "receive_video: Error encoding "
|
||||
"video: %s", av_err2str(ret));
|
||||
//FIXME: stop the encode with an error
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -761,12 +816,13 @@ static void receive_video(void *param, struct video_data *frame)
|
|||
if (ret != 0) {
|
||||
blog(LOG_WARNING, "receive_video: Error writing video: %s",
|
||||
av_err2str(ret));
|
||||
//FIXME: stop the encode with an error
|
||||
}
|
||||
|
||||
data->total_frames++;
|
||||
}
|
||||
|
||||
static void encode_audio(struct ffmpeg_output *output,
|
||||
static void encode_audio(struct ffmpeg_output *output, int idx,
|
||||
struct AVCodecContext *context, size_t block_size)
|
||||
{
|
||||
struct ffmpeg_data *data = &output->ff_data;
|
||||
|
|
@ -775,24 +831,25 @@ static void encode_audio(struct ffmpeg_output *output,
|
|||
int ret, got_packet;
|
||||
size_t total_size = data->frame_size * block_size * context->channels;
|
||||
|
||||
data->aframe->nb_samples = data->frame_size;
|
||||
data->aframe->pts = av_rescale_q(data->total_samples,
|
||||
data->aframe[idx]->nb_samples = data->frame_size;
|
||||
data->aframe[idx]->pts = av_rescale_q(data->total_samples[idx],
|
||||
(AVRational){1, context->sample_rate},
|
||||
context->time_base);
|
||||
|
||||
ret = avcodec_fill_audio_frame(data->aframe, context->channels,
|
||||
context->sample_fmt, data->samples[0],
|
||||
ret = avcodec_fill_audio_frame(data->aframe[idx], context->channels,
|
||||
context->sample_fmt, data->samples[idx][0],
|
||||
(int)total_size, 1);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "encode_audio: avcodec_fill_audio_frame "
|
||||
"failed: %s", av_err2str(ret));
|
||||
//FIXME: stop the encode with an error
|
||||
return;
|
||||
}
|
||||
|
||||
data->total_samples += data->frame_size;
|
||||
data->total_samples[idx] += data->frame_size;
|
||||
|
||||
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101)
|
||||
ret = avcodec_send_frame(context, data->aframe);
|
||||
ret = avcodec_send_frame(context, data->aframe[idx]);
|
||||
if (ret == 0)
|
||||
ret = avcodec_receive_packet(context, &packet);
|
||||
|
||||
|
|
@ -801,23 +858,26 @@ static void encode_audio(struct ffmpeg_output *output,
|
|||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
|
||||
ret = 0;
|
||||
#else
|
||||
ret = avcodec_encode_audio2(context, &packet, data->aframe,
|
||||
ret = avcodec_encode_audio2(context, &packet, data->aframe[idx],
|
||||
&got_packet);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "encode_audio: Error encoding audio: %s",
|
||||
av_err2str(ret));
|
||||
//FIXME: stop the encode with an error
|
||||
return;
|
||||
}
|
||||
|
||||
if (!got_packet)
|
||||
return;
|
||||
|
||||
packet.pts = rescale_ts(packet.pts, context, data->audio->time_base);
|
||||
packet.dts = rescale_ts(packet.dts, context, data->audio->time_base);
|
||||
packet.pts = rescale_ts(packet.pts, context,
|
||||
data->audio_streams[idx]->time_base);
|
||||
packet.dts = rescale_ts(packet.dts, context,
|
||||
data->audio_streams[idx]->time_base);
|
||||
packet.duration = (int)av_rescale_q(packet.duration, context->time_base,
|
||||
data->audio->time_base);
|
||||
packet.stream_index = data->audio->index;
|
||||
data->audio_streams[idx]->time_base);
|
||||
packet.stream_index = data->audio_streams[idx]->index;
|
||||
|
||||
pthread_mutex_lock(&output->write_mutex);
|
||||
da_push_back(output->packets, &packet);
|
||||
|
|
@ -853,18 +913,38 @@ static bool prepare_audio(struct ffmpeg_data *data,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void receive_audio(void *param, struct audio_data *frame)
|
||||
/* Given a bitmask for the selected tracks and the mix index,
|
||||
* this returns the stream index which will be passed to the muxer. */
|
||||
static int get_track_order(int track_config, size_t mix_index)
|
||||
{
|
||||
int position = 0;
|
||||
for (size_t i = 0; i < mix_index; i++) {
|
||||
if (track_config & 1 << i)
|
||||
position++;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
static void receive_audio(void *param, size_t mix_idx, struct audio_data *frame)
|
||||
{
|
||||
struct ffmpeg_output *output = param;
|
||||
struct ffmpeg_data *data = &output->ff_data;
|
||||
size_t frame_size_bytes;
|
||||
struct audio_data in;
|
||||
int track_order;
|
||||
|
||||
// codec doesn't support audio or none configured
|
||||
if (!data->audio)
|
||||
if (!data->audio_streams)
|
||||
return;
|
||||
|
||||
AVCodecContext *context = data->audio->codec;
|
||||
/* check that the track was selected */
|
||||
if ((data->audio_tracks & (1 << mix_idx)) == 0)
|
||||
return;
|
||||
|
||||
/* get track order (first selected, etc ...) */
|
||||
track_order = get_track_order(data->audio_tracks, mix_idx);
|
||||
|
||||
AVCodecContext *context = data->audio_streams[track_order]->codec;
|
||||
|
||||
if (!data->start_timestamp)
|
||||
return;
|
||||
|
|
@ -877,15 +957,16 @@ static void receive_audio(void *param, struct audio_data *frame)
|
|||
frame_size_bytes = (size_t)data->frame_size * data->audio_size;
|
||||
|
||||
for (size_t i = 0; i < data->audio_planes; i++)
|
||||
circlebuf_push_back(&data->excess_frames[i], in.data[i],
|
||||
in.frames * data->audio_size);
|
||||
circlebuf_push_back(&data->excess_frames[track_order][i],
|
||||
in.data[i], in.frames * data->audio_size);
|
||||
|
||||
while (data->excess_frames[0].size >= frame_size_bytes) {
|
||||
while (data->excess_frames[track_order][0].size >= frame_size_bytes) {
|
||||
for (size_t i = 0; i < data->audio_planes; i++)
|
||||
circlebuf_pop_front(&data->excess_frames[i],
|
||||
data->samples[i], frame_size_bytes);
|
||||
circlebuf_pop_front(&data->excess_frames[track_order][i],
|
||||
data->samples[track_order][i],
|
||||
frame_size_bytes);
|
||||
|
||||
encode_audio(output, context, data->audio_size);
|
||||
encode_audio(output, track_order, context, data->audio_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -901,7 +982,7 @@ static uint64_t get_packet_sys_dts(struct ffmpeg_output *output,
|
|||
time_base = data->video->time_base;
|
||||
start_ts = output->video_start_ts;
|
||||
} else {
|
||||
time_base = data->audio->time_base;
|
||||
time_base = data->audio_streams[0]->time_base;
|
||||
start_ts = output->audio_start_ts;
|
||||
}
|
||||
|
||||
|
|
@ -944,8 +1025,9 @@ static int process_packet(struct ffmpeg_output *output)
|
|||
ret = av_interleaved_write_frame(output->ff_data.output, &packet);
|
||||
if (ret < 0) {
|
||||
av_free_packet(&packet);
|
||||
blog(LOG_WARNING, "receive_audio: Error writing packet: %s",
|
||||
av_err2str(ret));
|
||||
ffmpeg_log_error(LOG_WARNING, &output->ff_data,
|
||||
"receive_audio: Error writing packet: %s",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -990,6 +1072,18 @@ static inline const char *get_string_or_null(obs_data_t *settings,
|
|||
return value;
|
||||
}
|
||||
|
||||
static int get_audio_mix_count(int audio_mix_mask)
|
||||
{
|
||||
int mix_count = 0;
|
||||
for (int i = 0; i < MAX_AUDIO_MIXES; i++) {
|
||||
if ((audio_mix_mask & (1 << i)) != 0) {
|
||||
mix_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return mix_count;
|
||||
}
|
||||
|
||||
static bool try_connect(struct ffmpeg_output *output)
|
||||
{
|
||||
video_t *video = obs_output_video(output->output);
|
||||
|
|
@ -1025,6 +1119,8 @@ static bool try_connect(struct ffmpeg_output *output)
|
|||
config.height = (int)obs_output_get_height(output->output);
|
||||
config.format = obs_to_ffmpeg_video_format(
|
||||
video_output_get_format(video));
|
||||
config.audio_tracks = (int)obs_output_get_mixers(output->output);
|
||||
config.audio_mix_count = get_audio_mix_count(config.audio_tracks);
|
||||
|
||||
if (format_is_yuv(voi->format)) {
|
||||
config.color_range = voi->range == VIDEO_RANGE_FULL ?
|
||||
|
|
@ -1049,8 +1145,14 @@ static bool try_connect(struct ffmpeg_output *output)
|
|||
success = ffmpeg_data_init(&output->ff_data, &config);
|
||||
obs_data_release(settings);
|
||||
|
||||
if (!success)
|
||||
if (!success) {
|
||||
if (output->ff_data.last_error) {
|
||||
obs_output_set_last_error(output->output,
|
||||
output->ff_data.last_error);
|
||||
}
|
||||
ffmpeg_data_free(&output->ff_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct audio_convert_info aci = {
|
||||
.format = output->ff_data.audio_format
|
||||
|
|
@ -1063,8 +1165,9 @@ static bool try_connect(struct ffmpeg_output *output)
|
|||
|
||||
ret = pthread_create(&output->write_thread, NULL, write_thread, output);
|
||||
if (ret != 0) {
|
||||
blog(LOG_WARNING, "ffmpeg_output_start: failed to create write "
|
||||
"thread.");
|
||||
ffmpeg_log_error(LOG_WARNING, &output->ff_data,
|
||||
"ffmpeg_output_start: failed to create write "
|
||||
"thread.");
|
||||
ffmpeg_output_full_stop(output);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1157,13 +1260,15 @@ static uint64_t ffmpeg_output_total_bytes(void *data)
|
|||
|
||||
struct obs_output_info ffmpeg_output = {
|
||||
.id = "ffmpeg_output",
|
||||
.flags = OBS_OUTPUT_AUDIO | OBS_OUTPUT_VIDEO,
|
||||
.flags = OBS_OUTPUT_AUDIO |
|
||||
OBS_OUTPUT_VIDEO |
|
||||
OBS_OUTPUT_MULTI_TRACK,
|
||||
.get_name = ffmpeg_output_getname,
|
||||
.create = ffmpeg_output_create,
|
||||
.destroy = ffmpeg_output_destroy,
|
||||
.start = ffmpeg_output_start,
|
||||
.stop = ffmpeg_output_stop,
|
||||
.raw_video = receive_video,
|
||||
.raw_audio = receive_audio,
|
||||
.raw_audio2 = receive_audio,
|
||||
.get_total_bytes = ffmpeg_output_total_bytes,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data)
|
|||
obs_properties_add_bool(props, "restart_on_activate",
|
||||
obs_module_text("RestartWhenActivated"));
|
||||
|
||||
obs_properties_add_int_slider(props, "buffering_mb",
|
||||
obs_module_text("BufferingMB"),
|
||||
1, 16, 1);
|
||||
|
||||
obs_properties_add_text(props, "input",
|
||||
obs_module_text("Input"), OBS_TEXT_DEFAULT);
|
||||
|
||||
|
|
|
|||
539
plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
Normal file
539
plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
/******************************************************************************
|
||||
Copyright (C) 2016 by Hugh Bailey <obs.jim@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#include <libavutil/avutil.h>
|
||||
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 27, 100)
|
||||
|
||||
#include <util/darray.h>
|
||||
#include <util/dstr.h>
|
||||
#include <util/base.h>
|
||||
#include <media-io/video-io.h>
|
||||
#include <obs-module.h>
|
||||
#include <obs-avc.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavfilter/avfilter.h>
|
||||
|
||||
#include "obs-ffmpeg-formats.h"
|
||||
|
||||
#define do_log(level, format, ...) \
|
||||
blog(level, "[FFMPEG VAAPI encoder: '%s'] " format, \
|
||||
obs_encoder_get_name(enc->encoder), ##__VA_ARGS__)
|
||||
|
||||
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
|
||||
struct vaapi_encoder {
|
||||
obs_encoder_t *encoder;
|
||||
|
||||
AVBufferRef *vadevice_ref;
|
||||
AVBufferRef *vaframes_ref;
|
||||
|
||||
AVCodec * vaapi;
|
||||
AVCodecContext *context;
|
||||
|
||||
AVFrame *vframe;
|
||||
|
||||
DARRAY(uint8_t) buffer;
|
||||
|
||||
uint8_t *header;
|
||||
size_t header_size;
|
||||
|
||||
uint8_t *sei;
|
||||
size_t sei_size;
|
||||
|
||||
int height;
|
||||
bool first_packet;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
static const char *vaapi_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
return "FFMPEG VAAPI";
|
||||
}
|
||||
|
||||
static inline bool valid_format(enum video_format format)
|
||||
{
|
||||
return format == VIDEO_FORMAT_NV12;
|
||||
}
|
||||
|
||||
static void vaapi_video_info(void *data, struct video_scale_info *info)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
enum video_format pref_format;
|
||||
|
||||
pref_format = obs_encoder_get_preferred_video_format(enc->encoder);
|
||||
|
||||
if (!valid_format(pref_format)) {
|
||||
pref_format = valid_format(info->format) ? info->format
|
||||
: VIDEO_FORMAT_NV12;
|
||||
}
|
||||
|
||||
info->format = pref_format;
|
||||
}
|
||||
|
||||
static bool vaapi_init_codec(struct vaapi_encoder *enc, const char *path)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = av_hwdevice_ctx_create(&enc->vadevice_ref, AV_HWDEVICE_TYPE_VAAPI,
|
||||
path, NULL, 0);
|
||||
if (ret < 0) {
|
||||
warn("Failed to create VAAPI device context: %s",
|
||||
av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
enc->vaframes_ref = av_hwframe_ctx_alloc(enc->vadevice_ref);
|
||||
if (!enc->vaframes_ref) {
|
||||
warn("Failed to alloc HW frames context");
|
||||
return false;
|
||||
}
|
||||
|
||||
AVHWFramesContext *frames_ctx =
|
||||
(AVHWFramesContext *)enc->vaframes_ref->data;
|
||||
frames_ctx->format = AV_PIX_FMT_VAAPI;
|
||||
frames_ctx->sw_format = AV_PIX_FMT_NV12;
|
||||
frames_ctx->width = enc->context->width;
|
||||
frames_ctx->height = enc->context->height;
|
||||
frames_ctx->initial_pool_size = 20;
|
||||
|
||||
ret = av_hwframe_ctx_init(enc->vaframes_ref);
|
||||
if (ret < 0) {
|
||||
warn("Failed to init HW frames context: %s", av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 2. Create software frame and picture */
|
||||
enc->vframe = av_frame_alloc();
|
||||
if (!enc->vframe) {
|
||||
warn("Failed to allocate video frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
enc->vframe->format = enc->context->pix_fmt;
|
||||
enc->vframe->width = enc->context->width;
|
||||
enc->vframe->height = enc->context->height;
|
||||
enc->vframe->colorspace = enc->context->colorspace;
|
||||
enc->vframe->color_range = enc->context->color_range;
|
||||
|
||||
ret = av_frame_get_buffer(enc->vframe, base_get_alignment());
|
||||
if (ret < 0) {
|
||||
warn("Failed to allocate vframe: %s", av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 3. set up codec */
|
||||
enc->context->pix_fmt = AV_PIX_FMT_VAAPI;
|
||||
enc->context->hw_frames_ctx = av_buffer_ref(enc->vaframes_ref);
|
||||
|
||||
ret = avcodec_open2(enc->context, enc->vaapi, NULL);
|
||||
if (ret < 0) {
|
||||
warn("Failed to open VAAPI codec: %s", av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
enc->initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vaapi_update(void *data, obs_data_t *settings)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
|
||||
const char *device = obs_data_get_string(settings, "vaapi_device");
|
||||
|
||||
int profile = (int)obs_data_get_int(settings, "profile");
|
||||
int bf = (int)obs_data_get_int(settings, "bf");
|
||||
|
||||
int level = (int)obs_data_get_int(settings, "level");
|
||||
int bitrate = (int)obs_data_get_int(settings, "bitrate");
|
||||
int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
|
||||
|
||||
int qp = (int)obs_data_get_int(settings, "qp");
|
||||
int quality = (int)obs_data_get_int(settings, "quality");
|
||||
|
||||
av_opt_set_int(enc->context->priv_data, "qp", qp, 0);
|
||||
av_opt_set_int(enc->context->priv_data, "quality", quality, 0);
|
||||
|
||||
video_t * video = obs_encoder_video(enc->encoder);
|
||||
const struct video_output_info *voi = video_output_get_info(video);
|
||||
struct video_scale_info info;
|
||||
|
||||
info.format = voi->format;
|
||||
info.colorspace = voi->colorspace;
|
||||
info.range = voi->range;
|
||||
|
||||
vaapi_video_info(enc, &info);
|
||||
|
||||
enc->context->profile = profile;
|
||||
enc->context->max_b_frames = bf;
|
||||
enc->context->level = level;
|
||||
enc->context->bit_rate = bitrate * 1000;
|
||||
enc->context->rc_max_rate = bitrate * 1000;
|
||||
|
||||
enc->context->width = obs_encoder_get_width(enc->encoder);
|
||||
enc->context->height = obs_encoder_get_height(enc->encoder);
|
||||
|
||||
enc->context->time_base = (AVRational){voi->fps_den, voi->fps_num};
|
||||
enc->context->pix_fmt = obs_to_ffmpeg_video_format(info.format);
|
||||
enc->context->colorspace = info.colorspace == VIDEO_CS_709
|
||||
? AVCOL_SPC_BT709
|
||||
: AVCOL_SPC_BT470BG;
|
||||
enc->context->color_range = info.range == VIDEO_RANGE_FULL
|
||||
? AVCOL_RANGE_JPEG
|
||||
: AVCOL_RANGE_MPEG;
|
||||
|
||||
if (keyint_sec > 0) {
|
||||
enc->context->gop_size =
|
||||
keyint_sec * voi->fps_num / voi->fps_den;
|
||||
} else {
|
||||
enc->context->gop_size = 120;
|
||||
}
|
||||
|
||||
enc->height = enc->context->height;
|
||||
|
||||
info("settings:\n"
|
||||
"\tdevice: %s\n"
|
||||
"\tqp: %d\n"
|
||||
"\tquality: %d\n"
|
||||
"\tprofile: %d\n"
|
||||
"\tlevel: %d\n"
|
||||
"\tbitrate: %d\n"
|
||||
"\tkeyint: %d\n"
|
||||
"\twidth: %d\n"
|
||||
"\theight: %d\n"
|
||||
"\tb-frames: %d\n",
|
||||
device, qp, quality, profile, level, bitrate,
|
||||
enc->context->gop_size, enc->context->width,
|
||||
enc->context->height, enc->context->max_b_frames);
|
||||
|
||||
return vaapi_init_codec(enc, device);
|
||||
}
|
||||
|
||||
static void vaapi_destroy(void *data)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
|
||||
if (enc->initialized) {
|
||||
AVPacket pkt = {0};
|
||||
int r_pkt = 1;
|
||||
|
||||
while (r_pkt) {
|
||||
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101)
|
||||
if (avcodec_receive_packet(enc->context, &pkt) < 0)
|
||||
break;
|
||||
#else
|
||||
if (avcodec_encode_video2(enc->context, &pkt, NULL,
|
||||
&r_pkt) < 0)
|
||||
break;
|
||||
#endif
|
||||
|
||||
if (r_pkt)
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
avcodec_close(enc->context);
|
||||
av_frame_unref(enc->vframe);
|
||||
av_frame_free(&enc->vframe);
|
||||
av_buffer_unref(&enc->vaframes_ref);
|
||||
av_buffer_unref(&enc->vadevice_ref);
|
||||
da_free(enc->buffer);
|
||||
bfree(enc->header);
|
||||
bfree(enc->sei);
|
||||
|
||||
bfree(enc);
|
||||
}
|
||||
|
||||
static void *vaapi_create(obs_data_t *settings, obs_encoder_t *encoder)
|
||||
{
|
||||
struct vaapi_encoder *enc;
|
||||
avcodec_register_all();
|
||||
|
||||
enc = bzalloc(sizeof(*enc));
|
||||
enc->encoder = encoder;
|
||||
|
||||
int vaapi_codec = (int)obs_data_get_int(settings, "vaapi_codec");
|
||||
|
||||
if (vaapi_codec == AV_CODEC_ID_H264) {
|
||||
enc->vaapi = avcodec_find_encoder_by_name("h264_vaapi");
|
||||
}
|
||||
|
||||
enc->first_packet = true;
|
||||
|
||||
blog(LOG_INFO, "---------------------------------");
|
||||
|
||||
if (!enc->vaapi) {
|
||||
warn("Couldn't find encoder");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
enc->context = avcodec_alloc_context3(enc->vaapi);
|
||||
if (!enc->context) {
|
||||
warn("Failed to create codec context");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!vaapi_update(enc, settings))
|
||||
goto fail;
|
||||
|
||||
return enc;
|
||||
|
||||
fail:
|
||||
vaapi_destroy(enc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void copy_data(AVFrame *pic, const struct encoder_frame *frame,
|
||||
int height, enum AVPixelFormat format)
|
||||
{
|
||||
int h_chroma_shift, v_chroma_shift;
|
||||
av_pix_fmt_get_chroma_sub_sample(
|
||||
format, &h_chroma_shift, &v_chroma_shift);
|
||||
for (int plane = 0; plane < MAX_AV_PLANES; plane++) {
|
||||
if (!frame->data[plane])
|
||||
continue;
|
||||
|
||||
int frame_rowsize = (int)frame->linesize[plane];
|
||||
int pic_rowsize = pic->linesize[plane];
|
||||
int bytes = frame_rowsize < pic_rowsize ? frame_rowsize
|
||||
: pic_rowsize;
|
||||
int plane_height = height >> (plane ? v_chroma_shift : 0);
|
||||
|
||||
for (int y = 0; y < plane_height; y++) {
|
||||
int pos_frame = y * frame_rowsize;
|
||||
int pos_pic = y * pic_rowsize;
|
||||
|
||||
memcpy(pic->data[plane] + pos_pic,
|
||||
frame->data[plane] + pos_frame, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool vaapi_encode(void *data, struct encoder_frame *frame,
|
||||
struct encoder_packet *packet, bool *received_packet)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
AVFrame * hwframe = NULL;
|
||||
AVPacket av_pkt;
|
||||
int got_packet;
|
||||
int ret;
|
||||
|
||||
hwframe = av_frame_alloc();
|
||||
if (!hwframe) {
|
||||
warn("vaapi_encode: failed to allocate hw frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = av_hwframe_get_buffer(enc->vaframes_ref, hwframe, 0);
|
||||
if (ret < 0) {
|
||||
warn("vaapi_encode: failed to get buffer for hw frame: %s",
|
||||
av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
copy_data(enc->vframe, frame, enc->height, enc->context->pix_fmt);
|
||||
|
||||
enc->vframe->pts = frame->pts;
|
||||
hwframe->pts = frame->pts;
|
||||
hwframe->width = enc->vframe->width;
|
||||
hwframe->height = enc->vframe->height;
|
||||
|
||||
ret = av_hwframe_transfer_data(hwframe, enc->vframe, 0);
|
||||
if (ret < 0) {
|
||||
warn("vaapi_encode: failed to upload hw frame: %s",
|
||||
av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = av_frame_copy_props(hwframe, enc->vframe);
|
||||
if (ret < 0) {
|
||||
warn("vaapi_encode: failed to copy props to hw frame: %s",
|
||||
av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
av_init_packet(&av_pkt);
|
||||
|
||||
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101)
|
||||
ret = avcodec_send_frame(enc->context, hwframe);
|
||||
if (ret == 0)
|
||||
ret = avcodec_receive_packet(enc->context, &av_pkt);
|
||||
|
||||
got_packet = (ret == 0);
|
||||
|
||||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
|
||||
ret = 0;
|
||||
#else
|
||||
ret = avcodec_encode_video2(
|
||||
enc->context, &av_pkt, hwframe, &got_packet);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
warn("vaapi_encode: Error encoding: %s", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (got_packet && av_pkt.size) {
|
||||
if (enc->first_packet) {
|
||||
uint8_t *new_packet;
|
||||
size_t size;
|
||||
|
||||
enc->first_packet = false;
|
||||
obs_extract_avc_headers(av_pkt.data, av_pkt.size,
|
||||
&new_packet, &size, &enc->header,
|
||||
&enc->header_size, &enc->sei,
|
||||
&enc->sei_size);
|
||||
|
||||
da_copy_array(enc->buffer, new_packet, size);
|
||||
bfree(new_packet);
|
||||
} else {
|
||||
da_copy_array(enc->buffer, av_pkt.data, av_pkt.size);
|
||||
}
|
||||
|
||||
packet->pts = av_pkt.pts;
|
||||
packet->dts = av_pkt.dts;
|
||||
packet->data = enc->buffer.array;
|
||||
packet->size = enc->buffer.num;
|
||||
packet->type = OBS_ENCODER_VIDEO;
|
||||
packet->keyframe = obs_avc_keyframe(packet->data, packet->size);
|
||||
*received_packet = true;
|
||||
} else {
|
||||
*received_packet = false;
|
||||
}
|
||||
|
||||
av_packet_unref(&av_pkt);
|
||||
av_frame_free(&hwframe);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
av_frame_free(&hwframe);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void set_visible(obs_properties_t *ppts, const char *name, bool visible)
|
||||
{
|
||||
obs_property_t *p = obs_properties_get(ppts, name);
|
||||
obs_property_set_visible(p, visible);
|
||||
}
|
||||
|
||||
static void vaapi_defaults(obs_data_t *settings)
|
||||
{
|
||||
obs_data_set_default_string(
|
||||
settings, "vaapi_device", "/dev/dri/renderD128");
|
||||
obs_data_set_default_int(settings, "vaapi_codec", AV_CODEC_ID_H264);
|
||||
obs_data_set_default_int(settings, "profile",
|
||||
FF_PROFILE_H264_CONSTRAINED_BASELINE);
|
||||
obs_data_set_default_int(settings, "level", 40);
|
||||
obs_data_set_default_int(settings, "bitrate", 2500);
|
||||
obs_data_set_default_int(settings, "keyint_sec", 0);
|
||||
obs_data_set_default_int(settings, "bf", 0);
|
||||
obs_data_set_default_int(settings, "qp", 20);
|
||||
obs_data_set_default_int(settings, "quality", 0);
|
||||
obs_data_set_default_int(settings, "rendermode", 0);
|
||||
}
|
||||
|
||||
static obs_properties_t *vaapi_properties(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
|
||||
obs_properties_t *props = obs_properties_create();
|
||||
obs_property_t * list;
|
||||
|
||||
list = obs_properties_add_list(props, "vaapi_device", "VAAPI Device",
|
||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
|
||||
char path[32] = "/dev/dri/renderD1";
|
||||
for (int i = 28;; i++) {
|
||||
sprintf(path, "/dev/dri/renderD1%d", i);
|
||||
if (access(path, F_OK) == 0) {
|
||||
char card[128] = "Card: ";
|
||||
sprintf(card, "Card%d: %s", i - 28, path);
|
||||
obs_property_list_add_string(list, card, path);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list = obs_properties_add_list(props, "vaapi_codec", "VAAPI Codec",
|
||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||
|
||||
obs_property_list_add_int(list, "H.264 (default)", AV_CODEC_ID_H264);
|
||||
|
||||
list = obs_properties_add_list(props, "level", "Level",
|
||||
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
|
||||
obs_property_list_add_int(list, "480p30 (3.0)", 30);
|
||||
obs_property_list_add_int(list, "720p30/480p60 (3.1)", 31);
|
||||
obs_property_list_add_int(
|
||||
list, "Compatibility mode (4.0 default)", 40);
|
||||
obs_property_list_add_int(list, "720p60/1080p30 (4.1)", 41);
|
||||
obs_property_list_add_int(list, "1080p60 (4.2)", 42);
|
||||
|
||||
obs_property_t *p;
|
||||
p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 0,
|
||||
300000, 50);
|
||||
obs_property_int_set_suffix(p, " Kbps");
|
||||
|
||||
obs_properties_add_int(props, "keyint_sec",
|
||||
obs_module_text("Keyframe Interval (seconds)"), 0, 20,
|
||||
1);
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
static bool vaapi_extra_data(void *data, uint8_t **extra_data, size_t *size)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
|
||||
*extra_data = enc->header;
|
||||
*size = enc->header_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vaapi_sei_data(void *data, uint8_t **extra_data, size_t *size)
|
||||
{
|
||||
struct vaapi_encoder *enc = data;
|
||||
|
||||
*extra_data = enc->sei;
|
||||
*size = enc->sei_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct obs_encoder_info vaapi_encoder_info = {
|
||||
.id = "ffmpeg_vaapi",
|
||||
.type = OBS_ENCODER_VIDEO,
|
||||
.codec = "h264",
|
||||
.get_name = vaapi_getname,
|
||||
.create = vaapi_create,
|
||||
.destroy = vaapi_destroy,
|
||||
.encode = vaapi_encode,
|
||||
.get_defaults = vaapi_defaults,
|
||||
.get_properties = vaapi_properties,
|
||||
.get_extra_data = vaapi_extra_data,
|
||||
.get_sei_data = vaapi_sei_data,
|
||||
.get_video_info = vaapi_video_info
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -2,12 +2,23 @@
|
|||
#include <util/darray.h>
|
||||
#include <util/platform.h>
|
||||
#include <libavutil/log.h>
|
||||
#include <libavutil/avutil.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <dxgi.h>
|
||||
#include <util/dstr.h>
|
||||
#include <util/windows/win-version.h>
|
||||
#endif
|
||||
|
||||
OBS_DECLARE_MODULE()
|
||||
OBS_MODULE_USE_DEFAULT_LOCALE("obs-ffmpeg", "en-US")
|
||||
MODULE_EXPORT const char *obs_module_description(void)
|
||||
{
|
||||
return "FFmpeg based sources/outputs/encoders";
|
||||
}
|
||||
|
||||
extern struct obs_source_info ffmpeg_source;
|
||||
extern struct obs_output_info ffmpeg_output;
|
||||
|
|
@ -17,6 +28,14 @@ extern struct obs_encoder_info aac_encoder_info;
|
|||
extern struct obs_encoder_info opus_encoder_info;
|
||||
extern struct obs_encoder_info nvenc_encoder_info;
|
||||
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 27, 100)
|
||||
#define LIBAVUTIL_VAAPI_AVAILABLE
|
||||
#endif
|
||||
|
||||
#ifdef LIBAVUTIL_VAAPI_AVAILABLE
|
||||
extern struct obs_encoder_info vaapi_encoder_info;
|
||||
#endif
|
||||
|
||||
static DARRAY(struct log_context {
|
||||
void *context;
|
||||
char str[4096];
|
||||
|
|
@ -121,6 +140,130 @@ cleanup:
|
|||
|
||||
static const char *nvenc_check_name = "nvenc_check";
|
||||
|
||||
#ifdef _WIN32
|
||||
static const wchar_t *blacklisted_adapters[] = {
|
||||
L"720M",
|
||||
L"730M",
|
||||
L"740M",
|
||||
L"745M",
|
||||
L"820M",
|
||||
L"830M",
|
||||
L"840M",
|
||||
L"845M",
|
||||
L"920M",
|
||||
L"930M",
|
||||
L"940M",
|
||||
L"945M",
|
||||
L"1030",
|
||||
L"MX110",
|
||||
L"MX130",
|
||||
L"MX150",
|
||||
L"MX230",
|
||||
L"MX250",
|
||||
L"M520",
|
||||
L"M500",
|
||||
L"P500",
|
||||
L"K620M"
|
||||
};
|
||||
|
||||
static const size_t num_blacklisted =
|
||||
sizeof(blacklisted_adapters) / sizeof(blacklisted_adapters[0]);
|
||||
|
||||
static bool is_adapter(const wchar_t *name, const wchar_t *adapter)
|
||||
{
|
||||
const wchar_t *find = wstrstri(name, adapter);
|
||||
if (!find) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check before string for potential numeric mismatch */
|
||||
if (find > name && iswdigit(find[-1]) && iswdigit(find[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check after string for potential numeric mismatch */
|
||||
size_t len = wcslen(adapter);
|
||||
if (iswdigit(find[len - 1]) && iswdigit(find[len])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_blacklisted(const wchar_t *name)
|
||||
{
|
||||
for (size_t i = 0; i < num_blacklisted; i++) {
|
||||
const wchar_t *blacklisted_adapter = blacklisted_adapters[i];
|
||||
if (is_adapter(name, blacklisted_adapter)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef HRESULT (WINAPI *create_dxgi_proc)(const IID *, IDXGIFactory1 **);
|
||||
|
||||
static bool nvenc_device_available(void)
|
||||
{
|
||||
static HMODULE dxgi = NULL;
|
||||
static create_dxgi_proc create = NULL;
|
||||
IDXGIFactory1 *factory;
|
||||
IDXGIAdapter1 *adapter;
|
||||
bool available = false;
|
||||
HRESULT hr;
|
||||
UINT i = 0;
|
||||
|
||||
if (!dxgi) {
|
||||
dxgi = GetModuleHandleW(L"dxgi");
|
||||
if (!dxgi) {
|
||||
dxgi = LoadLibraryW(L"dxgi");
|
||||
if (!dxgi) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!create) {
|
||||
create = (create_dxgi_proc)GetProcAddress(dxgi,
|
||||
"CreateDXGIFactory1");
|
||||
if (!create) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
hr = create(&IID_IDXGIFactory1, &factory);
|
||||
if (FAILED(hr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while (factory->lpVtbl->EnumAdapters1(factory, i++, &adapter) == S_OK) {
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
|
||||
hr = adapter->lpVtbl->GetDesc(adapter, &desc);
|
||||
adapter->lpVtbl->Release(adapter);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wstrstri(desc.Description, L"nvidia") &&
|
||||
!is_blacklisted(desc.Description)) {
|
||||
available = true;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
factory->lpVtbl->Release(factory);
|
||||
return available;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
extern bool load_nvenc_lib(void);
|
||||
#endif
|
||||
|
||||
static bool nvenc_supported(void)
|
||||
{
|
||||
av_register_all();
|
||||
|
|
@ -136,10 +279,12 @@ static bool nvenc_supported(void)
|
|||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (sizeof(void*) == 8) {
|
||||
lib = os_dlopen("nvEncodeAPI64.dll");
|
||||
} else {
|
||||
lib = os_dlopen("nvEncodeAPI.dll");
|
||||
if (!nvenc_device_available()) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (load_nvenc_lib()) {
|
||||
success = true;
|
||||
goto finish;
|
||||
}
|
||||
#else
|
||||
lib = os_dlopen("libnvidia-encode.so.1");
|
||||
|
|
@ -152,12 +297,28 @@ static bool nvenc_supported(void)
|
|||
cleanup:
|
||||
if (lib)
|
||||
os_dlclose(lib);
|
||||
#if defined(_WIN32)
|
||||
finish:
|
||||
#endif
|
||||
profile_end(nvenc_check_name);
|
||||
return success;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LIBAVUTIL_VAAPI_AVAILABLE
|
||||
static bool vaapi_supported(void)
|
||||
{
|
||||
AVCodec *vaenc = avcodec_find_encoder_by_name("h264_vaapi");
|
||||
return !!vaenc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
extern void jim_nvenc_load(void);
|
||||
extern void jim_nvenc_unload(void);
|
||||
#endif
|
||||
|
||||
bool obs_module_load(void)
|
||||
{
|
||||
da_init(active_log_contexts);
|
||||
|
|
@ -174,8 +335,19 @@ bool obs_module_load(void)
|
|||
#ifndef __APPLE__
|
||||
if (nvenc_supported()) {
|
||||
blog(LOG_INFO, "NVENC supported");
|
||||
#ifdef _WIN32
|
||||
if (get_win_ver_int() > 0x0601) {
|
||||
jim_nvenc_load();
|
||||
}
|
||||
#endif
|
||||
obs_register_encoder(&nvenc_encoder_info);
|
||||
}
|
||||
#if !defined(_WIN32) && defined(LIBAVUTIL_VAAPI_AVAILABLE)
|
||||
if (vaapi_supported()) {
|
||||
blog(LOG_INFO, "FFMPEG VAAPI supported");
|
||||
obs_register_encoder(&vaapi_encoder_info);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
|
@ -197,4 +369,8 @@ void obs_module_unload(void)
|
|||
|
||||
da_free(active_log_contexts);
|
||||
da_free(cached_log_contexts);
|
||||
|
||||
#ifdef _WIN32
|
||||
jim_nvenc_unload();
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue