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/webm/webm_cluster_parser.h" | 5 #include "media/formats/webm/webm_cluster_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> |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 std::unique_ptr<Cluster> CreateEncryptedCluster(int bytes_to_write) { | 172 std::unique_ptr<Cluster> CreateEncryptedCluster(int bytes_to_write) { |
173 CHECK_GT(bytes_to_write, 0); | 173 CHECK_GT(bytes_to_write, 0); |
174 CHECK_LE(bytes_to_write, static_cast<int>(sizeof(kEncryptedFrame))); | 174 CHECK_LE(bytes_to_write, static_cast<int>(sizeof(kEncryptedFrame))); |
175 | 175 |
176 ClusterBuilder cb; | 176 ClusterBuilder cb; |
177 cb.SetClusterTimecode(0); | 177 cb.SetClusterTimecode(0); |
178 cb.AddSimpleBlock(kVideoTrackNum, 0, 0, kEncryptedFrame, bytes_to_write); | 178 cb.AddSimpleBlock(kVideoTrackNum, 0, 0, kEncryptedFrame, bytes_to_write); |
179 return cb.Finish(); | 179 return cb.Finish(); |
180 } | 180 } |
181 | 181 |
182 bool VerifyBuffers(const WebMClusterParser::BufferQueue& audio_buffers, | 182 bool VerifyBuffers(const StreamParser::BufferQueueMap& buffer_queue_map, |
183 const WebMClusterParser::BufferQueue& video_buffers, | |
184 const WebMClusterParser::BufferQueue& text_buffers, | |
185 const BlockInfo* block_info, | 183 const BlockInfo* block_info, |
186 int block_count) { | 184 int block_count) { |
187 int buffer_count = audio_buffers.size() + video_buffers.size() + | 185 int buffer_count = 0; |
188 text_buffers.size(); | 186 for (const auto& it : buffer_queue_map) |
| 187 buffer_count += it.second.size(); |
189 if (block_count != buffer_count) { | 188 if (block_count != buffer_count) { |
190 DVLOG(1) << __FUNCTION__ << " : block_count (" << block_count | 189 DVLOG(1) << __FUNCTION__ << " : block_count (" << block_count |
191 << ") mismatches buffer_count (" << buffer_count << ")"; | 190 << ") mismatches buffer_count (" << buffer_count << ")"; |
192 return false; | 191 return false; |
193 } | 192 } |
194 | 193 |
195 size_t audio_offset = 0; | 194 size_t audio_offset = 0; |
196 size_t video_offset = 0; | 195 size_t video_offset = 0; |
197 size_t text_offset = 0; | 196 size_t text_offset = 0; |
198 for (int i = 0; i < block_count; i++) { | 197 for (int i = 0; i < block_count; i++) { |
199 const WebMClusterParser::BufferQueue* buffers = NULL; | 198 const StreamParser::BufferQueue* buffers = NULL; |
200 size_t* offset; | 199 size_t* offset; |
201 StreamParserBuffer::Type expected_type = DemuxerStream::UNKNOWN; | 200 StreamParserBuffer::Type expected_type = DemuxerStream::UNKNOWN; |
202 | 201 |
| 202 const auto& it = buffer_queue_map.find(block_info[i].track_num); |
| 203 EXPECT_NE(buffer_queue_map.end(), it); |
| 204 buffers = &it->second; |
203 if (block_info[i].track_num == kAudioTrackNum) { | 205 if (block_info[i].track_num == kAudioTrackNum) { |
204 buffers = &audio_buffers; | |
205 offset = &audio_offset; | 206 offset = &audio_offset; |
206 expected_type = DemuxerStream::AUDIO; | 207 expected_type = DemuxerStream::AUDIO; |
207 } else if (block_info[i].track_num == kVideoTrackNum) { | 208 } else if (block_info[i].track_num == kVideoTrackNum) { |
208 buffers = &video_buffers; | |
209 offset = &video_offset; | 209 offset = &video_offset; |
210 expected_type = DemuxerStream::VIDEO; | 210 expected_type = DemuxerStream::VIDEO; |
211 } else if (block_info[i].track_num == kTextTrackNum) { | 211 } else if (block_info[i].track_num == kTextTrackNum) { |
212 buffers = &text_buffers; | |
213 offset = &text_offset; | 212 offset = &text_offset; |
214 expected_type = DemuxerStream::TEXT; | 213 expected_type = DemuxerStream::TEXT; |
215 } else { | 214 } else { |
216 LOG(ERROR) << "Unexpected track number " << block_info[i].track_num; | 215 LOG(ERROR) << "Unexpected track number " << block_info[i].track_num; |
217 return false; | 216 return false; |
218 } | 217 } |
219 | 218 |
220 if (*offset >= buffers->size()) { | 219 if (*offset >= buffers->size()) { |
221 DVLOG(1) << __FUNCTION__ << " : Too few buffers (" << buffers->size() | 220 DVLOG(1) << __FUNCTION__ << " : Too few buffers (" << buffers->size() |
222 << ") for track_num (" << block_info[i].track_num | 221 << ") for track_num (" << block_info[i].track_num |
(...skipping 10 matching lines...) Expand all Loading... |
233 EXPECT_EQ(block_info[i].track_num, buffer->track_id()); | 232 EXPECT_EQ(block_info[i].track_num, buffer->track_id()); |
234 EXPECT_EQ(block_info[i].is_key_frame, buffer->is_key_frame()); | 233 EXPECT_EQ(block_info[i].is_key_frame, buffer->is_key_frame()); |
235 } | 234 } |
236 | 235 |
237 return true; | 236 return true; |
238 } | 237 } |
239 | 238 |
240 bool VerifyBuffers(const std::unique_ptr<WebMClusterParser>& parser, | 239 bool VerifyBuffers(const std::unique_ptr<WebMClusterParser>& parser, |
241 const BlockInfo* block_info, | 240 const BlockInfo* block_info, |
242 int block_count) { | 241 int block_count) { |
243 const WebMClusterParser::TextBufferQueueMap& text_map = | 242 StreamParser::BufferQueueMap buffers; |
244 parser->GetTextBuffers(); | 243 parser->GetBuffers(&buffers); |
245 const WebMClusterParser::BufferQueue* text_buffers; | 244 return VerifyBuffers(buffers, block_info, block_count); |
246 const WebMClusterParser::BufferQueue no_text_buffers; | |
247 if (!text_map.empty()) | |
248 text_buffers = &(text_map.rbegin()->second); | |
249 else | |
250 text_buffers = &no_text_buffers; | |
251 | |
252 return VerifyBuffers(parser->GetAudioBuffers(), | |
253 parser->GetVideoBuffers(), | |
254 *text_buffers, | |
255 block_info, | |
256 block_count); | |
257 } | 245 } |
258 | 246 |
259 bool VerifyTextBuffers(const std::unique_ptr<WebMClusterParser>& parser, | 247 bool VerifyTextBuffers(const std::unique_ptr<WebMClusterParser>& parser, |
260 const BlockInfo* block_info_ptr, | 248 const BlockInfo* block_info_ptr, |
261 int block_count, | 249 int block_count, |
262 int text_track_num, | 250 int text_track_num, |
263 const WebMClusterParser::BufferQueue& text_buffers) { | 251 const WebMClusterParser::BufferQueue& text_buffers) { |
264 const BlockInfo* const block_info_end = block_info_ptr + block_count; | 252 const BlockInfo* const block_info_end = block_info_ptr + block_count; |
265 | 253 |
266 typedef WebMClusterParser::BufferQueue::const_iterator TextBufferIter; | 254 typedef WebMClusterParser::BufferQueue::const_iterator TextBufferIter; |
(...skipping 20 matching lines...) Expand all Loading... |
287 EXPECT_TRUE(buffer_iter == buffer_end); | 275 EXPECT_TRUE(buffer_iter == buffer_end); |
288 return true; | 276 return true; |
289 } | 277 } |
290 | 278 |
291 void VerifyEncryptedBuffer(scoped_refptr<StreamParserBuffer> buffer) { | 279 void VerifyEncryptedBuffer(scoped_refptr<StreamParserBuffer> buffer) { |
292 EXPECT_TRUE(buffer->decrypt_config()); | 280 EXPECT_TRUE(buffer->decrypt_config()); |
293 EXPECT_EQ(static_cast<unsigned long>(DecryptConfig::kDecryptionKeySize), | 281 EXPECT_EQ(static_cast<unsigned long>(DecryptConfig::kDecryptionKeySize), |
294 buffer->decrypt_config()->iv().length()); | 282 buffer->decrypt_config()->iv().length()); |
295 } | 283 } |
296 | 284 |
297 void AppendToEnd(const WebMClusterParser::BufferQueue& src, | 285 void AppendToEnd(const StreamParser::BufferQueue& src, |
298 WebMClusterParser::BufferQueue* dest) { | 286 StreamParser::BufferQueue* dest) { |
299 for (WebMClusterParser::BufferQueue::const_iterator itr = src.begin(); | 287 for (StreamParser::BufferQueue::const_iterator itr = src.begin(); |
300 itr != src.end(); ++itr) { | 288 itr != src.end(); ++itr) { |
301 dest->push_back(*itr); | 289 dest->push_back(*itr); |
302 } | 290 } |
303 } | 291 } |
304 | 292 |
305 } // namespace | 293 } // namespace |
306 | 294 |
307 class WebMClusterParserTest : public testing::Test { | 295 class WebMClusterParserTest : public testing::Test { |
308 public: | 296 public: |
309 WebMClusterParserTest() | 297 WebMClusterParserTest() |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 int result = parser_->Parse(cluster->data(), cluster->size()); | 496 int result = parser_->Parse(cluster->data(), cluster->size()); |
509 EXPECT_EQ(cluster->size(), result); | 497 EXPECT_EQ(cluster->size(), result); |
510 ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count)); | 498 ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count)); |
511 } | 499 } |
512 | 500 |
513 TEST_F(WebMClusterParserTest, ParseClusterWithMultipleCalls) { | 501 TEST_F(WebMClusterParserTest, ParseClusterWithMultipleCalls) { |
514 int block_count = arraysize(kDefaultBlockInfo); | 502 int block_count = arraysize(kDefaultBlockInfo); |
515 std::unique_ptr<Cluster> cluster( | 503 std::unique_ptr<Cluster> cluster( |
516 CreateCluster(0, kDefaultBlockInfo, block_count)); | 504 CreateCluster(0, kDefaultBlockInfo, block_count)); |
517 | 505 |
518 WebMClusterParser::BufferQueue audio_buffers; | |
519 WebMClusterParser::BufferQueue video_buffers; | |
520 const WebMClusterParser::BufferQueue no_text_buffers; | |
521 | |
522 const uint8_t* data = cluster->data(); | 506 const uint8_t* data = cluster->data(); |
523 int size = cluster->size(); | 507 int size = cluster->size(); |
524 int default_parse_size = 3; | 508 int default_parse_size = 3; |
525 int parse_size = std::min(default_parse_size, size); | 509 int parse_size = std::min(default_parse_size, size); |
526 | 510 |
| 511 StreamParser::BufferQueueMap buffers; |
527 while (size > 0) { | 512 while (size > 0) { |
528 int result = parser_->Parse(data, parse_size); | 513 int result = parser_->Parse(data, parse_size); |
529 ASSERT_GE(result, 0); | 514 ASSERT_GE(result, 0); |
530 ASSERT_LE(result, parse_size); | 515 ASSERT_LE(result, parse_size); |
531 | 516 |
532 if (result == 0) { | 517 if (result == 0) { |
533 // The parser needs more data so increase the parse_size a little. | 518 // The parser needs more data so increase the parse_size a little. |
534 parse_size += default_parse_size; | 519 parse_size += default_parse_size; |
535 parse_size = std::min(parse_size, size); | 520 parse_size = std::min(parse_size, size); |
536 continue; | 521 continue; |
537 } | 522 } |
538 | 523 |
539 AppendToEnd(parser_->GetAudioBuffers(), &audio_buffers); | 524 StreamParser::BufferQueueMap bqm; |
540 AppendToEnd(parser_->GetVideoBuffers(), &video_buffers); | 525 parser_->GetBuffers(&bqm); |
| 526 for (const auto& it : bqm) { |
| 527 AppendToEnd(it.second, &buffers[it.first]); |
| 528 } |
541 | 529 |
542 parse_size = default_parse_size; | 530 parse_size = default_parse_size; |
543 | 531 |
544 data += result; | 532 data += result; |
545 size -= result; | 533 size -= result; |
546 } | 534 } |
547 ASSERT_TRUE(VerifyBuffers(audio_buffers, video_buffers, | 535 ASSERT_TRUE(VerifyBuffers(buffers, kDefaultBlockInfo, block_count)); |
548 no_text_buffers, kDefaultBlockInfo, | |
549 block_count)); | |
550 } | 536 } |
551 | 537 |
552 // Verify that both BlockGroups with the BlockDuration before the Block | 538 // Verify that both BlockGroups with the BlockDuration before the Block |
553 // and BlockGroups with the BlockDuration after the Block are supported | 539 // and BlockGroups with the BlockDuration after the Block are supported |
554 // correctly. | 540 // correctly. |
555 // Note: Raw bytes are use here because ClusterBuilder only generates | 541 // Note: Raw bytes are use here because ClusterBuilder only generates |
556 // one of these scenarios. | 542 // one of these scenarios. |
557 TEST_F(WebMClusterParserTest, ParseBlockGroup) { | 543 TEST_F(WebMClusterParserTest, ParseBlockGroup) { |
558 const BlockInfo kBlockInfo[] = { | 544 const BlockInfo kBlockInfo[] = { |
559 {kAudioTrackNum, 0, 23, false, NULL, 0, true}, | 545 {kAudioTrackNum, 0, 23, false, NULL, 0, true}, |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 | 727 |
742 parser_.reset(CreateParserWithKeyIdsAndAudioCodec( | 728 parser_.reset(CreateParserWithKeyIdsAndAudioCodec( |
743 std::string(), "video_key_id", kUnknownAudioCodec)); | 729 std::string(), "video_key_id", kUnknownAudioCodec)); |
744 | 730 |
745 // The encrypted cluster contains just one block, video. | 731 // The encrypted cluster contains just one block, video. |
746 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated( | 732 EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated( |
747 WebMClusterParser::kDefaultVideoBufferDurationInMs)); | 733 WebMClusterParser::kDefaultVideoBufferDurationInMs)); |
748 | 734 |
749 int result = parser_->Parse(cluster->data(), cluster->size()); | 735 int result = parser_->Parse(cluster->data(), cluster->size()); |
750 EXPECT_EQ(cluster->size(), result); | 736 EXPECT_EQ(cluster->size(), result); |
751 ASSERT_EQ(1UL, parser_->GetVideoBuffers().size()); | 737 StreamParser::BufferQueueMap buffers; |
752 scoped_refptr<StreamParserBuffer> buffer = parser_->GetVideoBuffers()[0]; | 738 parser_->GetBuffers(&buffers); |
| 739 EXPECT_EQ(1UL, buffers[kVideoTrackNum].size()); |
| 740 scoped_refptr<StreamParserBuffer> buffer = buffers[kVideoTrackNum][0]; |
753 VerifyEncryptedBuffer(buffer); | 741 VerifyEncryptedBuffer(buffer); |
754 } | 742 } |
755 | 743 |
756 TEST_F(WebMClusterParserTest, ParseBadEncryptedBlock) { | 744 TEST_F(WebMClusterParserTest, ParseBadEncryptedBlock) { |
757 std::unique_ptr<Cluster> cluster( | 745 std::unique_ptr<Cluster> cluster( |
758 CreateEncryptedCluster(sizeof(kEncryptedFrame) - 1)); | 746 CreateEncryptedCluster(sizeof(kEncryptedFrame) - 1)); |
759 | 747 |
760 parser_.reset(CreateParserWithKeyIdsAndAudioCodec( | 748 parser_.reset(CreateParserWithKeyIdsAndAudioCodec( |
761 std::string(), "video_key_id", kUnknownAudioCodec)); | 749 std::string(), "video_key_id", kUnknownAudioCodec)); |
762 int result = parser_->Parse(cluster->data(), cluster->size()); | 750 int result = parser_->Parse(cluster->data(), cluster->size()); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 | 860 |
873 // Send slightly less than the first full cluster so all but the last video | 861 // Send slightly less than the first full cluster so all but the last video |
874 // block is parsed. Verify the last fully parsed audio and video buffer are | 862 // block is parsed. Verify the last fully parsed audio and video buffer are |
875 // both missing from the result (parser should hold them aside for duration | 863 // both missing from the result (parser should hold them aside for duration |
876 // estimation prior to end of cluster detection in the absence of | 864 // estimation prior to end of cluster detection in the absence of |
877 // DefaultDurations.) | 865 // DefaultDurations.) |
878 int result = parser_->Parse(cluster1->data(), cluster1->size() - 1); | 866 int result = parser_->Parse(cluster1->data(), cluster1->size() - 1); |
879 EXPECT_GT(result, 0); | 867 EXPECT_GT(result, 0); |
880 EXPECT_LT(result, cluster1->size()); | 868 EXPECT_LT(result, cluster1->size()); |
881 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1 - 3)); | 869 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1 - 3)); |
882 EXPECT_EQ(3UL, parser_->GetAudioBuffers().size()); | 870 StreamParser::BufferQueueMap buffers; |
883 EXPECT_EQ(1UL, parser_->GetVideoBuffers().size()); | 871 parser_->GetBuffers(&buffers); |
| 872 EXPECT_EQ(3UL, buffers[kAudioTrackNum].size()); |
| 873 EXPECT_EQ(1UL, buffers[kVideoTrackNum].size()); |
884 | 874 |
885 parser_->Reset(); | 875 parser_->Reset(); |
886 | 876 |
887 // Now parse the full first cluster and verify all the blocks are parsed. | 877 // Now parse the full first cluster and verify all the blocks are parsed. |
888 EXPECT_MEDIA_LOG( | 878 EXPECT_MEDIA_LOG( |
889 WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs)); | 879 WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs)); |
890 EXPECT_MEDIA_LOG( | 880 EXPECT_MEDIA_LOG( |
891 WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); | 881 WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); |
892 result = parser_->Parse(cluster1->data(), cluster1->size()); | 882 result = parser_->Parse(cluster1->data(), cluster1->size()); |
893 EXPECT_EQ(cluster1->size(), result); | 883 EXPECT_EQ(cluster1->size(), result); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 | 934 |
945 // Send slightly less than the first full cluster so all but the last video | 935 // Send slightly less than the first full cluster so all but the last video |
946 // block is parsed. Verify the last fully parsed audio and video buffer are | 936 // block is parsed. Verify the last fully parsed audio and video buffer are |
947 // both missing from the result (parser should hold them aside for duration | 937 // both missing from the result (parser should hold them aside for duration |
948 // estimation prior to end of cluster detection in the absence of | 938 // estimation prior to end of cluster detection in the absence of |
949 // DefaultDurations.) | 939 // DefaultDurations.) |
950 int result = parser_->Parse(cluster1->data(), cluster1->size() - 1); | 940 int result = parser_->Parse(cluster1->data(), cluster1->size() - 1); |
951 EXPECT_GT(result, 0); | 941 EXPECT_GT(result, 0); |
952 EXPECT_LT(result, cluster1->size()); | 942 EXPECT_LT(result, cluster1->size()); |
953 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1 - 3)); | 943 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1 - 3)); |
954 EXPECT_EQ(3UL, parser_->GetAudioBuffers().size()); | 944 StreamParser::BufferQueueMap buffers; |
955 EXPECT_EQ(1UL, parser_->GetVideoBuffers().size()); | 945 parser_->GetBuffers(&buffers); |
| 946 EXPECT_EQ(3UL, buffers[kAudioTrackNum].size()); |
| 947 EXPECT_EQ(1UL, buffers[kVideoTrackNum].size()); |
956 | 948 |
957 parser_->Reset(); | 949 parser_->Reset(); |
958 | 950 |
959 // Now parse the full first cluster and verify all the blocks are parsed. | 951 // Now parse the full first cluster and verify all the blocks are parsed. |
960 EXPECT_MEDIA_LOG( | 952 EXPECT_MEDIA_LOG( |
961 WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs)); | 953 WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs)); |
962 EXPECT_MEDIA_LOG( | 954 EXPECT_MEDIA_LOG( |
963 WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); | 955 WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); |
964 result = parser_->Parse(cluster1->data(), cluster1->size()); | 956 result = parser_->Parse(cluster1->data(), cluster1->size()); |
965 EXPECT_EQ(cluster1->size(), result); | 957 EXPECT_EQ(cluster1->size(), result); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 int block_count = arraysize(kBlockInfo); | 1172 int block_count = arraysize(kBlockInfo); |
1181 std::unique_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); | 1173 std::unique_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); |
1182 int result = parser_->Parse(cluster->data(), cluster->size()); | 1174 int result = parser_->Parse(cluster->data(), cluster->size()); |
1183 EXPECT_EQ(cluster->size(), result); | 1175 EXPECT_EQ(cluster->size(), result); |
1184 | 1176 |
1185 // Will verify that duration of buffer matches that of BlockDuration. | 1177 // Will verify that duration of buffer matches that of BlockDuration. |
1186 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count)); | 1178 ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count)); |
1187 } | 1179 } |
1188 | 1180 |
1189 } // namespace media | 1181 } // namespace media |
OLD | NEW |