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

Side by Side Diff: media/filters/frame_processor.cc

Issue 276573002: Add gapless playback support for AAC playback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Comments. Created 6 years, 7 months 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
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698