summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/rtsp/rtp_test.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-08-04 10:14:30 -0700
committerAndreas Huber <andih@google.com>2010-08-04 11:49:24 -0700
commit39ddf8e0f18766f7ba1e3246b774aa6ebd93eea8 (patch)
tree87f5d0d68c1779f113843e939c41440ff6b00389 /media/libstagefright/rtsp/rtp_test.cpp
parent610959a52fe22a88e50d158f5f5f492fee4f1921 (diff)
downloadframeworks_av-39ddf8e0f18766f7ba1e3246b774aa6ebd93eea8.zip
frameworks_av-39ddf8e0f18766f7ba1e3246b774aa6ebd93eea8.tar.gz
frameworks_av-39ddf8e0f18766f7ba1e3246b774aa6ebd93eea8.tar.bz2
Support for Gtalk video, includes AMR/H.263 assembler and packetization support, extensions to MediaRecorder to stream via RTP over a pair of UDP sockets as well as various fixes to the RTP implementation.
Change-Id: I95b8dd487061add9bade15749e563b01cd99d9a6
Diffstat (limited to 'media/libstagefright/rtsp/rtp_test.cpp')
-rw-r--r--media/libstagefright/rtsp/rtp_test.cpp227
1 files changed, 227 insertions, 0 deletions
diff --git a/media/libstagefright/rtsp/rtp_test.cpp b/media/libstagefright/rtsp/rtp_test.cpp
new file mode 100644
index 0000000..cec6c0c
--- /dev/null
+++ b/media/libstagefright/rtsp/rtp_test.cpp
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/ProcessState.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/foundation/base64.h>
+
+#include "ARTPSession.h"
+#include "ASessionDescription.h"
+#include "UDPPusher.h"
+
+using namespace android;
+
+int main(int argc, char **argv) {
+ android::ProcessState::self()->startThreadPool();
+
+ DataSource::RegisterDefaultSniffers();
+
+ const char *rtpFilename = NULL;
+ const char *rtcpFilename = NULL;
+
+ if (argc == 3) {
+ rtpFilename = argv[1];
+ rtcpFilename = argv[2];
+ } else if (argc != 1) {
+ fprintf(stderr, "usage: %s [ rtpFilename rtcpFilename ]\n", argv[0]);
+ return 1;
+ }
+
+#if 0
+ static const uint8_t kSPS[] = {
+ 0x67, 0x42, 0x80, 0x0a, 0xe9, 0x02, 0x83, 0xe4, 0x20, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x0e, 0xa6, 0x00, 0x80
+ };
+ static const uint8_t kPPS[] = {
+ 0x68, 0xce, 0x3c, 0x80
+ };
+ AString out1, out2;
+ encodeBase64(kSPS, sizeof(kSPS), &out1);
+ encodeBase64(kPPS, sizeof(kPPS), &out2);
+ printf("params=%s,%s\n", out1.c_str(), out2.c_str());
+#endif
+
+ sp<ALooper> looper = new ALooper;
+
+ sp<UDPPusher> rtp_pusher;
+ sp<UDPPusher> rtcp_pusher;
+
+ if (rtpFilename != NULL) {
+ rtp_pusher = new UDPPusher(rtpFilename, 5434);
+ looper->registerHandler(rtp_pusher);
+
+ rtcp_pusher = new UDPPusher(rtcpFilename, 5435);
+ looper->registerHandler(rtcp_pusher);
+ }
+
+ sp<ARTPSession> session = new ARTPSession;
+ looper->registerHandler(session);
+
+#if 0
+ // My H264 SDP
+ static const char *raw =
+ "v=0\r\n"
+ "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
+ "s=QuickTime\r\n"
+ "t=0 0\r\n"
+ "a=range:npt=0-315\r\n"
+ "a=isma-compliance:2,2.0,2\r\n"
+ "m=video 5434 RTP/AVP 97\r\n"
+ "c=IN IP4 127.0.0.1\r\n"
+ "b=AS:30\r\n"
+ "a=rtpmap:97 H264/90000\r\n"
+ "a=fmtp:97 packetization-mode=1;profile-level-id=42000C;"
+ "sprop-parameter-sets=Z0IADJZUCg+I,aM44gA==\r\n"
+ "a=mpeg4-esid:201\r\n"
+ "a=cliprect:0,0,240,320\r\n"
+ "a=framesize:97 320-240\r\n";
+#elif 0
+ // My H263 SDP
+ static const char *raw =
+ "v=0\r\n"
+ "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
+ "s=QuickTime\r\n"
+ "t=0 0\r\n"
+ "a=range:npt=0-315\r\n"
+ "a=isma-compliance:2,2.0,2\r\n"
+ "m=video 5434 RTP/AVP 97\r\n"
+ "c=IN IP4 127.0.0.1\r\n"
+ "b=AS:30\r\n"
+ "a=rtpmap:97 H263-1998/90000\r\n"
+ "a=cliprect:0,0,240,320\r\n"
+ "a=framesize:97 320-240\r\n";
+#elif 0
+ // My AMR SDP
+ static const char *raw =
+ "v=0\r\n"
+ "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
+ "s=QuickTime\r\n"
+ "t=0 0\r\n"
+ "a=range:npt=0-315\r\n"
+ "a=isma-compliance:2,2.0,2\r\n"
+ "m=audio 5434 RTP/AVP 97\r\n"
+ "c=IN IP4 127.0.0.1\r\n"
+ "b=AS:30\r\n"
+ "a=rtpmap:97 AMR/8000/1\r\n"
+ "a=fmtp:97 octet-align\r\n";
+#elif 1
+ // GTalk's H264 SDP
+ static const char *raw =
+ "v=0\r\n"
+ "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
+ "s=QuickTime\r\n"
+ "t=0 0\r\n"
+ "a=range:npt=now-\r\n"
+ "m=video 5434 RTP/AVP 96\r\n"
+ "c=IN IP4 127.0.0.1\r\n"
+ "b=AS:320000\r\n"
+ "a=rtpmap:96 H264/90000\r\n"
+ "a=fmtp:96 packetization-mode=1;profile-level-id=42001E;"
+ "sprop-parameter-sets=Z0IAHpZUBaHogA==,aM44gA==\r\n"
+ "a=cliprect:0,0,480,270\r\n"
+ "a=framesize:96 720-480\r\n";
+#else
+ // sholes H264 SDP
+ static const char *raw =
+ "v=0\r\n"
+ "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
+ "s=QuickTime\r\n"
+ "t=0 0\r\n"
+ "a=range:npt=now-\r\n"
+ "m=video 5434 RTP/AVP 96\r\n"
+ "c=IN IP4 127.0.0.1\r\n"
+ "b=AS:320000\r\n"
+ "a=rtpmap:96 H264/90000\r\n"
+ "a=fmtp:96 packetization-mode=1;profile-level-id=42001E;"
+ "sprop-parameter-sets=Z0KACukCg+QgAAB9AAAOpgCA,aM48gA==\r\n"
+ "a=cliprect:0,0,240,320\r\n"
+ "a=framesize:96 320-240\r\n";
+#endif
+
+ sp<ASessionDescription> desc = new ASessionDescription;
+ CHECK(desc->setTo(raw, strlen(raw)));
+
+ CHECK_EQ(session->setup(desc), (status_t)OK);
+
+ if (rtp_pusher != NULL) {
+ rtp_pusher->start();
+ }
+
+ if (rtcp_pusher != NULL) {
+ rtcp_pusher->start();
+ }
+
+ looper->start(false /* runOnCallingThread */);
+
+ CHECK_EQ(session->countTracks(), 1u);
+ sp<MediaSource> source = session->trackAt(0);
+
+ OMXClient client;
+ CHECK_EQ(client.connect(), (status_t)OK);
+
+ sp<MediaSource> decoder = OMXCodec::Create(
+ client.interface(),
+ source->getFormat(), false /* createEncoder */,
+ source,
+ NULL,
+ 0); // OMXCodec::kPreferSoftwareCodecs);
+ CHECK(decoder != NULL);
+
+ CHECK_EQ(decoder->start(), (status_t)OK);
+
+ for (;;) {
+ MediaBuffer *buffer;
+ status_t err = decoder->read(&buffer);
+
+ if (err != OK) {
+ if (err == INFO_FORMAT_CHANGED) {
+ int32_t width, height;
+ CHECK(decoder->getFormat()->findInt32(kKeyWidth, &width));
+ CHECK(decoder->getFormat()->findInt32(kKeyHeight, &height));
+ printf("INFO_FORMAT_CHANGED %d x %d\n", width, height);
+ continue;
+ }
+
+ LOG(ERROR) << "decoder returned error "
+ << StringPrintf("0x%08x", err);
+ break;
+ }
+
+#if 1
+ if (buffer->range_length() != 0) {
+ int64_t timeUs;
+ CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
+
+ printf("decoder returned frame of size %d at time %.2f secs\n",
+ buffer->range_length(), timeUs / 1E6);
+ }
+#endif
+
+ buffer->release();
+ buffer = NULL;
+ }
+
+ CHECK_EQ(decoder->stop(), (status_t)OK);
+
+ looper->stop();
+
+ return 0;
+}