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
3 // found in the LICENSE file.
5 #include "media/base/stream_parser_buffer.h"
7 #include "base/logging.h"
8 #include "media/base/buffers.h"
12 static scoped_refptr
<StreamParserBuffer
> CopyBuffer(
13 const StreamParserBuffer
& buffer
) {
14 if (buffer
.end_of_stream())
15 return StreamParserBuffer::CreateEOSBuffer();
17 scoped_refptr
<StreamParserBuffer
> copied_buffer
=
18 StreamParserBuffer::CopyFrom(buffer
.data(),
21 buffer
.side_data_size(),
25 copied_buffer
->SetDecodeTimestamp(buffer
.GetDecodeTimestamp());
26 copied_buffer
->SetConfigId(buffer
.GetConfigId());
27 copied_buffer
->set_timestamp(buffer
.timestamp());
28 copied_buffer
->set_duration(buffer
.duration());
29 copied_buffer
->set_discard_padding(buffer
.discard_padding());
30 copied_buffer
->set_splice_timestamp(buffer
.splice_timestamp());
31 const DecryptConfig
* decrypt_config
= buffer
.decrypt_config();
33 copied_buffer
->set_decrypt_config(
34 make_scoped_ptr(new DecryptConfig(decrypt_config
->key_id(),
36 decrypt_config
->subsamples())));
42 scoped_refptr
<StreamParserBuffer
> StreamParserBuffer::CreateEOSBuffer() {
43 return make_scoped_refptr(new StreamParserBuffer(NULL
, 0, NULL
, 0, false,
44 DemuxerStream::UNKNOWN
, 0));
47 scoped_refptr
<StreamParserBuffer
> StreamParserBuffer::CopyFrom(
48 const uint8
* data
, int data_size
, bool is_keyframe
, Type type
,
50 return make_scoped_refptr(
51 new StreamParserBuffer(data
, data_size
, NULL
, 0, is_keyframe
, type
,
55 scoped_refptr
<StreamParserBuffer
> StreamParserBuffer::CopyFrom(
56 const uint8
* data
, int data_size
,
57 const uint8
* side_data
, int side_data_size
,
58 bool is_keyframe
, Type type
, TrackId track_id
) {
59 return make_scoped_refptr(
60 new StreamParserBuffer(data
, data_size
, side_data
, side_data_size
,
61 is_keyframe
, type
, track_id
));
64 base::TimeDelta
StreamParserBuffer::GetDecodeTimestamp() const {
65 if (decode_timestamp_
== kNoTimestamp())
67 return decode_timestamp_
;
70 void StreamParserBuffer::SetDecodeTimestamp(const base::TimeDelta
& timestamp
) {
71 decode_timestamp_
= timestamp
;
74 StreamParserBuffer::StreamParserBuffer(const uint8
* data
, int data_size
,
75 const uint8
* side_data
,
76 int side_data_size
, bool is_keyframe
,
77 Type type
, TrackId track_id
)
78 : DecoderBuffer(data
, data_size
, side_data
, side_data_size
),
79 is_keyframe_(is_keyframe
),
80 decode_timestamp_(kNoTimestamp()),
81 config_id_(kInvalidConfigId
),
84 // TODO(scherkus): Should DataBuffer constructor accept a timestamp and
85 // duration to force clients to set them? Today they end up being zero which
86 // is both a common and valid value and could lead to bugs.
88 set_duration(kNoTimestamp());
92 StreamParserBuffer::~StreamParserBuffer() {}
94 int StreamParserBuffer::GetConfigId() const {
98 void StreamParserBuffer::SetConfigId(int config_id
) {
99 config_id_
= config_id
;
102 void StreamParserBuffer::ConvertToSpliceBuffer(
103 const BufferQueue
& pre_splice_buffers
) {
104 DCHECK(splice_buffers_
.empty());
105 DCHECK(!end_of_stream());
107 // Make a copy of this first, before making any changes.
108 scoped_refptr
<StreamParserBuffer
> overlapping_buffer
= CopyBuffer(*this);
109 overlapping_buffer
->set_splice_timestamp(kNoTimestamp());
111 const scoped_refptr
<StreamParserBuffer
>& first_splice_buffer
=
112 pre_splice_buffers
.front();
114 // Ensure the given buffers are actually before the splice point.
115 DCHECK(first_splice_buffer
->timestamp() <= overlapping_buffer
->timestamp());
117 // TODO(dalecurtis): We should also clear |data| and |side_data|, but since
118 // that implies EOS care must be taken to ensure there are no clients relying
121 // Rewrite |this| buffer as a splice buffer.
122 SetDecodeTimestamp(first_splice_buffer
->GetDecodeTimestamp());
123 SetConfigId(first_splice_buffer
->GetConfigId());
124 set_timestamp(first_splice_buffer
->timestamp());
125 is_keyframe_
= first_splice_buffer
->IsKeyframe();
126 type_
= first_splice_buffer
->type();
127 track_id_
= first_splice_buffer
->track_id();
128 set_splice_timestamp(overlapping_buffer
->timestamp());
130 // The splice duration is the duration of all buffers before the splice plus
131 // the highest ending timestamp after the splice point.
133 std::max(overlapping_buffer
->timestamp() + overlapping_buffer
->duration(),
134 pre_splice_buffers
.back()->timestamp() +
135 pre_splice_buffers
.back()->duration()) -
136 first_splice_buffer
->timestamp());
138 // Copy all pre splice buffers into our wrapper buffer.
139 for (BufferQueue::const_iterator it
= pre_splice_buffers
.begin();
140 it
!= pre_splice_buffers
.end();
142 const scoped_refptr
<StreamParserBuffer
>& buffer
= *it
;
143 DCHECK(!buffer
->end_of_stream());
144 DCHECK(buffer
->get_splice_buffers().empty());
145 splice_buffers_
.push_back(CopyBuffer(*buffer
));
146 splice_buffers_
.back()->set_splice_timestamp(splice_timestamp());
149 splice_buffers_
.push_back(overlapping_buffer
);