New upstream version 0.15.4+dfsg1

This commit is contained in:
Sebastian Ramacher 2016-08-28 14:07:43 +02:00
parent 55d5047af0
commit 67704ac59c
359 changed files with 8423 additions and 1050 deletions

View file

@ -2,11 +2,11 @@ FFmpegOutput="FFmpeg ulostulo"
FFmpegAAC="FFmpeg oletus AAC-enkooderi"
Bitrate="Bitrate"
Preset="Esiasetus"
RateControl="Nopeudensäädin"
KeyframeIntervalSec="Keyframe-väli (sec, 0=auto)"
RateControl="Rate Control -tila"
KeyframeIntervalSec="Keyframe-väli (sekunteina, 0=automaattinen)"
Lossless="Häviötön"
NVENC.Use2Pass="Käytä kaksivaiheista enkoodausta"
NVENC.Use2Pass="Käytä Two-Pass enkoodausta"
NVENC.Preset.default="Oletusarvo"
NVENC.Preset.hq="Korkea laatu"
NVENC.Preset.hp="Korkea suorituskyky"
@ -22,7 +22,7 @@ Looping="Toista jatkuvasti"
Input="Sisääntulo"
InputFormat="Sisääntulon muoto"
ForceFormat="Pakota muodon muuntaminen"
HardwareDecode="Käytä laitteistoa purkamiseen, kun mahdollista"
HardwareDecode="Käytä laitteistotason purkua, kun mahdollista"
ClearOnMediaEnd="Piilota lähde kun toisto päättyy"
Advanced="Lisäasetukset"
AudioBufferSize="Äänipuskurin koko (ruutua)"

View file

@ -1,7 +1,20 @@
FFmpegOutput="פלט FFmpeg"
FFmpegAAC="FFmpeg מקודד AAC ברירת מחדל"
Bitrate="קצב ביטים"
Preset="קבוע מראש"
RateControl="בקרת קצב"
KeyframeIntervalSec="מרווח ערך ה keyframe בשניות (0=אוטומטי)"
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,6 +36,10 @@ DiscardNonIntra="פריימים לא ביינים"
DiscardNonKey="מסגרות שאינן מפתח"
DiscardAll="כל הפריימים (זהירות!)"
RestartWhenActivated="הפעל מחדש השמעה כאשר מקור הופך לפעיל"
ColorRange="טווח צבעים YUV"
ColorRange.Auto="אוטומטי"
ColorRange.Partial="חלקי"
ColorRange.Full="מלא"
MediaFileFilter.AllMediaFiles="כל קבצי המדיה"

View file

@ -2,7 +2,9 @@ FFmpegOutput="FFmpeg izlaz"
FFmpegAAC="FFmpeg podrazumevani AAC enkoder"
Bitrate="Protok"
Preset="Šablon"
RateControl="Kontrola protoka"
KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)"
Lossless="Bez gubitka"
NVENC.Use2Pass="Koristi enkoding duplog prolaza"
NVENC.Preset.default="Podrazumevani"

View file

@ -1,7 +1,20 @@
FFmpegOutput="Uscita FFmpeg"
FFmpegAAC="Codificatore FFmpeg predefinito AAC"
Bitrate="Bitrate"
Preset="Preset"
RateControl="Controllo frequenza"
KeyframeIntervalSec="Intervallo Keyframe (secondi, 0=automatico)"
Lossless="Lossless"
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.Preset.ll="Bassa latenza"
NVENC.Preset.llhq="Bassa latenza Alta Qualità"
NVENC.Preset.llhp="Bassa latenza ad Alte Prestazioni"
NVENC.Level="Livello"
FFmpegSource="Origine multimediale"
LocalFile="File locale"
@ -23,6 +36,14 @@ DiscardNonIntra="Frame non interposti"
DiscardNonKey="Frame non di chiave"
DiscardAll="Tutti i Frame (opzione per utenti più esperti)"
RestartWhenActivated="Riattiva playback quando la fonte torna attiva"
ColorRange="Gamma di colore YUV"
ColorRange.Auto="Autom."
ColorRange.Partial="Parziale"
ColorRange.Full="Intero"
MediaFileFilter.AllMediaFiles="Tutti i file media"
MediaFileFilter.VideoFiles="File video"
MediaFileFilter.AudioFiles="File audio"
MediaFileFilter.AllFiles="Tutti i file"

View file

