1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef IMEDIASOURCEFUZZIMPL_H
18 #define IMEDIASOURCEFUZZIMPL_H
19
20 #include <media/stagefright/MediaSource.h>
21
22 #define MAX_FRAMES 5
23
24 namespace android {
25
26 class IMediaSourceFuzzImpl : public IMediaSource {
27 public:
IMediaSourceFuzzImpl(FuzzedDataProvider * _fdp,size_t _max_buffer_size)28 IMediaSourceFuzzImpl(FuzzedDataProvider* _fdp, size_t _max_buffer_size)
29 : frames_read(0), fdp(_fdp), min_buffer_size(32 * 32), max_buffer_size(_max_buffer_size) {}
start(MetaData *)30 status_t start(MetaData*) override { return 0; }
stop()31 status_t stop() override { return 0; }
getFormat()32 sp<MetaData> getFormat() override { return nullptr; }
33 status_t read(MediaBufferBase**, const MediaSource::ReadOptions*) override;
34 status_t readMultiple(Vector<MediaBufferBase*>*, uint32_t,
35 const MediaSource::ReadOptions*) override;
supportReadMultiple()36 bool supportReadMultiple() override { return true; }
supportNonblockingRead()37 bool supportNonblockingRead() override { return true; }
pause()38 status_t pause() override { return 0; }
39
40 protected:
onAsBinder()41 IBinder* onAsBinder() { return nullptr; }
42
43 private:
44 uint8_t frames_read;
45 FuzzedDataProvider* fdp;
46 const size_t min_buffer_size;
47 const size_t max_buffer_size;
48 std::vector<uint8_t> buf;
49 };
50
51 // This class is simply to expose the destructor
52 class MediaBufferFuzzImpl : public MediaBuffer {
53 public:
MediaBufferFuzzImpl(void * data,size_t size)54 MediaBufferFuzzImpl(void *data, size_t size) : MediaBuffer(data, size) {}
~MediaBufferFuzzImpl()55 ~MediaBufferFuzzImpl() {}
56 };
57
read(MediaBufferBase ** buffer,const MediaSource::ReadOptions *)58 status_t IMediaSourceFuzzImpl::read(MediaBufferBase** buffer, const MediaSource::ReadOptions*) {
59 Vector<MediaBufferBase*> buffers;
60 status_t ret = readMultiple(&buffers, 1, nullptr);
61 *buffer = buffers.empty() ? nullptr : buffers[0];
62
63 return ret;
64 }
65
readMultiple(Vector<MediaBufferBase * > * buffers,uint32_t,const MediaSource::ReadOptions *)66 status_t IMediaSourceFuzzImpl::readMultiple(Vector<MediaBufferBase*>* buffers, uint32_t,
67 const MediaSource::ReadOptions*) {
68 if (++frames_read == MAX_FRAMES) {
69 auto size = fdp->ConsumeIntegralInRange<size_t>(min_buffer_size, max_buffer_size);
70 buf = fdp->ConsumeBytes<uint8_t>(size);
71 if (buf.size() < size) {
72 buf.resize(size, 0);
73 }
74
75 MediaBufferBase* mbb = new MediaBufferFuzzImpl(buf.data(), buf.size());
76 mbb->meta_data().setInt64(kKeyTime, fdp->ConsumeIntegral<uint64_t>());
77 buffers->push_back(mbb);
78
79 return ERROR_END_OF_STREAM;
80 }
81
82 auto size = fdp->ConsumeIntegralInRange<size_t>(min_buffer_size, max_buffer_size);
83 buf = fdp->ConsumeBytes<uint8_t>(size);
84 if (buf.size() < size) {
85 buf.resize(size, 0);
86 }
87
88 MediaBufferBase* mbb = new MediaBufferFuzzImpl(buf.data(), buf.size());
89 mbb->meta_data().setInt64(kKeyTime, fdp->ConsumeIntegral<uint64_t>());
90 buffers->push_back(mbb);
91
92 return OK;
93 }
94
95 } // namespace android
96
97 #endif // IMEDIASOURCEFUZZIMPL_H
98
99