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

Side by Side Diff: media/webm/cluster_builder.cc

Issue 7203002: Adding ChunkDemuxer implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed unit tests and nits Created 9 years, 5 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
« no previous file with comments | « media/webm/cluster_builder.h ('k') | media/webm/webm_cluster_parser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/webm/cluster_builder.h"
6
7 #include "base/logging.h"
8 #include "media/base/data_buffer.h"
9
10 namespace media {
11
12 static const uint8 kClusterHeader[] = {
13 0x1F, 0x43, 0xB6, 0x75, // CLUSTER ID
14 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // cluster(size = 0)
15 0xE7, // Timecode ID
16 0x88, // timecode(size=8)
17 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // timecode value
18 };
19
20 const int kClusterHeaderSize = sizeof(kClusterHeader);
21 const int kClusterSizeOffset = 4;
22 const int kClusterTimecodeOffset = 14;
23
24 static const uint8 kSimpleBlockHeader[] = {
25 0xA3, // SimpleBlock ID
26 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SimpleBlock(size = 0)
27 };
28
29 const int kSimpleBlockHeaderSize = sizeof(kSimpleBlockHeader);
30 const int kSimpleBlockSizeOffset = 1;
31
32 const int kInitialBufferSize = 32768;
33
34 Cluster::Cluster(const uint8* data, int size) : data_(data), size_(size) {}
35 Cluster::~Cluster() {}
36
37 ClusterBuilder::ClusterBuilder() { Reset(); }
38
39 void ClusterBuilder::SetClusterTimecode(int64 cluster_timecode) {
40 DCHECK_EQ(cluster_timecode_, -1);
41
42 cluster_timecode_ = cluster_timecode;
43
44 // Write the timecode into the header.
45 uint8* buf = buffer_.get() + kClusterTimecodeOffset;
46 for (int i = 7; i >= 0; --i) {
47 buf[i] = cluster_timecode & 0xff;
48 cluster_timecode >>= 8;
49 }
50 }
51
52 void ClusterBuilder::AddSimpleBlock(int track_num, int64 timecode, int flags,
53 const uint8* data, int size) {
54 DCHECK_GE(track_num, 0);
55 DCHECK_LE(track_num, 126);
56 DCHECK_GE(flags, 0);
57 DCHECK_LE(flags, 0xff);
58 DCHECK(data);
59 DCHECK_GT(size, 0);
60 DCHECK_NE(cluster_timecode_, -1);
61
62 int64 timecode_delta = timecode - cluster_timecode_;
63 DCHECK_GE(timecode_delta, -32768);
64 DCHECK_LE(timecode_delta, 32767);
65
66 int block_size = 4 + size;
67 int bytes_needed = kSimpleBlockHeaderSize + block_size;
68 if (bytes_needed > (buffer_size_ - bytes_used_))
69 ExtendBuffer(bytes_needed);
70
71 uint8* buf = buffer_.get() + bytes_used_;
72 int block_offset = bytes_used_;
73 memcpy(buf, kSimpleBlockHeader, kSimpleBlockHeaderSize);
74 UpdateUInt64(block_offset + kSimpleBlockSizeOffset, block_size);
75 buf += kSimpleBlockHeaderSize;
76
77 buf[0] = 0x80 | (track_num & 0x7F);
78 buf[1] = (timecode_delta >> 8) & 0xff;
79 buf[2] = timecode_delta & 0xff;
80 buf[3] = flags & 0xff;
81 memcpy(buf + 4, data, size);
82
83 bytes_used_ += bytes_needed;
84 }
85
86 Cluster* ClusterBuilder::Finish() {
87 DCHECK_NE(cluster_timecode_, -1);
88
89 UpdateUInt64(kClusterSizeOffset, bytes_used_ - (kClusterSizeOffset + 8));
90
91 scoped_ptr<Cluster> ret(new Cluster(buffer_.release(), bytes_used_));
92 Reset();
93 return ret.release();
94 }
95
96 void ClusterBuilder::Reset() {
97 buffer_size_ = kInitialBufferSize;
98 buffer_.reset(new uint8[buffer_size_]);
99 memcpy(buffer_.get(), kClusterHeader, kClusterHeaderSize);
100 bytes_used_ = kClusterHeaderSize;
101 cluster_timecode_ = -1;
102 }
103
104 void ClusterBuilder::ExtendBuffer(int bytes_needed) {
105 int new_buffer_size = 2 * buffer_size_;
106
107 while ((new_buffer_size - bytes_used_) < bytes_needed)
108 new_buffer_size *= 2;
109
110 scoped_array<uint8> new_buffer(new uint8[new_buffer_size]);
111
112 memcpy(new_buffer.get(), buffer_.get(), bytes_used_);
113 buffer_.reset(new_buffer.release());
114 buffer_size_ = new_buffer_size;
115 }
116
117 void ClusterBuilder::UpdateUInt64(int offset, int64 value) {
118 DCHECK_LE(offset + 7, buffer_size_);
119 uint8* buf = buffer_.get() + offset;
120
121 // Fill the last 7 bytes of size field in big-endian order.
122 for (int i = 7; i > 0; i--) {
123 buf[i] = value & 0xff;
124 value >>= 8;
125 }
126 }
127
128 } // namespace media
OLDNEW
« no previous file with comments | « media/webm/cluster_builder.h ('k') | media/webm/webm_cluster_parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698