1230 lines
32 KiB
Diff
1230 lines
32 KiB
Diff
|
From acdda313bd35124e71b0dbdb76fe8e9eb6ec7e18 Mon Sep 17 00:00:00 2001
|
||
|
From: "jun.zeng" <jun.zeng@mediatek.com>
|
||
|
Date: Tue, 30 Jan 2018 16:10:14 +0800
|
||
|
Subject: [PATCH] gmrender
|
||
|
|
||
|
---
|
||
|
src/Makefile.am | 2 +-
|
||
|
src/dmr_ipc.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
src/dmr_ipc.h | 22 ++++++
|
||
|
src/logging.c | 19 +++++
|
||
|
src/logging.h | 29 ++++++-
|
||
|
src/main.c | 14 ++--
|
||
|
src/output.c | 44 +++++++++--
|
||
|
src/output.h | 1 +
|
||
|
src/output_gstreamer.c | 81 +++++++++++++++++++-
|
||
|
src/output_module.h | 1 +
|
||
|
src/song-meta-data.c | 28 +++++--
|
||
|
src/upnp_connmgr.c | 9 ++-
|
||
|
src/upnp_control.c | 4 +-
|
||
|
src/upnp_device.c | 10 +--
|
||
|
src/upnp_transport.c | 145 ++++++++++++++++++++++++++---------
|
||
|
src/webserver.c | 8 +-
|
||
|
16 files changed, 536 insertions(+), 82 deletions(-)
|
||
|
create mode 100644 src/dmr_ipc.c
|
||
|
create mode 100644 src/dmr_ipc.h
|
||
|
|
||
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
||
|
index 00323cf..84103ba 100644
|
||
|
--- a/src/Makefile.am
|
||
|
+++ b/src/Makefile.am
|
||
|
@@ -1,6 +1,6 @@
|
||
|
bin_PROGRAMS = gmediarender
|
||
|
|
||
|
-gmediarender_SOURCES = main.c git-version.h \
|
||
|
+gmediarender_SOURCES = main.c git-version.h dmr_ipc.h dmr_ipc.c \
|
||
|
upnp.c upnp_control.c upnp_connmgr.c upnp_transport.c \
|
||
|
upnp.h upnp_control.h upnp_connmgr.h upnp_transport.h \
|
||
|
song-meta-data.h song-meta-data.c \
|
||
|
diff --git a/src/dmr_ipc.c b/src/dmr_ipc.c
|
||
|
new file mode 100644
|
||
|
index 0000000..e0c0176
|
||
|
--- /dev/null
|
||
|
+++ b/src/dmr_ipc.c
|
||
|
@@ -0,0 +1,201 @@
|
||
|
+#include "dmr_ipc.h"
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+char buf_r[100];
|
||
|
+
|
||
|
+#define FIFO_TO_APP "/tmp/dlna_rev_fifo"
|
||
|
+#define FIFO_TO_DMR "/tmp/dlna_send_fifo"
|
||
|
+
|
||
|
+#define ipc_info(fmt...) \
|
||
|
+ printf("[Gmrender_IPC | %s][%d]: ", __FUNCTION__, __LINE__); \
|
||
|
+ printf(fmt); \
|
||
|
+ printf("\n");
|
||
|
+
|
||
|
+struct ipc_notify {
|
||
|
+ int (*play)(struct action_event *event);
|
||
|
+ int (*pause)(struct action_event *event);
|
||
|
+ int (*stop)(struct action_event *event);
|
||
|
+};
|
||
|
+
|
||
|
+struct ipc_notify* dmr_ipc_notify = NULL;
|
||
|
+
|
||
|
+static int recv_msg_from_app(void *arg)
|
||
|
+{
|
||
|
+ ipc_info("begin msg thread\n");
|
||
|
+ char buf_r[100];
|
||
|
+ int fd;
|
||
|
+ int nread;
|
||
|
+ if((mkfifo(FIFO_TO_DMR, O_CREAT | O_EXCL) < 0) && ( errno != EEXIST))
|
||
|
+ {
|
||
|
+ ipc_info("cann't craate fifoserver \n");
|
||
|
+ }
|
||
|
+
|
||
|
+ memset(buf_r, 0, sizeof(buf_r));
|
||
|
+
|
||
|
+ fd = open(FIFO_TO_DMR, O_RDONLY | O_NONBLOCK, 0);
|
||
|
+ if(-1 == fd)
|
||
|
+ {
|
||
|
+ ipc_info("open");
|
||
|
+ exit(1);
|
||
|
+ }
|
||
|
+
|
||
|
+ while(1)
|
||
|
+ {
|
||
|
+ memset(buf_r, 0, sizeof(buf_r));
|
||
|
+ nread = read(fd, buf_r, 100);
|
||
|
+ if (nread > 0 && dmr_ipc_notify != NULL)
|
||
|
+ {
|
||
|
+ if (0 == strcmp("0", buf_r))
|
||
|
+ {
|
||
|
+ ipc_info("recv stop msg from app\n");
|
||
|
+ dmr_ipc_notify->stop(NULL);
|
||
|
+ }else if (0 == strcmp("1", buf_r))
|
||
|
+ {
|
||
|
+ ipc_info("recv play msg from app\n");
|
||
|
+ dmr_ipc_notify->play(NULL);
|
||
|
+ }else if(0 == strcmp("2", buf_r))
|
||
|
+ {
|
||
|
+ ipc_info("recv pause msg from app\n");
|
||
|
+ dmr_ipc_notify->pause(NULL);
|
||
|
+ }
|
||
|
+ }else if (dmr_ipc_notify == NULL)
|
||
|
+ {
|
||
|
+ ipc_info("dmr_ipc_notify is null\n");
|
||
|
+ }
|
||
|
+ sleep(1);
|
||
|
+ }
|
||
|
+ pause();
|
||
|
+ ipc_info("end msg thread\n");
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static int create_thread()
|
||
|
+{
|
||
|
+ pthread_t a_thread;
|
||
|
+ int res;
|
||
|
+ res = pthread_create(&a_thread, NULL, recv_msg_from_app, NULL);
|
||
|
+ if(res != 0)
|
||
|
+ {
|
||
|
+ ipc_info("Thread creation failed");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int InitIPC(void *play_func, void *pause_func, void *stop_func)
|
||
|
+{
|
||
|
+ if(access(FIFO_TO_APP, F_OK) == -1)
|
||
|
+ {
|
||
|
+ if(mkfifo(FIFO_TO_APP, 0777 ) < 0)
|
||
|
+ {
|
||
|
+ ipc_info("cann't craate FIFO_TO_APP file\n");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if(access(FIFO_TO_DMR, F_OK) == -1)
|
||
|
+ {
|
||
|
+ if(mkfifo(FIFO_TO_DMR, 0777 ) < 0)
|
||
|
+ {
|
||
|
+ ipc_info("cann't craate FIFO_TO_DMR file\n");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ dmr_ipc_notify = (struct ipc_notify *) malloc(sizeof(struct ipc_notify));
|
||
|
+ dmr_ipc_notify->play = play_func;
|
||
|
+ dmr_ipc_notify->pause = pause_func;
|
||
|
+ dmr_ipc_notify->stop = stop_func;
|
||
|
+
|
||
|
+ create_thread();
|
||
|
+ ipc_info("exit from InitIPC()\n");
|
||
|
+ return 0;
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+int ReadIPC(void)
|
||
|
+{
|
||
|
+ int fd = open(FIFO_TO_APP, O_WRONLY, 0);
|
||
|
+ if(-1 == fd)
|
||
|
+ {
|
||
|
+ ipc_info("open error\n");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ ipc_info("open sus, fd:%d\n", fd);
|
||
|
+ }
|
||
|
+ int nread;
|
||
|
+ while(1)
|
||
|
+ {
|
||
|
+ memset(buf_r, 0, sizeof(buf_r));
|
||
|
+ nread = read(fd, buf_r, 100);
|
||
|
+ ipc_info("read %s from FIFO\n", buf_r);
|
||
|
+ sleep(1);
|
||
|
+ }
|
||
|
+ close(fd);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int WriteIPC(int int_status)
|
||
|
+{
|
||
|
+ int fd = open(FIFO_TO_APP, O_WRONLY, 0);
|
||
|
+ if(-1 == fd)
|
||
|
+ {
|
||
|
+ ipc_info("open error\n");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ int nwrite = 0;
|
||
|
+ char dmr_status = '0' + int_status;
|
||
|
+ if(-1 == (nwrite = write(fd, &dmr_status, 1)))
|
||
|
+ {
|
||
|
+ if(errno == EAGAIN)
|
||
|
+ {
|
||
|
+ ipc_info("Error, The FIFO has not been read yet, Please try later\n");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ ipc_info("write error\n");
|
||
|
+ }
|
||
|
+
|
||
|
+ }
|
||
|
+ else
|
||
|
+ { if ('0' == dmr_status)
|
||
|
+ {
|
||
|
+ ipc_info("send stop cmd to the APP\n");
|
||
|
+ }else if ('1' == dmr_status)
|
||
|
+ {
|
||
|
+ ipc_info("send play cmd to the APP\n");
|
||
|
+ }else if ('2' == dmr_status)
|
||
|
+ {
|
||
|
+ ipc_info("send pause cmd to the APP\n");
|
||
|
+ }else if ('3' == dmr_status)
|
||
|
+ {
|
||
|
+ ipc_info("send stopped done cmd to the APP\n");
|
||
|
+ }else if ('4' == dmr_status)
|
||
|
+ {
|
||
|
+ ipc_info("send played done cmd to the APP\n");
|
||
|
+ }else if ('5' == dmr_status)
|
||
|
+ {
|
||
|
+ ipc_info("send paused done cmd to the APP\n");
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+ close(fd);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+int StopIPC(void)
|
||
|
+{
|
||
|
+ unlink(FIFO_TO_APP);
|
||
|
+ ipc_info(" stop finish\n");
|
||
|
+ if (NULL != dmr_ipc_notify)
|
||
|
+ {
|
||
|
+ dmr_ipc_notify = NULL;
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
diff --git a/src/dmr_ipc.h b/src/dmr_ipc.h
|
||
|
new file mode 100644
|
||
|
index 0000000..398289b
|
||
|
--- /dev/null
|
||
|
+++ b/src/dmr_ipc.h
|
||
|
@@ -0,0 +1,22 @@
|
||
|
+#ifndef _DMRIPC_H
|
||
|
+#define _DMRIPC_H
|
||
|
+
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/stat.h>
|
||
|
+#include <errno.h>
|
||
|
+#include <fcntl.h>
|
||
|
+#include <stdio.h>
|
||
|
+#include <stdlib.h>
|
||
|
+#include <string.h>
|
||
|
+#include <unistd.h>
|
||
|
+
|
||
|
+#define FIFO_NAME "dmr_fifo"
|
||
|
+#define BUFFER_SIZE PIPE_BUF
|
||
|
+#define TEN_MEG (1024 * 1024 * 10)
|
||
|
+
|
||
|
+int InitIPC(void *play_func, void *pause_func, void *stop_func);
|
||
|
+int ReadIPC(void);
|
||
|
+int StopIPC(void);
|
||
|
+int WriteIPC(int int_status);
|
||
|
+
|
||
|
+#endif
|
||
|
diff --git a/src/logging.c b/src/logging.c
|
||
|
index 2d01477..e462d94 100644
|
||
|
--- a/src/logging.c
|
||
|
+++ b/src/logging.c
|
||
|
@@ -41,6 +41,7 @@
|
||
|
|
||
|
static int log_fd = -1;
|
||
|
static int enable_color = 0;
|
||
|
+int dlna_enable = 1;
|
||
|
|
||
|
static const char *const kInfoHighlight = "\033[1mINFO ";
|
||
|
static const char *const kErrorHighlight = "\033[1m\033[31mERROR ";
|
||
|
@@ -78,6 +79,18 @@ int Log_color_allowed(void) { return enable_color; }
|
||
|
int Log_info_enabled(void) { return log_fd >= 0; }
|
||
|
int Log_error_enabled(void) { return 1; }
|
||
|
|
||
|
+void enable_dlna_log()
|
||
|
+{
|
||
|
+ if(access(DLNA_ENABLE_PATH, F_OK) != -1)
|
||
|
+ {
|
||
|
+ Log_info("Logging", "dlna log enable");
|
||
|
+ dlna_enable = 1;
|
||
|
+ }else
|
||
|
+ {
|
||
|
+ Log_info("Logging", "dlna log disable");
|
||
|
+ dlna_enable = 0;
|
||
|
+ }
|
||
|
+}
|
||
|
static void Log_internal(int fd, const char *markup_start,
|
||
|
const char *category, const char *format,
|
||
|
va_list ap) {
|
||
|
@@ -106,6 +119,11 @@ static void Log_internal(int fd, const char *markup_start,
|
||
|
free(parts[1].iov_base);
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+/*
|
||
|
void Log_info(const char *category, const char *format, ...) {
|
||
|
if (log_fd < 0) return;
|
||
|
va_list ap;
|
||
|
@@ -121,3 +139,4 @@ void Log_error(const char *category, const char *format, ...) {
|
||
|
error_markup_start_, category, format, ap);
|
||
|
va_end(ap);
|
||
|
}
|
||
|
+*/
|
||
|
diff --git a/src/logging.h b/src/logging.h
|
||
|
index 6e4cd19..3635ce9 100644
|
||
|
--- a/src/logging.h
|
||
|
+++ b/src/logging.h
|
||
|
@@ -35,9 +35,30 @@ int Log_color_allowed(void); // Returns if we're allowed to use terminal color.
|
||
|
int Log_info_enabled(void);
|
||
|
int Log_error_enabled(void);
|
||
|
|
||
|
-void Log_info(const char *category, const char *format, ...)
|
||
|
- PRINTF_FMT_CHECK(2, 3);
|
||
|
-void Log_error(const char *category, const char *format, ...)
|
||
|
- PRINTF_FMT_CHECK(2, 3);
|
||
|
+#define DLNA_LOG_ENABLE 0
|
||
|
|
||
|
+#define Log_info(category, fmt...) \
|
||
|
+ printf("[GMR_%s | I | %s][%d]: ", category, __FUNCTION__, __LINE__); \
|
||
|
+ printf(fmt); \
|
||
|
+ printf("\n");
|
||
|
+
|
||
|
+
|
||
|
+#define Log_error(category, fmt...) \
|
||
|
+ printf("[GMR_%s | E | %s][%d]: ", category, __FUNCTION__, __LINE__); \
|
||
|
+ printf(fmt); \
|
||
|
+ printf("\n");
|
||
|
+
|
||
|
+#define Log_debug(category, fmt...) \
|
||
|
+ if (DLNA_LOG_ENABLE) \
|
||
|
+ {\
|
||
|
+ printf("[GMR_%s | D | %s][%d]: ", category, __FUNCTION__, __LINE__); \
|
||
|
+ printf(fmt); \
|
||
|
+ printf("\n"); \
|
||
|
+ }
|
||
|
+
|
||
|
+#ifndef GMR_IPC
|
||
|
+#define GMR_IPC 1
|
||
|
+#endif
|
||
|
+
|
||
|
+#define DLNA_ENABLE_PATH "/data/dlna_enable"
|
||
|
#endif /* _LOGGING_H */
|
||
|
diff --git a/src/main.c b/src/main.c
|
||
|
index 7b25014..631d895 100644
|
||
|
--- a/src/main.c
|
||
|
+++ b/src/main.c
|
||
|
@@ -164,7 +164,7 @@ static void log_variable_change(void *userdata, int var_num,
|
||
|
// Silly terminal codes. Set to empty strings if not needed.
|
||
|
const char *var_start = Log_color_allowed() ? "\033[1m\033[34m" : "";
|
||
|
const char *var_end = Log_color_allowed() ? "\033[0m" : "";
|
||
|
- Log_info(category, "%s%s%s: %s%s",
|
||
|
+ Log_debug(category, "%s%s%s: %s%s",
|
||
|
var_start, variable_name, var_end,
|
||
|
variable_value, needs_newline ? "\n" : "");
|
||
|
}
|
||
|
@@ -205,11 +205,10 @@ int main(int argc, char **argv)
|
||
|
#if !GLIB_CHECK_VERSION(2,32,0)
|
||
|
g_thread_init (NULL); // Was necessary < glib 2.32, deprecated since.
|
||
|
#endif
|
||
|
-
|
||
|
if (!process_cmdline(argc, argv)) {
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
-
|
||
|
+
|
||
|
if (show_version) {
|
||
|
do_show_version();
|
||
|
exit(EXIT_SUCCESS);
|
||
|
@@ -259,14 +258,12 @@ int main(int argc, char **argv)
|
||
|
if (upnp_renderer == NULL) {
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
-
|
||
|
- rc = output_init(output);
|
||
|
+ rc = output_init(NULL);
|
||
|
if (rc != 0) {
|
||
|
Log_error("main",
|
||
|
"ERROR: Failed to initialize Output subsystem");
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
-
|
||
|
struct upnp_device *device;
|
||
|
if (listen_port != 0 &&
|
||
|
(listen_port < 49152 || listen_port > 65535)) {
|
||
|
@@ -306,14 +303,13 @@ int main(int argc, char **argv)
|
||
|
|
||
|
// Write both to the log (which might be disabled) and console.
|
||
|
Log_info("main", "Ready for rendering.");
|
||
|
- fprintf(stderr, "Ready for rendering.\n");
|
||
|
+ Log_info("main", "Ready for rendering.\n");
|
||
|
|
||
|
output_loop();
|
||
|
|
||
|
// We're here, because the loop exited. Probably due to catching
|
||
|
// a signal.
|
||
|
- Log_info("main", "Exiting.");
|
||
|
upnp_device_shutdown(device);
|
||
|
-
|
||
|
+ Log_info("main", "Exiting.");
|
||
|
return EXIT_SUCCESS;
|
||
|
}
|
||
|
diff --git a/src/output.c b/src/output.c
|
||
|
index 451c6a3..0a575a2 100644
|
||
|
--- a/src/output.c
|
||
|
+++ b/src/output.c
|
||
|
@@ -50,6 +50,7 @@ static struct output_module *modules[] = {
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
+
|
||
|
static struct output_module *output_module = NULL;
|
||
|
|
||
|
void output_dump_modules(void)
|
||
|
@@ -70,8 +71,27 @@ void output_dump_modules(void)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+int output_gst_init()
|
||
|
+{
|
||
|
+ if (output_module->init) {
|
||
|
+ return output_module->init();
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+int output_gst_destroy()
|
||
|
+{
|
||
|
+ if (output_module->destroy) {
|
||
|
+ return output_module->destroy();
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
int output_init(const char *shortname)
|
||
|
{
|
||
|
+ if (output_module != NULL)
|
||
|
+ {
|
||
|
+ Log_error("output", "[%s]: no need, already init\n");
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
int count;
|
||
|
|
||
|
count = sizeof(modules) / sizeof(struct output_module *);
|
||
|
@@ -99,11 +119,11 @@ int output_init(const char *shortname)
|
||
|
|
||
|
Log_info("output", "Using output module: %s (%s)",
|
||
|
output_module->shortname, output_module->description);
|
||
|
-
|
||
|
- if (output_module->init) {
|
||
|
- return output_module->init();
|
||
|
+
|
||
|
+ if (output_module->init)
|
||
|
+ {
|
||
|
+ output_module->init();
|
||
|
}
|
||
|
-
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -148,6 +168,9 @@ int output_add_options(GOptionContext *ctx)
|
||
|
void output_set_uri(const char *uri, output_update_meta_cb_t meta_cb) {
|
||
|
if (output_module && output_module->set_uri) {
|
||
|
output_module->set_uri(uri, meta_cb);
|
||
|
+ }else
|
||
|
+ {
|
||
|
+ Log_error("output", "function pointer not be inited");
|
||
|
}
|
||
|
}
|
||
|
void output_set_next_uri(const char *uri) {
|
||
|
@@ -158,7 +181,11 @@ void output_set_next_uri(const char *uri) {
|
||
|
|
||
|
int output_play(output_transition_cb_t transition_callback) {
|
||
|
if (output_module && output_module->play) {
|
||
|
+ output_module->init();
|
||
|
return output_module->play(transition_callback);
|
||
|
+ }else
|
||
|
+ {
|
||
|
+ Log_error("output", "function pointer not be inited");
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
@@ -172,7 +199,12 @@ int output_pause(void) {
|
||
|
|
||
|
int output_stop(void) {
|
||
|
if (output_module && output_module->stop) {
|
||
|
- return output_module->stop();
|
||
|
+
|
||
|
+ output_module->stop();
|
||
|
+ return output_module->destroy();
|
||
|
+ }else
|
||
|
+ {
|
||
|
+ Log_error("output", "function pointer not be inited");
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
@@ -199,7 +231,7 @@ int output_get_volume(float *value) {
|
||
|
}
|
||
|
int output_set_volume(float value) {
|
||
|
if (output_module && output_module->set_volume) {
|
||
|
- return output_module->set_volume(value);
|
||
|
+ return output_module->set_volume(value * 10);
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
diff --git a/src/output.h b/src/output.h
|
||
|
index 9230752..9134460 100644
|
||
|
--- a/src/output.h
|
||
|
+++ b/src/output.h
|
||
|
@@ -40,6 +40,7 @@ typedef void (*output_transition_cb_t)(enum PlayFeedback);
|
||
|
typedef void (*output_update_meta_cb_t)(const struct SongMetaData *);
|
||
|
|
||
|
int output_init(const char *shortname);
|
||
|
+int output_gst_init(void);
|
||
|
int output_add_options(GOptionContext *ctx);
|
||
|
void output_dump_modules(void);
|
||
|
|
||
|
diff --git a/src/output_gstreamer.c b/src/output_gstreamer.c
|
||
|
index 72b9dfc..81da3bb 100644
|
||
|
--- a/src/output_gstreamer.c
|
||
|
+++ b/src/output_gstreamer.c
|
||
|
@@ -40,6 +40,8 @@
|
||
|
#include "output_module.h"
|
||
|
#include "output_gstreamer.h"
|
||
|
|
||
|
+static gboolean gst_has_inited = FALSE;
|
||
|
+
|
||
|
static void scan_caps(const GstCaps * caps)
|
||
|
{
|
||
|
guint i;
|
||
|
@@ -181,6 +183,11 @@ static void output_gstreamer_set_uri(const char *uri,
|
||
|
}
|
||
|
|
||
|
static int output_gstreamer_play(output_transition_cb_t callback) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
play_trans_callback_ = callback;
|
||
|
if (get_current_player_state() != GST_STATE_PAUSED) {
|
||
|
if (gst_element_set_state(player_, GST_STATE_READY) ==
|
||
|
@@ -188,6 +195,7 @@ static int output_gstreamer_play(output_transition_cb_t callback) {
|
||
|
Log_error("gstreamer", "setting play state failed (1)");
|
||
|
// Error, but continue; can't get worse :)
|
||
|
}
|
||
|
+ Log_info("gsteamer", "play url:%s", gsuri_);
|
||
|
g_object_set(G_OBJECT(player_), "uri", gsuri_, NULL);
|
||
|
}
|
||
|
if (gst_element_set_state(player_, GST_STATE_PLAYING) ==
|
||
|
@@ -198,7 +206,27 @@ static int output_gstreamer_play(output_transition_cb_t callback) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int output_gstreamer_destroy(void)
|
||
|
+{
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ SongMetaData_clear(&song_meta_);
|
||
|
+ gst_element_set_state(player_, GST_STATE_NULL);
|
||
|
+ gst_object_unref(GST_OBJECT (player_));
|
||
|
+ gst_has_inited = FALSE;
|
||
|
+ Log_info("gstreamer", "gstreamer destroy successfully");
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static int output_gstreamer_stop(void) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
if (gst_element_set_state(player_, GST_STATE_READY) ==
|
||
|
GST_STATE_CHANGE_FAILURE) {
|
||
|
return -1;
|
||
|
@@ -208,6 +236,11 @@ static int output_gstreamer_stop(void) {
|
||
|
}
|
||
|
|
||
|
static int output_gstreamer_pause(void) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
if (gst_element_set_state(player_, GST_STATE_PAUSED) ==
|
||
|
GST_STATE_CHANGE_FAILURE) {
|
||
|
return -1;
|
||
|
@@ -217,6 +250,11 @@ static int output_gstreamer_pause(void) {
|
||
|
}
|
||
|
|
||
|
static int output_gstreamer_seek(gint64 position_nanos) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
if (gst_element_seek(player_, 1.0, GST_FORMAT_TIME,
|
||
|
GST_SEEK_FLAG_FLUSH,
|
||
|
GST_SEEK_TYPE_SET, position_nanos,
|
||
|
@@ -376,8 +414,8 @@ static gboolean my_bus_callback(GstBus * bus, GstMessage * msg,
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
-static gchar *audio_sink = NULL;
|
||
|
-static gchar *audio_device = NULL;
|
||
|
+static gchar *audio_sink = "alsasink";
|
||
|
+static gchar *audio_device = "hw:0,0";
|
||
|
static gchar *videosink = NULL;
|
||
|
static double initial_db = 0.0;
|
||
|
|
||
|
@@ -417,6 +455,10 @@ static int output_gstreamer_add_options(GOptionContext *ctx)
|
||
|
|
||
|
static int output_gstreamer_get_position(gint64 *track_duration,
|
||
|
gint64 *track_pos) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
*track_duration = last_known_time_.duration;
|
||
|
*track_pos = last_known_time_.position;
|
||
|
|
||
|
@@ -446,6 +488,11 @@ static int output_gstreamer_get_position(gint64 *track_duration,
|
||
|
}
|
||
|
|
||
|
static int output_gstreamer_get_volume(float *v) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
double volume;
|
||
|
g_object_get(player_, "volume", &volume, NULL);
|
||
|
Log_info("gstreamer", "Query volume fraction: %f", volume);
|
||
|
@@ -453,17 +500,32 @@ static int output_gstreamer_get_volume(float *v) {
|
||
|
return 0;
|
||
|
}
|
||
|
static int output_gstreamer_set_volume(float value) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
Log_info("gstreamer", "Set volume fraction to %f", value);
|
||
|
g_object_set(player_, "volume", (double) value, NULL);
|
||
|
return 0;
|
||
|
}
|
||
|
static int output_gstreamer_get_mute(int *m) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
gboolean val;
|
||
|
g_object_get(player_, "mute", &val, NULL);
|
||
|
*m = val;
|
||
|
return 0;
|
||
|
}
|
||
|
static int output_gstreamer_set_mute(int m) {
|
||
|
+ if (!gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "error, not init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
Log_info("gstreamer", "Set mute to %s", m ? "on" : "off");
|
||
|
g_object_set(player_, "mute", (gboolean) m, NULL);
|
||
|
return 0;
|
||
|
@@ -486,8 +548,15 @@ static void prepare_next_stream(GstElement *obj, gpointer userdata) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+
|
||
|
static int output_gstreamer_init(void)
|
||
|
{
|
||
|
+
|
||
|
+ if (gst_has_inited)
|
||
|
+ {
|
||
|
+ Log_info("gstreamer", "no need, already init");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
GstBus *bus;
|
||
|
|
||
|
SongMetaData_init(&song_meta_);
|
||
|
@@ -505,7 +574,7 @@ static int output_gstreamer_init(void)
|
||
|
bus = gst_pipeline_get_bus(GST_PIPELINE(player_));
|
||
|
gst_bus_add_watch(bus, my_bus_callback, NULL);
|
||
|
gst_object_unref(bus);
|
||
|
-
|
||
|
+
|
||
|
if (audio_sink != NULL) {
|
||
|
GstElement *sink = NULL;
|
||
|
Log_info("gstreamer", "Setting audio sink to %s; device=%s\n",
|
||
|
@@ -521,6 +590,7 @@ static int output_gstreamer_init(void)
|
||
|
g_object_set (G_OBJECT (player_), "audio-sink", sink, NULL);
|
||
|
}
|
||
|
}
|
||
|
+
|
||
|
if (videosink != NULL) {
|
||
|
GstElement *sink = NULL;
|
||
|
Log_info("gstreamer", "Setting video sink to %s", videosink);
|
||
|
@@ -539,7 +609,9 @@ static int output_gstreamer_init(void)
|
||
|
if (initial_db < 0) {
|
||
|
output_gstreamer_set_volume(exp(initial_db / 20 * log(10)));
|
||
|
}
|
||
|
-
|
||
|
+
|
||
|
+ Log_info("gstreamer", "gstreamer init successfully");
|
||
|
+ gst_has_inited = TRUE;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -547,6 +619,7 @@ struct output_module gstreamer_output = {
|
||
|
.shortname = "gst",
|
||
|
.description = "GStreamer multimedia framework",
|
||
|
.init = output_gstreamer_init,
|
||
|
+ .destroy = output_gstreamer_destroy,
|
||
|
.add_options = output_gstreamer_add_options,
|
||
|
.set_uri = output_gstreamer_set_uri,
|
||
|
.set_next_uri= output_gstreamer_set_next_uri,
|
||
|
diff --git a/src/output_module.h b/src/output_module.h
|
||
|
index d4250ef..9afa152 100644
|
||
|
--- a/src/output_module.h
|
||
|
+++ b/src/output_module.h
|
||
|
@@ -33,6 +33,7 @@ struct output_module {
|
||
|
|
||
|
// Commands.
|
||
|
int (*init)(void);
|
||
|
+ int (*destroy)(void);
|
||
|
void (*set_uri)(const char *uri, output_update_meta_cb_t meta_info);
|
||
|
void (*set_next_uri)(const char *uri);
|
||
|
int (*play)(output_transition_cb_t transition_callback);
|
||
|
diff --git a/src/song-meta-data.c b/src/song-meta-data.c
|
||
|
index 1727d2e..c6c3850 100644
|
||
|
--- a/src/song-meta-data.c
|
||
|
+++ b/src/song-meta-data.c
|
||
|
@@ -38,14 +38,26 @@ void SongMetaData_init(struct SongMetaData *value) {
|
||
|
memset(value, 0, sizeof(struct SongMetaData));
|
||
|
}
|
||
|
void SongMetaData_clear(struct SongMetaData *value) {
|
||
|
- free((char*)value->title);
|
||
|
- value->title = NULL;
|
||
|
- free((char*)value->artist);
|
||
|
- value->artist = NULL;
|
||
|
- free((char*)value->album);
|
||
|
- value->album = NULL;
|
||
|
- free((char*)value->genre);
|
||
|
- value->genre = NULL;
|
||
|
+ if (value->title != NULL)
|
||
|
+ {
|
||
|
+ free((char*)value->title);
|
||
|
+ value->title = NULL;
|
||
|
+ }
|
||
|
+ if (value->artist != NULL)
|
||
|
+ {
|
||
|
+ free((char*)value->artist);
|
||
|
+ value->artist = NULL;
|
||
|
+ }
|
||
|
+ if (value->album != NULL)
|
||
|
+ {
|
||
|
+ free((char*)value->album);
|
||
|
+ value->album = NULL;
|
||
|
+ }
|
||
|
+ if (value->genre != NULL)
|
||
|
+ {
|
||
|
+ free((char*)value->genre);
|
||
|
+ value->genre = NULL;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
static const char kDidlHeader[] = "<DIDL-Lite "
|
||
|
diff --git a/src/upnp_connmgr.c b/src/upnp_connmgr.c
|
||
|
index 97257e7..9ccf258 100644
|
||
|
--- a/src/upnp_connmgr.c
|
||
|
+++ b/src/upnp_connmgr.c
|
||
|
@@ -198,7 +198,7 @@ static void register_mime_type_internal(const char *mime_type) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
- Log_info("connmgr", "Registering support for '%s'", mime_type);
|
||
|
+ Log_debug("connmgr", "Registering support for '%s'", mime_type);
|
||
|
|
||
|
entry = malloc(sizeof(struct mime_type));
|
||
|
entry->mime_type = strdup(mime_type);
|
||
|
@@ -207,6 +207,10 @@ static void register_mime_type_internal(const char *mime_type) {
|
||
|
}
|
||
|
|
||
|
void register_mime_type(const char *mime_type) {
|
||
|
+ if (strstr(mime_type, "audio/")== NULL)
|
||
|
+ {
|
||
|
+ return;
|
||
|
+ }
|
||
|
register_mime_type_internal(mime_type);
|
||
|
if (strcmp("audio/mpeg", mime_type) == 0) {
|
||
|
register_mime_type_internal("audio/x-mpeg");
|
||
|
@@ -290,7 +294,6 @@ int connmgr_init(void) {
|
||
|
*p = '\0';
|
||
|
}
|
||
|
*p = '\0';
|
||
|
-
|
||
|
VariableContainer_change(srv->variable_container,
|
||
|
CONNMGR_VAR_SINK_PROTO_INFO, buf);
|
||
|
free(buf);
|
||
|
@@ -328,7 +331,7 @@ static int get_current_conn_info(struct action_event *event)
|
||
|
if (value == NULL) {
|
||
|
return -1;
|
||
|
}
|
||
|
- Log_info("connmgr", "Query ConnectionID='%s'", value);
|
||
|
+ Log_debug("connmgr", "Query ConnectionID='%s'", value);
|
||
|
|
||
|
upnp_append_variable(event, CONNMGR_VAR_AAT_RCS_ID, "RcsID");
|
||
|
upnp_append_variable(event, CONNMGR_VAR_AAT_AVT_ID, "AVTransportID");
|
||
|
diff --git a/src/upnp_control.c b/src/upnp_control.c
|
||
|
index a1ad1cd..61b6db1 100644
|
||
|
--- a/src/upnp_control.c
|
||
|
+++ b/src/upnp_control.c
|
||
|
@@ -519,7 +519,7 @@ static int cmd_obtain_variable(struct action_event *event,
|
||
|
if (instance == NULL) {
|
||
|
return -1;
|
||
|
}
|
||
|
- Log_info("control", "%s: %s for instance %s\n",
|
||
|
+ Log_debug("control", "%s: %s for instance %s\n",
|
||
|
__FUNCTION__, paramname, instance);
|
||
|
|
||
|
upnp_append_variable(event, varnum, paramname);
|
||
|
@@ -611,6 +611,7 @@ static int get_mute(struct action_event *event)
|
||
|
}
|
||
|
|
||
|
static void set_mute_toggle(int do_mute) {
|
||
|
+ Log_info("upnp", "call output_set_mute");
|
||
|
replace_var(CONTROL_VAR_MUTE, do_mute ? "1" : "0");
|
||
|
output_set_mute(do_mute);
|
||
|
}
|
||
|
@@ -792,6 +793,7 @@ void upnp_control_init(struct upnp_device *device) {
|
||
|
|
||
|
// Set initial volume.
|
||
|
float volume_fraction = 0;
|
||
|
+ Log_info("upnp", "call output_get_volume");
|
||
|
if (output_get_volume(&volume_fraction) == 0) {
|
||
|
Log_info("control", "Output inital volume is %f; setting "
|
||
|
"control variables accordingly.", volume_fraction);
|
||
|
diff --git a/src/upnp_device.c b/src/upnp_device.c
|
||
|
index a31b420..729f4fd 100644
|
||
|
--- a/src/upnp_device.c
|
||
|
+++ b/src/upnp_device.c
|
||
|
@@ -161,8 +161,8 @@ static int handle_subscription_request(struct upnp_device *priv,
|
||
|
|
||
|
assert(priv != NULL);
|
||
|
|
||
|
- Log_info("upnp", "Subscription request for %s (%s)",
|
||
|
- sr_event->ServiceId, sr_event->UDN);
|
||
|
+ Log_debug("upnp", "event:%p, Subscription request for %s (%s)",
|
||
|
+ sr_event, sr_event->ServiceId, sr_event->UDN);
|
||
|
|
||
|
srv = find_service(priv->upnp_device_descriptor, sr_event->ServiceId);
|
||
|
if (srv == NULL) {
|
||
|
@@ -203,7 +203,7 @@ static int handle_subscription_request(struct upnp_device *priv,
|
||
|
}
|
||
|
ithread_mutex_unlock(srv->service_mutex);
|
||
|
char *xml_value = UPnPLastChangeBuilder_to_xml(builder);
|
||
|
- Log_info("upnp", "Initial variable sync: %s", xml_value);
|
||
|
+ Log_debug("upnp", "event:%p, Initial variable sync: %s", sr_event, xml_value);
|
||
|
eventvar_values[0] = xmlescape(xml_value, 0);
|
||
|
free(xml_value);
|
||
|
UPnPLastChangeBuilder_delete(builder);
|
||
|
@@ -341,7 +341,7 @@ static int handle_action_request(struct upnp_device *priv,
|
||
|
char *action_result_xml = NULL;
|
||
|
action_result_xml = ixmlDocumenttoString(
|
||
|
ar_event->ActionResult);
|
||
|
- Log_info("upnp", "Action '%s' OK; Response %s",
|
||
|
+ Log_debug("upnp", "Action '%s' OK; Response %s",
|
||
|
ar_event->ActionName,
|
||
|
action_result_xml);
|
||
|
free(action_result_xml);
|
||
|
@@ -417,7 +417,7 @@ static gboolean initialize_device(struct upnp_device_descriptor *device_def,
|
||
|
ip_address, port, UpnpGetErrorMessage(rc), rc);
|
||
|
return FALSE;
|
||
|
}
|
||
|
- Log_info("upnp", "Registered IP=%s port=%d\n",
|
||
|
+ Log_debug("upnp", "Registered IP=%s port=%d\n",
|
||
|
UpnpGetServerIpAddress(), UpnpGetServerPort());
|
||
|
|
||
|
rc = UpnpEnableWebserver(TRUE);
|
||
|
diff --git a/src/upnp_transport.c b/src/upnp_transport.c
|
||
|
index f9c97fb..4de63ba 100644
|
||
|
--- a/src/upnp_transport.c
|
||
|
+++ b/src/upnp_transport.c
|
||
|
@@ -26,6 +26,7 @@
|
||
|
#endif
|
||
|
|
||
|
#include "upnp_transport.h"
|
||
|
+#include "dmr_ipc.h"
|
||
|
|
||
|
#define _GNU_SOURCE
|
||
|
#include <stdio.h>
|
||
|
@@ -35,16 +36,16 @@
|
||
|
#include <assert.h>
|
||
|
|
||
|
#include <glib.h>
|
||
|
-
|
||
|
#include <upnp/upnp.h>
|
||
|
#include <upnp/ithread.h>
|
||
|
|
||
|
#include "output.h"
|
||
|
#include "upnp.h"
|
||
|
+
|
||
|
#include "upnp_device.h"
|
||
|
#include "variable-container.h"
|
||
|
#include "xmlescape.h"
|
||
|
-
|
||
|
+#include "logging.h"
|
||
|
#define TRANSPORT_TYPE "urn:schemas-upnp-org:service:AVTransport:1"
|
||
|
#define TRANSPORT_SERVICE_ID "urn:upnp-org:serviceId:AVTransport"
|
||
|
|
||
|
@@ -56,6 +57,15 @@
|
||
|
#define TRANSPORT_EVENT_XML_NS "urn:schemas-upnp-org:metadata-1-0/AVT/"
|
||
|
|
||
|
typedef enum {
|
||
|
+ DLNA_STOP_REQ = 0,
|
||
|
+ DLNA_PLAY_REQ,
|
||
|
+ DLNA_PAUSE_REQ,
|
||
|
+ DLNA_STOP_DONE,
|
||
|
+ DLNA_PLAY_DONE,
|
||
|
+ DLNA_PUASE_DONE
|
||
|
+}DLNA_MSG;
|
||
|
+
|
||
|
+typedef enum {
|
||
|
TRANSPORT_VAR_TRANSPORT_STATUS,
|
||
|
TRANSPORT_VAR_NEXT_AV_URI,
|
||
|
TRANSPORT_VAR_NEXT_AV_URI_META,
|
||
|
@@ -655,9 +665,15 @@ static int set_avtransport_uri(struct action_event *event)
|
||
|
if (uri == NULL) {
|
||
|
return -1;
|
||
|
}
|
||
|
+ if (TRANSPORT_STOPPED != transport_state_ && TRANSPORT_NO_MEDIA_PRESENT != transport_state_)
|
||
|
+ {
|
||
|
+ stop(NULL);
|
||
|
+ }
|
||
|
|
||
|
service_lock();
|
||
|
const char *meta = upnp_get_string(event, "CurrentURIMetaData");
|
||
|
+ Log_info("transport", "url : %s", uri);
|
||
|
+ Log_info("transport", "meta: %s", meta);
|
||
|
// Transport URI/Meta set now, current URI/Meta when it starts playing.
|
||
|
int requires_meta_update = replace_transport_uri_and_meta(uri, meta);
|
||
|
|
||
|
@@ -669,12 +685,12 @@ static int set_avtransport_uri(struct action_event *event)
|
||
|
// current URI/Meta as well to reflect the state best.
|
||
|
replace_current_uri_and_meta(uri, meta);
|
||
|
}
|
||
|
-
|
||
|
+
|
||
|
+ Log_info("transport", "call output_set_uri");
|
||
|
output_set_uri(uri, (requires_meta_update
|
||
|
? update_meta_from_stream
|
||
|
: NULL));
|
||
|
service_unlock();
|
||
|
-
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -772,7 +788,7 @@ static void *thread_update_track_time(void *userdata) {
|
||
|
char tbuf[32];
|
||
|
gint64 last_duration = -1, last_position = -1;
|
||
|
for (;;) {
|
||
|
- usleep(500000); // 500ms
|
||
|
+ usleep(1 * 1000 * 1000); // 1000ms
|
||
|
service_lock();
|
||
|
gint64 duration, position;
|
||
|
const int pos_result = output_get_position(&duration, &position);
|
||
|
@@ -787,6 +803,10 @@ static void *thread_update_track_time(void *userdata) {
|
||
|
replace_var(TRANSPORT_VAR_REL_TIME_POS, tbuf);
|
||
|
last_position = position / one_sec_unit;
|
||
|
}
|
||
|
+ if (TRANSPORT_STOPPED != transport_state_ && TRANSPORT_NO_MEDIA_PRESENT != transport_state_)
|
||
|
+ {
|
||
|
+ Log_debug("transport", "progress : %lld / %lld", last_position, last_duration / one_sec_unit);
|
||
|
+ }
|
||
|
}
|
||
|
service_unlock();
|
||
|
}
|
||
|
@@ -822,16 +842,29 @@ static int get_device_caps(struct action_event *event)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static int stop(struct action_event *event)
|
||
|
-{
|
||
|
- if (obtain_instanceid(event, NULL) < 0) {
|
||
|
- return -1;
|
||
|
+int stop(struct action_event *event)
|
||
|
+{
|
||
|
+ if (event != NULL)
|
||
|
+ {
|
||
|
+ if (obtain_instanceid(event, NULL) < 0) {
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ if (TRANSPORT_STOPPED != transport_state_
|
||
|
+ && TRANSPORT_NO_MEDIA_PRESENT != transport_state_)
|
||
|
+ {
|
||
|
+ Log_info("transport", "recv stop cmd from dmc");
|
||
|
+#if GMR_IPC
|
||
|
+ WriteIPC(DLNA_STOP_REQ);
|
||
|
+ return 0;
|
||
|
+#endif
|
||
|
+ }
|
||
|
}
|
||
|
-
|
||
|
service_lock();
|
||
|
switch (transport_state_) {
|
||
|
case TRANSPORT_STOPPED:
|
||
|
// nothing to change.
|
||
|
+ Log_info("transport", "no need, already sttopped");
|
||
|
+ output_gst_destroy();
|
||
|
break;
|
||
|
case TRANSPORT_PLAYING:
|
||
|
case TRANSPORT_TRANSITIONING:
|
||
|
@@ -839,19 +872,25 @@ static int stop(struct action_event *event)
|
||
|
case TRANSPORT_RECORDING:
|
||
|
case TRANSPORT_PAUSED_PLAYBACK:
|
||
|
output_stop();
|
||
|
+#if GMR_IPC
|
||
|
+ WriteIPC(DLNA_STOP_DONE);
|
||
|
+#endif
|
||
|
change_transport_state(TRANSPORT_STOPPED);
|
||
|
break;
|
||
|
|
||
|
case TRANSPORT_NO_MEDIA_PRESENT:
|
||
|
- /* action not allowed in these states - error 701 */
|
||
|
- upnp_set_error(event, UPNP_TRANSPORT_E_TRANSITION_NA,
|
||
|
+ /* action not allowed in these states - error 701 */
|
||
|
+ output_gst_destroy();
|
||
|
+ if (event != NULL)
|
||
|
+ {
|
||
|
+ Log_info("transport", "no need, gmrender status : TRANSPORT_NO_MEDIA_PRESENT");
|
||
|
+ upnp_set_error(event, UPNP_TRANSPORT_E_TRANSITION_NA,
|
||
|
"Transition to STOP not allowed; allowed=%s",
|
||
|
get_var(TRANSPORT_VAR_CUR_TRANSPORT_ACTIONS));
|
||
|
-
|
||
|
+ }
|
||
|
break;
|
||
|
}
|
||
|
service_unlock();
|
||
|
-
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -877,12 +916,20 @@ static void inform_play_transition_from_output(enum PlayFeedback fb) {
|
||
|
service_unlock();
|
||
|
}
|
||
|
|
||
|
-static int play(struct action_event *event)
|
||
|
+int play(struct action_event *event)
|
||
|
{
|
||
|
- if (obtain_instanceid(event, NULL) < 0) {
|
||
|
- return -1;
|
||
|
+ if (event != NULL)
|
||
|
+ {
|
||
|
+ if (obtain_instanceid(event, NULL) < 0) {
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ Log_info("transport", "recv play cmd from dmc");
|
||
|
+#if GMR_IPC
|
||
|
+ WriteIPC(DLNA_PLAY_REQ);
|
||
|
+ return 0;
|
||
|
+#endif
|
||
|
}
|
||
|
-
|
||
|
+ output_gst_init();
|
||
|
int rc = 0;
|
||
|
service_lock();
|
||
|
switch (transport_state_) {
|
||
|
@@ -901,10 +948,16 @@ static int play(struct action_event *event)
|
||
|
|
||
|
case TRANSPORT_PAUSED_PLAYBACK:
|
||
|
if (output_play(&inform_play_transition_from_output)) {
|
||
|
- upnp_set_error(event, 704, "Playing failed");
|
||
|
- rc = -1;
|
||
|
+ if (event != NULL)
|
||
|
+ {
|
||
|
+ upnp_set_error(event, 704, "Playing failed");
|
||
|
+ rc = -1;
|
||
|
+ }
|
||
|
} else {
|
||
|
- change_transport_state(TRANSPORT_PLAYING);
|
||
|
+#if GMR_IPC
|
||
|
+ WriteIPC(DLNA_PLAY_DONE);
|
||
|
+#endif
|
||
|
+ change_transport_state(TRANSPORT_PLAYING);
|
||
|
const char *av_uri = get_var(TRANSPORT_VAR_AV_URI);
|
||
|
const char *av_meta = get_var(TRANSPORT_VAR_AV_URI_META);
|
||
|
replace_current_uri_and_meta(av_uri, av_meta);
|
||
|
@@ -923,15 +976,22 @@ static int play(struct action_event *event)
|
||
|
break;
|
||
|
}
|
||
|
service_unlock();
|
||
|
-
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
-static int pause_stream(struct action_event *event)
|
||
|
-{
|
||
|
- if (obtain_instanceid(event, NULL) < 0) {
|
||
|
- return -1;
|
||
|
- }
|
||
|
+int pause_stream(struct action_event *event)
|
||
|
+{
|
||
|
+ if (event != NULL)
|
||
|
+ {
|
||
|
+ if (obtain_instanceid(event, NULL) < 0) {
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ Log_info("transport", "recv pause cmd from dmc");
|
||
|
+#if GMR_IPC
|
||
|
+ WriteIPC(DLNA_PAUSE_REQ);
|
||
|
+ return 0;
|
||
|
+#endif
|
||
|
+}
|
||
|
|
||
|
int rc = 0;
|
||
|
service_lock();
|
||
|
@@ -942,22 +1002,30 @@ static int pause_stream(struct action_event *event)
|
||
|
|
||
|
case TRANSPORT_PLAYING:
|
||
|
if (output_pause()) {
|
||
|
- upnp_set_error(event, 704, "Pause failed");
|
||
|
- rc = -1;
|
||
|
+ if (event != NULL)
|
||
|
+ {
|
||
|
+ upnp_set_error(event, 704, "Pause failed");
|
||
|
+ rc = -1;
|
||
|
+ }
|
||
|
} else {
|
||
|
- change_transport_state(TRANSPORT_PAUSED_PLAYBACK);
|
||
|
+#if GMR_IPC
|
||
|
+ WriteIPC(DLNA_PUASE_DONE);
|
||
|
+#endif
|
||
|
+ change_transport_state(TRANSPORT_PAUSED_PLAYBACK);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
- default:
|
||
|
+ default:
|
||
|
+ if (event != NULL)
|
||
|
+ {
|
||
|
/* action not allowed in these states - error 701 */
|
||
|
- upnp_set_error(event, UPNP_TRANSPORT_E_TRANSITION_NA,
|
||
|
- "Transition to PAUSE not allowed; allowed=%s",
|
||
|
- get_var(TRANSPORT_VAR_CUR_TRANSPORT_ACTIONS));
|
||
|
- rc = -1;
|
||
|
- }
|
||
|
+ upnp_set_error(event, UPNP_TRANSPORT_E_TRANSITION_NA,
|
||
|
+ "Transition to PAUSE not allowed; allowed=%s",
|
||
|
+ get_var(TRANSPORT_VAR_CUR_TRANSPORT_ACTIONS));
|
||
|
+ rc = -1;
|
||
|
+ }
|
||
|
+ }
|
||
|
service_unlock();
|
||
|
-
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
@@ -1036,6 +1104,9 @@ void upnp_transport_init(struct upnp_device *device) {
|
||
|
TRANSPORT_VAR_ABS_CTR_POS);
|
||
|
|
||
|
pthread_t thread;
|
||
|
+#if GMR_IPC
|
||
|
+ InitIPC(play, pause_stream, stop);
|
||
|
+#endif
|
||
|
pthread_create(&thread, NULL, thread_update_track_time, NULL);
|
||
|
}
|
||
|
|
||
|
diff --git a/src/webserver.c b/src/webserver.c
|
||
|
index eaf0331..14e00e3 100644
|
||
|
--- a/src/webserver.c
|
||
|
+++ b/src/webserver.c
|
||
|
@@ -63,7 +63,7 @@ int webserver_register_buf(const char *path, const char *contents,
|
||
|
{
|
||
|
struct virtual_file *entry;
|
||
|
|
||
|
- Log_info("webserver", "Provide %s (%s) from buffer",
|
||
|
+ Log_debug("webserver", "Provide %s (%s) from buffer",
|
||
|
path, content_type);
|
||
|
|
||
|
assert(path != NULL);
|
||
|
@@ -94,7 +94,7 @@ int webserver_register_file(const char *path, const char *content_type)
|
||
|
snprintf(local_fname, sizeof(local_fname), "%s%s", PKG_DATADIR,
|
||
|
strrchr(path, '/'));
|
||
|
|
||
|
- Log_info("webserver", "Provide %s (%s) from %s", path, content_type,
|
||
|
+ Log_debug("webserver", "Provide %s (%s) from %s", path, content_type,
|
||
|
local_fname);
|
||
|
|
||
|
rc = stat(local_fname, &buf);
|
||
|
@@ -154,14 +154,14 @@ static int webserver_get_info(const char *filename, struct File_Info *info)
|
||
|
info->is_readable = 1;
|
||
|
info->content_type =
|
||
|
ixmlCloneDOMString(virtfile->content_type);
|
||
|
- Log_info("webserver", "Access %s (%s) len=%zd",
|
||
|
+ Log_debug("webserver", "Access %s (%s) len=%zd",
|
||
|
filename, info->content_type, virtfile->len);
|
||
|
return 0;
|
||
|
}
|
||
|
virtfile = virtfile->next;
|
||
|
}
|
||
|
|
||
|
- Log_info("webserver", "404 Not found. (attempt to access "
|
||
|
+ Log_debug("webserver", "404 Not found. (attempt to access "
|
||
|
"non-existent '%s')", filename);
|
||
|
|
||
|
return -1;
|
||
|
--
|
||
|
1.9.1
|
||
|
|