[1.0.19] Implement raw media packet push case 75/290175/5
authorGilbok Lee <gilbok.lee@samsung.com>
Tue, 21 Mar 2023 06:04:40 +0000 (15:04 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Mon, 10 Apr 2023 01:52:18 +0000 (10:52 +0900)
Change-Id: I31c8382b15156fb5abf29ce326ca2ef350b77307

18 files changed:
CMakeLists.txt
include/MediaSourceAudio.h [moved from include/MediaSourceBinBaseAudio.h with 91% similarity]
include/MediaSourceBinAudioTest.h
include/MediaSourceBinCamera.h
include/MediaSourceBinMediaPacket.h
include/MediaSourceBinMic.h
include/MediaSourceBinVideoTest.h
include/MediaSourceVideo.h [moved from include/MediaSourceBinBaseVideo.h with 91% similarity]
include/MediaTransporterParam.h
packaging/capi-media-transporter.spec
src/MediaSourceAudio.cpp [moved from src/MediaSourceBinBaseAudio.cpp with 83% similarity]
src/MediaSourceBinMediaPacket.cpp
src/MediaSourceVideo.cpp [moved from src/MediaSourceBinBaseVideo.cpp with 80% similarity]
src/MediaTransporter.cpp
test/CMakeLists.txt
test/mtpr_test.c
test/mtpr_test_with_camera.c [new file with mode: 0644]
test/mtpr_test_with_camera.h [new file with mode: 0644]

index 6d3a7cf..2d0ab70 100644 (file)
@@ -11,9 +11,9 @@ SET(INC_DIR include)
 INCLUDE_DIRECTORIES(${INC_DIR})
 
 SET(dependents "dlog glib-2.0 gstreamer-1.0 gstreamer-video-1.0 gstreamer-audio-1.0 \
-                iniparser mm-common capi-media-tool mm-display-interface \
-                cynara-client libsmack capi-system-info capi-media-sound-manager \
-                gstreamer-rtsp-server-1.0 libpulse")
+                gstreamer-allocators-1.0 iniparser mm-common capi-media-tool mm-display-interface \
+                cynara-client libsmack libtbm capi-system-info \
+                capi-media-sound-manager gstreamer-rtsp-server-1.0 libpulse")
 
 IF(NOT TIZEN_PROFILE_TV)
     SET(dependents "${dependents} mm-resource-manager")
similarity index 91%
rename from include/MediaSourceBinBaseAudio.h
rename to include/MediaSourceAudio.h
index 6c2c3d0..38dfe41 100644 (file)
 
 namespace tizen_media_transporter {
 
-class MediaSourceBinBaseAudio : public MediaSourceBinBase
+class MediaSourceAudio
 {
 public:
-       MediaSourceBinBaseAudio() = default;
-       ~MediaSourceBinBaseAudio() = default;
+       MediaSourceAudio() = default;
+       ~MediaSourceAudio() = default;
 
        void setSourceAudioChannels(int channels);
        int getSourceAudioChannels();
@@ -49,6 +49,7 @@ protected:
        void setSourceParam(gst::GstElements& elements, const param::audioInfo& aInfo);
 
        param::audioInfo _audioInfo;
+       bool _useSrcCapsfilter = true;
 };
 
 } // namespace
index ae1051e..49bbcca 100644 (file)
 #include "MediaTransporter.h"
 #include "MediaTransporterGst.h"
 #include "MediaTransporterParam.h"
-#include "MediaSourceBinBaseAudio.h"
+#include "MediaSourceBinBase.h"
+#include "MediaSourceAudio.h"
 
 namespace tizen_media_transporter {
 
 const std::string DEFAULT_ELEMENT_AUDIO_TEST = "audiotestsrc";
 
-class MediaSourceBinAudioTest : public MediaSourceBinBaseAudio
+class MediaSourceBinAudioTest : public MediaSourceAudio, public MediaSourceBinBase
 {
 public:
        MediaSourceBinAudioTest();
index 96f6082..6eacf2e 100644 (file)
 #include "MediaTransporter.h"
 #include "MediaTransporterGst.h"
 #include "MediaTransporterParam.h"
-#include "MediaSourceBinBaseVideo.h"
+#include "MediaSourceBinBase.h"
+#include "MediaSourceVideo.h"
 
 namespace tizen_media_transporter {
 
 const std::string DEFAULT_ELEMENT_CAMERASRC = "v4l2src";
 
-class MediaSourceBinCamera : public MediaSourceBinBaseVideo
+class MediaSourceBinCamera : public MediaSourceVideo, public MediaSourceBinBase
 {
 public:
        MediaSourceBinCamera();
index 1f50f4b..ac1cbd5 100644 (file)
 #ifdef __cplusplus
 
 #include <string>
+#include <gst/gstallocator.h>
 
 #include "MediaTransporter.h"
 #include "MediaTransporterGst.h"
 #include "MediaTransporterParam.h"
 #include "MediaTransporterCallback.h"
 #include "MediaSourceBinBase.h"
+#include "MediaSourceAudio.h"
+#include "MediaSourceVideo.h"
 
 namespace tizen_media_transporter {
 
 const std::string DEFAULT_ELEMENT_MEDIA_PACKET = "appsrc";
 
-class MediaSourceBinMediaPacket : public MediaSourceBinBase
+class MediaSourceBinMediaPacket : public MediaSourceAudio, public MediaSourceVideo, public MediaSourceBinBase
 {
 public:
        MediaSourceBinMediaPacket();
@@ -64,17 +67,17 @@ private:
        void _makeCapsFromMediaFormat(media_format_h format);
        void _makeVideoCapsFromMediaFormat(media_format_h format);
        void _makeAudioCapsFromMediaFormat(media_format_h format);
-       GstCaps* _makeH264Caps(media_format_h format);
-       GstCaps* _makeAACCaps(media_format_h format);
+
        GstBuffer* _mediaPacketToGstBuffer(media_packet_h packet);
+       GstBuffer* _tbmSurfaceMediaPacketToGstBuffer(media_packet_h packet);
 
        media_format_h _mediaFormat = nullptr;
        formatType _formatType = FORMAT_NONE;
        GstElement* _mediaPacketSource = nullptr;
        GstCaps* _sourceCaps = nullptr;
        GList* _signals = nullptr;
-       param::videoInfo _videoInfo;
-       param::audioInfo _audioInfo;
+
+       GstAllocator* _gstAllocator = nullptr;
 };
 
 } // namespace
index 0df7624..032e21c 100644 (file)
 #include "MediaTransporter.h"
 #include "MediaTransporterGst.h"
 #include "MediaTransporterParam.h"
-#include "MediaSourceBinBaseAudio.h"
+#include "MediaSourceBinBase.h"
+#include "MediaSourceAudio.h"
 
 namespace tizen_media_transporter {
 
 const std::string DEFAULT_ELEMENT_MICSRC = "pulsesrc";
 
-class MediaSourceBinMic : public MediaSourceBinBaseAudio
+class MediaSourceBinMic : public MediaSourceAudio, public MediaSourceBinBase
 {
 public:
        MediaSourceBinMic();
index cc42aff..1f393ec 100644 (file)
 #include "MediaTransporter.h"
 #include "MediaTransporterGst.h"
 #include "MediaTransporterParam.h"
-#include "MediaSourceBinBaseVideo.h"
+#include "MediaSourceBinBase.h"
+#include "MediaSourceVideo.h"
 
 namespace tizen_media_transporter {
 
 const std::string DEFAULT_ELEMENT_VIDEO_TEST = "videotestsrc";
 
-class MediaSourceBinVideoTest : public MediaSourceBinBaseVideo
+class MediaSourceBinVideoTest : public MediaSourceVideo, public MediaSourceBinBase
 {
 public:
        MediaSourceBinVideoTest();
similarity index 91%
rename from include/MediaSourceBinBaseVideo.h
rename to include/MediaSourceVideo.h
index ea711b9..984de3b 100644 (file)
@@ -33,11 +33,11 @@ namespace tizen_media_transporter {
 
 using VideoResolution = std::pair<int, int>;
 
-class MediaSourceBinBaseVideo : public MediaSourceBinBase
+class MediaSourceVideo
 {
 public:
-       MediaSourceBinBaseVideo() = default;
-       ~MediaSourceBinBaseVideo() = default;
+       MediaSourceVideo() = default;
+       ~MediaSourceVideo() = default;
 
        void setSourceVideoResolution(int width, int height);
        VideoResolution getSourceVideoResolution();
@@ -50,6 +50,7 @@ protected:
        void setSourceParam(gst::GstElements& elements, const param::videoInfo& vInfo);
 
        param::videoInfo _videoInfo;
+       bool _useSrcCapsfilter = true;
 };
 
 } // namespace
index d427c44..58c4dd2 100644 (file)
@@ -25,14 +25,12 @@ namespace tizen_media_transporter {
 namespace param {
 
 struct videoInfo {
-       std::string mimeType;
        int width { -1 };
        int height { -1 };
        int frameRate { -1 };
 };
 
 struct audioInfo {
-       std::string mimeType;
        int channels { -1 };
        int rate { -1 };
        std::string format;
index 9216479..0011371 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-transporter
 Summary:    A Media Transporter library in Tizen Native API
-Version:    1.0.18
+Version:    1.0.19
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
@@ -25,10 +25,13 @@ BuildRequires:  pkgconfig(mm-common)
 BuildRequires:  pkgconfig(cynara-client)
 BuildRequires:  pkgconfig(libsmack)
 BuildRequires:  pkgconfig(capi-system-info)
+BuildRequires:  pkgconfig(libtbm)
 BuildRequires:  pkgconfig(capi-media-sound-manager)
+# for test
 BuildRequires:  pkgconfig(mm-display-interface)
 BuildRequires:  pkgconfig(esplusplayer)
 BuildRequires:  pkgconfig(mm-resource-manager)
+BuildRequires:  pkgconfig(capi-media-camera)
 %if 0%{?gtests:1}
 BuildRequires:  pkgconfig(gmock)
 %endif
similarity index 83%
rename from src/MediaSourceBinBaseAudio.cpp
rename to src/MediaSourceAudio.cpp
index 59e0cfe..22b95d0 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MediaSourceBinBaseAudio.h"
+#include "MediaSourceAudio.h"
 #include "MediaTransporterException.h"
 #include "MediaTransporterLog.h"
 #include "MediaTransporterParseIni.h"
@@ -60,23 +60,23 @@ static GstElement * _prepareAudioEncoder(const MtprMediaSourceIni& ini)
                                                                                MediaTransporterIni::get().general().gstExcludedElements);
 }
 
-gst::GstElements MediaSourceBinBaseAudio::createAudioRestOfElements(const MtprMediaSourceIni& ini)
+gst::GstElements MediaSourceAudio::createAudioRestOfElements(const MtprMediaSourceIni& ini)
 {
        gst::GstElements elements;
 
        // FIXME: make this simple
 
        try {
-               // capsfilter
-               GstElement* capsfilter = gst::_createElement("capsfilter", ELEMENT_NAME_SRC_CAPSFILTER);
-
                GstCaps* sinkCaps = NULL;
-               if ((sinkCaps = __makeAudioDefaultRawCaps(ini))) {
-                       g_object_set(G_OBJECT(capsfilter), "caps", sinkCaps, NULL);
-                       // source->render[idx].appsrc_caps = gst_caps_copy(sinkCaps);
-                       gst_caps_unref(sinkCaps);
+
+               if (_useSrcCapsfilter) {
+                       GstElement* capsfilter = gst::_createElement("capsfilter", ELEMENT_NAME_SRC_CAPSFILTER);
+                       if ((sinkCaps = __makeAudioDefaultRawCaps(ini))) {
+                               g_object_set(G_OBJECT(capsfilter), "caps", sinkCaps, NULL);
+                               gst_caps_unref(sinkCaps);
+                       }
+                       elements.push_back(capsfilter);
                }
-               elements.push_back(capsfilter);
 
                // audio convert
                elements.push_back(gst::_createElement("audioconvert"));
@@ -108,7 +108,7 @@ gst::GstElements MediaSourceBinBaseAudio::createAudioRestOfElements(const MtprMe
        return elements;
 }
 
-void MediaSourceBinBaseAudio::setSourceAudioSampleRate(int sampleRate)
+void MediaSourceAudio::setSourceAudioSampleRate(int sampleRate)
 {
        if (sampleRate <= 0)
                throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "invalid input sampleRate");
@@ -116,12 +116,12 @@ void MediaSourceBinBaseAudio::setSourceAudioSampleRate(int sampleRate)
        _audioInfo.rate = sampleRate;
 }
 
-int MediaSourceBinBaseAudio::getSourceAudioSampleRate()
+int MediaSourceAudio::getSourceAudioSampleRate()
 {
        return _audioInfo.rate;
 }
 
-void MediaSourceBinBaseAudio::setSourceAudioChannels(int channels)
+void MediaSourceAudio::setSourceAudioChannels(int channels)
 {
        if (channels <= 0)
                throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "invalid input channel");
@@ -129,12 +129,12 @@ void MediaSourceBinBaseAudio::setSourceAudioChannels(int channels)
        _audioInfo.channels = channels;
 }
 
-int MediaSourceBinBaseAudio::getSourceAudioChannels()
+int MediaSourceAudio::getSourceAudioChannels()
 {
        return _audioInfo.channels;
 }
 
-void MediaSourceBinBaseAudio::setSourceAudioFormat(mtprSourceAudioFormat format)
+void MediaSourceAudio::setSourceAudioFormat(mtprSourceAudioFormat format)
 {
        switch (format)
        {
@@ -185,7 +185,7 @@ void MediaSourceBinBaseAudio::setSourceAudioFormat(mtprSourceAudioFormat format)
        }
 }
 
-mtprSourceAudioFormat MediaSourceBinBaseAudio::getSourceAudioFormat()
+mtprSourceAudioFormat MediaSourceAudio::getSourceAudioFormat()
 {
        if (_audioInfo.format == "S16LE")
                return  MTPR_SOURCE_AUDIO_FORMAT_S16LE;
@@ -219,11 +219,13 @@ mtprSourceAudioFormat MediaSourceBinBaseAudio::getSourceAudioFormat()
                return  MTPR_SOURCE_AUDIO_FORMAT_NONE;
 }
 
-void MediaSourceBinBaseAudio::setSourceParam(gst::GstElements& elements, const param::audioInfo& aInfo)
+void MediaSourceAudio::setSourceParam(gst::GstElements& elements, const param::audioInfo& aInfo)
 {
-       GstElement* srcCapsfilter = gst::_findElementByName(elements, ELEMENT_NAME_SRC_CAPSFILTER);
-       if (srcCapsfilter)
-               gst::_updateCaps(srcCapsfilter, aInfo);
+       if (_useSrcCapsfilter) {
+               GstElement* srcCapsfilter = gst::_findElementByName(elements, ELEMENT_NAME_SRC_CAPSFILTER);
+               if (srcCapsfilter)
+                       gst::_updateCaps(srcCapsfilter, aInfo);
+       }
 
        GstElement* encCapsfilter = gst::_findElementByName(elements, ELEMENT_NAME_ENCODE_CAPSFILTER);
        if (encCapsfilter)
index 5e9cd93..91b5f0c 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 #include <algorithm>
+#include <tuple>
+
 #include <gst/app/gstappsrc.h>
+#include <gst/audio/audio.h>
+#include <gst/allocators/gsttizenmemory.h>
+
+#include <tbm_bufmgr.h>
 
 #include "MediaSourceBinMediaPacket.h"
 #include "MediaTransporterLog.h"
 #include "MediaTransporterParam.h"
 #include "MediaTransporterGst.h"
 
-
 using namespace tizen_media_transporter;
 
+const uint64_t CLOCK_TIME_NONE = ((uint64_t) -1);
+
 MediaSourceBinMediaPacket::MediaSourceBinMediaPacket()
 {
        LOG_DEBUG("ctor: %p", this);
@@ -37,6 +44,9 @@ MediaSourceBinMediaPacket::~MediaSourceBinMediaPacket()
        LOG_DEBUG("dtor: %p", this);
        if (_sourceCaps)
                gst_caps_unref(_sourceCaps);
+
+       if (_gstAllocator)
+               gst_object_unref(_gstAllocator);
 }
 
 void MediaSourceBinMediaPacket::_createMediaPacketSource()
@@ -59,6 +69,9 @@ MediaSourceBinInfo MediaSourceBinMediaPacket::generate()
 {
        gst::GstElements elements;
 
+       if (_mediaPacketSource == nullptr)
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Media packet source isn't created");
+
        try {
                elements.push_back(_mediaPacketSource);
                gst::_connectAndAppendSignal(&_signals, G_OBJECT(_mediaPacketSource), "need-data", G_CALLBACK(_needDataCallback), this);
@@ -79,6 +92,20 @@ MediaSourceBinInfo MediaSourceBinMediaPacket::generate()
                        GstElement *queue = gst::_createElement("queue", "srcQueue");
                        g_object_set(G_OBJECT(queue), "max-size-buffers", 1, NULL);
                        elements.push_back(queue);
+               } else if (_formatType == FORMAT_RAW_AUDIO) {
+                       MediaSourceAudio::_useSrcCapsfilter = false;
+                       auto created = createAudioRestOfElements(MediaTransporterIni::get().mediaSource(static_cast<int>(MTPR_SOURCE_TYPE_MEDIAPACKET)));
+                       std::copy(created.begin(), created.end(), std::back_inserter(elements));
+
+                       MediaSourceAudio::setSourceParam(elements, _audioInfo);
+                       setEncoderParam(elements, _encInfo);
+               } else if (_formatType == FORMAT_RAW_VIDEO) {
+                       MediaSourceVideo::_useSrcCapsfilter = false;
+                       auto created = createVideoRestOfElements(MediaTransporterIni::get().mediaSource(static_cast<int>(MTPR_SOURCE_TYPE_MEDIAPACKET)));
+                       std::copy(created.begin(), created.end(), std::back_inserter(elements));
+
+                       MediaSourceVideo::setSourceParam(elements, _videoInfo);
+                       setEncoderParam(elements, _encInfo);
                }
        } catch (const MediaTransporterException& e) {
                gst::_disconnectSignal(&_signals, G_OBJECT(_mediaPacketSource));
@@ -123,7 +150,11 @@ void MediaSourceBinMediaPacket::pushMediaPacket(media_packet_h packet)
                if (_mediaPacketSource == nullptr)
                        throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Media packet source isn't created");
 
-               GstBuffer* buffer = _mediaPacketToGstBuffer(packet);
+               bool hasTbmSurface = false;
+               if (media_packet_has_tbm_surface_buffer(packet, &hasTbmSurface) != MEDIA_PACKET_ERROR_NONE)
+                       throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "failed to media_packet_has_tbm_surface_buffer()");
+
+               GstBuffer* buffer = hasTbmSurface ? _tbmSurfaceMediaPacketToGstBuffer(packet) : _mediaPacketToGstBuffer(packet);
                gst_app_src_push_buffer(GST_APP_SRC(_mediaPacketSource), buffer);
 
        } catch (const MediaTransporterException& e) {
@@ -147,15 +178,75 @@ void MediaSourceBinMediaPacket::_makeCapsFromMediaFormat(media_format_h format)
                throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Fail to get media format type");
        }
 
-       if (mediaFormatType == MEDIA_FORMAT_VIDEO) {
-               _makeVideoCapsFromMediaFormat(format);
-       } else if (mediaFormatType == MEDIA_FORMAT_AUDIO) {
-               _makeAudioCapsFromMediaFormat(format);
-       } else {
-               throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "Not supported media format");
+       try {
+               if (mediaFormatType == MEDIA_FORMAT_VIDEO) {
+                       _makeVideoCapsFromMediaFormat(format);
+               } else if (mediaFormatType == MEDIA_FORMAT_AUDIO) {
+                       _makeAudioCapsFromMediaFormat(format);
+               } else {
+                       throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "Not supported media format");
+               }
+       } catch (const MediaTransporterException& e) {
+               LOG_ERROR("%s", e.what());
+               throw;
        }
 }
 
+static void memoryFinalizeCallback(media_packet_h packet)
+{
+       LOG_DEBUG("packet[%p] about to release", packet);
+
+       media_packet_destroy(packet);
+}
+
+GstBuffer* MediaSourceBinMediaPacket::_tbmSurfaceMediaPacketToGstBuffer(media_packet_h packet)
+{
+       if (!packet)
+               throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "packet is NULL");
+
+       tbm_surface_h surface = nullptr;
+       if (media_packet_get_tbm_surface(packet, &surface) != MEDIA_PACKET_ERROR_NONE)
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "failed to media_packet_get_tbm_surface()");
+
+       uint64_t pts = CLOCK_TIME_NONE;
+       if (media_packet_get_pts(packet, &pts) != MEDIA_PACKET_ERROR_NONE)
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "failed to media_packet_get_pts()");
+
+       uint64_t dts = CLOCK_TIME_NONE;
+       if (media_packet_get_dts(packet, &dts) != MEDIA_PACKET_ERROR_NONE)
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "failed to media_packet_get_dts()");
+
+       uint64_t duration = CLOCK_TIME_NONE;
+       if (media_packet_get_duration(packet, &duration) != MEDIA_PACKET_ERROR_NONE)
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "failed to media_packet_get_duration()");
+
+       GstBuffer* gstBuffer = gst_buffer_new();
+       if (!gstBuffer)
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "failed to gst_buffer_new()");
+
+       if (!_gstAllocator)
+               _gstAllocator = gst_tizen_allocator_new();
+
+       GstVideoInfo vinfo {};
+       GstMemory* gstMemory = gst_tizen_allocator_alloc_surface(_gstAllocator, &vinfo, surface, packet, (GDestroyNotify)memoryFinalizeCallback);
+       if (!gstMemory) {
+               gst_buffer_unref(gstBuffer);
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "failed to gst_tizen_allocator_alloc_surface()");
+       }
+
+       if (pts != CLOCK_TIME_NONE)
+               GST_BUFFER_PTS(gstBuffer) = static_cast<GstClockTime>(pts);
+
+       if (dts != CLOCK_TIME_NONE)
+               GST_BUFFER_DTS(gstBuffer) = static_cast<GstClockTime>(dts);
+
+       if (duration != CLOCK_TIME_NONE)
+               GST_BUFFER_DURATION(gstBuffer) = static_cast<GstClockTime>(duration);
+
+       gst_buffer_append_memory(gstBuffer, gstMemory);
+
+       return gstBuffer;
+}
 
 GstBuffer* MediaSourceBinMediaPacket::_mediaPacketToGstBuffer(media_packet_h packet)
 {
@@ -192,123 +283,173 @@ GstBuffer* MediaSourceBinMediaPacket::_mediaPacketToGstBuffer(media_packet_h pac
 
        gst_buffer_set_size(gstBuffer, size);
 
-       uint64_t pts = 0;
+       uint64_t pts = CLOCK_TIME_NONE;
        media_packet_get_pts(packet, &pts);
-       GST_BUFFER_PTS(gstBuffer) = static_cast<GstClockTime>(pts);
+       if (pts != CLOCK_TIME_NONE)
+               GST_BUFFER_PTS(gstBuffer) = static_cast<GstClockTime>(pts);
 
-       uint64_t duration = 0;
+       uint64_t dts = CLOCK_TIME_NONE;
+       media_packet_get_dts(packet, &dts);
+       if (dts != CLOCK_TIME_NONE)
+               GST_BUFFER_DTS(gstBuffer) = static_cast<GstClockTime>(dts);
+
+       uint64_t duration = CLOCK_TIME_NONE;
        media_packet_get_duration(packet, &duration);
-       GST_BUFFER_DURATION(gstBuffer) = static_cast<GstClockTime>(duration);
+       if (duration != CLOCK_TIME_NONE)
+               GST_BUFFER_DURATION(gstBuffer) = static_cast<GstClockTime>(duration);
 
        return gstBuffer;
 }
 
-void MediaSourceBinMediaPacket::_makeAudioCapsFromMediaFormat(media_format_h format)
+std::tuple <std::string, std::string, int>
+       _getAudioFormat(media_format_mimetype_e mimeType)
 {
-       int ret;
-       media_format_mimetype_e mimetype;
-       ret = media_format_get_audio_info(format, &mimetype, &_audioInfo.channels, &_audioInfo.rate, nullptr, nullptr);
-       if (ret != MEDIA_FORMAT_ERROR_NONE) {
-               LOG_ERROR("Fail to get audio info");
-               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Fail to get audio info");
+       switch (mimeType) {
+       /* RAW formats */
+       case MEDIA_FORMAT_PCM_S16LE:
+               return std::make_tuple("audio/x-raw", "S16LE", 0);
+       case MEDIA_FORMAT_PCM_S24LE:
+               return std::make_tuple("audio/x-raw", "S24LE", 0);
+       case MEDIA_FORMAT_PCM_S32LE:
+               return std::make_tuple("audio/x-raw", "S32LE", 0);
+       case MEDIA_FORMAT_PCM_S16BE:
+               return std::make_tuple("audio/x-raw", "S16BE", 0);
+       case MEDIA_FORMAT_PCM_S24BE:
+               return std::make_tuple("audio/x-raw", "S24BE", 0);
+       case MEDIA_FORMAT_PCM_S32BE:
+               return std::make_tuple("audio/x-raw", "S32BE", 0);
+       case MEDIA_FORMAT_PCM_F32LE:
+               return std::make_tuple("audio/x-raw", "F32LE", 0);
+       case MEDIA_FORMAT_PCM_F32BE:
+               return std::make_tuple("audio/x-raw", "F32BE", 0);
+       case MEDIA_FORMAT_PCM_U16LE:
+               return std::make_tuple("audio/x-raw", "U16LE", 0);
+       case MEDIA_FORMAT_PCM_U24LE:
+               return std::make_tuple("audio/x-raw", "U24LE", 0);
+       case MEDIA_FORMAT_PCM_U32LE:
+               return std::make_tuple("audio/x-raw", "U32LE", 0);
+       case MEDIA_FORMAT_PCM_U16BE:
+               return std::make_tuple("audio/x-raw", "U16BE", 0);
+       case MEDIA_FORMAT_PCM_U24BE:
+               return std::make_tuple("audio/x-raw", "U24BE", 0);
+       case MEDIA_FORMAT_PCM_U32BE:
+               return std::make_tuple("audio/x-raw", "U32BE", 0);
+       /* ENCODED formats */
+       case MEDIA_FORMAT_AAC: /* fall through */
+       case MEDIA_FORMAT_AAC_HE: /* fall through */
+       case MEDIA_FORMAT_AAC_HE_PS:
+               return std::make_tuple("audio/mpeg", "", 4);
+       default:
+               LOG_ERROR("not supported audio mimeType(0x%x)", mimeType);
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "not supported audio mimeType");
        }
+}
 
-       if (isRawFormat(mimetype)) {
-               _formatType = FORMAT_RAW_AUDIO;
-               _audioInfo.mimeType = "audio/x-raw";
-       } else {
-               _formatType = FORMAT_ENCODED_AUDIO;
-               if ((mimetype >= MEDIA_FORMAT_AAC) && (mimetype <= MEDIA_FORMAT_AAC_HE_PS)) {
-                       LOG_DEBUG("Input format is aac");
-                       _sourceCaps = _makeAACCaps(format);
-               } else {
-                       throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "Not supported audio format");
-               }
+std::tuple <std::string, std::string, std::string>
+       _getVideoFormat(media_format_mimetype_e mimeType)
+{
+       switch (mimeType) {
+       /* RAW formats */
+       case MEDIA_FORMAT_I420:
+               return std::make_tuple("video/x-raw", "I420", "");
+       case MEDIA_FORMAT_NV12:
+               return std::make_tuple("video/x-raw", "NV12", "");
+       /* ENCODED formats */
+       case MEDIA_FORMAT_H264_SP: /* fall through */
+       case MEDIA_FORMAT_H264_MP: /* fall through */
+       case MEDIA_FORMAT_H264_HP:
+               return std::make_tuple("video/x-h264", "", "byte-stream");
+       default:
+               LOG_ERROR("not supported video mimeType(0x%x)", mimeType);
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "not supported video mimeType");
        }
 }
 
-void MediaSourceBinMediaPacket::_makeVideoCapsFromMediaFormat(media_format_h format)
+void MediaSourceBinMediaPacket::_makeAudioCapsFromMediaFormat(media_format_h format)
 {
        int ret;
        media_format_mimetype_e mimetype;
-       ret = media_format_get_video_info(format, &mimetype, nullptr, nullptr, nullptr, nullptr);
+       GstCaps* caps = nullptr;
+
+       ret = media_format_get_audio_info(format, &mimetype, &_audioInfo.channels, &_audioInfo.rate, nullptr, nullptr);
        if (ret != MEDIA_FORMAT_ERROR_NONE) {
-               LOG_ERROR("Fail to get video info");
-               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Fail to get video info");
+               LOG_ERROR("Fail to get audio info");
+               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Fail to get audio info");
        }
 
-       if (isRawFormat(mimetype)) {
-               _formatType = FORMAT_RAW_VIDEO;
-               _videoInfo.mimeType = "video/x-raw";
-       } else {
-               _formatType = FORMAT_ENCODED_VIDEO;
-               if ((mimetype >= MEDIA_FORMAT_H264_SP) && (mimetype <= MEDIA_FORMAT_H264_C444P)) {
-                       LOG_DEBUG("Input format is H264");
-                       _sourceCaps =_makeH264Caps(format);
-               } else {
-                       throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "Not supported video format");
-               }
+       _formatType = isRawFormat(mimetype) ? FORMAT_RAW_AUDIO : FORMAT_ENCODED_AUDIO;
+
+       if (_formatType == FORMAT_ENCODED_AUDIO &&
+                       ((mimetype < MEDIA_FORMAT_AAC) || (mimetype > MEDIA_FORMAT_AAC_HE_PS)))
+               throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "Not supported audio format");
+
+       auto [mime, audioFormat, mpegVersion] = _getAudioFormat(mimetype);
+
+       caps = gst_caps_new_empty_simple(mime.c_str());
+
+       if (!audioFormat.empty()) {
+               gst_caps_set_simple(caps, "format", G_TYPE_STRING, audioFormat.c_str(), nullptr);
+               _audioInfo.format = audioFormat;
        }
+
+       if (mpegVersion > 0)
+               gst_caps_set_simple(caps, "mpegversion", G_TYPE_INT, mpegVersion, nullptr);
+
+       if (_audioInfo.channels > 0)
+               gst_caps_set_simple(caps, "channels", G_TYPE_INT, _audioInfo.channels, nullptr);
+
+       if (_audioInfo.rate > 0)
+               gst_caps_set_simple(caps, "rate", G_TYPE_INT, _audioInfo.rate, nullptr);
+
+       _sourceCaps = caps;
 }
 
-GstCaps* MediaSourceBinMediaPacket::_makeH264Caps(media_format_h format)
+void MediaSourceBinMediaPacket::_makeVideoCapsFromMediaFormat(media_format_h format)
 {
        int ret;
-       int width = 0;
-       int height = 0;
-       int frameRate = 0;
+       media_format_mimetype_e mimetype;
        GstCaps* caps = nullptr;
 
-       ret = media_format_get_video_info(format, nullptr, &width, &height, nullptr, nullptr);
+       ret = media_format_get_video_info(format, &mimetype, &_videoInfo.width, &_videoInfo.height, nullptr, nullptr);
        if (ret != MEDIA_FORMAT_ERROR_NONE) {
                LOG_ERROR("Fail to get video info");
                throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Fail to get video info");
        }
 
-       ret = media_format_get_video_frame_rate(format, &frameRate);
+       ret = media_format_get_video_frame_rate(format, &_videoInfo.frameRate);
        if (ret != MEDIA_FORMAT_ERROR_NONE) {
                throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Fail to get video frame rate");
        }
 
-       caps = gst_caps_new_empty_simple("video/x-h264");
-       gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", nullptr);
+       _formatType = isRawFormat(mimetype) ? FORMAT_RAW_VIDEO : FORMAT_ENCODED_VIDEO;
 
-       if (width > 0)
-               gst_caps_set_simple(caps, "width", G_TYPE_INT, width, nullptr);
+       if (_formatType == FORMAT_ENCODED_VIDEO &&
+                       ((mimetype < MEDIA_FORMAT_H264_SP) || (mimetype > MEDIA_FORMAT_H264_C444P)))
+               throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "Not supported video format");
 
-       if (height > 0)
-               gst_caps_set_simple(caps, "height", G_TYPE_INT, height, nullptr);
+       auto [mime, name, streamFormat] = _getVideoFormat(mimetype);
 
-       if (frameRate > 0)
-               gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION,
-                               frameRate, 1, nullptr);
+       caps = gst_caps_new_empty_simple(mime.c_str());
 
