Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: media/formats/mp2t/mp2t_stream_parser.cc

Issue 2371783002: Remove stl_util's deletion functions from media/. (Closed)
Patch Set: wolenetz Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "media/formats/mp2t/mp2t_stream_parser.h" 5 #include "media/formats/mp2t/mp2t_stream_parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/stl_util.h"
13 #include "media/base/media_tracks.h" 12 #include "media/base/media_tracks.h"
14 #include "media/base/stream_parser_buffer.h" 13 #include "media/base/stream_parser_buffer.h"
15 #include "media/base/text_track_config.h" 14 #include "media/base/text_track_config.h"
16 #include "media/base/timestamp_constants.h" 15 #include "media/base/timestamp_constants.h"
17 #include "media/formats/mp2t/es_parser.h" 16 #include "media/formats/mp2t/es_parser.h"
18 #include "media/formats/mp2t/es_parser_adts.h" 17 #include "media/formats/mp2t/es_parser_adts.h"
19 #include "media/formats/mp2t/es_parser_h264.h" 18 #include "media/formats/mp2t/es_parser_h264.h"
20 #include "media/formats/mp2t/es_parser_mpeg1audio.h" 19 #include "media/formats/mp2t/es_parser_mpeg1audio.h"
21 #include "media/formats/mp2t/mp2t_common.h" 20 #include "media/formats/mp2t/mp2t_common.h"
22 #include "media/formats/mp2t/ts_packet.h" 21 #include "media/formats/mp2t/ts_packet.h"
(...skipping 15 matching lines...) Expand all
38 class PidState { 37 class PidState {
39 public: 38 public:
40 enum PidType { 39 enum PidType {
41 kPidPat, 40 kPidPat,
42 kPidPmt, 41 kPidPmt,
43 kPidAudioPes, 42 kPidAudioPes,
44 kPidVideoPes, 43 kPidVideoPes,
45 }; 44 };
46 45
47 PidState(int pid, 46 PidState(int pid,
48 PidType pid_tyoe, 47 PidType pid_type,
49 std::unique_ptr<TsSection> section_parser); 48 std::unique_ptr<TsSection> section_parser);
50 49
51 // Extract the content of the TS packet and parse it. 50 // Extract the content of the TS packet and parse it.
52 // Return true if successful. 51 // Return true if successful.
53 bool PushTsPacket(const TsPacket& ts_packet); 52 bool PushTsPacket(const TsPacket& ts_packet);
54 53
55 // Flush the PID state (possibly emitting some pending frames) 54 // Flush the PID state (possibly emitting some pending frames)
56 // and reset its state. 55 // and reset its state.
57 void Flush(); 56 void Flush();
58 57
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 160
162 Mp2tStreamParser::Mp2tStreamParser(bool sbr_in_mimetype) 161 Mp2tStreamParser::Mp2tStreamParser(bool sbr_in_mimetype)
163 : sbr_in_mimetype_(sbr_in_mimetype), 162 : sbr_in_mimetype_(sbr_in_mimetype),
164 selected_audio_pid_(-1), 163 selected_audio_pid_(-1),
165 selected_video_pid_(-1), 164 selected_video_pid_(-1),
166 is_initialized_(false), 165 is_initialized_(false),
167 segment_started_(false) { 166 segment_started_(false) {
168 } 167 }
169 168
170 Mp2tStreamParser::~Mp2tStreamParser() { 169 Mp2tStreamParser::~Mp2tStreamParser() {
171 base::STLDeleteValues(&pids_);
172 } 170 }
173 171
174 void Mp2tStreamParser::Init( 172 void Mp2tStreamParser::Init(
175 const InitCB& init_cb, 173 const InitCB& init_cb,
176 const NewConfigCB& config_cb, 174 const NewConfigCB& config_cb,
177 const NewBuffersCB& new_buffers_cb, 175 const NewBuffersCB& new_buffers_cb,
178 bool /* ignore_text_tracks */, 176 bool /* ignore_text_tracks */,
179 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, 177 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
180 const NewMediaSegmentCB& new_segment_cb, 178 const NewMediaSegmentCB& new_segment_cb,
181 const EndMediaSegmentCB& end_of_segment_cb, 179 const EndMediaSegmentCB& end_of_segment_cb,
(...skipping 13 matching lines...) Expand all
195 encrypted_media_init_data_cb_ = encrypted_media_init_data_cb; 193 encrypted_media_init_data_cb_ = encrypted_media_init_data_cb;
196 new_segment_cb_ = new_segment_cb; 194 new_segment_cb_ = new_segment_cb;
197 end_of_segment_cb_ = end_of_segment_cb; 195 end_of_segment_cb_ = end_of_segment_cb;
198 media_log_ = media_log; 196 media_log_ = media_log;
199 } 197 }
200 198
201 void Mp2tStreamParser::Flush() { 199 void Mp2tStreamParser::Flush() {
202 DVLOG(1) << "Mp2tStreamParser::Flush"; 200 DVLOG(1) << "Mp2tStreamParser::Flush";
203 201
204 // Flush the buffers and reset the pids. 202 // Flush the buffers and reset the pids.
205 for (std::map<int, PidState*>::iterator it = pids_.begin(); 203 for (const auto& pid_pair : pids_) {
206 it != pids_.end(); ++it) { 204 DVLOG(1) << "Flushing PID: " << pid_pair.first;
207 DVLOG(1) << "Flushing PID: " << it->first; 205 pid_pair.second->Flush();
208 PidState* pid_state = it->second;
209 pid_state->Flush();
210 delete pid_state;
211 } 206 }
212 pids_.clear(); 207 pids_.clear();
213 208
214 // Flush is invoked from SourceBuffer.abort/SourceState::ResetParserState, and 209 // Flush is invoked from SourceBuffer.abort/SourceState::ResetParserState, and
215 // MSE spec prohibits emitting new configs in ResetParserState algorithm (see 210 // MSE spec prohibits emitting new configs in ResetParserState algorithm (see
216 // https://w3c.github.io/media-source/#sourcebuffer-reset-parser-state, 211 // https://w3c.github.io/media-source/#sourcebuffer-reset-parser-state,
217 // 3.5.2 Reset Parser State states that new frames might be processed only in 212 // 3.5.2 Reset Parser State states that new frames might be processed only in
218 // PARSING_MEDIA_SEGMENT and therefore doesn't allow emitting new configs, 213 // PARSING_MEDIA_SEGMENT and therefore doesn't allow emitting new configs,
219 // since that might need to run "init segment received" algorithm). 214 // since that might need to run "init segment received" algorithm).
220 // So before we emit remaining buffers here, we need to trim our buffer queue 215 // So before we emit remaining buffers here, we need to trim our buffer queue
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 if (!ts_packet) { 272 if (!ts_packet) {
278 DVLOG(1) << "Error: invalid TS packet"; 273 DVLOG(1) << "Error: invalid TS packet";
279 ts_byte_queue_.Pop(1); 274 ts_byte_queue_.Pop(1);
280 continue; 275 continue;
281 } 276 }
282 DVLOG(LOG_LEVEL_TS) 277 DVLOG(LOG_LEVEL_TS)
283 << "Processing PID=" << ts_packet->pid() 278 << "Processing PID=" << ts_packet->pid()
284 << " start_unit=" << ts_packet->payload_unit_start_indicator(); 279 << " start_unit=" << ts_packet->payload_unit_start_indicator();
285 280
286 // Parse the section. 281 // Parse the section.
287 std::map<int, PidState*>::iterator it = pids_.find(ts_packet->pid()); 282 auto it = pids_.find(ts_packet->pid());
288 if (it == pids_.end() && 283 if (it == pids_.end() &&
289 ts_packet->pid() == TsSection::kPidPat) { 284 ts_packet->pid() == TsSection::kPidPat) {
290 // Create the PAT state here if needed. 285 // Create the PAT state here if needed.
291 std::unique_ptr<TsSection> pat_section_parser(new TsSectionPat( 286 std::unique_ptr<TsSection> pat_section_parser(new TsSectionPat(
292 base::Bind(&Mp2tStreamParser::RegisterPmt, base::Unretained(this)))); 287 base::Bind(&Mp2tStreamParser::RegisterPmt, base::Unretained(this))));
293 std::unique_ptr<PidState> pat_pid_state(new PidState( 288 std::unique_ptr<PidState> pat_pid_state(new PidState(
294 ts_packet->pid(), PidState::kPidPat, std::move(pat_section_parser))); 289 ts_packet->pid(), PidState::kPidPat, std::move(pat_section_parser)));
295 pat_pid_state->Enable(); 290 pat_pid_state->Enable();
296 it = pids_.insert( 291 it = pids_
297 std::pair<int, PidState*>(ts_packet->pid(), 292 .insert(
298 pat_pid_state.release())).first; 293 std::make_pair(ts_packet->pid(), std::move(pat_pid_state)))
294 .first;
299 } 295 }
300 296
301 if (it != pids_.end()) { 297 if (it != pids_.end()) {
302 if (!it->second->PushTsPacket(*ts_packet)) 298 if (!it->second->PushTsPacket(*ts_packet))
303 return false; 299 return false;
304 } else { 300 } else {
305 DVLOG(LOG_LEVEL_TS) << "Ignoring TS packet for pid: " << ts_packet->pid(); 301 DVLOG(LOG_LEVEL_TS) << "Ignoring TS packet for pid: " << ts_packet->pid();
306 } 302 }
307 303
308 // Go to the next packet. 304 // Go to the next packet.
309 ts_byte_queue_.Pop(TsPacket::kPacketSize); 305 ts_byte_queue_.Pop(TsPacket::kPacketSize);
310 } 306 }
311 307
312 RCHECK(FinishInitializationIfNeeded()); 308 RCHECK(FinishInitializationIfNeeded());
313 309
314 // Emit the A/V buffers that kept accumulating during TS parsing. 310 // Emit the A/V buffers that kept accumulating during TS parsing.
315 return EmitRemainingBuffers(); 311 return EmitRemainingBuffers();
316 } 312 }
317 313
318 void Mp2tStreamParser::RegisterPmt(int program_number, int pmt_pid) { 314 void Mp2tStreamParser::RegisterPmt(int program_number, int pmt_pid) {
319 DVLOG(1) << "RegisterPmt:" 315 DVLOG(1) << "RegisterPmt:"
320 << " program_number=" << program_number 316 << " program_number=" << program_number
321 << " pmt_pid=" << pmt_pid; 317 << " pmt_pid=" << pmt_pid;
322 318
323 // Only one TS program is allowed. Ignore the incoming program map table, 319 // Only one TS program is allowed. Ignore the incoming program map table,
324 // if there is already one registered. 320 // if there is already one registered.
325 for (std::map<int, PidState*>::iterator it = pids_.begin(); 321 for (const auto& pid_pair : pids_) {
326 it != pids_.end(); ++it) { 322 PidState* pid_state = pid_pair.second.get();
327 PidState* pid_state = it->second;
328 if (pid_state->pid_type() == PidState::kPidPmt) { 323 if (pid_state->pid_type() == PidState::kPidPmt) {
329 DVLOG_IF(1, pmt_pid != it->first) << "More than one program is defined"; 324 DVLOG_IF(1, pmt_pid != pid_pair.first)
325 << "More than one program is defined";
330 return; 326 return;
331 } 327 }
332 } 328 }
333 329
334 // Create the PMT state here if needed. 330 // Create the PMT state here if needed.
335 DVLOG(1) << "Create a new PMT parser"; 331 DVLOG(1) << "Create a new PMT parser";
336 std::unique_ptr<TsSection> pmt_section_parser(new TsSectionPmt(base::Bind( 332 std::unique_ptr<TsSection> pmt_section_parser(new TsSectionPmt(base::Bind(
337 &Mp2tStreamParser::RegisterPes, base::Unretained(this), pmt_pid))); 333 &Mp2tStreamParser::RegisterPes, base::Unretained(this), pmt_pid)));
338 std::unique_ptr<PidState> pmt_pid_state( 334 std::unique_ptr<PidState> pmt_pid_state(
339 new PidState(pmt_pid, PidState::kPidPmt, std::move(pmt_section_parser))); 335 new PidState(pmt_pid, PidState::kPidPmt, std::move(pmt_section_parser)));
340 pmt_pid_state->Enable(); 336 pmt_pid_state->Enable();
341 pids_.insert(std::pair<int, PidState*>(pmt_pid, pmt_pid_state.release())); 337 pids_.insert(std::make_pair(pmt_pid, std::move(pmt_pid_state)));
342 } 338 }
343 339
344 void Mp2tStreamParser::RegisterPes(int pmt_pid, 340 void Mp2tStreamParser::RegisterPes(int pmt_pid,
345 int pes_pid, 341 int pes_pid,
346 int stream_type) { 342 int stream_type) {
347 // TODO(damienv): check there is no mismatch if the entry already exists. 343 // TODO(damienv): check there is no mismatch if the entry already exists.
348 DVLOG(1) << "RegisterPes:" 344 DVLOG(1) << "RegisterPes:"
349 << " pes_pid=" << pes_pid 345 << " pes_pid=" << pes_pid
350 << " stream_type=" << std::hex << stream_type << std::dec; 346 << " stream_type=" << std::hex << stream_type << std::dec;
351 std::map<int, PidState*>::iterator it = pids_.find(pes_pid); 347 auto it = pids_.find(pes_pid);
352 if (it != pids_.end()) 348 if (it != pids_.end())
353 return; 349 return;
354 350
355 // Create a stream parser corresponding to the stream type. 351 // Create a stream parser corresponding to the stream type.
356 bool is_audio = false; 352 bool is_audio = false;
357 std::unique_ptr<EsParser> es_parser; 353 std::unique_ptr<EsParser> es_parser;
358 if (stream_type == kStreamTypeAVC) { 354 if (stream_type == kStreamTypeAVC) {
359 es_parser.reset( 355 es_parser.reset(
360 new EsParserH264( 356 new EsParserH264(
361 base::Bind(&Mp2tStreamParser::OnVideoConfigChanged, 357 base::Bind(&Mp2tStreamParser::OnVideoConfigChanged,
(...skipping 26 matching lines...) Expand all
388 } 384 }
389 385
390 // Create the PES state here. 386 // Create the PES state here.
391 DVLOG(1) << "Create a new PES state"; 387 DVLOG(1) << "Create a new PES state";
392 std::unique_ptr<TsSection> pes_section_parser( 388 std::unique_ptr<TsSection> pes_section_parser(
393 new TsSectionPes(std::move(es_parser), &timestamp_unroller_)); 389 new TsSectionPes(std::move(es_parser), &timestamp_unroller_));
394 PidState::PidType pid_type = 390 PidState::PidType pid_type =
395 is_audio ? PidState::kPidAudioPes : PidState::kPidVideoPes; 391 is_audio ? PidState::kPidAudioPes : PidState::kPidVideoPes;
396 std::unique_ptr<PidState> pes_pid_state( 392 std::unique_ptr<PidState> pes_pid_state(
397 new PidState(pes_pid, pid_type, std::move(pes_section_parser))); 393 new PidState(pes_pid, pid_type, std::move(pes_section_parser)));
398 pids_.insert(std::pair<int, PidState*>(pes_pid, pes_pid_state.release())); 394 pids_.insert(std::make_pair(pes_pid, std::move(pes_pid_state)));
399 395
400 // A new PES pid has been added, the PID filter might change. 396 // A new PES pid has been added, the PID filter might change.
401 UpdatePidFilter(); 397 UpdatePidFilter();
402 } 398 }
403 399
404 void Mp2tStreamParser::UpdatePidFilter() { 400 void Mp2tStreamParser::UpdatePidFilter() {
405 // Applies the HLS rule to select the default audio/video PIDs: 401 // Applies the HLS rule to select the default audio/video PIDs:
406 // select the audio/video streams with the lowest PID. 402 // select the audio/video streams with the lowest PID.
407 // TODO(damienv): this can be changed when the StreamParser interface 403 // TODO(damienv): this can be changed when the StreamParser interface
408 // supports multiple audio/video streams. 404 // supports multiple audio/video streams.
409 PidMap::iterator lowest_audio_pid = pids_.end(); 405 auto lowest_audio_pid = pids_.end();
410 PidMap::iterator lowest_video_pid = pids_.end(); 406 auto lowest_video_pid = pids_.end();
411 for (PidMap::iterator it = pids_.begin(); it != pids_.end(); ++it) { 407 for (auto it = pids_.begin(); it != pids_.end(); ++it) {
412 int pid = it->first; 408 int pid = it->first;
413 PidState* pid_state = it->second; 409 PidState* pid_state = it->second.get();
414 if (pid_state->pid_type() == PidState::kPidAudioPes && 410 if (pid_state->pid_type() == PidState::kPidAudioPes &&
415 (lowest_audio_pid == pids_.end() || pid < lowest_audio_pid->first)) 411 (lowest_audio_pid == pids_.end() || pid < lowest_audio_pid->first))
416 lowest_audio_pid = it; 412 lowest_audio_pid = it;
417 if (pid_state->pid_type() == PidState::kPidVideoPes && 413 if (pid_state->pid_type() == PidState::kPidVideoPes &&
418 (lowest_video_pid == pids_.end() || pid < lowest_video_pid->first)) 414 (lowest_video_pid == pids_.end() || pid < lowest_video_pid->first))
419 lowest_video_pid = it; 415 lowest_video_pid = it;
420 } 416 }
421 417
422 // Enable both the lowest audio and video PIDs. 418 // Enable both the lowest audio and video PIDs.
423 if (lowest_audio_pid != pids_.end()) { 419 if (lowest_audio_pid != pids_.end()) {
424 DVLOG(1) << "Enable audio pid: " << lowest_audio_pid->first; 420 DVLOG(1) << "Enable audio pid: " << lowest_audio_pid->first;
425 lowest_audio_pid->second->Enable(); 421 lowest_audio_pid->second->Enable();
426 selected_audio_pid_ = lowest_audio_pid->first; 422 selected_audio_pid_ = lowest_audio_pid->first;
427 } 423 }
428 if (lowest_video_pid != pids_.end()) { 424 if (lowest_video_pid != pids_.end()) {
429 DVLOG(1) << "Enable video pid: " << lowest_video_pid->first; 425 DVLOG(1) << "Enable video pid: " << lowest_video_pid->first;
430 lowest_video_pid->second->Enable(); 426 lowest_video_pid->second->Enable();
431 selected_video_pid_ = lowest_video_pid->first; 427 selected_video_pid_ = lowest_video_pid->first;
432 } 428 }
433 429
434 // Disable all the other audio and video PIDs. 430 // Disable all the other audio and video PIDs.
435 for (PidMap::iterator it = pids_.begin(); it != pids_.end(); ++it) { 431 for (auto it = pids_.begin(); it != pids_.end(); ++it) {
436 PidState* pid_state = it->second; 432 PidState* pid_state = it->second.get();
437 if (it != lowest_audio_pid && it != lowest_video_pid && 433 if (it != lowest_audio_pid && it != lowest_video_pid &&
438 (pid_state->pid_type() == PidState::kPidAudioPes || 434 (pid_state->pid_type() == PidState::kPidAudioPes ||
439 pid_state->pid_type() == PidState::kPidVideoPes)) 435 pid_state->pid_type() == PidState::kPidVideoPes))
440 pid_state->Disable(); 436 pid_state->Disable();
441 } 437 }
442 } 438 }
443 439
444 void Mp2tStreamParser::OnVideoConfigChanged( 440 void Mp2tStreamParser::OnVideoConfigChanged(
445 int pes_pid, 441 int pes_pid,
446 const VideoDecoderConfig& video_decoder_config) { 442 const VideoDecoderConfig& video_decoder_config) {
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 // so that buffers with the same config can be added later on. 671 // so that buffers with the same config can be added later on.
676 BufferQueueWithConfig queue_with_config( 672 BufferQueueWithConfig queue_with_config(
677 true, last_audio_config, last_video_config); 673 true, last_audio_config, last_video_config);
678 buffer_queue_chain_.push_back(queue_with_config); 674 buffer_queue_chain_.push_back(queue_with_config);
679 675
680 return true; 676 return true;
681 } 677 }
682 678
683 } // namespace mp2t 679 } // namespace mp2t
684 } // namespace media 680 } // namespace media
OLDNEW
« no previous file with comments | « media/formats/mp2t/mp2t_stream_parser.h ('k') | media/formats/webm/webm_content_encodings_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698