Add support for submit packet
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 4 May 2023 06:39:51 +0000 (15:39 +0900)
committer이상철/Tizen Platform Lab(SR)/삼성전자 <sc11.lee@samsung.com>
Wed, 10 May 2023 07:53:34 +0000 (16:53 +0900)
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
src/client/espp_service_client.c
src/client/espp_service_client.h
src/client/espp_service_client_priv.h
src/client/espp_service_client_socket.c
src/common/espp_service_ipc.c
src/common/espp_service_ipc.h
src/daemon/espp_service_handler.c
src/daemon/espp_service_priv.h
src/daemon/espp_service_socket.c

index a295cb6a01d169a87a36a607c66b06555f3babb6..286cdf754489cb127cb490fb266c416f55e2606b 100644 (file)
@@ -273,3 +273,22 @@ int espp_client_set_audio_mute(espp_h espp, bool mute)
 
        return ESPP_CLIENT_ERROR_NONE;
 }
+
+int espp_client_submit_packet(espp_h espp, espp_packet_s *packet, espp_submit_error_e *error)
+{
+       espp_s *_espp = (espp_s *)espp;
+       g_autoptr(GMutexLocker) locker = NULL;
+
+       RET_VAL_IF(!espp, ESPP_CLIENT_ERROR_INVALID_PARAMETER, "espp is NULL");
+       RET_VAL_IF(!packet, ESPP_CLIENT_ERROR_INVALID_PARAMETER, "packet is NULL");
+
+       locker = g_mutex_locker_new(&_espp->mutex);
+
+       if (espp_service_client_socket_request_submit_packet(_espp, packet, error) != 0)
+               return ESPP_CLIENT_ERROR_INVALID_OPERATION;
+
+       LOG_INFO("espp[%p]", espp);
+
+       return ESPP_CLIENT_ERROR_NONE;
+}
+
index aa9a1693b3bebd330c0c6199e349d699664237c0..f4a915d7075f5de7c12949d8732376d6add8ca8f 100644 (file)
@@ -101,6 +101,16 @@ typedef enum {
   ESPP_DISPLAY_TYPE_MIXER,   /**< Mixer */
 } espp_display_type_e;
 
+/**
+ * @brief Enumerations for the submit error
+ */
+typedef enum {
+  ESPP_SUBMIT_ERROR_NOT_PREPARED,    /**< Not prepared */
+  ESPP_SUBMIT_ERROR_INVALID_PACKET,  /**< Invalid packet */
+  ESPP_SUBMIT_ERROR_OUT_OF_MEMORY,   /**< Out of memory */
+  ESPP_SUBMIT_ERROR_FULL,            /**< Full */
+} espp_submit_error_e;
+
 /**
  * @brief Audio stream information structure
  */
@@ -128,6 +138,20 @@ typedef struct {
   uint32_t framerate_den;
 } espp_video_stream_info_s;
 
+/**
+ * @brief ESPP packet structure
+ */
+typedef struct {
+  espp_stream_type_e type;
+  char *buffer;
+  uint32_t buffer_size;
+  uint64_t pts;
+  uint64_t duration;
+  void *matroska_color_info; /* FIXME: add matroska_color structure if needed */
+  uint32_t hdr10p_metadata_size;
+  char *hdr10p_metadata;
+} espp_packet_s;
+
 /**
  * @brief Called when when the ESPP service client handle is prepared to receive es packets after calling espp_client_prepare_async().
  * @param[in] stream_type  The stream type
@@ -329,6 +353,21 @@ int espp_client_set_display_surface_id(espp_h espp, espp_display_type_e type, un
  */
 int espp_client_set_audio_mute(espp_h espp, bool mute);
 
