OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/renderer/api/display_source/wifi_display/wifi_display_media
_pipeline.h" | 5 #include "extensions/renderer/api/display_source/wifi_display/wifi_display_media
_pipeline.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "content/public/renderer/render_thread.h" | 8 #include "content/public/renderer/render_thread.h" |
9 #include "content/public/renderer/video_encode_accelerator.h" | 9 #include "content/public/renderer/video_encode_accelerator.h" |
10 #include "extensions/renderer/api/display_source/wifi_display/wifi_display_eleme
ntary_stream_descriptor.h" | |
11 #include "extensions/renderer/api/display_source/wifi_display/wifi_display_eleme
ntary_stream_info.h" | |
12 | 10 |
13 namespace extensions { | 11 namespace extensions { |
14 | 12 |
15 namespace { | 13 namespace { |
16 | 14 |
| 15 const char kErrorAudioEncoderError[] = "Unrepairable audio encoder error"; |
17 const char kErrorVideoEncoderError[] = "Unrepairable video encoder error"; | 16 const char kErrorVideoEncoderError[] = "Unrepairable video encoder error"; |
18 const char kErrorUnableSendMedia[] = "Unable to send media"; | 17 const char kErrorUnableSendMedia[] = "Unable to send media"; |
19 | 18 |
20 } // namespace | 19 } // namespace |
21 | 20 |
22 WiFiDisplayMediaPipeline::WiFiDisplayMediaPipeline( | 21 WiFiDisplayMediaPipeline::WiFiDisplayMediaPipeline( |
23 wds::SessionType type, | 22 wds::SessionType type, |
24 const WiFiDisplayVideoEncoder::InitParameters& video_parameters, | 23 const WiFiDisplayVideoEncoder::InitParameters& video_parameters, |
25 const wds::AudioCodec& audio_codec, | 24 const wds::AudioCodec& audio_codec, |
26 const std::string& sink_ip_address, | 25 const std::string& sink_ip_address, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 video_encoder_->InsertRawVideoFrame(video_frame, reference_time); | 65 video_encoder_->InsertRawVideoFrame(video_frame, reference_time); |
67 } | 66 } |
68 | 67 |
69 void WiFiDisplayMediaPipeline::RequestIDRPicture() { | 68 void WiFiDisplayMediaPipeline::RequestIDRPicture() { |
70 DCHECK(video_encoder_); | 69 DCHECK(video_encoder_); |
71 video_encoder_->RequestIDRPicture(); | 70 video_encoder_->RequestIDRPicture(); |
72 } | 71 } |
73 | 72 |
74 enum WiFiDisplayMediaPipeline::InitializationStep : unsigned { | 73 enum WiFiDisplayMediaPipeline::InitializationStep : unsigned { |
75 INITIALIZE_FIRST, | 74 INITIALIZE_FIRST, |
76 INITIALIZE_VIDEO_ENCODER = INITIALIZE_FIRST, | 75 INITIALIZE_AUDIO_ENCODER = INITIALIZE_FIRST, |
| 76 INITIALIZE_VIDEO_ENCODER, |
77 INITIALIZE_MEDIA_PACKETIZER, | 77 INITIALIZE_MEDIA_PACKETIZER, |
78 INITIALIZE_MEDIA_SERVICE, | 78 INITIALIZE_MEDIA_SERVICE, |
79 INITIALIZE_LAST = INITIALIZE_MEDIA_SERVICE | 79 INITIALIZE_LAST = INITIALIZE_MEDIA_SERVICE |
80 }; | 80 }; |
81 | 81 |
82 void WiFiDisplayMediaPipeline::Initialize( | 82 void WiFiDisplayMediaPipeline::Initialize( |
83 const InitCompletionCallback& callback) { | 83 const InitCompletionCallback& callback) { |
84 DCHECK(!video_encoder_ && !packetizer_); | 84 DCHECK(!audio_encoder_ && !video_encoder_ && !packetizer_); |
85 OnInitialize(callback, INITIALIZE_FIRST, true); | 85 OnInitialize(callback, INITIALIZE_FIRST, true); |
86 } | 86 } |
87 | 87 |
88 void WiFiDisplayMediaPipeline::OnInitialize( | 88 void WiFiDisplayMediaPipeline::OnInitialize( |
89 const InitCompletionCallback& callback, | 89 const InitCompletionCallback& callback, |
90 InitializationStep current_step, | 90 InitializationStep current_step, |
91 bool success) { | 91 bool success) { |
92 if (!success) { | 92 if (!success) { |
93 callback.Run(false); | 93 callback.Run(false); |
94 return; | 94 return; |
95 } | 95 } |
96 | 96 |
97 InitStepCompletionCallback init_step_callback; | 97 InitStepCompletionCallback init_step_callback; |
98 if (current_step < INITIALIZE_LAST) { | 98 if (current_step < INITIALIZE_LAST) { |
99 InitializationStep next_step = | 99 InitializationStep next_step = |
100 static_cast<InitializationStep>(current_step + 1u); | 100 static_cast<InitializationStep>(current_step + 1u); |
101 init_step_callback = base::Bind(&WiFiDisplayMediaPipeline::OnInitialize, | 101 init_step_callback = base::Bind(&WiFiDisplayMediaPipeline::OnInitialize, |
102 weak_factory_.GetWeakPtr(), callback, next_step); | 102 weak_factory_.GetWeakPtr(), callback, next_step); |
103 } | 103 } |
104 | 104 |
105 switch (current_step) { | 105 switch (current_step) { |
| 106 case INITIALIZE_AUDIO_ENCODER: |
| 107 DCHECK(!audio_encoder_); |
| 108 if (type_ & wds::AudioSession) { |
| 109 auto result_callback = |
| 110 base::Bind(&WiFiDisplayMediaPipeline::OnAudioEncoderCreated, |
| 111 weak_factory_.GetWeakPtr(), init_step_callback); |
| 112 WiFiDisplayAudioEncoder::Create(audio_codec_, result_callback); |
| 113 } else { |
| 114 init_step_callback.Run(true); |
| 115 } |
| 116 break; |
106 case INITIALIZE_VIDEO_ENCODER: | 117 case INITIALIZE_VIDEO_ENCODER: |
107 DCHECK(!video_encoder_); | 118 DCHECK(!video_encoder_); |
108 if (type_ & wds::VideoSession) { | 119 if (type_ & wds::VideoSession) { |
109 auto result_callback = | 120 auto result_callback = |
110 base::Bind(&WiFiDisplayMediaPipeline::OnVideoEncoderCreated, | 121 base::Bind(&WiFiDisplayMediaPipeline::OnVideoEncoderCreated, |
111 weak_factory_.GetWeakPtr(), init_step_callback); | 122 weak_factory_.GetWeakPtr(), init_step_callback); |
112 WiFiDisplayVideoEncoder::Create(video_parameters_, result_callback); | 123 WiFiDisplayVideoEncoder::Create(video_parameters_, result_callback); |
113 } else { | 124 } else { |
114 init_step_callback.Run(true); | 125 init_step_callback.Run(true); |
115 } | 126 } |
(...skipping 15 matching lines...) Expand all Loading... |
131 void WiFiDisplayMediaPipeline::CreateMediaPacketizer() { | 142 void WiFiDisplayMediaPipeline::CreateMediaPacketizer() { |
132 DCHECK(!packetizer_); | 143 DCHECK(!packetizer_); |
133 std::vector<WiFiDisplayElementaryStreamInfo> stream_infos; | 144 std::vector<WiFiDisplayElementaryStreamInfo> stream_infos; |
134 | 145 |
135 if (type_ & wds::VideoSession) { | 146 if (type_ & wds::VideoSession) { |
136 DCHECK(video_encoder_); | 147 DCHECK(video_encoder_); |
137 stream_infos.push_back(video_encoder_->CreateElementaryStreamInfo()); | 148 stream_infos.push_back(video_encoder_->CreateElementaryStreamInfo()); |
138 } | 149 } |
139 | 150 |
140 if (type_ & wds::AudioSession) { | 151 if (type_ & wds::AudioSession) { |
141 using LPCMAudioStreamDescriptor = | 152 DCHECK(audio_encoder_); |
142 WiFiDisplayElementaryStreamDescriptor::LPCMAudioStream; | 153 stream_infos.push_back(audio_encoder_->CreateElementaryStreamInfo()); |
143 std::vector<WiFiDisplayElementaryStreamDescriptor> descriptors; | |
144 descriptors.emplace_back( | |
145 LPCMAudioStreamDescriptor::Create( | |
146 audio_codec_.modes.test(wds::LPCM_48K_16B_2CH) | |
147 ? LPCMAudioStreamDescriptor::SAMPLING_FREQUENCY_48K | |
148 : LPCMAudioStreamDescriptor::SAMPLING_FREQUENCY_44_1K, | |
149 LPCMAudioStreamDescriptor::BITS_PER_SAMPLE_16, | |
150 false, // emphasis_flag | |
151 LPCMAudioStreamDescriptor::NUMBER_OF_CHANNELS_STEREO)); | |
152 stream_infos.emplace_back(WiFiDisplayElementaryStreamInfo::AUDIO_LPCM, | |
153 std::move(descriptors)); | |
154 } | 154 } |
155 | 155 |
156 packetizer_.reset(new WiFiDisplayMediaPacketizer( | 156 packetizer_.reset(new WiFiDisplayMediaPacketizer( |
157 base::TimeDelta::FromMilliseconds(200), stream_infos, | 157 base::TimeDelta::FromMilliseconds(200), stream_infos, |
158 base::Bind(&WiFiDisplayMediaPipeline::OnPacketizedMediaDatagramPacket, | 158 base::Bind(&WiFiDisplayMediaPipeline::OnPacketizedMediaDatagramPacket, |
159 base::Unretained(this)))); | 159 base::Unretained(this)))); |
160 } | 160 } |
161 | 161 |
| 162 void WiFiDisplayMediaPipeline::OnAudioEncoderCreated( |
| 163 const InitStepCompletionCallback& callback, |
| 164 scoped_refptr<WiFiDisplayAudioEncoder> audio_encoder) { |
| 165 DCHECK(!audio_encoder_); |
| 166 |
| 167 if (!audio_encoder) { |
| 168 callback.Run(false); |
| 169 return; |
| 170 } |
| 171 |
| 172 audio_encoder_ = std::move(audio_encoder); |
| 173 auto encoded_callback = |
| 174 base::Bind(&WiFiDisplayMediaPipeline::OnEncodedAudioUnit, |
| 175 weak_factory_.GetWeakPtr()); |
| 176 auto error_callback = base::Bind(error_callback_, kErrorAudioEncoderError); |
| 177 audio_encoder_->SetCallbacks(encoded_callback, error_callback); |
| 178 |
| 179 callback.Run(true); |
| 180 } |
| 181 |
162 void WiFiDisplayMediaPipeline::OnVideoEncoderCreated( | 182 void WiFiDisplayMediaPipeline::OnVideoEncoderCreated( |
163 const InitStepCompletionCallback& callback, | 183 const InitStepCompletionCallback& callback, |
164 scoped_refptr<WiFiDisplayVideoEncoder> video_encoder) { | 184 scoped_refptr<WiFiDisplayVideoEncoder> video_encoder) { |
165 DCHECK(!video_encoder_); | 185 DCHECK(!video_encoder_); |
166 | 186 |
167 if (!video_encoder) { | 187 if (!video_encoder) { |
168 callback.Run(false); | 188 callback.Run(false); |
169 return; | 189 return; |
170 } | 190 } |
171 | 191 |
(...skipping 11 matching lines...) Expand all Loading... |
183 const InitCompletionCallback& callback) { | 203 const InitCompletionCallback& callback) { |
184 DCHECK(media_service_); | 204 DCHECK(media_service_); |
185 auto error_callback = base::Bind(error_callback_, kErrorUnableSendMedia); | 205 auto error_callback = base::Bind(error_callback_, kErrorUnableSendMedia); |
186 media_service_.set_connection_error_handler(error_callback); | 206 media_service_.set_connection_error_handler(error_callback); |
187 media_service_->SetDesinationPoint( | 207 media_service_->SetDesinationPoint( |
188 sink_ip_address_, | 208 sink_ip_address_, |
189 static_cast<int32_t>(sink_rtp_ports_.first), | 209 static_cast<int32_t>(sink_rtp_ports_.first), |
190 callback); | 210 callback); |
191 } | 211 } |
192 | 212 |
| 213 void WiFiDisplayMediaPipeline::OnEncodedAudioUnit( |
| 214 std::unique_ptr<WiFiDisplayEncodedFrame> unit) { |
| 215 DCHECK(packetizer_); |
| 216 const unsigned stream_index = (type_ & wds::VideoSession) ? 1u : 0u; |
| 217 if (!packetizer_->EncodeElementaryStreamUnit(stream_index, unit->bytes(), |
| 218 unit->size(), unit->key_frame, |
| 219 unit->pts, unit->dts, true)) { |
| 220 DVLOG(1) << "Couldn't write audio mpegts packet"; |
| 221 } |
| 222 } |
| 223 |
193 void WiFiDisplayMediaPipeline::OnEncodedVideoFrame( | 224 void WiFiDisplayMediaPipeline::OnEncodedVideoFrame( |
194 std::unique_ptr<WiFiDisplayEncodedFrame> frame) { | 225 std::unique_ptr<WiFiDisplayEncodedFrame> frame) { |
195 DCHECK(packetizer_); | 226 DCHECK(packetizer_); |
196 if (!packetizer_->EncodeElementaryStreamUnit(0u, frame->bytes(), | 227 if (!packetizer_->EncodeElementaryStreamUnit(0u, frame->bytes(), |
197 frame->size(), frame->key_frame, | 228 frame->size(), frame->key_frame, |
198 frame->pts, frame->dts, true)) { | 229 frame->pts, frame->dts, true)) { |
199 DVLOG(1) << "Couldn't write video mpegts packet"; | 230 DVLOG(1) << "Couldn't write video mpegts packet"; |
200 } | 231 } |
201 } | 232 } |
202 | 233 |
203 bool WiFiDisplayMediaPipeline::OnPacketizedMediaDatagramPacket( | 234 bool WiFiDisplayMediaPipeline::OnPacketizedMediaDatagramPacket( |
204 WiFiDisplayMediaDatagramPacket media_datagram_packet) { | 235 WiFiDisplayMediaDatagramPacket media_datagram_packet) { |
205 DCHECK(media_service_); | 236 DCHECK(media_service_); |
206 media_service_->SendMediaPacket(std::move(media_datagram_packet)); | 237 media_service_->SendMediaPacket(std::move(media_datagram_packet)); |
207 return true; | 238 return true; |
208 } | 239 } |
209 | 240 |
210 } // namespace extensions | 241 } // namespace extensions |
OLD | NEW |