webrtc_sink: Revise media packet for encoded frame callback 02/253702/4
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 17 Feb 2021 00:05:49 +0000 (09:05 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 19 Feb 2021 08:48:55 +0000 (17:48 +0900)
The gstbuffer data field is set as external memory pointer of the
media packet. The pointer of gstbuffer is set to extra data of the
media packet. If the caps of the pad has 'codec_data' field, it is
set to the media packet.

[Version] 0.1.113
[Issue Type] Improvement

Change-Id: Ib361a0a9a2600b262c60486c22f27850a21cc5d0
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/capi-media-webrtc.spec
src/webrtc_sink.c

index 61f0b87a25a888a81ed70621ed62ded7b8d4b175..42de0987f6ddc7abc454cfa201cb8683e20bfe3c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.1.112
+Version:    0.1.113
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 28015a64a5cbb81d333acf599a5a78877e894518..5e7a152840383edd179cafeee4049ec096ff4e10 100644 (file)
@@ -17,6 +17,7 @@
 #include "webrtc.h"
 #include "webrtc_private.h"
 #include <gst/video/videooverlay.h>
+#include <media_packet_internal.h>
 
 #define GST_KLASS_NAME_DEPAYLOADER_RTP "Codec/Depayloader/Network/RTP"
 
@@ -531,6 +532,7 @@ static media_format_h __make_media_format(GstPad *pad)
 {
        GstCaps *caps;
        GstStructure *structure;
+       gchar *caps_str;
        const gchar *mime;
        media_format_h format;
        media_format_mimetype_e mimetype;
@@ -543,26 +545,27 @@ static media_format_h __make_media_format(GstPad *pad)
        structure = gst_caps_get_structure(caps, 0);
        mime = gst_structure_get_name(structure);
 
-       gchar *caps_str = gst_caps_to_string(caps);
-       LOG_INFO("%s", caps_str);
+       caps_str = gst_caps_to_string(caps);
+       LOG_WARNING("%s", caps_str);
        g_free(caps_str);
-       gst_caps_unref(caps);
 
        if (__get_media_format_mimetype(mime, &mimetype) != WEBRTC_ERROR_NONE) {
+               gst_caps_unref(caps);
                media_format_unref(format);
                return NULL;
        }
+       gst_caps_unref(caps);
 
        LOG_INFO("mimetype[0x%x]", mimetype);
 
-       if (g_strrstr(mime, "video")) {
+       if (mimetype & MEDIA_FORMAT_VIDEO) {
                ret = media_format_set_video_mime(format, mimetype);
                if (ret != MEDIA_FORMAT_ERROR_NONE) {
                        LOG_ERROR("failed to media_format_set_video_mime()");
                        media_format_unref(format);
                        return NULL;
                }
-       } else if (g_strrstr(mime, "audio")) {
+       } else if (mimetype & MEDIA_FORMAT_AUDIO) {
                ret = media_format_set_audio_mime(format, mimetype);
                if (ret != MEDIA_FORMAT_ERROR_NONE) {
                        LOG_ERROR("failed to media_format_set_audio_mime()");
@@ -581,20 +584,47 @@ static int __media_packet_finalize_cb(media_packet_h packet, int error_code, voi
 
        RET_VAL_IF(sink == NULL, MEDIA_PACKET_FINALIZE, "sink is NULL");
 
-       if (media_packet_get_buffer_data_ptr(packet, (void**)&buffer) == MEDIA_PACKET_ERROR_NONE)
+       if (media_packet_get_extra(packet, (void**)&buffer) == MEDIA_PACKET_ERROR_NONE)
                gst_buffer_unref(buffer);
-       else
-               LOG_ERROR("failed to media_packet_get_buffer_data_ptr()");
 
        LOG_DEBUG("sink[%p], packet[%p], buffer[%p]", sink, packet, buffer);
 
        return MEDIA_PACKET_FINALIZE;
 }
 
+static int __set_codec_data_if_exist(media_packet_h packet, GstPad *pad)
+{
+       int ret = WEBRTC_ERROR_NONE;
+       GstCaps *caps;
+       const GValue *codec_data_value;
+
+       caps = gst_pad_get_current_caps(pad);
+
+       if ((codec_data_value = gst_structure_get_value(gst_caps_get_structure(caps, 0), "codec_data"))) {
+               GstBuffer *codec_data;
+               GstMapInfo buff_info;
+
+               codec_data = gst_value_get_buffer(codec_data_value);
+               gst_buffer_map(codec_data, &buff_info, GST_MAP_READ);
+               ret = media_packet_set_codec_data(packet, buff_info.data, buff_info.size);
+               if (ret != MEDIA_PACKET_ERROR_NONE) {
+                       LOG_ERROR("failed to media_packet_set_codec_data()");
+                       ret = WEBRTC_ERROR_INVALID_OPERATION;
+               }
+               LOG_DEBUG("codec_data[%p, size:%u] is set to the media packet[%p]", buff_info.data, buff_info.size, packet);
+               gst_buffer_unmap(codec_data, &buff_info);
+       }
+
+       gst_caps_unref(caps);
+
+       return ret;
+}
+
 static media_packet_h __make_media_packet(webrtc_gst_slot_s *sink, GstBuffer *buffer, GstPad *pad)
 {
        int ret;
-       media_packet_h packet;
+       media_packet_h packet = NULL;
+       GstMapInfo info = GST_MAP_INFO_INIT;
 
        RET_VAL_IF(sink == NULL, NULL, "sink is NULL");
        RET_VAL_IF(buffer == NULL, NULL, "buffer is NULL");
@@ -604,12 +634,47 @@ static media_packet_h __make_media_packet(webrtc_gst_slot_s *sink, GstBuffer *bu
                sink->media_format = __make_media_format(pad);
 
        gst_buffer_ref(buffer);
-       ret = media_packet_create_from_external_memory(sink->media_format, buffer, gst_buffer_get_size(buffer), __media_packet_finalize_cb, sink, &packet);
-       RET_VAL_IF(ret != MEDIA_PACKET_ERROR_NONE, NULL, "failed to media_packet_create_from_external_memory()");
+
+       if (!gst_buffer_map(buffer, &info, GST_MAP_READ)) {
+               LOG_ERROR("failed to gst_buffer_map()");
+               goto error;
+       }
+
+       ret = media_packet_create_from_external_memory(sink->media_format, info.data, gst_buffer_get_size(buffer), __media_packet_finalize_cb, sink, &packet);
+       gst_buffer_unmap(buffer, &info);
+       if (ret != MEDIA_PACKET_ERROR_NONE) {
+               LOG_ERROR("failed to media_packet_create_from_external_memory()");
+               goto error;
+       }
+
+       ret |= media_packet_set_pts(packet, GST_BUFFER_PTS(buffer));
+       ret |= media_packet_set_dts(packet, GST_BUFFER_DTS(buffer));
+       ret |= media_packet_set_duration(packet, GST_BUFFER_DURATION(buffer));
+
+       /* FIXME: We put the gstbuffer to extra field of media packet. It does not guarantee the validity of the gstbuffer
+        * after destroying this media packet. Currently, the gstbuffer must be used before destroying the packet. */
+       ret |= media_packet_set_extra(packet, (void *)buffer);
+       if (ret != MEDIA_PACKET_ERROR_NONE) {
+               LOG_ERROR("failed to media_packet_set_*()");
+               goto error;
+       }
+
+       ret = __set_codec_data_if_exist(packet, pad);
+       if (ret != WEBRTC_ERROR_NONE)
+               goto error;
 
        LOG_DEBUG("sink[%p], packet[%p], buffer[%p]", sink, packet, buffer);
 
        return packet;
+
+error:
+       if (packet)
+               media_packet_destroy(packet);
+       gst_buffer_unref(buffer);
+       media_format_unref(sink->media_format);
+       sink->media_format = NULL;
+
+       return NULL;
 }
 
 /* handoff signal handler */