Add API to set audio/video stream info
authorSangchul Lee <sc11.lee@samsung.com>
Sat, 22 Apr 2023 11:03:48 +0000 (20:03 +0900)
committer이상철/Tizen Platform Lab(SR)/삼성전자 <sc11.lee@samsung.com>
Tue, 25 Apr 2023 23:05:25 +0000 (08:05 +0900)
[Version] 0.1.2

Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/espp-service.spec
src/client/espp_service_client.c
src/client/espp_service_client.h
src/client/espp_service_client_msg.c
src/client/espp_service_client_priv.h
src/client/espp_service_client_socket.c
src/common/espp_service_common.c
src/common/espp_service_common.h
src/daemon/espp_service_handler.c

index 7458bb76cfbb4925d352423bc0456fa063e89999..73062d84bede336c508600811dae6f3ad5abb47f 100644 (file)
@@ -1,6 +1,6 @@
 Name:       espp-service
 Summary:    ESPP service package which contains client lib. and daemon binary
-Version:    0.1.1
+Version:    0.1.2
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index db0463883918d607cc0e2c752cb16d60e062e805..17f53c36c502c99199c09d794c149336ff01b2cb 100644 (file)
@@ -76,5 +76,39 @@ int espp_client_start(espp_h espp)
 
        LOG_INFO("espp[%p] is started", espp);
 
+       return ESPP_CLIENT_ERROR_NONE;
+}
+
+int espp_client_set_audio_stream_info(espp_h espp, espp_audio_stream_info_s *info)
+{
+       espp_s *_espp = (espp_s *)espp;
+       g_autoptr(GMutexLocker) locker = NULL;
+
+       RET_VAL_IF(!espp, ESPP_CLIENT_ERROR_INVALID_PARAMETER, "espp is NULL");
+
+       locker = g_mutex_locker_new(&_espp->mutex);
+
+       if (espp_service_client_socket_request_set_audio_stream_info(_espp, info) != 0)
+               return ESPP_CLIENT_ERROR_INVALID_OPERATION;
+
+       LOG_INFO("espp[%p]", espp);
+
+       return ESPP_CLIENT_ERROR_NONE;
+}
+
+int espp_client_set_video_stream_info(espp_h espp, espp_video_stream_info_s *info)
+{
+       espp_s *_espp = (espp_s *)espp;
+       g_autoptr(GMutexLocker) locker = NULL;
+
+       RET_VAL_IF(!espp, ESPP_CLIENT_ERROR_INVALID_PARAMETER, "espp is NULL");
+
+       locker = g_mutex_locker_new(&_espp->mutex);
+
+       if (espp_service_client_socket_request_set_video_stream_info(_espp, info) != 0)
+               return ESPP_CLIENT_ERROR_INVALID_OPERATION;
+
+       LOG_INFO("espp[%p]", espp);
+
        return ESPP_CLIENT_ERROR_NONE;
 }
\ No newline at end of file
index 4c59b7f1d03f1319e0f11679a7d17525ecac1f5e..e38c7377c2251f7c09110529e09ea4fd0ad26dc9 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef __ESPP_SERVICE_CLIENT_H__
 #define __ESPP_SERVICE_CLIENT_H__
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -35,6 +37,78 @@ typedef enum {
        ESPP_CLIENT_ERROR_INVALID_OPERATION,      /**< Invalid operation */
 } espp_client_error_e;
 
