OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/formats/mp2t/mp2t_stream_parser.h" | 5 #include "media/formats/mp2t/mp2t_stream_parser.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <memory> | 11 #include <memory> |
12 #include <string> | 12 #include <string> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
| 18 #include "base/strings/string_number_conversions.h" |
18 #include "base/time/time.h" | 19 #include "base/time/time.h" |
19 #include "media/base/audio_decoder_config.h" | 20 #include "media/base/audio_decoder_config.h" |
20 #include "media/base/decoder_buffer.h" | 21 #include "media/base/decoder_buffer.h" |
21 #include "media/base/media_log.h" | 22 #include "media/base/media_log.h" |
22 #include "media/base/media_track.h" | 23 #include "media/base/media_track.h" |
23 #include "media/base/media_tracks.h" | 24 #include "media/base/media_tracks.h" |
24 #include "media/base/stream_parser_buffer.h" | 25 #include "media/base/stream_parser_buffer.h" |
25 #include "media/base/test_data_util.h" | 26 #include "media/base/test_data_util.h" |
26 #include "media/base/text_track_config.h" | 27 #include "media/base/text_track_config.h" |
27 #include "media/base/video_decoder_config.h" | 28 #include "media/base/video_decoder_config.h" |
| 29 #include "media/media_features.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
29 | 31 |
| 32 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
| 33 #include <openssl/aes.h> |
| 34 #include <openssl/evp.h> |
| 35 #include "crypto/openssl_util.h" |
| 36 #endif |
| 37 |
30 namespace media { | 38 namespace media { |
31 namespace mp2t { | 39 namespace mp2t { |
32 | 40 |
33 namespace { | 41 namespace { |
34 | 42 |
35 bool IsMonotonic(const StreamParser::BufferQueue& buffers) { | 43 bool IsMonotonic(const StreamParser::BufferQueue& buffers) { |
36 if (buffers.empty()) | 44 if (buffers.empty()) |
37 return true; | 45 return true; |
38 | 46 |
39 StreamParser::BufferQueue::const_iterator it1 = buffers.begin(); | 47 StreamParser::BufferQueue::const_iterator it1 = buffers.begin(); |
40 StreamParser::BufferQueue::const_iterator it2 = ++it1; | 48 StreamParser::BufferQueue::const_iterator it2 = ++it1; |
41 for ( ; it2 != buffers.end(); ++it1, ++it2) { | 49 for ( ; it2 != buffers.end(); ++it1, ++it2) { |
42 if ((*it2)->GetDecodeTimestamp() < (*it1)->GetDecodeTimestamp()) | 50 if ((*it2)->GetDecodeTimestamp() < (*it1)->GetDecodeTimestamp()) |
43 return false; | 51 return false; |
44 } | 52 } |
45 return true; | 53 return true; |
46 } | 54 } |
47 | 55 |
48 bool IsAlmostEqual(DecodeTimestamp t0, DecodeTimestamp t1) { | 56 bool IsAlmostEqual(DecodeTimestamp t0, DecodeTimestamp t1) { |
49 base::TimeDelta kMaxDeviation = base::TimeDelta::FromMilliseconds(5); | 57 base::TimeDelta kMaxDeviation = base::TimeDelta::FromMilliseconds(5); |
50 base::TimeDelta diff = t1 - t0; | 58 base::TimeDelta diff = t1 - t0; |
51 return (diff >= -kMaxDeviation && diff <= kMaxDeviation); | 59 return (diff >= -kMaxDeviation && diff <= kMaxDeviation); |
52 } | 60 } |
53 | 61 |
| 62 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
| 63 class ScopedCipherCTX { |
| 64 public: |
| 65 explicit ScopedCipherCTX() { EVP_CIPHER_CTX_init(&ctx_); } |
| 66 ~ScopedCipherCTX() { |
| 67 EVP_CIPHER_CTX_cleanup(&ctx_); |
| 68 crypto::ClearOpenSSLERRStack(FROM_HERE); |
| 69 } |
| 70 EVP_CIPHER_CTX* get() { return &ctx_; } |
| 71 |
| 72 private: |
| 73 EVP_CIPHER_CTX ctx_; |
| 74 }; |
| 75 |
| 76 std::string DecryptSampleAES(const std::string& key, |
| 77 const std::string& iv, |
| 78 const uint8_t* input, |
| 79 int input_size, |
| 80 bool has_pattern) { |
| 81 DCHECK(input); |
| 82 EXPECT_EQ(input_size % 16, 0); |
| 83 crypto::EnsureOpenSSLInit(); |
| 84 std::string result; |
| 85 const EVP_CIPHER* cipher = EVP_aes_128_cbc(); |
| 86 ScopedCipherCTX ctx; |
| 87 EXPECT_EQ(EVP_CipherInit_ex(ctx.get(), cipher, NULL, |
| 88 reinterpret_cast<const uint8_t*>(key.data()), |
| 89 reinterpret_cast<const uint8_t*>(iv.data()), 0), |
| 90 1); |
| 91 EVP_CIPHER_CTX_set_padding(ctx.get(), 0); |
| 92 const size_t output_size = input_size; |
| 93 std::unique_ptr<char[]> output(new char[output_size]); |
| 94 uint8_t* in_ptr = const_cast<uint8_t*>(input); |
| 95 uint8_t* out_ptr = reinterpret_cast<uint8_t*>(output.get()); |
| 96 size_t bytes_remaining = output_size; |
| 97 |
| 98 while (bytes_remaining) { |
| 99 int unused; |
| 100 size_t amount_to_decrypt = has_pattern ? 16UL : bytes_remaining; |
| 101 EXPECT_EQ(EVP_CipherUpdate(ctx.get(), out_ptr, &unused, in_ptr, |
| 102 amount_to_decrypt), |
| 103 1); |
| 104 bytes_remaining -= amount_to_decrypt; |
| 105 if (bytes_remaining) { |
| 106 out_ptr += amount_to_decrypt; |
| 107 in_ptr += amount_to_decrypt; |
| 108 size_t amount_to_skip = 144UL; |
| 109 if (amount_to_skip > bytes_remaining) |
| 110 amount_to_skip = bytes_remaining; |
| 111 memcpy(out_ptr, in_ptr, amount_to_skip); |
| 112 out_ptr += amount_to_skip; |
| 113 in_ptr += amount_to_skip; |
| 114 bytes_remaining -= amount_to_skip; |
| 115 } |
| 116 } |
| 117 |
| 118 result.assign(output.get(), output_size); |
| 119 return result; |
| 120 } |
| 121 |
| 122 // We only support AES-CBC at this time. |
| 123 // For the purpose of these tests, the key id is also used as the actual key. |
| 124 std::string DecryptBuffer(const StreamParserBuffer& buffer, |
| 125 const EncryptionScheme& scheme) { |
| 126 EXPECT_TRUE(scheme.is_encrypted()); |
| 127 EXPECT_TRUE(scheme.mode() == EncryptionScheme::CIPHER_MODE_AES_CBC); |
| 128 bool has_pattern = scheme.pattern().IsInEffect(); |
| 129 EXPECT_TRUE(!has_pattern || |
| 130 scheme.pattern().Matches(EncryptionScheme::Pattern(1, 9))); |
| 131 |
| 132 std::string key; |
| 133 EXPECT_TRUE( |
| 134 LookupTestKeyString(buffer.decrypt_config()->key_id(), false, &key)); |
| 135 std::string iv = buffer.decrypt_config()->iv(); |
| 136 EXPECT_EQ(key.size(), 16UL); |
| 137 EXPECT_EQ(iv.size(), 16UL); |
| 138 std::string result; |
| 139 uint8_t* in_ptr = const_cast<uint8_t*>(buffer.data()); |
| 140 const DecryptConfig* decrypt_config = buffer.decrypt_config(); |
| 141 for (const auto& subsample : decrypt_config->subsamples()) { |
| 142 std::string clear(reinterpret_cast<char*>(in_ptr), subsample.clear_bytes); |
| 143 result += clear; |
| 144 in_ptr += subsample.clear_bytes; |
| 145 result += |
| 146 DecryptSampleAES(key, iv, in_ptr, subsample.cypher_bytes, has_pattern); |
| 147 in_ptr += subsample.cypher_bytes; |
| 148 } |
| 149 return result; |
| 150 } |
| 151 #endif |
| 152 |
54 } // namespace | 153 } // namespace |
55 | 154 |
56 class Mp2tStreamParserTest : public testing::Test { | 155 class Mp2tStreamParserTest : public testing::Test { |
57 public: | 156 public: |
58 Mp2tStreamParserTest() | 157 Mp2tStreamParserTest() |
59 : segment_count_(0), | 158 : segment_count_(0), |
60 config_count_(0), | 159 config_count_(0), |
61 audio_frame_count_(0), | 160 audio_frame_count_(0), |
62 video_frame_count_(0), | 161 video_frame_count_(0), |
63 has_video_(true), | 162 has_video_(true), |
64 audio_min_dts_(kNoDecodeTimestamp()), | 163 audio_min_dts_(kNoDecodeTimestamp()), |
65 audio_max_dts_(kNoDecodeTimestamp()), | 164 audio_max_dts_(kNoDecodeTimestamp()), |
66 video_min_dts_(kNoDecodeTimestamp()), | 165 video_min_dts_(kNoDecodeTimestamp()), |
67 video_max_dts_(kNoDecodeTimestamp()), | 166 video_max_dts_(kNoDecodeTimestamp()), |
68 audio_track_id_(0), | 167 audio_track_id_(0), |
69 video_track_id_(0) { | 168 video_track_id_(0), |
| 169 current_audio_config_(), |
| 170 current_video_config_(), |
| 171 capture_buffers(false) { |
70 bool has_sbr = false; | 172 bool has_sbr = false; |
71 parser_.reset(new Mp2tStreamParser(has_sbr)); | 173 parser_.reset(new Mp2tStreamParser(has_sbr)); |
72 } | 174 } |
73 | 175 |
74 protected: | 176 protected: |
75 std::unique_ptr<Mp2tStreamParser> parser_; | 177 std::unique_ptr<Mp2tStreamParser> parser_; |
76 int segment_count_; | 178 int segment_count_; |
77 int config_count_; | 179 int config_count_; |
78 int audio_frame_count_; | 180 int audio_frame_count_; |
79 int video_frame_count_; | 181 int video_frame_count_; |
80 bool has_video_; | 182 bool has_video_; |
81 DecodeTimestamp audio_min_dts_; | 183 DecodeTimestamp audio_min_dts_; |
82 DecodeTimestamp audio_max_dts_; | 184 DecodeTimestamp audio_max_dts_; |
83 DecodeTimestamp video_min_dts_; | 185 DecodeTimestamp video_min_dts_; |
84 DecodeTimestamp video_max_dts_; | 186 DecodeTimestamp video_max_dts_; |
85 StreamParser::TrackId audio_track_id_; | 187 StreamParser::TrackId audio_track_id_; |
86 StreamParser::TrackId video_track_id_; | 188 StreamParser::TrackId video_track_id_; |
87 | 189 |
| 190 AudioDecoderConfig current_audio_config_; |
| 191 VideoDecoderConfig current_video_config_; |
| 192 std::vector<scoped_refptr<StreamParserBuffer>> audio_buffer_capture_; |
| 193 std::vector<scoped_refptr<StreamParserBuffer>> video_buffer_capture_; |
| 194 bool capture_buffers; |
| 195 |
88 void ResetStats() { | 196 void ResetStats() { |
89 segment_count_ = 0; | 197 segment_count_ = 0; |
90 config_count_ = 0; | 198 config_count_ = 0; |
91 audio_frame_count_ = 0; | 199 audio_frame_count_ = 0; |
92 video_frame_count_ = 0; | 200 video_frame_count_ = 0; |
93 audio_min_dts_ = kNoDecodeTimestamp(); | 201 audio_min_dts_ = kNoDecodeTimestamp(); |
94 audio_max_dts_ = kNoDecodeTimestamp(); | 202 audio_max_dts_ = kNoDecodeTimestamp(); |
95 video_min_dts_ = kNoDecodeTimestamp(); | 203 video_min_dts_ = kNoDecodeTimestamp(); |
96 video_max_dts_ = kNoDecodeTimestamp(); | 204 video_max_dts_ = kNoDecodeTimestamp(); |
97 } | 205 } |
(...skipping 26 matching lines...) Expand all Loading... |
124 const StreamParser::TextTrackConfigMap& tc) { | 232 const StreamParser::TextTrackConfigMap& tc) { |
125 DVLOG(1) << "OnNewConfig: got " << tracks->tracks().size() << " tracks"; | 233 DVLOG(1) << "OnNewConfig: got " << tracks->tracks().size() << " tracks"; |
126 bool found_audio_track = false; | 234 bool found_audio_track = false; |
127 bool found_video_track = false; | 235 bool found_video_track = false; |
128 for (const auto& track : tracks->tracks()) { | 236 for (const auto& track : tracks->tracks()) { |
129 const auto& track_id = track->bytestream_track_id(); | 237 const auto& track_id = track->bytestream_track_id(); |
130 if (track->type() == MediaTrack::Audio) { | 238 if (track->type() == MediaTrack::Audio) { |
131 audio_track_id_ = track_id; | 239 audio_track_id_ = track_id; |
132 found_audio_track = true; | 240 found_audio_track = true; |
133 EXPECT_TRUE(tracks->getAudioConfig(track_id).IsValidConfig()); | 241 EXPECT_TRUE(tracks->getAudioConfig(track_id).IsValidConfig()); |
| 242 current_audio_config_ = tracks->getAudioConfig(track_id); |
134 } else if (track->type() == MediaTrack::Video) { | 243 } else if (track->type() == MediaTrack::Video) { |
135 video_track_id_ = track_id; | 244 video_track_id_ = track_id; |
136 found_video_track = true; | 245 found_video_track = true; |
137 EXPECT_TRUE(tracks->getVideoConfig(track_id).IsValidConfig()); | 246 EXPECT_TRUE(tracks->getVideoConfig(track_id).IsValidConfig()); |
| 247 current_video_config_ = tracks->getVideoConfig(track_id); |
138 } else { | 248 } else { |
139 // Unexpected track type. | 249 // Unexpected track type. |
140 LOG(ERROR) << "Unexpected track type " << track->type(); | 250 LOG(ERROR) << "Unexpected track type " << track->type(); |
141 EXPECT_TRUE(false); | 251 EXPECT_TRUE(false); |
142 } | 252 } |
143 } | 253 } |
144 EXPECT_TRUE(found_audio_track); | 254 EXPECT_TRUE(found_audio_track); |
145 EXPECT_EQ(has_video_, found_video_track); | 255 EXPECT_EQ(has_video_, found_video_track); |
146 config_count_++; | 256 config_count_++; |
147 return true; | 257 return true; |
148 } | 258 } |
149 | 259 |
| 260 void CaptureVideoBuffers(const StreamParser::BufferQueue& video_buffers) { |
| 261 for (const auto& buffer : video_buffers) { |
| 262 video_buffer_capture_.push_back(buffer); |
| 263 } |
| 264 } |
| 265 |
| 266 void CaptureAudioBuffers(const StreamParser::BufferQueue& audio_buffers) { |
| 267 for (const auto& buffer : audio_buffers) { |
| 268 audio_buffer_capture_.push_back(buffer); |
| 269 } |
| 270 } |
| 271 |
150 bool OnNewBuffers(const StreamParser::BufferQueueMap& buffer_queue_map) { | 272 bool OnNewBuffers(const StreamParser::BufferQueueMap& buffer_queue_map) { |
151 EXPECT_GT(config_count_, 0); | 273 EXPECT_GT(config_count_, 0); |
152 // Ensure that track ids are properly assigned on all emitted buffers. | 274 // Ensure that track ids are properly assigned on all emitted buffers. |
153 for (const auto& it : buffer_queue_map) { | 275 for (const auto& it : buffer_queue_map) { |
154 DVLOG(3) << "Buffers for track_id=" << it.first; | 276 DVLOG(3) << "Buffers for track_id=" << it.first; |
155 for (const auto& buf : it.second) { | 277 for (const auto& buf : it.second) { |
156 DVLOG(3) << " track_id=" << buf->track_id() | 278 DVLOG(3) << " track_id=" << buf->track_id() |
157 << ", size=" << buf->data_size() | 279 << ", size=" << buf->data_size() |
158 << ", pts=" << buf->timestamp().InSecondsF() | 280 << ", pts=" << buf->timestamp().InSecondsF() |
159 << ", dts=" << buf->GetDecodeTimestamp().InSecondsF() | 281 << ", dts=" << buf->GetDecodeTimestamp().InSecondsF() |
160 << ", dur=" << buf->duration().InSecondsF(); | 282 << ", dur=" << buf->duration().InSecondsF(); |
161 EXPECT_EQ(it.first, buf->track_id()); | 283 EXPECT_EQ(it.first, buf->track_id()); |
162 } | 284 } |
163 } | 285 } |
164 | 286 |
165 const StreamParser::BufferQueue empty_buffers; | 287 const StreamParser::BufferQueue empty_buffers; |
166 const auto& itr_audio = buffer_queue_map.find(audio_track_id_); | 288 const auto& itr_audio = buffer_queue_map.find(audio_track_id_); |
167 const StreamParser::BufferQueue& audio_buffers = | 289 const StreamParser::BufferQueue& audio_buffers = |
168 (itr_audio == buffer_queue_map.end()) ? empty_buffers | 290 (itr_audio == buffer_queue_map.end()) ? empty_buffers |
169 : itr_audio->second; | 291 : itr_audio->second; |
170 | 292 |
171 const auto& itr_video = buffer_queue_map.find(video_track_id_); | 293 const auto& itr_video = buffer_queue_map.find(video_track_id_); |
172 const StreamParser::BufferQueue& video_buffers = | 294 const StreamParser::BufferQueue& video_buffers = |
173 (itr_video == buffer_queue_map.end()) ? empty_buffers | 295 (itr_video == buffer_queue_map.end()) ? empty_buffers |
174 : itr_video->second; | 296 : itr_video->second; |
175 | 297 |
| 298 if (capture_buffers) { |
| 299 CaptureVideoBuffers(video_buffers); |
| 300 CaptureAudioBuffers(audio_buffers); |
| 301 } |
| 302 |
176 // Verify monotonicity. | 303 // Verify monotonicity. |
177 if (!IsMonotonic(video_buffers)) | 304 if (!IsMonotonic(video_buffers)) |
178 return false; | 305 return false; |
179 if (!IsMonotonic(audio_buffers)) | 306 if (!IsMonotonic(audio_buffers)) |
180 return false; | 307 return false; |
181 | 308 |
182 if (!video_buffers.empty()) { | 309 if (!video_buffers.empty()) { |
183 DecodeTimestamp first_dts = video_buffers.front()->GetDecodeTimestamp(); | 310 DecodeTimestamp first_dts = video_buffers.front()->GetDecodeTimestamp(); |
184 DecodeTimestamp last_dts = video_buffers.back()->GetDecodeTimestamp(); | 311 DecodeTimestamp last_dts = video_buffers.back()->GetDecodeTimestamp(); |
185 if (video_max_dts_ != kNoDecodeTimestamp() && first_dts < video_max_dts_) | 312 if (video_max_dts_ != kNoDecodeTimestamp() && first_dts < video_max_dts_) |
(...skipping 12 matching lines...) Expand all Loading... |
198 audio_max_dts_ = last_dts; | 325 audio_max_dts_ = last_dts; |
199 } | 326 } |
200 | 327 |
201 audio_frame_count_ += audio_buffers.size(); | 328 audio_frame_count_ += audio_buffers.size(); |
202 video_frame_count_ += video_buffers.size(); | 329 video_frame_count_ += video_buffers.size(); |
203 return true; | 330 return true; |
204 } | 331 } |
205 | 332 |
206 void OnKeyNeeded(EmeInitDataType type, | 333 void OnKeyNeeded(EmeInitDataType type, |
207 const std::vector<uint8_t>& init_data) { | 334 const std::vector<uint8_t>& init_data) { |
| 335 #if !BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
208 LOG(ERROR) << "OnKeyNeeded not expected in the Mpeg2 TS parser"; | 336 LOG(ERROR) << "OnKeyNeeded not expected in the Mpeg2 TS parser"; |
209 EXPECT_TRUE(false); | 337 EXPECT_TRUE(false); |
| 338 #endif |
210 } | 339 } |
211 | 340 |
212 void OnNewSegment() { | 341 void OnNewSegment() { |
213 DVLOG(1) << "OnNewSegment"; | 342 DVLOG(1) << "OnNewSegment"; |
214 segment_count_++; | 343 segment_count_++; |
215 } | 344 } |
216 | 345 |
217 void OnEndOfSegment() { | 346 void OnEndOfSegment() { |
218 LOG(ERROR) << "OnEndOfSegment not expected in the Mpeg2 TS parser"; | 347 LOG(ERROR) << "OnEndOfSegment not expected in the Mpeg2 TS parser"; |
219 EXPECT_TRUE(false); | 348 EXPECT_TRUE(false); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 has_video_ = false; | 446 has_video_ = false; |
318 ParseMpeg2TsFile("bear_adts_in_private_stream_1.ts", 512); | 447 ParseMpeg2TsFile("bear_adts_in_private_stream_1.ts", 512); |
319 parser_->Flush(); | 448 parser_->Flush(); |
320 EXPECT_EQ(audio_frame_count_, 40); | 449 EXPECT_EQ(audio_frame_count_, 40); |
321 EXPECT_EQ(video_frame_count_, 0); | 450 EXPECT_EQ(video_frame_count_, 0); |
322 // This stream has no mid-stream configuration change. | 451 // This stream has no mid-stream configuration change. |
323 EXPECT_EQ(config_count_, 1); | 452 EXPECT_EQ(config_count_, 1); |
324 EXPECT_EQ(segment_count_, 1); | 453 EXPECT_EQ(segment_count_, 1); |
325 } | 454 } |
326 | 455 |
| 456 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
| 457 TEST_F(Mp2tStreamParserTest, HLSSampleAES) { |
| 458 std::vector<std::string> decrypted_video_buffers; |
| 459 std::vector<std::string> decrypted_audio_buffers; |
| 460 InitializeParser(); |
| 461 capture_buffers = true; |
| 462 ParseMpeg2TsFile("bear-1280x720-hls-sample-aes.ts", 2048); |
| 463 parser_->Flush(); |
| 464 EncryptionScheme video_encryption_scheme = |
| 465 current_video_config_.encryption_scheme(); |
| 466 EXPECT_TRUE(video_encryption_scheme.is_encrypted()); |
| 467 for (const auto& buffer : video_buffer_capture_) { |
| 468 std::string decrypted_video_buffer = |
| 469 DecryptBuffer(*buffer.get(), video_encryption_scheme); |
| 470 decrypted_video_buffers.push_back(decrypted_video_buffer); |
| 471 } |
| 472 EncryptionScheme audio_encryption_scheme = |
| 473 current_audio_config_.encryption_scheme(); |
| 474 EXPECT_TRUE(audio_encryption_scheme.is_encrypted()); |
| 475 for (const auto& buffer : audio_buffer_capture_) { |
| 476 std::string decrypted_audio_buffer = |
| 477 DecryptBuffer(*buffer.get(), audio_encryption_scheme); |
| 478 decrypted_audio_buffers.push_back(decrypted_audio_buffer); |
| 479 } |
| 480 |
| 481 parser_.reset(new Mp2tStreamParser(false)); |
| 482 ResetStats(); |
| 483 InitializeParser(); |
| 484 video_buffer_capture_.clear(); |
| 485 audio_buffer_capture_.clear(); |
| 486 ParseMpeg2TsFile("bear-1280x720-hls.ts", 2048); |
| 487 parser_->Flush(); |
| 488 video_encryption_scheme = current_video_config_.encryption_scheme(); |
| 489 EXPECT_FALSE(video_encryption_scheme.is_encrypted()); |
| 490 // Skip the last buffer, which may be truncated. |
| 491 for (size_t i = 0; i + 1 < video_buffer_capture_.size(); i++) { |
| 492 const auto& buffer = video_buffer_capture_[i]; |
| 493 std::string unencrypted_video_buffer( |
| 494 reinterpret_cast<const char*>(buffer->data()), buffer->data_size()); |
| 495 EXPECT_EQ(decrypted_video_buffers[i], unencrypted_video_buffer); |
| 496 } |
| 497 audio_encryption_scheme = current_audio_config_.encryption_scheme(); |
| 498 EXPECT_FALSE(audio_encryption_scheme.is_encrypted()); |
| 499 for (size_t i = 0; i + 1 < audio_buffer_capture_.size(); i++) { |
| 500 const auto& buffer = audio_buffer_capture_[i]; |
| 501 std::string unencrypted_audio_buffer( |
| 502 reinterpret_cast<const char*>(buffer->data()), buffer->data_size()); |
| 503 EXPECT_EQ(decrypted_audio_buffers[i], unencrypted_audio_buffer); |
| 504 } |
| 505 } |
| 506 #endif |
| 507 |
327 } // namespace mp2t | 508 } // namespace mp2t |
328 } // namespace media | 509 } // namespace media |
OLD | NEW |