summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build10
-rw-r--r--src/codec/ffmpeg/resampler.c2
-rw-r--r--src/codec/meson.build1
-rw-r--r--src/fruits/ctv/ctv.c102
-rw-r--r--src/fruits/ctv/meson.build4
-rw-r--r--src/fruits/droid/ctv/.gitignore3
-rw-r--r--src/fruits/droid/ctv/app/src/main/AndroidManifest.xml2
-rw-r--r--src/fruits/droid/ctv/app/src/main/jniLibs/arm64-v8a/.gitignore1
-rw-r--r--src/fruits/droid/ctv/app/src/main/jniLibs/armeabi-v7a/.gitignore1
-rw-r--r--src/fruits/droid/ctv/app/src/main/jniLibs/x86/.gitignore1
-rw-r--r--src/libsink/sink.c8
-rw-r--r--src/mixer/audio_miniaudio.c4
-rw-r--r--src/mixer/meson.build4
-rw-r--r--src/screen/screen.c4
-rw-r--r--src/screen/screen.h2
-rw-r--r--src/sink/common.h87
-rw-r--r--src/sink/desktop.c77
-rw-r--r--subprojects/packagefiles/ffmpeg/meson.build3
18 files changed, 215 insertions, 101 deletions
diff --git a/meson.build b/meson.build
index 0cc690b..e4bcfd9 100644
--- a/meson.build
+++ b/meson.build
@@ -68,12 +68,12 @@ if get_option('sink').enabled()
subdir('src/libsink')
subdir('src/sink')
if not meson.is_subproject()
- subdir('src/fruits/cmv')
+ if is_android
+ subdir('src/fruits/ctv')
+ else
+ subdir('src/fruits/cmv')
+ endif
endif
-endif
-
-if is_android
- subdir('src/fruits/ctv')
endif
if get_option('tests')
diff --git a/src/codec/ffmpeg/resampler.c b/src/codec/ffmpeg/resampler.c
index 00418e6..4f5a2ab 100644
--- a/src/codec/ffmpeg/resampler.c
+++ b/src/codec/ffmpeg/resampler.c
@@ -23,7 +23,7 @@ static bool ff_resampler_init(struct camu_resampler *resamp, struct camu_resampl
return false;
}
-#ifndef _WIN32
+#ifdef CAMU_HAVE_SOXR
// Slower but more accurate resampler.
av_opt_set_int(av->resample_context, "resampler", SWR_ENGINE_SOXR, 0);
#endif
diff --git a/src/codec/meson.build b/src/codec/meson.build
index 32a942e..fa5ff9a 100644
--- a/src/codec/meson.build
+++ b/src/codec/meson.build
@@ -43,6 +43,7 @@ if get_option('codecs').contains('ffmpeg')
soxr = compiler.find_library('soxr', required: false)
if soxr.found()
ffmpeg_deps += [soxr]
+ ffmpeg_args += ['-DCAMU_HAVE_SOXR']
endif
endif
endif
diff --git a/src/fruits/ctv/ctv.c b/src/fruits/ctv/ctv.c
index 9c45637..75936eb 100644
--- a/src/fruits/ctv/ctv.c
+++ b/src/fruits/ctv/ctv.c
@@ -1,26 +1,116 @@
#include <stl/window.h>
#include <stl/platform.h>
-#include "../../sink/desktop.h"
+#include "../../screen/screen.h"
+#include "../../render/renderer_libplacebo.h"
+#include "../../mixer/mixer.h"
+#include "../../libsink/sink.h"
+#include "../../mixer/audio_null.h"
+#include "../../mixer/audio_miniaudio.h"
+#include "../../sink/common.h"
+#include "../../server/common.c"
struct ctv {
struct aki_event_loop loop;
- struct camu_desktop desktop;
+ struct camu_screen scr;
+ struct camu_renderer *renderer;
+ struct camu_mixer mixer;
+ struct camu_sink sink;
+ struct aki_thread thread;
+ bool created;
};
-static void onSurfaceDestroyed(GLFMDisplay *display) {
+static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
+{
+ struct ctv *c = (struct ctv *)userdata;
+ if (!camu_default_sink_callback(&c->scr, &c->mixer, op, type, opaque)) {
+ camu_sink_close(&c->sink);
+ }
+ return CAMU_SINK_OK;
}
-static void onDraw(GLFMDisplay *display) {
+static void screen_callback(void *userdata, u8 op, void *opaque)
+{
+ struct ctv *c = (struct ctv *)userdata;
+ (void)c;
+ (void)op;
+ (void)opaque;
}
-void glfmMain(GLFMDisplay *display) {
+static aki_thread_result AKI_THREADCALL event_loop_thread(void *userdata)
+{
+ struct ctv *c = (struct ctv *)userdata;
+ aki_event_loop_run(&c->loop);
+ return 0;
+}
+
+static void onSurfaceCreated(GLFMDisplay *display, s32 width, s32 height)
+{
+ struct ctv *c = (struct ctv *)glfmGetUserData(display);
+ (void)width;
+ (void)height;
+ if (!c->created) {
+ c->scr.callback = screen_callback;
+ c->scr.userdata = c;
+ camu_screen_init(&c->scr, display);
+ camu_screen_create_window(&c->scr, "ctv");
+ c->renderer = camu_renderer_lp_create();
+ camu_screen_create_renderer(&c->scr, c->renderer);
+
+ camu_mixer_init(&c->mixer, camu_audio_miniaudio_create());
+ c->mixer.audio->configure_stream(c->mixer.audio, NULL);
+ camu_mixer_pick_format(&c->mixer, &c->mixer.fmt);
+
+ aki_event_loop_init(&c->loop);
+
+ camu_sink_init(&c->sink, &c->loop, &c->mixer, c->renderer);
+ c->sink.callback = sink_callback;
+ c->sink.userdata = c;
+ camu_sink_connect(&c->sink, AKI_SOCKET_TCP, CAMU_SERVER_IP, CAMU_PORT, al_str_c("ctv"));
+
+ aki_thread_create(&c->thread, event_loop_thread, c);
+
+ c->created = true;
+ }
+}
+
+static void onSurfaceDestroyed(GLFMDisplay *display)
+{
+ (void)display;
+}
+
+static void onDraw(GLFMDisplay *display)
+{
+ struct ctv *c = (struct ctv *)glfmGetUserData(display);
+ if (camu_screen_tick(&c->scr)) {
+ c->renderer->render(c->renderer, &c->scr);
+ }
+}
+
+static s32 log_callback(void *userdata, char *message)
+{
+ (void)userdata;
+ __android_log_print(ANDROID_LOG_DEBUG, "CTV", "%s", message);
+ s32 ret = al_strlen(message);
+ al_free(message);
+ return ret;
+}
+
+void glfmMain(GLFMDisplay *display)
+{
+ struct ctv *c = al_alloc_object(struct ctv);
+ c->created = false;
+
+ al_set_print(log_callback, c);
+
+ glfmSetUserData(display, c);
glfmSetDisplayConfig(display,
GLFMRenderingAPIOpenGLES2,
GLFMColorFormatRGBA8888,
GLFMDepthFormatNone,
GLFMStencilFormatNone,
GLFMMultisampleNone);
- glfmSetRenderFunc(display, onDraw);
+ glfmSetSurfaceCreatedFunc(display, onSurfaceCreated);
glfmSetSurfaceDestroyedFunc(display, onSurfaceDestroyed);
+ glfmSetRenderFunc(display, onDraw);
}
diff --git a/src/fruits/ctv/meson.build b/src/fruits/ctv/meson.build
index 768f9e1..c06cec3 100644
--- a/src/fruits/ctv/meson.build
+++ b/src/fruits/ctv/meson.build
@@ -1,6 +1,6 @@
ctv_src = ['ctv.c']
-ctv_deps = [desktop]
-ctv_args = []
+ctv_deps = [common_deps, buffer, render, screen, mixer, libsink]
+ctv_args = ['-DCAMU_MIXER_THREADED', '-DCAMU_SCREEN_THREADED']
# https://github.com/google/ExoPlayer/issues/9933#issuecomment-1029775358
shared_library('ctv', ctv_src, dependencies: ctv_deps, c_args: ctv_args, link_args: ['-Wl,-Bsymbolic', '-static-libstdc++'])
diff --git a/src/fruits/droid/ctv/.gitignore b/src/fruits/droid/ctv/.gitignore
index 9c951ae..565a541 100644
--- a/src/fruits/droid/ctv/.gitignore
+++ b/src/fruits/droid/ctv/.gitignore
@@ -14,6 +14,3 @@
.externalNativeBuild
.cxx
local.properties
-app/src/main/jniLibs/arm64-v8a/*
-app/src/main/jniLibs/armeabi-v7a/*
-app/src/main/jniLibs/x86/*
diff --git a/src/fruits/droid/ctv/app/src/main/AndroidManifest.xml b/src/fruits/droid/ctv/app/src/main/AndroidManifest.xml
index be6971b..4393ee9 100644
--- a/src/fruits/droid/ctv/app/src/main/AndroidManifest.xml
+++ b/src/fruits/droid/ctv/app/src/main/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
-
+ <uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
diff --git a/src/fruits/droid/ctv/app/src/main/jniLibs/arm64-v8a/.gitignore b/src/fruits/droid/ctv/app/src/main/jniLibs/arm64-v8a/.gitignore
new file mode 100644
index 0000000..64b29ac
--- /dev/null
+++ b/src/fruits/droid/ctv/app/src/main/jniLibs/arm64-v8a/.gitignore
@@ -0,0 +1 @@
+libctv.so
diff --git a/src/fruits/droid/ctv/app/src/main/jniLibs/armeabi-v7a/.gitignore b/src/fruits/droid/ctv/app/src/main/jniLibs/armeabi-v7a/.gitignore
new file mode 100644
index 0000000..64b29ac
--- /dev/null
+++ b/src/fruits/droid/ctv/app/src/main/jniLibs/armeabi-v7a/.gitignore
@@ -0,0 +1 @@
+libctv.so
diff --git a/src/fruits/droid/ctv/app/src/main/jniLibs/x86/.gitignore b/src/fruits/droid/ctv/app/src/main/jniLibs/x86/.gitignore
new file mode 100644
index 0000000..64b29ac
--- /dev/null
+++ b/src/fruits/droid/ctv/app/src/main/jniLibs/x86/.gitignore
@@ -0,0 +1 @@
+libctv.so
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 894dc40..538515a 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -537,7 +537,9 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
} else {
entry->audio.state = BUFFER_CONFIGURED;
}
- evaluate_latency(sink, entry);
+ if (VIDEO_READY_OR_EMPTY(entry)) {
+ evaluate_latency(sink, entry);
+ }
aki_mutex_unlock(&sink->mutex);
break;
#ifndef CAMU_SINK_NO_VIDEO
@@ -552,7 +554,9 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
} else {
entry->video.state = BUFFER_CONFIGURED;
}
- evaluate_latency(sink, entry);
+ if (AUDIO_READY_OR_EMPTY(entry)) {
+ evaluate_latency(sink, entry);
+ }
aki_mutex_unlock(&sink->mutex);
break;
#endif
diff --git a/src/mixer/audio_miniaudio.c b/src/mixer/audio_miniaudio.c
index 2f98335..4cb67de 100644
--- a/src/mixer/audio_miniaudio.c
+++ b/src/mixer/audio_miniaudio.c
@@ -188,6 +188,10 @@ static bool audio_miniaudio_configure_stream(struct camu_audio *audio, void *opa
static u64 audio_miniaudio_get_latency(struct camu_audio *audio)
{
struct camu_audio_miniaudio *ma = (struct camu_audio_miniaudio *)audio;
+ al_log_debug("audio_miniaudio", "periods: %u, period_size_in_frames: %u, sample_rate: %u.",
+ ma->device.playback.internalPeriods,
+ ma->device.playback.internalPeriodSizeInFrames,
+ ma->device.playback.internalSampleRate);
u32 periods = ma->device.playback.internalPeriods;
return (ma->device.playback.internalPeriodSizeInFrames * periods) /
(ma->device.playback.internalSampleRate / 1000000.0);
diff --git a/src/mixer/meson.build b/src/mixer/meson.build
index 0a2e9d7..7adc75c 100644
--- a/src/mixer/meson.build
+++ b/src/mixer/meson.build
@@ -1,4 +1,4 @@
-mixer_src = ['mixer.c']
+mixer_src = ['mixer.c', 'audio_null.c']
mixer_deps = [common_deps]
mixer_args = []
@@ -26,8 +26,6 @@ if use_miniaudio
elif is_android
mixer_args += ['-DMA_ENABLE_AAUDIO']
endif
-else
- mixer_src += ['audio_null.c']
endif
mixer = declare_dependency(sources: mixer_src, dependencies: mixer_deps, compile_args: mixer_args)
diff --git a/src/screen/screen.c b/src/screen/screen.c
index aa61ba6..bd6547f 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -259,12 +259,12 @@ static void key_immediate_callback(void *userdata, u8 state, u8 button)
}
}
-bool camu_screen_init(struct camu_screen *scr)
+bool camu_screen_init(struct camu_screen *scr, void *context)
{
al_atomic_store(s32)(&scr->state, CAMU_SCREEN_PAUSED, AL_ATOMIC_RELAXED);
al_array_init(scr->videos);
scr->renderer = NULL;
- scr->window = stl_window_create();
+ scr->window = stl_window_create(context);
scr->window->pointer_pos_callback = pointer_pos_callback;
scr->window->scroll_callback = scroll_callback;
scr->window->mouse_button_callback = mouse_button_callback;
diff --git a/src/screen/screen.h b/src/screen/screen.h
index 0c56cf9..bfb2dd3 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -67,7 +67,7 @@ struct camu_screen {
void *userdata;
};
-bool camu_screen_init(struct camu_screen *scr);
+bool camu_screen_init(struct camu_screen *scr, void *context);
bool camu_screen_create_window(struct camu_screen *scr, const char *name);
bool camu_screen_create_renderer(struct camu_screen *scr, struct camu_renderer *renderer);
void camu_screen_add_buffer(struct camu_screen *scr, struct camu_video_buffer *buf);
diff --git a/src/sink/common.h b/src/sink/common.h
new file mode 100644
index 0000000..ed84c39
--- /dev/null
+++ b/src/sink/common.h
@@ -0,0 +1,87 @@
+#include <al/log.h>
+
+#include "../screen/screen.h"
+#include "../mixer/mixer.h"
+#include "../libsink/sink.h"
+
+AL_UNUSED_FUNCTION_PUSH
+
+static bool camu_default_sink_callback(struct camu_screen *scr, struct camu_mixer *mixer, u8 op, u8 type, void *opaque)
+{
+ switch (op) {
+ case CAMU_SINK_ADD_BUFFER:
+ switch (type) {
+ case CAMU_SINK_AUDIO: {
+ struct camu_audio_buffer *buf = (struct camu_audio_buffer *)opaque;
+ camu_mixer_add_buffer(mixer, buf);
+ al_log_debug("camu_desktop", "Audio buffer added.");
+ break;
+ }
+ case CAMU_SINK_VIDEO: {
+ struct camu_video_buffer *buf = (struct camu_video_buffer *)opaque;
+ camu_screen_add_buffer(scr, buf);
+ al_log_debug("camu_desktop", "Video buffer added.");
+ break;
+ }
+ }
+ break;
+ case CAMU_SINK_REMOVE_BUFFER:
+ switch (type) {
+ case CAMU_SINK_AUDIO: {
+ struct camu_audio_buffer *buf = (struct camu_audio_buffer *)opaque;
+ camu_mixer_remove_buffer(mixer, buf);
+ al_log_debug("camu_desktop", "Audio buffer removed.");
+ break;
+ }
+ case CAMU_SINK_VIDEO: {
+ struct camu_video_buffer *buf = (struct camu_video_buffer *)opaque;
+ camu_screen_remove_buffer(scr, buf);
+ al_log_debug("camu_desktop", "Video buffer removed.");
+ break;
+ }
+ }
+ break;
+ case CAMU_SINK_SWAP_BUFFER:
+ switch (type) {
+ case CAMU_SINK_AUDIO: {
+ break;
+ }
+ }
+ break;
+ case CAMU_SINK_START:
+ switch (type) {
+ case CAMU_SINK_AUDIO: {
+ camu_mixer_resume(mixer);
+ al_log_info("camu_desktop", "Audio started.");
+ break;
+ }
+ case CAMU_SINK_VIDEO: {
+ camu_screen_set_state(scr, CAMU_SCREEN_PLAYING);
+ camu_screen_wake(scr);
+ al_log_info("camu_desktop", "Video started.");
+ break;
+ }
+ }
+ break;
+ case CAMU_SINK_STOP:
+ switch (type) {
+ case CAMU_SINK_AUDIO: {
+ camu_mixer_pause(mixer);
+ al_log_info("camu_desktop", "Audio stopped.");
+ break;
+ }
+ case CAMU_SINK_VIDEO: {
+ camu_screen_set_state(scr, CAMU_SCREEN_PAUSED);
+ al_log_info("camu_desktop", "Video stopped.");
+ break;
+ }
+ }
+ break;
+ case CAMU_SINK_EXIT:
+ return false;
+
+ }
+ return true;
+}
+
+AL_UNUSED_FUNCTION_POP
diff --git a/src/sink/desktop.c b/src/sink/desktop.c
index 2e2863f..efe835e 100644
--- a/src/sink/desktop.c
+++ b/src/sink/desktop.c
@@ -1,7 +1,7 @@
#include <al/log.h>
+#include "../mixer/audio_null.h"
#include "../mixer/audio_miniaudio.h"
-//#include "../mixer/audio_null.h"
#if defined CAMU_RENDERER_TIGER
#include "../render/renderer_tiger.h"
#elif defined CAMU_RENDERER_LIBPLACEBO
@@ -9,85 +9,16 @@
#endif
#include "desktop.h"
+#include "common.h"
static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
{
struct camu_desktop *c = (struct camu_desktop *)userdata;
- switch (op) {
- case CAMU_SINK_ADD_BUFFER:
- switch (type) {
- case CAMU_SINK_AUDIO: {
- struct camu_audio_buffer *buf = (struct camu_audio_buffer *)opaque;
- camu_mixer_add_buffer(&c->mixer, buf);
- al_log_debug("camu_desktop", "Audio buffer added.");
- break;
- }
- case CAMU_SINK_VIDEO: {
- struct camu_video_buffer *buf = (struct camu_video_buffer *)opaque;
- camu_screen_add_buffer(&c->scr, buf);
- al_log_debug("camu_desktop", "Video buffer added.");
- break;
- }
- }
- break;
- case CAMU_SINK_REMOVE_BUFFER:
- switch (type) {
- case CAMU_SINK_AUDIO: {
- struct camu_audio_buffer *buf = (struct camu_audio_buffer *)opaque;
- camu_mixer_remove_buffer(&c->mixer, buf);
- al_log_debug("camu_desktop", "Audio buffer removed.");
- break;
- }
- case CAMU_SINK_VIDEO: {
- struct camu_video_buffer *buf = (struct camu_video_buffer *)opaque;
- camu_screen_remove_buffer(&c->scr, buf);
- al_log_debug("camu_desktop", "Video buffer removed.");
- break;
- }
- }
- break;
- case CAMU_SINK_SWAP_BUFFER:
- switch (type) {
- case CAMU_SINK_AUDIO: {
- break;
- }
- }
- break;
- case CAMU_SINK_START:
- switch (type) {
- case CAMU_SINK_AUDIO: {
- camu_mixer_resume(&c->mixer);
- al_log_info("camu_desktop", "Audio started.");
- break;
- }
- case CAMU_SINK_VIDEO: {
- camu_screen_set_state(&c->scr, CAMU_SCREEN_PLAYING);
- camu_screen_wake(&c->scr);
- al_log_info("camu_desktop", "Video started.");
- break;
- }
- }
- break;
- case CAMU_SINK_STOP:
- switch (type) {
- case CAMU_SINK_AUDIO: {
- camu_mixer_pause(&c->mixer);
- al_log_info("camu_desktop", "Audio stopped.");
- break;
- }
- case CAMU_SINK_VIDEO: {
- camu_screen_set_state(&c->scr, CAMU_SCREEN_PAUSED);
- al_log_info("camu_desktop", "Video stopped.");
- break;
- }
- }
- break;
- case CAMU_SINK_EXIT:
+ if (!camu_default_sink_callback(&c->scr, &c->mixer, op, type, opaque)) {
camu_sink_close(&c->sink);
if (c->exit_callback) {
c->exit_callback(c->userdata, c);
}
- break;
}
return CAMU_SINK_OK;
}
@@ -131,7 +62,7 @@ bool camu_desktop_init(struct camu_desktop *c, const char *name)
{
c->scr.callback = screen_callback;
c->scr.userdata = c;
- if (!camu_screen_init(&c->scr) || !camu_screen_create_window(&c->scr, name)) {
+ if (!camu_screen_init(&c->scr, NULL) || !camu_screen_create_window(&c->scr, name)) {
return false;
}
#if defined CAMU_RENDERER_TIGER
diff --git a/subprojects/packagefiles/ffmpeg/meson.build b/subprojects/packagefiles/ffmpeg/meson.build
index 511b233..4ab44f7 100644
--- a/subprojects/packagefiles/ffmpeg/meson.build
+++ b/subprojects/packagefiles/ffmpeg/meson.build
@@ -13,7 +13,7 @@ is_mingw = is_windows and not is_msvc
extra_options = []
if not is_debug
- extra_options += ['--disable-debug', '--enable-small']
+ extra_options += ['--disable-debug']
endif
extra_options += ['--cc=' + compiler.cmd_array()[0]]
@@ -69,7 +69,6 @@ proj = ext_proj.add_project('configure',
'--enable-pic',
'--enable-static',
'--disable-shared',
- '--disable-stripping',
'--disable-logging',
'--disable-all',
'--disable-autodetect',