Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / base / stream_parser_buffer.cc
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.
4
5 #include "media/base/stream_parser_buffer.h"
6
7 #include "base/logging.h"
8 #include "media/base/buffers.h"
9
10 namespace media {
11
12 static scoped_refptr<StreamParserBuffer> CopyBuffer(
13     const StreamParserBuffer& buffer) {
14   if (buffer.end_of_stream())
15     return StreamParserBuffer::CreateEOSBuffer();
16
17   scoped_refptr<StreamParserBuffer> copied_buffer =
18       StreamParserBuffer::CopyFrom(buffer.data(),
19                                    buffer.data_size(),
20                                    buffer.side_data(),
21                                    buffer.side_data_size(),
22                                    buffer.IsKeyframe(),
23                                    buffer.type(),
24                                    buffer.track_id());
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();
32   if (decrypt_config) {
33     copied_buffer->set_decrypt_config(
34         make_scoped_ptr(new DecryptConfig(decrypt_config->key_id(),
35                                           decrypt_config->iv(),
36                                           decrypt_config->subsamples())));
37   }
38
39   return copied_buffer;
40 }
41
42 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CreateEOSBuffer() {
43   return make_scoped_refptr(new StreamParserBuffer(NULL, 0, NULL, 0, false,
44                                                    DemuxerStream::UNKNOWN, 0));
45 }
46
47 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom(
48     const uint8* data, int data_size, bool is_keyframe, Type type,
49     TrackId track_id) {
50   return make_scoped_refptr(
51       new StreamParserBuffer(data, data_size, NULL, 0, is_keyframe, type,
52                              track_id));
53 }
54
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));
62 }
63
64 base::TimeDelta StreamParserBuffer::GetDecodeTimestamp() const {
65   if (decode_timestamp_ == kNoTimestamp())
66     return timestamp();
67   return decode_timestamp_;
68 }
69
70 void StreamParserBuffer::SetDecodeTimestamp(const base::TimeDelta& timestamp) {
71   decode_timestamp_ = timestamp;
72 }
73
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),
82       type_(type),
83       track_id_(track_id) {
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.
87   if (data) {
88     set_duration(kNoTimestamp());
89   }
90 }
91
92 StreamParserBuffer::~StreamParserBuffer() {}
93
94 int StreamParserBuffer::GetConfigId() const {
95   return config_id_;
96 }
97
98 void StreamParserBuffer::SetConfigId(int config_id) {
99   config_id_ = config_id;
100 }
101
102 void StreamParserBuffer::ConvertToSpliceBuffer(
103     const BufferQueue& pre_splice_buffers) {
104   DCHECK(splice_buffers_.empty());
105   DCHECK(!end_of_stream());
106
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());
110
111   const scoped_refptr<StreamParserBuffer>& first_splice_buffer =
112       pre_splice_buffers.front();
113
114   // Ensure the given buffers are actually before the splice point.
115   DCHECK(first_splice_buffer->timestamp() <= overlapping_buffer->timestamp());
116
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
119   // on that behavior.
120
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());
129
130   // The splice duration is the duration of all buffers before the splice plus
131   // the highest ending timestamp after the splice point.
132   set_duration(
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());
137
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();
141        ++it) {
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());
147   }
148
149   splice_buffers_.push_back(overlapping_buffer);
150 }
151
152 }  // namespace media