-       return caps;
-}
+       if (!name.empty())
+               gst_caps_set_simple(caps, "format", G_TYPE_STRING, name.c_str(), nullptr);
 
-GstCaps* MediaSourceBinMediaPacket::_makeAACCaps(media_format_h format)
-{
-       int ret;
-       int channels = 0;
-       int rate = 0;
-       GstCaps* caps = nullptr;
+       if (!streamFormat.empty())
+               gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, streamFormat.c_str(), nullptr);
 
-       ret = media_format_get_audio_info(format, nullptr, &channels, &rate, nullptr, nullptr);
-       if (ret != MEDIA_FORMAT_ERROR_NONE) {
-               LOG_ERROR("Fail to get audio info");
-               throw MediaTransporterException(MTPR_ERROR_INVALID_OPERATION, "Fail to get audio info");
-       }
 
-       caps = gst_caps_new_simple("audio/mpeg",
-                                       "mpegversion", G_TYPE_INT, 4, nullptr);
+       if (_videoInfo.width > 0)
+               gst_caps_set_simple(caps, "width", G_TYPE_INT, _videoInfo.width, nullptr);
 
-       if (channels > 0)
-               gst_caps_set_simple(caps, "channels", G_TYPE_INT, channels, nullptr);
+       if (_videoInfo.height > 0)
+               gst_caps_set_simple(caps, "height", G_TYPE_INT, _videoInfo.height, nullptr);
+
+       if (_videoInfo.frameRate > 0)
+               gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION,
+                               _videoInfo.frameRate, 1, nullptr);
 
