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
176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0
186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "ASessionDescription"
196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h>
20b2396a52aa1620a68bba4d776b136b03707f7556Ray Essick#include <cutils/log.h>
216e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h"
23cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h>
26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <stdlib.h>
28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberASessionDescription::ASessionDescription()
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    : mIsValid(false) {
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberASessionDescription::~ASessionDescription() {
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::setTo(const void *data, size_t size) {
39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mIsValid = parse(data, size);
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!mIsValid) {
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mTracks.clear();
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mFormats.clear();
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mIsValid;
47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::parse(const void *data, size_t size) {
50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mTracks.clear();
51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mFormats.clear();
52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mTracks.push(Attribs());
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mFormats.push(AString("[root]"));
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString desc((const char *)data, size);
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t i = 0;
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
604579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber        ssize_t eolPos = desc.find("\n", i);
614579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber
62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (eolPos < 0) {
63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
664579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber        AString line;
674579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber        if ((size_t)eolPos > i && desc.c_str()[eolPos - 1] == '\r') {
684579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber            // We accept both '\n' and '\r\n' line endings, if it's
694579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber            // the latter, strip the '\r' as well.
704579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber            line.setTo(desc, i, eolPos - i - 1);
714579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber        } else {
724579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber            line.setTo(desc, i, eolPos - i);
734579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber        }
74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
75dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber        if (line.empty()) {
76dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber            i = eolPos + 1;
77dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber            continue;
78dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber        }
79dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (line.size() < 2 || line.c_str()[1] != '=') {
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return false;
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
84df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("%s", line.c_str());
85fc9ac988e08a8b4c42e58999300265989f26f24cAndreas Huber
86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        switch (line.c_str()[0]) {
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 'v':
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            {
89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                if (strcmp(line.c_str(), "v=0")) {
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    return false;
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                }
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 'a':
96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 'b':
97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            {
98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                AString key, value;
99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                ssize_t colonPos = line.find(":", 2);
101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                if (colonPos < 0) {
102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    key = line;
103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                } else {
104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    key.setTo(line, 0, colonPos);
105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    if (key == "a=fmtp" || key == "a=rtpmap"
107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                            || key == "a=framesize") {
108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        ssize_t spacePos = line.find(" ", colonPos + 1);
109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        if (spacePos < 0) {
110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                            return false;
111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        }
112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        key.setTo(line, 0, spacePos);
114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                        colonPos = spacePos;
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    }
117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    value.setTo(line, colonPos + 1, line.size() - colonPos - 1);
119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                }
120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                key.trim();
122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                value.trim();
123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
1243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("adding '%s' => '%s'", key.c_str(), value.c_str());
125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                mTracks.editItemAt(mTracks.size() - 1).add(key, value);
127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 'm':
131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            {
1323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("new section '%s'",
1336e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber                     AString(line, 2, line.size() - 2).c_str());
134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                mTracks.push(Attribs());
136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                mFormats.push(AString(line, 2, line.size() - 2));
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
13939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            default:
14139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            {
14239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                AString key, value;
14339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                ssize_t equalPos = line.find("=");
14539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                key = AString(line, 0, equalPos + 1);
14739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                value = AString(line, equalPos + 1, line.size() - equalPos - 1);
14839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                key.trim();
15039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                value.trim();
15139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
1523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("adding '%s' => '%s'", key.c_str(), value.c_str());
15339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
15439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                mTracks.editItemAt(mTracks.size() - 1).add(key, value);
15539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                break;
15639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            }
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
1594579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber        i = eolPos + 1;
160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::isValid() const {
166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mIsValid;
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersize_t ASessionDescription::countTracks() const {
170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mTracks.size();
171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ASessionDescription::getFormat(size_t index, AString *value) const {
174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(index, 0u);
175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LT(index, mTracks.size());
176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *value = mFormats.itemAt(index);
178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::findAttribute(
181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t index, const char *key, AString *value) const {
182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(index, 0u);
183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_LT(index, mTracks.size());
184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    value->clear();
186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const Attribs &track = mTracks.itemAt(index);
188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    ssize_t i = track.indexOfKey(AString(key));
189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (i < 0) {
191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *value = track.valueAt(i);
195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ASessionDescription::getFormatType(
200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t index, unsigned long *PT,
201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        AString *desc, AString *params) const {
202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString format;
203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    getFormat(index, &format);
204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2054e2ffa400b82559cab2c5717c8dcdff393d334a9Mike Lockwood    const char *lastSpacePos = strrchr(format.c_str(), ' ');
206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(lastSpacePos != NULL);
207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char *end;
209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long x = strtoul(lastSpacePos + 1, &end, 10);
210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, lastSpacePos + 1);
211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(*end, '\0');
212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *PT = x;
214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
215b2396a52aa1620a68bba4d776b136b03707f7556Ray Essick    char key[32];
216b2396a52aa1620a68bba4d776b136b03707f7556Ray Essick    snprintf(key, sizeof(key), "a=rtpmap:%lu", x);
21730474b19a4f9785494d34c15ee2deabe36970814Robert Shih    if (findAttribute(index, key, desc)) {
21830474b19a4f9785494d34c15ee2deabe36970814Robert Shih        snprintf(key, sizeof(key), "a=fmtp:%lu", x);
21930474b19a4f9785494d34c15ee2deabe36970814Robert Shih        if (!findAttribute(index, key, params)) {
22030474b19a4f9785494d34c15ee2deabe36970814Robert Shih            params->clear();
22130474b19a4f9785494d34c15ee2deabe36970814Robert Shih        }
22230474b19a4f9785494d34c15ee2deabe36970814Robert Shih    } else {
22330474b19a4f9785494d34c15ee2deabe36970814Robert Shih        desc->clear();
224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        params->clear();
225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
228ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huberbool ASessionDescription::getDimensions(
229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t index, unsigned long PT,
230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t *width, int32_t *height) const {
231ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber    *width = 0;
232ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber    *height = 0;
233ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber
234b2396a52aa1620a68bba4d776b136b03707f7556Ray Essick    char key[33];
235b2396a52aa1620a68bba4d776b136b03707f7556Ray Essick    snprintf(key, sizeof(key), "a=framesize:%lu", PT);
236b2396a52aa1620a68bba4d776b136b03707f7556Ray Essick    if (PT > 9999999) {
237b2396a52aa1620a68bba4d776b136b03707f7556Ray Essick        android_errorWriteLog(0x534e4554, "25747670");
238b2396a52aa1620a68bba4d776b136b03707f7556Ray Essick    }
239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString value;
240ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber    if (!findAttribute(index, key, &value)) {
241ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber        return false;
242ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber    }
243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const char *s = value.c_str();
245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char *end;
246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *width = strtoul(s, &end, 10);
247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, s);
248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(*end, '-');
249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    s = end + 1;
251cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *height = strtoul(s, &end, 10);
252cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, s);
253cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(*end, '\0');
254ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber
255ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber    return true;
256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
257cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
258cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ASessionDescription::getDurationUs(int64_t *durationUs) const {
259cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *durationUs = 0;
260cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(mIsValid);
262cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
263cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString value;
264cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!findAttribute(0, "a=range", &value)) {
265cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
266cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
267cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
268cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (strncmp(value.c_str(), "npt=", 4)) {
269cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
270cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
271cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
272783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    float from, to;
273783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    if (!parseNTPRange(value.c_str() + 4, &from, &to)) {
274934ca8cb1bcffcf1781a576ca625d2f901e5f0a9Andreas Huber        return false;
275934ca8cb1bcffcf1781a576ca625d2f901e5f0a9Andreas Huber    }
276cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
277cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *durationUs = (int64_t)((to - from) * 1E6);
278cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
279cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
280cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
281cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
282cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static
283cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ASessionDescription::ParseFormatDesc(
284cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const char *desc, int32_t *timescale, int32_t *numChannels) {
285cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const char *slash1 = strchr(desc, '/');
286cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(slash1 != NULL);
287cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
288cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const char *s = slash1 + 1;
289cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    char *end;
290cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long x = strtoul(s, &end, 10);
291cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GT(end, s);
292cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(*end == '\0' || *end == '/');
293cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
294cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *timescale = x;
295cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *numChannels = 1;
296cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
297cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (*end == '/') {
298cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        s = end + 1;
299cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        unsigned long x = strtoul(s, &end, 10);
300cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_GT(end, s);
301cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK_EQ(*end, '\0');
302cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
303cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        *numChannels = x;
304cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
305cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
306cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
307783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber// static
308783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huberbool ASessionDescription::parseNTPRange(
309783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber        const char *s, float *npt1, float *npt2) {
310783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    if (s[0] == '-') {
311783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber        return false;  // no start time available.
312783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    }
313783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
314783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    if (!strncmp("now", s, 3)) {
315783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber        return false;  // no absolute start time available
316783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    }
317783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
318783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    char *end;
319783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    *npt1 = strtof(s, &end);
320783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
321783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    if (end == s || *end != '-') {
322783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber        // Failed to parse float or trailing "dash".
323783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber        return false;
324783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    }
325783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
326783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    s = end + 1;  // skip the dash.
327783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
328f4eadb67ba9130b583b8f2f192276b53fa3d50bcWei Jia    if (*s == '\0') {
329f4eadb67ba9130b583b8f2f192276b53fa3d50bcWei Jia        *npt2 = FLT_MAX;  // open ended.
330f4eadb67ba9130b583b8f2f192276b53fa3d50bcWei Jia        return true;
331f4eadb67ba9130b583b8f2f192276b53fa3d50bcWei Jia    }
332f4eadb67ba9130b583b8f2f192276b53fa3d50bcWei Jia
333783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    if (!strncmp("now", s, 3)) {
334783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber        return false;  // no absolute end time available
335783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    }
336783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
337783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    *npt2 = strtof(s, &end);
338783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
339783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    if (end == s || *end != '\0') {
340783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber        return false;
341783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    }
342783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
343783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber    return *npt2 > *npt1;
344783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber}
345783e5cd85d4bd40b1a04dfdfed256c5dcb2525ccAndreas Huber
346cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
347cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
348