Loading media/libstagefright/mpeg2ts/ATSParser.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -534,6 +534,16 @@ status_t ATSParser::Stream::parse( mBuffer->setRange(0, 0); mExpectedContinuityCounter = -1; #if 0 // Uncomment this if you'd rather see no corruption whatsoever on // screen and suspend updates until we come across another IDR frame. if (mStreamType == STREAMTYPE_H264) { ALOGI("clearing video queue"); mQueue->clear(true /* clearFormat */); } #endif return OK; } Loading media/libstagefright/wifi-display/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ LOCAL_SRC_FILES:= \ ANetworkSession.cpp \ Parameters.cpp \ ParsedMessage.cpp \ sink/DirectRenderer.cpp \ sink/LinearRegression.cpp \ sink/RTPSink.cpp \ sink/TunnelRenderer.cpp \ Loading @@ -18,6 +19,7 @@ LOCAL_SRC_FILES:= \ source/TSPacketizer.cpp \ source/WifiDisplaySource.cpp \ TimeSeries.cpp \ VideoFormats.cpp \ LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/media/libstagefright \ Loading media/libstagefright/wifi-display/VideoFormats.cpp 0 → 100644 +370 −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 "VideoFormats" #include <utils/Log.h> #include "VideoFormats.h" #include <media/stagefright/foundation/ADebug.h> namespace android { VideoFormats::VideoFormats() { for (size_t i = 0; i < kNumResolutionTypes; ++i) { mResolutionEnabled[i] = 0; } setNativeResolution(RESOLUTION_CEA, 0); // default to 640x480 p60 } void VideoFormats::setNativeResolution(ResolutionType type, size_t index) { CHECK_LT(type, kNumResolutionTypes); CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL)); mNativeType = type; mNativeIndex = index; setResolutionEnabled(type, index); } void VideoFormats::getNativeResolution( ResolutionType *type, size_t *index) const { *type = mNativeType; *index = mNativeIndex; } void VideoFormats::disableAll() { for (size_t i = 0; i < kNumResolutionTypes; ++i) { mResolutionEnabled[i] = 0; } } void VideoFormats::enableAll() { for (size_t i = 0; i < kNumResolutionTypes; ++i) { mResolutionEnabled[i] = 0xffffffff; } } void VideoFormats::setResolutionEnabled( ResolutionType type, size_t index, bool enabled) { CHECK_LT(type, kNumResolutionTypes); CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL)); if (enabled) { mResolutionEnabled[type] |= (1ul << index); } else { mResolutionEnabled[type] &= ~(1ul << index); } } bool VideoFormats::isResolutionEnabled( ResolutionType type, size_t index) const { CHECK_LT(type, kNumResolutionTypes); CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL)); return mResolutionEnabled[type] & (1ul << index); } // static bool VideoFormats::GetConfiguration( ResolutionType type, size_t index, size_t *width, size_t *height, size_t *framesPerSecond, bool *interlaced) { CHECK_LT(type, kNumResolutionTypes); if (index >= 32) { return false; } static const struct config_t { size_t width, height, framesPerSecond; bool interlaced; } kConfigs[kNumResolutionTypes][32] = { { // CEA Resolutions { 640, 480, 60, false }, { 720, 480, 60, false }, { 720, 480, 60, true }, { 720, 576, 50, false }, { 720, 576, 50, true }, { 1280, 720, 30, false }, { 1280, 720, 60, false }, { 1920, 1080, 30, false }, { 1920, 1080, 60, false }, { 1920, 1080, 60, true }, { 1280, 720, 25, false }, { 1280, 720, 50, false }, { 1920, 1080, 25, false }, { 1920, 1080, 50, false }, { 1920, 1080, 50, true }, { 1280, 720, 24, false }, { 1920, 1080, 24, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, }, { // VESA Resolutions { 800, 600, 30, false }, { 800, 600, 60, false }, { 1024, 768, 30, false }, { 1024, 768, 60, false }, { 1152, 864, 30, false }, { 1152, 864, 60, false }, { 1280, 768, 30, false }, { 1280, 768, 60, false }, { 1280, 800, 30, false }, { 1280, 800, 60, false }, { 1360, 768, 30, false }, { 1360, 768, 60, false }, { 1366, 768, 30, false }, { 1366, 768, 60, false }, { 1280, 1024, 30, false }, { 1280, 1024, 60, false }, { 1400, 1050, 30, false }, { 1400, 1050, 60, false }, { 1440, 900, 30, false }, { 1440, 900, 60, false }, { 1600, 900, 30, false }, { 1600, 900, 60, false }, { 1600, 1200, 30, false }, { 1600, 1200, 60, false }, { 1680, 1024, 30, false }, { 1680, 1024, 60, false }, { 1680, 1050, 30, false }, { 1680, 1050, 60, false }, { 1920, 1200, 30, false }, { 1920, 1200, 60, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, }, { // HH Resolutions { 800, 480, 30, false }, { 800, 480, 60, false }, { 854, 480, 30, false }, { 854, 480, 60, false }, { 864, 480, 30, false }, { 864, 480, 60, false }, { 640, 360, 30, false }, { 640, 360, 60, false }, { 960, 540, 30, false }, { 960, 540, 60, false }, { 848, 480, 30, false }, { 848, 480, 60, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, } }; const config_t *config = &kConfigs[type][index]; if (config->width == 0) { return false; } if (width) { *width = config->width; } if (height) { *height = config->height; } if (framesPerSecond) { *framesPerSecond = config->framesPerSecond; } if (interlaced) { *interlaced = config->interlaced; } return true; } bool VideoFormats::parseFormatSpec(const char *spec) { CHECK_EQ(kNumResolutionTypes, 3); unsigned native, dummy; if (sscanf( spec, "%02x %02x %02x %02x %08X %08X %08X", &native, &dummy, &dummy, &dummy, &mResolutionEnabled[0], &mResolutionEnabled[1], &mResolutionEnabled[2]) != 7) { return false; } mNativeIndex = native >> 3; mNativeType = (ResolutionType)(native & 7); if (mNativeType >= kNumResolutionTypes) { return false; } return GetConfiguration(mNativeType, mNativeIndex, NULL, NULL, NULL, NULL); } AString VideoFormats::getFormatSpec() const { CHECK_EQ(kNumResolutionTypes, 3); // wfd_video_formats: // 1 byte "native" // 1 byte "preferred-display-mode-supported" 0 or 1 // one or more avc codec structures // 1 byte profile // 1 byte level // 4 byte CEA mask // 4 byte VESA mask // 4 byte HH mask // 1 byte latency // 2 byte min-slice-slice // 2 byte slice-enc-params // 1 byte framerate-control-support // max-hres (none or 2 byte) // max-vres (none or 2 byte) return StringPrintf( "%02x 00 02 02 %08x %08x %08x 00 0000 0000 00 none none", (mNativeIndex << 3) | mNativeType, mResolutionEnabled[0], mResolutionEnabled[1], mResolutionEnabled[2]); } // static bool VideoFormats::PickBestFormat( const VideoFormats &sinkSupported, const VideoFormats &sourceSupported, ResolutionType *chosenType, size_t *chosenIndex) { ResolutionType nativeType; size_t nativeIndex; sinkSupported.getNativeResolution(&nativeType, &nativeIndex); if (sinkSupported.isResolutionEnabled(nativeType, nativeIndex)) { if (sourceSupported.isResolutionEnabled(nativeType, nativeIndex)) { ALOGI("Choosing sink's native resolution"); *chosenType = nativeType; *chosenIndex = nativeIndex; return true; } } else { ALOGW("Sink advertised native resolution that it doesn't " "actually support... ignoring"); } sourceSupported.getNativeResolution(&nativeType, &nativeIndex); if (sourceSupported.isResolutionEnabled(nativeType, nativeIndex)) { if (sinkSupported.isResolutionEnabled(nativeType, nativeIndex)) { ALOGI("Choosing source's native resolution"); *chosenType = nativeType; *chosenIndex = nativeIndex; return true; } } else { ALOGW("Source advertised native resolution that it doesn't " "actually support... ignoring"); } bool first = true; uint32_t bestScore = 0; size_t bestType = 0; size_t bestIndex = 0; for (size_t i = 0; i < kNumResolutionTypes; ++i) { for (size_t j = 0; j < 32; ++j) { size_t width, height, framesPerSecond; bool interlaced; if (!GetConfiguration( (ResolutionType)i, j, &width, &height, &framesPerSecond, &interlaced)) { break; } if (!sinkSupported.isResolutionEnabled((ResolutionType)i, j) || !sourceSupported.isResolutionEnabled( (ResolutionType)i, j)) { continue; } ALOGV("type %u, index %u, %u x %u %c%u supported", i, j, width, height, interlaced ? 'i' : 'p', framesPerSecond); uint32_t score = width * height * framesPerSecond; if (!interlaced) { score *= 2; } if (first || score > bestScore) { bestScore = score; bestType = i; bestIndex = j; first = false; } } } if (first) { return false; } *chosenType = (ResolutionType)bestType; *chosenIndex = bestIndex; return true; } } // namespace android media/libstagefright/wifi-display/VideoFormats.h 0 → 100644 +83 −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. */ #ifndef VIDEO_FORMATS_H_ #define VIDEO_FORMATS_H_ #include <media/stagefright/foundation/ABase.h> #include <stdint.h> namespace android { struct AString; // This class encapsulates that video resolution capabilities of a wfd source // or sink as outlined in the wfd specs. Currently three sets of resolutions // are specified, each of which supports up to 32 resolutions. // In addition to its capabilities each sink/source also publishes its // "native" resolution, presumably one that is preferred among all others // because it wouldn't require any scaling and directly corresponds to the // display capabilities/pixels. struct VideoFormats { VideoFormats(); enum ResolutionType { RESOLUTION_CEA, RESOLUTION_VESA, RESOLUTION_HH, kNumResolutionTypes, }; void setNativeResolution(ResolutionType type, size_t index); void getNativeResolution(ResolutionType *type, size_t *index) const; void disableAll(); void enableAll(); void setResolutionEnabled( ResolutionType type, size_t index, bool enabled = true); bool isResolutionEnabled(ResolutionType type, size_t index) const; static bool GetConfiguration( ResolutionType type, size_t index, size_t *width, size_t *height, size_t *framesPerSecond, bool *interlaced); bool parseFormatSpec(const char *spec); AString getFormatSpec() const; static bool PickBestFormat( const VideoFormats &sinkSupported, const VideoFormats &sourceSupported, ResolutionType *chosenType, size_t *chosenIndex); private: ResolutionType mNativeType; size_t mNativeIndex; uint32_t mResolutionEnabled[kNumResolutionTypes]; DISALLOW_EVIL_CONSTRUCTORS(VideoFormats); }; } // namespace android #endif // VIDEO_FORMATS_H_ media/libstagefright/wifi-display/sink/RTPSink.cpp +14 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,14 @@ #include "RTPSink.h" #include "ANetworkSession.h" #if USE_TUNNEL_RENDERER #include "TunnelRenderer.h" #define RENDERER_CLASS TunnelRenderer #else #include "DirectRenderer.h" #define RENDERER_CLASS DirectRenderer #endif #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> Loading Loading @@ -238,9 +245,11 @@ void RTPSink::Source::addReportBlock( RTPSink::RTPSink( const sp<ANetworkSession> &netSession, const sp<IGraphicBufferProducer> &bufferProducer) const sp<IGraphicBufferProducer> &bufferProducer, const sp<AMessage> ¬ify) : mNetSession(netSession), mSurfaceTex(bufferProducer), mNotify(notify), mRTPPort(0), mRTPSessionID(0), mRTCPSessionID(0), Loading Loading @@ -470,6 +479,7 @@ status_t RTPSink::parseRTP(const sp<ABuffer> &buffer) { uint32_t rtpTime = U32_AT(&data[4]); uint16_t seqNo = U16_AT(&data[2]); #if 0 int64_t arrivalTimeUs; CHECK(buffer->meta()->findInt64("arrivalTimeUs", &arrivalTimeUs)); Loading Loading @@ -500,6 +510,7 @@ status_t RTPSink::parseRTP(const sp<ABuffer> &buffer) { ALOGI("packet was %.2f ms late", latenessMs); } } #endif sp<AMessage> meta = buffer->meta(); meta->setInt32("ssrc", srcId); Loading @@ -515,12 +526,12 @@ status_t RTPSink::parseRTP(const sp<ABuffer> &buffer) { sp<AMessage> notifyLost = new AMessage(kWhatPacketLost, id()); notifyLost->setInt32("ssrc", srcId); mRenderer = new TunnelRenderer(notifyLost, mSurfaceTex); mRenderer = new RENDERER_CLASS(notifyLost, mSurfaceTex); looper()->registerHandler(mRenderer); } sp<AMessage> queueBufferMsg = new AMessage(TunnelRenderer::kWhatQueueBuffer, mRenderer->id()); new AMessage(RENDERER_CLASS::kWhatQueueBuffer, mRenderer->id()); sp<Source> source = new Source(seqNo, buffer, queueBufferMsg); mSources.add(srcId, source); Loading Loading
media/libstagefright/mpeg2ts/ATSParser.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -534,6 +534,16 @@ status_t ATSParser::Stream::parse( mBuffer->setRange(0, 0); mExpectedContinuityCounter = -1; #if 0 // Uncomment this if you'd rather see no corruption whatsoever on // screen and suspend updates until we come across another IDR frame. if (mStreamType == STREAMTYPE_H264) { ALOGI("clearing video queue"); mQueue->clear(true /* clearFormat */); } #endif return OK; } Loading
media/libstagefright/wifi-display/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ LOCAL_SRC_FILES:= \ ANetworkSession.cpp \ Parameters.cpp \ ParsedMessage.cpp \ sink/DirectRenderer.cpp \ sink/LinearRegression.cpp \ sink/RTPSink.cpp \ sink/TunnelRenderer.cpp \ Loading @@ -18,6 +19,7 @@ LOCAL_SRC_FILES:= \ source/TSPacketizer.cpp \ source/WifiDisplaySource.cpp \ TimeSeries.cpp \ VideoFormats.cpp \ LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/media/libstagefright \ Loading
media/libstagefright/wifi-display/VideoFormats.cpp 0 → 100644 +370 −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 "VideoFormats" #include <utils/Log.h> #include "VideoFormats.h" #include <media/stagefright/foundation/ADebug.h> namespace android { VideoFormats::VideoFormats() { for (size_t i = 0; i < kNumResolutionTypes; ++i) { mResolutionEnabled[i] = 0; } setNativeResolution(RESOLUTION_CEA, 0); // default to 640x480 p60 } void VideoFormats::setNativeResolution(ResolutionType type, size_t index) { CHECK_LT(type, kNumResolutionTypes); CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL)); mNativeType = type; mNativeIndex = index; setResolutionEnabled(type, index); } void VideoFormats::getNativeResolution( ResolutionType *type, size_t *index) const { *type = mNativeType; *index = mNativeIndex; } void VideoFormats::disableAll() { for (size_t i = 0; i < kNumResolutionTypes; ++i) { mResolutionEnabled[i] = 0; } } void VideoFormats::enableAll() { for (size_t i = 0; i < kNumResolutionTypes; ++i) { mResolutionEnabled[i] = 0xffffffff; } } void VideoFormats::setResolutionEnabled( ResolutionType type, size_t index, bool enabled) { CHECK_LT(type, kNumResolutionTypes); CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL)); if (enabled) { mResolutionEnabled[type] |= (1ul << index); } else { mResolutionEnabled[type] &= ~(1ul << index); } } bool VideoFormats::isResolutionEnabled( ResolutionType type, size_t index) const { CHECK_LT(type, kNumResolutionTypes); CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL)); return mResolutionEnabled[type] & (1ul << index); } // static bool VideoFormats::GetConfiguration( ResolutionType type, size_t index, size_t *width, size_t *height, size_t *framesPerSecond, bool *interlaced) { CHECK_LT(type, kNumResolutionTypes); if (index >= 32) { return false; } static const struct config_t { size_t width, height, framesPerSecond; bool interlaced; } kConfigs[kNumResolutionTypes][32] = { { // CEA Resolutions { 640, 480, 60, false }, { 720, 480, 60, false }, { 720, 480, 60, true }, { 720, 576, 50, false }, { 720, 576, 50, true }, { 1280, 720, 30, false }, { 1280, 720, 60, false }, { 1920, 1080, 30, false }, { 1920, 1080, 60, false }, { 1920, 1080, 60, true }, { 1280, 720, 25, false }, { 1280, 720, 50, false }, { 1920, 1080, 25, false }, { 1920, 1080, 50, false }, { 1920, 1080, 50, true }, { 1280, 720, 24, false }, { 1920, 1080, 24, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, }, { // VESA Resolutions { 800, 600, 30, false }, { 800, 600, 60, false }, { 1024, 768, 30, false }, { 1024, 768, 60, false }, { 1152, 864, 30, false }, { 1152, 864, 60, false }, { 1280, 768, 30, false }, { 1280, 768, 60, false }, { 1280, 800, 30, false }, { 1280, 800, 60, false }, { 1360, 768, 30, false }, { 1360, 768, 60, false }, { 1366, 768, 30, false }, { 1366, 768, 60, false }, { 1280, 1024, 30, false }, { 1280, 1024, 60, false }, { 1400, 1050, 30, false }, { 1400, 1050, 60, false }, { 1440, 900, 30, false }, { 1440, 900, 60, false }, { 1600, 900, 30, false }, { 1600, 900, 60, false }, { 1600, 1200, 30, false }, { 1600, 1200, 60, false }, { 1680, 1024, 30, false }, { 1680, 1024, 60, false }, { 1680, 1050, 30, false }, { 1680, 1050, 60, false }, { 1920, 1200, 30, false }, { 1920, 1200, 60, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, }, { // HH Resolutions { 800, 480, 30, false }, { 800, 480, 60, false }, { 854, 480, 30, false }, { 854, 480, 60, false }, { 864, 480, 30, false }, { 864, 480, 60, false }, { 640, 360, 30, false }, { 640, 360, 60, false }, { 960, 540, 30, false }, { 960, 540, 60, false }, { 848, 480, 30, false }, { 848, 480, 60, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, { 0, 0, 0, false }, } }; const config_t *config = &kConfigs[type][index]; if (config->width == 0) { return false; } if (width) { *width = config->width; } if (height) { *height = config->height; } if (framesPerSecond) { *framesPerSecond = config->framesPerSecond; } if (interlaced) { *interlaced = config->interlaced; } return true; } bool VideoFormats::parseFormatSpec(const char *spec) { CHECK_EQ(kNumResolutionTypes, 3); unsigned native, dummy; if (sscanf( spec, "%02x %02x %02x %02x %08X %08X %08X", &native, &dummy, &dummy, &dummy, &mResolutionEnabled[0], &mResolutionEnabled[1], &mResolutionEnabled[2]) != 7) { return false; } mNativeIndex = native >> 3; mNativeType = (ResolutionType)(native & 7); if (mNativeType >= kNumResolutionTypes) { return false; } return GetConfiguration(mNativeType, mNativeIndex, NULL, NULL, NULL, NULL); } AString VideoFormats::getFormatSpec() const { CHECK_EQ(kNumResolutionTypes, 3); // wfd_video_formats: // 1 byte "native" // 1 byte "preferred-display-mode-supported" 0 or 1 // one or more avc codec structures // 1 byte profile // 1 byte level // 4 byte CEA mask // 4 byte VESA mask // 4 byte HH mask // 1 byte latency // 2 byte min-slice-slice // 2 byte slice-enc-params // 1 byte framerate-control-support // max-hres (none or 2 byte) // max-vres (none or 2 byte) return StringPrintf( "%02x 00 02 02 %08x %08x %08x 00 0000 0000 00 none none", (mNativeIndex << 3) | mNativeType, mResolutionEnabled[0], mResolutionEnabled[1], mResolutionEnabled[2]); } // static bool VideoFormats::PickBestFormat( const VideoFormats &sinkSupported, const VideoFormats &sourceSupported, ResolutionType *chosenType, size_t *chosenIndex) { ResolutionType nativeType; size_t nativeIndex; sinkSupported.getNativeResolution(&nativeType, &nativeIndex); if (sinkSupported.isResolutionEnabled(nativeType, nativeIndex)) { if (sourceSupported.isResolutionEnabled(nativeType, nativeIndex)) { ALOGI("Choosing sink's native resolution"); *chosenType = nativeType; *chosenIndex = nativeIndex; return true; } } else { ALOGW("Sink advertised native resolution that it doesn't " "actually support... ignoring"); } sourceSupported.getNativeResolution(&nativeType, &nativeIndex); if (sourceSupported.isResolutionEnabled(nativeType, nativeIndex)) { if (sinkSupported.isResolutionEnabled(nativeType, nativeIndex)) { ALOGI("Choosing source's native resolution"); *chosenType = nativeType; *chosenIndex = nativeIndex; return true; } } else { ALOGW("Source advertised native resolution that it doesn't " "actually support... ignoring"); } bool first = true; uint32_t bestScore = 0; size_t bestType = 0; size_t bestIndex = 0; for (size_t i = 0; i < kNumResolutionTypes; ++i) { for (size_t j = 0; j < 32; ++j) { size_t width, height, framesPerSecond; bool interlaced; if (!GetConfiguration( (ResolutionType)i, j, &width, &height, &framesPerSecond, &interlaced)) { break; } if (!sinkSupported.isResolutionEnabled((ResolutionType)i, j) || !sourceSupported.isResolutionEnabled( (ResolutionType)i, j)) { continue; } ALOGV("type %u, index %u, %u x %u %c%u supported", i, j, width, height, interlaced ? 'i' : 'p', framesPerSecond); uint32_t score = width * height * framesPerSecond; if (!interlaced) { score *= 2; } if (first || score > bestScore) { bestScore = score; bestType = i; bestIndex = j; first = false; } } } if (first) { return false; } *chosenType = (ResolutionType)bestType; *chosenIndex = bestIndex; return true; } } // namespace android
media/libstagefright/wifi-display/VideoFormats.h 0 → 100644 +83 −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. */ #ifndef VIDEO_FORMATS_H_ #define VIDEO_FORMATS_H_ #include <media/stagefright/foundation/ABase.h> #include <stdint.h> namespace android { struct AString; // This class encapsulates that video resolution capabilities of a wfd source // or sink as outlined in the wfd specs. Currently three sets of resolutions // are specified, each of which supports up to 32 resolutions. // In addition to its capabilities each sink/source also publishes its // "native" resolution, presumably one that is preferred among all others // because it wouldn't require any scaling and directly corresponds to the // display capabilities/pixels. struct VideoFormats { VideoFormats(); enum ResolutionType { RESOLUTION_CEA, RESOLUTION_VESA, RESOLUTION_HH, kNumResolutionTypes, }; void setNativeResolution(ResolutionType type, size_t index); void getNativeResolution(ResolutionType *type, size_t *index) const; void disableAll(); void enableAll(); void setResolutionEnabled( ResolutionType type, size_t index, bool enabled = true); bool isResolutionEnabled(ResolutionType type, size_t index) const; static bool GetConfiguration( ResolutionType type, size_t index, size_t *width, size_t *height, size_t *framesPerSecond, bool *interlaced); bool parseFormatSpec(const char *spec); AString getFormatSpec() const; static bool PickBestFormat( const VideoFormats &sinkSupported, const VideoFormats &sourceSupported, ResolutionType *chosenType, size_t *chosenIndex); private: ResolutionType mNativeType; size_t mNativeIndex; uint32_t mResolutionEnabled[kNumResolutionTypes]; DISALLOW_EVIL_CONSTRUCTORS(VideoFormats); }; } // namespace android #endif // VIDEO_FORMATS_H_
media/libstagefright/wifi-display/sink/RTPSink.cpp +14 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,14 @@ #include "RTPSink.h" #include "ANetworkSession.h" #if USE_TUNNEL_RENDERER #include "TunnelRenderer.h" #define RENDERER_CLASS TunnelRenderer #else #include "DirectRenderer.h" #define RENDERER_CLASS DirectRenderer #endif #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> Loading Loading @@ -238,9 +245,11 @@ void RTPSink::Source::addReportBlock( RTPSink::RTPSink( const sp<ANetworkSession> &netSession, const sp<IGraphicBufferProducer> &bufferProducer) const sp<IGraphicBufferProducer> &bufferProducer, const sp<AMessage> ¬ify) : mNetSession(netSession), mSurfaceTex(bufferProducer), mNotify(notify), mRTPPort(0), mRTPSessionID(0), mRTCPSessionID(0), Loading Loading @@ -470,6 +479,7 @@ status_t RTPSink::parseRTP(const sp<ABuffer> &buffer) { uint32_t rtpTime = U32_AT(&data[4]); uint16_t seqNo = U16_AT(&data[2]); #if 0 int64_t arrivalTimeUs; CHECK(buffer->meta()->findInt64("arrivalTimeUs", &arrivalTimeUs)); Loading Loading @@ -500,6 +510,7 @@ status_t RTPSink::parseRTP(const sp<ABuffer> &buffer) { ALOGI("packet was %.2f ms late", latenessMs); } } #endif sp<AMessage> meta = buffer->meta(); meta->setInt32("ssrc", srcId); Loading @@ -515,12 +526,12 @@ status_t RTPSink::parseRTP(const sp<ABuffer> &buffer) { sp<AMessage> notifyLost = new AMessage(kWhatPacketLost, id()); notifyLost->setInt32("ssrc", srcId); mRenderer = new TunnelRenderer(notifyLost, mSurfaceTex); mRenderer = new RENDERER_CLASS(notifyLost, mSurfaceTex); looper()->registerHandler(mRenderer); } sp<AMessage> queueBufferMsg = new AMessage(TunnelRenderer::kWhatQueueBuffer, mRenderer->id()); new AMessage(RENDERER_CLASS::kWhatQueueBuffer, mRenderer->id()); sp<Source> source = new Source(seqNo, buffer, queueBufferMsg); mSources.add(srcId, source); Loading