OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/renderer/pepper/pepper_media_stream_audio_track_host.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/location.h" | |
9 #include "base/logging.h" | |
10 #include "base/message_loop/message_loop_proxy.h" | |
11 #include "ppapi/c/pp_errors.h" | |
12 #include "ppapi/c/ppb_audio_frame.h" | |
13 #include "ppapi/shared_impl/media_stream_frame.h" | |
14 | |
15 namespace { | |
16 | |
17 // TODO(penghuang): make it configurable. | |
18 const int32_t kNumberOfFrames = 4; | |
19 | |
20 } // namespace | |
21 | |
22 namespace content { | |
23 | |
24 PepperMediaStreamAudioTrackHost::PepperMediaStreamAudioTrackHost( | |
25 RendererPpapiHost* host, | |
26 PP_Instance instance, | |
27 PP_Resource resource, | |
28 const blink::WebMediaStreamTrack& track) | |
29 : PepperMediaStreamTrackHostBase(host, instance, resource), | |
30 track_(track), | |
31 connected_(false), | |
32 frame_data_size_(0), | |
33 main_message_loop_proxy_(base::MessageLoopProxy::current()), | |
34 weak_factory_(this) { | |
35 DCHECK(!track_.isNull()); | |
36 } | |
37 | |
38 PepperMediaStreamAudioTrackHost::~PepperMediaStreamAudioTrackHost() { | |
39 OnClose(); | |
40 } | |
41 | |
42 void PepperMediaStreamAudioTrackHost::InitFramesOnMainThread( | |
43 uint32_t number_of_frames, uint32_t frame_size) { | |
44 bool result = InitFrames(number_of_frames, frame_size); | |
45 DCHECK(result); | |
46 } | |
47 | |
48 void PepperMediaStreamAudioTrackHost::OnClose() { | |
49 if (connected_) { | |
50 MediaStreamAudioSink::RemoveFromAudioTrack(this, track_); | |
51 connected_ = false; | |
52 } | |
53 } | |
54 | |
55 void PepperMediaStreamAudioTrackHost::OnData(const int16* audio_data, | |
56 int sample_rate, | |
57 int number_of_channels, | |
58 int number_of_frames) { | |
59 DCHECK(audio_data); | |
60 DCHECK_EQ(sample_rate, audio_params_.sample_rate()); | |
61 DCHECK_EQ(number_of_channels, audio_params_.channels()); | |
62 DCHECK_EQ(number_of_frames, audio_params_.frames_per_buffer()); | |
63 | |
64 int32_t index = frame_buffer()->DequeueFrame(); | |
65 // Drop frames if the underlying buffer is full or not initialized. | |
66 if (index >= 0) { | |
67 // TODO(penghuang): support re-sampling, etc. | |
68 ppapi::MediaStreamFrame::Audio* frame = | |
69 &(frame_buffer()->GetFramePointer(index)->audio); | |
70 frame->header.size = frame_buffer()->frame_size(); | |
71 frame->header.type = ppapi::MediaStreamFrame::TYPE_AUDIO; | |
72 frame->timestamp = timestamp_.InMillisecondsF(); | |
73 frame->sample_rate = static_cast<PP_AudioSampleRate>(sample_rate); | |
74 frame->number_of_channels = number_of_channels; | |
75 frame->number_of_samples = number_of_channels * number_of_frames; | |
76 frame->data_size = frame_data_size_; | |
77 | |
78 memcpy(frame->data, audio_data, frame_data_size_); | |
79 SendEnqueueFrameMessageToPlugin(index); | |
80 } | |
81 timestamp_ += frame_duration_; | |
82 } | |
83 | |
84 void PepperMediaStreamAudioTrackHost::OnSetFormat( | |
85 const media::AudioParameters& params) { | |
86 DCHECK(!audio_params_.IsValid()); | |
87 DCHECK(params.IsValid()); | |
88 DCHECK_EQ(params.bits_per_sample(), 16); | |
89 | |
90 // TODO(penghuang): support setting format more than once. | |
91 audio_params_ = params; | |
92 frame_duration_ = audio_params_.GetBufferDuration(); | |
93 frame_data_size_ = audio_params_.GetBytesPerBuffer(); | |
94 int32_t size = sizeof(ppapi::MediaStreamFrame::Audio) + frame_data_size_; | |
dmichael (off chromium)
2014/01/16 22:34:20
I don't know if we care, but this size calculation
Peng
2014/01/17 00:23:49
Done.
| |
95 | |
96 main_message_loop_proxy_->PostTask( | |
dmichael (off chromium)
2014/01/16 22:34:20
What thread is this coming in on? Do you know the
Peng
2014/01/17 00:23:49
OnData() & OnSetFormat() are called from an Audio
| |
97 FROM_HERE, | |
98 base::Bind(&PepperMediaStreamAudioTrackHost::InitFramesOnMainThread, | |
99 weak_factory_.GetWeakPtr(), kNumberOfFrames, size)); | |
100 } | |
101 | |
102 void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { | |
103 if (!connected_) { | |
104 MediaStreamAudioSink::AddToAudioTrack(this, track_); | |
105 connected_ = true; | |
106 } | |
107 } | |
108 | |
109 } // namespace content | |
OLD | NEW |