+/**
+ * @brief Enumerations for audio mime type
+ */
+typedef enum {
+  ESPP_AUDIO_MIME_TYPE_UNKNOWN,    /**< Unknown */
+  ESPP_AUDIO_MIME_TYPE_AAC,        /**< AAC */
+  ESPP_AUDIO_MIME_TYPE_MP2,        /**< MP2 */
+  ESPP_AUDIO_MIME_TYPE_MP3,        /**< MP3 */
+  ESPP_AUDIO_MIME_TYPE_AC3,        /**< AC3 */
+  ESPP_AUDIO_MIME_TYPE_EAC3,       /**< EAC3 */
+  ESPP_AUDIO_MIME_TYPE_VORBIS,     /**< VORBIS */
+  ESPP_AUDIO_MIME_TYPE_OPUS,       /**< OPUS */
+  ESPP_AUDIO_MIME_TYPE_PCM_S16LE,  /**< PCM s16le */
+  ESPP_AUDIO_MIME_TYPE_PCM_S16BE,  /**< PCM s16be */
+  ESPP_AUDIO_MIME_TYPE_PCM_U16LE,  /**< PCM u16le */
+  ESPP_AUDIO_MIME_TYPE_PCM_U16BE,  /**< PCM u16be */
+  ESPP_AUDIO_MIME_TYPE_PCM_S24LE,  /**< PCM s24le */
+  ESPP_AUDIO_MIME_TYPE_PCM_S24BE,  /**< PCM s24be */
+  ESPP_AUDIO_MIME_TYPE_PCM_U24LE,  /**< PCM u24le */
+  ESPP_AUDIO_MIME_TYPE_PCM_U24BE,  /**< PCM u24be */
+  ESPP_AUDIO_MIME_TYPE_PCM_S32LE,  /**< PCM s32le */
+  ESPP_AUDIO_MIME_TYPE_PCM_S32BE,  /**< PCM s32be */
+  ESPP_AUDIO_MIME_TYPE_PCM_U32LE,  /**< PCM u32le */
+  ESPP_AUDIO_MIME_TYPE_PCM_U32BE,  /**< PCM u32be */
+  ESPP_AUDIO_MIME_TYPE_G711_MULAW  /**< G711 mulaw */
+} espp_audio_mime_type_e;
+
+/**
+ * @brief Enumerations for video mime type
+ */
+typedef enum {
+  ESPP_VIDEO_MIME_TYPE_UNKNOWN,   /**< Unknown */
+  ESPP_VIDEO_MIME_TYPE_H263,      /**< H263 */
+  ESPP_VIDEO_MIME_TYPE_H264,      /**< H264 */
+  ESPP_VIDEO_MIME_TYPE_HEVC,      /**< HEVC */
+  ESPP_VIDEO_MIME_TYPE_MPEG1,     /**< MPEG1 */
+  ESPP_VIDEO_MIME_TYPE_MPEG2,     /**< MPEG2 */
+  ESPP_VIDEO_MIME_TYPE_MPEG4,     /**< MPEG4 */
+  ESPP_VIDEO_MIME_TYPE_VP8,       /**< VP8 */
+  ESPP_VIDEO_MIME_TYPE_VP9,       /**< VP9 */
+  ESPP_VIDEO_MIME_TYPE_WMV3,      /**< WMV3 */
+  ESPP_VIDEO_MIME_TYPE_AV1,       /**< AV1 */
+  ESPP_VIDEO_MIME_TYPE_MJPEG      /**< MJPEG */
+} espp_video_mime_type_e;
+
+/**
+ * @brief Audio stream information structure
+ */
+typedef struct {
+  char *codec_data;
+  uint32_t codec_data_length;
+  espp_audio_mime_type_e mime_type;
+  uint32_t bitrate;
+  uint32_t channels;
+  uint32_t sample_rate;
+} espp_audio_stream_info_s;
+
+/**
+ * @brief Video stream information structure
+ */
+typedef struct {
+  char *codec_data;
+  uint32_t codec_data_length;
+  espp_video_mime_type_e mime_type;
+  uint32_t width;
+  uint32_t height;
+  uint32_t max_width;
+  uint32_t max_height;
+  uint32_t framerate_num;
+  uint32_t framerate_den;
+} espp_video_stream_info_s;
+
 /**
  * @brief Creates an instance of ESPP service client.
  * @param[out] espp    ESPP service client handle
@@ -71,6 +145,36 @@ int espp_client_destroy(espp_h espp);
  */
 int espp_client_start(espp_h espp);
 
+/**
+ * @brief Sets the audio stream information.
+ * @remarks This API has to be called before calling the espp_client_prepare_async().
+ * @param[in] espp    ESPP service client handle
+ * @param[in] info    Audio stream information structure pointer
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #ESPP_CLIENT_ERROR_NONE Successful
+ * @retval #ESPP_CLIENT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #ESPP_CLIENT_ERROR_INVALID_OPERATION Invalid operation
+ * @see espp_client_prepare_async()
+ * @see espp_client_set_video_stream_info()
+ */
+int espp_client_set_audio_stream_info(espp_h espp, espp_audio_stream_info_s *info);
+
+/**
+ * @brief Sets the video stream information.
+ * @remarks This API has to be called before calling the espp_client_prepare_async().
+ * @param[in] espp    ESPP service client handle
+ * @param[in] info    Video stream information structure pointer
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #ESPP_CLIENT_ERROR_NONE Successful
+ * @retval #ESPP_CLIENT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #ESPP_CLIENT_ERROR_INVALID_OPERATION Invalid operation
+ * @see espp_client_prepare_async()
+ * @see espp_client_set_audio_stream_info()
+ */
+int espp_client_set_video_stream_info(espp_h espp, espp_video_stream_info_s *info);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index a1a1aec55ae50d468a14d8f0a76fa092e97a97ae..43e227223ac8daa29ec396063375bb28a814dcd4 100644 (file)
@@ -82,6 +82,7 @@ static JsonObject *make_json_object_params(va_list ap, const char *formats, Json
        return object;
 }
 
