Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(367)

Side by Side Diff: media/formats/mp2t/es_parser_h264_unittest.cc

Issue 399433003: Mpeg2 TS - Fail when no valid timestamp in the ADTS parser. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update ComputePacketSize prototype. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <algorithm> 5 #include <algorithm>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/files/memory_mapped_file.h" 10 #include "base/files/memory_mapped_file.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/path_service.h" 12 #include "base/path_service.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "media/base/stream_parser_buffer.h" 14 #include "media/base/stream_parser_buffer.h"
15 #include "media/base/test_data_util.h" 15 #include "media/base/test_data_util.h"
16 #include "media/filters/h264_parser.h" 16 #include "media/filters/h264_parser.h"
17 #include "media/formats/mp2t/es_parser_h264.h" 17 #include "media/formats/mp2t/es_parser_h264.h"
18 #include "media/formats/mp2t/es_parser_test_helper.h"
18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
19 20
20 namespace media { 21 namespace media {
21 class VideoDecoderConfig; 22 class VideoDecoderConfig;
22 23
23 namespace mp2t { 24 namespace mp2t {
24 25
25 namespace { 26 namespace {
26 27
27 struct Packet {
28 // Offset in the stream.
29 size_t offset;
30
31 // Size of the packet.
32 size_t size;
33
34 // Timestamp of the packet.
35 base::TimeDelta pts;
36 };
37
38 // Compute the size of each packet assuming packets are given in stream order
39 // and the last packet covers the end of the stream.
40 void ComputePacketSize(std::vector<Packet>& packets, size_t stream_size) {
41 for (size_t k = 0; k < packets.size() - 1; k++) {
42 DCHECK_GE(packets[k + 1].offset, packets[k].offset);
43 packets[k].size = packets[k + 1].offset - packets[k].offset;
44 }
45 packets[packets.size() - 1].size =
46 stream_size - packets[packets.size() - 1].offset;
47 }
48
49 // Get the offset of the start of each access unit. 28 // Get the offset of the start of each access unit.
50 // This function assumes there is only one slice per access unit. 29 // This function assumes there is only one slice per access unit.
51 // This is a very simplified access unit segmenter that is good 30 // This is a very simplified access unit segmenter that is good
52 // enough for unit tests. 31 // enough for unit tests.
53 std::vector<Packet> GetAccessUnits(const uint8* stream, size_t stream_size) { 32 std::vector<Packet> GetAccessUnits(const uint8* stream, size_t stream_size) {
54 std::vector<Packet> access_units; 33 std::vector<Packet> access_units;
55 bool start_access_unit = true; 34 bool start_access_unit = true;
56 35
57 // In a first pass, retrieve the offsets of all access units. 36 // In a first pass, retrieve the offsets of all access units.
58 size_t offset = 0; 37 size_t offset = 0;
(...skipping 21 matching lines...) Expand all
80 break; 59 break;
81 int nal_unit_type = stream[offset] & 0x1f; 60 int nal_unit_type = stream[offset] & 0x1f;
82 61
83 // We assume there is only one slice per access unit. 62 // We assume there is only one slice per access unit.
84 if (nal_unit_type == H264NALU::kIDRSlice || 63 if (nal_unit_type == H264NALU::kIDRSlice ||
85 nal_unit_type == H264NALU::kNonIDRSlice) { 64 nal_unit_type == H264NALU::kNonIDRSlice) {
86 start_access_unit = true; 65 start_access_unit = true;
87 } 66 }
88 } 67 }
89 68
90 ComputePacketSize(access_units, stream_size); 69 ComputePacketSize(&access_units, stream_size);
91 return access_units; 70 return access_units;
92 } 71 }
93 72
94 // Append an AUD NALU at the beginning of each access unit 73 // Append an AUD NALU at the beginning of each access unit
95 // needed for streams which do not already have AUD NALUs. 74 // needed for streams which do not already have AUD NALUs.
96 void AppendAUD( 75 void AppendAUD(
97 const uint8* stream, size_t stream_size, 76 const uint8* stream, size_t stream_size,
98 const std::vector<Packet>& access_units, 77 const std::vector<Packet>& access_units,
99 std::vector<uint8>& stream_with_aud, 78 std::vector<uint8>& stream_with_aud,
100 std::vector<Packet>& access_units_with_aud) { 79 std::vector<Packet>& access_units_with_aud) {
(...skipping 19 matching lines...) Expand all
120 99
121 class EsParserH264Test : public testing::Test { 100 class EsParserH264Test : public testing::Test {
122 public: 101 public:
123 EsParserH264Test() : buffer_count_(0) { 102 EsParserH264Test() : buffer_count_(0) {
124 } 103 }
125 virtual ~EsParserH264Test() {} 104 virtual ~EsParserH264Test() {}
126 105
127 protected: 106 protected:
128 void LoadStream(const char* filename); 107 void LoadStream(const char* filename);
129 void GetPesTimestamps(std::vector<Packet>& pes_packets); 108 void GetPesTimestamps(std::vector<Packet>& pes_packets);
130 void ProcessPesPackets(const std::vector<Packet>& pes_packets, 109 bool Process(const std::vector<Packet>& pes_packets, bool force_timing);
131 bool force_timing);
132 110
133 // Stream with AUD NALUs. 111 // Stream with AUD NALUs.
134 std::vector<uint8> stream_; 112 std::vector<uint8> stream_;
135 113
136 // Access units of the stream with AUD NALUs. 114 // Access units of the stream with AUD NALUs.
137 std::vector<Packet> access_units_; 115 std::vector<Packet> access_units_;
138 116
139 // Number of buffers generated while parsing the H264 stream. 117 // Number of buffers generated while parsing the H264 stream.
140 size_t buffer_count_; 118 size_t buffer_count_;
141 119
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 size_t pes_end = pes_packets[pes_idx].offset + pes_packets[pes_idx].size; 165 size_t pes_end = pes_packets[pes_idx].offset + pes_packets[pes_idx].size;
188 if (pes_start <= access_units_[k].offset && 166 if (pes_start <= access_units_[k].offset &&
189 pes_end > access_units_[k].offset) { 167 pes_end > access_units_[k].offset) {
190 pes_packets[pes_idx].pts = access_units_[k].pts; 168 pes_packets[pes_idx].pts = access_units_[k].pts;
191 break; 169 break;
192 } 170 }
193 } 171 }
194 } 172 }
195 } 173 }
196 174
197 void EsParserH264Test::ProcessPesPackets( 175 bool EsParserH264Test::Process(
198 const std::vector<Packet>& pes_packets, 176 const std::vector<Packet>& pes_packets,
199 bool force_timing) { 177 bool force_timing) {
200 EsParserH264 es_parser( 178 EsParserH264 es_parser(
201 base::Bind(&EsParserH264Test::NewVideoConfig, base::Unretained(this)), 179 base::Bind(&EsParserH264Test::NewVideoConfig, base::Unretained(this)),
202 base::Bind(&EsParserH264Test::EmitBuffer, base::Unretained(this))); 180 base::Bind(&EsParserH264Test::EmitBuffer, base::Unretained(this)));
203 181
204 for (size_t k = 0; k < pes_packets.size(); k++) { 182 return ProcessPesPackets(&es_parser, stream_, pes_packets, force_timing);
205 size_t cur_pes_offset = pes_packets[k].offset;
206 size_t cur_pes_size = pes_packets[k].size;
207
208 base::TimeDelta pts = kNoTimestamp();
209 base::TimeDelta dts = kNoTimestamp();
210 if (pes_packets[k].pts >= base::TimeDelta() || force_timing)
211 pts = pes_packets[k].pts;
212
213 ASSERT_TRUE(
214 es_parser.Parse(&stream_[cur_pes_offset], cur_pes_size, pts, dts));
215 }
216 es_parser.Flush();
217 } 183 }
218 184
219 void EsParserH264Test::EmitBuffer(scoped_refptr<StreamParserBuffer> buffer) { 185 void EsParserH264Test::EmitBuffer(scoped_refptr<StreamParserBuffer> buffer) {
220 ASSERT_LT(buffer_count_, access_units_.size()); 186 ASSERT_LT(buffer_count_, access_units_.size());
221 EXPECT_EQ(buffer->timestamp(), access_units_[buffer_count_].pts); 187 EXPECT_EQ(buffer->timestamp(), access_units_[buffer_count_].pts);
222 buffer_count_++; 188 buffer_count_++;
223 } 189 }
224 190
225 TEST_F(EsParserH264Test, OneAccessUnitPerPes) { 191 TEST_F(EsParserH264Test, OneAccessUnitPerPes) {
226 LoadStream("bear.h264"); 192 LoadStream("bear.h264");
227 193
228 // One to one equivalence between PES packets and access units. 194 // One to one equivalence between PES packets and access units.
229 std::vector<Packet> pes_packets(access_units_); 195 std::vector<Packet> pes_packets(access_units_);
230 GetPesTimestamps(pes_packets); 196 GetPesTimestamps(pes_packets);
231 197
232 // Process each PES packet. 198 // Process each PES packet.
233 ProcessPesPackets(pes_packets, false); 199 EXPECT_TRUE(Process(pes_packets, false));
234 EXPECT_EQ(buffer_count_, access_units_.size()); 200 EXPECT_EQ(buffer_count_, access_units_.size());
235 } 201 }
236 202
237 TEST_F(EsParserH264Test, NonAlignedPesPacket) { 203 TEST_F(EsParserH264Test, NonAlignedPesPacket) {
238 LoadStream("bear.h264"); 204 LoadStream("bear.h264");
239 205
240 // Generate the PES packets. 206 // Generate the PES packets.
241 std::vector<Packet> pes_packets; 207 std::vector<Packet> pes_packets;
242 Packet cur_pes_packet; 208 Packet cur_pes_packet;
243 cur_pes_packet.offset = 0; 209 cur_pes_packet.offset = 0;
244 for (size_t k = 0; k < access_units_.size(); k++) { 210 for (size_t k = 0; k < access_units_.size(); k++) {
245 pes_packets.push_back(cur_pes_packet); 211 pes_packets.push_back(cur_pes_packet);
246 212
247 // The current PES packet includes the remaining bytes of the previous 213 // The current PES packet includes the remaining bytes of the previous
248 // access unit and some bytes of the current access unit 214 // access unit and some bytes of the current access unit
249 // (487 bytes in this unit test but no more than the current access unit 215 // (487 bytes in this unit test but no more than the current access unit
250 // size). 216 // size).
251 cur_pes_packet.offset = access_units_[k].offset + 217 cur_pes_packet.offset = access_units_[k].offset +
252 std::min<size_t>(487u, access_units_[k].size); 218 std::min<size_t>(487u, access_units_[k].size);
253 } 219 }
254 ComputePacketSize(pes_packets, stream_.size()); 220 ComputePacketSize(&pes_packets, stream_.size());
255 GetPesTimestamps(pes_packets); 221 GetPesTimestamps(pes_packets);
256 222
257 // Process each PES packet. 223 // Process each PES packet.
258 ProcessPesPackets(pes_packets, false); 224 EXPECT_TRUE(Process(pes_packets, false));
259 EXPECT_EQ(buffer_count_, access_units_.size()); 225 EXPECT_EQ(buffer_count_, access_units_.size());
260 } 226 }
261 227
262 TEST_F(EsParserH264Test, SeveralPesPerAccessUnit) { 228 TEST_F(EsParserH264Test, SeveralPesPerAccessUnit) {
263 LoadStream("bear.h264"); 229 LoadStream("bear.h264");
264 230
265 // Get the minimum size of an access unit. 231 // Get the minimum size of an access unit.
266 size_t min_access_unit_size = stream_.size(); 232 size_t min_access_unit_size = stream_.size();
267 for (size_t k = 0; k < access_units_.size(); k++) { 233 for (size_t k = 0; k < access_units_.size(); k++) {
268 if (min_access_unit_size >= access_units_[k].size) 234 if (min_access_unit_size >= access_units_[k].size)
269 min_access_unit_size = access_units_[k].size; 235 min_access_unit_size = access_units_[k].size;
270 } 236 }
271 237
272 // Use a small PES packet size or the minimum access unit size 238 // Use a small PES packet size or the minimum access unit size
273 // if it is even smaller. 239 // if it is even smaller.
274 size_t pes_size = 512; 240 size_t pes_size = 512;
275 if (min_access_unit_size < pes_size) 241 if (min_access_unit_size < pes_size)
276 pes_size = min_access_unit_size; 242 pes_size = min_access_unit_size;
277 243
278 std::vector<Packet> pes_packets; 244 std::vector<Packet> pes_packets;
279 Packet cur_pes_packet; 245 Packet cur_pes_packet;
280 cur_pes_packet.offset = 0; 246 cur_pes_packet.offset = 0;
281 while (cur_pes_packet.offset < stream_.size()) { 247 while (cur_pes_packet.offset < stream_.size()) {
282 pes_packets.push_back(cur_pes_packet); 248 pes_packets.push_back(cur_pes_packet);
283 cur_pes_packet.offset += pes_size; 249 cur_pes_packet.offset += pes_size;
284 } 250 }
285 ComputePacketSize(pes_packets, stream_.size()); 251 ComputePacketSize(&pes_packets, stream_.size());
286 GetPesTimestamps(pes_packets); 252 GetPesTimestamps(pes_packets);
287 253
288 // Process each PES packet. 254 // Process each PES packet.
289 ProcessPesPackets(pes_packets, false); 255 EXPECT_TRUE(Process(pes_packets, false));
290 EXPECT_EQ(buffer_count_, access_units_.size()); 256 EXPECT_EQ(buffer_count_, access_units_.size());
291 257
292 // Process PES packets forcing timings for each PES packet. 258 // Process PES packets forcing timings for each PES packet.
293 buffer_count_ = 0; 259 buffer_count_ = 0;
294 ProcessPesPackets(pes_packets, true); 260 EXPECT_TRUE(Process(pes_packets, true));
295 EXPECT_EQ(buffer_count_, access_units_.size()); 261 EXPECT_EQ(buffer_count_, access_units_.size());
296 } 262 }
297 263
298 } // namespace mp2t 264 } // namespace mp2t
299 } // namespace media 265 } // namespace media
300 266
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698