@ -1,13 +1,26 @@
FFmpegOutput="FFmpeg utdata"
FFmpegAAC="Standard FFmpeg AAC-koder"
Bitrate="Bitrate"
Preset="Forhåndsinnstilling"
RateControl="Hastighetskontroll"
KeyframeIntervalSec="Nøkkelbildeintervall (sekunder, 0 = automatisk)"
Lossless="Tapsfri"
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.ll="Lav latens"
NVENC.Preset.llhq="Lav latens, høy kvalitet"
NVENC.Preset.llhp="Lav latens, høy ytelse"
NVENC.Level="Nivå"
FFmpegSource="Mediekilde"
LocalFile="Lokal fil"
Looping="Repeter"
Input="Inndata"
InputFormat="Inndataformat"
Input="Inngang"
InputFormat="Inngangsformat"
ForceFormat="Tving formatkonvertering"
HardwareDecode="Bruk maskinvaredekoding når tilgjengelig"
ClearOnMediaEnd="Skjul kilde når avspilling ender"
@ -22,6 +35,15 @@ DiscardBiDir="Toveisbilder"
DiscardNonIntra="Non-intra bilder"
DiscardNonKey="Ikkenøkkelbilder"
DiscardAll="Alle bilder (forsiktig!)"
RestartWhenActivated="Start avspilling omigjen når kilde blir aktiv"
ColorRange="YUV fargerom"
ColorRange.Auto="Automatisk"
ColorRange.Partial="Delvis"
ColorRange.Full="Hel"
MediaFileFilter.AllMediaFiles="Alle mediefiler"
MediaFileFilter.VideoFiles="Videofiler"
MediaFileFilter.AudioFiles="Lydfiler"
MediaFileFilter.AllFiles="Alle filer"

View file

@ -2,7 +2,9 @@ FFmpegOutput="Wyjście FFmpeg"
FFmpegAAC="Domyślny enkoder AAC w FFmpeg"
Bitrate="Przepływność bitowa"
Preset="Profil ustawień"
RateControl="Typ przepływności"
KeyframeIntervalSec="Odstęp między klatkami kluczowymi (sekundy, 0=automatyczny)"
Lossless="Bezstratny"
NVENC.Use2Pass="Użyj enkodowania dwuprzebiegowego"
NVENC.Preset.default="Domyślny"

View file

@ -1,7 +1,19 @@
FFmpegOutput="Saída do FFmpeg"
FFmpegAAC="Codificador AAC Padrão do FFmpeg"
Bitrate="Taxa de Bits"
Preset="Predefinição"
RateControl="Controle de Taxa"
KeyframeIntervalSec="Intervalo do keyframe (segundos, 0=automático)"
Lossless="Sem perdas"
NVENC.Preset.default="Predefinido"
NVENC.Preset.hq="Alta Qualidade"
NVENC.Preset.hp="Alto Desempenho"
NVENC.Preset.bd="Bluray"
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 mídia"
LocalFile="Arquivo Local"

View file

@ -1,7 +1,19 @@
FFmpegOutput="Saída de FFmpeg"
FFmpegAAC="Codificador AAC padrão do FFmpeg"
Bitrate="Bitrate"
Preset="Predefinição"
RateControl="Controle de Taxa"
KeyframeIntervalSec="Intervalo do keyframe (segundos, 0=automático)"
Lossless="Sem perdas"
NVENC.Preset.default="Predefinido"
NVENC.Preset.hq="Alta Qualidade"
NVENC.Preset.hp="Alto Desempenho"
NVENC.Preset.bd="Bluray"
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,6 +34,15 @@ DiscardBiDir="Fotogramas bidirecionais"
DiscardNonIntra="Fotogramas não internos"
DiscardNonKey="Fotogramas não registados"
DiscardAll="Todos os fotogramas (cuidado!)"
RestartWhenActivated="Reiniciar reprodução quando a fonte se torna ativo"
ColorRange="Gama de cor YUV"
ColorRange.Auto="Auto"
ColorRange.Partial="Parcial"
ColorRange.Full="Completo"
MediaFileFilter.AllMediaFiles="Todos os Arquivos de Media"
MediaFileFilter.VideoFiles="Arquivos de Vídeo"
MediaFileFilter.AudioFiles="Arquivos de Áudio"
MediaFileFilter.AllFiles="Todos os ficheiros"

View file

@ -2,7 +2,9 @@ FFmpegOutput="Вывод FFmpeg"
FFmpegAAC="Стандартный AAC-кодер FFmpeg"
Bitrate="Битрейт"
Preset="Пресет"
RateControl="Управление битрейтом"
KeyframeIntervalSec="Интервал ключевых кадров (сек, 0=авто)"
Lossless="Без потерь"
NVENC.Use2Pass="Использовать двухпроходное кодирование"
NVENC.Preset.default="По умолчанию"

