RemoteMediaExtractor.cpp revision 3d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0
1/*
2 * Copyright 2017, 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//#define LOG_NDEBUG 0
18#define LOG_TAG "RemoteMediaExtractor"
19#include <utils/Log.h>
20
21#include <media/stagefright/InterfaceUtils.h>
22#include <media/MediaAnalyticsItem.h>
23#include <media/MediaSource.h>
24#include <media/stagefright/RemoteMediaExtractor.h>
25
26// still doing some on/off toggling here.
27#define MEDIA_LOG       1
28
29namespace android {
30
31// key for media statistics
32static const char *kKeyExtractor = "extractor";
33
34// attrs for media statistics
35// NB: these are matched with public Java API constants defined
36// in frameworks/base/media/java/android/media/MediaExtractor.java
37// These must be kept synchronized with the constants there.
38static const char *kExtractorFormat = "android.media.mediaextractor.fmt";
39static const char *kExtractorMime = "android.media.mediaextractor.mime";
40static const char *kExtractorTracks = "android.media.mediaextractor.ntrk";
41
42RemoteMediaExtractor::RemoteMediaExtractor(
43        MediaExtractor *extractor,
44        const sp<DataSource> &source,
45        const sp<RefBase> &plugin)
46    :mExtractor(extractor),
47     mSource(source),
48     mExtractorPlugin(plugin) {
49
50    mAnalyticsItem = nullptr;
51    if (MEDIA_LOG) {
52        mAnalyticsItem = new MediaAnalyticsItem(kKeyExtractor);
53
54        // track the container format (mpeg, aac, wvm, etc)
55        size_t ntracks = extractor->countTracks();
56        mAnalyticsItem->setCString(kExtractorFormat, extractor->name());
57        // tracks (size_t)
58        mAnalyticsItem->setInt32(kExtractorTracks, ntracks);
59        // metadata
60        MetaDataBase pMetaData;
61        if (extractor->getMetaData(pMetaData) == OK) {
62            String8 xx = pMetaData.toString();
63            // 'titl' -- but this verges into PII
64            // 'mime'
65            const char *mime = nullptr;
66            if (pMetaData.findCString(kKeyMIMEType, &mime)) {
67                mAnalyticsItem->setCString(kExtractorMime,  mime);
68            }
69            // what else is interesting and not already available?
70        }
71    }
72}
73
74RemoteMediaExtractor::~RemoteMediaExtractor() {
75    delete mExtractor;
76    mSource->close();
77    mSource.clear();
78    mExtractorPlugin = nullptr;
79    // log the current record, provided it has some information worth recording
80    if (MEDIA_LOG) {
81        if (mAnalyticsItem != nullptr) {
82            if (mAnalyticsItem->count() > 0) {
83                mAnalyticsItem->selfrecord();
84            }
85        }
86    }
87    if (mAnalyticsItem != nullptr) {
88        delete mAnalyticsItem;
89        mAnalyticsItem = nullptr;
90    }
91}
92
93size_t RemoteMediaExtractor::countTracks() {
94    return mExtractor->countTracks();
95}
96
97sp<IMediaSource> RemoteMediaExtractor::getTrack(size_t index) {
98    MediaTrack *source = mExtractor->getTrack(index);
99    return (source == nullptr)
100            ? nullptr : CreateIMediaSourceFromMediaSourceBase(this, source, mExtractorPlugin);
101}
102
103sp<MetaData> RemoteMediaExtractor::getTrackMetaData(size_t index, uint32_t flags) {
104    sp<MetaData> meta = new MetaData();
105    if (mExtractor->getTrackMetaData(*meta.get(), index, flags) == OK) {
106        return meta;
107    }
108    return nullptr;
109}
110
111sp<MetaData> RemoteMediaExtractor::getMetaData() {
112    sp<MetaData> meta = new MetaData();
113    if (mExtractor->getMetaData(*meta.get()) == OK) {
114        return meta;
115    }
116    return nullptr;
117}
118
119status_t RemoteMediaExtractor::getMetrics(Parcel *reply) {
120    if (mAnalyticsItem == nullptr || reply == nullptr) {
121        return UNKNOWN_ERROR;
122    }
123
124    mAnalyticsItem->writeToParcel(reply);
125    return OK;
126}
127
128uint32_t RemoteMediaExtractor::flags() const {
129    return mExtractor->flags();
130}
131
132status_t RemoteMediaExtractor::setMediaCas(const HInterfaceToken &casToken) {
133    return mExtractor->setMediaCas((uint8_t*)casToken.data(), casToken.size());
134}
135
136const char * RemoteMediaExtractor::name() {
137    return mExtractor->name();
138}
139
140////////////////////////////////////////////////////////////////////////////////
141
142// static
143sp<IMediaExtractor> RemoteMediaExtractor::wrap(
144        MediaExtractor *extractor,
145        const sp<DataSource> &source,
146        const sp<RefBase> &plugin) {
147    if (extractor == nullptr) {
148        return nullptr;
149    }
150    return new RemoteMediaExtractor(extractor, source, plugin);
151}
152
153}  // namespace android
154