1 /******************************************************************************
2  *
3  * Copyright (C) 2020 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 #ifndef __EXTRACTOR_FUZZER_BASE_H__
22 #define __EXTRACTOR_FUZZER_BASE_H__
23 
24 #include <media/DataSource.h>
25 #include <media/MediaExtractorPluginHelper.h>
26 #include <media/stagefright/MediaBufferGroup.h>
27 #include <vector>
28 
29 extern "C" {
30 android::ExtractorDef GETEXTRACTORDEF();
31 }
32 
33 constexpr int32_t kFuzzerMaxSeekPointsCount = 5;
34 
35 namespace android {
36 
37 class ExtractorFuzzerBase {
38  public:
39   ExtractorFuzzerBase() = default;
~ExtractorFuzzerBase()40   virtual ~ExtractorFuzzerBase() {
41     if (mExtractor) {
42       delete mExtractor;
43       mExtractor = nullptr;
44     }
45     if (mBufferSource) {
46       mBufferSource.clear();
47       mBufferSource = nullptr;
48     }
49   }
50 
51   /** Function to create the media extractor component.
52     * To be implemented by the derived class.
53     */
54   virtual bool createExtractor() = 0;
55 
56   /** Parent class functions to be reused by derived class.
57     * These are common for all media extractor components.
58     */
59   bool setDataSource(const uint8_t* data, size_t size);
60 
61   void getExtractorDef();
62 
63   void extractTracks();
64 
65   void getMetadata();
66 
67   void getTracksMetadata();
68 
69   void setDataSourceFlags(uint32_t flags);
70 
71   void seekAndExtractTracks();
72 
73   void processData(const uint8_t* data, size_t size);
74 
75  protected:
76   class BufferSource : public DataSource {
77    public:
BufferSource(const uint8_t * data,size_t length)78     BufferSource(const uint8_t* data, size_t length) : mData(data), mLength(length) {}
~BufferSource()79     virtual ~BufferSource() { mData = nullptr; }
80 
setFlags(uint32_t flags)81     void setFlags(uint32_t flags) { mFlags = flags; }
82 
flags()83     uint32_t flags() { return mFlags; }
84 
initCheck()85     status_t initCheck() const { return mData != nullptr ? OK : NO_INIT; }
86 
readAt(off64_t offset,void * data,size_t size)87     ssize_t readAt(off64_t offset, void* data, size_t size) {
88       if (!mData) {
89         return NO_INIT;
90       }
91 
92       Mutex::Autolock autoLock(mLock);
93       if ((offset >= static_cast<off64_t>(mLength)) || (offset < 0)) {
94         return 0;  // read beyond bounds.
95       }
96       size_t numAvailable = mLength - static_cast<size_t>(offset);
97       if (size > numAvailable) {
98         size = numAvailable;
99       }
100       return readAt_l(offset, data, size);
101     }
102 
getSize(off64_t * size)103     status_t getSize(off64_t* size) {
104       if (!mData) {
105         return NO_INIT;
106       }
107 
108       Mutex::Autolock autoLock(mLock);
109       *size = static_cast<off64_t>(mLength);
110       return OK;
111     }
112 
113    protected:
readAt_l(off64_t offset,void * data,size_t size)114     ssize_t readAt_l(off64_t offset, void* data, size_t size) {
115       void* result = memcpy(data, mData + offset, size);
116       return result != nullptr ? size : 0;
117     }
118 
119     const uint8_t* mData = nullptr;
120     size_t mLength = 0;
121     Mutex mLock;
122     uint32_t mFlags = 0;
123 
124    private:
125     DISALLOW_EVIL_CONSTRUCTORS(BufferSource);
126   };
127 
128   sp<BufferSource> mBufferSource;
129   DataSource* mDataSource = nullptr;
130   MediaExtractorPluginHelper* mExtractor = nullptr;
131 
132   virtual void extractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup);
133   virtual void seekAndExtractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup,
134                                    int64_t trackDuration);
135 };
136 
137 }  // namespace android
138 
139 #endif  // __EXTRACTOR_FUZZER_BASE_H__
140