View file

@ -2,7 +2,9 @@ FFmpegOutput="FFmpeg izlaz"
FFmpegAAC="FFmpeg podrazumevani AAC enkoder"
Bitrate="Protok"
Preset="Šablon"
RateControl="Kontrola protoka"
KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)"
Lossless="Bez gubitka"
NVENC.Use2Pass="Koristi enkoding duplog prolaza"
NVENC.Preset.default="Podrazumevani"

View file

@ -2,7 +2,9 @@ FFmpegOutput="FFmpeg излаз"
FFmpegAAC="FFmpeg подразумевани AAC енкодер"
Bitrate="Проток"
Preset="Шаблон"
RateControl="Контрола протока"
KeyframeIntervalSec="Интервал кључних фрејмова (секунде, 0=аутоматски)"
Lossless="Без губитка"
NVENC.Use2Pass="Користи енкодинг дуплог пролаза"
NVENC.Preset.default="Подразумевани"

View file

@ -2,6 +2,8 @@ FFmpegOutput="FFmpeg-utmatning"
FFmpegAAC="AAC-kodare (FFmpeg standard)"
Bitrate="Bithastighet"
Preset="Förinställning"
RateControl="Hastighetskontroll"
Lossless="Förlustfri"
NVENC.Use2Pass="Använd tvåpassavkodning"
NVENC.Preset.default="Standard"

View file

@ -1,7 +1,20 @@
FFmpegOutput="FFmpeg 輸出"
FFmpegAAC="FFmpeg 預設 AAC 編碼器"
Bitrate="流量"
Bitrate="位元率"
Preset="預置"
RateControl="位元率控制"
KeyframeIntervalSec="關鍵訊框間隔 (秒0 = 自動)"
Lossless="無損"
NVENC.Use2Pass="使用 Two-Pass 編碼"
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="本機檔案"
@ -12,15 +25,21 @@ ForceFormat="強制格式轉換"
HardwareDecode="盡可能使用硬體解碼"
ClearOnMediaEnd="當播放結束時隱藏來源"
Advanced="進階"
AudioBufferSize="音訊緩衝區大小 ()"
VideoBufferSize="影像緩衝區大小 ()"
FrameDropping="掉幀程度"
AudioBufferSize="音訊緩衝區大小 (訊框)"
VideoBufferSize="影像緩衝區大小 (訊框)"
FrameDropping="丟棄訊框级别"
DiscardNone="無"
DiscardDefault="預設 (無效封包)"
DiscardNonRef="非參考幀"
DiscardNonIntra="非內部框架"
DiscardNonKey="非關鍵幀"
DiscardAll="所有幀(小心!)"
DiscardNonRef="非參考訊框"
DiscardBiDir="雙向訊框"
DiscardNonIntra="非內部訊框"
DiscardNonKey="非關鍵訊框"
DiscardAll="所有訊框(小心!)"
RestartWhenActivated="當來源可使用時重新播放"
ColorRange="YUV 色彩空間"
ColorRange.Auto="自動"
ColorRange.Partial="部分"
ColorRange.Full="全部"
MediaFileFilter.AllMediaFiles="所有媒體檔案"

View file

