16e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber/* 26e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * Copyright (C) 2010 The Android Open Source Project 36e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * 46e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 56e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * you may not use this file except in compliance with the License. 66e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * You may obtain a copy of the License at 76e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * 86e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 96e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * 106e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * Unless required by applicable law or agreed to in writing, software 116e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 126e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * See the License for the specific language governing permissions and 146e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber * limitations under the License. 156e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber */ 166e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber 176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0 186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "ARTPWriter" 196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h> 206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber 2139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "ARTPWriter.h" 2239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 2339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <fcntl.h> 2439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 2539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 2639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/ADebug.h> 2739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/AMessage.h> 2839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/hexdump.h> 2939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/MediaBuffer.h> 3039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/MediaDefs.h> 3139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/MediaSource.h> 3239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/MetaData.h> 3339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <utils/ByteOrder.h> 3439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 3539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#define PT 97 3639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#define PT_STR "97" 3739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 3839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubernamespace android { 3939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 4039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber// static const size_t kMaxPacketSize = 65507; // maximum payload in UDP over IP 4139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic const size_t kMaxPacketSize = 1500; 4239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 4339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic int UniformRand(int limit) { 4439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return ((double)rand() * limit) / RAND_MAX; 4539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 4639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 4739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberARTPWriter::ARTPWriter(int fd) 4839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber : mFlags(0), 49674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd(dup(fd)), 5039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLooper(new ALooper), 5139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mReflector(new AHandlerReflector<ARTPWriter>(this)) { 5239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_GE(fd, 0); 5339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 54a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mLooper->setName("rtp writer"); 5539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLooper->registerHandler(mReflector); 5639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLooper->start(); 5739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 5839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mSocket = socket(AF_INET, SOCK_DGRAM, 0); 5939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_GE(mSocket, 0); 6039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 6139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memset(mRTPAddr.sin_zero, 0, sizeof(mRTPAddr.sin_zero)); 6239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTPAddr.sin_family = AF_INET; 6339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 6439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if 1 6539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTPAddr.sin_addr.s_addr = INADDR_ANY; 6639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#else 67a6238a1e5b603ca2ccf3b2297c9bc8a141cf8559Andreas Huber mRTPAddr.sin_addr.s_addr = inet_addr("172.19.18.246"); 6839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif 6939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 7039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTPAddr.sin_port = htons(5634); 7139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(0, ntohs(mRTPAddr.sin_port) & 1); 7239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 7339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTCPAddr = mRTPAddr; 7439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTCPAddr.sin_port = htons(ntohs(mRTPAddr.sin_port) | 1); 7539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 7639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if LOG_TO_FILES 7739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTPFd = open( 7839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "/data/misc/rtpout.bin", 7939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber O_WRONLY | O_CREAT | O_TRUNC, 8039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 0644); 8139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_GE(mRTPFd, 0); 8239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 8339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTCPFd = open( 8439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "/data/misc/rtcpout.bin", 8539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber O_WRONLY | O_CREAT | O_TRUNC, 8639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 0644); 8739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_GE(mRTCPFd, 0); 8839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif 8939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 9039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 9139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberARTPWriter::~ARTPWriter() { 9239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if LOG_TO_FILES 9339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber close(mRTCPFd); 9439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTCPFd = -1; 9539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 9639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber close(mRTPFd); 9739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTPFd = -1; 9839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif 9939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 10039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber close(mSocket); 10139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mSocket = -1; 10239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 10339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber close(mFd); 10439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFd = -1; 10539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 10639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 10739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t ARTPWriter::addSource(const sp<MediaSource> &source) { 10839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mSource = source; 10939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return OK; 11039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 11139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 11239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberbool ARTPWriter::reachedEOS() { 11339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 11439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return (mFlags & kFlagEOS) != 0; 11539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 11639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 11739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t ARTPWriter::start(MetaData *params) { 11839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 11939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mFlags & kFlagStarted) { 12039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return INVALID_OPERATION; 12139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 12239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 12339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFlags &= ~kFlagEOS; 12439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mSourceID = rand(); 12539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mSeqNo = UniformRand(65536); 12639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mRTPTimeBase = rand(); 12739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mNumRTPSent = 0; 12839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mNumRTPOctetsSent = 0; 12939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastRTPTime = 0; 13039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastNTPTime = 0; 13139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mNumSRsSent = 0; 13239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 13339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber const char *mime; 13439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 13539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 13639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mMode = INVALID; 13739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 13839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mMode = H264; 13939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { 14039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mMode = H263; 14139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 14239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mMode = AMR_NB; 14339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 14439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mMode = AMR_WB; 14539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else { 14639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber TRESPASS(); 14739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 14839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 14939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (new AMessage(kWhatStart, mReflector->id()))->post(); 15039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 15139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber while (!(mFlags & kFlagStarted)) { 15239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mCondition.wait(mLock); 15339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 15439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 15539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return OK; 15639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 15739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 15837187916a486504acaf83bea30147eb5fbf46ae5James Dongstatus_t ARTPWriter::stop() { 15939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 16039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (!(mFlags & kFlagStarted)) { 16137187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 16239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 16339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 16439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (new AMessage(kWhatStop, mReflector->id()))->post(); 16539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 16639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber while (mFlags & kFlagStarted) { 16739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mCondition.wait(mLock); 16839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 16937187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 17039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 17139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 17237187916a486504acaf83bea30147eb5fbf46ae5James Dongstatus_t ARTPWriter::pause() { 17337187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 17439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 17539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 17639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic void StripStartcode(MediaBuffer *buffer) { 17739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (buffer->range_length() < 4) { 17839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return; 17939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 18039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 18139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber const uint8_t *ptr = 18239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 18339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 18439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) { 18539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->set_range( 18639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->range_offset() + 4, buffer->range_length() - 4); 18739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 18839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 18939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 19039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::onMessageReceived(const sp<AMessage> &msg) { 19139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber switch (msg->what()) { 19239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case kWhatStart: 19339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 19439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(mSource->start(), (status_t)OK); 19539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 19639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if 0 19739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mMode == H264) { 19839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber MediaBuffer *buffer; 19939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(mSource->read(&buffer), (status_t)OK); 20039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 20139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber StripStartcode(buffer); 20239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber makeH264SPropParamSets(buffer); 20339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->release(); 20439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer = NULL; 20539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 20639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 20739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber dumpSessionDesc(); 20839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif 20939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 21039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 21139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 21239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFlags |= kFlagStarted; 21339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mCondition.signal(); 21439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 21539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 21639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (new AMessage(kWhatRead, mReflector->id()))->post(); 21739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (new AMessage(kWhatSendSR, mReflector->id()))->post(); 21839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 21939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 22039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 22139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case kWhatStop: 22239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 22339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(mSource->stop(), (status_t)OK); 22439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 22539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sendBye(); 22639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 22739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 22839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 22939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFlags &= ~kFlagStarted; 23039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mCondition.signal(); 23139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 23239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 23339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 23439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 23539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case kWhatRead: 23639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 23739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 23839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 23939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (!(mFlags & kFlagStarted)) { 24039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 24139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 24239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 24339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 24439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber onRead(msg); 24539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 24639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 24739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 24839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case kWhatSendSR: 24939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 25039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 25139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 25239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (!(mFlags & kFlagStarted)) { 25339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 25439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 25539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 25639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 25739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber onSendSR(msg); 25839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 25939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 26039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 26139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber default: 26239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber TRESPASS(); 26339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 26439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 26539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 26639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 26739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::onRead(const sp<AMessage> &msg) { 26839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber MediaBuffer *mediaBuf; 26939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber status_t err = mSource->read(&mediaBuf); 27039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 27139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (err != OK) { 272df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("reached EOS."); 27339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 27439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Mutex::Autolock autoLock(mLock); 27539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mFlags |= kFlagEOS; 27639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return; 27739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 27839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 27939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mediaBuf->range_length() > 0) { 2803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("read buffer of size %d", mediaBuf->range_length()); 28139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 28239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mMode == H264) { 28339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber StripStartcode(mediaBuf); 28439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sendAVCData(mediaBuf); 28539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (mMode == H263) { 28639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sendH263Data(mediaBuf); 28739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (mMode == AMR_NB || mMode == AMR_WB) { 28839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sendAMRData(mediaBuf); 28939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 29039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 29139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 29239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mediaBuf->release(); 29339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mediaBuf = NULL; 29439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 29539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber msg->post(); 29639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 29739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 29839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::onSendSR(const sp<AMessage> &msg) { 29939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ABuffer> buffer = new ABuffer(65536); 30039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(0, 0); 30139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 30239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber addSR(buffer); 30339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber addSDES(buffer); 30439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 30539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber send(buffer, true /* isRTCP */); 30639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 30739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mNumSRsSent; 30839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber msg->post(3000000); 30939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 31039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 31139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::send(const sp<ABuffer> &buffer, bool isRTCP) { 31239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ssize_t n = sendto( 31339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mSocket, buffer->data(), buffer->size(), 0, 31439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (const struct sockaddr *)(isRTCP ? &mRTCPAddr : &mRTPAddr), 31539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sizeof(mRTCPAddr)); 31639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 31739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(n, (ssize_t)buffer->size()); 31839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 31939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if LOG_TO_FILES 32039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int fd = isRTCP ? mRTCPFd : mRTPFd; 32139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 32239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t ms = tolel(ALooper::GetNowUs() / 1000ll); 32339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t length = tolel(buffer->size()); 32439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber write(fd, &ms, sizeof(ms)); 32539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber write(fd, &length, sizeof(length)); 32639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber write(fd, buffer->data(), buffer->size()); 32739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif 32839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 32939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 33039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::addSR(const sp<ABuffer> &buffer) { 33139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data() + buffer->size(); 33239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 33339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[0] = 0x80 | 0; 33439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] = 200; // SR 33539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[2] = 0; 33639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[3] = 6; 33739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[4] = mSourceID >> 24; 33839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[5] = (mSourceID >> 16) & 0xff; 33939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[6] = (mSourceID >> 8) & 0xff; 34039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[7] = mSourceID & 0xff; 34139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 34239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[8] = mLastNTPTime >> (64 - 8); 34339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[9] = (mLastNTPTime >> (64 - 16)) & 0xff; 34439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[10] = (mLastNTPTime >> (64 - 24)) & 0xff; 34539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[11] = (mLastNTPTime >> 32) & 0xff; 34639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[12] = (mLastNTPTime >> 24) & 0xff; 34739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[13] = (mLastNTPTime >> 16) & 0xff; 34839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[14] = (mLastNTPTime >> 8) & 0xff; 34939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[15] = mLastNTPTime & 0xff; 35039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 35139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[16] = (mLastRTPTime >> 24) & 0xff; 35239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[17] = (mLastRTPTime >> 16) & 0xff; 35339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[18] = (mLastRTPTime >> 8) & 0xff; 35439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[19] = mLastRTPTime & 0xff; 35539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 35639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[20] = mNumRTPSent >> 24; 35739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[21] = (mNumRTPSent >> 16) & 0xff; 35839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[22] = (mNumRTPSent >> 8) & 0xff; 35939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[23] = mNumRTPSent & 0xff; 36039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 36139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[24] = mNumRTPOctetsSent >> 24; 36239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[25] = (mNumRTPOctetsSent >> 16) & 0xff; 36339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[26] = (mNumRTPOctetsSent >> 8) & 0xff; 36439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[27] = mNumRTPOctetsSent & 0xff; 36539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 36639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(buffer->offset(), buffer->size() + 28); 36739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 36839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 36939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::addSDES(const sp<ABuffer> &buffer) { 37039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data() + buffer->size(); 37139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[0] = 0x80 | 1; 37239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] = 202; // SDES 37339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[4] = mSourceID >> 24; 37439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[5] = (mSourceID >> 16) & 0xff; 37539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[6] = (mSourceID >> 8) & 0xff; 37639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[7] = mSourceID & 0xff; 37739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 37839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t offset = 8; 37939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 38039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[offset++] = 1; // CNAME 38139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 38239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber static const char *kCNAME = "someone@somewhere"; 38339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[offset++] = strlen(kCNAME); 38439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 38539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memcpy(&data[offset], kCNAME, strlen(kCNAME)); 38639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber offset += strlen(kCNAME); 38739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 38839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[offset++] = 7; // NOTE 38939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 39039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber static const char *kNOTE = "Hell's frozen over."; 39139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[offset++] = strlen(kNOTE); 39239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 39339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memcpy(&data[offset], kNOTE, strlen(kNOTE)); 39439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber offset += strlen(kNOTE); 39539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 39639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[offset++] = 0; 39739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 39839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if ((offset % 4) > 0) { 39939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t count = 4 - (offset % 4); 40039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber switch (count) { 40139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 3: 40239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[offset++] = 0; 40339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 2: 40439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[offset++] = 0; 40539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 1: 40639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[offset++] = 0; 40739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 40839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 40939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 41039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t numWords = (offset / 4) - 1; 41139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[2] = numWords >> 8; 41239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[3] = numWords & 0xff; 41339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 41439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(buffer->offset(), buffer->size() + offset); 41539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 41639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 41739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber// static 41839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberuint64_t ARTPWriter::GetNowNTP() { 41939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint64_t nowUs = ALooper::GetNowUs(); 42039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 42139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll; 42239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 42339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint64_t hi = nowUs / 1000000ll; 42439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll; 42539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 42639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return (hi << 32) | lo; 42739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 42839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 42939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::dumpSessionDesc() { 43039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber AString sdp; 43139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp = "v=0\r\n"; 43239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 43339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("o=- "); 43439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 43539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint64_t ntp = GetNowNTP(); 43639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(ntp); 43739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(" "); 43839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(ntp); 43939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(" IN IP4 127.0.0.0\r\n"); 44039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 44139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append( 44239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "s=Sample\r\n" 44339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "i=Playing around\r\n" 44439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "c=IN IP4 "); 44539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 44639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber struct in_addr addr; 44739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber addr.s_addr = ntohl(INADDR_LOOPBACK); 44839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 44939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(inet_ntoa(addr)); 45039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 45139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append( 45239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "\r\n" 45339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "t=0 0\r\n" 45439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "a=range:npt=now-\r\n"); 45539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 45639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<MetaData> meta = mSource->getFormat(); 45739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 45839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mMode == H264 || mMode == H263) { 45939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("m=video "); 46039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else { 46139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("m=audio "); 46239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 46339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 46439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(StringPrintf("%d", ntohs(mRTPAddr.sin_port))); 46539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append( 46639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber " RTP/AVP " PT_STR "\r\n" 46739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "b=AS 320000\r\n" 46839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "a=rtpmap:" PT_STR " "); 46939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 47039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mMode == H264) { 47139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("H264/90000"); 47239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (mMode == H263) { 47339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("H263-1998/90000"); 47439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (mMode == AMR_NB || mMode == AMR_WB) { 47539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t sampleRate, numChannels; 47639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(mSource->getFormat()->findInt32(kKeySampleRate, &sampleRate)); 47739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(mSource->getFormat()->findInt32(kKeyChannelCount, &numChannels)); 47839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 47939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(numChannels, 1); 48039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(sampleRate, (mMode == AMR_NB) ? 8000 : 16000); 48139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 48239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(mMode == AMR_NB ? "AMR" : "AMR-WB"); 48339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(StringPrintf("/%d/%d", sampleRate, numChannels)); 48439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else { 48539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber TRESPASS(); 48639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 48739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 48839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("\r\n"); 48939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 49039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mMode == H264 || mMode == H263) { 49139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t width, height; 49239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 49339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 49439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 49539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("a=cliprect 0,0,"); 49639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(height); 49739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(","); 49839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(width); 49939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("\r\n"); 50039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 50139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append( 50239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "a=framesize:" PT_STR " "); 50339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(width); 50439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("-"); 50539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(height); 50639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("\r\n"); 50739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 50839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 50939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mMode == H264) { 51039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append( 51139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "a=fmtp:" PT_STR " profile-level-id="); 51239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(mProfileLevel); 51339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(";sprop-parameter-sets="); 51439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 51539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(mSeqParamSet); 51639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(","); 51739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(mPicParamSet); 51839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append(";packetization-mode=1\r\n"); 51939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (mMode == AMR_NB || mMode == AMR_WB) { 52039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sdp.append("a=fmtp:" PT_STR " octed-align\r\n"); 52139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 52239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 523df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("%s", sdp.c_str()); 52439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 52539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 52639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::makeH264SPropParamSets(MediaBuffer *buffer) { 52739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber static const char kStartCode[] = "\x00\x00\x00\x01"; 52839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 52939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber const uint8_t *data = 53039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 53139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t size = buffer->range_length(); 53239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 53339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_GE(size, 0u); 53439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 53539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t startCodePos = 0; 53639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber while (startCodePos + 3 < size 53739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber && memcmp(kStartCode, &data[startCodePos], 4)) { 53839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++startCodePos; 53939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 54039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 54139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_LT(startCodePos + 3, size); 54239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 54339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ((unsigned)data[0], 0x67u); 54439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 54539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mProfileLevel = 54639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber StringPrintf("%02X%02X%02X", data[1], data[2], data[3]); 54739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 54839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber encodeBase64(data, startCodePos, &mSeqParamSet); 54939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 55039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber encodeBase64(&data[startCodePos + 4], size - startCodePos - 4, 55139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber &mPicParamSet); 55239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 55339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 55439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::sendBye() { 55539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ABuffer> buffer = new ABuffer(8); 55639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data(); 55739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *data++ = (2 << 6) | 1; 55839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *data++ = 203; 55939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *data++ = 0; 56039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *data++ = 1; 56139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *data++ = mSourceID >> 24; 56239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *data++ = (mSourceID >> 16) & 0xff; 56339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *data++ = (mSourceID >> 8) & 0xff; 56439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *data++ = mSourceID & 0xff; 56539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(0, 8); 56639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 56739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber send(buffer, true /* isRTCP */); 56839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 56939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 57039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::sendAVCData(MediaBuffer *mediaBuf) { 57139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // 12 bytes RTP header + 2 bytes for the FU-indicator and FU-header. 57239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_GE(kMaxPacketSize, 12u + 2u); 57339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 57439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int64_t timeUs; 57539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 57639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 57739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll); 57839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 57939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber const uint8_t *mediaData = 58039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 58139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 58239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 58339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mediaBuf->range_length() + 12 <= buffer->capacity()) { 58439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // The data fits into a single packet 58539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data(); 58639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[0] = 0x80; 58739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] = (1 << 7) | PT; // M-bit 58839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[2] = (mSeqNo >> 8) & 0xff; 58939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[3] = mSeqNo & 0xff; 59039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[4] = rtpTime >> 24; 59139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 59239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 59339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[7] = rtpTime & 0xff; 59439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[8] = mSourceID >> 24; 59539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[9] = (mSourceID >> 16) & 0xff; 59639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[10] = (mSourceID >> 8) & 0xff; 59739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[11] = mSourceID & 0xff; 59839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 59939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memcpy(&data[12], 60039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mediaData, mediaBuf->range_length()); 60139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 60239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(0, mediaBuf->range_length() + 12); 60339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 60439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber send(buffer, false /* isRTCP */); 60539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 60639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mSeqNo; 60739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mNumRTPSent; 60839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mNumRTPOctetsSent += buffer->size() - 12; 60939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else { 61039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // FU-A 61139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 61239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber unsigned nalType = mediaData[0]; 61339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t offset = 1; 61439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 61539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber bool firstPacket = true; 61639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber while (offset < mediaBuf->range_length()) { 61739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t size = mediaBuf->range_length() - offset; 61839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber bool lastPacket = true; 61939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (size + 12 + 2 > buffer->capacity()) { 62039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber lastPacket = false; 62139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size = buffer->capacity() - 12 - 2; 62239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 62339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 62439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data(); 62539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[0] = 0x80; 62639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] = (lastPacket ? (1 << 7) : 0x00) | PT; // M-bit 62739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[2] = (mSeqNo >> 8) & 0xff; 62839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[3] = mSeqNo & 0xff; 62939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[4] = rtpTime >> 24; 63039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 63139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 63239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[7] = rtpTime & 0xff; 63339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[8] = mSourceID >> 24; 63439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[9] = (mSourceID >> 16) & 0xff; 63539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[10] = (mSourceID >> 8) & 0xff; 63639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[11] = mSourceID & 0xff; 63739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 63839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[12] = 28 | (nalType & 0xe0); 63939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 64039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(!firstPacket || !lastPacket); 64139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 64239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[13] = 64339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (firstPacket ? 0x80 : 0x00) 64439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber | (lastPacket ? 0x40 : 0x00) 64539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber | (nalType & 0x1f); 64639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 64739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memcpy(&data[14], &mediaData[offset], size); 64839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 64939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(0, 14 + size); 65039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 65139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber send(buffer, false /* isRTCP */); 65239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 65339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mSeqNo; 65439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mNumRTPSent; 65539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mNumRTPOctetsSent += buffer->size() - 12; 65639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 65739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber firstPacket = false; 65839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber offset += size; 65939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 66039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 66139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 66239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastRTPTime = rtpTime; 66339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastNTPTime = GetNowNTP(); 66439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 66539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 66639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::sendH263Data(MediaBuffer *mediaBuf) { 66739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_GE(kMaxPacketSize, 12u + 2u); 66839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 66939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int64_t timeUs; 67039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 67139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 67239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll); 67339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 67439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber const uint8_t *mediaData = 67539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 67639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 67739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // hexdump(mediaData, mediaBuf->range_length()); 67839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 67939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ((unsigned)mediaData[0], 0u); 68039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ((unsigned)mediaData[1], 0u); 68139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 68239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t offset = 2; 68339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t size = mediaBuf->range_length(); 68439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 68539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber while (offset < size) { 68639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 68739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // CHECK_LE(mediaBuf->range_length() -2 + 14, buffer->capacity()); 68839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 68939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t remaining = size - offset; 69039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber bool lastPacket = (remaining + 14 <= buffer->capacity()); 69139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (!lastPacket) { 69239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber remaining = buffer->capacity() - 14; 69339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 69439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 69539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data(); 69639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[0] = 0x80; 69739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] = (lastPacket ? 0x80 : 0x00) | PT; // M-bit 69839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[2] = (mSeqNo >> 8) & 0xff; 69939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[3] = mSeqNo & 0xff; 70039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[4] = rtpTime >> 24; 70139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 70239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 70339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[7] = rtpTime & 0xff; 70439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[8] = mSourceID >> 24; 70539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[9] = (mSourceID >> 16) & 0xff; 70639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[10] = (mSourceID >> 8) & 0xff; 70739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[11] = mSourceID & 0xff; 70839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 70939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[12] = (offset == 2) ? 0x04 : 0x00; // P=?, V=0 71039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[13] = 0x00; // PLEN = PEBIT = 0 71139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 71239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memcpy(&data[14], &mediaData[offset], remaining); 71339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber offset += remaining; 71439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 71539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(0, remaining + 14); 71639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 71739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber send(buffer, false /* isRTCP */); 71839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 71939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mSeqNo; 72039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mNumRTPSent; 72139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mNumRTPOctetsSent += buffer->size() - 12; 72239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 72339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 72439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastRTPTime = rtpTime; 72539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastNTPTime = GetNowNTP(); 72639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 72739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 72839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic size_t getFrameSize(bool isWide, unsigned FT) { 72939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber static const size_t kFrameSizeNB[8] = { 73039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 95, 103, 118, 134, 148, 159, 204, 244 73139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber }; 73239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber static const size_t kFrameSizeWB[9] = { 73339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 132, 177, 253, 285, 317, 365, 397, 461, 477 73439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber }; 73539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 73639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT]; 73739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 73839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // Round up bits to bytes and add 1 for the header byte. 73939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber frameSize = (frameSize + 7) / 8 + 1; 74039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 74139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return frameSize; 74239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 74339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 74439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPWriter::sendAMRData(MediaBuffer *mediaBuf) { 74539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber const uint8_t *mediaData = 74639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 74739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 74839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t mediaLength = mediaBuf->range_length(); 74939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 75039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_GE(kMaxPacketSize, 12u + 1u + mediaLength); 75139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 75239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber const bool isWide = (mMode == AMR_WB); 75339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 75439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int64_t timeUs; 75539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 75639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t rtpTime = mRTPTimeBase + (timeUs / (isWide ? 250 : 125)); 75739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 75839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // hexdump(mediaData, mediaLength); 75939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 76039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber Vector<uint8_t> tableOfContents; 76139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t srcOffset = 0; 76239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber while (srcOffset < mediaLength) { 76339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t toc = mediaData[srcOffset]; 76439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 76539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber unsigned FT = (toc >> 3) & 0x0f; 76639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK((isWide && FT <= 8) || (!isWide && FT <= 7)); 76739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 76839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber tableOfContents.push(toc); 76939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber srcOffset += getFrameSize(isWide, FT); 77039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 77139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(srcOffset, mediaLength); 77239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 77339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 77439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_LE(mediaLength + 12 + 1, buffer->capacity()); 77539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 77639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // The data fits into a single packet 77739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data(); 77839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[0] = 0x80; 77939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] = PT; 78039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mNumRTPSent == 0) { 78139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // Signal start of talk-spurt. 78239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] |= 0x80; // M-bit 78339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 78439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[2] = (mSeqNo >> 8) & 0xff; 78539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[3] = mSeqNo & 0xff; 78639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[4] = rtpTime >> 24; 78739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 78839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 78939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[7] = rtpTime & 0xff; 79039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[8] = mSourceID >> 24; 79139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[9] = (mSourceID >> 16) & 0xff; 79239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[10] = (mSourceID >> 8) & 0xff; 79339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[11] = mSourceID & 0xff; 79439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 79539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[12] = 0xf0; // CMR=15, RR=0 79639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 79739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t dstOffset = 13; 79839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 79939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber for (size_t i = 0; i < tableOfContents.size(); ++i) { 80039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t toc = tableOfContents[i]; 80139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 80239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (i + 1 < tableOfContents.size()) { 80339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber toc |= 0x80; 80439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else { 80539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber toc &= ~0x80; 80639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 80739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 80839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[dstOffset++] = toc; 80939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 81039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 81139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber srcOffset = 0; 81239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber for (size_t i = 0; i < tableOfContents.size(); ++i) { 81339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t toc = tableOfContents[i]; 81439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber unsigned FT = (toc >> 3) & 0x0f; 81539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t frameSize = getFrameSize(isWide, FT); 81639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 81739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++srcOffset; // skip toc 81839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memcpy(&data[dstOffset], &mediaData[srcOffset], frameSize - 1); 81939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber srcOffset += frameSize - 1; 82039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber dstOffset += frameSize - 1; 82139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 82239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 82339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(0, dstOffset); 82439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 82539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber send(buffer, false /* isRTCP */); 82639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 82739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mSeqNo; 82839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++mNumRTPSent; 82939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mNumRTPOctetsSent += buffer->size() - 12; 83039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 83139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastRTPTime = rtpTime; 83239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastNTPTime = GetNowNTP(); 83339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 83439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 83539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} // namespace android 83639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 837