-       if (rate > 0)
-               gst_caps_set_simple(caps, "rate", G_TYPE_INT, rate, nullptr);
+       _sourceCaps = caps;
 
-       return caps;
 }
 
 void MediaSourceBinMediaPacket::setBufferStateChangedCallback(void* handle, mtprPacketSourceBufferStateCallback callback, void* userData)
similarity index 80%
rename from src/MediaSourceBinBaseVideo.cpp
rename to src/MediaSourceVideo.cpp
index a3a8f22..fa3cf9a 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MediaSourceBinBaseVideo.h"
+#include "MediaSourceVideo.h"
 #include "MediaTransporterException.h"
 #include "MediaTransporterLog.h"
 #include "MediaTransporterParseIni.h"
@@ -66,24 +66,25 @@ static GstElement * _prepareVideoEncoder(const MtprMediaSourceIni& ini)
                                                                                MediaTransporterIni::get().general().gstExcludedElements);
 }
 
-std::vector<GstElement*> MediaSourceBinBaseVideo::createVideoRestOfElements(const MtprMediaSourceIni& ini)
+std::vector<GstElement*> MediaSourceVideo::createVideoRestOfElements(const MtprMediaSourceIni& ini)
 {
        std::vector<GstElement*>  elements;
 
        // FIXME: make this simple
 
        try {
-               // capsfilter
-               GstElement *capsfilter = gst::_createElement("capsfilter", ELEMENT_NAME_SRC_CAPSFILTER);
-
                GstCaps *sinkCaps = NULL;
-               if ((sinkCaps = __makeVideoDefaultRawCaps(ini))) {
-                       gst::_printCaps(sinkCaps, ELEMENT_NAME_SRC_CAPSFILTER);
-                       g_object_set(G_OBJECT(capsfilter), "caps", sinkCaps, NULL);
-                       // source->render[idx].appsrc_caps = gst_caps_copy(sinkCaps);
-                       gst_caps_unref(sinkCaps);
+
+               if (_useSrcCapsfilter) {
+                       GstElement *capsfilter = gst::_createElement("capsfilter", ELEMENT_NAME_SRC_CAPSFILTER);
+
+                       if ((sinkCaps = __makeVideoDefaultRawCaps(ini))) {
+                               gst::_printCaps(sinkCaps, ELEMENT_NAME_SRC_CAPSFILTER);
+                               g_object_set(G_OBJECT(capsfilter), "caps", sinkCaps, NULL);
+                               gst_caps_unref(sinkCaps);
+                       }
+                       elements.push_back(capsfilter);
                }
-               elements.push_back(capsfilter);
 
                // encoder
                GstElement *encoder = _prepareVideoEncoder(ini);
@@ -93,20 +94,6 @@ std::vector<GstElement*> MediaSourceBinBaseVideo::createVideoRestOfElements(cons
 
                elements.push_back(encoder);
 
-               // parser from encoder
-               std::string factory_name = GST_OBJECT_NAME(gst_element_get_factory(encoder));
-               GstElement *parser = nullptr;
-
-               if (factory_name.find("h264") != std::string::npos)
-                       parser = gst::_createElement("h264parse");
-               else if (factory_name.find("mpeg4") != std::string::npos)
-                       parser = gst::_createElement("mpeg4videoparse");
-
-               if (parser) {
-                       g_object_set(G_OBJECT(parser), "config-interval", -1, NULL);
-                       elements.push_back(parser);
-               }
-
                // capsfilter2
                GstElement *capsfilter2 = gst::_createElement("capsfilter", ELEMENT_NAME_ENCODE_CAPSFILTER);
 
@@ -123,6 +110,20 @@ std::vector<GstElement*> MediaSourceBinBaseVideo::createVideoRestOfElements(cons
 
                elements.push_back(capsfilter2);
 
+               // parser from encoder
+               std::string factory_name = GST_OBJECT_NAME(gst_element_get_factory(encoder));
+               GstElement *parser = nullptr;
+
+               if (factory_name.find("h264") != std::string::npos)
+                       parser = gst::_createElement("h264parse");
+               else if (factory_name.find("mpeg4") != std::string::npos)
+                       parser = gst::_createElement("mpeg4videoparse");
+
+               if (parser) {
+                       g_object_set(G_OBJECT(parser), "config-interval", -1, NULL);
+                       elements.push_back(parser);
+               }
+
                // queue
                GstElement *queue = gst::_createElement("queue", "srcQueue");
                g_object_set(G_OBJECT(queue), "max-size-buffers", 1, NULL);
@@ -135,7 +136,7 @@ std::vector<GstElement*> MediaSourceBinBaseVideo::createVideoRestOfElements(cons
        return elements;
 }
 
-void MediaSourceBinBaseVideo::setSourceVideoResolution(int width, int height)
+void MediaSourceVideo::setSourceVideoResolution(int width, int height)
 {
        if (width <= 0 || height <= 0)
                throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "invalid input width/height");
@@ -144,12 +145,12 @@ void MediaSourceBinBaseVideo::setSourceVideoResolution(int width, int height)
        _videoInfo.height = height;
 }
 
-VideoResolution MediaSourceBinBaseVideo::getSourceVideoResolution()
+VideoResolution MediaSourceVideo::getSourceVideoResolution()
 {
        return std::make_pair(_videoInfo.width, _videoInfo.height);
 }
 
-void MediaSourceBinBaseVideo::setSourceVideoFrameRate(int frameRate)
+void MediaSourceVideo::setSourceVideoFrameRate(int frameRate)
 {
        if (frameRate <= 0)
                throw MediaTransporterException(MTPR_ERROR_INVALID_PARAMETER, "invalid input frameRate");
@@ -157,16 +158,18 @@ void MediaSourceBinBaseVideo::setSourceVideoFrameRate(int frameRate)
        _videoInfo.frameRate = frameRate;
 }
 
-int MediaSourceBinBaseVideo::getSourceVideoFrameRate()
+int MediaSourceVideo::getSourceVideoFrameRate()
 {
        return _videoInfo.frameRate;
 }
 
-void MediaSourceBinBaseVideo::setSourceParam(gst::GstElements& elements, const param::videoInfo& vInfo)
+void MediaSourceVideo::setSourceParam(gst::GstElements& elements, const param::videoInfo& vInfo)
 {
-       GstElement* srcCapsfilter = gst::_findElementByName(elements, ELEMENT_NAME_SRC_CAPSFILTER);
-       if (srcCapsfilter)
-               gst::_updateCaps(srcCapsfilter, vInfo);
+       if (_useSrcCapsfilter) {
+               GstElement* srcCapsfilter = gst::_findElementByName(elements, ELEMENT_NAME_SRC_CAPSFILTER);
+               if (srcCapsfilter)
+                       gst::_updateCaps(srcCapsfilter, vInfo);
+       }
 
        GstElement* encCapsfilter = gst::_findElementByName(elements, ELEMENT_NAME_ENCODE_CAPSFILTER);
        if (encCapsfilter)
index 3f21a70..830e4c0 100644 (file)
@@ -5,8 +5,8 @@
 #include "MediaTransporterFactory.h"
 #include "MediaSourceBinFactory.h"
 #include "MediaSourceBinBase.h"
-#include "MediaSourceBinBaseAudio.h"
-#include "MediaSourceBinBaseVideo.h"
+#include "MediaSourceAudio.h"
+#include "MediaSourceVideo.h"
 #include "MediaTransporterException.h"
 #include "MediaTransporterSender.h"
 #include "MediaTransporterReceiver.h"
@@ -320,10 +320,13 @@ int mtpr_media_source_set_video_resolution(mtpr_h mtpr, unsigned int source_id,
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseVideo* videoSourceBin = dynamic_cast<MediaSourceBinBaseVideo*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!videoSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
 
-               videoSourceBin->setSourceVideoResolution(width, height);
+               MediaSourceVideo* videoSource = dynamic_cast<MediaSourceVideo*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!videoSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+
+               videoSource->setSourceVideoResolution(width, height);
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to set video source resolution!!! : %s", e.what());
                return e.error();
@@ -345,10 +348,13 @@ int mtpr_media_source_get_video_resolution(mtpr_h mtpr, unsigned int source_id,
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseVideo* videoSourceBin = dynamic_cast<MediaSourceBinBaseVideo*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!videoSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
+
+               MediaSourceVideo* videoSource = dynamic_cast<MediaSourceVideo*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!videoSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               std::tie(*width, *height)  = videoSourceBin->getSourceVideoResolution();
+               std::tie(*width, *height)  = videoSource->getSourceVideoResolution();
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to get video source resolution!!! : %s", e.what());
                return e.error();
@@ -368,10 +374,13 @@ int mtpr_media_source_set_video_framerate(mtpr_h mtpr, unsigned int source_id, i
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseVideo* videoSourceBin = dynamic_cast<MediaSourceBinBaseVideo*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!videoSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
+
+               MediaSourceVideo* videoSource = dynamic_cast<MediaSourceVideo*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!videoSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               videoSourceBin->setSourceVideoFrameRate(framerate);
+               videoSource->setSourceVideoFrameRate(framerate);
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to set video source framerate!!! : %s", e.what());
                return e.error();
@@ -392,10 +401,13 @@ int mtpr_media_source_get_video_framerate(mtpr_h mtpr, unsigned int source_id, i
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseVideo* videoSourceBin = dynamic_cast<MediaSourceBinBaseVideo*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!videoSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
 
-               *framerate = videoSourceBin->getSourceVideoFrameRate();
+               MediaSourceVideo* videoSource = dynamic_cast<MediaSourceVideo*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!videoSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+
+               *framerate = videoSource->getSourceVideoFrameRate();
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to get video source framerate!!! : %s", e.what());
                return e.error();
@@ -415,10 +427,13 @@ int mtpr_media_source_set_audio_channels(mtpr_h mtpr, unsigned int source_id, in
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseAudio* audioSourceBin = dynamic_cast<MediaSourceBinBaseAudio*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!audioSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
+
+               MediaSourceAudio* audioSource = dynamic_cast<MediaSourceAudio*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!audioSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               audioSourceBin->setSourceAudioChannels(channels);
+               audioSource->setSourceAudioChannels(channels);
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to set audio channel!!! : %s", e.what());
                return e.error();
@@ -439,10 +454,13 @@ int mtpr_media_source_get_audio_channels(mtpr_h mtpr, unsigned int source_id, in
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseAudio* audioSourceBin = dynamic_cast<MediaSourceBinBaseAudio*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!audioSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
 
-               *channels = audioSourceBin->getSourceAudioChannels();
+               MediaSourceAudio* audioSource = dynamic_cast<MediaSourceAudio*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!audioSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+
+               *channels = audioSource->getSourceAudioChannels();
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to get audio channel!!! : %s", e.what());
                return e.error();
@@ -462,10 +480,13 @@ int mtpr_media_source_set_audio_samplerate(mtpr_h mtpr, unsigned int source_id,
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseAudio* audioSourceBin = dynamic_cast<MediaSourceBinBaseAudio*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!audioSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
+
+               MediaSourceAudio* audioSource = dynamic_cast<MediaSourceAudio*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!audioSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               audioSourceBin->setSourceAudioSampleRate(samplerate);
+               audioSource->setSourceAudioSampleRate(samplerate);
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to set audio samplerate!!! : %s", e.what());
                return e.error();
@@ -486,10 +507,13 @@ int mtpr_media_source_get_audio_samplerate(mtpr_h mtpr, unsigned int source_id,
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseAudio* audioSourceBin = dynamic_cast<MediaSourceBinBaseAudio*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!audioSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
+
+               MediaSourceAudio* audioSource = dynamic_cast<MediaSourceAudio*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!audioSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               *samplerate = audioSourceBin->getSourceAudioSampleRate();
+               *samplerate = audioSource->getSourceAudioSampleRate();
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to get audio samplerate!!! : %s", e.what());
                return e.error();
@@ -509,10 +533,13 @@ int mtpr_media_source_set_audio_format(mtpr_h mtpr, unsigned int source_id, mtpr
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseAudio* audioSourceBin = dynamic_cast<MediaSourceBinBaseAudio*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!audioSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
 
-               audioSourceBin->setSourceAudioFormat(format);
+               MediaSourceAudio* audioSource = dynamic_cast<MediaSourceAudio*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!audioSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+
+               audioSource->setSourceAudioFormat(format);
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to set audio format!!! : %s", e.what());
                return e.error();
@@ -533,10 +560,13 @@ int mtpr_media_source_get_audio_format(mtpr_h mtpr, unsigned int source_id, mtpr
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinBaseAudio* audioSourceBin = dynamic_cast<MediaSourceBinBaseAudio*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!audioSourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(mediaPacketSourceBIn, MTPR_ERROR_INVALID_OPERATION, "mediapacket source type doesn't support this api ");
+
+               MediaSourceAudio* audioSource = dynamic_cast<MediaSourceAudio*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!audioSource, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               *format = audioSourceBin->getSourceAudioFormat();
+               *format = audioSource->getSourceAudioFormat();
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to get audio format!!! : %s", e.what());
                return e.error();
@@ -557,10 +587,10 @@ int mtpr_media_packet_source_set_format(mtpr_h mtpr, unsigned int source_id, med
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinMediaPacket* mediaPacketsourceBin = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!mediaPacketsourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!mediaPacketSourceBIn, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               mediaPacketsourceBin->setMediaFormat(format);
+               mediaPacketSourceBIn->setMediaFormat(format);
 
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to set media packet format!!! : %s", e.what());
@@ -581,10 +611,10 @@ int mtpr_media_packet_source_push_packet(mtpr_h mtpr, unsigned int source_id, me
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinMediaPacket* mediaPacketsourceBin = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!mediaPacketsourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!mediaPacketSourceBIn, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               mediaPacketsourceBin->pushMediaPacket(packet);
+               mediaPacketSourceBIn->pushMediaPacket(packet);
 
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to push media packet!!! : %s", e.what());
@@ -605,10 +635,10 @@ int mtpr_media_packet_source_set_buffer_state_changed_cb(mtpr_h mtpr, unsigned i
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinMediaPacket* mediaPacketsourceBin = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!mediaPacketsourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!mediaPacketSourceBIn, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               mediaPacketsourceBin->setBufferStateChangedCallback(mtpr, callback, user_data);
+               mediaPacketSourceBIn->setBufferStateChangedCallback(mtpr, callback, user_data);
 
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to set media packet source state changed callback!!! : %s", e.what());
@@ -629,10 +659,10 @@ int mtpr_media_packet_source_unset_buffer_state_changed_cb(mtpr_h mtpr, unsigned
                MediaTransporterSender* sender = dynamic_cast<MediaTransporterSender*>(handle->base.get());
                RET_VAL_IF(!sender, MTPR_ERROR_INVALID_OPERATION, "only sender support this api!!!");
 
-               MediaSourceBinMediaPacket* mediaPacketsourceBin = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
-               RET_VAL_IF(!mediaPacketsourceBin, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
+               MediaSourceBinMediaPacket* mediaPacketSourceBIn = dynamic_cast<MediaSourceBinMediaPacket*>(sender->getMediaSource(source_id));
+               RET_VAL_IF(!mediaPacketSourceBIn, MTPR_ERROR_INVALID_PARAMETER, "Invalid source id");
 
-               mediaPacketsourceBin->unsetBufferStateChangedCallback();
+               mediaPacketSourceBIn->unsetBufferStateChangedCallback();
 
        } catch (const MediaTransporterException& e) {
                LOG_ERROR("Failed to unset media packet source state changed callback!!! : %s", e.what());
index 00d6b01..a7b7596 100644 (file)
@@ -7,7 +7,7 @@ INCLUDE_DIRECTORIES(../include)
 link_directories(${CMAKE_SOURCE_DIR}/../)
 
 INCLUDE(FindPkgConfig)
-    pkg_check_modules(${fw_test} REQUIRED glib-2.0 appcore-efl elementary esplusplayer)
+    pkg_check_modules(${fw_test} REQUIRED glib-2.0 appcore-efl elementary esplusplayer capi-media-camera)
 
 FOREACH(flag ${${fw_test}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
index 955adb3..f4bc0de 100644 (file)
@@ -25,6 +25,7 @@
 #ifdef TIZEN_FEATURE_ESPP
 #include "mtpr_test_espp.h"
 #endif
+#include "mtpr_test_with_camera.h"
 
 #ifdef PACKAGE
 #undef PACKAGE
@@ -94,6 +95,7 @@ static int g_video_source_id = 0;
 #ifdef TIZEN_FEATURE_ESPP
 static bool g_use_espp = false;
 #endif
+static bool g_use_camera_for_packet = false;
 
 static void _mtpr_test_unset_track_cb();
 static void _mtpr_test_unset_encoded_audio_frame_cb();
@@ -329,6 +331,9 @@ static void _mtpr_test_destroy()
                sound_manager_destroy_stream_information(g_stream_info);
                g_stream_info = NULL;
        }
+
+       if (g_use_camera_for_packet)
+               _mtrp_test_camera_packet_src_destroy();
 }
 
 static void _mtpr_test_start()
@@ -345,6 +350,9 @@ static void _mtpr_test_start()
                g_print("             => failed to mtpr_start() returned [0x%x]\n", ret);
        else
                g_print("             => mtpr_start() success\n");
+
+       if (g_use_camera_for_packet)
+               _mtpr_test_camera_packet_src_start();
 }
 
 static void _mtpr_test_stop()
@@ -361,6 +369,9 @@ static void _mtpr_test_stop()
                g_print("             => failed to mtpr_stop() returned [0x%x]\n", ret);
        else
                g_print("             => mtpr_stop() success\n");
+
+       if (g_use_camera_for_packet)
+               _mtrp_test_camera_packet_src_stop();
 }
 
 static void _mtpr_test_set_display(unsigned int type)
@@ -1175,7 +1186,7 @@ static void displaymenu()
        } else if (g_menu_state == CURRENT_STATUS_CONNECTION_GET_PARAM) {
                g_print("*** Input connection param key\n");
        } else if (g_menu_state == CURRENT_STATUS_ADD_MEDIA_SOURCE) {
-               g_print("*** Input media source type.(1:camera, 2:mic, 3:videotest, 4:audiotest)\n");
+               g_print("*** Input media source type.(1:camera, 2:mic, 3:videotest, 4:audiotest, 5:mediapacket(camera))\n");
        } else if (g_menu_state == CURRENT_STATUS_SOURCE_VIDEO_RESOLUTION) {
                g_print("*** Input source video resolution(width, height)\n");
        } else if (g_menu_state == CURRENT_STATUS_SOURCE_VIDEO_FRAMERATE) {
@@ -1304,6 +1315,10 @@ static void interpret(char *cmd)
        case CURRENT_STATUS_ADD_MEDIA_SOURCE: {
                value = atoi(cmd);
                _mtpr_test_add_media_source((mtpr_source_type_e) value - 1);
+               if (value == 5) {
+                       _mtpr_test_camera_packet_src_create(g_mtpr, g_video_source_id);
+                       g_use_camera_for_packet = true;
+               }
                reset_menu_state();
                break;
        }
diff --git a/test/mtpr_test_with_camera.c b/test/mtpr_test_with_camera.c
new file mode 100644 (file)
index 0000000..2655e04
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <camera.h>
+#include "mtpr_test_with_camera.h"
+
+#define WAIT_TIMEOUT 5
+
+typedef struct _test_camera_packet_src_s {
+       mtpr_h mtpr;
+       int source_id;
+       camera_h camera;
+       bool push_packet;
+       media_format_h format;
+} test_camera_packet_src_s;
+
+static test_camera_packet_src_s *g_camera_src = NULL;
+
+
+static void _camera_error_cb(int error, camera_state_e current_state, void *user_data)
+{
+       g_print("\n\n\tERROR [0x%x], current state %d\n", error, current_state);
+
+       switch (error) {
+       case CAMERA_ERROR_RESOURCE_CONFLICT:
+               g_print("\t\t[CAMERA_ERROR_RESOURCE_CONFLICT]\n\n");
+               break;
+       case CAMERA_ERROR_SECURITY_RESTRICTED:
+               g_print("\t\t[CAMERA_ERROR_SECURITY_RESTRICTED]\n\n");
+               break;
+       case CAMERA_ERROR_SERVICE_DISCONNECTED:
+               g_print("\t\t[CAMERA_ERROR_SERVICE_DISCONNECTED]\n\n");
+               break;
+       default:
+               break;
+       }
+}
+
+static void _camera_media_packet_cb(media_packet_h pkt, void *user_data)
+{
+       test_camera_packet_src_s *camera_src = (test_camera_packet_src_s *)user_data;
+       if (!camera_src)
+               return;
+
+       if (!camera_src->mtpr)
+               return;
+
+       if (!pkt)
+               return;
+
+       if (!camera_src->format) {
+               media_format_h get_format;
+               media_format_mimetype_e mime_type;
+               int width;
+               int height;
+               int framerate;
+               media_packet_get_format(pkt, &get_format);
+               media_format_get_video_info(get_format, &mime_type, &width, &height, NULL, NULL);
+               media_format_get_video_frame_rate(get_format, &framerate);
+               camera_src->format = get_format;
+               bool hasTbmSurface;
+               media_packet_has_tbm_surface_buffer(pkt, &hasTbmSurface);
+               mtpr_media_packet_source_set_format(camera_src->mtpr, camera_src->source_id, camera_src->format);
+       }
+
+       if (camera_src->push_packet)
+               mtpr_media_packet_source_push_packet(camera_src->mtpr, camera_src->source_id, pkt);
+
+       media_packet_unref(pkt);
+}
+
+void _mtpr_test_camera_packet_src_create(mtpr_h mtpr, int source_id)
+{
+       if (!mtpr) {
+               g_print("mtpr is NULL\n");
+               return;
+       }
+
+       g_camera_src = g_new0(test_camera_packet_src_s, 1);
+       g_camera_src->mtpr = mtpr;
+       g_camera_src->source_id = source_id;
+
+       camera_create(CAMERA_DEVICE_CAMERA0, &g_camera_src->camera);
+       camera_set_error_cb(g_camera_src->camera, _camera_error_cb, NULL);
+       camera_set_display(g_camera_src->camera, CAMERA_DISPLAY_TYPE_NONE, NULL);
+       camera_set_media_packet_preview_cb(g_camera_src->camera, _camera_media_packet_cb, g_camera_src);
+       camera_start_preview(g_camera_src->camera);
+}
+
+void _mtpr_test_camera_packet_src_start()
+{
+       g_camera_src->push_packet = true;
+}
+
+void _mtrp_test_camera_packet_src_stop()
+{
+       camera_stop_preview(g_camera_src->camera);
+}
+
+void _mtrp_test_camera_packet_src_destroy()
+{
+       camera_destroy(g_camera_src->camera);
+       g_free(g_camera_src);
+       g_camera_src = NULL;
+}
diff --git a/test/mtpr_test_with_camera.h b/test/mtpr_test_with_camera.h
new file mode 100644 (file)
index 0000000..d2a6a4f
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_MEDIA_MTPR_CAMERA_TEST_H__
+#define __TIZEN_MEDIA_MTPR_CAMERA_TEST_H__
+
+#include <mtpr_internal.h>
+
+void _mtpr_test_camera_packet_src_create(mtpr_h mtpr, int source_id);
+void _mtpr_test_camera_packet_src_start();
+void _mtrp_test_camera_packet_src_stop();
+void _mtrp_test_camera_packet_src_destroy();
+
+#endif
\ No newline at end of file