+/**
+ * @brief Submits ESPP packet
+ * @param[in] espp    ESPP service client handle
+ * @param[in] packet  ESPP packet pointer
+ * @param[out] error  ESPP packet submit error (optional, this can be NULL)
+ * @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
+ * @post espp_ready_to_prepare_cb() will be invoked.
+ * @see espp_ready_to_prepare_cb()
+ */
+int espp_client_submit_packet(espp_h espp, espp_packet_s *packet, espp_submit_error_e *error);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index ce1a2284df067cd57a4313f132a112c683d9a8d7..314f5ad0c80e58bc0c076d829f840fd9776b0d52 100644 (file)
@@ -75,6 +75,7 @@ int espp_service_client_socket_request_set_video_stream_info(espp_s *espp, espp_
 int espp_service_client_socket_request_set_display_surface_id(espp_s *espp, espp_display_type_e type, unsigned int surface_id, int x, int y, int w, int h);
 int espp_service_client_socket_request_set_audio_mute(espp_s *espp, bool mute);
 int espp_service_client_socket_request_set_callback(espp_s *espp, espp_service_event_e type, void *callback, void *user_data);
+int espp_service_client_socket_request_submit_packet(espp_s *espp, espp_packet_s *packet, espp_submit_error_e *error);
 
 /* event handler */
 gpointer espp_service_client_event_handler_thread_func(gpointer data);
index e01ab738e228cd8a78d222aedf6afcdb6ba40b1c..0f73bf5c1c368539b06ba40a4c3ad45bcb8a8bc3 100644 (file)
@@ -103,7 +103,6 @@ static int connect_socket(int fd)
 
 static int send_data(int fd, espp_service_data_from_client_s *data, espp_service_data_from_server_s *result)
 {
-       int ret;
        char str_error[MAX_ERROR_LEN] = {'\0',};
 
        ASSERT(fd >= 0);
@@ -116,13 +115,46 @@ static int send_data(int fd, espp_service_data_from_client_s *data, espp_service
                return -1;
        }
 
-       if ((ret = read(fd, result, sizeof(espp_service_data_from_server_s))) < 0) {
+       if (read(fd, result, sizeof(espp_service_data_from_server_s)) < 0) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               LOG_ERROR("failed to read(), fd[%d], err: %s", fd, str_error);
+               return -1;
+       }
+
+       LOG_DEBUG("fd[%d] request[%d], result->ret[%d]", fd, data->request, result->ret);
+
+       return 0;
+}
+
+static int send_data_and_buffer(int fd, espp_service_data_from_client_s *data, char *buffer, uint32_t buffer_size, espp_service_data_from_server_s *result)
+{
+       char str_error[MAX_ERROR_LEN] = {'\0',};
+
+       ASSERT(fd >= 0);
+       ASSERT(data);
+       ASSERT(buffer);
+       ASSERT(buffer_size > 0);
+       ASSERT(result);
+
+       if (write(fd, data, sizeof(espp_service_data_from_client_s)) < 0) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               LOG_ERROR("failed to write(), fd[%d], err: %s", fd, str_error);
+               return -1;
+       }
+
+       if (write(fd, buffer, buffer_size) < 0) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               LOG_ERROR("failed to write(), fd[%d], err: %s", fd, str_error);
+               return -1;
+       }
+
+       if (read(fd, result, sizeof(espp_service_data_from_server_s)) < 0) {
                strerror_r(errno, str_error, sizeof(str_error));
                LOG_ERROR("failed to read(), fd[%d], err: %s", fd, str_error);
                return -1;
        }
 
-       LOG_DEBUG("fd[%d] request[%d], ret[%d]", fd, data->request, result->ret);
+       LOG_DEBUG("fd[%d] request[%d], buffer_size[%u], result->ret[%d]", fd, data->request, buffer_size, result->ret);
 
        return 0;
 }
@@ -492,3 +524,33 @@ int espp_service_client_socket_request_set_callback(espp_s *espp, espp_service_e
 
        return 0;
 }
