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 |