APacketSource.cpp revision 85f12e9b9062402d6110df3f7099707912040edb
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 "APacketSource.h" 18cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 19cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h" 20cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 2185f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include "avc_utils.h" 2285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 23ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber#include <ctype.h> 24ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber 25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h> 27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h> 28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h> 29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/base64.h> 30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/hexdump.h> 31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaBuffer.h> 32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaDefs.h> 33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MetaData.h> 34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <utils/Vector.h> 35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android { 37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic bool GetAttribute(const char *s, const char *key, AString *value) { 39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value->clear(); 40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t keyLen = strlen(key); 42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (;;) { 44ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber while (isspace(*s)) { 45ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber ++s; 46ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 47ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber 48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const char *colonPos = strchr(s, ';'); 49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t len = 51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (colonPos == NULL) ? strlen(s) : colonPos - s; 52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) { 54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value->setTo(&s[keyLen + 1], len - keyLen - 1); 55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return true; 56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (colonPos == NULL) { 59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber s = colonPos + 1; 63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic sp<ABuffer> decodeHex(const AString &s) { 67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((s.size() % 2) != 0) { 68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return NULL; 69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t outLen = s.size() / 2; 72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> buffer = new ABuffer(outLen); 73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t *out = buffer->data(); 74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t accum = 0; 76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < s.size(); ++i) { 77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char c = s.c_str()[i]; 78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned value; 79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (c >= '0' && c <= '9') { 80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - '0'; 81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (c >= 'a' && c <= 'f') { 82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - 'a' + 10; 83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (c >= 'A' && c <= 'F') { 84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - 'A' + 10; 85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return NULL; 87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber accum = (accum << 4) | value; 90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (i & 1) { 92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = accum; 93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber accum = 0; 95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return buffer; 99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 10185f12e9b9062402d6110df3f7099707912040edbAndreas Huberstatic sp<ABuffer> MakeAVCCodecSpecificData( 10285f12e9b9062402d6110df3f7099707912040edbAndreas Huber const char *params, int32_t *width, int32_t *height) { 10385f12e9b9062402d6110df3f7099707912040edbAndreas Huber *width = 0; 10485f12e9b9062402d6110df3f7099707912040edbAndreas Huber *height = 0; 10585f12e9b9062402d6110df3f7099707912040edbAndreas Huber 106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString val; 10733a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (!GetAttribute(params, "profile-level-id", &val)) { 10833a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber return NULL; 10933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> profileLevelID = decodeHex(val); 112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(profileLevelID != NULL); 113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ(profileLevelID->size(), 3u); 114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Vector<sp<ABuffer> > paramSets; 116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t numSeqParameterSets = 0; 118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t totalSeqParameterSetSize = 0; 119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t numPicParameterSets = 0; 120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t totalPicParameterSetSize = 0; 121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 12233a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (!GetAttribute(params, "sprop-parameter-sets", &val)) { 12333a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber return NULL; 12433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 12533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber 126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t start = 0; 127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (;;) { 128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ssize_t commaPos = val.find(",", start); 129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t end = (commaPos < 0) ? val.size() : commaPos; 130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString nalString(val, start, end - start); 132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = decodeBase64(nalString); 133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(nal != NULL); 134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GT(nal->size(), 0u); 135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LE(nal->size(), 65535u); 136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t nalType = nal->data()[0] & 0x1f; 138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (numSeqParameterSets == 0) { 139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 7u); 140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (numPicParameterSets > 0) { 141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 8u); 142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (nalType == 7) { 144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++numSeqParameterSets; 145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber totalSeqParameterSetSize += nal->size(); 146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 8u); 148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++numPicParameterSets; 149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber totalPicParameterSetSize += nal->size(); 150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber paramSets.push(nal); 153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (commaPos < 0) { 155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber start = commaPos + 1; 159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LT(numSeqParameterSets, 32u); 162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LE(numPicParameterSets, 255u); 163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t csdSize = 165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 1 + 3 + 1 + 1 166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber + 2 * numSeqParameterSets + totalSeqParameterSetSize 167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber + 1 + 2 * numPicParameterSets + totalPicParameterSetSize; 168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> csd = new ABuffer(csdSize); 170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t *out = csd->data(); 171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = 0x01; // configurationVersion 173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, profileLevelID->data(), 3); 174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += 3; 175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes 176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = 0xe0 | numSeqParameterSets; 177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = paramSets.editItemAt(i); 180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() >> 8; 182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() & 0xff; 183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, nal->data(), nal->size()); 185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += nal->size(); 18785f12e9b9062402d6110df3f7099707912040edbAndreas Huber 18885f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (i == 0) { 18985f12e9b9062402d6110df3f7099707912040edbAndreas Huber FindAVCDimensions(nal, width, height); 19085f12e9b9062402d6110df3f7099707912040edbAndreas Huber LOG(INFO) << "dimensions " << *width << "x" << *height; 19185f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = numPicParameterSets; 195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < numPicParameterSets; ++i) { 197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets); 198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() >> 8; 200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() & 0xff; 201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, nal->data(), nal->size()); 203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += nal->size(); 205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 20785f12e9b9062402d6110df3f7099707912040edbAndreas Huber // hexdump(csd->data(), csd->size()); 208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return csd; 210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<ABuffer> MakeAACCodecSpecificData(const char *params) { 213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString val; 214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(GetAttribute(params, "config", &val)); 215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> config = decodeHex(val); 217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(config != NULL); 218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(config->size(), 4u); 219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = config->data(); 221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber x = (x >> 1) & 0xffff; 223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber static const uint8_t kStaticESDS[] = { 225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x03, 22, 226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, // ES_ID 227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x04, 17, 230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x40, // Audio ISO/IEC 14496-3 231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x05, 2, 236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // AudioSpecificInfo follows 237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber }; 238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2); 240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS)); 241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff; 242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff; 243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 24485f12e9b9062402d6110df3f7099707912040edbAndreas Huber // hexdump(csd->data(), csd->size()); 245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return csd; 247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::APacketSource( 250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ASessionDescription> &sessionDesc, size_t index) 25139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber : mInitCheck(NO_INIT), 25239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat(new MetaData), 25339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mEOSResult(OK), 25439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFirstAccessUnit(true), 25539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFirstAccessUnitNTP(0) { 256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned long PT; 257cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString desc; 258cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString params; 259cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 260cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int64_t durationUs; 262cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (sessionDesc->getDurationUs(&durationUs)) { 263cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt64(kKeyDuration, durationUs); 264cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 265cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt64(kKeyDuration, 60 * 60 * 1000000ll); 266cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 267cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 26839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = OK; 269cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!strncmp(desc.c_str(), "H264/", 5)) { 270cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 271cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 272cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t width, height; 273ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 27485f12e9b9062402d6110df3f7099707912040edbAndreas Huber width = -1; 27585f12e9b9062402d6110df3f7099707912040edbAndreas Huber height = -1; 276ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 277cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 27885f12e9b9062402d6110df3f7099707912040edbAndreas Huber int32_t encWidth, encHeight; 279cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> codecSpecificData = 28085f12e9b9062402d6110df3f7099707912040edbAndreas Huber MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight); 281cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 28233a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (codecSpecificData != NULL) { 28385f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (width < 0) { 28485f12e9b9062402d6110df3f7099707912040edbAndreas Huber // If no explicit width/height given in the sdp, use the dimensions 28585f12e9b9062402d6110df3f7099707912040edbAndreas Huber // extracted from the first sequence parameter set. 28685f12e9b9062402d6110df3f7099707912040edbAndreas Huber width = encWidth; 28785f12e9b9062402d6110df3f7099707912040edbAndreas Huber height = encHeight; 28885f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 28985f12e9b9062402d6110df3f7099707912040edbAndreas Huber 29033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber mFormat->setData( 29133a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber kKeyAVCC, 0, 29233a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber codecSpecificData->data(), codecSpecificData->size()); 29385f12e9b9062402d6110df3f7099707912040edbAndreas Huber } else if (width < 0) { 29485f12e9b9062402d6110df3f7099707912040edbAndreas Huber mInitCheck = ERROR_UNSUPPORTED; 29585f12e9b9062402d6110df3f7099707912040edbAndreas Huber return; 29633a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 29785f12e9b9062402d6110df3f7099707912040edbAndreas Huber 29885f12e9b9062402d6110df3f7099707912040edbAndreas Huber mFormat->setInt32(kKeyWidth, width); 29985f12e9b9062402d6110df3f7099707912040edbAndreas Huber mFormat->setInt32(kKeyHeight, height); 30039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "H263-2000/", 10) 30139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber || !strncmp(desc.c_str(), "H263-1998/", 10)) { 30239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 303cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 30439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t width, height; 305ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 306ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 307ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber return; 308ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 30939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 31039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyWidth, width); 31139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyHeight, height); 31239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) { 313cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 314cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 315cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t sampleRate, numChannels; 316cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ASessionDescription::ParseFormatDesc( 317cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber desc.c_str(), &sampleRate, &numChannels); 318cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 319cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 320cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 321cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 322cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> codecSpecificData = 323cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MakeAACCodecSpecificData(params.c_str()); 324cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 325cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setData( 326cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber kKeyESDS, 0, 327cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber codecSpecificData->data(), codecSpecificData->size()); 32839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "AMR/", 4)) { 32939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 33039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 33139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t sampleRate, numChannels; 33239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ASessionDescription::ParseFormatDesc( 33339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber desc.c_str(), &sampleRate, &numChannels); 33439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 33539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 33639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 33739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 33839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (sampleRate != 8000 || numChannels != 1) { 33939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 34039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 34139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { 34239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 34339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 34439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t sampleRate, numChannels; 34539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ASessionDescription::ParseFormatDesc( 34639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber desc.c_str(), &sampleRate, &numChannels); 34739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 34839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 34939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 35039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 35139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (sampleRate != 16000 || numChannels != 1) { 35239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 35339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 354cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 35539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 356cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 357cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 358cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 359cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::~APacketSource() { 360cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 361cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 36239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t APacketSource::initCheck() const { 36339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return mInitCheck; 36439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 36539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 366cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::start(MetaData *params) { 36739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFirstAccessUnit = true; 36839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFirstAccessUnitNTP = 0; 36939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 370cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 371cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 372cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 373cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::stop() { 374cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 375cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 376cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 377cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<MetaData> APacketSource::getFormat() { 378cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return mFormat; 379cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 380cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 381cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::read( 382cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MediaBuffer **out, const ReadOptions *) { 383cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out = NULL; 384cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 385cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 386cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (mEOSResult == OK && mBuffers.empty()) { 387cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.wait(mLock); 388cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 389cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 390cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!mBuffers.empty()) { 391cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ABuffer> buffer = *mBuffers.begin(); 392cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 39339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size()); 39439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 395f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber int64_t timeUs; 396f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 397cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 398cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs); 39939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 400cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(mediaBuffer->data(), buffer->data(), buffer->size()); 401cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out = mediaBuffer; 402cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 403cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mBuffers.erase(mBuffers.begin()); 404cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 405cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 406cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 407cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return mEOSResult; 408cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 409cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 410cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) { 411cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t damaged; 412cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (buffer->meta()->findInt32("damaged", &damaged) && damaged) { 4136dc387a8c3f031f9f17d1138295368946563f7a5Andreas Huber LOG(VERBOSE) << "discarding damaged AU"; 414cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 415cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 416cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 417f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber uint64_t ntpTime; 418f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber CHECK(buffer->meta()->findInt64( 419f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber "ntp-time", (int64_t *)&ntpTime)); 420f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber 421f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber if (mFirstAccessUnit) { 422f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber mFirstAccessUnit = false; 423f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber mFirstAccessUnitNTP = ntpTime; 424f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber } 425f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber 426f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber if (ntpTime > mFirstAccessUnitNTP) { 427f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber ntpTime -= mFirstAccessUnitNTP; 428f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber } else { 429f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber ntpTime = 0; 430f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber } 431f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber 432f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber int64_t timeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32)); 433f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber 434f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber buffer->meta()->setInt64("timeUs", timeUs); 435f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber 436cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 437cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mBuffers.push_back(buffer); 438cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.signal(); 439cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 440cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 441cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::signalEOS(status_t result) { 442cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(result != OK); 443cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 444cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 445cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mEOSResult = result; 446cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.signal(); 447cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 448cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 44939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberint64_t APacketSource::getQueuedDuration(bool *eos) { 45039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 45139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 45239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *eos = (mEOSResult != OK); 45339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 45439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mBuffers.empty()) { 45539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return 0; 45639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 45739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 45839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ABuffer> buffer = *mBuffers.begin(); 45939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 46039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint64_t ntpTime; 46139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(buffer->meta()->findInt64( 46239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "ntp-time", (int64_t *)&ntpTime)); 46339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 46439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int64_t firstTimeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32)); 46539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 46639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer = *--mBuffers.end(); 46739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 46839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(buffer->meta()->findInt64( 46939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "ntp-time", (int64_t *)&ntpTime)); 47039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 47139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int64_t lastTimeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32)); 47239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 47339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return lastTimeUs - firstTimeUs; 47439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 47539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 476cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} // namespace android 477