From 7d9ad58ad682011409e8acfba65e9a76adb97fc4 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Fri, 10 Feb 2023 12:57:04 -0500 Subject: [PATCH] add pipeline base_time, start_time variables --- renderers/audio_renderer.h | 2 +- renderers/audio_renderer_gstreamer.c | 40 ++++++++++++++++------------ renderers/video_renderer.h | 2 +- renderers/video_renderer_gstreamer.c | 19 ++++++++----- uxplay.cpp | 9 ++++--- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/renderers/audio_renderer.h b/renderers/audio_renderer.h index da754b4..6825009 100644 --- a/renderers/audio_renderer.h +++ b/renderers/audio_renderer.h @@ -34,7 +34,7 @@ extern "C" { bool gstreamer_init(); void audio_renderer_init(logger_t *logger, const char* audiosink, const bool *audio_sync); -void audio_renderer_start(unsigned char* compression_type); +void audio_renderer_start(unsigned char* compression_type, uint64_t *base_time, uint64_t *start_time); void audio_renderer_stop(); void audio_renderer_render_buffer(unsigned char* data, int *data_len, unsigned short *seqnum, uint64_t *ntp_time); void audio_renderer_set_volume(float volume); diff --git a/renderers/audio_renderer_gstreamer.c b/renderers/audio_renderer_gstreamer.c index 97ee8f7..684a089 100644 --- a/renderers/audio_renderer_gstreamer.c +++ b/renderers/audio_renderer_gstreamer.c @@ -26,6 +26,22 @@ #include "audio_renderer.h" #define SECOND_IN_NSECS 1000000000UL +#define NFORMATS 2 /* set to 4 to enable AAC_LD and PCM: allowed, but never seen in real-world use */ + +static GstClockTime gst_audio_pipeline_base_time = GST_CLOCK_TIME_NONE; +static GstClockTime gst_audio_pipeline_start_time = GST_CLOCK_TIME_NONE; +static logger_t *logger = NULL; +const char * format[NFORMATS]; + +typedef struct audio_renderer_s { + GstElement *appsrc; + GstElement *pipeline; + GstElement *volume; + unsigned char ct; +} audio_renderer_t ; +static audio_renderer_t *renderer_type[NFORMATS]; +static audio_renderer_t *renderer = NULL; + /* GStreamer Caps strings for Airplay-defined audio compression types (ct) */ /* ct = 1; linear PCM (uncompressed): 44100/16/2, S16LE */ @@ -41,14 +57,6 @@ static const char aac_lc_caps[] ="audio/mpeg,mpegversion=(int)4,channnels=(int)2 /* ct = 8; codec_data from MPEG v4 ISO 14996-3 Section 1.6.2.1: AAC_ELD 44100/2 spf = 480 */ static const char aac_eld_caps[] ="audio/mpeg,mpegversion=(int)4,channnels=(int)2,rate=(int)44100,stream-format=raw,codec_data=(buffer)f8e85000"; -typedef struct audio_renderer_s { - GstElement *appsrc; - GstElement *pipeline; - GstElement *volume; - unsigned char ct; -} audio_renderer_t ; - - static gboolean check_plugins (void) { int i; @@ -78,13 +86,6 @@ bool gstreamer_init(){ return (bool) check_plugins (); } -#define NFORMATS 2 /* set to 4 to enable AAC_LD and PCM: allowed, but never seen in real-world use */ -static audio_renderer_t *renderer_type[NFORMATS]; -static audio_renderer_t *renderer = NULL; -static GstClockTime gst_audio_pipeline_base_time = GST_CLOCK_TIME_NONE; -static logger_t *logger = NULL; -const char * format[NFORMATS]; - void audio_renderer_init(logger_t *render_logger, const char* audiosink, const bool* audio_sync) { GError *error = NULL; GstCaps *caps = NULL; @@ -179,7 +180,7 @@ void audio_renderer_stop() { } } -void audio_renderer_start(unsigned char *ct) { +void audio_renderer_start(unsigned char *ct, uint64_t *base_time, uint64_t *start_time) { unsigned char compression_type = 0, id; for (int i = 0; i < NFORMATS; i++) { if(renderer_type[i]->ct == *ct) { @@ -196,16 +197,21 @@ void audio_renderer_start(unsigned char *ct) { renderer = renderer_type[id]; gst_element_set_state (renderer->pipeline, GST_STATE_PLAYING); gst_audio_pipeline_base_time = gst_element_get_base_time(renderer->appsrc); + *base_time = gst_audio_pipeline_base_time; + gst_audio_pipeline_start_time = gst_element_get_start_time(renderer->appsrc); + *start_time = gst_audio_pipeline_base_time; } } else if (compression_type) { logger_log(logger, LOGGER_INFO, "start audio connection, format %s", format[id]); renderer = renderer_type[id]; gst_element_set_state (renderer->pipeline, GST_STATE_PLAYING); gst_audio_pipeline_base_time = gst_element_get_base_time(renderer->appsrc); + *base_time = gst_audio_pipeline_base_time; + gst_audio_pipeline_start_time = gst_element_get_start_time(renderer->appsrc); + *start_time = gst_audio_pipeline_base_time; } else { logger_log(logger, LOGGER_ERR, "unknown audio compression type ct = %d", *ct); } - } void audio_renderer_render_buffer(unsigned char* data, int *data_len, unsigned short *seqnum, uint64_t *ntp_time) { diff --git a/renderers/video_renderer.h b/renderers/video_renderer.h index 8a604fa..f8ef3d1 100644 --- a/renderers/video_renderer.h +++ b/renderers/video_renderer.h @@ -49,7 +49,7 @@ typedef struct video_renderer_s video_renderer_t; void video_renderer_init (logger_t *logger, const char *server_name, videoflip_t videoflip[2], const char *parser, const char *decoder, const char *converter, const char *videosink, const bool *fullscreen); -void video_renderer_start (); +void video_renderer_start (uint64_t *base_time, uint64_t *start_time); void video_renderer_stop (); void video_renderer_render_buffer (unsigned char* data, int *data_len, int *nal_count, uint64_t *ntp_time); void video_renderer_flush (); diff --git a/renderers/video_renderer_gstreamer.c b/renderers/video_renderer_gstreamer.c index 9c424d2..0dd2aec 100644 --- a/renderers/video_renderer_gstreamer.c +++ b/renderers/video_renderer_gstreamer.c @@ -34,6 +34,14 @@ static bool alt_keypress = false; static unsigned char X11_search_attempts; #endif +static video_renderer_t *renderer = NULL; +static GstClockTime gst_video_pipeline_base_time = GST_CLOCK_TIME_NONE; +static GstClockTime gst_video_pipeline_start_time = GST_CLOCK_TIME_NONE; +static logger_t *logger = NULL; +static unsigned short width, height, width_source, height_source; /* not currently used */ +static bool first_packet = false; + + struct video_renderer_s { GstElement *appsrc, *pipeline, *sink; GstBus *bus; @@ -100,12 +108,6 @@ static void append_videoflip (GString *launch, const videoflip_t *flip, const vi } } -static video_renderer_t *renderer = NULL; -static GstClockTime gst_video_pipeline_base_time = GST_CLOCK_TIME_NONE; -static logger_t *logger = NULL; -static unsigned short width, height, width_source, height_source; /* not currently used */ -static bool first_packet = false; - /* apple uses colorimetry=1:3:5:1 * * (not recognized by v4l2 plugin in Gstreamer < 1.20.4) * * See .../gst-libs/gst/video/video-color.h in gst-plugins-base * @@ -212,9 +214,12 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide } } -void video_renderer_start() { +void video_renderer_start(uint64_t *base_time, uint64_t *start_time) { gst_element_set_state (renderer->pipeline, GST_STATE_PLAYING); gst_video_pipeline_base_time = gst_element_get_base_time(renderer->appsrc); + gst_video_pipeline_start_time = gst_element_get_start_time(renderer->appsrc); + *base_time = (uint64_t) gst_video_pipeline_base_time; + *start_time = (uint64_t) gst_video_pipeline_start_time; renderer->bus = gst_element_get_bus(renderer->pipeline); first_packet = true; #ifdef X_DISPLAY_FIX diff --git a/uxplay.cpp b/uxplay.cpp index 5ee2f19..082751e 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -111,6 +111,9 @@ static bool bt709_fix = false; static int max_connections = 2; static unsigned short raop_port; static unsigned short airplay_port; +static uint64_t audio_base_time, audio_start_time, video_base_time, video_start_time; + + /* 95 byte png file with a 1x1 white square (single pixel): placeholder for coverart*/ static const unsigned char empty_image[] = { @@ -1043,7 +1046,7 @@ extern "C" void audio_get_format (void *cls, unsigned char *ct, unsigned short * audio_type = type; if (use_audio) { - audio_renderer_start(ct); + audio_renderer_start(ct, &audio_base_time, &audio_start_time); } if (coverart_filename.length()) { @@ -1294,7 +1297,7 @@ int main (int argc, char *argv[]) { if (use_video) { video_renderer_init(render_logger, server_name.c_str(), videoflip, video_parser.c_str(), video_decoder.c_str(), video_converter.c_str(), videosink.c_str(), &fullscreen); - video_renderer_start(); + video_renderer_start(&video_base_time, &video_start_time); } if (udp[0]) { @@ -1347,7 +1350,7 @@ int main (int argc, char *argv[]) { video_renderer_destroy(); video_renderer_init(render_logger, server_name.c_str(), videoflip, video_parser.c_str(), video_decoder.c_str(), video_converter.c_str(), videosink.c_str(), &fullscreen); - video_renderer_start(); + video_renderer_start(&video_base_time, &video_start_time); } if (relaunch_video) { unsigned short port = raop_get_port(raop);