@ -19,6 +19,7 @@
#include <obs-avc.h>
#include <util/dstr.h>
#include <util/pipe.h>
#include <util/threading.h>
#include "ffmpeg-mux/ffmpeg-mux.h"
#include <libavformat/avformat.h>
@ -33,10 +34,12 @@
struct ffmpeg_muxer {
obs_output_t *output;
os_process_pipe_t *pipe;
int64_t stop_ts;
struct dstr path;
bool sent_headers;
bool active;
bool capturing;
volatile bool active;
volatile bool stopping;
volatile bool capturing;
};
static const char *ffmpeg_mux_getname(void *unused)
@ -72,6 +75,21 @@ static void *ffmpeg_mux_create(obs_data_t *settings, obs_output_t *output)
#define FFMPEG_MUX "ffmpeg-mux"
#endif
static inline bool capturing(struct ffmpeg_muxer *stream)
{
return os_atomic_load_bool(&stream->capturing);
}
static inline bool stopping(struct ffmpeg_muxer *stream)
{
return os_atomic_load_bool(&stream->stopping);
}
static inline bool active(struct ffmpeg_muxer *stream)
{
return os_atomic_load_bool(&stream->active);
}
/* TODO: allow codecs other than h264 whenever we start using them */
static void add_video_encoder_params(struct ffmpeg_muxer *stream,
@ -223,8 +241,8 @@ static bool ffmpeg_mux_start(void *data)
}
/* write headers and start capture */
stream->active = true;
stream->capturing = true;
os_atomic_set_bool(&stream->active, true);
os_atomic_set_bool(&stream->capturing, true);
obs_output_begin_data_capture(stream->output, 0);
info("Writing file '%s'...", stream->path.array);
@ -235,29 +253,32 @@ static int deactivate(struct ffmpeg_muxer *stream)
{
int ret = -1;
if (stream->active) {
if (active(stream)) {
ret = os_process_pipe_destroy(stream->pipe);
stream->pipe = NULL;
stream->active = false;
stream->sent_headers = false;
os_atomic_set_bool(&stream->active, false);
os_atomic_set_bool(&stream->sent_headers, false);
info("Output of file '%s' stopped", stream->path.array);
}
if (stopping(stream))
obs_output_end_data_capture(stream->output);
os_atomic_set_bool(&stream->stopping, false);
return ret;
}
static void ffmpeg_mux_stop(void *data)
static void ffmpeg_mux_stop(void *data, uint64_t ts)
{
struct ffmpeg_muxer *stream = data;
if (stream->capturing) {
obs_output_end_data_capture(stream->output);
stream->capturing = false;
if (capturing(stream)) {
stream->stop_ts = (int64_t)ts / 1000LL;
os_atomic_set_bool(&stream->stopping, true);
os_atomic_set_bool(&stream->capturing, false);
}
deactivate(stream);
}
static void signal_failure(struct ffmpeg_muxer *stream)
@ -271,7 +292,7 @@ static void signal_failure(struct ffmpeg_muxer *stream)
}
obs_output_signal_stop(stream->output, code);
stream->capturing = false;
os_atomic_set_bool(&stream->capturing, false);
}
static bool write_packet(struct ffmpeg_muxer *stream,
@ -358,7 +379,7 @@ static void ffmpeg_mux_data(void *data, struct encoder_packet *packet)
{
struct ffmpeg_muxer *stream = data;
if (!stream->active)
if (!active(stream))
return;
if (!stream->sent_headers) {
@ -368,6 +389,13 @@ static void ffmpeg_mux_data(void *data, struct encoder_packet *packet)
stream->sent_headers = true;
}
if (stopping(stream)) {
if (packet->sys_dts_usec >= stream->stop_ts) {
deactivate(stream);
return;
}
}
write_packet(stream, packet);
}

View file

@ -160,6 +160,8 @@ static bool nvenc_update(void *data, obs_data_t *settings)
nvenc_video_info(enc, &info);
av_opt_set_int(enc->context->priv_data, "cbr", false, 0);
av_opt_set(enc->context->priv_data, "preset", preset, 0);
if (astrcmpi(rc, "cqp") == 0) {
bitrate = 0;
enc->context->global_quality = cqp;
@ -171,7 +173,7 @@ static bool nvenc_update(void *data, obs_data_t *settings)
bool hp = (astrcmpi(preset, "hp") == 0 ||
astrcmpi(preset, "llhp") == 0);
av_opt_set(enc->context->priv_data, "profile",
av_opt_set(enc->context->priv_data, "preset",
hp ? "losslesshp" : "lossless", 0);
} else if (astrcmpi(rc, "vbr") != 0) { /* CBR by default */
@ -182,7 +184,6 @@ static bool nvenc_update(void *data, obs_data_t *settings)
}
av_opt_set(enc->context->priv_data, "preset", preset, 0);
av_opt_set(enc->context->priv_data, "level", level, 0);
av_opt_set_int(enc->context->priv_data, "2pass", twopass, 0);
av_opt_set_int(enc->context->priv_data, "gpu", gpu, 0);

View file

@ -89,6 +89,11 @@ struct ffmpeg_output {
bool connecting;
pthread_t start_thread;
uint64_t audio_start_ts;
uint64_t video_start_ts;
uint64_t stop_ts;
volatile bool stopping;
bool write_thread_active;
pthread_mutex_t write_mutex;
pthread_t write_thread;
@ -237,6 +242,7 @@ static bool create_video_stream(struct ffmpeg_data *data)
context->pix_fmt = closest_format;
context->colorspace = data->config.color_space;
context->color_range = data->config.color_range;
context->thread_count = 0;
data->video->time_base = context->time_base;
@ -548,6 +554,11 @@ fail:
/* ------------------------------------------------------------------------- */
static inline bool stopping(struct ffmpeg_output *output)
{
return os_atomic_load_bool(&output->stopping);
}
static const char *ffmpeg_output_getname(void *unused)
{
UNUSED_PARAMETER(unused);
@ -588,7 +599,7 @@ fail:
return NULL;
}
static void ffmpeg_output_stop(void *data);
static void ffmpeg_output_full_stop(void *data);
static void ffmpeg_deactivate(struct ffmpeg_output *output);
static void ffmpeg_output_destroy(void *data)
@ -599,7 +610,7 @@ static void ffmpeg_output_destroy(void *data)
if (output->connecting)
pthread_join(output->start_thread, NULL);
ffmpeg_output_stop(output);
ffmpeg_output_full_stop(output);
pthread_mutex_destroy(&output->write_mutex);
os_sem_destroy(output->write_sem);
@ -647,6 +658,8 @@ static void receive_video(void *param, struct video_data *frame)
av_init_packet(&packet);
if (!output->video_start_ts)
output->video_start_ts = frame->timestamp;
if (!data->start_timestamp)
data->start_timestamp = frame->timestamp;
@ -768,6 +781,8 @@ static bool prepare_audio(struct ffmpeg_data *data,
return false;
cutoff = data->start_timestamp - frame->timestamp;
output->timestamp += cutoff;
cutoff = cutoff * (uint64_t)data->audio_samplerate /
1000000000;
@ -797,6 +812,9 @@ static void receive_audio(void *param, struct audio_data *frame)
if (!prepare_audio(data, frame, &in))
return;
if (!output->audio_start_ts)
output->audio_start_ts = in.timestamp;
frame_size_bytes = (size_t)data->frame_size * data->audio_size;
for (size_t i = 0; i < data->audio_planes; i++)
@ -812,6 +830,26 @@ static void receive_audio(void *param, struct audio_data *frame)
}
}
static uint64_t get_packet_sys_dts(struct ffmpeg_output *output,
AVPacket *packet)
{
struct ffmpeg_data *data = &output->ff_data;
uint64_t start_ts;
AVRational time_base;
if (data->video && data->video->index == packet->stream_index) {
time_base = data->video->time_base;
start_ts = output->video_start_ts;
} else {
time_base = data->audio->time_base;
start_ts = output->audio_start_ts;
}
return start_ts + (uint64_t)av_rescale_q(packet->dts,
time_base, (AVRational){1, 1000000000});
}
static int process_packet(struct ffmpeg_output *output)
{
AVPacket packet;
@ -834,6 +872,14 @@ static int process_packet(struct ffmpeg_output *output)
packet.size, packet.flags,
packet.stream_index, output->packets.num);*/
if (stopping(output)) {
uint64_t sys_ts = get_packet_sys_dts(output, &packet);
if (sys_ts >= output->stop_ts) {
ffmpeg_output_full_stop(output);
return 0;
}
}
ret = av_interleaved_write_frame(output->ff_data.output, &packet);
if (ret < 0) {
av_free_packet(&packet);
@ -954,7 +1000,7 @@ static bool try_connect(struct ffmpeg_output *output)
if (ret != 0) {
blog(LOG_WARNING, "ffmpeg_output_start: failed to create write "
"thread.");
ffmpeg_output_stop(output);
ffmpeg_output_full_stop(output);
return false;
}
@ -985,11 +1031,15 @@ static bool ffmpeg_output_start(void *data)
if (output->connecting)
return false;
os_atomic_set_bool(&output->stopping, false);
output->audio_start_ts = 0;
output->video_start_ts = 0;
ret = pthread_create(&output->start_thread, NULL, start_thread, output);
return (output->connecting = (ret == 0));
}
static void ffmpeg_output_stop(void *data)
static void ffmpeg_output_full_stop(void *data)
{
struct ffmpeg_output *output = data;
@ -999,6 +1049,20 @@ static void ffmpeg_output_stop(void *data)
}
}
static void ffmpeg_output_stop(void *data, uint64_t ts)
{
struct ffmpeg_output *output = data;
if (output->active) {
if (ts == 0) {
ffmpeg_output_full_stop(output);
} else {
os_atomic_set_bool(&output->stopping, true);
output->stop_ts = ts;
}
}
}
static void ffmpeg_deactivate(struct ffmpeg_output *output)
{
if (output->write_thread_active) {