Loading media/libstagefright/wifi-display/Android.mk +76 −0 Original line number Diff line number Diff line Loading @@ -4,10 +4,17 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ ANetworkSession.cpp \ MediaReceiver.cpp \ MediaSender.cpp \ Parameters.cpp \ ParsedMessage.cpp \ rtp/RTPAssembler.cpp \ rtp/RTPReceiver.cpp \ rtp/RTPSender.cpp \ sink/DirectRenderer.cpp \ sink/WifiDisplaySink.cpp \ SNTPClient.cpp \ TimeSyncer.cpp \ source/Converter.cpp \ source/MediaPuller.cpp \ source/PlaybackSession.cpp \ Loading Loading @@ -60,3 +67,72 @@ LOCAL_MODULE:= wfd LOCAL_MODULE_TAGS := debug include $(BUILD_EXECUTABLE) ################################################################################ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ udptest.cpp \ LOCAL_SHARED_LIBRARIES:= \ libbinder \ libgui \ libmedia \ libstagefright \ libstagefright_foundation \ libstagefright_wfd \ libutils \ liblog \ LOCAL_MODULE:= udptest LOCAL_MODULE_TAGS := debug include $(BUILD_EXECUTABLE) ################################################################################ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ rtptest.cpp \ LOCAL_SHARED_LIBRARIES:= \ libbinder \ libgui \ libmedia \ libstagefright \ libstagefright_foundation \ libstagefright_wfd \ libutils \ liblog \ LOCAL_MODULE:= rtptest LOCAL_MODULE_TAGS := debug include $(BUILD_EXECUTABLE) ################################################################################ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ nettest.cpp \ LOCAL_SHARED_LIBRARIES:= \ libbinder \ libgui \ libmedia \ libstagefright \ libstagefright_foundation \ libstagefright_wfd \ libutils \ liblog \ LOCAL_MODULE:= nettest LOCAL_MODULE_TAGS := debug include $(BUILD_EXECUTABLE) media/libstagefright/wifi-display/MediaReceiver.cpp 0 → 100644 +328 −0 Original line number Diff line number Diff line /* * Copyright 2013, 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "MediaReceiver" #include <utils/Log.h> #include "MediaReceiver.h" #include "ANetworkSession.h" #include "AnotherPacketSource.h" #include "rtp/RTPReceiver.h" #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/MetaData.h> #include <media/stagefright/Utils.h> namespace android { MediaReceiver::MediaReceiver( const sp<ANetworkSession> &netSession, const sp<AMessage> ¬ify) : mNetSession(netSession), mNotify(notify), mMode(MODE_UNDEFINED), mGeneration(0), mInitStatus(OK), mInitDoneCount(0) { } MediaReceiver::~MediaReceiver() { } ssize_t MediaReceiver::addTrack( RTPReceiver::TransportMode rtpMode, RTPReceiver::TransportMode rtcpMode, int32_t *localRTPPort) { if (mMode != MODE_UNDEFINED) { return INVALID_OPERATION; } size_t trackIndex = mTrackInfos.size(); TrackInfo info; sp<AMessage> notify = new AMessage(kWhatReceiverNotify, id()); notify->setInt32("generation", mGeneration); notify->setSize("trackIndex", trackIndex); info.mReceiver = new RTPReceiver(mNetSession, notify); looper()->registerHandler(info.mReceiver); info.mReceiver->registerPacketType( 33, RTPReceiver::PACKETIZATION_TRANSPORT_STREAM); info.mReceiver->registerPacketType( 96, RTPReceiver::PACKETIZATION_AAC); info.mReceiver->registerPacketType( 97, RTPReceiver::PACKETIZATION_H264); status_t err = info.mReceiver->initAsync( rtpMode, rtcpMode, localRTPPort); if (err != OK) { looper()->unregisterHandler(info.mReceiver->id()); info.mReceiver.clear(); return err; } mTrackInfos.push_back(info); return trackIndex; } status_t MediaReceiver::connectTrack( size_t trackIndex, const char *remoteHost, int32_t remoteRTPPort, int32_t remoteRTCPPort) { if (trackIndex >= mTrackInfos.size()) { return -ERANGE; } TrackInfo *info = &mTrackInfos.editItemAt(trackIndex); return info->mReceiver->connect(remoteHost, remoteRTPPort, remoteRTCPPort); } status_t MediaReceiver::initAsync(Mode mode) { if ((mode == MODE_TRANSPORT_STREAM || mode == MODE_TRANSPORT_STREAM_RAW) && mTrackInfos.size() > 1) { return INVALID_OPERATION; } sp<AMessage> msg = new AMessage(kWhatInit, id()); msg->setInt32("mode", mode); msg->post(); return OK; } void MediaReceiver::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatInit: { int32_t mode; CHECK(msg->findInt32("mode", &mode)); CHECK_EQ(mMode, MODE_UNDEFINED); mMode = (Mode)mode; if (mInitStatus != OK || mInitDoneCount == mTrackInfos.size()) { notifyInitDone(mInitStatus); } mTSParser = new ATSParser( ATSParser::ALIGNED_VIDEO_DATA | ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE); mFormatKnownMask = 0; break; } case kWhatReceiverNotify: { int32_t generation; CHECK(msg->findInt32("generation", &generation)); if (generation != mGeneration) { break; } onReceiverNotify(msg); break; } default: TRESPASS(); } } void MediaReceiver::onReceiverNotify(const sp<AMessage> &msg) { int32_t what; CHECK(msg->findInt32("what", &what)); switch (what) { case RTPReceiver::kWhatInitDone: { ++mInitDoneCount; int32_t err; CHECK(msg->findInt32("err", &err)); if (err != OK) { mInitStatus = err; ++mGeneration; } if (mMode != MODE_UNDEFINED) { if (mInitStatus != OK || mInitDoneCount == mTrackInfos.size()) { notifyInitDone(mInitStatus); } } break; } case RTPReceiver::kWhatError: { int32_t err; CHECK(msg->findInt32("err", &err)); notifyError(err); break; } case RTPReceiver::kWhatAccessUnit: { size_t trackIndex; CHECK(msg->findSize("trackIndex", &trackIndex)); sp<ABuffer> accessUnit; CHECK(msg->findBuffer("accessUnit", &accessUnit)); int32_t followsDiscontinuity; if (!msg->findInt32( "followsDiscontinuity", &followsDiscontinuity)) { followsDiscontinuity = 0; } if (mMode == MODE_TRANSPORT_STREAM) { if (followsDiscontinuity) { mTSParser->signalDiscontinuity( ATSParser::DISCONTINUITY_TIME, NULL /* extra */); } for (size_t offset = 0; offset < accessUnit->size(); offset += 188) { status_t err = mTSParser->feedTSPacket( accessUnit->data() + offset, 188); if (err != OK) { notifyError(err); break; } } drainPackets(0 /* trackIndex */, ATSParser::VIDEO); drainPackets(1 /* trackIndex */, ATSParser::AUDIO); } else { postAccessUnit(trackIndex, accessUnit, NULL); } break; } case RTPReceiver::kWhatPacketLost: { notifyPacketLost(); break; } default: TRESPASS(); } } void MediaReceiver::drainPackets( size_t trackIndex, ATSParser::SourceType type) { sp<AnotherPacketSource> source = static_cast<AnotherPacketSource *>( mTSParser->getSource(type).get()); if (source == NULL) { return; } sp<AMessage> format; if (!(mFormatKnownMask & (1ul << trackIndex))) { sp<MetaData> meta = source->getFormat(); CHECK(meta != NULL); CHECK_EQ((status_t)OK, convertMetaDataToMessage(meta, &format)); mFormatKnownMask |= 1ul << trackIndex; } status_t finalResult; while (source->hasBufferAvailable(&finalResult)) { sp<ABuffer> accessUnit; status_t err = source->dequeueAccessUnit(&accessUnit); if (err == OK) { postAccessUnit(trackIndex, accessUnit, format); format.clear(); } else if (err != INFO_DISCONTINUITY) { notifyError(err); } } if (finalResult != OK) { notifyError(finalResult); } } void MediaReceiver::notifyInitDone(status_t err) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatInitDone); notify->setInt32("err", err); notify->post(); } void MediaReceiver::notifyError(status_t err) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatError); notify->setInt32("err", err); notify->post(); } void MediaReceiver::notifyPacketLost() { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatPacketLost); notify->post(); } void MediaReceiver::postAccessUnit( size_t trackIndex, const sp<ABuffer> &accessUnit, const sp<AMessage> &format) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatAccessUnit); notify->setSize("trackIndex", trackIndex); notify->setBuffer("accessUnit", accessUnit); if (format != NULL) { notify->setMessage("format", format); } notify->post(); } status_t MediaReceiver::informSender( size_t trackIndex, const sp<AMessage> ¶ms) { if (trackIndex >= mTrackInfos.size()) { return -ERANGE; } TrackInfo *info = &mTrackInfos.editItemAt(trackIndex); return info->mReceiver->informSender(params); } } // namespace android media/libstagefright/wifi-display/MediaReceiver.h 0 → 100644 +111 −0 Original line number Diff line number Diff line /* * Copyright 2013, 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 <media/stagefright/foundation/AHandler.h> #include "ATSParser.h" #include "rtp/RTPReceiver.h" namespace android { struct ABuffer; struct ANetworkSession; struct AMessage; struct ATSParser; // This class facilitates receiving of media data for one or more tracks // over RTP. Either a 1:1 track to RTP channel mapping is used or a single // RTP channel provides the data for a transport stream that is consequently // demuxed and its track's data provided to the observer. struct MediaReceiver : public AHandler { enum { kWhatInitDone, kWhatError, kWhatAccessUnit, kWhatPacketLost, }; MediaReceiver( const sp<ANetworkSession> &netSession, const sp<AMessage> ¬ify); ssize_t addTrack( RTPReceiver::TransportMode rtpMode, RTPReceiver::TransportMode rtcpMode, int32_t *localRTPPort); status_t connectTrack( size_t trackIndex, const char *remoteHost, int32_t remoteRTPPort, int32_t remoteRTCPPort); enum Mode { MODE_UNDEFINED, MODE_TRANSPORT_STREAM, MODE_TRANSPORT_STREAM_RAW, MODE_ELEMENTARY_STREAMS, }; status_t initAsync(Mode mode); status_t informSender(size_t trackIndex, const sp<AMessage> ¶ms); protected: virtual void onMessageReceived(const sp<AMessage> &msg); virtual ~MediaReceiver(); private: enum { kWhatInit, kWhatReceiverNotify, }; struct TrackInfo { sp<RTPReceiver> mReceiver; }; sp<ANetworkSession> mNetSession; sp<AMessage> mNotify; Mode mMode; int32_t mGeneration; Vector<TrackInfo> mTrackInfos; status_t mInitStatus; size_t mInitDoneCount; sp<ATSParser> mTSParser; uint32_t mFormatKnownMask; void onReceiverNotify(const sp<AMessage> &msg); void drainPackets(size_t trackIndex, ATSParser::SourceType type); void notifyInitDone(status_t err); void notifyError(status_t err); void notifyPacketLost(); void postAccessUnit( size_t trackIndex, const sp<ABuffer> &accessUnit, const sp<AMessage> &format); DISALLOW_EVIL_CONSTRUCTORS(MediaReceiver); }; } // namespace android media/libstagefright/wifi-display/MediaSender.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -341,6 +341,22 @@ void MediaSender::onSenderNotify(const sp<AMessage> &msg) { break; } case kWhatInformSender: { int64_t avgLatencyUs; CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs)); int64_t maxLatencyUs; CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs)); sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatInformSender); notify->setInt64("avgLatencyUs", avgLatencyUs); notify->setInt64("maxLatencyUs", maxLatencyUs); notify->post(); break; } default: TRESPASS(); } Loading media/libstagefright/wifi-display/MediaSender.h +1 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ struct MediaSender : public AHandler { kWhatInitDone, kWhatError, kWhatNetworkStall, kWhatInformSender, }; MediaSender( Loading Loading
media/libstagefright/wifi-display/Android.mk +76 −0 Original line number Diff line number Diff line Loading @@ -4,10 +4,17 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ ANetworkSession.cpp \ MediaReceiver.cpp \ MediaSender.cpp \ Parameters.cpp \ ParsedMessage.cpp \ rtp/RTPAssembler.cpp \ rtp/RTPReceiver.cpp \ rtp/RTPSender.cpp \ sink/DirectRenderer.cpp \ sink/WifiDisplaySink.cpp \ SNTPClient.cpp \ TimeSyncer.cpp \ source/Converter.cpp \ source/MediaPuller.cpp \ source/PlaybackSession.cpp \ Loading Loading @@ -60,3 +67,72 @@ LOCAL_MODULE:= wfd LOCAL_MODULE_TAGS := debug include $(BUILD_EXECUTABLE) ################################################################################ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ udptest.cpp \ LOCAL_SHARED_LIBRARIES:= \ libbinder \ libgui \ libmedia \ libstagefright \ libstagefright_foundation \ libstagefright_wfd \ libutils \ liblog \ LOCAL_MODULE:= udptest LOCAL_MODULE_TAGS := debug include $(BUILD_EXECUTABLE) ################################################################################ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ rtptest.cpp \ LOCAL_SHARED_LIBRARIES:= \ libbinder \ libgui \ libmedia \ libstagefright \ libstagefright_foundation \ libstagefright_wfd \ libutils \ liblog \ LOCAL_MODULE:= rtptest LOCAL_MODULE_TAGS := debug include $(BUILD_EXECUTABLE) ################################################################################ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ nettest.cpp \ LOCAL_SHARED_LIBRARIES:= \ libbinder \ libgui \ libmedia \ libstagefright \ libstagefright_foundation \ libstagefright_wfd \ libutils \ liblog \ LOCAL_MODULE:= nettest LOCAL_MODULE_TAGS := debug include $(BUILD_EXECUTABLE)
media/libstagefright/wifi-display/MediaReceiver.cpp 0 → 100644 +328 −0 Original line number Diff line number Diff line /* * Copyright 2013, 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "MediaReceiver" #include <utils/Log.h> #include "MediaReceiver.h" #include "ANetworkSession.h" #include "AnotherPacketSource.h" #include "rtp/RTPReceiver.h" #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/MetaData.h> #include <media/stagefright/Utils.h> namespace android { MediaReceiver::MediaReceiver( const sp<ANetworkSession> &netSession, const sp<AMessage> ¬ify) : mNetSession(netSession), mNotify(notify), mMode(MODE_UNDEFINED), mGeneration(0), mInitStatus(OK), mInitDoneCount(0) { } MediaReceiver::~MediaReceiver() { } ssize_t MediaReceiver::addTrack( RTPReceiver::TransportMode rtpMode, RTPReceiver::TransportMode rtcpMode, int32_t *localRTPPort) { if (mMode != MODE_UNDEFINED) { return INVALID_OPERATION; } size_t trackIndex = mTrackInfos.size(); TrackInfo info; sp<AMessage> notify = new AMessage(kWhatReceiverNotify, id()); notify->setInt32("generation", mGeneration); notify->setSize("trackIndex", trackIndex); info.mReceiver = new RTPReceiver(mNetSession, notify); looper()->registerHandler(info.mReceiver); info.mReceiver->registerPacketType( 33, RTPReceiver::PACKETIZATION_TRANSPORT_STREAM); info.mReceiver->registerPacketType( 96, RTPReceiver::PACKETIZATION_AAC); info.mReceiver->registerPacketType( 97, RTPReceiver::PACKETIZATION_H264); status_t err = info.mReceiver->initAsync( rtpMode, rtcpMode, localRTPPort); if (err != OK) { looper()->unregisterHandler(info.mReceiver->id()); info.mReceiver.clear(); return err; } mTrackInfos.push_back(info); return trackIndex; } status_t MediaReceiver::connectTrack( size_t trackIndex, const char *remoteHost, int32_t remoteRTPPort, int32_t remoteRTCPPort) { if (trackIndex >= mTrackInfos.size()) { return -ERANGE; } TrackInfo *info = &mTrackInfos.editItemAt(trackIndex); return info->mReceiver->connect(remoteHost, remoteRTPPort, remoteRTCPPort); } status_t MediaReceiver::initAsync(Mode mode) { if ((mode == MODE_TRANSPORT_STREAM || mode == MODE_TRANSPORT_STREAM_RAW) && mTrackInfos.size() > 1) { return INVALID_OPERATION; } sp<AMessage> msg = new AMessage(kWhatInit, id()); msg->setInt32("mode", mode); msg->post(); return OK; } void MediaReceiver::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatInit: { int32_t mode; CHECK(msg->findInt32("mode", &mode)); CHECK_EQ(mMode, MODE_UNDEFINED); mMode = (Mode)mode; if (mInitStatus != OK || mInitDoneCount == mTrackInfos.size()) { notifyInitDone(mInitStatus); } mTSParser = new ATSParser( ATSParser::ALIGNED_VIDEO_DATA | ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE); mFormatKnownMask = 0; break; } case kWhatReceiverNotify: { int32_t generation; CHECK(msg->findInt32("generation", &generation)); if (generation != mGeneration) { break; } onReceiverNotify(msg); break; } default: TRESPASS(); } } void MediaReceiver::onReceiverNotify(const sp<AMessage> &msg) { int32_t what; CHECK(msg->findInt32("what", &what)); switch (what) { case RTPReceiver::kWhatInitDone: { ++mInitDoneCount; int32_t err; CHECK(msg->findInt32("err", &err)); if (err != OK) { mInitStatus = err; ++mGeneration; } if (mMode != MODE_UNDEFINED) { if (mInitStatus != OK || mInitDoneCount == mTrackInfos.size()) { notifyInitDone(mInitStatus); } } break; } case RTPReceiver::kWhatError: { int32_t err; CHECK(msg->findInt32("err", &err)); notifyError(err); break; } case RTPReceiver::kWhatAccessUnit: { size_t trackIndex; CHECK(msg->findSize("trackIndex", &trackIndex)); sp<ABuffer> accessUnit; CHECK(msg->findBuffer("accessUnit", &accessUnit)); int32_t followsDiscontinuity; if (!msg->findInt32( "followsDiscontinuity", &followsDiscontinuity)) { followsDiscontinuity = 0; } if (mMode == MODE_TRANSPORT_STREAM) { if (followsDiscontinuity) { mTSParser->signalDiscontinuity( ATSParser::DISCONTINUITY_TIME, NULL /* extra */); } for (size_t offset = 0; offset < accessUnit->size(); offset += 188) { status_t err = mTSParser->feedTSPacket( accessUnit->data() + offset, 188); if (err != OK) { notifyError(err); break; } } drainPackets(0 /* trackIndex */, ATSParser::VIDEO); drainPackets(1 /* trackIndex */, ATSParser::AUDIO); } else { postAccessUnit(trackIndex, accessUnit, NULL); } break; } case RTPReceiver::kWhatPacketLost: { notifyPacketLost(); break; } default: TRESPASS(); } } void MediaReceiver::drainPackets( size_t trackIndex, ATSParser::SourceType type) { sp<AnotherPacketSource> source = static_cast<AnotherPacketSource *>( mTSParser->getSource(type).get()); if (source == NULL) { return; } sp<AMessage> format; if (!(mFormatKnownMask & (1ul << trackIndex))) { sp<MetaData> meta = source->getFormat(); CHECK(meta != NULL); CHECK_EQ((status_t)OK, convertMetaDataToMessage(meta, &format)); mFormatKnownMask |= 1ul << trackIndex; } status_t finalResult; while (source->hasBufferAvailable(&finalResult)) { sp<ABuffer> accessUnit; status_t err = source->dequeueAccessUnit(&accessUnit); if (err == OK) { postAccessUnit(trackIndex, accessUnit, format); format.clear(); } else if (err != INFO_DISCONTINUITY) { notifyError(err); } } if (finalResult != OK) { notifyError(finalResult); } } void MediaReceiver::notifyInitDone(status_t err) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatInitDone); notify->setInt32("err", err); notify->post(); } void MediaReceiver::notifyError(status_t err) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatError); notify->setInt32("err", err); notify->post(); } void MediaReceiver::notifyPacketLost() { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatPacketLost); notify->post(); } void MediaReceiver::postAccessUnit( size_t trackIndex, const sp<ABuffer> &accessUnit, const sp<AMessage> &format) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatAccessUnit); notify->setSize("trackIndex", trackIndex); notify->setBuffer("accessUnit", accessUnit); if (format != NULL) { notify->setMessage("format", format); } notify->post(); } status_t MediaReceiver::informSender( size_t trackIndex, const sp<AMessage> ¶ms) { if (trackIndex >= mTrackInfos.size()) { return -ERANGE; } TrackInfo *info = &mTrackInfos.editItemAt(trackIndex); return info->mReceiver->informSender(params); } } // namespace android
media/libstagefright/wifi-display/MediaReceiver.h 0 → 100644 +111 −0 Original line number Diff line number Diff line /* * Copyright 2013, 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 <media/stagefright/foundation/AHandler.h> #include "ATSParser.h" #include "rtp/RTPReceiver.h" namespace android { struct ABuffer; struct ANetworkSession; struct AMessage; struct ATSParser; // This class facilitates receiving of media data for one or more tracks // over RTP. Either a 1:1 track to RTP channel mapping is used or a single // RTP channel provides the data for a transport stream that is consequently // demuxed and its track's data provided to the observer. struct MediaReceiver : public AHandler { enum { kWhatInitDone, kWhatError, kWhatAccessUnit, kWhatPacketLost, }; MediaReceiver( const sp<ANetworkSession> &netSession, const sp<AMessage> ¬ify); ssize_t addTrack( RTPReceiver::TransportMode rtpMode, RTPReceiver::TransportMode rtcpMode, int32_t *localRTPPort); status_t connectTrack( size_t trackIndex, const char *remoteHost, int32_t remoteRTPPort, int32_t remoteRTCPPort); enum Mode { MODE_UNDEFINED, MODE_TRANSPORT_STREAM, MODE_TRANSPORT_STREAM_RAW, MODE_ELEMENTARY_STREAMS, }; status_t initAsync(Mode mode); status_t informSender(size_t trackIndex, const sp<AMessage> ¶ms); protected: virtual void onMessageReceived(const sp<AMessage> &msg); virtual ~MediaReceiver(); private: enum { kWhatInit, kWhatReceiverNotify, }; struct TrackInfo { sp<RTPReceiver> mReceiver; }; sp<ANetworkSession> mNetSession; sp<AMessage> mNotify; Mode mMode; int32_t mGeneration; Vector<TrackInfo> mTrackInfos; status_t mInitStatus; size_t mInitDoneCount; sp<ATSParser> mTSParser; uint32_t mFormatKnownMask; void onReceiverNotify(const sp<AMessage> &msg); void drainPackets(size_t trackIndex, ATSParser::SourceType type); void notifyInitDone(status_t err); void notifyError(status_t err); void notifyPacketLost(); void postAccessUnit( size_t trackIndex, const sp<ABuffer> &accessUnit, const sp<AMessage> &format); DISALLOW_EVIL_CONSTRUCTORS(MediaReceiver); }; } // namespace android
media/libstagefright/wifi-display/MediaSender.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -341,6 +341,22 @@ void MediaSender::onSenderNotify(const sp<AMessage> &msg) { break; } case kWhatInformSender: { int64_t avgLatencyUs; CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs)); int64_t maxLatencyUs; CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs)); sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatInformSender); notify->setInt64("avgLatencyUs", avgLatencyUs); notify->setInt64("maxLatencyUs", maxLatencyUs); notify->post(); break; } default: TRESPASS(); } Loading
media/libstagefright/wifi-display/MediaSender.h +1 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ struct MediaSender : public AHandler { kWhatInitDone, kWhatError, kWhatNetworkStall, kWhatInformSender, }; MediaSender( Loading