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

@ -1,10 +1,29 @@
project(obs-filters)
find_package(Libspeexdsp QUIET)
if(LIBSPEEXDSP_FOUND)
set(obs-filters_LIBSPEEXDSP_SOURCES
noise-suppress-filter.c)
set(obs-filters_LIBSPEEXDSP_LIBRARIES
${LIBSPEEXDSP_LIBRARIES})
else()
message(STATUS "Speexdsp library not found, speexdsp filters disabled")
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/obs-filters-config.h.in"
"${CMAKE_BINARY_DIR}/plugins/obs-filters/config/obs-filters-config.h")
set(obs-filters_config_HEADERS
"${CMAKE_BINARY_DIR}/plugins/obs-filters/config/obs-filters-config.h")
include_directories(${LIBSPEEXDSP_INCLUDE_DIRS}
"${CMAKE_BINARY_DIR}/plugins/obs-filters/config")
set(obs-filters_SOURCES
obs-filters.c
color-filter.c
async-delay-filter.c
crop-filter.c
scale-filter.c
scroll-filter.c
chroma-key-filter.c
color-key-filter.c
@ -14,8 +33,11 @@ set(obs-filters_SOURCES
mask-filter.c)
add_library(obs-filters MODULE
${obs-filters_SOURCES})
${obs-filters_SOURCES}
${obs-filters_config_HEADERS}
${obs-filters_LIBSPEEXDSP_SOURCES})
target_link_libraries(obs-filters
libobs)
libobs
${obs-filters_LIBSPEEXDSP_LIBRARIES})
install_obs_plugin_with_data(obs-filters data)

View file

@ -115,7 +115,7 @@ static obs_properties_t *async_delay_filter_properties(void *data)
obs_properties_t *props = obs_properties_create();
obs_properties_add_int(props, SETTING_DELAY_MS, TEXT_DELAY_MS,
0, 6000, 1);
0, 20000, 1);
UNUSED_PARAMETER(data);
return props;

View file