+/* Use g_free() to release the return value. */
 gchar *espp_service_client_msg_params_new(const char *formats, ...)
 {
        gchar *result = NULL;
index 6a205b94576388a437e7384bf88d2b0b363fa2ac..44b14db6a4ce259430d8446e70735565abcb4a85 100644 (file)
@@ -18,6 +18,7 @@
 #define __ESPP_SERVICE_CLIENT_PRIVATE_H__
 
 #include "../common/espp_service_common.h"
+#include "espp_service_client.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -39,6 +40,8 @@ gchar *espp_service_client_msg_params_new(const char *formats, ...);
 int espp_service_client_socket_request_create(espp_s *espp);
 int espp_service_client_socket_request_destroy(espp_s *espp);
 int espp_service_client_socket_request_start(espp_s *espp);
+int espp_service_client_socket_request_set_audio_stream_info(espp_s *espp, espp_audio_stream_info_s *info);
+int espp_service_client_socket_request_set_video_stream_info(espp_s *espp, espp_video_stream_info_s *info);
 
 #ifdef __cplusplus
 }
index 00cb4dbe0abacc5e3893eb0ce2b8c58d0b37c0d6..0ef033931f1a0554729f2123b4b8faa1314cb840 100644 (file)
@@ -204,5 +204,52 @@ int espp_service_client_socket_request_start(espp_s *espp)
 
        LOG_DEBUG("espp[%p], fd[%d]", espp, espp->fd);
 
+       return 0;
+}
+
+int espp_service_client_socket_request_set_audio_stream_info(espp_s *espp, espp_audio_stream_info_s *info)
+{
+       espp_service_data_from_client_s data;
+       espp_service_data_from_server_s result;
+
+       ASSERT(espp);
+       ASSERT(info);
+       RET_VAL_IF(espp->fd == -1, -1, "fd is -1");
+
+       FILL_SOCKET_MSG_REQUEST(data, ESPP_SERVICE_REQUEST_SET_AUDIO_STREAM_INFO);
+       FILL_SOCKET_MSG_PARAMS(data, ESPP_SERVICE_REQUEST_SET_AUDIO_STREAM_INFO,
+               info->codec_data, info->codec_data_length, info->mime_type,
+               info->bitrate, info->channels, info->sample_rate);
+       if (send_data(espp->fd, &data, &result) != 0)
+               return -1;
+
+       RET_VAL_IF_SERVER_RESULT_ERROR(result, -1);
+
+       LOG_DEBUG("espp[%p], fd[%d]", espp, espp->fd);
+
+       return 0;
+}
+
+int espp_service_client_socket_request_set_video_stream_info(espp_s *espp, espp_video_stream_info_s *info)
+{
+       espp_service_data_from_client_s data;
+       espp_service_data_from_server_s result;
+
+       ASSERT(espp);
+       ASSERT(info);
+       RET_VAL_IF(espp->fd == -1, -1, "fd is -1");
+
+       FILL_SOCKET_MSG_REQUEST(data, ESPP_SERVICE_REQUEST_SET_VIDEO_STREAM_INFO);
+       FILL_SOCKET_MSG_PARAMS(data, ESPP_SERVICE_REQUEST_SET_VIDEO_STREAM_INFO,
+               info->codec_data, info->codec_data_length, info->mime_type,
+               info->width, info->height, info->max_width, info->max_height,
+               info->framerate_num, info->framerate_den);
+       if (send_data(espp->fd, &data, &result) != 0)
+               return -1;
+
+       RET_VAL_IF_SERVER_RESULT_ERROR(result, -1);
+
+       LOG_DEBUG("espp[%p], fd[%d]", espp, espp->fd);
+
        return 0;
 }
