• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <sys/stat.h>
19 #include <cstring>
20 #include <iostream>
21 #include <vector>
22 #include <memory>
23 #include <thread>
24 #include "demuxer_plugin_manager.h"
25 #include "stream_demuxer.h"
26 #include "common/media_source.h"
27 #include "plugin/plugin_manager_v2.h"
28 #include "buffer/avbuffer.h"
29 #include "demuxerplugintype_sample.h"
30 
31 using namespace OHOS::Media;
32 using namespace OHOS::Media::Plugins;
33 using namespace OHOS::Media::Plugins::Ffmpeg;
34 
35 namespace OHOS {
36 namespace Media {
37 constexpr uint32_t THREE = 3;
38 DemuxerPluginTypeTest::DemuxerPluginTypeTest() = default;
39 
~DemuxerPluginTypeTest()40 DemuxerPluginTypeTest::~DemuxerPluginTypeTest()
41 {
42     if (fd_ >= 0) {
43         close(fd_);
44     }
45     fd_ = -1;
46     demuxerPlugin_ = nullptr;
47 }
48 
InitWithData(const uint8_t * data,size_t size)49 bool DemuxerPluginTypeTest::InitWithData(const uint8_t* data, size_t size)
50 {
51     if (!data || size == 0) {
52         return false;
53     }
54     fd_ = open(testFilePath_, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
55     if (fd_ < 0) {
56         return false;
57     }
58     ssize_t len = write(fd_, data, size);
59     if (len != static_cast<ssize_t>(size)) {
60         close(fd_);
61         fd_ = -1;
62         return false;
63     }
64     lseek(fd_, 0, SEEK_SET);
65     dataSize_ = size;
66     return true;
67 }
68 
PrepareDemuxerPlugin(MediaInfo & mediaInfo,size_t & bufferSize,AVBufferWrapper & buffer)69 void DemuxerPluginTypeTest::PrepareDemuxerPlugin(MediaInfo& mediaInfo, size_t& bufferSize, AVBufferWrapper& buffer)
70 {
71     std::string uri = "fd://" + std::to_string(fd_) + "?offset=0&size=" + std::to_string(dataSize_);
72     std::shared_ptr<MediaSource> mediaSource = std::make_shared<MediaSource>(uri);
73     std::shared_ptr<StreamDemuxer> streamDemuxer = std::make_shared<StreamDemuxer>();
74     std::shared_ptr<Source> source = std::make_shared<Source>();
75     source->SetSource(mediaSource);
76     streamDemuxer->SetSource(source);
77     streamDemuxer->SetSourceType(mediaSource->GetSourceType());
78     streamDemuxer->Init(uri);
79     streamDemuxer->SetDemuxerState(0, DemuxerState::DEMUXER_STATE_PARSE_FRAME);
80 
81     dataSource = std::make_shared<DataSourceImpl>(streamDemuxer, 0);
82     auto basePlugin = PluginManagerV2::Instance().CreatePluginByName(demuxerPluginName_);
83     demuxerPlugin_ = std::reinterpret_pointer_cast<FFmpegDemuxerPlugin>(basePlugin);
84     if (!demuxerPlugin_) {
85         return;
86     }
87     if (demuxerPlugin_->SetDataSource(dataSource) != Status::OK) {
88         demuxerPlugin_ = nullptr;
89         return;
90     }
91 
92     if (demuxerPlugin_->GetMediaInfo(mediaInfo) != Status::OK) {
93         demuxerPlugin_ = nullptr;
94         return;
95     }
96 
97     int32_t width = videoWidthDefault_;
98     int32_t height = videoHeightDefault_;
99     for (const auto& track : mediaInfo.tracks) {
100         int32_t w = 0;
101         int32_t h = 0;
102         track.GetData(Tag::VIDEO_WIDTH, w);
103         track.GetData(Tag::VIDEO_HEIGHT, h);
104         if (w > 0 && h > 0) {
105             width = w;
106             height = h;
107             break;
108         }
109     }
110     bufferSize = width * height * 3; // 3 bytes per pixel (RGB)
111     buffer = AVBufferWrapper(bufferSize);
112 }
113 
OperateDemuxerPlugin(MediaInfo & mediaInfo,size_t bufferSize,AVBufferWrapper & buffer)114 void DemuxerPluginTypeTest::OperateDemuxerPlugin(MediaInfo& mediaInfo, size_t bufferSize, AVBufferWrapper& buffer)
115 {
116     for (uint32_t idx = 0; idx < mediaInfo.tracks.size(); ++idx) {
117         demuxerPlugin_->SelectTrack(idx);
118     }
119     for (uint32_t idx = 0; idx < mediaInfo.tracks.size(); ++idx) {
120         demuxerPlugin_->UnselectTrack(idx);
121     }
122     for (uint32_t idx = 0; idx < mediaInfo.tracks.size(); ++idx) {
123         demuxerPlugin_->SelectTrack(idx);
124     }
125 
126     for (uint32_t idx = 0; idx < mediaInfo.tracks.size(); ++idx) {
127         demuxerPlugin_->ReadSample(idx, buffer.mediaAVBuffer, interfaceTimeout_);
128         demuxerPlugin_->ReadSample(idx, buffer.mediaAVBuffer);
129         int32_t nextSampleSize = 0;
130         int64_t pts = 0;
131         demuxerPlugin_->GetNextSampleSize(idx, nextSampleSize, interfaceTimeout_);
132         demuxerPlugin_->GetLastPTSByTrackId(idx, pts);
133         demuxerPlugin_->Pause();
134     }
135 
136     int64_t seekTime = 0;
137     demuxerPlugin_->SeekTo(-1, 0, SeekMode::SEEK_NEXT_SYNC, seekTime);
138     demuxerPlugin_->Flush();
139     demuxerPlugin_->SeekTo(0, seekTimeDefault_, SeekMode::SEEK_PREVIOUS_SYNC, seekTime);
140     demuxerPlugin_->Reset();
141 }
142 
DemuxerPlugintask(MediaInfo & mediaInfo,AVBufferWrapper & buffer)143 void DemuxerPluginTypeTest::DemuxerPlugintask(MediaInfo& mediaInfo, AVBufferWrapper& buffer)
144 {
145     for (uint32_t idx = 0; idx < mediaInfo.tracks.size(); ++idx) {
146         demuxerPlugin_->ReadSample(idx, buffer.mediaAVBuffer, interfaceTimeout_);
147     }
148     int64_t seekTime = 0;
149     demuxerPlugin_->SeekTo(0, seekTimeDefault_, SeekMode::SEEK_PREVIOUS_SYNC, seekTime);
150 }
151 
RunDemuxerInterfaceFuzz()152 void DemuxerPluginTypeTest::RunDemuxerInterfaceFuzz()
153 {
154     if (fd_ < 0) {
155         return;
156     }
157     MediaInfo mediaInfo;
158     size_t bufferSize = 0;
159     AVBufferWrapper buffer(1); // 占位初始化
160     PrepareDemuxerPlugin(mediaInfo, bufferSize, buffer);
161     if (!demuxerPlugin_) {
162         return;
163     }
164     OperateDemuxerPlugin(mediaInfo, bufferSize, buffer);
165     if (demuxerPlugin_->SetDataSource(dataSource) != Status::OK) {
166         demuxerPlugin_ = nullptr;
167         return;
168     }
169     for (uint32_t idx = 0; idx < mediaInfo.tracks.size(); ++idx) {
170         demuxerPlugin_->SelectTrack(idx);
171     }
172     std::thread readPluginThread1([mediaInfo, this]() {
173         MediaInfo Info = mediaInfo;
174         AVBufferWrapper buf(videoWidthDefault_ * videoHeightDefault_ * THREE);
175         DemuxerPlugintask(Info, buf);
176     });
177     std::thread readPluginThread2([mediaInfo, this]() {
178         MediaInfo Info1 = mediaInfo;
179         AVBufferWrapper buf1(videoWidthDefault_ * videoHeightDefault_ * THREE);
180         DemuxerPlugintask(Info1, buf1);
181     });
182     readPluginThread1.join();
183     readPluginThread2.join();
184     for (uint32_t idx = 0; idx < mediaInfo.tracks.size(); ++idx) {
185         demuxerPlugin_->UnselectTrack(idx);
186     }
187 }
188 
189 } // namespace Media
190 } // namespace OHOS