APacketSource.cpp revision 4dba3e90f211eb5f5af19b10c5d3fc8c967b0086
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 2562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber#include <media/stagefright/foundation/ABitReader.h> 26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h> 28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h> 29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h> 30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/base64.h> 31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/hexdump.h> 32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaBuffer.h> 33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MediaDefs.h> 34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/MetaData.h> 35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <utils/Vector.h> 36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android { 38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic bool GetAttribute(const char *s, const char *key, AString *value) { 40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value->clear(); 41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t keyLen = strlen(key); 43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (;;) { 45ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber while (isspace(*s)) { 46ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber ++s; 47ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 48ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber 49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const char *colonPos = strchr(s, ';'); 50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t len = 52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (colonPos == NULL) ? strlen(s) : colonPos - s; 53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) { 55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value->setTo(&s[keyLen + 1], len - keyLen - 1); 56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return true; 57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (colonPos == NULL) { 60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber s = colonPos + 1; 64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic sp<ABuffer> decodeHex(const AString &s) { 68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((s.size() % 2) != 0) { 69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return NULL; 70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t outLen = s.size() / 2; 73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> buffer = new ABuffer(outLen); 74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t *out = buffer->data(); 75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t accum = 0; 77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < s.size(); ++i) { 78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char c = s.c_str()[i]; 79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned value; 80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (c >= '0' && c <= '9') { 81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - '0'; 82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (c >= 'a' && c <= 'f') { 83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - 'a' + 10; 84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (c >= 'A' && c <= 'F') { 85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber value = c - 'A' + 10; 86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return NULL; 88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber accum = (accum << 4) | value; 91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (i & 1) { 93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = accum; 94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber accum = 0; 96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return buffer; 100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 10285f12e9b9062402d6110df3f7099707912040edbAndreas Huberstatic sp<ABuffer> MakeAVCCodecSpecificData( 10385f12e9b9062402d6110df3f7099707912040edbAndreas Huber const char *params, int32_t *width, int32_t *height) { 10485f12e9b9062402d6110df3f7099707912040edbAndreas Huber *width = 0; 10585f12e9b9062402d6110df3f7099707912040edbAndreas Huber *height = 0; 10685f12e9b9062402d6110df3f7099707912040edbAndreas Huber 107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString val; 10833a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (!GetAttribute(params, "profile-level-id", &val)) { 10933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber return NULL; 11033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> profileLevelID = decodeHex(val); 113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(profileLevelID != NULL); 114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ(profileLevelID->size(), 3u); 115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Vector<sp<ABuffer> > paramSets; 117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t numSeqParameterSets = 0; 119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t totalSeqParameterSetSize = 0; 120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t numPicParameterSets = 0; 121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t totalPicParameterSetSize = 0; 122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 12333a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (!GetAttribute(params, "sprop-parameter-sets", &val)) { 12433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber return NULL; 12533a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 12633a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber 127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t start = 0; 128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (;;) { 129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ssize_t commaPos = val.find(",", start); 130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t end = (commaPos < 0) ? val.size() : commaPos; 131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString nalString(val, start, end - start); 133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = decodeBase64(nalString); 134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(nal != NULL); 135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GT(nal->size(), 0u); 136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LE(nal->size(), 65535u); 137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t nalType = nal->data()[0] & 0x1f; 139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (numSeqParameterSets == 0) { 140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 7u); 141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (numPicParameterSets > 0) { 142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 8u); 143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (nalType == 7) { 145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++numSeqParameterSets; 146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber totalSeqParameterSetSize += nal->size(); 147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ((unsigned)nalType, 8u); 149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++numPicParameterSets; 150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber totalPicParameterSetSize += nal->size(); 151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber paramSets.push(nal); 154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (commaPos < 0) { 156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber start = commaPos + 1; 160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LT(numSeqParameterSets, 32u); 163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_LE(numPicParameterSets, 255u); 164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t csdSize = 166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 1 + 3 + 1 + 1 167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber + 2 * numSeqParameterSets + totalSeqParameterSetSize 168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber + 1 + 2 * numPicParameterSets + totalPicParameterSetSize; 169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> csd = new ABuffer(csdSize); 171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint8_t *out = csd->data(); 172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = 0x01; // configurationVersion 174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, profileLevelID->data(), 3); 175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += 3; 176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes 177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = 0xe0 | numSeqParameterSets; 178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = paramSets.editItemAt(i); 181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() >> 8; 183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() & 0xff; 184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, nal->data(), nal->size()); 186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += nal->size(); 18885f12e9b9062402d6110df3f7099707912040edbAndreas Huber 18985f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (i == 0) { 19085f12e9b9062402d6110df3f7099707912040edbAndreas Huber FindAVCDimensions(nal, width, height); 19185f12e9b9062402d6110df3f7099707912040edbAndreas Huber LOG(INFO) << "dimensions " << *width << "x" << *height; 19285f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = numPicParameterSets; 196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < numPicParameterSets; ++i) { 198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets); 199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() >> 8; 201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out++ = nal->size() & 0xff; 202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(out, nal->data(), nal->size()); 204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber out += nal->size(); 206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 20885f12e9b9062402d6110df3f7099707912040edbAndreas Huber // hexdump(csd->data(), csd->size()); 209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return csd; 211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<ABuffer> MakeAACCodecSpecificData(const char *params) { 214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString val; 215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(GetAttribute(params, "config", &val)); 216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> config = decodeHex(val); 218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(config != NULL); 219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(config->size(), 4u); 220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = config->data(); 222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber x = (x >> 1) & 0xffff; 224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber static const uint8_t kStaticESDS[] = { 226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x03, 22, 227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, // ES_ID 228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x04, 17, 231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x40, // Audio ISO/IEC 14496-3 232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x00, 0x00, 0x00, 0x00, 235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0x05, 2, 237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // AudioSpecificInfo follows 238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber }; 239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2); 241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS)); 242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff; 243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff; 244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 24585f12e9b9062402d6110df3f7099707912040edbAndreas Huber // hexdump(csd->data(), csd->size()); 246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return csd; 248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 2504dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber// From mpeg4-generic configuration data. 2514dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Hubersp<ABuffer> MakeAACCodecSpecificData2(const char *params) { 2524dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber AString val; 2534dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber unsigned long objectType; 2544dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber if (GetAttribute(params, "objectType", &val)) { 2554dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber const char *s = val.c_str(); 2564dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber char *end; 2574dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber objectType = strtoul(s, &end, 10); 2584dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber CHECK(end > s && *end == '\0'); 2594dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber } else { 2604dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber objectType = 0x40; // Audio ISO/IEC 14496-3 2614dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber } 2624dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2634dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber CHECK(GetAttribute(params, "config", &val)); 2644dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2654dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber sp<ABuffer> config = decodeHex(val); 2664dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber CHECK(config != NULL); 2674dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2684dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber // Make sure size fits into a single byte and doesn't have to 2694dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber // be encoded. 2704dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber CHECK_LT(20 + config->size(), 128u); 2714dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2724dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber const uint8_t *data = config->data(); 2734dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2744dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber static const uint8_t kStaticESDS[] = { 2754dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x03, 22, 2764dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, 0x00, // ES_ID 2774dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 2784dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2794dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x04, 17, 2804dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x40, // Audio ISO/IEC 14496-3 2814dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, 0x00, 0x00, 0x00, 2824dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, 0x00, 0x00, 0x00, 2834dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x00, 0x00, 0x00, 0x00, 2844dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2854dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 0x05, 2, 2864dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber // AudioSpecificInfo follows 2874dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber }; 2884dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 2894dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size()); 2904dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber uint8_t *dst = csd->data(); 2914dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x03; 2924dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 20 + config->size(); 2934dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x00; // ES_ID 2944dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x00; 2954dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 2964dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x04; 2974dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 15 + config->size(); 2984dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = objectType; 2994dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber for (int i = 0; i < 12; ++i) { *dst++ = 0x00; } 3004dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = 0x05; 3014dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber *dst++ = config->size(); 3024dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber memcpy(dst, config->data(), config->size()); 3034dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 3044dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber // hexdump(csd->data(), csd->size()); 3054dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 3064dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber return csd; 3074dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber} 3084dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 30962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic size_t GetSizeWidth(size_t x) { 31062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t n = 1; 31162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber while (x > 127) { 31262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber ++n; 31362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber x >>= 7; 31462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 31562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return n; 31662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber} 31762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 31862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic uint8_t *EncodeSize(uint8_t *dst, size_t x) { 31962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber while (x > 127) { 32062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = (x & 0x7f) | 0x80; 32162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber x >>= 7; 32262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 32362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = x; 32462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return dst; 32562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber} 32662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 32762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huberstatic bool ExtractDimensionsFromVOLHeader( 32862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber const sp<ABuffer> &config, int32_t *width, int32_t *height) { 32962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *width = 0; 33062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *height = 0; 33162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 33262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber const uint8_t *ptr = config->data(); 33362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t offset = 0; 33462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber bool foundVOL = false; 33562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber while (offset + 3 < config->size()) { 33662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (memcmp("\x00\x00\x01", &ptr[offset], 3) 33762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber || (ptr[offset + 3] & 0xf0) != 0x20) { 33862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber ++offset; 33962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber continue; 34062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 34162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 34262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber foundVOL = true; 34362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber break; 34462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 34562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 34662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (!foundVOL) { 34762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return false; 34862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 34962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 35062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber ABitReader br(&ptr[offset + 4], config->size() - offset - 4); 35162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber br.skipBits(1); // random_accessible_vol 35262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned video_object_type_indication = br.getBits(8); 35362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 35462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK_NE(video_object_type_indication, 35562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 0x21u /* Fine Granularity Scalable */); 35662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 35762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned video_object_layer_verid; 35862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned video_object_layer_priority; 35962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (br.getBits(1)) { 36062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber video_object_layer_verid = br.getBits(4); 36162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber video_object_layer_priority = br.getBits(3); 36262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 36362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned aspect_ratio_info = br.getBits(4); 36462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (aspect_ratio_info == 0x0f /* extended PAR */) { 36562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber br.skipBits(8); // par_width 36662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber br.skipBits(8); // par_height 36762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 36862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (br.getBits(1)) { // vol_control_parameters 36962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber br.skipBits(2); // chroma_format 37062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber br.skipBits(1); // low_delay 37162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (br.getBits(1)) { // vbv_parameters 37262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber TRESPASS(); 37362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 37462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 37562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned video_object_layer_shape = br.getBits(2); 37662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */); 37762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 37862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(br.getBits(1)); // marker_bit 37962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned vop_time_increment_resolution = br.getBits(16); 38062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(br.getBits(1)); // marker_bit 38162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 38262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (br.getBits(1)) { // fixed_vop_rate 38362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // range [0..vop_time_increment_resolution) 38462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 38562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // vop_time_increment_resolution 38662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // 2 => 0..1, 1 bit 38762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // 3 => 0..2, 2 bits 38862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // 4 => 0..3, 2 bits 38962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // 5 => 0..4, 3 bits 39062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // ... 39162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 39262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK_GT(vop_time_increment_resolution, 0u); 39362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber --vop_time_increment_resolution; 39462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 39562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned numBits = 0; 39662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber while (vop_time_increment_resolution > 0) { 39762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber ++numBits; 39862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber vop_time_increment_resolution >>= 1; 39962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 40062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 40162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber br.skipBits(numBits); // fixed_vop_time_increment 40262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 40362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 40462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(br.getBits(1)); // marker_bit 40562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned video_object_layer_width = br.getBits(13); 40662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(br.getBits(1)); // marker_bit 40762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned video_object_layer_height = br.getBits(13); 40862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(br.getBits(1)); // marker_bit 40962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 41062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber unsigned interlaced = br.getBits(1); 41162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 41262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *width = video_object_layer_width; 41362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *height = video_object_layer_height; 41462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 41562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber LOG(INFO) << "VOL dimensions = " << *width << "x" << *height; 41662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 41762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return true; 41862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber} 41962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 42062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Hubersp<ABuffer> MakeMPEG4VideoCodecSpecificData( 42162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber const char *params, int32_t *width, int32_t *height) { 42262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *width = 0; 42362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *height = 0; 42462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 42562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber AString val; 42662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(GetAttribute(params, "config", &val)); 42762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 42862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber sp<ABuffer> config = decodeHex(val); 42962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber CHECK(config != NULL); 43062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 43162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (!ExtractDimensionsFromVOLHeader(config, width, height)) { 43262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return NULL; 43362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 43462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 43562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t len1 = config->size() + GetSizeWidth(config->size()) + 1; 43662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13; 43762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3; 43862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 43962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber sp<ABuffer> csd = new ABuffer(len3); 44062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber uint8_t *dst = csd->data(); 44162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x03; 44262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber dst = EncodeSize(dst, len2 + 3); 44362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x00; // ES_ID 44462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x00; 44562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 44662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 44762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x04; 44862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber dst = EncodeSize(dst, len1 + 13); 44962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile 45062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber for (size_t i = 0; i < 12; ++i) { 45162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x00; 45262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 45362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 45462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber *dst++ = 0x05; 45562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber dst = EncodeSize(dst, config->size()); 45662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber memcpy(dst, config->data(), config->size()); 45762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber dst += config->size(); 45862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 45962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber // hexdump(csd->data(), csd->size()); 46062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 46162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return csd; 46262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber} 46362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 4648d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberstatic bool GetClockRate(const AString &desc, uint32_t *clockRate) { 4658d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber ssize_t slashPos = desc.find("/"); 4668d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber if (slashPos < 0) { 4678d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return false; 4688d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber } 4698d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4708d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber const char *s = desc.c_str() + slashPos + 1; 4718d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4728d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber char *end; 4738d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber unsigned long x = strtoul(s, &end, 10); 4748d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4758d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber if (end == s || (*end != '\0' && *end != '/')) { 4768d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return false; 4778d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber } 4788d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4798d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber *clockRate = x; 4808d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 4818d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return true; 4828d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 4838d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 484cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::APacketSource( 485cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ASessionDescription> &sessionDesc, size_t index) 48639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber : mInitCheck(NO_INIT), 48739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat(new MetaData), 4888d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mEOSResult(OK), 4898d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mRTPTimeBase(0), 4908d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mNormalPlayTimeBaseUs(0), 4918d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mLastNormalPlayTimeUs(0) { 492cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned long PT; 493cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString desc; 494cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString params; 495cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 496cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 4978d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber CHECK(GetClockRate(desc, &mClockRate)); 4988d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 499cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int64_t durationUs; 500cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (sessionDesc->getDurationUs(&durationUs)) { 501cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt64(kKeyDuration, durationUs); 502cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 503cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt64(kKeyDuration, 60 * 60 * 1000000ll); 504cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 505cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 50639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = OK; 507cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!strncmp(desc.c_str(), "H264/", 5)) { 508cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 509cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 510cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t width, height; 511ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 51285f12e9b9062402d6110df3f7099707912040edbAndreas Huber width = -1; 51385f12e9b9062402d6110df3f7099707912040edbAndreas Huber height = -1; 514ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 515cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 51685f12e9b9062402d6110df3f7099707912040edbAndreas Huber int32_t encWidth, encHeight; 517cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> codecSpecificData = 51885f12e9b9062402d6110df3f7099707912040edbAndreas Huber MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight); 519cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 52033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber if (codecSpecificData != NULL) { 52185f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (width < 0) { 52285f12e9b9062402d6110df3f7099707912040edbAndreas Huber // If no explicit width/height given in the sdp, use the dimensions 52385f12e9b9062402d6110df3f7099707912040edbAndreas Huber // extracted from the first sequence parameter set. 52485f12e9b9062402d6110df3f7099707912040edbAndreas Huber width = encWidth; 52585f12e9b9062402d6110df3f7099707912040edbAndreas Huber height = encHeight; 52685f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 52785f12e9b9062402d6110df3f7099707912040edbAndreas Huber 52833a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber mFormat->setData( 52933a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber kKeyAVCC, 0, 53033a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber codecSpecificData->data(), codecSpecificData->size()); 53185f12e9b9062402d6110df3f7099707912040edbAndreas Huber } else if (width < 0) { 53285f12e9b9062402d6110df3f7099707912040edbAndreas Huber mInitCheck = ERROR_UNSUPPORTED; 53385f12e9b9062402d6110df3f7099707912040edbAndreas Huber return; 53433a8457868eb00b94b37b53321a80d9307202a9dAndreas Huber } 53585f12e9b9062402d6110df3f7099707912040edbAndreas Huber 53685f12e9b9062402d6110df3f7099707912040edbAndreas Huber mFormat->setInt32(kKeyWidth, width); 53785f12e9b9062402d6110df3f7099707912040edbAndreas Huber mFormat->setInt32(kKeyHeight, height); 53839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "H263-2000/", 10) 53939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber || !strncmp(desc.c_str(), "H263-1998/", 10)) { 54039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 541cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 54239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t width, height; 543ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 544ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 545ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber return; 546ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 54739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 54839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyWidth, width); 54939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyHeight, height); 55039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) { 551cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 552cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 553cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t sampleRate, numChannels; 554cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ASessionDescription::ParseFormatDesc( 555cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber desc.c_str(), &sampleRate, &numChannels); 556cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 557cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 558cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 559cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 560cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> codecSpecificData = 561cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MakeAACCodecSpecificData(params.c_str()); 562cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 563cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mFormat->setData( 564cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber kKeyESDS, 0, 565cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber codecSpecificData->data(), codecSpecificData->size()); 56639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "AMR/", 4)) { 56739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB); 56839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 56939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t sampleRate, numChannels; 57039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ASessionDescription::ParseFormatDesc( 57139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber desc.c_str(), &sampleRate, &numChannels); 57239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 57339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 57439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 57539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 57639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (sampleRate != 8000 || numChannels != 1) { 57739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 57839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 57939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { 58039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB); 58139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 58239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t sampleRate, numChannels; 58339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ASessionDescription::ParseFormatDesc( 58439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber desc.c_str(), &sampleRate, &numChannels); 58539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 58639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 58739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 58839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 58939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (sampleRate != 16000 || numChannels != 1) { 59039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 59139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 59262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) { 59362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 59462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 59562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber int32_t width, height; 59662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (!sessionDesc->getDimensions(index, PT, &width, &height)) { 59762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber width = -1; 59862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber height = -1; 59962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 60062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 60162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber int32_t encWidth, encHeight; 60262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber sp<ABuffer> codecSpecificData = 60362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber MakeMPEG4VideoCodecSpecificData( 60462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber params.c_str(), &encWidth, &encHeight); 60562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 60662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (codecSpecificData != NULL) { 60762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mFormat->setData( 60862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber kKeyESDS, 0, 60962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber codecSpecificData->data(), codecSpecificData->size()); 61062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 61162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber if (width < 0) { 61262cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber width = encWidth; 61362cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber height = encHeight; 61462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 61562cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } else if (width < 0) { 61662cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 61762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber return; 61862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber } 61962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 62062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mFormat->setInt32(kKeyWidth, width); 62162cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mFormat->setInt32(kKeyHeight, height); 6224dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) { 6234dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber AString val; 6244dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber if (!GetAttribute(params.c_str(), "mode", &val) 6254dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber || (strcasecmp(val.c_str(), "AAC-lbr") 6264dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber && strcasecmp(val.c_str(), "AAC-hbr"))) { 6274dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 6284dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber return; 6294dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber } 6304dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 6314dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 6324dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 6334dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber int32_t sampleRate, numChannels; 6344dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber ASessionDescription::ParseFormatDesc( 6354dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber desc.c_str(), &sampleRate, &numChannels); 6364dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 6374dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mFormat->setInt32(kKeySampleRate, sampleRate); 6384dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mFormat->setInt32(kKeyChannelCount, numChannels); 6394dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 6404dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber sp<ABuffer> codecSpecificData = 6414dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber MakeAACCodecSpecificData2(params.c_str()); 6424dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber 6434dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mFormat->setData( 6444dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber kKeyESDS, 0, 6454dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber codecSpecificData->data(), codecSpecificData->size()); 646cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 64739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mInitCheck = ERROR_UNSUPPORTED; 648cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 649cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 650cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 651cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAPacketSource::~APacketSource() { 652cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 653cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 65439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t APacketSource::initCheck() const { 65539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return mInitCheck; 65639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 65739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 658cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::start(MetaData *params) { 659cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 660cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 661cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 662cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::stop() { 663cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 664cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 665cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 666cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubersp<MetaData> APacketSource::getFormat() { 667cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return mFormat; 668cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 669cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 670cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t APacketSource::read( 671cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MediaBuffer **out, const ReadOptions *) { 672cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out = NULL; 673cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 674cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 675cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (mEOSResult == OK && mBuffers.empty()) { 676cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.wait(mLock); 677cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 678cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 679cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!mBuffers.empty()) { 680cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ABuffer> buffer = *mBuffers.begin(); 681cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 6828d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber updateNormalPlayTime_l(buffer); 6838d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 68439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size()); 68539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 686f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber int64_t timeUs; 687f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 688cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 689cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs); 69039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 691cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memcpy(mediaBuffer->data(), buffer->data(), buffer->size()); 692cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *out = mediaBuffer; 693cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 694cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mBuffers.erase(mBuffers.begin()); 695cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 696cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 697cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 698cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return mEOSResult; 699cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 700cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 7018d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid APacketSource::updateNormalPlayTime_l(const sp<ABuffer> &buffer) { 7028d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber uint32_t rtpTime; 7038d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 7048d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 7058d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mLastNormalPlayTimeUs = 7068d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber (((double)rtpTime - (double)mRTPTimeBase) / mClockRate) 7078d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber * 1000000ll 7088d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber + mNormalPlayTimeBaseUs; 7098d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 7108d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 711cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::queueAccessUnit(const sp<ABuffer> &buffer) { 712cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t damaged; 713cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (buffer->meta()->findInt32("damaged", &damaged) && damaged) { 7146dc387a8c3f031f9f17d1138295368946563f7a5Andreas Huber LOG(VERBOSE) << "discarding damaged AU"; 715cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 716cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 717cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 718cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 719cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mBuffers.push_back(buffer); 720cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.signal(); 721cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 722cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 723cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid APacketSource::signalEOS(status_t result) { 724cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(result != OK); 725cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 726cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber Mutex::Autolock autoLock(mLock); 727cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mEOSResult = result; 728cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mCondition.signal(); 729cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 730cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 731cce326fe43411855aca2f719e505b051bc4b61b3Andreas Hubervoid APacketSource::flushQueue() { 73239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 733cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber mBuffers.clear(); 73439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 73539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 7368d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberint64_t APacketSource::getNormalPlayTimeUs() { 7378d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber Mutex::Autolock autoLock(mLock); 7388d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return mLastNormalPlayTimeUs; 7398d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 7408d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 7418d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid APacketSource::setNormalPlayTimeMapping( 7428d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber uint32_t rtpTime, int64_t normalPlayTimeUs) { 7438d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber Mutex::Autolock autoLock(mLock); 7448d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 7458d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mRTPTimeBase = rtpTime; 7468d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber mNormalPlayTimeBaseUs = normalPlayTimeUs; 7478d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 7488d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 749cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} // namespace android 750