DataSource.cpp revision 3de157dd8f9cd45bf9b0406268f5830887105ae1
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
163de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang//#define LOG_NDEBUG 0
173de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang#define LOG_TAG "DataSource"
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1966326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/AMRExtractor.h"
206c83e3be2921009ff7dcfced2a3eda7811b8b041Narayan Kamath
2156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include "include/AACExtractor.h"
2256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include "include/DRMExtractor.h"
2356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include "include/FLACExtractor.h"
2456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include "include/HTTPBase.h"
2566326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MP3Extractor.h"
262944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber#include "include/MPEG2PSExtractor.h"
27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "include/MPEG2TSExtractor.h"
2856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include "include/MPEG4Extractor.h"
290a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#include "include/NuCachedSource2.h"
3056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include "include/OggExtractor.h"
3156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include "include/WAVExtractor.h"
329d2f386dd2885eaffa11fd494ae258bb09fe6397James Dong#include "include/WVMExtractor.h"
3366326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber
34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "matroska/MatroskaExtractor.h"
35093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
361b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPConnection.h>
371b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h>
383de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang#include <media/stagefright/foundation/ADebug.h>
395a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber#include <media/stagefright/foundation/AMessage.h>
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h>
414bbfff2dbf3968c267c3b2ea9f8912a38372a9daAndreas Huber#include <media/stagefright/DataURISource.h>
42fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <media/stagefright/FileSource.h>
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaErrors.h>
441b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/MediaHTTP.h>
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h>
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47a89082944308805b0def7de87c67e370e74b8789Gloria Wang#include <cutils/properties.h>
48a89082944308805b0def7de87c67e370e74b8789Gloria Wang
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
51c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongbool DataSource::getUInt16(off64_t offset, uint16_t *x) {
52693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *x = 0;
53693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
54693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    uint8_t byte[2];
5534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (readAt(offset, byte, 2) != 2) {
56693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return false;
57693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
58693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    *x = (byte[0] << 8) | byte[1];
60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return true;
62693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
63693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
64ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissenbool DataSource::getUInt24(off64_t offset, uint32_t *x) {
65ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    *x = 0;
66ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
67ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint8_t byte[3];
68ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (readAt(offset, byte, 3) != 3) {
69ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return false;
70ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
71ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
72ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
73ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
74ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    return true;
75ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen}
76ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
7705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenbool DataSource::getUInt32(off64_t offset, uint32_t *x) {
7805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    *x = 0;
7905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
8005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint32_t tmp;
8105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (readAt(offset, &tmp, 4) != 4) {
8205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return false;
8305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
8405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
8505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    *x = ntohl(tmp);
8605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
8705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return true;
8805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
8905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
9005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissenbool DataSource::getUInt64(off64_t offset, uint64_t *x) {
9105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    *x = 0;
9205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
9305f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    uint64_t tmp;
9405f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    if (readAt(offset, &tmp, 8) != 8) {
9505f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen        return false;
9605f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    }
9705f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
9805f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    *x = ntoh64(tmp);
9905f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
10005f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen    return true;
10105f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen}
10205f625c46b992ab66b8d1527a366fe2746b4e3c7Marco Nelissen
103c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t DataSource::getSize(off64_t *size) {
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *size = 0;
10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ERROR_UNSUPPORTED;
10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber////////////////////////////////////////////////////////////////////////////////
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMutex DataSource::gSnifferMutex;
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberList<DataSource::SnifferFunc> DataSource::gSniffers;
113377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissenbool DataSource::gSniffersRegistered = false;
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1155a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huberbool DataSource::sniff(
1165a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        String8 *mimeType, float *confidence, sp<AMessage> *meta) {
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *mimeType = "";
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *confidence = 0.0f;
1195a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber    meta->clear();
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
121377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    {
122377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen        Mutex::Autolock autoLock(gSnifferMutex);
123377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen        if (!gSniffersRegistered) {
124377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen            return false;
125377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen        }
126377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    }
127377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (List<SnifferFunc>::iterator it = gSniffers.begin();
12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber         it != gSniffers.end(); ++it) {
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        String8 newMimeType;
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        float newConfidence;
1325a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> newMeta;
1335a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        if ((*it)(this, &newMimeType, &newConfidence, &newMeta)) {
13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (newConfidence > *confidence) {
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                *mimeType = newMimeType;
13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                *confidence = newConfidence;
1375a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber                *meta = newMeta;
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return *confidence > 0.0;
14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
146377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissenvoid DataSource::RegisterSniffer_l(SnifferFunc func) {
14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (List<SnifferFunc>::iterator it = gSniffers.begin();
14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber         it != gSniffers.end(); ++it) {
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (*it == func) {
15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return;
15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    gSniffers.push_back(func);
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid DataSource::RegisterDefaultSniffers() {
159377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    Mutex::Autolock autoLock(gSnifferMutex);
160377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    if (gSniffersRegistered) {
161377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen        return;
162377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    }
163377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen
164377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffMPEG4);
165377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffMatroska);
166377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffOgg);
167377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffWAV);
168377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffFLAC);
169377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffAMR);
170377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffMPEG2TS);
171377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffMP3);
172377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffAAC);
173377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffMPEG2PS);
174377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    RegisterSniffer_l(SniffWVM);
175a89082944308805b0def7de87c67e370e74b8789Gloria Wang
176a89082944308805b0def7de87c67e370e74b8789Gloria Wang    char value[PROPERTY_VALUE_MAX];
177a89082944308805b0def7de87c67e370e74b8789Gloria Wang    if (property_get("drm.service.enabled", value, NULL)
178a89082944308805b0def7de87c67e370e74b8789Gloria Wang            && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
179377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen        RegisterSniffer_l(SniffDRM);
180a89082944308805b0def7de87c67e370e74b8789Gloria Wang    }
181377fce69297a0e5b7c3b266a7602b17146785635Marco Nelissen    gSniffersRegistered = true;
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
184fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber// static
1855561ccf4a8db88a2e44eac1b3ed13b4ff53a7f20Andreas Hubersp<DataSource> DataSource::CreateFromURI(
1861b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const sp<IMediaHTTPService> &httpService,
1871b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const char *uri,
1883de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        const KeyedVector<String8, String8> *headers,
1893de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        AString *sniffedMIME) {
1903de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    if (sniffedMIME != NULL) {
1913de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        *sniffedMIME = "";
1923de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    }
1933de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
1941608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    bool isWidevine = !strncasecmp("widevine://", uri, 11);
1951608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
196fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    sp<DataSource> source;
197fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (!strncasecmp("file://", uri, 7)) {
198fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        source = new FileSource(uri + 7);
1998cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber    } else if (!strncasecmp("http://", uri, 7)
2001608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            || !strncasecmp("https://", uri, 8)
2011608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            || isWidevine) {
2021b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        sp<HTTPBase> httpSource = new MediaHTTP(httpService->makeHTTPConnection());
2031608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
2041608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        String8 tmp;
2051608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        if (isWidevine) {
2061608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            tmp = String8("http://");
2071608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            tmp.append(uri + 11);
2081608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
2091608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            uri = tmp.string();
2101608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        }
2111608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
21279f77ef3b0a37660ba8c5bcb2dfbfda3860f2135Andreas Huber        if (httpSource->connect(uri, headers) != OK) {
2133de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            ALOGE("Failed to connect http source!");
214e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            return NULL;
215e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        }
216918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
2171608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        if (!isWidevine) {
2181608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            String8 cacheConfig;
2191608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            bool disconnectAtHighwatermark;
2201608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            if (headers != NULL) {
2211608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                KeyedVector<String8, String8> copy = *headers;
2221608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                NuCachedSource2::RemoveCacheSpecificHeaders(
2231608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                        &copy, &cacheConfig, &disconnectAtHighwatermark);
2241608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            }
225918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
2263de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            sp<NuCachedSource2> cachedSource = new NuCachedSource2(
2271608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                    httpSource,
2281608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                    cacheConfig.isEmpty() ? NULL : cacheConfig.string());
2293de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2303de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            String8 contentType = httpSource->getMIMEType();
2313de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2323de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            if (strncasecmp(contentType.string(), "audio/", 6)) {
2333de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // We're not doing this for streams that appear to be audio-only
2343de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // streams to ensure that even low bandwidth streams start
2353de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // playing back fairly instantly.
2363de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2373de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // We're going to prefill the cache before trying to instantiate
2383de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // the extractor below, as the latter is an operation that otherwise
2393de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // could block on the datasource for a significant amount of time.
2403de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // During that time we'd be unable to abort the preparation phase
2413de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // without this prefill.
2423de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2433de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // Initially make sure we have at least 192 KB for the sniff
2443de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                // to complete without blocking.
2453de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                static const size_t kMinBytesForSniffing = 192 * 1024;
2463de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2473de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                off64_t metaDataSize = -1ll;
2483de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                for (;;) {
2493de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    status_t finalStatus;
2503de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    size_t cachedDataRemaining =
2513de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                            cachedSource->approxDataRemaining(&finalStatus);
2523de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2533de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    if (finalStatus != OK || (metaDataSize >= 0
2543de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                            && (off64_t)cachedDataRemaining >= metaDataSize)) {
2553de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        ALOGV("stop caching, status %d, "
2563de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                                "metaDataSize %lld, cachedDataRemaining %zu",
2573de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                                finalStatus, metaDataSize, cachedDataRemaining);
2583de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        break;
2593de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    }
2603de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2613de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    ALOGV("now cached %zu bytes of data", cachedDataRemaining);
2623de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2633de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    if (metaDataSize < 0
2643de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                            && cachedDataRemaining >= kMinBytesForSniffing) {
2653de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        String8 tmp;
2663de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        float confidence;
2673de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        sp<AMessage> meta;
2683de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        if (!cachedSource->sniff(&tmp, &confidence, &meta)) {
2693de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                            return NULL;
2703de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        }
2713de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2723de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        // We successfully identified the file's extractor to
2733de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        // be, remember this mime type so we don't have to
2743de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        // sniff it again when we call MediaExtractor::Create()
2753de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        if (sniffedMIME != NULL) {
2763de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                            *sniffedMIME = tmp.string();
2773de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        }
2783de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2793de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        if (meta == NULL
2803de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                                || !meta->findInt64("meta-data-size",
2813de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                                     reinterpret_cast<int64_t*>(&metaDataSize))) {
2823de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                            metaDataSize = kDefaultMetaSize;
2833de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        }
2843de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2853de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        if (metaDataSize < 0ll) {
2863de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                            ALOGE("invalid metaDataSize = %lld bytes", metaDataSize);
2873de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                            return NULL;
2883de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        }
2893de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    }
2903de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2913de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    usleep(200000);
2923de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                }
2933de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            }
2943de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2953de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            source = cachedSource;
2961608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        } else {
2971608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            // We do not want that prefetching, caching, datasource wrapper
2981608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            // in the widevine:// case.
2991608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            source = httpSource;
3001608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        }
3014bbfff2dbf3968c267c3b2ea9f8912a38372a9daAndreas Huber    } else if (!strncasecmp("data:", uri, 5)) {
3024bbfff2dbf3968c267c3b2ea9f8912a38372a9daAndreas Huber        source = DataURISource::Create(uri);
303fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    } else {
304fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        // Assume it's a filename.
305fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        source = new FileSource(uri);
306fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
307fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
308fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    if (source == NULL || source->initCheck() != OK) {
309fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        return NULL;
310fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    }
311fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
312fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber    return source;
313fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber}
314fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
3156511c9755c3a3360ba869772600c7aae048a7ffcAndreas HuberString8 DataSource::getMIMEType() const {
3166511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber    return String8("application/octet-stream");
3176511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber}
3186511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
320