+
+int espp_service_client_socket_request_submit_packet(espp_s *espp, espp_packet_s *packet, espp_submit_error_e *error)
+{
+       espp_service_data_from_client_s data;
+       espp_service_data_from_server_s result;
+
+       ASSERT(espp);
+       ASSERT(packet);
+       RET_VAL_IF(espp->fd == -1, -1, "fd is -1");
+       RET_VAL_IF(packet->buffer_size == 0, -1, "packet->buffer_size is 0");
+
+       FILL_SOCKET_MSG_REQUEST(data, ESPP_SERVICE_REQUEST_SUBMIT_PACKET);
+       FILL_SOCKET_MSG_PARAMS(data, ESPP_SERVICE_REQUEST_SUBMIT_PACKET,
+               "type", packet->type,
+               "buffer_size", packet->buffer_size,
+               "pts", packet->pts,
+               "duration", packet->duration,
+               "hdr10p_metadata_size", packet->hdr10p_metadata_size);
+       if (send_data_and_buffer(espp->fd, &data, packet->buffer, packet->buffer_size, &result) != 0)
+               return -1;
+
+       if (result.ret != 0 && error)
+               *error = result.ret;
+
+       RET_VAL_IF_SERVER_RESULT_ERROR(result, -1);
+
+       LOG_DEBUG("espp[%p], fd[%d]", espp, espp->fd);
+
+       return 0;
+}
index 9db4ec676eb7139c5fa6a474574752b16309cd84..af86e6f9f9fd9296c1a2db4b30660129e03f4fc2 100644 (file)
@@ -30,6 +30,7 @@ espp_service_ipc_data_s requests[] = {
        [ESPP_SERVICE_REQUEST_SET_VIDEO_STREAM_INFO] = { "SetVideoStreamInfo", "suiuuuuuu" },
        [ESPP_SERVICE_REQUEST_SET_DISPLAY_SURFACE_ID] = { "SetDisplaySurfaceId", "iuiiii" },
        [ESPP_SERVICE_REQUEST_SET_AUDIO_MUTE] = { "SetAudioMute", "b" },
+       [ESPP_SERVICE_REQUEST_SUBMIT_PACKET] = { "SubmitPacket", "iukku" },
        [ESPP_SERVICE_REQUEST_SET_CALLBACK] = { "SetCallback", "i" },
 };
 
index 8e6ad56dd189dc39a452e4174b25a8bbcc0a50a9..05c88260359ef5c3a18cf761a35739296f31145c 100644 (file)
@@ -39,6 +39,7 @@ typedef enum {
        ESPP_SERVICE_REQUEST_SET_VIDEO_STREAM_INFO,
        ESPP_SERVICE_REQUEST_SET_DISPLAY_SURFACE_ID,
        ESPP_SERVICE_REQUEST_SET_AUDIO_MUTE,
+       ESPP_SERVICE_REQUEST_SUBMIT_PACKET,
        ESPP_SERVICE_REQUEST_SET_CALLBACK,
 } espp_service_request_e;
 
index 8177052c7037306ca3425585944db050c0ad9c06..77c546852e0945d42a8bfdd2ee95e6a00214181c 100644 (file)
@@ -17,6 +17,7 @@
 #include "espp_service_priv.h"
 #include <esplusplayer_capi.h>
 #include <esplusplayer_internal.h>
+#include <inttypes.h>
 
 typedef int (*set_cb_func) (esplusplayer_handle handle, void *callback, void *user_data);
 typedef void (*func_handler) (handler_userdata_s *hdata, espp_service_data_from_client_s *data, espp_service_data_from_server_s *result);
