From 2df0c3a21536e29df3de50e41a3fcb56e712318b Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Sat, 22 Apr 2023 20:03:48 +0900 Subject: [PATCH] Add API to set audio/video stream info [Version] 0.1.2 Signed-off-by: Sangchul Lee --- packaging/espp-service.spec | 2 +- src/client/espp_service_client.c | 34 +++++++++++ src/client/espp_service_client.h | 104 ++++++++++++++++++++++++++++++++ src/client/espp_service_client_msg.c | 1 + src/client/espp_service_client_priv.h | 3 + src/client/espp_service_client_socket.c | 47 +++++++++++++++ src/common/espp_service_common.c | 2 + src/common/espp_service_common.h | 2 + src/daemon/espp_service_handler.c | 61 +++++++++++++++++++ 9 files changed, 255 insertions(+), 1 deletion(-) diff --git a/packaging/espp-service.spec b/packaging/espp-service.spec index 7458bb7..73062d8 100644 --- a/packaging/espp-service.spec +++ b/packaging/espp-service.spec @@ -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 diff --git a/src/client/espp_service_client.c b/src/client/espp_service_client.c index db04638..17f53c3 100644 --- a/src/client/espp_service_client.c +++ b/src/client/espp_service_client.c @@ -77,4 +77,38 @@ 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 diff --git a/src/client/espp_service_client.h b/src/client/espp_service_client.h index 4c59b7f..e38c737 100644 --- a/src/client/espp_service_client.h +++ b/src/client/espp_service_client.h @@ -17,6 +17,8 @@ #ifndef __ESPP_SERVICE_CLIENT_H__ #define __ESPP_SERVICE_CLIENT_H__ +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -36,6 +38,78 @@ typedef enum { } 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 * @return @c 0 on success, @@ -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 */ diff --git a/src/client/espp_service_client_msg.c b/src/client/espp_service_client_msg.c index a1a1aec..43e2272 100644 --- a/src/client/espp_service_client_msg.c +++ b/src/client/espp_service_client_msg.c @@ -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; diff --git a/src/client/espp_service_client_priv.h b/src/client/espp_service_client_priv.h index 6a205b9..44b14db 100644 --- a/src/client/espp_service_client_priv.h +++ b/src/client/espp_service_client_priv.h @@ -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 } diff --git a/src/client/espp_service_client_socket.c b/src/client/espp_service_client_socket.c index 00cb4db..0ef0339 100644 --- a/src/client/espp_service_client_socket.c +++ b/src/client/espp_service_client_socket.c @@ -205,4 +205,51 @@ 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 diff --git a/src/common/espp_service_common.c b/src/common/espp_service_common.c index 42b7b32..830293d 100644 --- a/src/common/espp_service_common.c +++ b/src/common/espp_service_common.c @@ -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[] = { diff --git a/src/common/espp_service_common.h b/src/common/espp_service_common.h index 1796456..0167b0d 100644 --- a/src/common/espp_service_common.h +++ b/src/common/espp_service_common.h @@ -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 { diff --git a/src/daemon/espp_service_handler.c b/src/daemon/espp_service_handler.c index 2311c83..8aee123 100644 --- a/src/daemon/espp_service_handler.c +++ b/src/daemon/espp_service_handler.c @@ -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) -- 2.7.4