\ No newline at end of file
index 42b7b3253a03383cd59ec7e3710f1dd8c180827c..830293dad2f6ab735edcad00c50d8fb83fa97cb8 100644 (file)
@@ -20,6 +20,8 @@ espp_service_request_s requests[] = { /* str, param_formats - 'b':bool, 'i':int,
        [ESPP_SERVICE_REQUEST_CREATE] = { "Create", NULL },
        [ESPP_SERVICE_REQUEST_DESTROY] = {"Destroy", NULL },
        [ESPP_SERVICE_REQUEST_START] = { "Start", NULL },
+       [ESPP_SERVICE_REQUEST_SET_AUDIO_STREAM_INFO] = { "SetAudioStreamInfo", "suiuuu" },
+       [ESPP_SERVICE_REQUEST_SET_VIDEO_STREAM_INFO] = { "SetVideoStreamInfo", "suiuuuuuu" },
 };
 
 const char *data_type_strs[] = {
index 179645646cbb4f6d9d4fea24b4bd91a738854916..0167b0dbec5ae206109daa3be0be95c5a0d8a57a 100644 (file)
@@ -125,6 +125,8 @@ typedef enum {
        ESPP_SERVICE_REQUEST_CREATE,
        ESPP_SERVICE_REQUEST_DESTROY,
        ESPP_SERVICE_REQUEST_START,
+       ESPP_SERVICE_REQUEST_SET_AUDIO_STREAM_INFO,
+       ESPP_SERVICE_REQUEST_SET_VIDEO_STREAM_INFO,
 } espp_service_request_e;
 
 enum {
index 2311c83fa476854fa1d6021a87323130cffc4174..8aee1239729d2d3c19434b8c842b276502ddc7d5 100644 (file)
@@ -88,10 +88,71 @@ static void __handle_start(espp_service_s *svc, int fd, espp_service_data_from_c
        result->ret = 0;
 }
 
+static void __handle_set_audio_stream_info(espp_service_s *svc, int fd, espp_service_data_from_client_s *data, espp_service_data_from_server_s *result)
+{
+       int ret;
+       esplusplayer_handle espp;
+       esplusplayer_audio_stream_info info;
+
+       ASSERT(svc);
+       ASSERT(fd >= 0);
+       ASSERT(data);
+       ASSERT(result);
+
+       result->ret = -1;
+
+       RET_IF(!(espp = g_hash_table_lookup(svc->espp_handles, GINT_TO_POINTER(fd))), "failed to g_hash_table_lookup(), fd[%d]", fd);
+
+       ret = espp_service_msg_parse_params(data->params, data->request,
+               &info.codec_data, &info.codec_data_length, &info.mime_type,
+               &info.bitrate, &info.channels, &info.sample_rate);
+       if (ret != 0)
+               return;
+
+       ret = esplusplayer_set_audio_stream_info(espp, &info);
+       RET_IF(ret != ESPLUSPLAYER_ERROR_TYPE_NONE, "failed to esplusplayer_set_audio_stream_info(), ESPP[%p]", espp);
+
+       LOG_INFO("fd[%d], ESPP[%p]: esplusplayer_set_audio_stream_info() success", fd, espp);
+
+       result->ret = 0;
+}
+
+static void __handle_set_video_stream_info(espp_service_s *svc, int fd, espp_service_data_from_client_s *data, espp_service_data_from_server_s *result)
+{
+       int ret;
+       esplusplayer_handle espp;
+       esplusplayer_video_stream_info info;
+
+       ASSERT(svc);
+       ASSERT(fd >= 0);
+       ASSERT(data);
+       ASSERT(result);
+
+       result->ret = -1;
+
+       RET_IF(!(espp = g_hash_table_lookup(svc->espp_handles, GINT_TO_POINTER(fd))), "failed to g_hash_table_lookup(), fd[%d]", fd);
+
+       ret = espp_service_msg_parse_params(data->params, data->request,
+               &info.codec_data, &info.codec_data_length, &info.mime_type,
+               &info.width, &info.height, &info.max_width, &info.max_height,
+               &info.framerate_num, &info.framerate_den);
+       if (ret != 0)
+               return;
+
+       ret = esplusplayer_set_video_stream_info(espp, &info);
+       RET_IF(ret != ESPLUSPLAYER_ERROR_TYPE_NONE, "failed to esplusplayer_set_video_stream_info(), ESPP[%p]", espp);
+
+       LOG_INFO("fd[%d], ESPP[%p]: esplusplayer_set_video_stream_info() success", fd, espp);
+
+       result->ret = 0;
+}
+
 static func_handler handlers[] = {
        [ESPP_SERVICE_REQUEST_CREATE] = __handle_create,
        [ESPP_SERVICE_REQUEST_DESTROY] = __handle_destroy,
        [ESPP_SERVICE_REQUEST_START] = __handle_start,
+       [ESPP_SERVICE_REQUEST_SET_AUDIO_STREAM_INFO] = __handle_set_audio_stream_info,
+       [ESPP_SERVICE_REQUEST_SET_VIDEO_STREAM_INFO] = __handle_set_video_stream_info,
 };
 
 int espp_service_func_handler(espp_service_s *svc, int fd, espp_service_data_from_client_s *data, espp_service_data_from_server_s *result)