Commit 5caab9db authored by Dale Curtis's avatar Dale Curtis Committed by Commit Bot

Fix spammy empty packets from slowing down demuxing.

This takes the runtime of the demuxer for the linked bug from 70s to
3.5s; there is a small risk this will block the blocking_thread_ for
a longer time, but that's a dedicated thread for this demuxer, so
that's fine.

BUG=852093
TEST=fuzzer
R=tmathmeyer

Change-Id: I01d1dab399059caaa7cf5b2a280484c0f9d4cc42
Reviewed-on: https://chromium-review.googlesource.com/c/1357631Reviewed-by: default avatarTed Meyer <tmathmeyer@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612913}
parent ffeff6a7
...@@ -220,6 +220,22 @@ static void SetTimeProperty(MediaLogEvent* event, ...@@ -220,6 +220,22 @@ static void SetTimeProperty(MediaLogEvent* event,
event->params.SetDouble(key, value.InSecondsF()); event->params.SetDouble(key, value.InSecondsF());
} }
static int ReadFrameAndDiscardEmpty(AVFormatContext* context,
AVPacket* packet) {
// Skip empty packets in a tight loop to avoid timing out fuzzers.
int result;
bool drop_packet;
do {
result = av_read_frame(context, packet);
drop_packet = (!packet->data || !packet->size) && result >= 0;
DLOG_IF(WARNING, drop_packet)
<< "Dropping empty packet, size: " << packet->size
<< ", data: " << static_cast<void*>(packet->data);
} while (drop_packet);
return result;
}
std::unique_ptr<FFmpegDemuxerStream> FFmpegDemuxerStream::Create( std::unique_ptr<FFmpegDemuxerStream> FFmpegDemuxerStream::Create(
FFmpegDemuxer* demuxer, FFmpegDemuxer* demuxer,
AVStream* stream, AVStream* stream,
...@@ -1817,9 +1833,10 @@ void FFmpegDemuxer::ReadFrameIfNeeded() { ...@@ -1817,9 +1833,10 @@ void FFmpegDemuxer::ReadFrameIfNeeded() {
pending_read_ = true; pending_read_ = true;
base::PostTaskAndReplyWithResult( base::PostTaskAndReplyWithResult(
blocking_task_runner_.get(), FROM_HERE, blocking_task_runner_.get(), FROM_HERE,
base::Bind(&av_read_frame, glue_->format_context(), packet_ptr), base::BindOnce(&ReadFrameAndDiscardEmpty, glue_->format_context(),
base::Bind(&FFmpegDemuxer::OnReadFrameDone, weak_factory_.GetWeakPtr(), packet_ptr),
base::Passed(&packet))); base::BindOnce(&FFmpegDemuxer::OnReadFrameDone,
weak_factory_.GetWeakPtr(), std::move(packet)));
} }
void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
...@@ -1870,11 +1887,11 @@ void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { ...@@ -1870,11 +1887,11 @@ void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
// giving us a bad stream index. See http://crbug.com/698549 for example. // giving us a bad stream index. See http://crbug.com/698549 for example.
if (packet->stream_index >= 0 && if (packet->stream_index >= 0 &&
static_cast<size_t>(packet->stream_index) < streams_.size()) { static_cast<size_t>(packet->stream_index) < streams_.size()) {
// Drop empty packets since they're ignored on the decoder side anyways. // This is ensured by ReadFrameAndDiscardEmpty.
if (!packet->data || !packet->size) { DCHECK(packet->data);
DLOG(WARNING) << "Dropping empty packet, size: " << packet->size DCHECK(packet->size);
<< ", data: " << static_cast<void*>(packet->data);
} else if (auto& demuxer_stream = streams_[packet->stream_index]) { if (auto& demuxer_stream = streams_[packet->stream_index]) {
if (demuxer_stream->IsEnabled()) if (demuxer_stream->IsEnabled())
demuxer_stream->EnqueuePacket(std::move(packet)); demuxer_stream->EnqueuePacket(std::move(packet));
......
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