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 #include "../includes/common.h"
17 #include <stdlib.h>
18 
19 // This PoC is only for 64-bit builds
20 #if _64_BIT
21 #include <android/IMediaExtractor.h>
22 #include <datasource/FileSource.h>
23 #include <dlfcn.h>
24 #include <media/DataSource.h>
25 #include <media/MediaTrack.h>
26 #include <media/stagefright/MediaExtractor.h>
27 #include <media/stagefright/MetaData.h>
28 #define LIBNAME "/system/lib64/extractors/libmp4extractor.so"
29 #define LIBNAME_APEX                                                           \
30   "/apex/com.android.media/lib64/extractors/libmp4extractor.so"
31 #define CONVERSION_FACTOR_SEC_TO_MICROSEC 1000000
32 
33 using namespace android;
34 #endif /* _64_BIT */
35 
main(int argc,char ** argv)36 int main(int argc, char **argv) {
37   (void)argc;
38   (void)argv;
39 
40 // This PoC is only for 64-bit builds
41 #if _64_BIT
42   if (argc < 2) {
43     return EXIT_FAILURE;
44   }
45 
46   void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
47   if (!libHandle) {
48     libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
49     if (!libHandle) {
50       return EXIT_FAILURE;
51     }
52   }
53 
54   GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
55   if (!getDef) {
56     dlclose(libHandle);
57     return EXIT_FAILURE;
58   }
59 
60   sp<DataSource> dataSource = new FileSource(argv[1]);
61   if (!dataSource) {
62     dlclose(libHandle);
63     return EXIT_FAILURE;
64   }
65 
66   void *meta = nullptr;
67   void *creator = nullptr;
68   FreeMetaFunc freeMeta = nullptr;
69   float confidence = 0.0f;
70   if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
71     creator = (void *)getDef().u.v2.sniff(dataSource->wrap(), &confidence,
72                                           &meta, &freeMeta);
73   } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
74     creator = (void *)getDef().u.v3.sniff(dataSource->wrap(), &confidence,
75                                           &meta, &freeMeta);
76   }
77   if (!creator) {
78     dlclose(libHandle);
79     return EXIT_FAILURE;
80   }
81 
82   CMediaExtractor *mp4Extractor =
83       ((CreatorFunc)creator)(dataSource->wrap(), meta);
84   if (!mp4Extractor) {
85     dlclose(libHandle);
86     return EXIT_FAILURE;
87   }
88 
89   if (meta != nullptr && freeMeta != nullptr) {
90     freeMeta(meta);
91   }
92 
93   MediaExtractorCUnwrapper *mediaExtractorCUnwrapper =
94       new MediaExtractorCUnwrapper(mp4Extractor);
95   if (!mediaExtractorCUnwrapper) {
96     dlclose(libHandle);
97     return EXIT_FAILURE;
98   }
99 
100   // seek to 10 seconds in the mp4 file
101   int64_t seekTimeUs = 10 * CONVERSION_FACTOR_SEC_TO_MICROSEC;
102   size_t numTracks = mediaExtractorCUnwrapper->countTracks();
103   for (size_t i = 0; i < numTracks; ++i) {
104     MetaDataBase metaData;
105     MediaTrack *mediaTrack = mediaExtractorCUnwrapper->getTrack(i);
106     mediaExtractorCUnwrapper->getTrackMetaData(
107         metaData, i, MediaExtractor::kIncludeExtensiveMetaData);
108     MediaTrack::ReadOptions options;
109     if (seekTimeUs >= 0) {
110       options.setSeekTo(seekTimeUs,
111                         MediaTrack::ReadOptions::SEEK_PREVIOUS_SYNC);
112     }
113     if (mediaTrack) {
114       MediaBufferBase *mbuf = nullptr;
115       mediaTrack->start();
116       mediaTrack->read(&mbuf, &options);
117     }
118   }
119 #endif /* _64_BIT */
120   return EXIT_SUCCESS;
121 }
122