@ -12,10 +12,10 @@ struct crop_filter_data {
int right;
int top;
int bottom;
uint32_t abs_cx;
uint32_t abs_cy;
uint32_t width;
uint32_t height;
int abs_cx;
int abs_cy;
int width;
int height;
bool absolute;
struct vec2 mul_val;
@ -108,13 +108,13 @@ static obs_properties_t *crop_filter_properties(void *data)
obs_property_set_modified_callback(p, relative_clicked);
obs_properties_add_int(props, "left", obs_module_text("Crop.Left"),
0, 8192, 1);
-8192, 8192, 1);
obs_properties_add_int(props, "top", obs_module_text("Crop.Top"),
0, 8192, 1);
-8192, 8192, 1);
obs_properties_add_int(props, "right", obs_module_text("Crop.Right"),
0, 8192, 1);
-8192, 8192, 1);
obs_properties_add_int(props, "bottom", obs_module_text("Crop.Bottom"),
0, 8192, 1);
-8192, 8192, 1);
obs_properties_add_int(props, "cx", obs_module_text("Crop.Width"),
0, 8192, 1);
obs_properties_add_int(props, "cy", obs_module_text("Crop.Height"),
@ -135,37 +135,26 @@ static void calc_crop_dimensions(struct crop_filter_data *filter,
obs_source_t *target = obs_filter_get_target(filter->context);
uint32_t width;
uint32_t height;
uint32_t total;
if (!target) {
width = 0;
height = 0;
return;
} else {
width = obs_source_get_base_width(target);
height = obs_source_get_base_height(target);
}
if (filter->absolute) {
uint32_t max_abs_cx = (filter->left + filter->abs_cx);
if (max_abs_cx > width) max_abs_cx = width;
max_abs_cx -= filter->left;
total = max_abs_cx < width ? (width - max_abs_cx) : 0;
filter->width = filter->abs_cx;
filter->height = filter->abs_cy;
} else {
total = filter->left + filter->right;
filter->width = (int)width - filter->left - filter->right;
filter->height = (int)height - filter->top - filter->bottom;
}
filter->width = total > width ? 0 : (width - total);
if (filter->absolute) {
uint32_t max_abs_cy = (filter->top + filter->abs_cy);
if (max_abs_cy > height) max_abs_cy = height;
max_abs_cy -= filter->top;
total = max_abs_cy < height ? (height - max_abs_cy) : 0;
} else {
total = filter->top + filter->bottom;
}
filter->height = total > height ? 0 : (height - total);
if (filter->width < 1) filter->width = 1;
if (filter->height < 1) filter->height = 1;
if (width && filter->width) {
mul_val->x = (float)filter->width / (float)width;
@ -209,13 +198,13 @@ static void crop_filter_render(void *data, gs_effect_t *effect)
static uint32_t crop_filter_width(void *data)
{
struct crop_filter_data *crop = data;
return crop->width;
return (uint32_t)crop->width;
}
static uint32_t crop_filter_height(void *data)
{
struct crop_filter_data *crop = data;
return crop->height;
return (uint32_t)crop->height;
}
struct obs_source_info crop_filter = {

View file

@ -6,8 +6,9 @@ uniform float2 add_val;
sampler_state textureSampler {
Filter = Linear;
AddressU = Wrap;
AddressV = Wrap;
AddressU = Border;
AddressV = Border;
BorderColor = 00000000;
};
struct VertData {

View file

@ -1,4 +1,4 @@
CropFilter="إقتطاع"
ColorFilter="التصحيح اللوني"
ScrollFilter="التمرير"
DelayMs="التأخير (مللي ثانية)"
Type="النّوع"

View file

@ -1,11 +1,12 @@
ColorFilter="Correcció de color"
MaskFilter="Màscara d'imatge o barreja"
AsyncDelayFilter="Retard del vídeo (asíncron)"
CropFilter="Escapça"
CropFilter="Escapça/Encoixinar"
ScrollFilter="Desplaçament"
ChromaKeyFilter="Clau croma"
ColorKeyFilter="Clau de color"
SharpnessFilter="Agudesa"
ScaleFilter="Escala/Relació d'Aspecte"
NoiseGate="Porta de soroll"
Gain="Guany"
DelayMs="Retard (en mil·lisegons)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Temps de mantenir (mil·lisegons)"
NoiseGate.ReleaseTime="Temps d'alliberar (mil·lisegons)"
Gain.GainDB="Guany (dB)"
StretchImage="Expandir imatge (descarta la relació d'aspecte d'imatge)"
Resolution="Resolució"
None="Cap"
ScaleFiltering="Escala de filtratge"
ScaleFiltering.Point="Punt"
ScaleFiltering.Bilinear="Bilineal"
ScaleFiltering.Bicubic="Bicúbic"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,11 +1,12 @@
ColorFilter="Korekce barev"
MaskFilter="Maska obrazu/prolnutí"
AsyncDelayFilter="Zpoždění obrazu"
CropFilter="Oříznutí"
CropFilter="Oříznutí/odsazení"
ScrollFilter="Rolování"
ChromaKeyFilter="Chroma Key"
ColorKeyFilter="Klíč barvy"
SharpnessFilter="Ostření"
ScaleFilter="Škálování/poměr stran"
NoiseGate="Šumová brána"
Gain="Zisk"
DelayMs="Zpoždění (ms)"
@ -34,7 +35,7 @@ Crop.Top="Nahoře"
Crop.Bottom="Dole"
Crop.Width="Šířka"
Crop.Height="Výška"
Crop.Relative="Relativní"
Crop.Relative="Relativně"
ScrollFilter.SpeedX="Rychlost - vodorovně"
ScrollFilter.SpeedY="Rychlost - svisle"
ScrollFilter.LimitWidth="Omezit šířku"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Čas držení (ms)"
NoiseGate.ReleaseTime="Čas uvolnění (ms)"
Gain.GainDB="Zisk (dB)"
StretchImage="Roztáhnout obrázek (ignorovat poměr stran)"
Resolution="Rozlišení"
None="Žádné"
ScaleFiltering="Filtrování rozsahu"
ScaleFiltering.Point="Bod"
ScaleFiltering.Bilinear="Bilineární"
ScaleFiltering.Bicubic="Bikubický"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,7 +1,6 @@
ColorFilter="Farvekorrektion"
MaskFilter="Billede maske/blanding"
AsyncDelayFilter="Video forsinkelse (asynkron)"
CropFilter="Beskær"
ScrollFilter="Rul"
ChromaKeyFilter="Chroma nøgle"
ColorKeyFilter="Farvenøgle"

View file

@ -1,11 +1,12 @@
ColorFilter="Farbkorrektur"
MaskFilter="Bild Maske/Blend"
AsyncDelayFilter="Videoverzögerung (Asynchron)"
CropFilter="Zuschneiden"
CropFilter="Zuschneiden/Pad"
ScrollFilter="Bewegung"
ChromaKeyFilter="Chroma Key"
ColorKeyFilter="Color Key"
SharpnessFilter="Schärfen"
ScaleFilter="Skalierung/Seitenverhältnis"
NoiseGate="Noise Gate"
Gain="Gain"
DelayMs="Verzögerung (Millisekunden)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Hold-Zeit (Millisekunden)"
NoiseGate.ReleaseTime="Release-Zeit (Millisekunden)"
Gain.GainDB="Gain (dB)"
StretchImage="Bild strecken (Bildseitenverhältnis verwerfen)"
Resolution="Auflösung"
None="Keine"
ScaleFiltering="Skalierungsfilterung"
ScaleFiltering.Point="Point"
ScaleFiltering.Bilinear="Bilinear"
ScaleFiltering.Bicubic="Bicubic"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,6 +1,5 @@
ColorFilter="Διόρθωση Χρώματος"
AsyncDelayFilter="Καθυστέρηση Βίντεο (Ασύγχρονη)"
CropFilter="Περικοπή"
ScrollFilter="Κύλιση"
ChromaKeyFilter="Κλειδί Chroma"
ColorKeyFilter="Κλειδί Χρώματος"

View file

@ -1,12 +1,14 @@
ColorFilter="Color Correction"
MaskFilter="Image Mask/Blend"
AsyncDelayFilter="Video Delay (Async)"
CropFilter="Crop"
CropFilter="Crop/Pad"
ScrollFilter="Scroll"
ChromaKeyFilter="Chroma Key"
ColorKeyFilter="Color Key"
SharpnessFilter="Sharpen"
ScaleFilter="Scaling/Aspect Ratio"
NoiseGate="Noise Gate"
NoiseSuppress="Noise Suppression"
Gain="Gain"
DelayMs="Delay (milliseconds)"
Type="Type"
@ -51,3 +53,11 @@ NoiseGate.HoldTime="Hold Time (milliseconds)"
NoiseGate.ReleaseTime="Release Time (milliseconds)"
Gain.GainDB="Gain (dB)"
StretchImage="Stretch Image (discard image aspect ratio)"
Resolution="Resolution"
None="None"
ScaleFiltering="Scale Filtering"
ScaleFiltering.Point="Point"
ScaleFiltering.Bilinear="Bilinear"
ScaleFiltering.Bicubic="Bicubic"
ScaleFiltering.Lanczos="Lanczos"
NoiseSuppress.SuppressLevel="Suppression Level (dB)"

View file

@ -1,11 +1,12 @@
ColorFilter="Corrección de color"
MaskFilter="Imagen máscara/mezcla"
AsyncDelayFilter="Demora de Video (asincróno)"
CropFilter="Filtro de Recorte"
CropFilter="Recortar/Acolchar"
ScrollFilter="desplazamiento"
ChromaKeyFilter="Fondro croma"
ColorKeyFilter="Filtro de color"
SharpnessFilter="Filtro de enfoque"
ScaleFilter="Escala/Relación de Aspecto"
NoiseGate="Puerta anti-ruidos"
Gain="Ganancia"
DelayMs="Retardo (milisegundos)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Tiempo (en milisegundos) de espera"
NoiseGate.ReleaseTime="Tiempo (en milisegundos) de liberacion"
Gain.GainDB="Ganancia (dB)"
StretchImage="Expandir imagen (descartar relación de aspecto de imagen)"
Resolution="Resolución"
None="Ninguno"
ScaleFiltering="Escala de filtrado"
ScaleFiltering.Point="Punto"
ScaleFiltering.Bilinear="Bilineal"
ScaleFiltering.Bicubic="Bicúbico"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,11 +1,12 @@
ColorFilter="Kolore-zuzenketa"
MaskFilter="Irudi maskara/nahasketa"
AsyncDelayFilter="Bideo atzerapena (Async)"
CropFilter="Moztu"
CropFilter="Moztu/Bete"
ScrollFilter="Korritu"
ChromaKeyFilter="Kroma gakoa"
ColorKeyFilter="Kolore gakoa"
SharpnessFilter="Enfokea"
ScaleFilter="Eskala/Aspektu-erlazioa"
NoiseGate="Zarata atalasea"
Gain="Irabazia"
DelayMs="Atzerapena (milisegundo)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Euste denbora (milisegundo)"
NoiseGate.ReleaseTime="Askatze denbora (milisegundo)"
Gain.GainDB="Irabazia (dB)"
StretchImage="Luzatu irudia (baztertu irudiaren aspektu-erlazioa)"
Resolution="Bereizmena"
None="Ezer ez"
ScaleFiltering="Iragazketa-eskala"
ScaleFiltering.Point="Puntua"
ScaleFiltering.Bilinear="Bilineala"
ScaleFiltering.Bicubic="Bikubikoa"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,14 +1,13 @@
ColorFilter="Värinkorjaus"
MaskFilter="Kuvamaski/Sekoitus"
AsyncDelayFilter="Kuvan viide (Async)"
CropFilter="Rajaa"
AsyncDelayFilter="Kuvan viive (Async)"
ScrollFilter="Vieritä"
ChromaKeyFilter="Chroma Key"
ChromaKeyFilter="Läpinäkyvä tausta"
ColorKeyFilter="Väriavain"
SharpnessFilter="Terävöitä"
NoiseGate="Noise Gate"
Gain="Vahvistus"
DelayMs="Viive (MS)"
DelayMs="Viive (millisekuntia)"
Type="Tyyppi"
MaskBlendType.MaskColor="Alpha-maski (värikanava)"
MaskBlendType.MaskAlpha="Alpha-maski (alfa-kanava)"
@ -40,9 +39,9 @@ ScrollFilter.SpeedY="Pystynopeus"
ScrollFilter.LimitWidth="Rajoita leveyttä"
ScrollFilter.LimitHeight="Rajoita korkeutta"
CustomColor="Mukautettu väri"
Red="Red"
Green="Green"
Blue="Blue"
Red="Punainen"
Green="Vihreä"
Blue="Sininen"
Magenta="Magenta"
NoiseGate.OpenThreshold="Avautumiskynnys (dB)"
NoiseGate.CloseThreshold="Sulkeutumiskynnys (dB)"
@ -50,5 +49,5 @@ NoiseGate.AttackTime="Reagointiviive (millisekuntia)"
NoiseGate.HoldTime="Pitoaika (millisekuntia)"
NoiseGate.ReleaseTime="Vapautumisaika (millisekuntia)"
Gain.GainDB="Vahvistus (dB)"
StretchImage="Venytä kuvaa (hylkää kuvasuhde)"
StretchImage="Venytä kuvaa (Ohita kuvasuhde)"

View file

@ -1,14 +1,15 @@
ColorFilter="Corrections colorimétrique"
MaskFilter="Masque d'image/mélange"
AsyncDelayFilter="Délai vidéo (async.)"
CropFilter="Rogner"
AsyncDelayFilter="Retard vidéo (async.)"
CropFilter="Rogner / Encadrer"
ScrollFilter="Défilement"
ChromaKeyFilter="Clé chromatique"
ColorKeyFilter="Couleur d'incrustation"
SharpnessFilter="Accentuer"
ScaleFilter="Mise à léchelle / Ratio d'affichage"
NoiseGate="Noise Gate"
Gain="Gain"
DelayMs="Délai (en millisecondes)"
DelayMs="Retard (en millisecondes)"
Type="Type "
MaskBlendType.MaskColor="Masque alpha (canal de couleur)"
MaskBlendType.MaskAlpha="Masque alpha (canal alpha)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Temps de maintien (millisecondes)"
NoiseGate.ReleaseTime="Temps d'arrêt (millisecondes)"
Gain.GainDB="Gain (dB)"
StretchImage="Étirer l'Image (ignorer ses proportions)"
Resolution="Résolution"
None="Aucune"
ScaleFiltering="Échelle de filtrage"
ScaleFiltering.Point="Point"
ScaleFiltering.Bilinear="Bilinéaire"
ScaleFiltering.Bicubic="Bicubique"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,7 +1,6 @@
ColorFilter="Corrección da cor"
MaskFilter="Máscara/mestura de imaxes"
AsyncDelayFilter="Atraso do vídeo (asíncrono)"
CropFilter="Recortar"
ScrollFilter="Desprazamento"
DelayMs="Atraso (milisegundos)"
Type="Tipo"

View file

@ -1,11 +1,12 @@
ColorFilter="תיקון צבע"
MaskFilter="מסכה/עירבוב תמונה"
AsyncDelayFilter="השהיית וידאו (אסינכרונית)"
CropFilter=תוך"
CropFilter=יתוך/ריפוד"
ScrollFilter="גלול"
ChromaKeyFilter="מסך כחול"
ColorKeyFilter="מפתח צבע"
SharpnessFilter="חידוד"
ScaleFilter="יחס גובה רוחב/קנה מידה"
NoiseGate="שער רעש"
Gain="הגברה"
DelayMs="השהייה (אלפיות שניה)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="זמן החזקה (אלפיות שניה)"
NoiseGate.ReleaseTime="זמן שחרור (אלפיות שניה)"
Gain.GainDB="הגברה (dB)"
StretchImage="מתח תמונה (יחס הגובה-רוחב של התמונה לא ישמר)"
Resolution="רזולוציה"
None="ללא"
ScaleFiltering="מסנן קנה מידה"
ScaleFiltering.Point="נקודה"
ScaleFiltering.Bilinear="ביליניארי"
ScaleFiltering.Bicubic="ביקיוביק"
ScaleFiltering.Lanczos="לנזוס"

View file

@ -1,7 +1,6 @@
ColorFilter="Promena boja"
MaskFilter="Slika maske i stapanja"
AsyncDelayFilter="Video pauza (asinhrono)"
CropFilter="Odsecanje"
ScrollFilter="Pomeranje"
ChromaKeyFilter="Ključ providnosti"
ColorKeyFilter="Ključ boje"

View file

@ -1,11 +1,12 @@
ColorFilter="Színkorrekció"
MaskFilter="Képmaszk/Keverés"
AsyncDelayFilter="Videó késleltetés (Async)"
CropFilter="Vágás"
CropFilter="Vágás/Margó"
ScrollFilter="Görgetés"
ChromaKeyFilter="Chroma kulcs"
ColorKeyFilter="Színkulcs"
SharpnessFilter="Élesítés"
ScaleFilter="Méretezés/Képarány"
NoiseGate="Zajgát"
Gain="Erősítés"
DelayMs="Késleltetés (ezredmásodperc)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Kitartás ideje (ezredmásodperc)"
NoiseGate.ReleaseTime="Felengedés ideje (ezredmásodperc)"
Gain.GainDB="Erősítés (dB)"
StretchImage="Kép nyújtása (képarány elvetésével)"
Resolution="Felbontás"
None="Nincs"
ScaleFiltering="Skála-szűrés"
ScaleFiltering.Point="Pont"
ScaleFiltering.Bilinear="Bilineáris"
ScaleFiltering.Bicubic="Kettős köbös"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,11 +1,12 @@
ColorFilter="Correzione colore"
MaskFilter="Immagine maschera/miscela"
AsyncDelayFilter="Ritardo video (Asincrono)"
CropFilter="Ritaglia"
CropFilter="Crop/Pad"
ScrollFilter="Scorrimento"
ChromaKeyFilter="Chroma Key"
ColorKeyFilter="Chiave Colore"
SharpnessFilter="Nitidizza"
ScaleFilter="Ridimensionamento/Aspect Ratio"
NoiseGate="Noise Gate"
Gain="Incremento"
DelayMs="Ritardo (millisecondi)"
@ -50,4 +51,12 @@ NoiseGate.AttackTime="Tempo d'inizio (millisecondi)"
NoiseGate.HoldTime="Tempo d'attesa (millisecondi)"
NoiseGate.ReleaseTime="Tempo di rilascio (millisecondi)"
Gain.GainDB="Incremento (dB)"
StretchImage="Stendi immagine (scarta proporzioni immagine)"
Resolution="Risoluzione"
None="Nessuno"
ScaleFiltering="Scala di filtraggio"
ScaleFiltering.Point="Punto"
ScaleFiltering.Bilinear="Bilineare"
ScaleFiltering.Bicubic="Bicubico"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,11 +1,12 @@
ColorFilter="色補正"
MaskFilter="イメージ マスク/ブレンド"
AsyncDelayFilter="映像の遅延 (非同期)"
CropFilter="クロップ"
CropFilter="クロップ/パッド"
ScrollFilter="スクロール"
ChromaKeyFilter="クロマキー"
ColorKeyFilter="カラーキー"
SharpnessFilter="シャープ"
ScaleFilter="スケーリング/アスペクト比"
NoiseGate="ノイズゲート"
Gain="ゲイン"
DelayMs="遅延時間 (ミリ秒)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="保持時間 (ミリ秒)"
NoiseGate.ReleaseTime="解除時間 (ミリ秒)"
Gain.GainDB="ゲイン (dB)"
StretchImage="画像を拡大 (アスペクト比を破棄)"
Resolution="解像度"
None="なし"
ScaleFiltering="スケールフィルタ"
ScaleFiltering.Point="ポイント"
ScaleFiltering.Bilinear="バイリニア"
ScaleFiltering.Bicubic="バイキュービック"
ScaleFiltering.Lanczos="ランチョス"

View file

@ -1,11 +1,12 @@
ColorFilter="색상 보정"
MaskFilter="이미지 마스크/혼합"
AsyncDelayFilter="비디오 지연 (비동기)"
CropFilter="자르기"
CropFilter="자르기/덧대기"
ScrollFilter="스크롤"
ChromaKeyFilter="크로마 키"
ColorKeyFilter="색상 키"
SharpnessFilter="선명하게"
ScaleFilter="비례축소/가로세로 비율"
NoiseGate="노이즈 게이트"
Gain="증폭"
DelayMs="지연 (밀리초)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="개방 유지 시간 (밀리세컨드)"
NoiseGate.ReleaseTime="폐쇄 준비 시간 (밀리세컨드)"
Gain.GainDB="증폭 (dB)"
StretchImage="이미지 늘리기 (이미지 가로 세로 비율 포기)"
Resolution="해상도"
None="없음"
ScaleFiltering="비율 필터링"
ScaleFiltering.Point="점"
ScaleFiltering.Bilinear="이중선형"
ScaleFiltering.Bicubic="쌍삼차"
ScaleFiltering.Lanczos="란초스"

View file

@ -1,7 +1,7 @@
ColorFilter="Fargekorrigering"
MaskFilter="Bildemaske/-blanding"
AsyncDelayFilter="Videoforsinkelse (asynkron)"
CropFilter="Beskjæring"
CropFilter="Beskjæring/utfall"
ScrollFilter="Rull"
ChromaKeyFilter="Chromafilter"
ColorKeyFilter="Fargefilter"
@ -50,4 +50,5 @@ NoiseGate.AttackTime="Angrepstid (millisekunder)"
NoiseGate.HoldTime="Holdetid (millisekunder)"
NoiseGate.ReleaseTime="Løslatelsestid (millisekunder)"
Gain.GainDB="Forsterkning (dB)"
StretchImage="Strekk bilde (ignorer bildets sideforhold)"

View file

@ -1,11 +1,12 @@
ColorFilter="Kleurcorrectie"
MaskFilter="Afbeeldingsmasker/Mengen"
AsyncDelayFilter="Videovertraging (Async)"
CropFilter="Bijsnijden"
CropFilter="Bijsnijden/Aanvullen"
ScrollFilter="Scrollen"
ChromaKeyFilter="Chroma Key"
ColorKeyFilter="Color Key"
SharpnessFilter="Verscherpen"
ScaleFilter="Schalen/Aspect Ratio"
NoiseGate="Noise Gate"
Gain="Gain"
DelayMs="Vertraging (milliseconden)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Hold-tijd (milliseconden)"
NoiseGate.ReleaseTime="Release-tijd (milliseconden)"
Gain.GainDB="Gain (dB)"
StretchImage="Afbeelding uitrekken (negeer beeldverhouding van de afbeelding)"
Resolution="Resolutie"
None="Geen"
ScaleFiltering="Schaal-filter"
ScaleFiltering.Point="Point"
ScaleFiltering.Bilinear="Bilinear"
ScaleFiltering.Bicubic="Bicubic"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,11 +1,12 @@
ColorFilter="Korekcja Kolorów"
MaskFilter="Maskowanie/nakładanie obrazu"
AsyncDelayFilter="Opóźnienie wideo (asynchronicznie)"
CropFilter="Kadrowanie"
CropFilter="Przytnij/Uzupełnij"
ScrollFilter="Przewijanie"
ChromaKeyFilter="Kluczowanie koloru (chroma key)"
ColorKeyFilter="Kluczowanie koloru (kolor)"
SharpnessFilter="Wyostrzanie"
ScaleFilter="Skalowanie/proporcje"
NoiseGate="Bramka szumów"
Gain="Poziom"
DelayMs="Opóźnienie (milisekundy)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Czas wstrzymania (milisekundy)"
NoiseGate.ReleaseTime="Czas zwolnienia (milisekundy)"
Gain.GainDB="Poziom (dB)"
StretchImage="Rozciągnięcie obrazu (ignoruj proporcje)"
Resolution="Rozdzielczość"
None="Brak"
ScaleFiltering="Filtrowanie"
ScaleFiltering.Point="Punktowe"
ScaleFiltering.Bilinear="Dwuliniowe"
ScaleFiltering.Bicubic="Dwusześcienne"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,7 +1,6 @@
ColorFilter="Correção de cor"
MaskFilter="Máscara/mistura de imagem"
AsyncDelayFilter="Atraso de vídeo (Async)"
CropFilter="Cortar"
ScrollFilter="Rolagem"
ChromaKeyFilter="Chroma Key"
ColorKeyFilter="Color Key"

View file

@ -1,7 +1,6 @@
ColorFilter="Correção de cor"
MaskFilter="Máscara/mistura de imagem"
AsyncDelayFilter="Atraso de vídeo (Async)"
CropFilter="Corte"
ScrollFilter="Percorre"
ChromaKeyFilter="Chroma Key"
ColorKeyFilter="Color Key"
@ -50,4 +49,5 @@ NoiseGate.AttackTime="Tempo de ataque (milissegundos)"
NoiseGate.HoldTime="Tempo de bloqueio (milissegundos)"
NoiseGate.ReleaseTime="Tempo de libertação (milissegundos)"
Gain.GainDB="Ganho (dB)"
StretchImage="Esticar a imagem (relação de aspeto de imagem de descarte)"

View file

@ -1,7 +1,6 @@
ColorFilter="Corecție de culoare"
MaskFilter="Mască/amestec de imagine"
AsyncDelayFilter="Întârziere video (asincron)"
CropFilter="Trunchiere"
ScrollFilter="Derulare"
ChromaKeyFilter="Cheie chroma"
ColorKeyFilter="Culoare cheie"

View file

@ -1,11 +1,12 @@
ColorFilter="Коррекция цвета"
MaskFilter="Маска изображения/Смешивание"
AsyncDelayFilter="Задержка видео (асинхронность)"
CropFilter="Обрезка"
CropFilter="Кадрировать"
ScrollFilter="Прокрутка"
ChromaKeyFilter="Хромакей"
ColorKeyFilter="Цветовой ключ"
SharpnessFilter="Увеличить резкость"
ScaleFilter="Коэффициент Масштабирования/Аспект"
NoiseGate="Подавление шума"
Gain="Усиление"
DelayMs="Задержка (миллисекунд)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="Длительность задержки (миллисек
NoiseGate.ReleaseTime="Длительность затухания (миллисекунд)"
Gain.GainDB="Усиление (дБ)"
StretchImage="Растянуть изображение (игнорировать пропорции изображения)"
Resolution="Разрешение"
None="Нет"
ScaleFiltering="Масштаб Фильтрации"
ScaleFiltering.Point="Точечная"
ScaleFiltering.Bilinear="Билинейная"
ScaleFiltering.Bicubic="Бикубическая"
ScaleFiltering.Lanczos="Ланцошная"

View file

@ -1,7 +1,6 @@
ColorFilter="Promena boja"
MaskFilter="Slika maske i stapanja"
AsyncDelayFilter="Video pauza (asinhrono)"
CropFilter="Odsecanje"
ScrollFilter="Pomeranje"
ChromaKeyFilter="Ključ providnosti"
ColorKeyFilter="Ključ boje"

View file

@ -1,7 +1,6 @@
ColorFilter="Промена боја"
MaskFilter="Слика маске и стапања"
AsyncDelayFilter="Видео пауза (асинхроно)"
CropFilter="Одсецање"
ScrollFilter="Померање"
ChromaKeyFilter="Кључ провидности"
ColorKeyFilter="Кључ боје"

View file

@ -1,11 +1,11 @@
ColorFilter="Färgkorrigering"
MaskFilter="Bild Mask/Blandning"
AsyncDelayFilter="Videofördröjning (Async)"
CropFilter="Beskär"
ScrollFilter="Scrollning"
ChromaKeyFilter="Kromafilter"
ColorKeyFilter="Färgfilter"
SharpnessFilter="Skärpa"
ScaleFilter="Skalning/Bildförhållande"
NoiseGate="Brusblockering"
Gain="Förstärkning"
DelayMs="Fördröjning (millisekunder)"
@ -51,4 +51,10 @@ NoiseGate.HoldTime="Hålltid (millisekunder)"
NoiseGate.ReleaseTime="Släpptid (millisekunder)"
Gain.GainDB="Förstärkning (dB)"
StretchImage="Sträck bild (ignorera bildförhållandet)"
Resolution="Upplösning"
None="Ingen"
ScaleFiltering="Skalningsfiltrering"
ScaleFiltering.Bilinear="Bilinjär"
ScaleFiltering.Bicubic="Bikubisk"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -1,7 +1,6 @@
ColorFilter="Renk Düzeltme"
MaskFilter="Görüntü Maskesi/Blend"
AsyncDelayFilter="Görüntü Gecikmesi (Async)"
CropFilter="Kırpma"
ScrollFilter="Kaydır"
ChromaKeyFilter="Chroma Anahtarı"
ColorKeyFilter="Renk Anahtarı"

View file

@ -1,11 +1,12 @@
ColorFilter="色彩校正"
MaskFilter="图像掩码/混合"
AsyncDelayFilter="视频延迟(异步)"
CropFilter="裁"
CropFilter="剪/填充"
ScrollFilter="滚动"
ChromaKeyFilter="色度键"
ColorKeyFilter="色值"
SharpnessFilter="锐化"
ScaleFilter="缩放比例"
NoiseGate="噪音阈值"
Gain="增益"
DelayMs="延迟(毫秒)"
@ -51,4 +52,11 @@ NoiseGate.HoldTime="保持时间(毫秒)"
NoiseGate.ReleaseTime="释放时间(毫秒)"
Gain.GainDB="增益 (dB)"
StretchImage="伸展图像 (丢弃图像纵横比)"
Resolution="分辨率"
None="无"
ScaleFiltering="尺度滤波"
ScaleFiltering.Point="点"
ScaleFiltering.Bilinear="双线性算法"
ScaleFiltering.Bicubic="双立方算法"
ScaleFiltering.Lanczos="兰索斯算法"

View file

@ -0,0 +1,62 @@
ColorFilter="色彩校正"
MaskFilter="影像遮罩/混合"
AsyncDelayFilter="視頻延遲 (非同步)"
CropFilter="剪裁/填充"
ScrollFilter="捲動"
ChromaKeyFilter="色度鍵"
ColorKeyFilter="色彩鍵"
SharpnessFilter="銳化"
ScaleFilter="縮放/長寬比"
NoiseGate="噪音閾"
Gain="增益"
DelayMs="延遲 (毫秒)"
Type="類型"
MaskBlendType.MaskColor="Alpha 遮罩 (顏色通道)"
MaskBlendType.MaskAlpha="Alpha 遮罩 Alpha 通道)"
MaskBlendType.BlendMultiply="混合 (乘法)"
MaskBlendType.BlendAddition="混合 (加法)"
MaskBlendType.BlendSubtraction="混合 (減法)"
Path="檔案路徑"
Color="顏色"
Opacity="不透明度"
Contrast="對比"
Brightness="亮度"
Gamma="伽瑪"
BrowsePath.Images="影像檔案"
BrowsePath.AllFiles="所有檔案"
KeyColorType="關鍵顏色類型"
KeyColor="關鍵顏色"
Similarity="相似性 (1-1000)"
Smoothness="平滑度 (1-1000)"
ColorSpillReduction="鍵色溢出減少 (1-1000)"
Crop.Left="左側"
Crop.Right="右側"
Crop.Top="上方"
Crop.Bottom="下方"
Crop.Width="寬度"
Crop.Height="高度"
Crop.Relative="相對"
ScrollFilter.SpeedX="水平速度"
ScrollFilter.SpeedY="垂直速度"
ScrollFilter.LimitWidth="限制寬度"
ScrollFilter.LimitHeight="限制高度"
CustomColor="自訂色彩"
Red="红"
Green="綠"
Blue="藍"
Magenta="洋紅"
NoiseGate.OpenThreshold="開啟閾值 (dB)"
NoiseGate.CloseThreshold="關閉閾值 (dB)"
NoiseGate.AttackTime="起音時間 (Attack time)(毫秒)"
NoiseGate.HoldTime="持續時間 (Hold time)(毫秒)"
NoiseGate.ReleaseTime="釋音時間 (Release time)(毫秒)"
Gain.GainDB="增益 (dB)"
StretchImage="伸展圖像 (無視圖像比例)"
Resolution="解析度"
None="無"
ScaleFiltering="縮放濾鏡"
ScaleFiltering.Point="點"
ScaleFiltering.Bilinear="雙線性插值"
ScaleFiltering.Bicubic="雙三次插值"
ScaleFiltering.Lanczos="Lanczos"

View file

@ -0,0 +1,297 @@
#include <stdint.h>
#include <inttypes.h>
#include <util/circlebuf.h>
#include <obs-module.h>
#include <speex/speex_preprocess.h>
/* -------------------------------------------------------- */
#define do_log(level, format, ...) \
blog(level, "[noise suppress: '%s'] " format, \
obs_source_get_name(ng->context), ##__VA_ARGS__)
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
#ifdef _DEBUG
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
#else
#define debug(format, ...)
#endif
/* -------------------------------------------------------- */
#define S_SUPPRESS_LEVEL "suppress_level"
#define MT_ obs_module_text
#define TEXT_SUPPRESS_LEVEL MT_("NoiseSuppress.SuppressLevel")
#define MAX_PREPROC_CHANNELS 2
/* -------------------------------------------------------- */
struct noise_suppress_data {
obs_source_t *context;
int suppress_level;
uint64_t last_timestamp;
size_t frames;
size_t channels;
struct circlebuf info_buffer;
struct circlebuf input_buffers[MAX_PREPROC_CHANNELS];
struct circlebuf output_buffers[MAX_PREPROC_CHANNELS];
/* Speex preprocessor state */
SpeexPreprocessState *states[MAX_PREPROC_CHANNELS];
/* 16 bit PCM buffers */
float *copy_buffers[MAX_PREPROC_CHANNELS];
spx_int16_t *segment_buffers[MAX_PREPROC_CHANNELS];
/* output data */
struct obs_audio_data output_audio;
DARRAY(float) output_data;
};
/* -------------------------------------------------------- */
#define SUP_MIN -60
#define SUP_MAX 0
static const float c_32_to_16 = (float)INT16_MAX;
static const float c_16_to_32 = ((float)INT16_MAX + 1.0f);
/* -------------------------------------------------------- */
static const char *noise_suppress_name(void *unused)
{
UNUSED_PARAMETER(unused);
return obs_module_text("NoiseSuppress");
}
static void noise_suppress_destroy(void *data)
{
struct noise_suppress_data *ng = data;
for (size_t i = 0; i < ng->channels; i++) {
speex_preprocess_state_destroy(ng->states[i]);
circlebuf_free(&ng->input_buffers[i]);
circlebuf_free(&ng->output_buffers[i]);
}
bfree(ng->segment_buffers[0]);
bfree(ng->copy_buffers[0]);
circlebuf_free(&ng->info_buffer);
da_free(ng->output_data);
bfree(ng);
}
static inline void alloc_channel(struct noise_suppress_data *ng,
uint32_t sample_rate, size_t channel, size_t frames)
{
ng->states[channel] = speex_preprocess_state_init((int)frames,
sample_rate);
circlebuf_reserve(&ng->input_buffers[channel], frames * sizeof(float));
circlebuf_reserve(&ng->output_buffers[channel], frames * sizeof(float));
}
static void noise_suppress_update(void *data, obs_data_t *s)
{
struct noise_suppress_data *ng = data;
uint32_t sample_rate = audio_output_get_sample_rate(obs_get_audio());
size_t channels = audio_output_get_channels(obs_get_audio());
size_t frames = (size_t)sample_rate / 100;
ng->suppress_level = (int)obs_data_get_int(s, S_SUPPRESS_LEVEL);
/* Process 10 millisecond segments to keep latency low */
ng->frames = frames;
ng->channels = channels;
/* Ignore if already allocated */
if (ng->states[0])
return;
/* One speex state for each channel (limit 2) */
ng->copy_buffers[0] = bmalloc(frames * channels * sizeof(float));
ng->segment_buffers[0] = bmalloc(frames * channels * sizeof(spx_int16_t));
if (channels == 2) {
ng->copy_buffers[1] = ng->copy_buffers[0] + frames;
ng->segment_buffers[1] = ng->segment_buffers[0] + frames;
}
for (size_t i = 0; i < channels; i++)
alloc_channel(ng, sample_rate, i, frames);
}
static void *noise_suppress_create(obs_data_t *settings, obs_source_t *filter)
{
struct noise_suppress_data *ng =
bzalloc(sizeof(struct noise_suppress_data));
ng->context = filter;
noise_suppress_update(ng, settings);
return ng;
}
static inline void process(struct noise_suppress_data *ng)
{
/* Pop from input circlebuf */
for (size_t i = 0; i < ng->channels; i++)
circlebuf_pop_front(&ng->input_buffers[i], ng->copy_buffers[i],
ng->frames * sizeof(float));
/* Set args */
for (size_t i = 0; i < ng->channels; i++)
speex_preprocess_ctl(ng->states[i],
SPEEX_PREPROCESS_SET_NOISE_SUPPRESS,
&ng->suppress_level);
/* Convert to 16bit */
for (size_t i = 0; i < ng->channels; i++)
for (size_t j = 0; j < ng->frames; j++)
ng->segment_buffers[i][j] = (spx_int16_t)
(ng->copy_buffers[i][j] * c_32_to_16);
/* Execute */
for (size_t i = 0; i < ng->channels; i++)
speex_preprocess_run(ng->states[i], ng->segment_buffers[i]);
/* Convert back to 32bit */
for (size_t i = 0; i < ng->channels; i++)
for (size_t j = 0; j < ng->frames; j++)
ng->copy_buffers[i][j] =
(float)ng->segment_buffers[i][j] / c_16_to_32;
/* Push to output circlebuf */
for (size_t i = 0; i < ng->channels; i++)
circlebuf_push_back(&ng->output_buffers[i], ng->copy_buffers[i],
ng->frames * sizeof(float));
}
struct ng_audio_info {
uint32_t frames;
uint64_t timestamp;
};
static inline void clear_circlebuf(struct circlebuf *buf)
{
circlebuf_pop_front(buf, NULL, buf->size);
}
static void reset_data(struct noise_suppress_data *ng)
{
for (size_t i = 0; i < ng->channels; i++) {
clear_circlebuf(&ng->input_buffers[i]);
clear_circlebuf(&ng->output_buffers[i]);
}
clear_circlebuf(&ng->info_buffer);
}
static struct obs_audio_data *noise_suppress_filter_audio(void *data,
struct obs_audio_data *audio)
{
struct noise_suppress_data *ng = data;
struct ng_audio_info info;
size_t segment_size = ng->frames * sizeof(float);
size_t out_size;
if (!ng->states[0])
return audio;
/* -----------------------------------------------
* if timestamp has dramatically changed, consider it a new stream of
* audio data. clear all circular buffers to prevent old audio data
* from being processed as part of the new data. */
if (ng->last_timestamp) {
int64_t diff = llabs((int64_t)ng->last_timestamp -
(int64_t)audio->timestamp);
if (diff > 1000000000LL)
reset_data(ng);
}
ng->last_timestamp = audio->timestamp;
/* -----------------------------------------------
* push audio packet info (timestamp/frame count) to info circlebuf */
info.frames = audio->frames;
info.timestamp = audio->timestamp;
circlebuf_push_back(&ng->info_buffer, &info, sizeof(info));
/* -----------------------------------------------
* push back current audio data to input circlebuf */
for (size_t i = 0; i < ng->channels; i++)
circlebuf_push_back(&ng->input_buffers[i], audio->data[i],
audio->frames * sizeof(float));
/* -----------------------------------------------
* pop/process each 10ms segments, push back to output circlebuf */
while (ng->input_buffers[0].size >= segment_size)
process(ng);
/* -----------------------------------------------
* peek front of info circlebuf, check to see if we have enough to
* pop the expected packet size, if not, return null */
memset(&info, 0, sizeof(info));
circlebuf_peek_front(&ng->info_buffer, &info, sizeof(info));
out_size = info.frames * sizeof(float);
if (ng->output_buffers[0].size < out_size)
return NULL;
/* -----------------------------------------------
* if there's enough audio data buffered in the output circlebuf,
* pop and return a packet */
circlebuf_pop_front(&ng->info_buffer, NULL, sizeof(info));
da_resize(ng->output_data, out_size * ng->channels);
for (size_t i = 0; i < ng->channels; i++) {
ng->output_audio.data[i] =
(uint8_t*)&ng->output_data.array[i * out_size];
circlebuf_pop_front(&ng->output_buffers[i],
ng->output_audio.data[i],
out_size);
}
ng->output_audio.frames = info.frames;
ng->output_audio.timestamp = info.timestamp;
return &ng->output_audio;
}
static void noise_suppress_defaults(obs_data_t *s)
{
obs_data_set_default_int(s, S_SUPPRESS_LEVEL, -30);
}
static obs_properties_t *noise_suppress_properties(void *data)
{
obs_properties_t *ppts = obs_properties_create();
obs_properties_add_int_slider(ppts, S_SUPPRESS_LEVEL,
TEXT_SUPPRESS_LEVEL, SUP_MIN, SUP_MAX, 0);
UNUSED_PARAMETER(data);
return ppts;
}
struct obs_source_info noise_suppress_filter = {
.id = "noise_suppress_filter",
.type = OBS_SOURCE_TYPE_FILTER,
.output_flags = OBS_SOURCE_AUDIO,
.get_name = noise_suppress_name,
.create = noise_suppress_create,
.destroy = noise_suppress_destroy,
.update = noise_suppress_update,
.filter_audio = noise_suppress_filter_audio,
.get_defaults = noise_suppress_defaults,
.get_properties = noise_suppress_properties,
};

View file

@ -0,0 +1,11 @@
#pragma once
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define SPEEXDSP_ENABLED @LIBSPEEXDSP_FOUND@

View file

@ -1,4 +1,5 @@
#include <obs-module.h>
#include "obs-filters-config.h"
OBS_DECLARE_MODULE()
@ -8,11 +9,15 @@ extern struct obs_source_info mask_filter;
extern struct obs_source_info crop_filter;
extern struct obs_source_info gain_filter;
extern struct obs_source_info color_filter;
extern struct obs_source_info scale_filter;
extern struct obs_source_info scroll_filter;
extern struct obs_source_info color_key_filter;
extern struct obs_source_info sharpness_filter;
extern struct obs_source_info chroma_key_filter;
extern struct obs_source_info async_delay_filter;
#if SPEEXDSP_ENABLED
extern struct obs_source_info noise_suppress_filter;
#endif
extern struct obs_source_info noise_gate_filter;
bool obs_module_load(void)
@ -21,11 +26,15 @@ bool obs_module_load(void)
obs_register_source(&crop_filter);
obs_register_source(&gain_filter);
obs_register_source(&color_filter);
obs_register_source(&scale_filter);
obs_register_source(&scroll_filter);
obs_register_source(&color_key_filter);
obs_register_source(&sharpness_filter);
obs_register_source(&chroma_key_filter);
obs_register_source(&async_delay_filter);
#if SPEEXDSP_ENABLED
obs_register_source(&noise_suppress_filter);
#endif
obs_register_source(&noise_gate_filter);
return true;
}

View file

@ -0,0 +1,342 @@
#include <stdio.h>
#include <stdlib.h>
#include <util/dstr.h>
#include <obs-module.h>
#include <util/platform.h>
#include <graphics/vec2.h>
#include <graphics/math-defs.h>
#define S_RESOLUTION "resolution"
#define S_SAMPLING "sampling"
#define T_RESOLUTION obs_module_text("Resolution")
#define T_NONE obs_module_text("None")
#define T_SAMPLING obs_module_text("ScaleFiltering")
#define T_SAMPLING_POINT obs_module_text("ScaleFiltering.Point")
#define T_SAMPLING_BILINEAR obs_module_text("ScaleFiltering.Bilinear")
#define T_SAMPLING_BICUBIC obs_module_text("ScaleFiltering.Bicubic")
#define T_SAMPLING_LANCZOS obs_module_text("ScaleFiltering.Lanczos")
#define S_SAMPLING_POINT "point"
#define S_SAMPLING_BILINEAR "bilinear"
#define S_SAMPLING_BICUBIC "bicubic"
#define S_SAMPLING_LANCZOS "lanczos"
struct scale_filter_data {
obs_source_t *context;
gs_effect_t *effect;
gs_eparam_t *image_param;
gs_eparam_t *dimension_param;
struct vec2 dimension_i;
int cx_in;
int cy_in;
int cx_out;
int cy_out;
enum obs_scale_type sampling;
gs_samplerstate_t *point_sampler;
bool aspect_ratio_only : 1;
bool target_valid : 1;
bool valid : 1;
};
static const char *scale_filter_name(void *unused)
{
UNUSED_PARAMETER(unused);
return obs_module_text("ScaleFilter");
}
static void scale_filter_update(void *data, obs_data_t *settings)
{
struct scale_filter_data *filter = data;
int ret;
const char *res_str = obs_data_get_string(settings, S_RESOLUTION);
const char *sampling = obs_data_get_string(settings, S_SAMPLING);
filter->valid = true;
ret = sscanf(res_str, "%dx%d", &filter->cx_in, &filter->cy_in);
if (ret == 2) {
filter->aspect_ratio_only = false;
} else {
ret = sscanf(res_str, "%d:%d", &filter->cx_in, &filter->cy_in);
if (ret != 2) {
filter->valid = false;
return;
}
filter->aspect_ratio_only = true;
}
if (astrcmpi(sampling, S_SAMPLING_POINT) == 0) {
filter->sampling = OBS_SCALE_POINT;
} else if (astrcmpi(sampling, S_SAMPLING_BILINEAR) == 0) {
filter->sampling = OBS_SCALE_BILINEAR;
} else if (astrcmpi(sampling, S_SAMPLING_LANCZOS) == 0) {
filter->sampling = OBS_SCALE_LANCZOS;
} else { /* S_SAMPLING_BICUBIC */
filter->sampling = OBS_SCALE_BICUBIC;
}
}
static void scale_filter_destroy(void *data)
{
struct scale_filter_data *filter = data;
obs_enter_graphics();
gs_samplerstate_destroy(filter->point_sampler);
obs_leave_graphics();
bfree(data);
}
static void *scale_filter_create(obs_data_t *settings, obs_source_t *context)
{
struct scale_filter_data *filter =
bzalloc(sizeof(struct scale_filter_data));
struct gs_sampler_info sampler_info = {0};
filter->context = context;
obs_enter_graphics();
filter->point_sampler = gs_samplerstate_create(&sampler_info);
obs_leave_graphics();
scale_filter_update(filter, settings);
return filter;
}
static void scale_filter_tick(void *data, float seconds)
{
struct scale_filter_data *filter = data;
enum obs_base_effect type;
obs_source_t *target;
bool lower_than_2x;
double cx_f;
double cy_f;
int cx;
int cy;
target = obs_filter_get_target(filter->context);
filter->cx_out = 0;
filter->cy_out = 0;
filter->target_valid = !!target;
if (!filter->target_valid)
return;
cx = obs_source_get_base_width(target);
cy = obs_source_get_base_height(target);
if (!cx || !cy) {
filter->target_valid = false;
return;
}
filter->cx_out = cx;
filter->cy_out = cy;
if (!filter->valid)
return;
/* ------------------------- */
cx_f = (double)cx;
cy_f = (double)cy;
if (filter->aspect_ratio_only) {
double old_aspect = cx_f / cy_f;
double new_aspect =
(double)filter->cx_in / (double)filter->cy_in;
if (fabs(old_aspect - new_aspect) <= EPSILON) {
filter->target_valid = false;
return;
} else {
if (new_aspect > old_aspect) {
filter->cx_out = (int)(cy_f * new_aspect);
filter->cy_out = cy;
} else {
filter->cx_out = cx;
filter->cy_out = (int)(cx_f / new_aspect);
}
}
} else {
filter->cx_out = filter->cx_in;
filter->cy_out = filter->cy_in;
}
vec2_set(&filter->dimension_i,
1.0f / (float)cx,
1.0f / (float)cy);
/* ------------------------- */
lower_than_2x = filter->cx_out < cx / 2 || filter->cy_out < cy / 2;
if (lower_than_2x && filter->sampling != OBS_SCALE_POINT) {
type = OBS_EFFECT_BILINEAR_LOWRES;
} else {
switch (filter->sampling) {
default:
case OBS_SCALE_POINT:
case OBS_SCALE_BILINEAR: type = OBS_EFFECT_DEFAULT; break;
case OBS_SCALE_BICUBIC: type = OBS_EFFECT_BICUBIC; break;
case OBS_SCALE_LANCZOS: type = OBS_EFFECT_LANCZOS; break;
}
}
filter->effect = obs_get_base_effect(type);
filter->image_param = gs_effect_get_param_by_name(filter->effect,
"image");
if (type != OBS_EFFECT_DEFAULT) {
filter->dimension_param = gs_effect_get_param_by_name(
filter->effect, "base_dimension_i");
} else {
filter->dimension_param = NULL;
}
UNUSED_PARAMETER(seconds);
}
static void scale_filter_render(void *data, gs_effect_t *effect)
{
struct scale_filter_data *filter = data;
if (!filter->valid || !filter->target_valid) {
obs_source_skip_video_filter(filter->context);
return;
}
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
OBS_NO_DIRECT_RENDERING))
return;
if (filter->dimension_param)
gs_effect_set_vec2(filter->dimension_param,
&filter->dimension_i);
if (filter->sampling == OBS_SCALE_POINT)
gs_effect_set_next_sampler(filter->image_param,
filter->point_sampler);
obs_source_process_filter_end(filter->context, filter->effect,
filter->cx_out, filter->cy_out);
UNUSED_PARAMETER(effect);
}
static const double downscale_vals[] = {
1.0,
1.25,
(1.0/0.75),
1.5,
(1.0/0.6),
1.75,
2.0,
2.25,
2.5,
2.75,
3.0
};
#define NUM_DOWNSCALES (sizeof(downscale_vals) / sizeof(double))
static const char *aspects[] = {
"16:9",
"16:10",
"4:3",
"1:1"
};
#define NUM_ASPECTS (sizeof(aspects) / sizeof(const char *))
static obs_properties_t *scale_filter_properties(void *data)
{
obs_properties_t *props = obs_properties_create();
struct obs_video_info ovi;
obs_property_t *p;
uint32_t cx;
uint32_t cy;
struct {
int cx;
int cy;
} downscales[NUM_DOWNSCALES];
/* ----------------- */
obs_get_video_info(&ovi);
cx = ovi.base_width;
cy = ovi.base_height;
for (size_t i = 0; i < NUM_DOWNSCALES; i++) {
downscales[i].cx = (int)((double)cx / downscale_vals[i]);
downscales[i].cy = (int)((double)cy / downscale_vals[i]);
}
p = obs_properties_add_list(props, S_SAMPLING, T_SAMPLING,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_property_list_add_string(p, T_SAMPLING_POINT, S_SAMPLING_POINT);
obs_property_list_add_string(p, T_SAMPLING_BILINEAR, S_SAMPLING_BILINEAR);
obs_property_list_add_string(p, T_SAMPLING_BICUBIC, S_SAMPLING_BICUBIC);
obs_property_list_add_string(p, T_SAMPLING_LANCZOS, S_SAMPLING_LANCZOS);
/* ----------------- */
p = obs_properties_add_list(props, S_RESOLUTION, T_RESOLUTION,
OBS_COMBO_TYPE_EDITABLE, OBS_COMBO_FORMAT_STRING);
obs_property_list_add_string(p, T_NONE, T_NONE);
for (size_t i = 0; i < NUM_ASPECTS; i++)
obs_property_list_add_string(p, aspects[i], aspects[i]);
for (size_t i = 0; i < NUM_DOWNSCALES; i++) {
char str[32];
snprintf(str, 32, "%dx%d", downscales[i].cx, downscales[i].cy);
obs_property_list_add_string(p, str, str);
}
/* ----------------- */
UNUSED_PARAMETER(data);
return props;
}
static void scale_filter_defaults(obs_data_t *settings)
{
obs_data_set_default_string(settings, S_SAMPLING, S_SAMPLING_BICUBIC);
obs_data_set_default_string(settings, S_RESOLUTION, T_NONE);
}
static uint32_t scale_filter_width(void *data)
{
struct scale_filter_data *filter = data;
return (uint32_t)filter->cx_out;
}
static uint32_t scale_filter_height(void *data)
{
struct scale_filter_data *filter = data;
return (uint32_t)filter->cy_out;
}
struct obs_source_info scale_filter = {
.id = "scale_filter",
.type = OBS_SOURCE_TYPE_FILTER,
.output_flags = OBS_SOURCE_VIDEO,
.get_name = scale_filter_name,
.create = scale_filter_create,
.destroy = scale_filter_destroy,
.video_tick = scale_filter_tick,
.video_render = scale_filter_render,
.update = scale_filter_update,
.get_properties = scale_filter_properties,
.get_defaults = scale_filter_defaults,
.get_width = scale_filter_width,
.get_height = scale_filter_height
};

View file

@ -7,8 +7,10 @@ struct scroll_filter_data {
gs_effect_t *effect;
gs_eparam_t *param_add;
gs_eparam_t *param_mul;
gs_eparam_t *param_image;
struct vec2 scroll_speed;
gs_samplerstate_t *sampler;
bool limit_cx;
bool limit_cy;
uint32_t cx;
@ -29,10 +31,17 @@ static void *scroll_filter_create(obs_data_t *settings, obs_source_t *context)
struct scroll_filter_data *filter = bzalloc(sizeof(*filter));
char *effect_path = obs_module_file("crop_filter.effect");
struct gs_sampler_info sampler_info = {
.filter = GS_FILTER_LINEAR,
.address_u = GS_ADDRESS_WRAP,
.address_v = GS_ADDRESS_WRAP
};
filter->context = context;
obs_enter_graphics();
filter->effect = gs_effect_create_from_file(effect_path, NULL);
filter->sampler = gs_samplerstate_create(&sampler_info);
obs_leave_graphics();
bfree(effect_path);
@ -46,6 +55,8 @@ static void *scroll_filter_create(obs_data_t *settings, obs_source_t *context)
"add_val");
filter->param_mul = gs_effect_get_param_by_name(filter->effect,
"mul_val");
filter->param_image = gs_effect_get_param_by_name(filter->effect,
"image");
obs_source_update(context, settings);
return filter;
@ -57,6 +68,7 @@ static void scroll_filter_destroy(void *data)
obs_enter_graphics();
gs_effect_destroy(filter->effect);
gs_samplerstate_destroy(filter->sampler);
obs_leave_graphics();
bfree(filter);
@ -187,6 +199,8 @@ static void scroll_filter_render(void *data, gs_effect_t *effect)
gs_effect_set_vec2(filter->param_add, &filter->offset);
gs_effect_set_vec2(filter->param_mul, &mul_val);
gs_effect_set_next_sampler(filter->param_image, filter->sampler);
obs_source_process_filter_end(filter->context, filter->effect, cx, cy);
UNUSED_PARAMETER(effect);