DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs
cenc.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 "packager/media/formats/mp4/cenc.h"
6 
7 #include <cstring>
8 
9 #include "packager/media/base/buffer_reader.h"
10 #include "packager/media/base/buffer_writer.h"
11 #include "packager/media/formats/mp4/rcheck.h"
12 
13 namespace {
14 // According to ISO/IEC FDIS 23001-7: CENC spec, IV should be either
15 // 64-bit (8-byte) or 128-bit (16-byte).
16 bool IsIvSizeValid(size_t iv_size) { return iv_size == 8 || iv_size == 16; }
17 
18 // 16-bit |clear_bytes| and 32-bit |cipher_bytes|.
19 const size_t kSubsampleEntrySize = sizeof(uint16_t) + sizeof(uint32_t);
20 } // namespace
21 
22 namespace edash_packager {
23 namespace media {
24 namespace mp4 {
25 
26 FrameCENCInfo::FrameCENCInfo() {}
27 FrameCENCInfo::FrameCENCInfo(const std::vector<uint8_t>& iv) : iv_(iv) {
28 }
29 FrameCENCInfo::~FrameCENCInfo() {}
30 
31 bool FrameCENCInfo::Parse(uint8_t iv_size, BufferReader* reader) {
32  DCHECK(reader);
33  // Mandated by CENC spec.
34  RCHECK(IsIvSizeValid(iv_size));
35 
36  iv_.resize(iv_size);
37  RCHECK(reader->ReadToVector(&iv_, iv_size));
38 
39  if (!reader->HasBytes(1))
40  return true;
41 
42  uint16_t subsample_count;
43  RCHECK(reader->Read2(&subsample_count) &&
44  reader->HasBytes(subsample_count * kSubsampleEntrySize));
45 
46  subsamples_.resize(subsample_count);
47  for (uint16_t i = 0; i < subsample_count; ++i) {
48  uint16_t clear_bytes;
49  uint32_t cipher_bytes;
50  RCHECK(reader->Read2(&clear_bytes) &&
51  reader->Read4(&cipher_bytes));
52  subsamples_[i].clear_bytes = clear_bytes;
53  subsamples_[i].cipher_bytes = cipher_bytes;
54  }
55  return true;
56 }
57 
58 void FrameCENCInfo::Write(BufferWriter* writer) const {
59  DCHECK(writer);
60  DCHECK(IsIvSizeValid(iv_.size()));
61  writer->AppendVector(iv_);
62 
63  uint16_t subsample_count = subsamples_.size();
64  if (subsample_count == 0)
65  return;
66  writer->AppendInt(subsample_count);
67 
68  for (uint16_t i = 0; i < subsample_count; ++i) {
69  writer->AppendInt(subsamples_[i].clear_bytes);
70  writer->AppendInt(subsamples_[i].cipher_bytes);
71  }
72 }
73 
74 size_t FrameCENCInfo::ComputeSize() const {
75  uint16_t subsample_count = subsamples_.size();
76  if (subsample_count == 0)
77  return iv_.size();
78 
79  return iv_.size() + sizeof(subsample_count) +
80  subsample_count * kSubsampleEntrySize;
81 }
82 
83 size_t FrameCENCInfo::GetTotalSizeOfSubsamples() const {
84  size_t size = 0;
85  for (size_t i = 0; i < subsamples_.size(); ++i) {
86  size += subsamples_[i].clear_bytes + subsamples_[i].cipher_bytes;
87  }
88  return size;
89 }
90 
91 } // namespace mp4
92 } // namespace media
93 } // namespace edash_packager