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