| 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 |