@@ -343,7 +344,43 @@ static void __handle_set_audio_mute(handler_userdata_s *hdata, espp_service_data
        ret = esplusplayer_set_audio_mute((esplusplayer_handle)hdata->espp, mute);
        RET_IF(ret != ESPLUSPLAYER_ERROR_TYPE_NONE, "failed to esplusplayer_set_audio_mute(), ESPP[%p], mute[%d]", hdata->espp, mute);
 
-       LOG_INFO("fd[%d], ESPP[%p]: esplusplayer_set_surface_display() success, mute[%d]", hdata->fd, hdata->espp, mute);
+       LOG_INFO("fd[%d], ESPP[%p]: esplusplayer_set_audio_mute() success, mute[%d]", hdata->fd, hdata->espp, mute);
+
+       result->ret = 0;
+}
+
+static void __handle_submit_packet(handler_userdata_s *hdata, espp_service_data_from_client_s *data, espp_service_data_from_server_s *result)
+{
+       int ret;
+       esplusplayer_es_packet es_packet;
+       esplusplayer_submit_status status;
+       g_autofree gchar *buffer = NULL;
+
+       memset(&es_packet, 0x0, sizeof(esplusplayer_es_packet));
+       ret = espp_service_msg_parse_params(data->params, data->request,
+               &es_packet.type, &es_packet.buffer_size,
+               &es_packet.pts, &es_packet.duration,
+               &es_packet.hdr10p_metadata_size);
+       if (ret != 0)
+               return;
+
+       LOG_INFO("type[%d], buffer_size[%u], pts[%" PRIu64 "], duration[%" PRIu64 "], hdr10p_metadata_size[%u]",
+               es_packet.type, es_packet.buffer_size, es_packet.pts, es_packet.duration, es_packet.hdr10p_metadata_size);
+
+       if (es_packet.buffer_size > 0) {
+               buffer = g_malloc0(es_packet.buffer_size);
+               espp_service_read_buffer(hdata->fd, buffer, es_packet.buffer_size);
+               es_packet.buffer = buffer;
+       }
+
+       status = esplusplayer_submit_packet((esplusplayer_handle)hdata->espp, &es_packet);
+       if (status != ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS) {
+               result->ret = status;
+               LOG_ERROR("failed to esplusplayer_submit_packet(), status:%d", status);
+               return;
+       }
+
+       LOG_INFO("fd[%d], ESPP[%p]: esplusplayer_submit_packet() success", hdata->fd, hdata->espp);
 
        result->ret = 0;
 }
@@ -439,6 +476,7 @@ static func_handler handlers[] = {
        [ESPP_SERVICE_REQUEST_SET_VIDEO_STREAM_INFO] = __handle_set_video_stream_info,
        [ESPP_SERVICE_REQUEST_SET_DISPLAY_SURFACE_ID] = __handle_set_display_surface_id,
        [ESPP_SERVICE_REQUEST_SET_AUDIO_MUTE] = __handle_set_audio_mute,
+       [ESPP_SERVICE_REQUEST_SUBMIT_PACKET] = __handle_submit_packet,
        [ESPP_SERVICE_REQUEST_SET_CALLBACK] = __handle_set_callback,
 };
 
index b9e086819fe4db4150ffd22557f14543d94fb276..2f8c40070e28cc137d22d9a15003f2adb7d91804 100644 (file)
@@ -68,6 +68,7 @@ typedef struct {
 int espp_service_init_socket(espp_service_s *svc);
 void espp_service_deinit_socket(espp_service_s *svc);
 int espp_service_send_data(int fd, espp_service_data_from_server_s *data);
+int espp_service_read_buffer(int fd, char *buffer, uint32_t size);
 
 /* handler */
 int espp_service_func_handler(handler_userdata_s *hdata, espp_service_data_from_client_s *data, espp_service_data_from_server_s *result);
index 1dc26cd4e25dbf1a064796e8c1544c735702d1af..6bd5da0ebf919b33705d94c0c65f5dc4471f5134 100644 (file)
@@ -114,6 +114,7 @@ static int __request_msg_handling(handler_userdata_s *hdata, bool *event_mode)
                strerror_r(errno, str_error, sizeof(str_error));
                LOG_ERROR("failed to write(), fd[%d], err: %s", fd, str_error);
        }
+
        EXIT_IF_NEEDED(rx_data);
        SET_IF_EVENT_MODE(rx_data, event_mode);
 
@@ -337,3 +338,26 @@ int espp_service_send_data(int fd, espp_service_data_from_server_s *data)
 
        return 0;
 }
+
+int espp_service_read_buffer(int fd, char *buffer, uint32_t size)
+{
+       int ret;
+       char str_error[MAX_ERROR_LEN] = {'\0',};
+
+       ASSERT(fd >= 0);
+       ASSERT(buffer);
+
+       if ((ret = read(fd, buffer, size)) < 0) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               LOG_ERROR("failed to read(), fd[%d], err: %s", fd, str_error);
+               return -1;
+       }
+
+       if ((uint32_t)ret != size) {
+               LOG_ERROR("failed to read(), fd[%d], read size mismatched: ret[%d], expect size[%u]",
+                       fd, ret, size);
+               return -1;
+       }
+
+       return 0;
+}