Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/filters/frame_processor.h" | 5 #include "media/filters/frame_processor.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "media/base/buffers.h" | 8 #include "media/base/buffers.h" |
| 9 #include "media/base/stream_parser_buffer.h" | 9 #include "media/base/stream_parser_buffer.h" |
| 10 | 10 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 } | 68 } |
| 69 | 69 |
| 70 // 2. - 4. Are handled by the WebMediaPlayer / Pipeline / Media Element. | 70 // 2. - 4. Are handled by the WebMediaPlayer / Pipeline / Media Element. |
| 71 | 71 |
| 72 // Step 5: | 72 // Step 5: |
| 73 update_duration_cb_.Run(group_end_timestamp_); | 73 update_duration_cb_.Run(group_end_timestamp_); |
| 74 | 74 |
| 75 return true; | 75 return true; |
| 76 } | 76 } |
| 77 | 77 |
| 78 bool FrameProcessor::ProcessFrame(scoped_refptr<StreamParserBuffer> frame, | 78 bool FrameProcessor::ProcessFrame( |
| 79 base::TimeDelta append_window_start, | 79 const scoped_refptr<StreamParserBuffer>& frame, |
| 80 base::TimeDelta append_window_end, | 80 base::TimeDelta append_window_start, |
| 81 base::TimeDelta* timestamp_offset, | 81 base::TimeDelta append_window_end, |
| 82 bool* new_media_segment) { | 82 base::TimeDelta* timestamp_offset, |
| 83 bool* new_media_segment) { | |
| 83 // Implements the loop within step 1 of the coded frame processing algorithm | 84 // Implements the loop within step 1 of the coded frame processing algorithm |
| 84 // for a single input frame per April 1, 2014 MSE spec editor's draft: | 85 // for a single input frame per April 1, 2014 MSE spec editor's draft: |
| 85 // https://dvcs.w3.org/hg/html-media/raw-file/d471a4412040/media-source/ | 86 // https://dvcs.w3.org/hg/html-media/raw-file/d471a4412040/media-source/ |
| 86 // media-source.html#sourcebuffer-coded-frame-processing | 87 // media-source.html#sourcebuffer-coded-frame-processing |
| 87 | 88 |
| 88 while (true) { | 89 while (true) { |
| 89 // 1. Loop Top: Let presentation timestamp be a double precision floating | 90 // 1. Loop Top: Let presentation timestamp be a double precision floating |
| 90 // point representation of the coded frame's presentation timestamp in | 91 // point representation of the coded frame's presentation timestamp in |
| 91 // seconds. | 92 // seconds. |
| 92 // 2. Let decode timestamp be a double precision floating point | 93 // 2. Let decode timestamp be a double precision floating point |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 | 257 |
| 257 // 10. If presentation timestamp is less than appendWindowStart, then set | 258 // 10. If presentation timestamp is less than appendWindowStart, then set |
| 258 // the need random access point flag to true, drop the coded frame, and | 259 // the need random access point flag to true, drop the coded frame, and |
| 259 // jump to the top of the loop to start processing the next coded | 260 // jump to the top of the loop to start processing the next coded |
| 260 // frame. | 261 // frame. |
| 261 // Note: We keep the result of partial discard of a buffer that overlaps | 262 // Note: We keep the result of partial discard of a buffer that overlaps |
| 262 // |append_window_start| and does not end after |append_window_end|. | 263 // |append_window_start| and does not end after |append_window_end|. |
| 263 // 11. If frame end timestamp is greater than appendWindowEnd, then set the | 264 // 11. If frame end timestamp is greater than appendWindowEnd, then set the |
| 264 // need random access point flag to true, drop the coded frame, and jump | 265 // need random access point flag to true, drop the coded frame, and jump |
| 265 // to the top of the loop to start processing the next coded frame. | 266 // to the top of the loop to start processing the next coded frame. |
| 266 if (presentation_timestamp < append_window_start || | 267 if (track_buffer->stream()->supports_partial_append_window_trimming() && |
| 267 frame_end_timestamp > append_window_end) { | 268 HandlePartialAppendWindowTrimming(append_window_start, |
| 268 // See if a partial discard can be done around |append_window_start|. | 269 append_window_end, |
| 269 // TODO(wolenetz): Refactor this into a base helper across legacy and | 270 presentation_timestamp, |
| 270 // new frame processors? | 271 frame_end_timestamp, |
| 271 if (track_buffer->stream()->supports_partial_append_window_trimming() && | 272 frame)) { |
| 272 presentation_timestamp < append_window_start && | 273 // |frame| has been partially trimmed or had preroll added. |
|
wolenetz
2014/05/23 19:59:45
ditto of LegacyFrameProcessor comment: do the foll
DaleCurtis
2014/05/23 21:46:26
Blew out the else from below. Should be fine now?
| |
| 273 frame_end_timestamp > append_window_start && | 274 decode_timestamp = frame->GetDecodeTimestamp(); |
| 274 frame_end_timestamp <= append_window_end) { | 275 presentation_timestamp = frame->timestamp(); |
| 275 DCHECK(frame->IsKeyframe()); | 276 frame_duration = frame->duration(); |
|
acolwell GONE FROM CHROMIUM
2014/05/23 17:27:30
Since presentation_timestamp & frame_duration are
DaleCurtis
2014/05/23 21:46:26
No, since the timestamp is moved forward by a valu
acolwell GONE FROM CHROMIUM
2014/05/24 00:58:20
ok. A comment or DCHECK here would be nice so that
DaleCurtis
2014/05/27 23:59:32
Done.
| |
| 276 DVLOG(1) << "Truncating buffer which overlaps append window start." | 277 } else if (presentation_timestamp < append_window_start || |
|
acolwell GONE FROM CHROMIUM
2014/05/23 17:27:30
I wonder if we should drop the else here. ISTM tha
wolenetz
2014/05/23 19:59:45
Good point: I think that would address my *new_med
DaleCurtis
2014/05/23 21:46:26
Seems reasonable. Done.
| |
| 277 << " presentation_timestamp " | 278 frame_end_timestamp > append_window_end) { |
| 278 << presentation_timestamp.InSecondsF() | 279 track_buffer->set_needs_random_access_point(true); |
| 279 << " append_window_start " << append_window_start.InSecondsF(); | 280 DVLOG(3) << "Dropping frame that is outside append window."; |
| 280 | 281 |
| 281 // Adjust the timestamp of this frame forward to |append_window_start|, | 282 if (!sequence_mode_) { |
| 282 // while decreasing the duration appropriately. | 283 // This also triggers a discontinuity so we need to treat the next |
| 283 frame->set_discard_padding(std::make_pair( | 284 // frames appended within the append window as if they were the |
| 284 append_window_start - presentation_timestamp, base::TimeDelta())); | 285 // beginning of a new segment. |
| 285 presentation_timestamp = append_window_start; // |frame| updated below. | 286 *new_media_segment = true; |
| 286 decode_timestamp = append_window_start; // |frame| updated below. | 287 } |
| 287 frame_duration = frame_end_timestamp - presentation_timestamp; | |
| 288 frame->set_duration(frame_duration); | |
| 289 | 288 |
| 290 // TODO(dalecurtis): This could also be done with |append_window_end|, | 289 return true; |
| 291 // but is not necessary since splice frames covert the overlap there. | |
| 292 } else { | |
| 293 track_buffer->set_needs_random_access_point(true); | |
| 294 DVLOG(3) << "Dropping frame that is outside append window."; | |
| 295 | |
| 296 if (!sequence_mode_) { | |
| 297 // This also triggers a discontinuity so we need to treat the next | |
| 298 // frames appended within the append window as if they were the | |
| 299 // beginning of a new segment. | |
| 300 *new_media_segment = true; | |
| 301 } | |
| 302 | |
| 303 return true; | |
| 304 } | |
| 305 } | 290 } |
| 306 | 291 |
| 307 // 12. If the need random access point flag on track buffer equals true, | 292 // 12. If the need random access point flag on track buffer equals true, |
| 308 // then run the following steps: | 293 // then run the following steps: |
| 309 if (track_buffer->needs_random_access_point()) { | 294 if (track_buffer->needs_random_access_point()) { |
| 310 // 12.1. If the coded frame is not a random access point, then drop the | 295 // 12.1. If the coded frame is not a random access point, then drop the |
| 311 // coded frame and jump to the top of the loop to start processing | 296 // coded frame and jump to the top of the loop to start processing |
| 312 // the next coded frame. | 297 // the next coded frame. |
| 313 if (!frame->IsKeyframe()) { | 298 if (!frame->IsKeyframe()) { |
| 314 DVLOG(3) << __FUNCTION__ | 299 DVLOG(3) << __FUNCTION__ |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 } | 354 } |
| 370 | 355 |
| 371 void FrameProcessor::SetAllTrackBuffersNeedRandomAccessPoint() { | 356 void FrameProcessor::SetAllTrackBuffersNeedRandomAccessPoint() { |
| 372 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 357 for (TrackBufferMap::iterator itr = track_buffers_.begin(); |
| 373 itr != track_buffers_.end(); ++itr) { | 358 itr != track_buffers_.end(); ++itr) { |
| 374 itr->second->set_needs_random_access_point(true); | 359 itr->second->set_needs_random_access_point(true); |
| 375 } | 360 } |
| 376 } | 361 } |
| 377 | 362 |
| 378 } // namespace media | 363 } // namespace media |
| OLD | NEW |