• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 __WRITER_FUZZER_BASE_H__
22 #define __WRITER_FUZZER_BASE_H__
23 
24 #include <media/stagefright/MediaAdapter.h>
25 #include <media/stagefright/MediaWriter.h>
26 #include <media/stagefright/MetaData.h>
27 #include <media/stagefright/Utils.h>
28 #include <media/stagefright/foundation/ABuffer.h>
29 #include <media/stagefright/foundation/AMessage.h>
30 #include <algorithm>
31 #include <cstring>
32 #include <vector>
33 
34 using namespace std;
35 
36 constexpr uint32_t kMimeSize = 128;
37 constexpr uint8_t kMaxTrackCount = 3;
38 constexpr uint32_t kMaxCSDStrlen = 16;
39 constexpr uint32_t kCodecConfigFlag = 32;
40 
41 namespace android {
42 
43 struct ConfigFormat {
44     char* mime;
45     int32_t width;
46     int32_t height;
47     int32_t sampleRate;
48     int32_t channelCount;
49 };
50 
51 struct FrameData {
52     size_t size;
53     uint8_t flags;
54     int64_t timeUs;
55     const uint8_t* buf;
56 };
57 
58 static string supportedMimeTypes[] = {"audio/3gpp",
59                                       "audio/amr-wb",
60                                       "audio/vorbis",
61                                       "audio/opus",
62                                       "audio/mp4a-latm",
63                                       "audio/mpeg",
64                                       "audio/mpeg-L1",
65                                       "audio/mpeg-L2",
66                                       "audio/midi",
67                                       "audio/qcelp",
68                                       "audio/g711-alaw",
69                                       "audio/g711-mlaw",
70                                       "audio/flac",
71                                       "audio/aac-adts",
72                                       "audio/gsm",
73                                       "audio/ac3",
74                                       "audio/eac3",
75                                       "audio/eac3-joc",
76                                       "audio/ac4",
77                                       "audio/scrambled",
78                                       "audio/alac",
79                                       "audio/x-ms-wma",
80                                       "audio/x-adpcm-ms",
81                                       "audio/x-adpcm-dvi-ima",
82                                       "video/avc",
83                                       "video/hevc",
84                                       "video/mp4v-es",
85                                       "video/3gpp",
86                                       "video/x-vnd.on2.vp8",
87                                       "video/x-vnd.on2.vp9",
88                                       "video/av01",
89                                       "video/mpeg2",
90                                       "video/dolby-vision",
91                                       "video/scrambled",
92                                       "video/divx",
93                                       "video/divx3",
94                                       "video/xvid",
95                                       "video/x-motion-jpeg",
96                                       "text/3gpp-tt",
97                                       "application/x-subrip",
98                                       "text/vtt",
99                                       "text/cea-608",
100                                       "text/cea-708",
101                                       "application/x-id3v4"};
102 
103 enum SampleFlag {
104     DEFAULT_FLAG = 0,
105     SYNC_FLAG = 1,
106     ENCRYPTED_FLAG = 2,
107 };
108 
109 static uint8_t flagTypes[] = {SampleFlag::DEFAULT_FLAG, SampleFlag::SYNC_FLAG,
110                               SampleFlag::ENCRYPTED_FLAG};
111 
112 class WriterFuzzerBase {
113    public:
114     WriterFuzzerBase() = default;
~WriterFuzzerBase()115     virtual ~WriterFuzzerBase() {
116         if (mFileMeta) {
117             mFileMeta.clear();
118             mFileMeta = nullptr;
119         }
120         if (mWriter) {
121             mWriter.clear();
122             mWriter = nullptr;
123         }
124         for (int32_t idx = 0; idx < kMaxTrackCount; ++idx) {
125             if (mCurrentTrack[idx]) {
126                 mCurrentTrack[idx]->stop();
127                 mCurrentTrack[idx].clear();
128                 mCurrentTrack[idx] = nullptr;
129             }
130         }
131         close(mFd);
132     };
133 
134     /** Function to create the media writer component.
135      * To be implemented by the derived class.
136      */
137     virtual bool createWriter() = 0;
138 
139     /** Parent class functions to be reused by derived class.
140      * These are common for all media writer components.
141      */
142     bool createOutputFile();
143 
144     void addWriterSource(int32_t trackIndex);
145 
146     void start();
147 
148     void sendBuffersToWriter(sp<MediaAdapter>& currentTrack, int32_t trackIndex,
149                              int32_t startFrameIndex, int32_t endFrameIndex);
150 
151     void sendBuffersInterleave(int32_t numTracks, uint8_t numBuffersInterleave);
152 
153     void initFileWriterAndProcessData(const uint8_t* data, size_t size);
154 
155    protected:
156     class BufferSource {
157        public:
BufferSource(const uint8_t * data,size_t size)158         BufferSource(const uint8_t* data, size_t size) : mData(data), mSize(size), mReadIndex(0) {}
~BufferSource()159         ~BufferSource() {
160             mData = nullptr;
161             mSize = 0;
162             mReadIndex = 0;
163             for (int32_t idx = 0; idx < kMaxTrackCount; ++idx) {
164                 mFrameList[idx].clear();
165             }
166         }
167         uint32_t getNumTracks();
168         bool getTrackInfo(int32_t trackIndex);
169         void getFrameInfo();
170         ConfigFormat getConfigFormat(int32_t trackIndex);
171         int32_t getNumCsds(int32_t trackIndex);
172         vector<FrameData>& getFrameList(int32_t trackIndex);
173 
174        private:
isMarker()175         bool isMarker() { return (memcmp(&mData[mReadIndex], kMarker, kMarkerSize) == 0); }
176 
isCSDMarker(size_t position)177         bool isCSDMarker(size_t position) {
178             return (memcmp(&mData[position], kCsdMarkerSuffix, kMarkerSuffixSize) == 0);
179         }
180 
181         bool searchForMarker(size_t startIndex);
182 
183         const uint8_t* mData = nullptr;
184         size_t mSize = 0;
185         size_t mReadIndex = 0;
186         ConfigFormat mParams[kMaxTrackCount] = {};
187         int32_t mNumCsds[kMaxTrackCount] = {0};
188         vector<FrameData> mFrameList[kMaxTrackCount];
189 
190         static constexpr int kSupportedMimeTypes = size(supportedMimeTypes);
191         static constexpr uint8_t kMarker[] = "_MARK";
192         static constexpr uint8_t kCsdMarkerSuffix[] = "_H_";
193         static constexpr uint8_t kFrameMarkerSuffix[] = "_F_";
194         // All markers should be 5 bytes long ( sizeof '_MARK' which is 5)
195         static constexpr size_t kMarkerSize = (sizeof(kMarker) - 1);
196         // All marker types should be 3 bytes long ('_H_', '_F_')
197         static constexpr size_t kMarkerSuffixSize = 3;
198     };
199 
200     BufferSource* mBufferSource = nullptr;
201     int32_t mFd = -1;
202     uint32_t mNumTracks = 0;
203     string mOutputFileName = "writer.out";
204     sp<MediaWriter> mWriter = nullptr;
205     sp<MetaData> mFileMeta = nullptr;
206     sp<MediaAdapter> mCurrentTrack[kMaxTrackCount] = {};
207 };
208 
209 }  // namespace android
210 
211 #endif  // __WRITER_FUZZER_BASE_H__
212