ASessionDescription.cpp revision 39ddf8e0f18766f7ba1e3246b774aa6ebd93eea8
1cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/*
2cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
4cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * you may not use this file except in compliance with the License.
6cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * You may obtain a copy of the License at
7cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
8cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
10cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * See the License for the specific language governing permissions and
14cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * limitations under the License.
15cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */
16cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
17cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h"
18cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
19cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
20cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h>
21cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <stdlib.h>
23cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberASessionDescription::ASessionDescription()
27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    : mIsValid(false) {
28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberASessionDescription::~ASessionDescription() {
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::setTo(const void *data, size_t size) {
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mIsValid = parse(data, size);
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!mIsValid) {
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mTracks.clear();
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormats.clear();
39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mIsValid;
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::parse(const void *data, size_t size) {
45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mTracks.clear();
46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mFormats.clear();
47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mTracks.push(Attribs());
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mFormats.push(AString("[root]"));
50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString desc((const char *)data, size);
5239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    LOG(INFO) << desc;
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t i = 0;
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ssize_t eolPos = desc.find("\r\n", i);
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (eolPos < 0) {
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        AString line(desc, i, eolPos - i);
62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (line.size() < 2 || line.c_str()[1] != '=') {
64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return false;
65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        switch (line.c_str()[0]) {
68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 'v':
69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            {
70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                if (strcmp(line.c_str(), "v=0")) {
71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    return false;
72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                }
73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 'a':
77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 'b':
78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            {
79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                AString key, value;
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                ssize_t colonPos = line.find(":", 2);
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                if (colonPos < 0) {
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    key = line;
84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                } else {
85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    key.setTo(line, 0, colonPos);
86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    if (key == "a=fmtp" || key == "a=rtpmap"
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                            || key == "a=framesize") {
89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        ssize_t spacePos = line.find(" ", colonPos + 1);
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        if (spacePos < 0) {
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                            return false;
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        }
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        key.setTo(line, 0, spacePos);
95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        colonPos = spacePos;
97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    }
98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    value.setTo(line, colonPos + 1, line.size() - colonPos - 1);
100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                }
101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                key.trim();
103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                value.trim();
104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                LOG(VERBOSE) << "adding '" << key << "' => '" << value << "'";
106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                mTracks.editItemAt(mTracks.size() - 1).add(key, value);
108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 'm':
112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            {
113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                LOG(VERBOSE) << "new section '" << AString(line, 2, line.size() - 2) << "'";
114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                mTracks.push(Attribs());
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                mFormats.push(AString(line, 2, line.size() - 2));
117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
11939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
12039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            default:
12139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            {
12239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                AString key, value;
12339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
12439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                ssize_t equalPos = line.find("=");
12539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
12639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                key = AString(line, 0, equalPos + 1);
12739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                value = AString(line, equalPos + 1, line.size() - equalPos - 1);
12839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
12939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                key.trim();
13039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                value.trim();
13139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
13239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                LOG(VERBOSE) << "adding '" << key << "' => '" << value << "'";
13339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
13439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                mTracks.editItemAt(mTracks.size() - 1).add(key, value);
13539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                break;
13639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            }
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        i = eolPos + 2;
140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::isValid() const {
146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mIsValid;
147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersize_t ASessionDescription::countTracks() const {
150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mTracks.size();
151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ASessionDescription::getFormat(size_t index, AString *value) const {
154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(index, 0u);
155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LT(index, mTracks.size());
156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *value = mFormats.itemAt(index);
158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::findAttribute(
161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t index, const char *key, AString *value) const {
162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(index, 0u);
163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LT(index, mTracks.size());
164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    value->clear();
166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const Attribs &track = mTracks.itemAt(index);
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    ssize_t i = track.indexOfKey(AString(key));
169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (i < 0) {
171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *value = track.valueAt(i);
175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ASessionDescription::getFormatType(
180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t index, unsigned long *PT,
181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        AString *desc, AString *params) const {
182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString format;
183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    getFormat(index, &format);
184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char *lastSpacePos = strrchr(format.c_str(), ' ');
186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(lastSpacePos != NULL);
187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char *end;
189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long x = strtoul(lastSpacePos + 1, &end, 10);
190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, lastSpacePos + 1);
191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(*end, '\0');
192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *PT = x;
194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char key[20];
196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sprintf(key, "a=rtpmap:%lu", x);
197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(findAttribute(index, key, desc));
199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sprintf(key, "a=fmtp:%lu", x);
201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!findAttribute(index, key, params)) {
202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        params->clear();
203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ASessionDescription::getDimensions(
207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t index, unsigned long PT,
208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t *width, int32_t *height) const {
209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char key[20];
210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sprintf(key, "a=framesize:%lu", PT);
211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString value;
212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(findAttribute(index, key, &value));
213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const char *s = value.c_str();
215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char *end;
216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *width = strtoul(s, &end, 10);
217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, s);
218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(*end, '-');
219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    s = end + 1;
221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *height = strtoul(s, &end, 10);
222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, s);
223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(*end, '\0');
224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::getDurationUs(int64_t *durationUs) const {
227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *durationUs = 0;
228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(mIsValid);
230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString value;
232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!findAttribute(0, "a=range", &value)) {
233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (value == "npt=now-") {
237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (strncmp(value.c_str(), "npt=", 4)) {
241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const char *s = value.c_str() + 4;
245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char *end;
246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    double from = strtod(s, &end);
247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, s);
248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(*end, '-');
249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    s = end + 1;
251cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    double to = strtod(s, &end);
252cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, s);
253cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(*end, '\0');
254cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
255cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(to, from);
256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
257cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *durationUs = (int64_t)((to - from) * 1E6);
258cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
259cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
260cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
262cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static
263cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ASessionDescription::ParseFormatDesc(
264cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const char *desc, int32_t *timescale, int32_t *numChannels) {
265cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const char *slash1 = strchr(desc, '/');
266cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(slash1 != NULL);
267cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
268cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const char *s = slash1 + 1;
269cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char *end;
270cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long x = strtoul(s, &end, 10);
271cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, s);
272cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(*end == '\0' || *end == '/');
273cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
274cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *timescale = x;
275cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *numChannels = 1;
276cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
277cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (*end == '/') {
278cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        s = end + 1;
279cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        unsigned long x = strtoul(s, &end, 10);
280cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_GT(end, s);
281cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_EQ(*end, '\0');
282cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
283cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *numChannels = x;
284cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
285cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
286cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
287cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
288cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
289