From 0d8e8ce3c179feb035d2470a828b4900ab9eb80a Mon Sep 17 00:00:00 2001 From: Fancy code <258828110.@qq.com> Date: Tue, 18 Jun 2024 16:10:16 +0800 Subject: [PATCH] Improve:ffmpeg compile CMakeLists.txt --- external/ffmpeg/CMakeLists.txt | 54 +++++++++----- external/ffmpeg/README.md | 24 +++++++ test/CMakeLists.txt | 23 +----- .../tool/src/AppManagerMakePtrTest.cpp | 4 +- test/utils/CMakeLists.txt | 3 +- test/utils/MediaBase/CMakeLists.txt | 71 +++++++++++++++++++ test/utils/MediaBase/mainTest.cpp | 23 ++++++ test/utils/MediaBase/src/MediaBase_Test.cpp | 32 +++++++++ utils/MediaBase/CMakeLists.txt | 3 +- utils/MediaBase/src/IMediaBase.cpp | 7 +- utils/MediaBase/src/MediaBaseImpl.cpp | 44 ++++++++++++ utils/MediaBase/src/MediaBaseMakePtr.cpp | 37 ++++++++++ utils/MediaBase/src/MediaBaseMakePtr.h | 28 ++++++++ 13 files changed, 304 insertions(+), 49 deletions(-) create mode 100644 external/ffmpeg/README.md create mode 100644 test/utils/MediaBase/CMakeLists.txt create mode 100644 test/utils/MediaBase/mainTest.cpp create mode 100644 test/utils/MediaBase/src/MediaBase_Test.cpp create mode 100644 utils/MediaBase/src/MediaBaseMakePtr.cpp create mode 100644 utils/MediaBase/src/MediaBaseMakePtr.h diff --git a/external/ffmpeg/CMakeLists.txt b/external/ffmpeg/CMakeLists.txt index 1310e1e3..a18f0da6 100644 --- a/external/ffmpeg/CMakeLists.txt +++ b/external/ffmpeg/CMakeLists.txt @@ -1,26 +1,42 @@ - +set(FFMPEG_INSTALL_PATH "${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg") +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + set(CONFIGURE_COMMAND "--enable-cross-compile --target-os=linux --arch=linux \ + --cc=${CMAKE_C_COMPILER} \ + --cxx=${CMAKE_CXX_COMPILER} \ + --prefix=${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg \ + --enable-parsers --enable-decoder=h264 \ + --enable-ffmpeg --enable-shared --enable-static \ + --enable-gpl --enable-nonfree --enable-version3 --enable-small \ + --enable-muxer=mov --enable-muxer=mp4 \ + --enable-decoder=aac \ + --enable-demuxer=mov \ + --enable-protocol=file --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --enable-bsf=hevc_mp4toannexb") +else() + set(CONFIGURE_COMMAND "--enable-cross-compile --target-os=linux --arch=arm64 \ + --cc=${CMAKE_C_COMPILER} \ + --cxx=${CMAKE_CXX_COMPILER} \ + --prefix=${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg \ + --disable-asm --enable-parsers --disable-decoders --enable-decoder=h264 \ + --disable-debug --enable-ffmpeg --enable-shared --enable-static --disable-stripping --disable-doc \ + --enable-gpl --enable-nonfree --enable-version3 --enable-small \ + --disable-mipsdsp --disable-mipsdspr2 \ + --disable-encoders \ + --disable-muxers --enable-muxer=mov --enable-muxer=mp4 \ + --disable-decoders --enable-decoder=aac \ + --disable-filters \ + --disable-demuxers --enable-demuxer=mov \ + --disable-parsers \ + --disable-protocols --enable-protocol=file \ + --disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --enable-bsf=hevc_mp4toannexb \ + --disable-indevs \ + --disable-outdevs --disable-ffprobe --disable-ffmpeg --disable-ffplay --disable-debug") +endif() +message("Compile ffmpeg comand : ${CONFIGURE_COMMAND}") add_custom_target( ffmpeg COMMAND test -f ${EXTERNAL_SOURCE_PATH}/ffmpeg/Makefile || tar -xf ffmpeg_6.1.1.orig.tar.xz COMMAND chmod 777 -R ffmpeg-6.1.1 - COMMAND cd ffmpeg-6.1.1 && ./configure --enable-cross-compile --target-os=linux --arch=arm64 - --cc=${CMAKE_C_COMPILER} - --cxx=${CMAKE_CXX_COMPILER} - --prefix=${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg - --disable-asm --enable-parsers --disable-decoders --enable-decoder=h264 - --disable-debug --enable-ffmpeg --enable-shared --enable-static --disable-stripping --disable-doc - --enable-gpl --enable-nonfree --enable-version3 --enable-small - --disable-mipsdsp --disable-mipsdspr2 - --disable-encoders - --disable-muxers --enable-muxer=mov --enable-muxer=mp4 - --disable-decoders --enable-decoder=aac - --disable-filters - --disable-demuxers --enable-demuxer=mov - --disable-parsers - --disable-protocols --enable-protocol=file - --disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --enable-bsf=hevc_mp4toannexb - --disable-indevs - --disable-outdevs --disable-ffprobe --disable-ffmpeg --disable-ffplay --disable-debug + COMMAND cd ffmpeg-6.1.1 && bash -c "./configure ${CONFIGURE_COMMAND}" COMMAND cd ffmpeg-6.1.1 && make COMMAND cd ffmpeg-6.1.1 && make install COMMAND cd ffmpeg-6.1.1 && make clean diff --git a/external/ffmpeg/README.md b/external/ffmpeg/README.md new file mode 100644 index 00000000..bb65b302 --- /dev/null +++ b/external/ffmpeg/README.md @@ -0,0 +1,24 @@ +# 1. ffmpeg开发文档 + +## 1.1. 问题记录 + +### 1.1.1. avformat_open_input执行失败 + +  在执行avformat_open_input时,返回-1094995529<0,错误 + +解决:在Ubuntu编译时,使能所有的编译选项,并且把--arch=赋值为linux + +```code +# 详见://external/ffmpeg/CMakeLists.txt +set(CONFIGURE_COMMAND "--enable-cross-compile --target-os=linux --arch=linux \ +--cc=${CMAKE_C_COMPILER} \ +--cxx=${CMAKE_CXX_COMPILER} \ +--prefix=${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg \ +--enable-parsers --enable-decoder=h264 \ +--enable-ffmpeg --enable-shared --enable-static \ +--enable-gpl --enable-nonfree --enable-version3 --enable-small \ +--enable-muxer=mov --enable-muxer=mp4 \ +--enable-decoder=aac \ +--enable-demuxer=mov \ +--enable-protocol=file --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --enable-bsf=hevc_mp4toannexb") +``` \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index cbd8e4cb..921a6cfe 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -32,28 +32,7 @@ endif() # Mock Linux api. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_LINUX_MOCK}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TEST_LINUX_MOCK}") -# build gtest and gmock -# add_custom_command( -# OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/libgtest.a -# OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/libgmock.a -# COMMAND echo "Build google test for test code." -# COMMAND sh build_gtest.sh ${TARGET_PLATFORM} ${PLATFORM_PATH} ${PLATFORM_PATH} -# COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib/libgtest.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgtest.a -# COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib/libgmock.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgmock.a -# WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/ -# ) -# # add_custom_target( -# # google_test -# # DEPENDS libgtest.a libgmock.a -# # ) -# add_custom_target( -# libgtest.a -# DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libgtest.a -# ) -# add_custom_target( -# libgmock.a -# DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libgmock.a -# ) +add_definitions(-DTEST_SOURCE_PATH="${TEST_SOURCE_PATH}") add_subdirectory(all) add_subdirectory(application) diff --git a/test/middleware/AppManager/tool/src/AppManagerMakePtrTest.cpp b/test/middleware/AppManager/tool/src/AppManagerMakePtrTest.cpp index e1598932..f2f3f88b 100644 --- a/test/middleware/AppManager/tool/src/AppManagerMakePtrTest.cpp +++ b/test/middleware/AppManager/tool/src/AppManagerMakePtrTest.cpp @@ -13,9 +13,9 @@ * limitations under the License. */ #include "AppManagerMakePtrTest.h" +#include "AppManagerMakePtr.h" #include "AppManagerMock.h" #include "IAppManager.h" -#include "AppManagerMakePtr.h" #include "ILog.h" #include "StatusCode.h" #include @@ -42,11 +42,9 @@ void CancelOverrideAppManagerMakePtrObject(void) } AppManagerMakePtrTest::AppManagerMakePtrTest() { - // } AppManagerMakePtrTest::~AppManagerMakePtrTest() { - // mAppManagerMock.reset(); } const StatusCode AppManagerMakePtrTest::CreateAppManager(std::shared_ptr &impl) diff --git a/test/utils/CMakeLists.txt b/test/utils/CMakeLists.txt index 251acc6d..5a21e7a2 100644 --- a/test/utils/CMakeLists.txt +++ b/test/utils/CMakeLists.txt @@ -8,4 +8,5 @@ add_subdirectory(LinuxApiMock) add_subdirectory(McuProtocol) add_subdirectory(FxHttpServer) add_subdirectory(TestManager) -add_subdirectory(TcpModule) \ No newline at end of file +add_subdirectory(TcpModule) +add_subdirectory(MediaBase) \ No newline at end of file diff --git a/test/utils/MediaBase/CMakeLists.txt b/test/utils/MediaBase/CMakeLists.txt new file mode 100644 index 00000000..e6f6492a --- /dev/null +++ b/test/utils/MediaBase/CMakeLists.txt @@ -0,0 +1,71 @@ +# include(${CMAKE_SOURCE_DIR}/build/independent_source.cmake) +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}/bin) + +include_directories( + ./tool/include + ${UTILS_SOURCE_PATH}/StatusCode/include + ${UTILS_SOURCE_PATH}/Log/include + ${UTILS_SOURCE_PATH}/MediaBase/include + ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include + ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include + ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include +) + +link_directories( + ${LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg/lib +) + +aux_source_directory(. SRC_FILES) +aux_source_directory(./src SRC_FILES) +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + aux_source_directory(./src_mock SRC_FILES) +endif() + +set(TARGET_NAME MediaBaseTest) +add_executable(${TARGET_NAME} ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} MediaBase gtest gmock pthread Log) +if(${TEST_COVERAGE} MATCHES "true") + target_link_libraries(${TARGET_NAME} gcov) +endif() +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + target_link_libraries(${TARGET_NAME} LinuxApiMock) +endif() +add_custom_target( + MediaBaseTest_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + # --line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/gtest.h\"}]' + --line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/*.h\"}]' + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/utils/MediaBase +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + MediaBaseTest_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/utils/MediaBase +) +if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make MediaBaseTest_code_check + COMMAND make MediaBaseTest_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TARGET_NAME}) + +# if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tool/CMakeLists.txt") +# add_subdirectory(tool) +# endif() \ No newline at end of file diff --git a/test/utils/MediaBase/mainTest.cpp b/test/utils/MediaBase/mainTest.cpp new file mode 100644 index 00000000..475ceee4 --- /dev/null +++ b/test/utils/MediaBase/mainTest.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Fancy Code. + * 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 +#include +#include +#include +int main(int argc, char *argv[]) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/test/utils/MediaBase/src/MediaBase_Test.cpp b/test/utils/MediaBase/src/MediaBase_Test.cpp new file mode 100644 index 00000000..79b4b5ad --- /dev/null +++ b/test/utils/MediaBase/src/MediaBase_Test.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Fancy Code. + * 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 "ILog.h" +#include "MediaBase.h" +#include +#include +#include +namespace MediaBaseTest +{ +// ../output_files/test/bin/MediaBaseTest --gtest_filter=MediaBaseTest.UNIT_MediaBase_EXAMPLE_Demo +TEST(MediaBaseTest, UNIT_MediaBase_EXAMPLE_Demo) +{ + CreateLogModule(); + ILogInit(LOG_INSTANCE_TYPE_END); + void *readH264 = ICreateMediaBase(MEDIA_HANDLE_TYPE_READ_H264); + IStartReadFile(readH264, TEST_SOURCE_PATH "/support_test/video.h264"); + IMediaBaseFree(readH264); + ILogUnInit(); +} +} // namespace MediaBaseTest \ No newline at end of file diff --git a/utils/MediaBase/CMakeLists.txt b/utils/MediaBase/CMakeLists.txt index c27aed28..070a87c3 100644 --- a/utils/MediaBase/CMakeLists.txt +++ b/utils/MediaBase/CMakeLists.txt @@ -9,6 +9,7 @@ include_directories( ${UTILS_SOURCE_PATH}/StatusCode/include ${UTILS_SOURCE_PATH}/ModBusCRC16/include ${UTILS_SOURCE_PATH}/Log/include + ${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg/include ) # link_directories( # ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs @@ -18,7 +19,7 @@ aux_source_directory(./src SRC_FILES) set(TARGET_NAME MediaBase) add_library(${TARGET_NAME} STATIC ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} StatusCode Log) +target_link_libraries(${TARGET_NAME} avformat avcodec avutil swresample StatusCode Log) add_custom_target( MediaBase_code_check diff --git a/utils/MediaBase/src/IMediaBase.cpp b/utils/MediaBase/src/IMediaBase.cpp index 0bbf06bd..7996ecb7 100644 --- a/utils/MediaBase/src/IMediaBase.cpp +++ b/utils/MediaBase/src/IMediaBase.cpp @@ -14,14 +14,15 @@ */ #include "IMediaBase.h" #include "ILog.h" +#include "MediaBaseMakePtr.h" #include StatusCode IMediaBase::StartReadFile(const std::string &path) { - LogInfo("STATUS_CODE_VIRTUAL_FUNCTION\n"); + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } static const char *MEDIA_BASE_NAME = "media_adapter"; -const char inline *GetMediaBaseModuleName(void) +const char *GetMediaBaseModuleName(void) { return MEDIA_BASE_NAME; } @@ -32,6 +33,6 @@ std::shared_ptr *NewIMediaBase(const MediaHandleType &type) MeidaAdapter tmp; memcpy((void *)impl, (void *)&tmp, sizeof(MeidaAdapter)); impl->mHeader.mCheckName = MEDIA_BASE_NAME; - impl->mIMediaBase = std::make_shared(); + impl->mIMediaBase = MediaBaseMakePtr::GetInstance()->CreateMediaBase(); return (std::shared_ptr *)(((char *)impl) + sizeof(MediaBaseHeader)); } \ No newline at end of file diff --git a/utils/MediaBase/src/MediaBaseImpl.cpp b/utils/MediaBase/src/MediaBaseImpl.cpp index 186715eb..360b965c 100644 --- a/utils/MediaBase/src/MediaBaseImpl.cpp +++ b/utils/MediaBase/src/MediaBaseImpl.cpp @@ -13,8 +13,52 @@ * limitations under the License. */ #include "MediaBaseImpl.h" +#include "ILog.h" +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +#ifdef __cplusplus +} +#endif StatusCode MediaBaseImpl::StartReadFile(const std::string &path) { + InitFfmpeg(); + int result = 0; + AVFormatContext *pFormatCtx = nullptr; + if ((result = avformat_open_input(&pFormatCtx, path.c_str(), nullptr, nullptr)) < 0) { + LogError("Couldn't open file: %s, result=%d\n", path.c_str(), result); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + if (avformat_find_stream_info(pFormatCtx, nullptr) < 0) { + LogError("Couldn't find stream information.\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + int video_stream_index = -1; + for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++) { + if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + video_stream_index = i; + break; + } + } + if (video_stream_index == -1) { + LogError("Didn't find a video stream.\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + AVPacket packet; + // av_new_packet(&packet, AV_INPUT_BUFFER_MIN_SIZE); + while (av_read_frame(pFormatCtx, &packet) >= 0) { + // 检查数据包是否属于视频流 + if (packet.stream_index == video_stream_index) { + LogInfo("Frame data address: %p, length: %zu\n", packet.data, packet.size); + } + // 释放数据包 + av_packet_unref(&packet); + } + + avformat_close_input(&pFormatCtx); return CreateStatusCode(STATUS_CODE_OK); } void MediaBaseImpl::InitFfmpeg(void) diff --git a/utils/MediaBase/src/MediaBaseMakePtr.cpp b/utils/MediaBase/src/MediaBaseMakePtr.cpp new file mode 100644 index 00000000..4c14267e --- /dev/null +++ b/utils/MediaBase/src/MediaBaseMakePtr.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Fancy Code. + * 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 "MediaBaseMakePtr.h" +#include "ILog.h" +#include "MediaBaseImpl.h" +std::shared_ptr &MediaBaseMakePtr::GetInstance(std::shared_ptr *impl) +{ + static auto instance = std::make_shared(); + if (impl) { + if (instance.use_count() == 1) { + LogInfo("Instance changed succeed.\n"); + instance = *impl; + } + else { + LogError("Can't changing the instance becase of using by some one.\n"); + } + } + return instance; +} +std::shared_ptr MediaBaseMakePtr::CreateMediaBase(void) +{ + LogInfo("MediaBaseMakePtr::CreateMediaBase.\n"); + auto tmp = std::make_shared(); + return tmp; +} \ No newline at end of file diff --git a/utils/MediaBase/src/MediaBaseMakePtr.h b/utils/MediaBase/src/MediaBaseMakePtr.h new file mode 100644 index 00000000..5f954aa2 --- /dev/null +++ b/utils/MediaBase/src/MediaBaseMakePtr.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Fancy Code. + * 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 MEDIA_BASE_MAKEPTR_H +#define MEDIA_BASE_MAKEPTR_H +#include "IMediaBase.h" +#include "StatusCode.h" +#include +class MediaBaseMakePtr +{ +public: + MediaBaseMakePtr() = default; + virtual ~MediaBaseMakePtr() = default; + static std::shared_ptr &GetInstance(std::shared_ptr *impl = nullptr); + virtual std::shared_ptr CreateMediaBase(void); +}; +#endif \ No newline at end of file