summaryrefslogtreecommitdiff
path: root/media/base/android/media_source_player.cc
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2013-08-05 13:57:33 +0100
committerTorne (Richard Coles) <torne@google.com>2013-08-05 13:57:33 +0100
commita36e5920737c6adbddd3e43b760e5de8431db6e0 (patch)
tree347d048bb8c8828d50113bf94ace40bf0613f2cd /media/base/android/media_source_player.cc
parent34378da0e9429d394aafdaa771301aff58447cb1 (diff)
downloadchromium_org-a36e5920737c6adbddd3e43b760e5de8431db6e0.tar.gz
Merge from Chromium at DEPS revision r215573
This commit was generated by merge_to_master.py. Change-Id: Ib95814f98e5765b459dd32425f9bf9138edf2bca
Diffstat (limited to 'media/base/android/media_source_player.cc')
-rw-r--r--media/base/android/media_source_player.cc120
1 files changed, 80 insertions, 40 deletions
diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc
index 5673b926a0..5d4aa98b66 100644
--- a/media/base/android/media_source_player.cc
+++ b/media/base/android/media_source_player.cc
@@ -22,7 +22,7 @@ namespace {
// Timeout value for media codec operations. Because the first
// DequeInputBuffer() can take about 150 milliseconds, use 250 milliseconds
// here. See b/9357571.
-const int kMediaCodecTimeoutInMicroseconds = 250000;
+const int kMediaCodecTimeoutInMilliseconds = 250;
// Use 16bit PCM for audio output. Keep this value in sync with the output
// format we passed to AudioTrack in MediaCodecBridge.
@@ -82,6 +82,8 @@ class AudioDecoderJob : public MediaDecoderJob {
const AudioCodec audio_codec, int sample_rate, int channel_count,
const uint8* extra_data, size_t extra_data_size, jobject media_crypto);
+ void SetVolume(double volume);
+
private:
AudioDecoderJob(MediaCodecBridge* media_codec_bridge);
};
@@ -100,7 +102,7 @@ class VideoDecoderJob : public MediaDecoderJob {
};
void MediaDecoderJob::Decode(
- const MediaPlayerHostMsg_ReadFromDemuxerAck_Params::AccessUnit& unit,
+ const AccessUnit& unit,
const base::TimeTicks& start_time_ticks,
const base::TimeDelta& start_presentation_timestamp,
const MediaDecoderJob::DecoderCallback& callback) {
@@ -114,43 +116,55 @@ void MediaDecoderJob::Decode(
needs_flush_ = false;
}
+MediaDecoderJob::DecodeStatus MediaDecoderJob::QueueInputBuffer(
+ const AccessUnit& unit) {
+ base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
+ kMediaCodecTimeoutInMilliseconds);
+ int input_buf_index = media_codec_bridge_->DequeueInputBuffer(timeout);
+ if (input_buf_index == MediaCodecBridge::INFO_MEDIA_CODEC_ERROR)
+ return DECODE_FAILED;
+ if (input_buf_index == MediaCodecBridge::INFO_TRY_AGAIN_LATER)
+ return DECODE_TRY_ENQUEUE_INPUT_AGAIN_LATER;
+
+ // TODO(qinmin): skip frames if video is falling far behind.
+ DCHECK(input_buf_index >= 0);
+ if (unit.end_of_stream || unit.data.empty()) {
+ media_codec_bridge_->QueueEOS(input_buf_index);
+ } else if (unit.key_id.empty()) {
+ media_codec_bridge_->QueueInputBuffer(
+ input_buf_index, &unit.data[0], unit.data.size(), unit.timestamp);
+ } else {
+ if (unit.iv.empty() || unit.subsamples.empty()) {
+ LOG(ERROR) << "The access unit doesn't have iv or subsamples while it "
+ << "has key IDs!";
+ return DECODE_FAILED;
+ }
+ media_codec_bridge_->QueueSecureInputBuffer(
+ input_buf_index, &unit.data[0], unit.data.size(),
+ reinterpret_cast<const uint8*>(&unit.key_id[0]), unit.key_id.size(),
+ reinterpret_cast<const uint8*>(&unit.iv[0]), unit.iv.size(),
+ &unit.subsamples[0], unit.subsamples.size(), unit.timestamp);
+ }
+
+ return DECODE_SUCCEEDED;
+}
+
void MediaDecoderJob::DecodeInternal(
- const MediaPlayerHostMsg_ReadFromDemuxerAck_Params::AccessUnit& unit,
+ const AccessUnit& unit,
const base::TimeTicks& start_time_ticks,
const base::TimeDelta& start_presentation_timestamp,
bool needs_flush,
const MediaDecoderJob::DecoderCallback& callback) {
- if (needs_flush)
+ if (needs_flush) {
+ DVLOG(1) << "DecodeInternal needs flush.";
media_codec_bridge_->Reset();
- base::TimeDelta timeout = base::TimeDelta::FromMicroseconds(
- kMediaCodecTimeoutInMicroseconds);
- int input_buf_index = media_codec_bridge_->DequeueInputBuffer(timeout);
- if (input_buf_index == MediaCodecBridge::INFO_MEDIA_CODEC_ERROR) {
- ui_loop_->PostTask(FROM_HERE, base::Bind(
- callback, DECODE_FAILED, start_presentation_timestamp, 0));
- return;
}
- // TODO(qinmin): skip frames if video is falling far behind.
- if (input_buf_index >= 0) {
- if (unit.end_of_stream || unit.data.empty()) {
- media_codec_bridge_->QueueEOS(input_buf_index);
- } else if (unit.key_id.empty()){
- media_codec_bridge_->QueueInputBuffer(
- input_buf_index, &unit.data[0], unit.data.size(), unit.timestamp);
- } else {
- if (unit.iv.empty() || unit.subsamples.empty()) {
- LOG(ERROR) << "The access unit doesn't have iv or subsamples while it "
- << "has key IDs!";
- ui_loop_->PostTask(FROM_HERE, base::Bind(
- callback, DECODE_FAILED, start_presentation_timestamp, 0));
- return;
- }
- media_codec_bridge_->QueueSecureInputBuffer(
- input_buf_index, &unit.data[0], unit.data.size(),
- reinterpret_cast<const uint8*>(&unit.key_id[0]), unit.key_id.size(),
- reinterpret_cast<const uint8*>(&unit.iv[0]), unit.iv.size(),
- &unit.subsamples[0], unit.subsamples.size(), unit.timestamp);
- }
+
+ DecodeStatus decode_status = QueueInputBuffer(unit);
+ if (decode_status != DECODE_SUCCEEDED) {
+ ui_loop_->PostTask(FROM_HERE,
+ base::Bind(callback, decode_status, start_presentation_timestamp, 0));
+ return;
}
size_t offset = 0;
@@ -158,9 +172,11 @@ void MediaDecoderJob::DecodeInternal(
base::TimeDelta presentation_timestamp;
bool end_of_stream = false;
+ base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
+ kMediaCodecTimeoutInMilliseconds);
int outputBufferIndex = media_codec_bridge_->DequeueOutputBuffer(
timeout, &offset, &size, &presentation_timestamp, &end_of_stream);
- DecodeStatus decode_status = DECODE_SUCCEEDED;
+
if (end_of_stream)
decode_status = DECODE_END_OF_STREAM;
switch (outputBufferIndex) {
@@ -172,7 +188,7 @@ void MediaDecoderJob::DecodeInternal(
decode_status = DECODE_FORMAT_CHANGED;
break;
case MediaCodecBridge::INFO_TRY_AGAIN_LATER:
- decode_status = DECODE_TRY_AGAIN_LATER;
+ decode_status = DECODE_TRY_DEQUEUE_OUTPUT_AGAIN_LATER;
break;
case MediaCodecBridge::INFO_MEDIA_CODEC_ERROR:
decode_status = DECODE_FAILED;
@@ -257,7 +273,7 @@ VideoDecoderJob* VideoDecoderJob::Create(
const VideoCodec video_codec, const gfx::Size& size, jobject surface,
jobject media_crypto) {
scoped_ptr<VideoCodecBridge> codec(VideoCodecBridge::Create(video_codec));
- if (codec->Start(video_codec, size, surface, media_crypto))
+ if (codec && codec->Start(video_codec, size, surface, media_crypto))
return new VideoDecoderJob(codec.release());
return NULL;
}
@@ -275,8 +291,8 @@ AudioDecoderJob* AudioDecoderJob::Create(
size_t extra_data_size,
jobject media_crypto) {
scoped_ptr<AudioCodecBridge> codec(AudioCodecBridge::Create(audio_codec));
- if (codec->Start(audio_codec, sample_rate, channel_count, extra_data,
- extra_data_size, true, media_crypto)) {
+ if (codec && codec->Start(audio_codec, sample_rate, channel_count, extra_data,
+ extra_data_size, true, media_crypto)) {
return new AudioDecoderJob(codec.release());
}
return NULL;
@@ -287,6 +303,10 @@ AudioDecoderJob::AudioDecoderJob(MediaCodecBridge* media_codec_bridge)
media_codec_bridge,
true) {}
+void AudioDecoderJob::SetVolume(double volume) {
+ static_cast<AudioCodecBridge*>(media_codec_bridge_.get())->SetVolume(volume);
+}
+
MediaSourcePlayer::MediaSourcePlayer(
int player_id,
MediaPlayerManager* manager)
@@ -304,6 +324,7 @@ MediaSourcePlayer::MediaSourcePlayer(
playing_(false),
is_audio_encrypted_(false),
is_video_encrypted_(false),
+ volume_(-1.0),
clock_(&default_tick_clock_),
reconfig_audio_decoder_(false),
reconfig_video_decoder_(false),
@@ -407,7 +428,9 @@ void MediaSourcePlayer::Release() {
ReleaseMediaResourcesFromManager();
}
-void MediaSourcePlayer::SetVolume(float leftVolume, float rightVolume) {
+void MediaSourcePlayer::SetVolume(double volume) {
+ volume_ = volume;
+ SetVolumeInternal();
}
bool MediaSourcePlayer::CanPause() {
@@ -546,6 +569,7 @@ void MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) {
}
void MediaSourcePlayer::OnSeekRequestAck(unsigned seek_request_id) {
+ DVLOG(1) << "OnSeekRequestAck(" << seek_request_id << ")";
// Do nothing until the most recent seek request is processed.
if (seek_request_id_ != seek_request_id)
return;
@@ -613,7 +637,9 @@ void MediaSourcePlayer::MediaDecoderCallback(
Release();
OnMediaError(MEDIA_ERROR_DECODE);
return;
- } else if (decode_status == MediaDecoderJob::DECODE_SUCCEEDED) {
+ }
+
+ if (decode_status != MediaDecoderJob::DECODE_TRY_ENQUEUE_INPUT_AGAIN_LATER) {
if (is_audio)
audio_access_unit_index_++;
else
@@ -698,6 +724,7 @@ void MediaSourcePlayer::DecodeMoreAudio() {
}
void MediaSourcePlayer::DecodeMoreVideo() {
+ DVLOG(1) << "DecodeMoreVideo()";
DCHECK(!video_decoder_job_->is_decoding());
DCHECK(HasVideoData());
@@ -712,6 +739,9 @@ void MediaSourcePlayer::DecodeMoreVideo() {
return;
}
+ DVLOG(3) << "VideoDecoderJob::Decode(" << video_access_unit_index_ << ", "
+ << start_time_ticks_.ToInternalValue() << ", "
+ << start_presentation_timestamp_.InMilliseconds() << ")";
video_decoder_job_->Decode(
received_video_.access_units[video_access_unit_index_],
start_time_ticks_, start_presentation_timestamp_,
@@ -734,6 +764,7 @@ void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
}
void MediaSourcePlayer::ClearDecodingData() {
+ DVLOG(1) << "ClearDecodingData()";
if (audio_decoder_job_)
audio_decoder_job_->Flush();
if (video_decoder_job_)
@@ -786,8 +817,10 @@ void MediaSourcePlayer::ConfigureAudioDecoderJob() {
audio_codec_, sampling_rate_, num_channels_, &audio_extra_data_[0],
audio_extra_data_.size(), media_codec.obj()));
- if (audio_decoder_job_)
+ if (audio_decoder_job_) {
+ SetVolumeInternal();
reconfig_audio_decoder_ = false;
+ }
}
void MediaSourcePlayer::ConfigureVideoDecoderJob() {
@@ -866,6 +899,7 @@ void MediaSourcePlayer::SyncAndStartDecoderJobs() {
}
void MediaSourcePlayer::RequestAudioData() {
+ DVLOG(2) << "RequestAudioData()";
DCHECK(HasAudio());
if (waiting_for_audio_data_)
@@ -878,6 +912,7 @@ void MediaSourcePlayer::RequestAudioData() {
}
void MediaSourcePlayer::RequestVideoData() {
+ DVLOG(2) << "RequestVideoData()";
DCHECK(HasVideo());
if (waiting_for_video_data_)
return;
@@ -896,4 +931,9 @@ bool MediaSourcePlayer::HasVideoData() const {
return video_access_unit_index_ < received_video_.access_units.size();
}
+void MediaSourcePlayer::SetVolumeInternal() {
+ if (audio_decoder_job_ && volume_ >= 0)
+ audio_decoder_job_.get()->SetVolume(volume_);
+}
+
} // namespace media