OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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 <algorithm> | |
6 #include <string> | |
7 | |
8 #include "base/bind.h" | |
9 #include "base/bind_helpers.h" | |
10 #include "base/logging.h" | |
11 #include "base/memory/ref_counted.h" | |
12 #include "base/time/time.h" | |
13 #include "media/base/audio_decoder_config.h" | |
14 #include "media/base/decoder_buffer.h" | |
15 #include "media/base/stream_parser_buffer.h" | |
16 #include "media/base/test_data_util.h" | |
17 #include "media/base/video_decoder_config.h" | |
18 #include "media/mp2t/mp2t_stream_parser.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 namespace media { | |
22 namespace mp2t { | |
23 | |
24 class Mp2tStreamParserTest : public testing::Test { | |
25 public: | |
26 Mp2tStreamParserTest() | |
27 : audio_frame_count_(0), | |
28 video_frame_count_(0), | |
29 video_min_dts_(kNoTimestamp()), | |
30 video_max_dts_(kNoTimestamp()) { | |
31 parser_.reset(new Mp2tStreamParser()); | |
32 } | |
33 | |
34 protected: | |
35 scoped_ptr<Mp2tStreamParser> parser_; | |
36 int audio_frame_count_; | |
37 int video_frame_count_; | |
38 base::TimeDelta video_min_dts_; | |
39 base::TimeDelta video_max_dts_; | |
40 | |
41 bool AppendData(const uint8* data, size_t length) { | |
42 return parser_->Parse(data, length); | |
43 } | |
44 | |
45 bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) { | |
46 const uint8* start = data; | |
47 const uint8* end = data + length; | |
48 while (start < end) { | |
49 size_t append_size = std::min(piece_size, | |
50 static_cast<size_t>(end - start)); | |
51 if (!AppendData(start, append_size)) | |
52 return false; | |
53 start += append_size; | |
54 } | |
55 return true; | |
56 } | |
57 | |
58 void InitF(bool init_ok, base::TimeDelta duration) { | |
acolwell GONE FROM CHROMIUM
2013/09/18 01:46:05
nit: drop F suffix here and below. You can use On
damienv1
2013/09/18 21:40:17
That was initially some code I took from the MP4 s
acolwell GONE FROM CHROMIUM
2013/09/18 22:38:55
Heh. I just realized this earlier today because I
| |
59 DVLOG(1) << "InitF: ok=" << init_ok | |
60 << ", dur=" << duration.InMilliseconds(); | |
61 } | |
62 | |
63 bool NewConfigF(const AudioDecoderConfig& ac, const VideoDecoderConfig& vc) { | |
64 DVLOG(1) << "NewConfigF: audio=" << ac.IsValidConfig() | |
65 << ", video=" << vc.IsValidConfig(); | |
66 return true; | |
67 } | |
68 | |
69 | |
70 void DumpBuffers(const std::string& label, | |
71 const StreamParser::BufferQueue& buffers) { | |
72 DVLOG(2) << "DumpBuffers: " << label << " size " << buffers.size(); | |
73 for (StreamParser::BufferQueue::const_iterator buf = buffers.begin(); | |
74 buf != buffers.end(); buf++) { | |
75 DVLOG(3) << " n=" << buf - buffers.begin() | |
76 << ", size=" << (*buf)->data_size() | |
77 << ", dur=" << (*buf)->duration().InMilliseconds(); | |
78 } | |
79 } | |
80 | |
81 bool NewBuffersF(const StreamParser::BufferQueue& audio_buffers, | |
82 const StreamParser::BufferQueue& video_buffers) { | |
83 DumpBuffers("audio_buffers", audio_buffers); | |
84 DumpBuffers("video_buffers", video_buffers); | |
85 audio_frame_count_ += audio_buffers.size(); | |
86 video_frame_count_ += video_buffers.size(); | |
87 | |
88 if (video_min_dts_ == kNoTimestamp() && !video_buffers.empty()) | |
89 video_min_dts_ = video_buffers.front()->GetDecodeTimestamp(); | |
90 if (!video_buffers.empty()) { | |
91 video_max_dts_ = video_buffers.back()->GetDecodeTimestamp(); | |
92 // Verify monotonicity. | |
93 StreamParser::BufferQueue::const_iterator it1 = video_buffers.begin(); | |
94 StreamParser::BufferQueue::const_iterator it2 = ++it1; | |
95 for ( ; it2 != video_buffers.end(); ++it1, ++it2) { | |
96 if ((*it2)->GetDecodeTimestamp() < (*it1)->GetDecodeTimestamp()) | |
97 return false; | |
98 } | |
99 } | |
100 | |
101 return true; | |
102 } | |
103 | |
104 bool NewTextBuffersF(TextTrack* text_track, | |
105 const StreamParser::BufferQueue& buffers) { | |
106 return true; | |
107 } | |
108 | |
109 void KeyNeededF(const std::string& type, | |
110 const std::vector<uint8>& init_data) { | |
111 DVLOG(1) << "KeyNeededF: " << init_data.size(); | |
112 } | |
113 | |
114 scoped_ptr<TextTrack> AddTextTrackF( | |
115 TextKind kind, | |
116 const std::string& label, | |
117 const std::string& language) { | |
118 return scoped_ptr<TextTrack>(); | |
119 } | |
120 | |
121 void NewSegmentF() { | |
122 DVLOG(1) << "NewSegmentF"; | |
123 } | |
124 | |
125 void EndOfSegmentF() { | |
126 DVLOG(1) << "EndOfSegmentF()"; | |
127 } | |
128 | |
129 void InitializeParser() { | |
130 parser_->Init( | |
131 base::Bind(&Mp2tStreamParserTest::InitF, | |
132 base::Unretained(this)), | |
133 base::Bind(&Mp2tStreamParserTest::NewConfigF, | |
134 base::Unretained(this)), | |
135 base::Bind(&Mp2tStreamParserTest::NewBuffersF, | |
136 base::Unretained(this)), | |
137 base::Bind(&Mp2tStreamParserTest::NewTextBuffersF, | |
138 base::Unretained(this)), | |
139 base::Bind(&Mp2tStreamParserTest::KeyNeededF, | |
140 base::Unretained(this)), | |
141 base::Bind(&Mp2tStreamParserTest::AddTextTrackF, | |
142 base::Unretained(this)), | |
143 base::Bind(&Mp2tStreamParserTest::NewSegmentF, | |
144 base::Unretained(this)), | |
145 base::Bind(&Mp2tStreamParserTest::EndOfSegmentF, | |
146 base::Unretained(this)), | |
147 LogCB()); | |
148 } | |
149 | |
150 bool ParseMpeg2TsFile(const std::string& filename, int append_bytes) { | |
151 InitializeParser(); | |
152 | |
153 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | |
154 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | |
155 buffer->data_size(), | |
156 append_bytes)); | |
157 return true; | |
158 } | |
159 }; | |
160 | |
161 TEST_F(Mp2tStreamParserTest, UnalignedAppend) { | |
acolwell GONE FROM CHROMIUM
2013/09/18 01:46:05
nit: Add a version that appends using a prime & sm
damienv1
2013/09/18 21:40:17
Done.
| |
162 // Test small, non-segment-aligned appends. | |
163 ParseMpeg2TsFile("bear-1280x720.ts", 512); | |
164 EXPECT_EQ(video_frame_count_, 81); | |
165 parser_->Flush(); | |
166 EXPECT_EQ(video_frame_count_, 82); | |
167 } | |
168 | |
169 TEST_F(Mp2tStreamParserTest, TimestampWrapAround) { | |
170 // "bear-1280x720_ptswraparound.ts" has been transcoded | |
171 // from bear-1280x720.mp4 by applying a time offset of 95442s | |
172 // (close to 2^33 / 90000) which results in timestamps wrap around | |
173 // in the Mpeg2 TS stream. | |
174 ParseMpeg2TsFile("bear-1280x720_ptswraparound.ts", 512); | |
175 EXPECT_EQ(video_frame_count_, 81); | |
176 EXPECT_GE(video_min_dts_, base::TimeDelta::FromSeconds(95443 - 10)); | |
177 EXPECT_LE(video_max_dts_, base::TimeDelta::FromSeconds(95443 + 10)); | |
178 } | |
179 | |
180 } // namespace mp2t | |
181 } // namespace media | |
OLD | NEW |