Skip to content

Commit c0a03da

Browse files
committed
Support piped input with QtAVPlayer
Signed-off-by: Maxime Gervais <[email protected]>
1 parent 28dbe85 commit c0a03da

File tree

8 files changed

+76
-106
lines changed

8 files changed

+76
-106
lines changed

Source/Core/AudioStreamStats.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,13 @@ AudioStreamStats::AudioStreamStats(XMLElement *streamElement) : CommonStreamStat
5959
bits_per_sample = std::stoi(bits_per_sample_value);
6060
}
6161

62-
AudioStreamStats::AudioStreamStats(QAVStream* stream, AVFormatContext *context) : CommonStreamStats(stream),
62+
AudioStreamStats::AudioStreamStats(QAVStream* stream) : CommonStreamStats(stream),
6363
sample_fmt_string(""),
6464
sample_rate(stream != NULL ? stream->stream()->codecpar->sample_rate : 0),
6565
channels(stream != NULL ? stream->stream()->codecpar->channels : 0),
6666
channel_layout(""),
6767
bits_per_sample(stream != NULL ? av_get_bits_per_sample(stream->stream()->codecpar->codec_id) : 0)
6868
{
69-
Q_UNUSED(context);
70-
7169
codec_type = "audio";
7270
stream_type = AVMEDIA_TYPE_AUDIO;
7371

Source/Core/AudioStreamStats.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class AudioStreamStats : public CommonStreamStats
2222
{
2323
public:
2424
AudioStreamStats(tinyxml2::XMLElement* streamElement);
25-
AudioStreamStats(QAVStream* stream, AVFormatContext *context);
25+
AudioStreamStats(QAVStream* stream);
2626

2727
virtual void writeStreamInfoToXML(QXmlStreamWriter* writer);
2828

Source/Core/CommonStreamStats.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ namespace tinyxml2 {
1717
class XMLElement;
1818
}
1919

20-
struct AVFormatContext;
2120
class QAVStream;
2221
struct AVCodec;
2322

Source/Core/FileInformation.cpp

Lines changed: 58 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -878,92 +878,70 @@ FileInformation::FileInformation (SignalServer* signalServer, const QString &Fil
878878
qDebug() << "m_mediaParser->currentVideoStreams(): " << m_mediaParser->currentVideoStreams().size();
879879
qDebug() << "m_mediaParser->currentAudioStreams(): " << m_mediaParser->currentAudioStreams().size();
880880

881-
auto streams = m_mediaParser->availableVideoStreams();
882-
streams.append(m_mediaParser->availableAudioStreams());
883-
884-
AVFormatContext* FormatContext = nullptr;
885-
auto stdMediaFileName = mediaOrMkvReportFileName.toStdString();
886-
AVDictionary* options = nullptr;
887-
if (dpxOffset != -1) {
888-
auto dpxOffsetString = std::to_string(dpxOffset);
889-
av_dict_set(&options, "f", "image2", 0);
890-
av_dict_set(&options, "start_number", dpxOffsetString.c_str(), 0);
891-
}
892-
if (avformat_open_input(&FormatContext, stdMediaFileName.c_str(), nullptr, &options)>=0)
893-
{
894-
QVector<QAVStream*> orderedStreams;
895-
if (avformat_find_stream_info(FormatContext, NULL)>=0) {
896-
897-
containerFormat = FormatContext->iformat->long_name;
898-
streamCount = FormatContext->nb_streams;
899-
bitRate = FormatContext->bit_rate;
900-
901-
size_t VideoPos=0;
902-
size_t AudioPos=0;
903-
904-
for(auto i = 0; i < FormatContext->nb_streams; ++i) {
905-
auto codec_type = FormatContext->streams[i]->codecpar->codec_type;
906-
if(codec_type != AVMEDIA_TYPE_VIDEO && codec_type != AVMEDIA_TYPE_AUDIO)
907-
continue;
908-
909-
auto streamIt = std::find_if(streams.begin(), streams.end(), [i](QAVStream& stream) {
910-
return stream.stream()->index == i;
911-
});
912-
913-
if(streamIt == streams.end()) {
914-
qDebug() << "error: it should never happen";
915-
assert(false);
916-
continue;
917-
}
881+
QVector<QAVStream> streams;
882+
streams.append(m_mediaParser->currentVideoStreams());
883+
streams.append(m_mediaParser->currentAudioStreams());
884+
885+
QVector<QAVStream*> orderedStreams;
886+
for (int i = 0; i < streams.size(); ++i) {
887+
if(streams[i].codec()->codec() == nullptr) {
888+
qDebug() << "error: codec is null for stream" << streams[i].stream()->index << "... skipping";
889+
continue;
890+
}
918891

919-
if(streamIt->codec()->codec() == nullptr) {
920-
qDebug() << "error: codec is null for stream" << i << "... skipping";
921-
continue;
922-
}
923-
orderedStreams.append(&*streamIt);
924-
925-
auto Duration = 0;
926-
auto FrameCount = streamIt->stream()->nb_frames;
927-
if (streamIt->stream()->duration != AV_NOPTS_VALUE)
928-
Duration= ((double)streamIt->stream()->duration)*streamIt->stream()->time_base.num/streamIt->stream()->time_base.den;
929-
930-
// If duration is not known, estimating it
931-
if (Duration==0 && FormatContext->duration!=AV_NOPTS_VALUE)
932-
Duration=((double)FormatContext->duration)/AV_TIME_BASE;
933-
934-
// If frame count is not known, estimating it
935-
if (FrameCount==0 && streamIt->stream()->avg_frame_rate.num && streamIt->stream()->avg_frame_rate.den && Duration)
936-
FrameCount=Duration*streamIt->stream()->avg_frame_rate.num/streamIt->stream()->avg_frame_rate.den;
937-
if (FrameCount==0
938-
&& ((streamIt->stream()->time_base.num==1 && streamIt->stream()->time_base.den>=24 && streamIt->stream()->time_base.den<=60)
939-
|| (streamIt->stream()->time_base.num==1001 && streamIt->stream()->time_base.den>=24000 && streamIt->stream()->time_base.den<=60000)))
940-
FrameCount=streamIt->stream()->duration;
941-
942-
CommonStats* Stat = nullptr;
943-
944-
if(streamIt->stream()->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
945-
if (!VideoPos || ActiveAllTracks[Type_Video])
946-
Stat = new VideoStats(FrameCount, Duration, &*streamIt);
947-
++VideoPos;
948-
} else if(streamIt->stream()->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
949-
if (!AudioPos || ActiveAllTracks[Type_Audio])
950-
Stat = new AudioStats(FrameCount, Duration, &*streamIt);
951-
++AudioPos;
952-
}
892+
auto codec_type = streams[i].stream()->codecpar->codec_type;
893+
if(codec_type != AVMEDIA_TYPE_VIDEO && codec_type != AVMEDIA_TYPE_AUDIO)
894+
continue;
953895

954-
if (Stat)
955-
Stats.push_back(Stat);
956-
}
896+
orderedStreams.append(&streams[i]);
897+
}
898+
std::sort(orderedStreams.begin(), orderedStreams.end(), [](QAVStream* a, QAVStream* b) {
899+
return a->stream()->index < b->stream()->index;
900+
});
957901

958-
streamsStats = new StreamsStats(orderedStreams, FormatContext);
959-
formatStats = new FormatStats(FormatContext);
902+
containerFormat = m_mediaParser->avctx()->iformat->long_name;
903+
streamCount = m_mediaParser->avctx()->nb_streams;
904+
bitRate = m_mediaParser->avctx()->bit_rate;
905+
906+
size_t VideoPos=0;
907+
size_t AudioPos=0;
908+
909+
for( auto streamIt = orderedStreams.begin(); streamIt != orderedStreams.end(); ++streamIt) {
910+
auto Duration = 0;
911+
auto FrameCount = (*streamIt)->stream()->nb_frames;
912+
if ((*streamIt)->stream()->duration != AV_NOPTS_VALUE)
913+
Duration= ((double)(*streamIt)->stream()->duration)*(*streamIt)->stream()->time_base.num/(*streamIt)->stream()->time_base.den;
914+
915+
// If duration is not known, estimating it
916+
if (Duration==0 && m_mediaParser->avctx()->duration!=AV_NOPTS_VALUE)
917+
Duration=((double) m_mediaParser->avctx()->duration)/AV_TIME_BASE;
918+
919+
// If frame count is not known, estimating it
920+
if (FrameCount==0 && (*streamIt)->stream()->avg_frame_rate.num && (*streamIt)->stream()->avg_frame_rate.den && Duration)
921+
FrameCount=Duration*(*streamIt)->stream()->avg_frame_rate.num/(*streamIt)->stream()->avg_frame_rate.den;
922+
if (FrameCount==0
923+
&& (((*streamIt)->stream()->time_base.num==1 && (*streamIt)->stream()->time_base.den>=24 && (*streamIt)->stream()->time_base.den<=60)
924+
|| ((*streamIt)->stream()->time_base.num==1001 && (*streamIt)->stream()->time_base.den>=24000 && (*streamIt)->stream()->time_base.den<=60000)))
925+
FrameCount=(*streamIt)->stream()->duration;
926+
927+
CommonStats* Stat = nullptr;
928+
929+
if((*streamIt)->stream()->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
930+
if (!VideoPos || ActiveAllTracks[Type_Video])
931+
Stat = new VideoStats(FrameCount, Duration, *streamIt);
932+
++VideoPos;
933+
} else if((*streamIt)->stream()->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
934+
if (!AudioPos || ActiveAllTracks[Type_Audio])
935+
Stat = new AudioStats(FrameCount, Duration, *streamIt);
936+
++AudioPos;
960937
}
961938

962-
avformat_close_input(&FormatContext);
963-
}
964-
if (options) {
965-
av_dict_free(&options);
939+
if (Stat)
940+
Stats.push_back(Stat);
966941
}
942+
943+
streamsStats = new StreamsStats(orderedStreams);
944+
formatStats = new FormatStats(m_mediaParser->avctx());
967945
}
968946

969947
if(attachment.isEmpty()) {

Source/Core/StreamsStats.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,21 @@ extern "C"
2626

2727
using namespace tinyxml2;
2828

29-
StreamsStats::StreamsStats(QVector<QAVStream*> qavstreams, AVFormatContext *context)
29+
StreamsStats::StreamsStats(QVector<QAVStream*> qavstreams)
3030
{
31-
if(context != NULL)
31+
for (size_t pos = 0; pos < qavstreams.count(); ++pos)
3232
{
33-
for (size_t pos = 0; pos < qavstreams.count(); ++pos)
33+
auto qavstream = qavstreams[pos];
34+
switch (qavstream->stream()->codecpar->codec_type)
3435
{
35-
auto qavstream = qavstreams[pos];
36-
switch (qavstream->stream()->codecpar->codec_type)
37-
{
38-
case AVMEDIA_TYPE_VIDEO:
39-
streams.push_back(std::unique_ptr<VideoStreamStats>(new VideoStreamStats(qavstream, context)));
40-
break;
41-
case AVMEDIA_TYPE_AUDIO:
42-
streams.push_back(std::unique_ptr<AudioStreamStats>(new AudioStreamStats(qavstream, context)));
43-
break;
44-
default:
45-
qDebug() << "only Audio / Video streams are supported for now.. skipping stream of index = " << pos << " and of type = " << context->streams[pos]->codecpar->codec_type;
46-
}
36+
case AVMEDIA_TYPE_VIDEO:
37+
streams.push_back(std::unique_ptr<VideoStreamStats>(new VideoStreamStats(qavstream)));
38+
break;
39+
case AVMEDIA_TYPE_AUDIO:
40+
streams.push_back(std::unique_ptr<AudioStreamStats>(new AudioStreamStats(qavstream)));
41+
break;
42+
default:
43+
qDebug() << "only Audio / Video streams are supported for now.. skipping stream of index = " << pos << " and of type = " << qavstream->stream()->codecpar->codec_type;
4744
}
4845
}
4946
}

Source/Core/StreamsStats.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
#include "Core/CommonStreamStats.h"
1818

19-
struct AVFormatContext;
2019
class QXmlStreamWriter;
2120
class CommonStreamStats;
2221
class QAVStream;
@@ -25,7 +24,7 @@ class StreamsStats {
2524
public:
2625
typedef std::unique_ptr<CommonStreamStats> CommonStreamStatsPtr;
2726

28-
StreamsStats(QVector<QAVStream*> streams = {}, AVFormatContext* context = NULL);
27+
StreamsStats(QVector<QAVStream*> streams = {});
2928
~StreamsStats();
3029

3130
bool readFromXML(const char* data, size_t size);

Source/Core/VideoStreamStats.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ VideoStreamStats::VideoStreamStats(XMLElement *streamElement) : CommonStreamStat
9999
refs = refs_value;
100100
}
101101

102-
VideoStreamStats::VideoStreamStats(QAVStream* stream, AVFormatContext *context) : CommonStreamStats(stream),
102+
VideoStreamStats::VideoStreamStats(QAVStream* stream) : CommonStreamStats(stream),
103103
width(stream != NULL ? std::to_string(stream->stream()->codecpar->width) : ""),
104104
height(stream != NULL ? std::to_string(stream->stream()->codecpar->height) : ""),
105105
coded_width(stream != NULL ? std::to_string(stream->codec()->avctx()->coded_width) : ""),
@@ -114,13 +114,12 @@ VideoStreamStats::VideoStreamStats(QAVStream* stream, AVFormatContext *context)
114114
{
115115
if(stream != NULL)
116116
{
117-
AVRational sar = av_guess_sample_aspect_ratio(context, stream->stream(), NULL);
117+
AVRational sar = av_guess_sample_aspect_ratio(NULL, stream->stream(), NULL); // context is unused and can be null in current ffmpeg code
118118
sample_aspect_ratio = rational_to_string(sar, ':');
119119

120120
if(stream->codec()->avctx()->sample_aspect_ratio.den)
121121
{
122122
AVRational dar;
123-
124123
av_reduce(&dar.num, &dar.den,
125124
stream->stream()->codecpar->width * sar.num,
126125
stream->stream()->codecpar->height * sar.den,

Source/Core/VideoStreamStats.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class VideoStreamStats : public CommonStreamStats
1818
{
1919
public:
2020
VideoStreamStats(tinyxml2::XMLElement* streamElement);
21-
VideoStreamStats(QAVStream* stream, AVFormatContext *context);
21+
VideoStreamStats(QAVStream* stream);
2222

2323
virtual void writeStreamInfoToXML(QXmlStreamWriter* writer);
2424

0 commit comments

Comments
 (0)