Shaka Player Embedded
ffmpeg_encoded_frame.cc
Go to the documentation of this file.
1 // Copyright 2017 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
17 extern "C" {
18 #include <libavutil/encryption_info.h>
19 }
20 
21 #include <glog/logging.h>
22 
23 #include <vector>
24 
26 
27 namespace shaka {
28 namespace media {
29 namespace ffmpeg {
30 
31 namespace {
32 
33 constexpr const uint32_t kCencScheme = 0x63656e63;
34 constexpr const uint32_t kCbcsScheme = 0x63626373;
35 
36 bool MakeEncryptionInfo(const AVPacket* packet,
37  std::shared_ptr<eme::FrameEncryptionInfo>* info) {
38  int side_data_size;
39  uint8_t* side_data = av_packet_get_side_data(
40  packet, AV_PKT_DATA_ENCRYPTION_INFO, &side_data_size);
41  if (!side_data) {
42  return true;
43  }
44 
45  std::unique_ptr<AVEncryptionInfo, void (*)(AVEncryptionInfo*)> enc_info(
46  av_encryption_info_get_side_data(side_data, side_data_size),
47  &av_encryption_info_free);
48  if (!enc_info) {
49  LOG(DFATAL) << "Could not allocate new encryption info structure.";
50  return false;
51  }
52 
53  std::vector<eme::SubsampleInfo> subsamples;
54  for (uint32_t i = 0; i < enc_info->subsample_count; i++) {
55  subsamples.emplace_back(enc_info->subsamples[i].bytes_of_clear_data,
56  enc_info->subsamples[i].bytes_of_protected_data);
57  }
58 
59  eme::EncryptionScheme scheme;
60  eme::EncryptionPattern pattern{0, 0};
61  if (enc_info->scheme == kCencScheme) {
63  } else if (enc_info->scheme == kCbcsScheme) {
65  pattern = eme::EncryptionPattern{enc_info->crypt_byte_block,
66  enc_info->skip_byte_block};
67  } else {
68  LOG(DFATAL) << "Unsupported scheme";
69  return false;
70  }
71 
72  auto make_vec = [](const uint8_t* data, size_t size) {
73  return std::vector<uint8_t>(data, data + size);
74  };
75  *info = std::make_shared<eme::FrameEncryptionInfo>(
76  scheme, pattern, make_vec(enc_info->key_id, enc_info->key_id_size),
77  make_vec(enc_info->iv, enc_info->iv_size), subsamples);
78  return true;
79 }
80 
81 } // namespace
82 
83 // static
85  AVPacket* pkt, std::shared_ptr<const StreamInfo> info,
86  double timestamp_offset) {
87  const double factor = info->time_scale;
88  const double pts = pkt->pts * factor + timestamp_offset;
89  const double dts = pkt->dts * factor + timestamp_offset;
90  const double duration = pkt->duration * factor;
91  const bool is_key_frame = pkt->flags & AV_PKT_FLAG_KEY;
92  std::shared_ptr<eme::FrameEncryptionInfo> encryption_info;
93  if (!MakeEncryptionInfo(pkt, &encryption_info))
94  return nullptr;
95 
96  return new (std::nothrow)
97  FFmpegEncodedFrame(pkt, pts, dts, duration, is_key_frame, info,
98  encryption_info, timestamp_offset);
99 }
100 
102  av_packet_unref(&packet_);
103 }
104 
106  size_t size = sizeof(*this) + packet_.size;
107  for (int i = packet_.side_data_elems; i; i--)
108  size += packet_.side_data[i - 1].size;
109  return size;
110 }
111 
112 FFmpegEncodedFrame::FFmpegEncodedFrame(
113  AVPacket* pkt, double pts, double dts, double duration, bool is_key_frame,
114  std::shared_ptr<const StreamInfo> info,
115  std::shared_ptr<eme::FrameEncryptionInfo> encryption_info,
116  double timestamp_offset)
117  : EncodedFrame(info, pts, dts, duration, is_key_frame, pkt->data, pkt->size,
118  timestamp_offset, encryption_info) {
119  av_packet_move_ref(&packet_, pkt);
120 }
121 
122 } // namespace ffmpeg
123 } // namespace media
124 } // namespace shaka
EncodedFrame(std::shared_ptr< const StreamInfo > stream, double pts, double dts, double duration, bool is_key_frame, const uint8_t *data, size_t data_size, double timestamp_offset, std::shared_ptr< eme::FrameEncryptionInfo > encryption_info)
Definition: frames.cc:131
const bool is_key_frame
Definition: frames.h:211
const std::shared_ptr< eme::FrameEncryptionInfo > encryption_info
Definition: frames.h:259
static FFmpegEncodedFrame * MakeFrame(AVPacket *pkt, std::shared_ptr< const StreamInfo > info, double timestamp_offset)
const double timestamp_offset
Definition: frames.h:253
const double duration
Definition: frames.h:208
const double dts
Definition: frames.h:205
const double pts
Definition: frames.h:202