APacketSource.cpp revision 386d609dc513e838c7e7c4c46c604493ccd560be
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 "APacketSource" 196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h> 206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber 21cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "APacketSource.h" 22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 23fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber#include "ARawAudioAssembler.h" 24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h" 25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 2685f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include "avc_utils.h" 2785f12e9b9062402d6110df3f7099707912040edbAndreas Huber 28ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber#include <ctype.h> 29ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber 3062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber#include <media/stagefright/foundation/ABitReader.h> 31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h> 33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h> 34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h> 35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/base64.h> 36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/hexdump.h> 37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaBuffer.h> 38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaDefs.h> 39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MetaData.h> 40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <utils/Vector.h> 41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android { 43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic bool GetAttribute(const char *s, const char *key, AString *value) { 45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value->clear(); 46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t keyLen = strlen(key); 48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (;;) { 50ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber while (isspace(*s)) { 51ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber ++s; 52ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 53ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber 54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const char *colonPos = strchr(s, ';'); 55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t len = 57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (colonPos == NULL) ? strlen(s) : colonPos - s; 58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) { 60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value->setTo(&s[keyLen + 1], len - keyLen - 1); 61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return true; 62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (colonPos == NULL) { 65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber s = colonPos + 1; 69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic sp<ABuffer> decodeHex(const AString &s) { 73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((s.size() % 2) != 0) { 74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return NULL; 75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t outLen = s.size() / 2; 78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> buffer = new ABuffer(outLen); 79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t *out = buffer->data(); 80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t accum = 0; 82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < s.size(); ++i) { 83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char c = s.c_str()[i]; 84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned value; 85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (c >= '0' && c <= '9') { 86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - '0'; 87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (c >= 'a' && c <= 'f') { 88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - 'a' + 10; 89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (c >= 'A' && c <= 'F') { 90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - 'A' + 10; 91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return NULL; 93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber accum = (accum << 4) | value; 96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (i & 1) { 98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = accum; 99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber accum = 0; 101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return buffer; 105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 10785f12e9b9062402d6110df3f7099707912040edbAndreas Huberstatic sp<ABuffer> MakeAVCCodecSpecificData( 10885f12e9b9062402d6110df3f7099707912040edbAndreas Huber const char *params, int32_t *width, int32_t *height) { 10985f12e9b9062402d6110df3f7099707912040edbAndreas Huber *width = 0; 11085f12e9b9062402d6110df3f7099707912040edbAndreas Huber *height = 0; 11185f12e9b9062402d6110df3f7099707912040edbAndreas Huber 112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString val; 11333a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (!GetAttribute(params, "profile-level-id", &val)) { 11433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber return NULL; 11533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> profileLevelID = decodeHex(val); 118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(profileLevelID != NULL); 119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ(profileLevelID->size(), 3u); 120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Vector<sp<ABuffer> > paramSets; 122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t numSeqParameterSets = 0; 124cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t totalSeqParameterSetSize = 0; 125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t numPicParameterSets = 0; 126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t totalPicParameterSetSize = 0; 127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 12833a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (!GetAttribute(params, "sprop-parameter-sets", &val)) { 12933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber return NULL; 13033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 13133a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber 132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t start = 0; 133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (;;) { 134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ssize_t commaPos = val.find(",", start); 135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t end = (commaPos < 0) ? val.size() : commaPos; 136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString nalString(val, start, end - start); 138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = decodeBase64(nalString); 139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(nal != NULL); 140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GT(nal->size(), 0u); 141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LE(nal->size(), 65535u); 142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t nalType = nal->data()[0] & 0x1f; 144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (numSeqParameterSets == 0) { 145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 7u); 146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (numPicParameterSets > 0) { 147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 8u); 148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (nalType == 7) { 150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++numSeqParameterSets; 151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber totalSeqParameterSetSize += nal->size(); 152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 8u); 154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++numPicParameterSets; 155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber totalPicParameterSetSize += nal->size(); 156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber paramSets.push(nal); 159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (commaPos < 0) { 161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber start = commaPos + 1; 165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LT(numSeqParameterSets, 32u); 168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LE(numPicParameterSets, 255u); 169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t csdSize = 171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 1 + 3 + 1 + 1 172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber + 2 * numSeqParameterSets + totalSeqParameterSetSize 173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber + 1 + 2 * numPicParameterSets + totalPicParameterSetSize; 174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> csd = new ABuffer(csdSize); 176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t *out = csd->data(); 177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = 0x01; // configurationVersion 179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, profileLevelID->data(), 3); 180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += 3; 181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes 182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = 0xe0 | numSeqParameterSets; 183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = paramSets.editItemAt(i); 186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() >> 8; 188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() & 0xff; 189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, nal->data(), nal->size()); 191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += nal->size(); 19385f12e9b9062402d6110df3f7099707912040edbAndreas Huber 19485f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (i == 0) { 19585f12e9b9062402d6110df3f7099707912040edbAndreas Huber FindAVCDimensions(nal, width, height); 1966e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("dimensions %dx%d", *width, *height); 19785f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = numPicParameterSets; 201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < numPicParameterSets; ++i) { 203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets); 204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() >> 8; 206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() & 0xff; 207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, nal->data(), nal->size()); 209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += nal->size(); 211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 21385f12e9b9062402d6110df3f7099707912040edbAndreas Huber // hexdump(csd->data(), csd->size()); 214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return csd; 216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<ABuffer> MakeAACCodecSpecificData(const char *params) { 219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString val; 220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(GetAttribute(params, "config", &val)); 221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> config = decodeHex(val); 223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(config != NULL); 224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(config->size(), 4u); 225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = config->data(); 227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber x = (x >> 1) & 0xffff; 229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber static const uint8_t kStaticESDS[] = { 231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x03, 22, 232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, // ES_ID 233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x04, 17, 236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x40, // Audio ISO/IEC 14496-3 237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x05, 2, 242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // AudioSpecificInfo follows 243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber }; 244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2); 246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS)); 247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff; 248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff; 249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 25085f12e9b9062402d6110df3f7099707912040edbAndreas Huber // hexdump(csd->data(), csd->size()); 251cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 252cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return csd; 253cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 254cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 2554dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber// From mpeg4-generic configuration data. 2564dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Hubersp<ABuffer> MakeAACCodecSpecificData2(const char *params) { 2574dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber AString val; 2584dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber unsigned long objectType; 2594dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber if (GetAttribute(params, "objectType", &val)) { 2604dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber const char *s = val.c_str(); 2614dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber char *end; 2624dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber objectType = strtoul(s, &end, 10); 2634dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber CHECK(end > s && *end == '\0'); 2644dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber } else { 2654dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber objectType = 0x40; // Audio ISO/IEC 14496-3 2664dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber } 2674dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2684dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber CHECK(GetAttribute(params, "config", &val)); 2694dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2704dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber sp<ABuffer> config = decodeHex(val); 2714dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber CHECK(config != NULL); 2724dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2734dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber // Make sure size fits into a single byte and doesn't have to 2744dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber // be encoded. 2754dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber CHECK_LT(20 + config->size(), 128u); 2764dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2774dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber const uint8_t *data = config->data(); 2784dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2794dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber static const uint8_t kStaticESDS[] = { 2804dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x03, 22, 2814dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, 0x00, // ES_ID 2824dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 2834dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2844dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x04, 17, 2854dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x40, // Audio ISO/IEC 14496-3 2864dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, 0x00, 0x00, 0x00, 2874dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, 0x00, 0x00, 0x00, 2884dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, 0x00, 0x00, 0x00, 2894dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2904dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x05, 2, 2914dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber // AudioSpecificInfo follows 2924dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber }; 2934dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2944dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size()); 2954dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber uint8_t *dst = csd->data(); 2964dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x03; 2974dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 20 + config->size(); 2984dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x00; // ES_ID 2994dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x00; 3004dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 3014dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x04; 3024dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 15 + config->size(); 3034dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = objectType; 3044dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber for (int i = 0; i < 12; ++i) { *dst++ = 0x00; } 3054dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x05; 3064dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = config->size(); 3074dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber memcpy(dst, config->data(), config->size()); 3084dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 3094dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber // hexdump(csd->data(), csd->size()); 3104dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 3114dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber return csd; 3124dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber} 3134dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 31462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic size_t GetSizeWidth(size_t x) { 31562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t n = 1; 31662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber while (x > 127) { 31762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber ++n; 31862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber x >>= 7; 31962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 32062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return n; 32162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber} 32262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 32362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic uint8_t *EncodeSize(uint8_t *dst, size_t x) { 32462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber while (x > 127) { 32562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = (x & 0x7f) | 0x80; 32662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber x >>= 7; 32762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 32862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = x; 32962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return dst; 33062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber} 33162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 332386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic bool ExtractDimensionsMPEG4Config( 33362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber const sp<ABuffer> &config, int32_t *width, int32_t *height) { 33462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *width = 0; 33562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *height = 0; 33662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 33762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber const uint8_t *ptr = config->data(); 33862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t offset = 0; 33962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber bool foundVOL = false; 34062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber while (offset + 3 < config->size()) { 34162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (memcmp("\x00\x00\x01", &ptr[offset], 3) 34262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber || (ptr[offset + 3] & 0xf0) != 0x20) { 34362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber ++offset; 34462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber continue; 34562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 34662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 34762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber foundVOL = true; 34862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber break; 34962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 35062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 35162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (!foundVOL) { 35262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return false; 35362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 35462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 355386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return ExtractDimensionsFromVOLHeader( 356386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber &ptr[offset], config->size() - offset, width, height); 35762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber} 35862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 359386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberstatic sp<ABuffer> MakeMPEG4VideoCodecSpecificData( 36062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber const char *params, int32_t *width, int32_t *height) { 36162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *width = 0; 36262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *height = 0; 36362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 36462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber AString val; 36562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(GetAttribute(params, "config", &val)); 36662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 36762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber sp<ABuffer> config = decodeHex(val); 36862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(config != NULL); 36962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 370386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (!ExtractDimensionsMPEG4Config(config, width, height)) { 37162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return NULL; 37262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 37362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 374386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber LOGI("VOL dimensions = %dx%d", *width, *height); 375386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 37662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t len1 = config->size() + GetSizeWidth(config->size()) + 1; 37762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13; 37862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3; 37962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 38062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber sp<ABuffer> csd = new ABuffer(len3); 38162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber uint8_t *dst = csd->data(); 38262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x03; 38362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber dst = EncodeSize(dst, len2 + 3); 38462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x00; // ES_ID 38562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x00; 38662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 38762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 38862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x04; 38962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber dst = EncodeSize(dst, len1 + 13); 39062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile 39162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber for (size_t i = 0; i < 12; ++i) { 39262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x00; 39362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 39462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 39562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x05; 39662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber dst = EncodeSize(dst, config->size()); 39762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber memcpy(dst, config->data(), config->size()); 39862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber dst += config->size(); 39962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 40062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // hexdump(csd->data(), csd->size()); 40162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 40262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return csd; 40362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber} 40462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 4058d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberstatic bool GetClockRate(const AString &desc, uint32_t *clockRate) { 4068d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber ssize_t slashPos = desc.find("/"); 4078d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber if (slashPos < 0) { 4088d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return false; 4098d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber } 4108d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4118d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber const char *s = desc.c_str() + slashPos + 1; 4128d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4138d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber char *end; 4148d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber unsigned long x = strtoul(s, &end, 10); 4158d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4168d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber if (end == s || (*end != '\0' && *end != '/')) { 4178d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return false; 4188d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber } 4198d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4208d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber *clockRate = x; 4218d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4228d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return true; 4238d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 4248d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 425cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::APacketSource( 426cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ASessionDescription> &sessionDesc, size_t index) 42739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber : mInitCheck(NO_INIT), 42839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat(new MetaData), 4298d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mEOSResult(OK), 430c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber mIsAVC(false), 431c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber mScanForIDR(true), 4328d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mRTPTimeBase(0), 4338d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mNormalPlayTimeBaseUs(0), 4348d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mLastNormalPlayTimeUs(0) { 435cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned long PT; 436cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString desc; 437cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString params; 438cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 439cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 4408d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber CHECK(GetClockRate(desc, &mClockRate)); 4418d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 442cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int64_t durationUs; 443cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (sessionDesc->getDurationUs(&durationUs)) { 444cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt64(kKeyDuration, durationUs); 445cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 446cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt64(kKeyDuration, 60 * 60 * 1000000ll); 447cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 448cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 44939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = OK; 450cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!strncmp(desc.c_str(), "H264/", 5)) { 451c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber mIsAVC = true; 452c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 453cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 454cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 455cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t width, height; 456ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 45785f12e9b9062402d6110df3f7099707912040edbAndreas Huber width = -1; 45885f12e9b9062402d6110df3f7099707912040edbAndreas Huber height = -1; 459ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 460cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 46185f12e9b9062402d6110df3f7099707912040edbAndreas Huber int32_t encWidth, encHeight; 462cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> codecSpecificData = 46385f12e9b9062402d6110df3f7099707912040edbAndreas Huber MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight); 464cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 46533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (codecSpecificData != NULL) { 46685f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (width < 0) { 46785f12e9b9062402d6110df3f7099707912040edbAndreas Huber // If no explicit width/height given in the sdp, use the dimensions 46885f12e9b9062402d6110df3f7099707912040edbAndreas Huber // extracted from the first sequence parameter set. 46985f12e9b9062402d6110df3f7099707912040edbAndreas Huber width = encWidth; 47085f12e9b9062402d6110df3f7099707912040edbAndreas Huber height = encHeight; 47185f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 47285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 47333a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber mFormat->setData( 47433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber kKeyAVCC, 0, 47533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber codecSpecificData->data(), codecSpecificData->size()); 47685f12e9b9062402d6110df3f7099707912040edbAndreas Huber } else if (width < 0) { 47785f12e9b9062402d6110df3f7099707912040edbAndreas Huber mInitCheck = ERROR_UNSUPPORTED; 47885f12e9b9062402d6110df3f7099707912040edbAndreas Huber return; 47933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 48085f12e9b9062402d6110df3f7099707912040edbAndreas Huber 48185f12e9b9062402d6110df3f7099707912040edbAndreas Huber mFormat->setInt32(kKeyWidth, width); 48285f12e9b9062402d6110df3f7099707912040edbAndreas Huber mFormat->setInt32(kKeyHeight, height); 48339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "H263-2000/", 10) 48439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber || !strncmp(desc.c_str(), "H263-1998/", 10)) { 48539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 486cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 48739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t width, height; 488ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 489ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 490ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber return; 491ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 49239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 49339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyWidth, width); 49439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyHeight, height); 49539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) { 496cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 497cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 498cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t sampleRate, numChannels; 499cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ASessionDescription::ParseFormatDesc( 500cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber desc.c_str(), &sampleRate, &numChannels); 501cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 502cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 503cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 504cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 505cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> codecSpecificData = 506cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MakeAACCodecSpecificData(params.c_str()); 507cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 508cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setData( 509cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber kKeyESDS, 0, 510cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber codecSpecificData->data(), codecSpecificData->size()); 51139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "AMR/", 4)) { 51239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 51339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 51439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t sampleRate, numChannels; 51539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ASessionDescription::ParseFormatDesc( 51639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber desc.c_str(), &sampleRate, &numChannels); 51739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 51839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 51939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 52039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 52139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (sampleRate != 8000 || numChannels != 1) { 52239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 52339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 52439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { 52539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 52639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 52739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t sampleRate, numChannels; 52839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ASessionDescription::ParseFormatDesc( 52939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber desc.c_str(), &sampleRate, &numChannels); 53039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 53139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 53239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 53339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 53439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (sampleRate != 16000 || numChannels != 1) { 53539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 53639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 53762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) { 53862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 53962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 54062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber int32_t width, height; 54162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 54262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber width = -1; 54362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber height = -1; 54462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 54562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 54662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber int32_t encWidth, encHeight; 54762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber sp<ABuffer> codecSpecificData = 54862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber MakeMPEG4VideoCodecSpecificData( 54962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber params.c_str(), &encWidth, &encHeight); 55062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 55162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (codecSpecificData != NULL) { 55262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mFormat->setData( 55362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber kKeyESDS, 0, 55462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber codecSpecificData->data(), codecSpecificData->size()); 55562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 55662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (width < 0) { 55762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber width = encWidth; 55862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber height = encHeight; 55962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 56062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } else if (width < 0) { 56162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 56262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return; 56362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 56462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 56562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mFormat->setInt32(kKeyWidth, width); 56662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mFormat->setInt32(kKeyHeight, height); 567dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber } else if (!strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) { 5684dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber AString val; 5694dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber if (!GetAttribute(params.c_str(), "mode", &val) 5704dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber || (strcasecmp(val.c_str(), "AAC-lbr") 5714dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber && strcasecmp(val.c_str(), "AAC-hbr"))) { 5724dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 5734dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber return; 5744dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber } 5754dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 5764dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 5774dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 5784dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber int32_t sampleRate, numChannels; 5794dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber ASessionDescription::ParseFormatDesc( 5804dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber desc.c_str(), &sampleRate, &numChannels); 5814dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 5824dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 5834dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 5844dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 5854dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber sp<ABuffer> codecSpecificData = 5864dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber MakeAACCodecSpecificData2(params.c_str()); 5874dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 5884dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mFormat->setData( 5894dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber kKeyESDS, 0, 5904dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber codecSpecificData->data(), codecSpecificData->size()); 591fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber } else if (ARawAudioAssembler::Supports(desc.c_str())) { 592fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber ARawAudioAssembler::MakeFormat(desc.c_str(), mFormat); 593cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 59439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 595cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 596cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 597cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 598cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::~APacketSource() { 599cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 600cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 60139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t APacketSource::initCheck() const { 60239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return mInitCheck; 60339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 60439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 605cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::start(MetaData *params) { 606cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 607cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 608cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 609cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::stop() { 610cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 611cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 612cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 613cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<MetaData> APacketSource::getFormat() { 614cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return mFormat; 615cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 616cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 617cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::read( 618cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MediaBuffer **out, const ReadOptions *) { 619cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out = NULL; 620cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 621cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 622cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (mEOSResult == OK && mBuffers.empty()) { 623cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.wait(mLock); 624cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 625cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 626cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!mBuffers.empty()) { 627cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ABuffer> buffer = *mBuffers.begin(); 628cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 6298d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber updateNormalPlayTime_l(buffer); 6308d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 63139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size()); 63239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 633f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber int64_t timeUs; 634f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 635cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 636cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs); 63739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 638cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(mediaBuffer->data(), buffer->data(), buffer->size()); 639cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out = mediaBuffer; 640cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 641cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mBuffers.erase(mBuffers.begin()); 642cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 643cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 644cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 645cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return mEOSResult; 646cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 647cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 6488d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid APacketSource::updateNormalPlayTime_l(const sp<ABuffer> &buffer) { 6498d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber uint32_t rtpTime; 6508d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 6518d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 6528d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mLastNormalPlayTimeUs = 6538d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber (((double)rtpTime - (double)mRTPTimeBase) / mClockRate) 6548d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber * 1000000ll 6558d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber + mNormalPlayTimeBaseUs; 6568d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 6578d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 658cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) { 659cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t damaged; 660cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (buffer->meta()->findInt32("damaged", &damaged) && damaged) { 6616e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("discarding damaged AU"); 662cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 663cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 664cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 665c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (mScanForIDR && mIsAVC) { 666c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber // This pretty piece of code ensures that the first access unit 667c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber // fed to the decoder after stream-start or seek is guaranteed to 668c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber // be an IDR frame. This is to workaround limitations of a certain 669c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber // hardware h.264 decoder that requires this to be the case. 670c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 671c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (!IsIDR(buffer)) { 672c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber LOGV("skipping AU while scanning for next IDR frame."); 673c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return; 674c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 675c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 676c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber mScanForIDR = false; 677c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 678c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 679cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 680cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mBuffers.push_back(buffer); 681cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.signal(); 682cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 683cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 684cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::signalEOS(status_t result) { 685cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(result != OK); 686cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 687cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 688cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mEOSResult = result; 689cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.signal(); 690cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 691cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 692cce326fe43411855aca2f719e505b051bc4b61b3Andreas Hubervoid APacketSource::flushQueue() { 69339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 694cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber mBuffers.clear(); 695c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 696c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber mScanForIDR = true; 69739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 69839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 6998d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberint64_t APacketSource::getNormalPlayTimeUs() { 7008d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber Mutex::Autolock autoLock(mLock); 7018d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return mLastNormalPlayTimeUs; 7028d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 7038d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 7048d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid APacketSource::setNormalPlayTimeMapping( 7058d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber uint32_t rtpTime, int64_t normalPlayTimeUs) { 7068d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber Mutex::Autolock autoLock(mLock); 7078d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 7088d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mRTPTimeBase = rtpTime; 7098d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mNormalPlayTimeBaseUs = normalPlayTimeUs; 7108d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 7118d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 712c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huberint64_t APacketSource::getQueueDurationUs(bool *eos) { 713c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber Mutex::Autolock autoLock(mLock); 714c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber 715c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber *eos = (mEOSResult != OK); 716c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber 717c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber if (mBuffers.size() < 2) { 718c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber return 0; 719c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber } 720c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber 721c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber const sp<ABuffer> first = *mBuffers.begin(); 722c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber const sp<ABuffer> last = *--mBuffers.end(); 723c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber 724c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber int64_t firstTimeUs; 725c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber CHECK(first->meta()->findInt64("timeUs", &firstTimeUs)); 726c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber 727c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber int64_t lastTimeUs; 728c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber CHECK(last->meta()->findInt64("timeUs", &lastTimeUs)); 729c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber 7306f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber if (lastTimeUs < firstTimeUs) { 7316e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGE("Huh? Time moving backwards? %lld > %lld", 7326e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber firstTimeUs, lastTimeUs); 7336e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber 7346f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber return 0; 7356f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber } 736c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber 737c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber return lastTimeUs - firstTimeUs; 738c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber} 739c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber 740cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} // namespace android 741