Commit bf74c81c authored by servolk's avatar servolk Committed by Commit bot

Skip audio frames with unknown timestamp in MPEG2TS

This is another issue with HLS streams produced by VLC. Even though it's recommended that each PES packet in MPEG2TS contain a timestamp, we have seen that in the real-world content streams that's not always the case. In order to be able to play such streams, instead of failing stream parsing when we don't have timing info at the beginning of playback, we will just skip some frames until we eventually  get a frame with timing info and from that point we should be able to proceed playing normally. Previous change by Damien fixed this issue for video streams. This change fixes it for AAC ADTS and MPEG1 audio streams in mpeg2 ts containers.

BUG=420227

Review URL: https://codereview.chromium.org/646673002

Cr-Commit-Position: refs/heads/master@{#298982}
parent 2eeb4667
...@@ -140,8 +140,9 @@ bool EsParserAdts::ParseFromEsQueue() { ...@@ -140,8 +140,9 @@ bool EsParserAdts::ParseFromEsQueue() {
audio_timestamp_helper_->SetBaseTimestamp(current_timing_desc.pts); audio_timestamp_helper_->SetBaseTimestamp(current_timing_desc.pts);
if (audio_timestamp_helper_->base_timestamp() == kNoTimestamp()) { if (audio_timestamp_helper_->base_timestamp() == kNoTimestamp()) {
DVLOG(1) << "Audio frame with unknown timestamp"; DVLOG(1) << "Skipping audio frame with unknown timestamp";
return false; SkipAdtsFrame(adts_frame);
continue;
} }
base::TimeDelta current_pts = audio_timestamp_helper_->GetTimestamp(); base::TimeDelta current_pts = audio_timestamp_helper_->GetTimestamp();
base::TimeDelta frame_duration = base::TimeDelta frame_duration =
......
...@@ -47,7 +47,11 @@ bool EsParserAdtsTest::Process( ...@@ -47,7 +47,11 @@ bool EsParserAdtsTest::Process(
TEST_F(EsParserAdtsTest, NoInitialPts) { TEST_F(EsParserAdtsTest, NoInitialPts) {
LoadStream("bear.adts"); LoadStream("bear.adts");
std::vector<Packet> pes_packets = GenerateFixedSizePesPacket(512); std::vector<Packet> pes_packets = GenerateFixedSizePesPacket(512);
EXPECT_FALSE(Process(pes_packets, false)); // Process should succeed even without timing info, we should just skip the
// audio frames without timing info, but still should be able to parse and
// play the stream after that.
EXPECT_TRUE(Process(pes_packets, false));
EXPECT_EQ(1u, config_count_);
EXPECT_EQ(0u, buffer_count_); EXPECT_EQ(0u, buffer_count_);
} }
......
...@@ -64,8 +64,9 @@ bool EsParserMpeg1Audio::ParseFromEsQueue() { ...@@ -64,8 +64,9 @@ bool EsParserMpeg1Audio::ParseFromEsQueue() {
audio_timestamp_helper_->SetBaseTimestamp(current_timing_desc.pts); audio_timestamp_helper_->SetBaseTimestamp(current_timing_desc.pts);
if (audio_timestamp_helper_->base_timestamp() == kNoTimestamp()) { if (audio_timestamp_helper_->base_timestamp() == kNoTimestamp()) {
DVLOG(1) << "Audio frame with unknown timestamp"; DVLOG(1) << "Skipping audio frame with unknown timestamp";
return false; SkipMpeg1AudioFrame(mpeg1audio_frame);
continue;
} }
base::TimeDelta current_pts = audio_timestamp_helper_->GetTimestamp(); base::TimeDelta current_pts = audio_timestamp_helper_->GetTimestamp();
base::TimeDelta frame_duration = base::TimeDelta frame_duration =
......
...@@ -68,5 +68,17 @@ TEST_F(EsParserMpeg1AudioTest, SinglePts) { ...@@ -68,5 +68,17 @@ TEST_F(EsParserMpeg1AudioTest, SinglePts) {
EXPECT_EQ(12u, buffer_count_); EXPECT_EQ(12u, buffer_count_);
} }
TEST_F(EsParserMpeg1AudioTest, NoTimingInfo) {
LoadStream("sfx.mp3");
std::vector<Packet> pes_packets = GenerateFixedSizePesPacket(512);
// Process should succeed even without timing info, we should just skip the
// audio frames without timing info, but still should be able to parse and
// play the stream after that.
EXPECT_TRUE(Process(pes_packets, false));
EXPECT_EQ(1u, config_count_);
EXPECT_EQ(0u, buffer_count_);
}
} // namespace mp2t } // namespace mp2t
} // namespace media } // namespace media
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment