1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Video Session Ffmpeg Utils
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktVideoSessionFfmpegUtils.hpp"
25 #include "vkDefs.hpp"
26 #include "tcuPlatform.hpp"
27 #include "tcuFunctionLibrary.hpp"
28
29 #include "extFFmpegDemuxer.h"
30 #include "deMemory.h"
31
32 #if (DE_OS == DE_OS_WIN32)
33 # define FFMPEG_AVCODEC_LIBRARY_NAME "avcodec-58.dll"
34 # define FFMPEG_AVFORMAT_LIBRARY_NAME "avformat-58.dll"
35 # define FFMPEG_AVUTIL_LIBRARY_NAME "avutil-56.dll"
36 #else
37 # define FFMPEG_AVCODEC_LIBRARY_NAME "libavcodec.so"
38 # define FFMPEG_AVFORMAT_LIBRARY_NAME "libavformat.so"
39 # define FFMPEG_AVUTIL_LIBRARY_NAME "libavutil.so"
40 #endif
41
42
43 namespace vkt
44 {
45 namespace video
46 {
47
48 class DataProviderImpl : public FFmpegDemuxer::DataProvider
49 {
50 public:
51 DataProviderImpl (de::MovePtr<std::vector<deUint8>>& data);
52
~DataProviderImpl()53 virtual ~DataProviderImpl () {};
54 virtual int GetData (uint8_t* pBuf, int nBuf);
GetDataSize(void)55 virtual size_t GetDataSize (void) { return m_data->size(); };
56
57 de::MovePtr<std::vector<deUint8>> m_data;
58 size_t m_used;
59 };
60
DataProviderImpl(de::MovePtr<std::vector<deUint8>> & data)61 DataProviderImpl::DataProviderImpl (de::MovePtr<std::vector<deUint8>>& data)
62 : m_data (data)
63 , m_used (0)
64 {
65 }
66
GetData(uint8_t * pBuf,int nBuf)67 int DataProviderImpl::GetData (uint8_t* pBuf, int nBuf)
68 {
69 if (nBuf <= 0 || pBuf == DE_NULL)
70 return 0;
71
72 const size_t left = m_data->size() - m_used;
73 const size_t requested = static_cast<size_t>(nBuf);
74 const size_t size = requested < left ? requested : left;
75
76 if (size > 0)
77 {
78 const std::vector<deUint8>& data = *m_data;
79
80 deMemcpy(pBuf, &data[m_used], size);
81
82 m_used += size;
83 }
84
85 return static_cast<int>(size);
86 }
87
88 class FfmpegDemuxerImpl : public IfcFfmpegDemuxer
89 {
90 public:
91 FfmpegDemuxerImpl (de::MovePtr<std::vector<deUint8>>& data, FFMpegAPI& api);
~FfmpegDemuxerImpl()92 virtual ~FfmpegDemuxerImpl () {};
93 virtual bool demux (deUint8** pData, deInt64* pSize);
94
95 protected:
96 DataProviderImpl m_dataProvider;
97 de::MovePtr<FFmpegDemuxer> m_FFmpegDemuxer;
98 };
99
FfmpegDemuxerImpl(de::MovePtr<std::vector<deUint8>> & data,FFMpegAPI & api)100 FfmpegDemuxerImpl::FfmpegDemuxerImpl (de::MovePtr<std::vector<deUint8>>& data, FFMpegAPI& api)
101 : m_dataProvider (data)
102 , m_FFmpegDemuxer (new FFmpegDemuxer(&m_dataProvider, &api))
103 {
104 }
105
demux(deUint8 ** pData,deInt64 * pSize)106 bool FfmpegDemuxerImpl::demux (deUint8** pData, deInt64* pSize)
107 {
108 int size = 0;
109 bool result = m_FFmpegDemuxer->Demux((uint8_t**)pData, &size);
110
111 if (pSize != DE_NULL)
112 *pSize = static_cast<deInt64>(size);
113
114 return result;
115 }
116
117 class FfmpegFunctionsImpl : public IfcFfmpegFunctions
118 {
119 public:
120 FfmpegFunctionsImpl ();
121 virtual IfcFfmpegDemuxer* createIfcFfmpegDemuxer (de::MovePtr<std::vector<deUint8>>& data);
122
123 protected:
124 tcu::DynamicFunctionLibrary m_functions_avcodec;
125 tcu::DynamicFunctionLibrary m_functions_avformat;
126 tcu::DynamicFunctionLibrary m_functions_avutil;
127
128 FFMpegAPI m_FFmpegApi;
129 };
130
131 // The following DLLs should be same folder as deqp-vk.exe: avcodec-59.dll avdevice-59.dll avfilter-8.dll avformat-59.dll avutil-57.dll swresample-4.dll swscale-6.dll
FfmpegFunctionsImpl()132 FfmpegFunctionsImpl::FfmpegFunctionsImpl ()
133 : m_functions_avcodec (FFMPEG_AVCODEC_LIBRARY_NAME)
134 , m_functions_avformat (FFMPEG_AVFORMAT_LIBRARY_NAME)
135 , m_functions_avutil (FFMPEG_AVUTIL_LIBRARY_NAME)
136 {
137 m_FFmpegApi =
138 {
139 (pFFMpeg_av_malloc) m_functions_avutil.getFunction("av_malloc"), // pFFMpeg_av_malloc av_malloc;
140 (pFFMpeg_av_freep) m_functions_avutil.getFunction("av_freep"), // pFFMpeg_av_freep av_freep;
141 (pFFMpeg_av_init_packet) m_functions_avcodec.getFunction("av_init_packet"), // pFFMpeg_av_init_packet av_init_packet;
142 (pFFMpeg_av_packet_unref) m_functions_avcodec.getFunction("av_packet_unref"), // pFFMpeg_av_packet_unref av_packet_unref;
143 (pFFMpeg_av_bsf_init) m_functions_avcodec.getFunction("av_bsf_init"), // pFFMpeg_av_bsf_init av_bsf_init;
144 (pFFMpeg_av_bsf_send_packet) m_functions_avcodec.getFunction("av_bsf_send_packet"), // pFFMpeg_av_bsf_send_packet av_bsf_send_packet;
145 (pFFMpeg_av_bsf_receive_packet) m_functions_avcodec.getFunction("av_bsf_receive_packet"), // pFFMpeg_av_bsf_receive_packet av_bsf_receive_packet;
146 (pFFMpeg_av_bsf_get_by_name) m_functions_avcodec.getFunction("av_bsf_get_by_name"), // pFFMpeg_av_bsf_get_by_name av_bsf_get_by_name;
147 (pFFMpeg_av_bsf_alloc) m_functions_avcodec.getFunction("av_bsf_alloc"), // pFFMpeg_av_bsf_alloc av_bsf_alloc;
148 (pFFMpeg_avio_alloc_context) m_functions_avformat.getFunction("avio_alloc_context"), // pFFMpeg_avio_alloc_context avio_alloc_context;
149 (pFFMpeg_av_find_best_stream) m_functions_avformat.getFunction("av_find_best_stream"), // pFFMpeg_av_find_best_stream av_find_best_stream;
150 (pFFMpeg_av_read_frame) m_functions_avformat.getFunction("av_read_frame"), // pFFMpeg_av_read_frame av_read_frame;
151 (pFFMpeg_avformat_alloc_context) m_functions_avformat.getFunction("avformat_alloc_context"), // pFFMpeg_avformat_alloc_context avformat_alloc_context;
152 (pFFMpeg_avformat_network_init) m_functions_avformat.getFunction("avformat_network_init"), // pFFMpeg_avformat_network_init avformat_network_init;
153 (pFFMpeg_avformat_find_stream_info) m_functions_avformat.getFunction("avformat_find_stream_info"), // pFFMpeg_avformat_find_stream_info avformat_find_stream_info;
154 (pFFMpeg_avformat_open_input) m_functions_avformat.getFunction("avformat_open_input"), // pFFMpeg_avformat_open_input avformat_open_input;
155 (pFFMpeg_avformat_close_input) m_functions_avformat.getFunction("avformat_close_input"), // pFFMpeg_avformat_close_input avformat_close_input;
156 };
157
158 for (size_t i = 0; i < sizeof(m_FFmpegApi)/sizeof(void*); i++)
159 {
160 const void* p = (void*)((void**)&m_FFmpegApi)[i];
161
162 DE_ASSERT(p != DE_NULL);
163
164 DE_UNREF(p);
165 }
166 }
167
createIfcFfmpegDemuxer(de::MovePtr<std::vector<deUint8>> & data)168 IfcFfmpegDemuxer* FfmpegFunctionsImpl::createIfcFfmpegDemuxer (de::MovePtr<std::vector<deUint8>>& data)
169 {
170 return new FfmpegDemuxerImpl(data, m_FFmpegApi);
171 }
172
createIfcFfmpegFunctions()173 de::MovePtr<IfcFfmpegFunctions> createIfcFfmpegFunctions ()
174 {
175 return de::MovePtr<IfcFfmpegFunctions>(new FfmpegFunctionsImpl());
176 }
177
178 } // video
179 } // vkt
180