summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikhal@chromium.org <mikhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-05 18:00:33 +0000
committermikhal@chromium.org <mikhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-05 18:00:33 +0000
commit25342bd3361026a14512e5a7ad46877b17f988ef (patch)
tree2653c801446efae3c9139ac984b878eaf640cace
parent1c4b859ab31b074892679a5c75587e31c8d8c904 (diff)
downloadchromium_src-25342bd3361026a14512e5a7ad46877b17f988ef.zip
chromium_src-25342bd3361026a14512e5a7ad46877b17f988ef.tar.gz
chromium_src-25342bd3361026a14512e5a7ad46877b17f988ef.tar.bz2
Cast: Fix audio pipeline
1. Add audio decoded callback - guarantees that we will return an audio frame when invoked. 2. Bug fixes in sender.cc 3. Add a return in transport.cc when we drop a packet. BUG=323703 Review URL: https://codereview.chromium.org/102293004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238992 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--media/cast/audio_receiver/audio_receiver.cc32
-rw-r--r--media/cast/audio_receiver/audio_receiver.h9
-rw-r--r--media/cast/test/receiver.cc8
-rw-r--r--media/cast/test/sender.cc14
-rw-r--r--media/cast/test/transport/transport.cc4
5 files changed, 51 insertions, 16 deletions
diff --git a/media/cast/audio_receiver/audio_receiver.cc b/media/cast/audio_receiver/audio_receiver.cc
index ea56195..9347f15 100644
--- a/media/cast/audio_receiver/audio_receiver.cc
+++ b/media/cast/audio_receiver/audio_receiver.cc
@@ -21,6 +21,13 @@ static const int64 kMinSchedulingDelayMs = 1;
namespace media {
namespace cast {
+DecodedAudioCallbackData::DecodedAudioCallbackData()
+ : number_of_10ms_blocks(0),
+ desired_frequency(0),
+ callback() {}
+
+DecodedAudioCallbackData::~DecodedAudioCallbackData() {}
+
// Local implementation of RtpData (defined in rtp_rtcp_defines.h).
// Used to pass payload data into the audio receiver.
class LocalRtpAudioData : public RtpData {
@@ -174,27 +181,37 @@ void AudioReceiver::IncomingParsedRtpPacket(const uint8* payload_data,
audio_decoder_->IncomingParsedRtpPacket(
reinterpret_cast<const uint8*>(plaintext.data()), plaintext.size(),
rtp_header);
+ if (!queued_decoded_callbacks_.empty()) {
+ DecodedAudioCallbackData decoded_data = queued_decoded_callbacks_.front();
+ queued_decoded_callbacks_.pop_front();
+ cast_environment_->PostTask(CastEnvironment::AUDIO_DECODER, FROM_HERE,
+ base::Bind(&AudioReceiver::DecodeAudioFrameThread,
+ base::Unretained(this),
+ decoded_data.number_of_10ms_blocks,
+ decoded_data.desired_frequency,
+ decoded_data.callback));
+ }
return;
}
+
DCHECK(audio_buffer_) << "Invalid internal state";
DCHECK(!audio_decoder_) << "Invalid internal state";
+
bool complete = audio_buffer_->InsertPacket(payload_data, payload_size,
rtp_header);
if (!complete) return; // Audio frame not complete; wait for more packets.
- if (queued_encoded_callbacks_.empty()) return; // No pending callback.
-
+ if (queued_encoded_callbacks_.empty()) return;
AudioFrameEncodedCallback callback = queued_encoded_callbacks_.front();
queued_encoded_callbacks_.pop_front();
cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
base::Bind(&AudioReceiver::GetEncodedAudioFrame,
- weak_factory_.GetWeakPtr(), callback));
+ weak_factory_.GetWeakPtr(), callback));
}
void AudioReceiver::GetRawAudioFrame(int number_of_10ms_blocks,
int desired_frequency, const AudioFrameDecodedCallback& callback) {
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
DCHECK(audio_decoder_) << "Invalid function call in this configuration";
-
// TODO(pwestin): we can skip this function by posting direct to the decoder.
cast_environment_->PostTask(CastEnvironment::AUDIO_DECODER, FROM_HERE,
base::Bind(&AudioReceiver::DecodeAudioFrameThread,
@@ -217,8 +234,11 @@ void AudioReceiver::DecodeAudioFrameThread(
desired_frequency,
audio_frame.get(),
&rtp_timestamp)) {
- // TODO(pwestin): This looks wrong, we would loose the pending call to
- // the application provided callback.
+ DecodedAudioCallbackData callback_data;
+ callback_data.number_of_10ms_blocks = number_of_10ms_blocks;
+ callback_data.desired_frequency = desired_frequency;
+ callback_data.callback = callback;
+ queued_decoded_callbacks_.push_back(callback_data);
return;
}
base::TimeTicks now = cast_environment_->Clock()->NowTicks();
diff --git a/media/cast/audio_receiver/audio_receiver.h b/media/cast/audio_receiver/audio_receiver.h
index 53e85db..0298641 100644
--- a/media/cast/audio_receiver/audio_receiver.h
+++ b/media/cast/audio_receiver/audio_receiver.h
@@ -34,6 +34,14 @@ class PacedPacketSender;
class RtpReceiver;
class RtpReceiverStatistics;
+struct DecodedAudioCallbackData {
+ DecodedAudioCallbackData();
+ ~DecodedAudioCallbackData();
+ int number_of_10ms_blocks;
+ int desired_frequency;
+ AudioFrameDecodedCallback callback;
+};
+
// This class is not thread safe. Should only be called from the Main cast
// thread.
class AudioReceiver : public base::NonThreadSafe,
@@ -126,6 +134,7 @@ class AudioReceiver : public base::NonThreadSafe,
std::string iv_mask_;
std::list<AudioFrameEncodedCallback> queued_encoded_callbacks_;
+ std::list<DecodedAudioCallbackData> queued_decoded_callbacks_;
};
} // namespace cast
diff --git a/media/cast/test/receiver.cc b/media/cast/test/receiver.cc
index 356d14a9..1321f53 100644
--- a/media/cast/test/receiver.cc
+++ b/media/cast/test/receiver.cc
@@ -29,13 +29,13 @@
namespace media {
namespace cast {
-
+// Settings chosen to match default sender settings.
#define DEFAULT_SEND_PORT "2346"
#define DEFAULT_RECEIVE_PORT "2344"
#define DEFAULT_SEND_IP "127.0.0.1"
#define DEFAULT_RESTART "0"
-#define DEFAULT_AUDIO_FEEDBACK_SSRC "2"
-#define DEFAULT_AUDIO_INCOMING_SSRC "1"
+#define DEFAULT_AUDIO_FEEDBACK_SSRC "1"
+#define DEFAULT_AUDIO_INCOMING_SSRC "2"
#define DEFAULT_AUDIO_PAYLOAD_TYPE "127"
#define DEFAULT_VIDEO_FEEDBACK_SSRC "12"
#define DEFAULT_VIDEO_INCOMING_SSRC "11"
@@ -180,7 +180,7 @@ class ReceiveProcess : public base::RefCountedThreadSafe<ReceiveProcess> {
base::TimeDelta::FromMilliseconds(kFrameTimerMs);
if (!last_playout_time_.is_null()){
time_diff = playout_time - last_playout_time_;
- VLOG(0) << " PlayoutDelay[mS] = " << time_diff.InMilliseconds();
+ VLOG(0) << " ***PlayoutDelay[mS] = " << time_diff.InMilliseconds();
}
last_playout_time_ = playout_time;
GetAudioFrame(time_diff);
diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc
index 4e491bf..e4c26de 100644
--- a/media/cast/test/sender.cc
+++ b/media/cast/test/sender.cc
@@ -21,6 +21,9 @@
#include "media/cast/test/video_utility.h"
#include "ui/gfx/size.h"
+namespace media {
+namespace cast {
+// Settings chosen to match default receiver settings.
#define DEFAULT_SEND_PORT "2344"
#define DEFAULT_RECEIVE_PORT "2346"
#define DEFAULT_SEND_IP "127.0.0.1"
@@ -38,9 +41,6 @@
#define DEFAULT_VIDEO_CODEC_MAX_BITRATE "4000"
#define DEFAULT_VIDEO_CODEC_MIN_BITRATE "1000"
-namespace media {
-namespace cast {
-
namespace {
static const int kAudioChannels = 2;
static const int kAudioSamplingFrequency = 48000;
@@ -49,6 +49,12 @@ static const int kSoundFrequency = 1234; // Frequency of sinusoid wave.
// a normal video is 30 fps hence the 33 ms between frames.
static const float kSoundVolume = 0.5f;
static const int kFrameTimerMs = 33;
+
+// Dummy callback function that does nothing except to accept ownership of
+// |audio_bus| for destruction. This guarantees that the audio_bus is valid for
+// the entire duration of the encode/send process (not equivalent to DoNothing).
+void OwnThatAudioBus(scoped_ptr<AudioBus> audio_bus) {
+}
} // namespace
void GetPorts(int* tx_port, int* rx_port) {
@@ -231,7 +237,7 @@ class SendProcess {
base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks));
AudioBus* const audio_bus_ptr = audio_bus.get();
frame_input_->InsertAudio(audio_bus_ptr, clock_->NowTicks(),
- base::Bind(base::DoNothing));
+ base::Bind(&OwnThatAudioBus, base::Passed(&audio_bus)));
gfx::Size size(video_config_.width, video_config_.height);
// TODO(mikhal): Use the provided timestamp.
diff --git a/media/cast/test/transport/transport.cc b/media/cast/test/transport/transport.cc
index 32ee246..9312470 100644
--- a/media/cast/test/transport/transport.cc
+++ b/media/cast/test/transport/transport.cc
@@ -114,8 +114,7 @@ class LocalPacketSender : public PacketSender,
virtual bool SendPacket(const Packet& packet) OVERRIDE {
io_thread_proxy_->PostTask(FROM_HERE,
- base::Bind(&LocalPacketSender::SendPacketToNetwork,
- this, packet));
+ base::Bind(&LocalPacketSender::SendPacketToNetwork, this, packet));
return true;
}
@@ -128,6 +127,7 @@ class LocalPacketSender : public PacketSender,
VLOG(1) << "Drop packet f:" << static_cast<int>(data[12 + 1])
<< " p:" << static_cast<int>(data[12 + 3])
<< " m:" << static_cast<int>(data[12 + 5]);
+ return;
}
}
net::TestCompletionCallback callback;