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

Side by Side Diff: media/mp4/mp4_stream_parser.cc

Issue 11471006: Log MediaSource parsing errors to the MediaLog so they can appear in chrome:media-internals. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix nit. Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « media/mp4/mp4_stream_parser.h ('k') | media/mp4/mp4_stream_parser_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/mp4/mp4_stream_parser.h" 5 #include "media/mp4/mp4_stream_parser.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 24 matching lines...) Expand all
35 } 35 }
36 36
37 MP4StreamParser::~MP4StreamParser() {} 37 MP4StreamParser::~MP4StreamParser() {}
38 38
39 void MP4StreamParser::Init(const InitCB& init_cb, 39 void MP4StreamParser::Init(const InitCB& init_cb,
40 const NewConfigCB& config_cb, 40 const NewConfigCB& config_cb,
41 const NewBuffersCB& audio_cb, 41 const NewBuffersCB& audio_cb,
42 const NewBuffersCB& video_cb, 42 const NewBuffersCB& video_cb,
43 const NeedKeyCB& need_key_cb, 43 const NeedKeyCB& need_key_cb,
44 const NewMediaSegmentCB& new_segment_cb, 44 const NewMediaSegmentCB& new_segment_cb,
45 const base::Closure& end_of_segment_cb) { 45 const base::Closure& end_of_segment_cb,
46 const LogCB& log_cb) {
46 DCHECK_EQ(state_, kWaitingForInit); 47 DCHECK_EQ(state_, kWaitingForInit);
47 DCHECK(init_cb_.is_null()); 48 DCHECK(init_cb_.is_null());
48 DCHECK(!init_cb.is_null()); 49 DCHECK(!init_cb.is_null());
49 DCHECK(!config_cb.is_null()); 50 DCHECK(!config_cb.is_null());
50 DCHECK(!audio_cb.is_null() || !video_cb.is_null()); 51 DCHECK(!audio_cb.is_null() || !video_cb.is_null());
51 DCHECK(!need_key_cb.is_null()); 52 DCHECK(!need_key_cb.is_null());
52 DCHECK(!end_of_segment_cb.is_null()); 53 DCHECK(!end_of_segment_cb.is_null());
53 54
54 ChangeState(kParsingBoxes); 55 ChangeState(kParsingBoxes);
55 init_cb_ = init_cb; 56 init_cb_ = init_cb;
56 config_cb_ = config_cb; 57 config_cb_ = config_cb;
57 audio_cb_ = audio_cb; 58 audio_cb_ = audio_cb;
58 video_cb_ = video_cb; 59 video_cb_ = video_cb;
59 need_key_cb_ = need_key_cb; 60 need_key_cb_ = need_key_cb;
60 new_segment_cb_ = new_segment_cb; 61 new_segment_cb_ = new_segment_cb;
61 end_of_segment_cb_ = end_of_segment_cb; 62 end_of_segment_cb_ = end_of_segment_cb;
63 log_cb_ = log_cb;
62 } 64 }
63 65
64 void MP4StreamParser::Reset() { 66 void MP4StreamParser::Reset() {
65 queue_.Reset(); 67 queue_.Reset();
66 moov_.reset(); 68 moov_.reset();
67 runs_.reset(); 69 runs_.reset();
68 moof_head_ = 0; 70 moof_head_ = 0;
69 mdat_tail_ = 0; 71 mdat_tail_ = 0;
70 } 72 }
71 73
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 115
114 return true; 116 return true;
115 } 117 }
116 118
117 bool MP4StreamParser::ParseBox(bool* err) { 119 bool MP4StreamParser::ParseBox(bool* err) {
118 const uint8* buf; 120 const uint8* buf;
119 int size; 121 int size;
120 queue_.Peek(&buf, &size); 122 queue_.Peek(&buf, &size);
121 if (!size) return false; 123 if (!size) return false;
122 124
123 scoped_ptr<BoxReader> reader(BoxReader::ReadTopLevelBox(buf, size, err)); 125 scoped_ptr<BoxReader> reader(
126 BoxReader::ReadTopLevelBox(buf, size, log_cb_, err));
124 if (reader.get() == NULL) return false; 127 if (reader.get() == NULL) return false;
125 128
126 if (reader->type() == FOURCC_MOOV) { 129 if (reader->type() == FOURCC_MOOV) {
127 *err = !ParseMoov(reader.get()); 130 *err = !ParseMoov(reader.get());
128 } else if (reader->type() == FOURCC_MOOF) { 131 } else if (reader->type() == FOURCC_MOOF) {
129 moof_head_ = queue_.head(); 132 moof_head_ = queue_.head();
130 *err = !ParseMoof(reader.get()); 133 *err = !ParseMoof(reader.get());
131 134
132 // Set up first mdat offset for ReadMDATsUntil(). 135 // Set up first mdat offset for ReadMDATsUntil().
133 mdat_tail_ = queue_.head() + reader->size(); 136 mdat_tail_ = queue_.head() + reader->size();
134 137
135 // Return early to avoid evicting 'moof' data from queue. Auxiliary info may 138 // Return early to avoid evicting 'moof' data from queue. Auxiliary info may
136 // be located anywhere in the file, including inside the 'moof' itself. 139 // be located anywhere in the file, including inside the 'moof' itself.
137 // (Since 'default-base-is-moof' is mandated, no data references can come 140 // (Since 'default-base-is-moof' is mandated, no data references can come
138 // before the head of the 'moof', so keeping this box around is sufficient.) 141 // before the head of the 'moof', so keeping this box around is sufficient.)
139 return !(*err); 142 return !(*err);
140 } else { 143 } else {
141 DVLOG(2) << "Skipping unrecognized top-level box: " 144 MEDIA_LOG(log_cb_) << "Skipping unrecognized top-level box: "
142 << FourCCToString(reader->type()); 145 << FourCCToString(reader->type());
143 } 146 }
144 147
145 queue_.Pop(reader->size()); 148 queue_.Pop(reader->size());
146 return !(*err); 149 return !(*err);
147 } 150 }
148 151
149 152
150 bool MP4StreamParser::ParseMoov(BoxReader* reader) { 153 bool MP4StreamParser::ParseMoov(BoxReader* reader) {
151 moov_.reset(new Movie); 154 moov_.reset(new Movie);
152 RCHECK(moov_->Parse(reader)); 155 RCHECK(moov_->Parse(reader));
153 runs_.reset(new TrackRunIterator(moov_.get())); 156 runs_.reset(new TrackRunIterator(moov_.get(), log_cb_));
154 157
155 has_audio_ = false; 158 has_audio_ = false;
156 has_video_ = false; 159 has_video_ = false;
157 160
158 AudioDecoderConfig audio_config; 161 AudioDecoderConfig audio_config;
159 VideoDecoderConfig video_config; 162 VideoDecoderConfig video_config;
160 163
161 for (std::vector<Track>::const_iterator track = moov_->tracks.begin(); 164 for (std::vector<Track>::const_iterator track = moov_->tracks.begin();
162 track != moov_->tracks.end(); ++track) { 165 track != moov_->tracks.end(); ++track) {
163 // TODO(strobe): Only the first audio and video track present in a file are 166 // TODO(strobe): Only the first audio and video track present in a file are
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 std::vector<SubsampleEntry> subsamples; 408 std::vector<SubsampleEntry> subsamples;
406 if (runs_->is_encrypted()) { 409 if (runs_->is_encrypted()) {
407 decrypt_config = runs_->GetDecryptConfig(); 410 decrypt_config = runs_->GetDecryptConfig();
408 subsamples = decrypt_config->subsamples(); 411 subsamples = decrypt_config->subsamples();
409 } 412 }
410 413
411 std::vector<uint8> frame_buf(buf, buf + runs_->sample_size()); 414 std::vector<uint8> frame_buf(buf, buf + runs_->sample_size());
412 if (video) { 415 if (video) {
413 if (!PrepareAVCBuffer(runs_->video_description().avcc, 416 if (!PrepareAVCBuffer(runs_->video_description().avcc,
414 &frame_buf, &subsamples)) { 417 &frame_buf, &subsamples)) {
415 DLOG(ERROR) << "Failed to prepare AVC sample for decode"; 418 MEDIA_LOG(log_cb_) << "Failed to prepare AVC sample for decode";
416 *err = true; 419 *err = true;
417 return false; 420 return false;
418 } 421 }
419 } 422 }
420 423
421 if (audio) { 424 if (audio) {
422 if (!PrepareAACBuffer(runs_->audio_description().esds.aac, 425 if (!PrepareAACBuffer(runs_->audio_description().esds.aac,
423 &frame_buf, &subsamples)) { 426 &frame_buf, &subsamples)) {
424 DLOG(ERROR) << "Failed to prepare AAC sample for decode"; 427 MEDIA_LOG(log_cb_) << "Failed to prepare AAC sample for decode";
425 *err = true; 428 *err = true;
426 return false; 429 return false;
427 } 430 }
428 } 431 }
429 432
430 if (decrypt_config.get() != NULL && !subsamples.empty()) { 433 if (decrypt_config.get() != NULL && !subsamples.empty()) {
431 decrypt_config.reset(new DecryptConfig( 434 decrypt_config.reset(new DecryptConfig(
432 decrypt_config->key_id(), 435 decrypt_config->key_id(),
433 decrypt_config->iv(), 436 decrypt_config->iv(),
434 decrypt_config->data_offset(), 437 decrypt_config->data_offset(),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 482
480 bool MP4StreamParser::ReadAndDiscardMDATsUntil(const int64 offset) { 483 bool MP4StreamParser::ReadAndDiscardMDATsUntil(const int64 offset) {
481 bool err = false; 484 bool err = false;
482 while (mdat_tail_ < offset) { 485 while (mdat_tail_ < offset) {
483 const uint8* buf; 486 const uint8* buf;
484 int size; 487 int size;
485 queue_.PeekAt(mdat_tail_, &buf, &size); 488 queue_.PeekAt(mdat_tail_, &buf, &size);
486 489
487 FourCC type; 490 FourCC type;
488 int box_sz; 491 int box_sz;
489 if (!BoxReader::StartTopLevelBox(buf, size, &type, &box_sz, &err)) 492 if (!BoxReader::StartTopLevelBox(buf, size, log_cb_,
493 &type, &box_sz, &err))
490 break; 494 break;
491 495
492 if (type != FOURCC_MDAT) { 496 if (type != FOURCC_MDAT) {
493 DLOG(WARNING) << "Unexpected box type while parsing MDATs: " 497 MEDIA_LOG(log_cb_) << "Unexpected box type while parsing MDATs: "
494 << FourCCToString(type); 498 << FourCCToString(type);
495 } 499 }
496 mdat_tail_ += box_sz; 500 mdat_tail_ += box_sz;
497 } 501 }
498 queue_.Trim(std::min(mdat_tail_, offset)); 502 queue_.Trim(std::min(mdat_tail_, offset));
499 return !err; 503 return !err;
500 } 504 }
501 505
502 void MP4StreamParser::ChangeState(State new_state) { 506 void MP4StreamParser::ChangeState(State new_state) {
503 DVLOG(2) << "Changing state: " << new_state; 507 DVLOG(2) << "Changing state: " << new_state;
504 state_ = new_state; 508 state_ = new_state;
505 } 509 }
506 510
507 } // namespace mp4 511 } // namespace mp4
508 } // namespace media 512 } // namespace media
OLDNEW
« no previous file with comments | « media/mp4/mp4_stream_parser.h ('k') | media/mp4/mp4_stream_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698