OLD | NEW |
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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 bool MP4StreamParser::ParseMoov(BoxReader* reader) { | 147 bool MP4StreamParser::ParseMoov(BoxReader* reader) { |
148 moov_.reset(new Movie); | 148 moov_.reset(new Movie); |
149 RCHECK(moov_->Parse(reader)); | 149 RCHECK(moov_->Parse(reader)); |
150 runs_.reset(new TrackRunIterator(moov_.get())); | 150 runs_.reset(new TrackRunIterator(moov_.get())); |
151 | 151 |
152 has_audio_ = false; | 152 has_audio_ = false; |
153 has_video_ = false; | 153 has_video_ = false; |
154 | 154 |
155 AudioDecoderConfig audio_config; | 155 AudioDecoderConfig audio_config; |
156 VideoDecoderConfig video_config; | 156 VideoDecoderConfig video_config; |
| 157 bool is_audio_encrypted = false; |
| 158 bool is_video_encrypted = false; |
157 | 159 |
158 for (std::vector<Track>::const_iterator track = moov_->tracks.begin(); | 160 for (std::vector<Track>::const_iterator track = moov_->tracks.begin(); |
159 track != moov_->tracks.end(); ++track) { | 161 track != moov_->tracks.end(); ++track) { |
160 // TODO(strobe): Only the first audio and video track present in a file are | 162 // TODO(strobe): Only the first audio and video track present in a file are |
161 // used. (Track selection is better accomplished via Source IDs, though, so | 163 // used. (Track selection is better accomplished via Source IDs, though, so |
162 // adding support for track selection within a stream is low-priority.) | 164 // adding support for track selection within a stream is low-priority.) |
163 const SampleDescription& samp_descr = | 165 const SampleDescription& samp_descr = |
164 track->media.information.sample_table.description; | 166 track->media.information.sample_table.description; |
165 | 167 |
166 // TODO(strobe): When codec reconfigurations are supported, detect and send | 168 // TODO(strobe): When codec reconfigurations are supported, detect and send |
(...skipping 24 matching lines...) Expand all Loading... |
191 (entry.format == FOURCC_ENCA && | 193 (entry.format == FOURCC_ENCA && |
192 entry.sinf.format.format == FOURCC_MP4A))) { | 194 entry.sinf.format.format == FOURCC_MP4A))) { |
193 LOG(ERROR) << "Unsupported audio format."; | 195 LOG(ERROR) << "Unsupported audio format."; |
194 return false; | 196 return false; |
195 } | 197 } |
196 // Check if it is MPEG4 AAC defined in ISO 14496 Part 3. | 198 // Check if it is MPEG4 AAC defined in ISO 14496 Part 3. |
197 if (entry.esds.object_type != kISO_14496_3) { | 199 if (entry.esds.object_type != kISO_14496_3) { |
198 LOG(ERROR) << "Unsupported audio object type."; | 200 LOG(ERROR) << "Unsupported audio object type."; |
199 return false; | 201 return false; |
200 } | 202 } |
| 203 |
| 204 is_audio_encrypted = entry.sinf.info.track_encryption.is_encrypted; |
201 RCHECK(EmitKeyNeeded(entry.sinf.info.track_encryption)); | 205 RCHECK(EmitKeyNeeded(entry.sinf.info.track_encryption)); |
202 | 206 |
203 audio_config.Initialize(kCodecAAC, entry.samplesize, | 207 audio_config.Initialize(kCodecAAC, entry.samplesize, |
204 aac.channel_layout(), | 208 aac.channel_layout(), |
205 aac.GetOutputSamplesPerSecond(has_sbr_), | 209 aac.GetOutputSamplesPerSecond(has_sbr_), |
206 NULL, 0, false); | 210 NULL, 0, false); |
207 has_audio_ = true; | 211 has_audio_ = true; |
208 audio_track_id_ = track->header.track_id; | 212 audio_track_id_ = track->header.track_id; |
209 } | 213 } |
210 if (track->media.handler.type == kVideo && !video_config.IsValidConfig()) { | 214 if (track->media.handler.type == kVideo && !video_config.IsValidConfig()) { |
211 RCHECK(!samp_descr.video_entries.empty()); | 215 RCHECK(!samp_descr.video_entries.empty()); |
212 if (desc_idx >= samp_descr.video_entries.size()) | 216 if (desc_idx >= samp_descr.video_entries.size()) |
213 desc_idx = 0; | 217 desc_idx = 0; |
214 const VideoSampleEntry& entry = samp_descr.video_entries[desc_idx]; | 218 const VideoSampleEntry& entry = samp_descr.video_entries[desc_idx]; |
215 | 219 |
216 if (!(entry.format == FOURCC_AVC1 || | 220 if (!(entry.format == FOURCC_AVC1 || |
217 (entry.format == FOURCC_ENCV && | 221 (entry.format == FOURCC_ENCV && |
218 entry.sinf.format.format == FOURCC_AVC1))) { | 222 entry.sinf.format.format == FOURCC_AVC1))) { |
219 LOG(ERROR) << "Unsupported video format."; | 223 LOG(ERROR) << "Unsupported video format."; |
220 return false; | 224 return false; |
221 } | 225 } |
| 226 |
| 227 is_video_encrypted = entry.sinf.info.track_encryption.is_encrypted; |
222 RCHECK(EmitKeyNeeded(entry.sinf.info.track_encryption)); | 228 RCHECK(EmitKeyNeeded(entry.sinf.info.track_encryption)); |
223 | 229 |
224 // TODO(strobe): Recover correct crop box | 230 // TODO(strobe): Recover correct crop box |
225 gfx::Size coded_size(entry.width, entry.height); | 231 gfx::Size coded_size(entry.width, entry.height); |
226 gfx::Rect visible_rect(coded_size); | 232 gfx::Rect visible_rect(coded_size); |
227 gfx::Size natural_size = GetNaturalSize(visible_rect.size(), | 233 gfx::Size natural_size = GetNaturalSize(visible_rect.size(), |
228 entry.pixel_aspect.h_spacing, | 234 entry.pixel_aspect.h_spacing, |
229 entry.pixel_aspect.v_spacing); | 235 entry.pixel_aspect.v_spacing); |
230 video_config.Initialize(kCodecH264, H264PROFILE_MAIN, VideoFrame::YV12, | 236 video_config.Initialize(kCodecH264, H264PROFILE_MAIN, VideoFrame::YV12, |
231 coded_size, visible_rect, natural_size, | 237 coded_size, visible_rect, natural_size, |
232 // No decoder-specific buffer needed for AVC; | 238 // No decoder-specific buffer needed for AVC; |
233 // SPS/PPS are embedded in the video stream | 239 // SPS/PPS are embedded in the video stream |
234 NULL, 0, true); | 240 NULL, 0, true); |
235 has_video_ = true; | 241 has_video_ = true; |
236 video_track_id_ = track->header.track_id; | 242 video_track_id_ = track->header.track_id; |
237 } | 243 } |
238 } | 244 } |
239 | 245 |
240 RCHECK(config_cb_.Run(audio_config, video_config)); | 246 RCHECK(config_cb_.Run(audio_config, video_config, |
| 247 is_audio_encrypted, is_video_encrypted)); |
241 | 248 |
242 base::TimeDelta duration; | 249 base::TimeDelta duration; |
243 if (moov_->extends.header.fragment_duration > 0) { | 250 if (moov_->extends.header.fragment_duration > 0) { |
244 duration = TimeDeltaFromRational(moov_->extends.header.fragment_duration, | 251 duration = TimeDeltaFromRational(moov_->extends.header.fragment_duration, |
245 moov_->header.timescale); | 252 moov_->header.timescale); |
246 } else if (moov_->header.duration > 0) { | 253 } else if (moov_->header.duration > 0) { |
247 duration = TimeDeltaFromRational(moov_->header.duration, | 254 duration = TimeDeltaFromRational(moov_->header.duration, |
248 moov_->header.timescale); | 255 moov_->header.timescale); |
249 } else { | 256 } else { |
250 duration = kInfiniteDuration(); | 257 duration = kInfiniteDuration(); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 return !err; | 490 return !err; |
484 } | 491 } |
485 | 492 |
486 void MP4StreamParser::ChangeState(State new_state) { | 493 void MP4StreamParser::ChangeState(State new_state) { |
487 DVLOG(2) << "Changing state: " << new_state; | 494 DVLOG(2) << "Changing state: " << new_state; |
488 state_ = new_state; | 495 state_ = new_state; |
489 } | 496 } |
490 | 497 |
491 } // namespace mp4 | 498 } // namespace mp4 |
492 } // namespace media | 499 } // namespace media |
OLD | NEW |