Skip to content

Commit

Permalink
decode() use Packet as parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
wang-bin committed Dec 16, 2014
1 parent 941a499 commit 46f8861
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 65 deletions.
47 changes: 1 addition & 46 deletions src/AVDemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,52 +318,7 @@ bool AVDemuxer::readFrame()
//qWarning("[AVDemuxer] unknown stream index: %d", stream_idx);
return false;
}
m_pkt.hasKeyFrame = !!(packet.flags & AV_PKT_FLAG_KEY);
// what about marking packet as invalid and do not use isCorrupt?
m_pkt.isCorrupt = !!(packet.flags & AV_PKT_FLAG_CORRUPT);
#if NO_PADDING_DATA
m_pkt.data.clear();
if (packet.data)
m_pkt.data = QByteArray((const char*)packet.data, packet.size);
#else
/*!
larger than the actual read bytes because some optimized bitstream readers read 32 or 64 bits at once and could read over the end.
The end of the input buffer avpkt->data should be set to 0 to ensure that no overreading happens for damaged MPEG streams
*/
QByteArray encoded;
if (packet.data) {
encoded.reserve(packet.size + FF_INPUT_BUFFER_PADDING_SIZE);
encoded.resize(packet.size);
// also copy padding data(usually 0)
memcpy(encoded.data(), packet.data, encoded.capacity()); // encoded.capacity() is always > 0 even if packet.data, so must check packet.data null
}
m_pkt.data = encoded;
#endif //NO_PADDING_DATA
m_pkt.duration = packet.duration;
//if (packet.dts == AV_NOPTS_VALUE && )
if (packet.dts != AV_NOPTS_VALUE) //has B-frames
m_pkt.pts = packet.dts;
else if (packet.pts != AV_NOPTS_VALUE)
m_pkt.pts = packet.pts;
else
m_pkt.pts = 0;
AVStream *stream = format_context->streams[stream_idx];
m_pkt.pts *= av_q2d(stream->time_base);
//TODO: pts must >= 0? look at ffplay
m_pkt.pts = qMax<qreal>(0, m_pkt.pts);
// TODO: convergence_duration
// subtitle is always key frame? convergence_duration may be 0
if (stream->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
&& (packet.flags & AV_PKT_FLAG_KEY)
&& packet.convergence_duration > 0 && packet.convergence_duration != AV_NOPTS_VALUE) { //??
m_pkt.duration = packet.convergence_duration * av_q2d(stream->time_base);
} else if (packet.duration > 0)
m_pkt.duration = packet.duration * av_q2d(stream->time_base);
else
m_pkt.duration = 0;
//qDebug("AVPacket.pts=%f, duration=%f, dts=%lld", m_pkt.pts, m_pkt.duration, packet.dts);
if (m_pkt.isCorrupt)
qDebug("currupt packet. pts: %f", m_pkt.pts);
m_pkt = Packet::fromAVPacket(&packet, av_q2d(format_context->streams[stream_idx]->time_base));
av_free_packet(&packet); //important!
return true;
}
Expand Down
21 changes: 11 additions & 10 deletions src/AudioThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ void AudioThread::run()
dec->flush();
continue;
}
qreal dts = pkt.dts; //FIXME: pts and dts
bool skip_render = pkt.pts < d.render_pts0;
// audio has no key frame, skip rendering equals to skip decoding
if (skip_render) {
Expand All @@ -106,8 +107,8 @@ void AudioThread::run()
* audio may be too fast than video if skip without sleep
* a frame is about 20ms. sleep time must be << frame time
*/
qreal a_v = pkt.pts - d.clock->videoPts();
//qDebug("skip audio decode at %f/%f v=%f a-v=%fms", pkt.pts, d.render_pts0, d.clock->videoPts(), a_v*1000.0);
qreal a_v = dts - d.clock->videoPts();
//qDebug("skip audio decode at %f/%f v=%f a-v=%fms", dts, d.render_pts0, d.clock->videoPts(), a_v*1000.0);
if (a_v > 0) {
msleep(qMin((ulong)20, ulong(a_v*1000.0)));
} else {
Expand All @@ -119,7 +120,7 @@ void AudioThread::run()
}
d.render_pts0 = 0;
if (is_external_clock) {
d.delay = pkt.pts - d.clock->value();
d.delay = dts - d.clock->value();
/*
*after seeking forward, a packet may be the old, v packet may be
*the new packet, then the d.delay is very large, omit it.
Expand Down Expand Up @@ -190,15 +191,15 @@ void AudioThread::run()
}
QMutexLocker locker(&d.mutex);
Q_UNUSED(locker);
if (!dec->decode(pkt.data)) {
qWarning("Decode audio failed");
qreal dt = pkt.pts - d.last_pts;
if (dt > 0.618 || dt < 0) {
if (!dec->decode(pkt)) {
qWarning("Decode audio failed. undecoded: %d", dec->undecodedSize());
qreal dt = dts - d.last_pts;
if (dt > 0.5 || dt < 0) {
dt = 0;
}
//qDebug("a sleep %f", dt);
//TODO: avoid acummulative error. External clock?
msleep((unsigned long)(dt*1000.0));
if (!qFuzzyIsNull(dt)) {
msleep((unsigned long)(dt*1000.0));
}
pkt = Packet();
d.last_pts = d.clock->value(); //not pkt.pts! the delay is updated!
continue;
Expand Down
2 changes: 2 additions & 0 deletions src/Packet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ bool Packet::fromAVPacket(Packet* pkt, const AVPacket *avpkt, double time_base)
if (pkt->isCorrupt)
qDebug("currupt packet. pts: %f", pkt->pts);

// old code set pts as dts is valid
if (avpkt->pts != AV_NOPTS_VALUE)
pkt->pts = avpkt->pts * time_base;
else if (avpkt->dts != AV_NOPTS_VALUE) // is it ok?
Expand All @@ -74,6 +75,7 @@ bool Packet::fromAVPacket(Packet* pkt, const AVPacket *avpkt, double time_base)
pkt->dts = avpkt->dts * time_base;
else
pkt->dts = pkt->pts;
//qDebug("pts %lld, dts: %lld ", avpkt->pts, avpkt->dts);
//TODO: pts must >= 0? look at ffplay
pkt->pts = qMax<qreal>(0, pkt->pts);
pkt->dts = qMax<qreal>(0, pkt->dts);
Expand Down
8 changes: 6 additions & 2 deletions src/VideoFrameExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ class VideoFrameExtractorPrivate : public DPtrPrivate<VideoFrameExtractor>
int k = 0;
while (k < 5 && !frame.isValid()) {
//qWarning("invalid key frame!!!!! undecoded: %d", decoder->undecodedSize());
if (!decoder->decode(pkt.data)) {
if (!decoder->decode(pkt)) {
//qWarning("!!!!!!!!!decode key failed!!!!!!!!");
return false;
}
Expand Down Expand Up @@ -244,6 +244,10 @@ class VideoFrameExtractorPrivate : public DPtrPrivate<VideoFrameExtractor>
//qWarning("out of range");
return frame.isValid();
}
if (!pkt.isValid()) {
qWarning("invalid packet. no decode");
continue;
}
if (pkt.hasKeyFrame) {
// FIXME:
//qCritical("Internal error. Can not be a key frame!!!!");
Expand All @@ -257,7 +261,7 @@ class VideoFrameExtractorPrivate : public DPtrPrivate<VideoFrameExtractor>
if (dec_opt != dec_opt_old)
decoder->setOptions(*dec_opt);
// invalid packet?
if (!decoder->decode(pkt.data)) {
if (!decoder->decode(pkt)) {
//qWarning("!!!!!!!!!decode failed!!!!");
return false;
}
Expand Down
8 changes: 4 additions & 4 deletions src/VideoThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ void VideoThread::run()
dec->flush();
continue;
}
qreal pts = pkt.pts;
const qreal pts = pkt.dts; //FIXME: pts and dts
// TODO: delta ref time
qreal diff = pts - d.clock->value();
if (diff > kSyncThreshold) {
Expand Down Expand Up @@ -444,7 +444,7 @@ void VideoThread::run()
}
if (dec_opt != dec_opt_old)
dec->setOptions(*dec_opt);
if (!dec->decode(pkt.data)) {
if (!dec->decode(pkt)) {
pkt = Packet();
continue;
} else {
Expand Down Expand Up @@ -482,11 +482,11 @@ void VideoThread::run()
seek_count = 1;
else if (seek_count > 0)
seek_count++;
frame.setTimestamp(pts); // TODO: pts is wrong
frame.setTimestamp(pkt.pts); // TODO: pts is wrong
frame.setImageConverter(d.conv);
Q_ASSERT(d.statistics);
d.statistics->video.current_time = QTime(0, 0, 0).addMSecs(int(pts * 1000.0)); //TODO: is it expensive?
applyFilters(frame, pts);
applyFilters(frame, pkt.pts);

//while can pause, processNextTask, not call outset.puase which is deperecated
while (d.outputSet->canPauseThread()) {
Expand Down
2 changes: 1 addition & 1 deletion src/codec/video/VideoDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ VideoFrame VideoDecoder::frame()
frame.setDisplayAspectRatio(displayAspectRatio);
frame.setBits(d.frame->data);
frame.setBytesPerLine(d.frame->linesize);
frame.setTimestamp((double)d.frame->pts/1000.0); // in s
frame.setTimestamp((double)d.frame->pkt_pts/1000.0); // in s
return frame;
}

Expand Down
5 changes: 3 additions & 2 deletions tests/decoder/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,18 @@ int main(int argc, char *argv[])
if (demux.stream() != vstream)
continue;
const Packet pkt = demux.packet();
if (dec->decode(pkt.data)) {
if (dec->decode(pkt)) {
/*
* TODO: may contains more than 1 frames
* map from gpu or not?
*/
//frame = dec->frame().clone();
count++;
printf("decode count: %d\r", count);fflush(0);
}
}
qint64 elapsed = timer.elapsed();
int msec = elapsed/1000LL;
int msec = elapsed/1000LL+1;
qDebug("decoded frames: %d, time: %d, average speed: %d", count, msec, count/msec);
return 0;
}

0 comments on commit 46f8861

Please sign in to comment.