Loading media/libstagefright/wifi-display/ANetworkSession.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,24 @@ status_t ANetworkSession::Session::writeMore() { do { const sp<ABuffer> &datagram = *mOutDatagrams.begin(); uint8_t *data = datagram->data(); if (data[0] == 0x80 && (data[1] & 0x7f) == 33) { int64_t nowUs = ALooper::GetNowUs(); uint32_t prevRtpTime = U32_AT(&data[4]); // 90kHz time scale uint32_t rtpTime = (nowUs * 9ll) / 100ll; int32_t diffTime = (int32_t)rtpTime - (int32_t)prevRtpTime; ALOGV("correcting rtpTime by %.0f ms", diffTime / 90.0); data[4] = rtpTime >> 24; data[5] = (rtpTime >> 16) & 0xff; data[6] = (rtpTime >> 8) & 0xff; data[7] = rtpTime & 0xff; } int n; do { n = send(mSocket, datagram->data(), datagram->size(), 0); Loading @@ -424,6 +442,9 @@ status_t ANetworkSession::Session::writeMore() { } while (err == OK && !mOutDatagrams.empty()); if (err == -EAGAIN) { if (!mOutDatagrams.empty()) { ALOGI("%d datagrams remain queued.", mOutDatagrams.size()); } err = OK; } Loading media/libstagefright/wifi-display/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ LOCAL_SRC_FILES:= \ source/Sender.cpp \ source/TSPacketizer.cpp \ source/WifiDisplaySource.cpp \ TimeSeries.cpp \ LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/media/libstagefright \ Loading media/libstagefright/wifi-display/TimeSeries.cpp 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright 2012, 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 "TimeSeries.h" #include <math.h> #include <string.h> namespace android { TimeSeries::TimeSeries() : mCount(0), mSum(0.0) { } void TimeSeries::add(double val) { if (mCount < kHistorySize) { mValues[mCount++] = val; mSum += val; } else { mSum -= mValues[0]; memmove(&mValues[0], &mValues[1], (kHistorySize - 1) * sizeof(double)); mValues[kHistorySize - 1] = val; mSum += val; } } double TimeSeries::mean() const { if (mCount < 1) { return 0.0; } return mSum / mCount; } double TimeSeries::sdev() const { if (mCount < 1) { return 0.0; } double m = mean(); double sum = 0.0; for (size_t i = 0; i < mCount; ++i) { double tmp = mValues[i] - m; tmp *= tmp; sum += tmp; } return sqrt(sum / mCount); } } // namespace android media/libstagefright/wifi-display/TimeSeries.h 0 → 100644 +46 −0 Original line number Diff line number Diff line /* * Copyright 2012, 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 TIME_SERIES_H_ #define TIME_SERIES_H_ #include <sys/types.h> namespace android { struct TimeSeries { TimeSeries(); void add(double val); double mean() const; double sdev() const; private: enum { kHistorySize = 20 }; double mValues[kHistorySize]; size_t mCount; double mSum; }; } // namespace android #endif // TIME_SERIES_H_ media/libstagefright/wifi-display/source/Converter.cpp +40 −6 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ Converter::Converter( mInputFormat(format), mIsVideo(false), mIsPCMAudio(usePCMAudio), mNeedToManuallyPrependSPSPPS(false), mDoMoreWorkPending(false) #if ENABLE_SILENCE_DETECTION ,mFirstSilentFrameUs(-1ll) Loading Loading @@ -94,6 +95,10 @@ sp<AMessage> Converter::getOutputFormat() const { return mOutputFormat; } bool Converter::needToManuallyPrependSPSPPS() const { return mNeedToManuallyPrependSPSPPS; } static int32_t getBitrate(const char *propName, int32_t defaultValue) { char val[PROPERTY_VALUE_MAX]; if (property_get(propName, val, NULL)) { Loading Loading @@ -157,16 +162,45 @@ status_t Converter::initEncoder() { mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant); mOutputFormat->setInt32("frame-rate", 30); mOutputFormat->setInt32("i-frame-interval", 1); // Iframes every 1 secs mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1); } ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); status_t err = mEncoder->configure( mNeedToManuallyPrependSPSPPS = false; status_t err = NO_INIT; if (!isAudio) { sp<AMessage> tmp = mOutputFormat->dup(); tmp->setInt32("prepend-sps-pps-to-idr-frames", 1); err = mEncoder->configure( tmp, NULL /* nativeWindow */, NULL /* crypto */, MediaCodec::CONFIGURE_FLAG_ENCODE); if (err == OK) { // Encoder supported prepending SPS/PPS, we don't need to emulate // it. mOutputFormat = tmp; } else { mNeedToManuallyPrependSPSPPS = true; ALOGI("We going to manually prepend SPS and PPS to IDR frames."); } } if (err != OK) { // We'll get here for audio or if we failed to configure the encoder // to automatically prepend SPS/PPS in the case of video. err = mEncoder->configure( mOutputFormat, NULL /* nativeWindow */, NULL /* crypto */, MediaCodec::CONFIGURE_FLAG_ENCODE); } if (err != OK) { return err; Loading Loading
media/libstagefright/wifi-display/ANetworkSession.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,24 @@ status_t ANetworkSession::Session::writeMore() { do { const sp<ABuffer> &datagram = *mOutDatagrams.begin(); uint8_t *data = datagram->data(); if (data[0] == 0x80 && (data[1] & 0x7f) == 33) { int64_t nowUs = ALooper::GetNowUs(); uint32_t prevRtpTime = U32_AT(&data[4]); // 90kHz time scale uint32_t rtpTime = (nowUs * 9ll) / 100ll; int32_t diffTime = (int32_t)rtpTime - (int32_t)prevRtpTime; ALOGV("correcting rtpTime by %.0f ms", diffTime / 90.0); data[4] = rtpTime >> 24; data[5] = (rtpTime >> 16) & 0xff; data[6] = (rtpTime >> 8) & 0xff; data[7] = rtpTime & 0xff; } int n; do { n = send(mSocket, datagram->data(), datagram->size(), 0); Loading @@ -424,6 +442,9 @@ status_t ANetworkSession::Session::writeMore() { } while (err == OK && !mOutDatagrams.empty()); if (err == -EAGAIN) { if (!mOutDatagrams.empty()) { ALOGI("%d datagrams remain queued.", mOutDatagrams.size()); } err = OK; } Loading
media/libstagefright/wifi-display/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ LOCAL_SRC_FILES:= \ source/Sender.cpp \ source/TSPacketizer.cpp \ source/WifiDisplaySource.cpp \ TimeSeries.cpp \ LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/media/libstagefright \ Loading
media/libstagefright/wifi-display/TimeSeries.cpp 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright 2012, 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 "TimeSeries.h" #include <math.h> #include <string.h> namespace android { TimeSeries::TimeSeries() : mCount(0), mSum(0.0) { } void TimeSeries::add(double val) { if (mCount < kHistorySize) { mValues[mCount++] = val; mSum += val; } else { mSum -= mValues[0]; memmove(&mValues[0], &mValues[1], (kHistorySize - 1) * sizeof(double)); mValues[kHistorySize - 1] = val; mSum += val; } } double TimeSeries::mean() const { if (mCount < 1) { return 0.0; } return mSum / mCount; } double TimeSeries::sdev() const { if (mCount < 1) { return 0.0; } double m = mean(); double sum = 0.0; for (size_t i = 0; i < mCount; ++i) { double tmp = mValues[i] - m; tmp *= tmp; sum += tmp; } return sqrt(sum / mCount); } } // namespace android
media/libstagefright/wifi-display/TimeSeries.h 0 → 100644 +46 −0 Original line number Diff line number Diff line /* * Copyright 2012, 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 TIME_SERIES_H_ #define TIME_SERIES_H_ #include <sys/types.h> namespace android { struct TimeSeries { TimeSeries(); void add(double val); double mean() const; double sdev() const; private: enum { kHistorySize = 20 }; double mValues[kHistorySize]; size_t mCount; double mSum; }; } // namespace android #endif // TIME_SERIES_H_
media/libstagefright/wifi-display/source/Converter.cpp +40 −6 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ Converter::Converter( mInputFormat(format), mIsVideo(false), mIsPCMAudio(usePCMAudio), mNeedToManuallyPrependSPSPPS(false), mDoMoreWorkPending(false) #if ENABLE_SILENCE_DETECTION ,mFirstSilentFrameUs(-1ll) Loading Loading @@ -94,6 +95,10 @@ sp<AMessage> Converter::getOutputFormat() const { return mOutputFormat; } bool Converter::needToManuallyPrependSPSPPS() const { return mNeedToManuallyPrependSPSPPS; } static int32_t getBitrate(const char *propName, int32_t defaultValue) { char val[PROPERTY_VALUE_MAX]; if (property_get(propName, val, NULL)) { Loading Loading @@ -157,16 +162,45 @@ status_t Converter::initEncoder() { mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant); mOutputFormat->setInt32("frame-rate", 30); mOutputFormat->setInt32("i-frame-interval", 1); // Iframes every 1 secs mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1); } ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); status_t err = mEncoder->configure( mNeedToManuallyPrependSPSPPS = false; status_t err = NO_INIT; if (!isAudio) { sp<AMessage> tmp = mOutputFormat->dup(); tmp->setInt32("prepend-sps-pps-to-idr-frames", 1); err = mEncoder->configure( tmp, NULL /* nativeWindow */, NULL /* crypto */, MediaCodec::CONFIGURE_FLAG_ENCODE); if (err == OK) { // Encoder supported prepending SPS/PPS, we don't need to emulate // it. mOutputFormat = tmp; } else { mNeedToManuallyPrependSPSPPS = true; ALOGI("We going to manually prepend SPS and PPS to IDR frames."); } } if (err != OK) { // We'll get here for audio or if we failed to configure the encoder // to automatically prepend SPS/PPS in the case of video. err = mEncoder->configure( mOutputFormat, NULL /* nativeWindow */, NULL /* crypto */, MediaCodec::CONFIGURE_FLAG_ENCODE); } if (err != OK) { return err; Loading