Skip to content

Commit

Permalink
fix to avoid the youtube video playing memory leak
Browse files Browse the repository at this point in the history
  • Loading branch information
Fernando Bernal committed Mar 8, 2017
1 parent ef8299a commit 158a023
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
12 changes: 11 additions & 1 deletion src/AVDemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 425,11 @@ bool AVDemuxer::readFrame()
d->pkt = Packet();
// no lock required because in AVDemuxThread read and seek are in the same thread
AVPacket packet;
av_init_packet(&packet);
d->interrupt_hanlder->begin(InterruptHandler::Read);
int ret = av_read_frame(d->format_ctx, &packet); //0: ok, <0: error/end
d->interrupt_hanlder->end();

// TODO: why return 0 if interrupted by user?
if (ret < 0) {
//end of file. FIXME: why no d->eof if replaying by seek(0)?
Expand All @@ -448,31 450,38 @@ bool AVDemuxer::readFrame()
#endif
qDebug("End of file. erreof=%d feof=%d", ret == AVERROR_EOF, avio_feof(d->format_ctx->pb));
}
av_packet_unref(&packet); //important!
return false;
}
if (ret == AVERROR(EAGAIN)) {
qWarning("demuxer EAGAIN :%s", av_err2str(ret));
av_packet_unref(&packet); //important!
return false;
}
AVError::ErrorCode ec(AVError::ReadError);
QString msg(tr("error reading stream data"));
handleError(ret, &ec, msg);
qWarning("[AVDemuxer] error: %s", av_err2str(ret));
av_packet_unref(&packet); //important!
return false;
}

d->stream = packet.stream_index;
//check whether the 1st frame is alreay got. emit only once
if (!d->started) {
d->started = true;
Q_EMIT started();
}

if (d->stream != videoStream() && d->stream != audioStream() && d->stream != subtitleStream()) {
//qWarning("[AVDemuxer] unknown stream index: %d", stream);
av_packet_unref(&packet); //important!
return false;
}

// TODO: v4l2 copy
d->pkt = Packet::fromAVPacket(&packet, av_q2d(d->format_ctx->streams[d->stream]->time_base));
av_packet_unref(&packet); //important!

d->eof = false;
if (d->pkt.pts > qreal(duration())/1000.0) {
d->max_pts = d->pkt.pts;
Expand Down Expand Up @@ -878,6 887,7 @@ bool AVDemuxer::unload()
d->input->release();
Q_EMIT unloaded();
}

return true;
}

Expand Down
8 changes: 7 additions & 1 deletion src/Packet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 126,14 @@ bool Packet::fromAVPacket(Packet* pkt, const AVPacket *avpkt, double time_base)
pkt->d = QSharedDataPointer<PacketPrivate>(new PacketPrivate());
pkt->d->initialized = true;
AVPacket *p = &pkt->d->avpkt;

if(p) {
av_packet_unref(p);
}

av_packet_ref(p, (AVPacket*)avpkt); //properties are copied internally
// add ref without copy, bytearray does not copy either. bytearray options linke remove() is safe. omit FF_INPUT_BUFFER_PADDING_SIZE
pkt->data = QByteArray::fromRawData((const char*)p->data, p->size);
pkt->data = QByteArray((const char*)p->data, p->size);
// QtAV always use ms (1/1000s) and s. As a result no time_base is required in Packet
p->pts = pkt->pts * 1000.0;
p->dts = pkt->dts * 1000.0;
Expand Down Expand Up @@ -176,6 181,7 @@ Packet& Packet::operator =(const Packet& other)

Packet::~Packet()
{
data.clear();
}

const AVPacket *Packet::asAVPacket() const
Expand Down

0 comments on commit 158a023

Please sign in to comment.