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