diff options
| author | 2025-01-05 20:42:51 -0500 | |
|---|---|---|
| committer | 2025-01-05 20:42:51 -0500 | |
| commit | 240ee00a9177d6ff80ef48ce577b06d93cb554c2 (patch) | |
| tree | 0f759e7a9fe28ae0d21a54917ca893131aef9dda /src | |
| parent | 9362f2223038b59954c8402963932b4eb77030be (diff) | |
| download | camu-240ee00a9177d6ff80ef48ce577b06d93cb554c2.tar.gz camu-240ee00a9177d6ff80ef48ce577b06d93cb554c2.tar.bz2 camu-240ee00a9177d6ff80ef48ce577b06d93cb554c2.zip | |
Temp fix for stream selection, compile fixes
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src')
| -rw-r--r-- | src/codec/codec.h | 19 | ||||
| -rw-r--r-- | src/codec/ffmpeg/common.c | 10 | ||||
| -rw-r--r-- | src/liana/client.c | 48 | ||||
| -rw-r--r-- | src/liana/handlers/codec_client.c | 2 | ||||
| -rw-r--r-- | src/libsink/sink.c | 31 | ||||
| -rw-r--r-- | src/screen/screen.c | 1 |
6 files changed, 65 insertions, 46 deletions
diff --git a/src/codec/codec.h b/src/codec/codec.h index 6ddcff9..fac3be8 100644 --- a/src/codec/codec.h +++ b/src/codec/codec.h @@ -255,20 +255,23 @@ static inline s32 camu_audio_format_bytes_per_sample(struct camu_audio_format *f #else switch (fmt->format) { case CAMU_SAMPLE_FORMAT_U8: - case CAMU_SAMPLE_FORMAT_U8P: return 1; + case CAMU_SAMPLE_FORMAT_U8P: + return 1; case CAMU_SAMPLE_FORMAT_S16: - case CAMU_SAMPLE_FORMAT_S16P: return 2; + case CAMU_SAMPLE_FORMAT_S16P: + return 2; case CAMU_SAMPLE_FORMAT_S32: case CAMU_SAMPLE_FORMAT_S32P: case CAMU_SAMPLE_FORMAT_FLT: - case CAMU_SAMPLE_FORMAT_FLTP: return 4; + case CAMU_SAMPLE_FORMAT_FLTP: + return 4; case CAMU_SAMPLE_FORMAT_S64: case CAMU_SAMPLE_FORMAT_S64P: case CAMU_SAMPLE_FORMAT_DBL: - case CAMU_SAMPLE_FORMAT_DBLP: return 8; + case CAMU_SAMPLE_FORMAT_DBLP: + return 8; default: - al_assert(false); - return -1; + al_assert_and_return(-1); } #endif } @@ -323,8 +326,8 @@ static const char *camu_pixel_format_name(s32 format) case CAMU_PIXEL_FORMAT_RGB: return "rgb"; case CAMU_PIXEL_FORMAT_GREYA: return "grey + alpha"; case CAMU_PIXEL_FORMAT_GREY: return "grey"; + default: return "(unknown)"; } - return "(unknown)"; } static inline s32 camu_pixel_format_from_channels(s32 channels) @@ -334,7 +337,7 @@ static inline s32 camu_pixel_format_from_channels(s32 channels) case 3: return CAMU_PIXEL_FORMAT_RGB; case 2: return CAMU_PIXEL_FORMAT_GREYA; case 1: return CAMU_PIXEL_FORMAT_GREY; - default: al_assert(false); return CAMU_PIXEL_FORMAT_GREY; + default: al_assert_and_return(CAMU_PIXEL_FORMAT_GREY); } } diff --git a/src/codec/ffmpeg/common.c b/src/codec/ffmpeg/common.c index b2e727d..95bf247 100644 --- a/src/codec/ffmpeg/common.c +++ b/src/codec/ffmpeg/common.c @@ -10,18 +10,20 @@ void camu_ff_set_log_callback(void (*callback)(void *, s32, const char *, va_lis } static char *buf = NULL; -static s32 pos = 0; +static size_t pos = 0; // If a line takes more than 2 steps to print, make sure we stay within AL_LOG_MESSAGE_SIZE. -#define CHUNK_SIZE (AL_LOG_MESSAGE_SIZE / 2) +#define CHUNK_SIZE (AL_LOG_MESSAGE_SIZE / 2u) static void av_log_callback(void *userdata, s32 level, const char *fmt, va_list args) { (void)userdata; al_assert(buf); if (level < AV_LOG_DEBUG) { - pos += al_vsnprintf(&buf[pos], CHUNK_SIZE, fmt, args); - if (buf[pos - 1] == '\n' || pos >= CHUNK_SIZE) { + s32 ret = al_vsnprintf(&buf[pos], CHUNK_SIZE, fmt, args); + al_assert(ret > 0); + pos += ret; + if ((pos > 0 && buf[pos - 1] == '\n') || pos >= CHUNK_SIZE) { if (level <= AV_LOG_INFO) { al_log_info("ff", buf); } else { diff --git a/src/liana/client.c b/src/liana/client.c index daf32b0..b6635af 100644 --- a/src/liana/client.c +++ b/src/liana/client.c @@ -22,6 +22,12 @@ static void parse_info_packet(struct lia_client *client, struct nn_packet *packe str liana; nn_packet_read_str(packet, &liana); client->duration = nn_packet_read_u64(packet); + // TODO: This should be made into 2 steps. + // 1. Collect all streams into an array + // 2. Perform selection based on prefrences. + bool have_audio = false; + bool have_video = false; + bool have_subs = false; u32 count = nn_packet_read_u32(packet); for (u32 i = 0; i < count; i++) { u8 mode = nn_packet_read_u8(packet); @@ -52,37 +58,42 @@ static void parse_info_packet(struct lia_client *client, struct nn_packet *packe } #ifdef CAMU_HAVE_FFMPEG case CAMU_FFMPEG_COMPAT: { + enum AVCodecID codec_id = nn_packet_read_av_codec_id(packet); + const AVCodec *codec = avcodec_find_decoder(codec_id); + AVFormatContext *format_context = avformat_alloc_context(); + AVStream *stream = nn_packet_read_av_stream(format_context, codec, packet); switch (type) { case CAMU_STREAM_AUDIO: + if (have_audio) { + goto skip; + } client->mask |= 1 << index; + have_audio = true; break; case CAMU_STREAM_VIDEO: + if (have_video) { + goto skip; + } client->mask |= 1 << index; + have_video = true; break; case CAMU_STREAM_SUBTITLE: + if (have_subs || codec_id != AV_CODEC_ID_ASS) { + goto skip; + } client->mask |= 1 << index; + have_subs = true; break; - case CAMU_STREAM_ATTACHMENT: - // Assume all the data we need is in the AVStream object. - break; - default: - continue; - } - enum AVCodecID codec_id = nn_packet_read_av_codec_id(packet); - const AVCodec *codec = avcodec_find_decoder(codec_id); - AVFormatContext *format_context = avformat_alloc_context(); - AVStream *stream = nn_packet_read_av_stream(format_context, codec, packet); - if (type == CAMU_STREAM_SUBTITLE && codec_id != AV_CODEC_ID_ASS) { - client->mask &= ~(1 << index); - continue; - } - if (type == CAMU_STREAM_ATTACHMENT) { + case CAMU_STREAM_ATTACHMENT: { struct camu_codec_stream attachment; attachment.type = CAMU_STREAM_ATTACHMENT; attachment.av.stream = stream; client->callback(client->userdata, LIANA_CLIENT_CONFIGURE, &attachment, track); - avformat_free_context(format_context); - continue; + // Assume all the data we need is in the AVStream object. + // fallthrough + } + default: + goto skip; } track = al_alloc_object(struct lia_vcr_track); track->stream.av.format_context = format_context; @@ -95,6 +106,9 @@ static void parse_info_packet(struct lia_client *client, struct nn_packet *packe fmt->channel_count = stream->codecpar->ch_layout.nb_channels; } break; +skip: + avformat_free_context(format_context); + continue; } #endif } diff --git a/src/liana/handlers/codec_client.c b/src/liana/handlers/codec_client.c index 2492533..0aef69f 100644 --- a/src/liana/handlers/codec_client.c +++ b/src/liana/handlers/codec_client.c @@ -65,9 +65,11 @@ static bool codec_client_handle_packet(struct lia_client_handler *handler, struc case CAMU_NORMAL: codec->dec->push(codec->dec, NULL); break; +#ifdef CAMU_HAVE_FFMPEG case CAMU_FFMPEG_COMPAT: codec->dec->push_av_packet(codec->dec, NULL); break; +#endif } // process() could still error. s32 ret = codec->dec->process(codec->dec); diff --git a/src/libsink/sink.c b/src/libsink/sink.c index 97f1d66..03f76b7 100644 --- a/src/libsink/sink.c +++ b/src/libsink/sink.c @@ -65,11 +65,6 @@ enum { #define VIDEO_EMPTY(entry) BUFFER_EMPTY(&(entry)->video) #endif -#define AUDIO_NOT_EMPTY(entry) BUFFER_NOT_EMPTY(&(entry)->audio) -#ifndef CAMU_SINK_NO_VIDEO -#define VIDEO_NOT_EMPTY(entry) BUFFER_NOT_EMPTY(&(entry)->video) -#endif - #define AUDIO_ADDED_OR_EMPTY(entry) ((entry)->audio.state == BUFFER_ADDED || BUFFER_EMPTY(&(entry)->audio)) #ifndef CAMU_SINK_NO_VIDEO #define VIDEO_ADDED_OR_EMPTY(entry) ((entry)->video.state == BUFFER_ADDED || BUFFER_EMPTY(&(entry)->video)) @@ -237,7 +232,7 @@ static void sink_local_pause(struct camu_sink *sink, struct camu_sink_entry *ent if (camu_clock_is_paused(&entry->clock)) { entry->audio.buffer_paused = false; camu_clock_resume(&entry->clock, 0); - if (AUDIO_NOT_EMPTY(entry) && sink->audio.state == SINK_PAUSED) { + if (!AUDIO_EMPTY(entry) && sink->audio.state == SINK_PAUSED) { sink->callback(sink->userdata, CAMU_SINK_START, CAMU_SINK_AUDIO, NULL); sink->audio.state = SINK_PLAYING; } @@ -790,6 +785,7 @@ static void audio_buffer_callback(void *userdata, u8 op) break; } case CAMU_BUFFER_ERRORED: + al_log_error("sink", "Audio buffer errored."); break; } } @@ -817,7 +813,7 @@ static void video_buffer_callback(void *userdata, u8 op) bool swapped = false; nn_mutex_lock(&sink->mutex); al_log_info("sink", "Video EOF."); - if (AUDIO_NOT_EMPTY(entry)) { + if (!AUDIO_EMPTY(entry)) { camu_audio_buffer_set_no_video(&entry->audio.buf, true); } if (!VIDEO_IS_SINGLE_FRAME(entry)) { @@ -840,6 +836,7 @@ static void video_buffer_callback(void *userdata, u8 op) break; } case CAMU_BUFFER_ERRORED: + al_log_error("sink", "Video buffer errored."); break; } } @@ -874,7 +871,7 @@ static void evaluate_latency(struct camu_sink *sink, struct camu_sink_entry *ent { #ifdef CAMU_SINK_LOCAL #ifndef CAMU_SINK_NO_VIDEO - if (AUDIO_NOT_EMPTY(entry) && VIDEO_NOT_EMPTY(entry)) { + if (!AUDIO_EMPTY(entry) && !VIDEO_EMPTY(entry)) { f64 audio = camu_mixer_get_latency(sink->audio.mixer); s32 frames = audio / entry->video.buf.avg_frame_duration; frames -= sink->video.renderer->get_latency(sink->video.renderer); @@ -889,7 +886,7 @@ static void evaluate_latency(struct camu_sink *sink, struct camu_sink_entry *ent // latency directly into the audio buffer. f64 audio = camu_mixer_get_latency(sink->audio.mixer); #ifndef CAMU_SINK_NO_VIDEO - if (VIDEO_NOT_EMPTY(entry)) { + if (!VIDEO_EMPTY(entry)) { s32 frames = audio / entry->video.buf.avg_frame_duration; frames += sink->video.renderer->get_latency(sink->video.renderer); camu_video_buffer_set_latency(&entry->video.buf, frames); @@ -933,7 +930,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str } else if (entry->audio.state == BUFFER_INIT) { entry->audio.state = BUFFER_CONFIGURED; } else { - assert(false); + al_assert(false); } if (VIDEO_ADDED_OR_EMPTY(entry)) { evaluate_latency(sink, entry); @@ -954,7 +951,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str } else if (entry->video.state == BUFFER_INIT) { entry->video.state = BUFFER_CONFIGURED; } else { - assert(false); + al_assert(false); } if (AUDIO_ADDED_OR_EMPTY(entry)) { evaluate_latency(sink, entry); @@ -985,14 +982,14 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str struct camu_codec_frame *frame = (struct camu_codec_frame *)opaque; switch (stream->type) { case CAMU_STREAM_AUDIO: - if (AUDIO_NOT_EMPTY(entry)) { + if (!AUDIO_EMPTY(entry)) { camu_audio_buffer_push(&entry->audio.buf, frame); return; } break; #ifndef CAMU_SINK_NO_VIDEO case CAMU_STREAM_VIDEO: - if (VIDEO_NOT_EMPTY(entry)) { + if (!VIDEO_EMPTY(entry)) { camu_video_buffer_push(&entry->video.buf, frame); return; } @@ -1074,11 +1071,11 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str ) { BLOCKING_SLEEP(NNWT_TS_FROM_USEC(2000)); } if (reconnect) { - if (AUDIO_NOT_EMPTY(entry)) { + if (!AUDIO_EMPTY(entry)) { camu_audio_buffer_reset(&entry->audio.buf); } #ifndef CAMU_SINK_NO_VIDEO - if (VIDEO_NOT_EMPTY(entry) && !ignore_video) { + if (!VIDEO_EMPTY(entry) && !ignore_video) { camu_video_buffer_reset(&entry->video.buf); } #endif @@ -1122,7 +1119,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str case LIANA_CLIENT_EOF: { switch (stream->type) { case CAMU_STREAM_AUDIO: { - if (AUDIO_NOT_EMPTY(entry)) { + if (!AUDIO_EMPTY(entry)) { camu_audio_buffer_flush(&entry->audio.buf); } break; @@ -1130,7 +1127,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str #ifndef CAMU_SINK_NO_VIDEO case CAMU_STREAM_VIDEO: { // Single frames are immediately flushed inside the buffer. - if (VIDEO_NOT_EMPTY(entry) && !VIDEO_IS_SINGLE_FRAME(entry)) { + if (!VIDEO_EMPTY(entry) && !VIDEO_IS_SINGLE_FRAME(entry)) { camu_video_buffer_flush(&entry->video.buf); } break; diff --git a/src/screen/screen.c b/src/screen/screen.c index de7c8a7..e76650f 100644 --- a/src/screen/screen.c +++ b/src/screen/screen.c @@ -1,5 +1,6 @@ #include <al/log.h> #include <nnwt/thread.h> +#include <math.h> #include "view.h" #include "screen.h" |