Skip to content

Commit 4ad7de8

Browse files
committed
Adding smarter logic for detecting start of MPEG packet data
Adding test cases to verify the MPEG audio/video header has been properly decoded
1 parent 333bdcb commit 4ad7de8

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

src/TaglibSharp.Tests/FileFormats/MpgFormatTest.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,19 @@ public void Init ()
2424
[Test]
2525
public void ReadAudioProperties ()
2626
{
27+
Assert.AreEqual (128, file.Properties.AudioBitrate);
28+
Assert.AreEqual (2, file.Properties.AudioChannels);
2729
Assert.AreEqual (44100, file.Properties.AudioSampleRate);
2830
// NOTE, with .net core it keeps the decimal places. So, for now, we round to match .net behavior
2931
Assert.AreEqual (1391, Math.Round (file.Properties.Duration.TotalMilliseconds));
32+
33+
}
34+
35+
[Test]
36+
public void ReadVideoProperties ()
37+
{
38+
Assert.AreEqual (480, file.Properties.VideoHeight);
39+
Assert.AreEqual (640, file.Properties.VideoWidth);
3040
}
3141

3242

@@ -68,7 +78,7 @@ public void WritePictures ()
6878

6979
file.Save ();
7080

71-
// Read back the Matroska-specific tags
81+
// Read back the Matroska-specific tags
7282
file = File.Create (tmp_file);
7383
Assert.NotNull (file);
7484
pics = file.Tag.Pictures;

src/TaglibSharp/Mpeg/File.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,29 @@ void ReadAudioPacket (ref long position)
547547
Seek (position + 4);
548548
int length = ReadBlock (2).ToUShort ();
549549

550-
if (!audio_found)
551-
audio_found = AudioHeader.Find (out audio_header, this, position + 15, length - 9);
550+
if (!audio_found) {
551+
// There is a maximum of 16 stuffing bytes, read up to the PTS/DTS flags
552+
ByteVector packetHeaderBytes = this.ReadBlock (19);
553+
int i = 0;
554+
while (i < packetHeaderBytes.Count && packetHeaderBytes[i] == 0xFF) {
555+
// Byte is a stuffing byte
556+
i++;
557+
}
558+
559+
if ((packetHeaderBytes[i] & 0x40) != 0) {
560+
// STD buffer size is unexpected for audio packets, but whatever
561+
i++;
562+
}
563+
564+
// Decode the PTS/DTS flags
565+
byte timestampFlags = packetHeaderBytes[i];
566+
long dataOffset = 4 + 2 + i + // Packet marker + packet length + stuffing bytes/STD buffer size
567+
((timestampFlags & 0x20) > 0 ? 4 : 0) + // Presentation timestamp
568+
((timestampFlags & 0x10) > 0 ? 4 : 0); // Decode timestamp
569+
570+
audio_found = AudioHeader.Find (out audio_header, this, position + dataOffset, length - 9);
571+
}
572+
552573
position += length;
553574
}
554575

0 commit comments

Comments
 (0)