DataSource.cpp revision dcd25efb46c41c8d24a0a9cf61fb57f84149709e
1/*
2 * Copyright (C) 2009 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#include "include/AMRExtractor.h"
18#include "include/MP3Extractor.h"
19#include "include/MPEG4Extractor.h"
20#include "include/WAVExtractor.h"
21#include "include/OggExtractor.h"
22#include "include/DRMExtractor.h"
23
24#include <media/stagefright/CachingDataSource.h>
25#include <media/stagefright/DataSource.h>
26#include <media/stagefright/FileSource.h>
27#include <media/stagefright/HTTPDataSource.h>
28#include <media/stagefright/MediaErrors.h>
29#include <utils/String8.h>
30
31namespace android {
32
33bool DataSource::getUInt16(off_t offset, uint16_t *x) {
34    *x = 0;
35
36    uint8_t byte[2];
37    if (readAt(offset, byte, 2) != 2) {
38        return false;
39    }
40
41    *x = (byte[0] << 8) | byte[1];
42
43    return true;
44}
45
46status_t DataSource::getSize(off_t *size) {
47    *size = 0;
48
49    return ERROR_UNSUPPORTED;
50}
51
52////////////////////////////////////////////////////////////////////////////////
53
54Mutex DataSource::gSnifferMutex;
55List<DataSource::SnifferFunc> DataSource::gSniffers;
56
57bool DataSource::sniff(String8 *mimeType, float *confidence) {
58    *mimeType = "";
59    *confidence = 0.0f;
60
61    Mutex::Autolock autoLock(gSnifferMutex);
62    for (List<SnifferFunc>::iterator it = gSniffers.begin();
63         it != gSniffers.end(); ++it) {
64        String8 newMimeType;
65        float newConfidence;
66        if ((*it)(this, &newMimeType, &newConfidence)) {
67            if (newConfidence > *confidence) {
68                *mimeType = newMimeType;
69                *confidence = newConfidence;
70            }
71        }
72    }
73
74    return *confidence > 0.0;
75}
76
77// static
78void DataSource::RegisterSniffer(SnifferFunc func) {
79    Mutex::Autolock autoLock(gSnifferMutex);
80
81    for (List<SnifferFunc>::iterator it = gSniffers.begin();
82         it != gSniffers.end(); ++it) {
83        if (*it == func) {
84            return;
85        }
86    }
87
88    gSniffers.push_back(func);
89}
90
91// static
92void DataSource::RegisterDefaultSniffers() {
93    RegisterSniffer(SniffMP3);
94    RegisterSniffer(SniffMPEG4);
95    RegisterSniffer(SniffAMR);
96    RegisterSniffer(SniffWAV);
97    RegisterSniffer(SniffOgg);
98    RegisterSniffer(SniffDRM);
99}
100
101// static
102sp<DataSource> DataSource::CreateFromURI(
103        const char *uri, const KeyedVector<String8, String8> *headers) {
104    sp<DataSource> source;
105    if (!strncasecmp("file://", uri, 7)) {
106        source = new FileSource(uri + 7);
107    } else if (!strncasecmp("http://", uri, 7)) {
108        sp<HTTPDataSource> httpSource = new HTTPDataSource(uri, headers);
109        if (httpSource->connect() != OK) {
110            return NULL;
111        }
112        source = new CachingDataSource(httpSource, 64 * 1024, 10);
113    } else {
114        // Assume it's a filename.
115        source = new FileSource(uri);
116    }
117
118    if (source == NULL || source->initCheck() != OK) {
119        return NULL;
120    }
121
122    return source;
123}
124
125}  // namespace android
126