QTfrontend/util/libav_iteraction.cpp
changeset 7280 fd707afbc3a2
parent 7235 baa69bd025d9
child 7353 0e55228e1303
equal deleted inserted replaced
7278:000e4543f204 7280:fd707afbc3a2
    22 #include "libavformat/avformat.h"
    22 #include "libavformat/avformat.h"
    23 }
    23 }
    24 #include <QVector>
    24 #include <QVector>
    25 #include <QList>
    25 #include <QList>
    26 #include <QMessageBox>
    26 #include <QMessageBox>
       
    27 #include <QComboBox>
    27 
    28 
    28 #include "libav_iteraction.h"
    29 #include "libav_iteraction.h"
    29 #include "HWApplication.h"
    30 #include "HWApplication.h"
    30 
    31 
    31 struct Codec
    32 struct Codec
    40 struct Format
    41 struct Format
    41 {
    42 {
    42     QString shortName;
    43     QString shortName;
    43     QString longName;
    44     QString longName;
    44     bool isRecomended;
    45     bool isRecomended;
    45   //  QString extension;
    46     QString extension;
    46     QVector<Codec*> codecs;
    47     QVector<Codec*> codecs;
    47 };
    48 };
    48 
    49 
    49 QList<Codec> codecs;
    50 QList<Codec> codecs;
    50 QMap<QString,Format> formats;
    51 QMap<QString,Format> formats;
    53 {
    54 {
    54     static LibavIteraction instance;
    55     static LibavIteraction instance;
    55     return instance;
    56     return instance;
    56 }
    57 }
    57 
    58 
       
    59 // test if given format supports given codec
    58 bool FormatQueryCodec(AVOutputFormat *ofmt, enum CodecID codec_id)
    60 bool FormatQueryCodec(AVOutputFormat *ofmt, enum CodecID codec_id)
    59 {  
    61 {  
    60 #if LIBAVFORMAT_VERSION_MAJOR >= 54
    62 #if LIBAVFORMAT_VERSION_MAJOR >= 54
    61     return avformat_query_codec(ofmt, codec_id, FF_COMPLIANCE_NORMAL) == 1;
    63     return avformat_query_codec(ofmt, codec_id, FF_COMPLIANCE_NORMAL) == 1;
    62 #else
    64 #else
    87 
    89 
    88         if (pCodec->type != AVMEDIA_TYPE_VIDEO && pCodec->type != AVMEDIA_TYPE_AUDIO)
    90         if (pCodec->type != AVMEDIA_TYPE_VIDEO && pCodec->type != AVMEDIA_TYPE_AUDIO)
    89             continue;
    91             continue;
    90 
    92 
    91         // this encoders seems to be buggy
    93         // this encoders seems to be buggy
    92         if (strcmp(pCodec->name, "rv10") == 0 ||
    94         if (strcmp(pCodec->name, "rv10") == 0 || strcmp(pCodec->name, "rv20") == 0)
    93             strcmp(pCodec->name, "rv20") == 0)
       
    94             continue;
    95             continue;
    95 
    96 
    96         // doesn't support stereo sound
    97         // doesn't support stereo sound
    97         if (strcmp(pCodec->name, "real_144") == 0)
    98         if (strcmp(pCodec->name, "real_144") == 0)
    98             continue;
    99             continue;
       
   100 
    99 #if LIBAVCODEC_VERSION_MAJOR < 54
   101 #if LIBAVCODEC_VERSION_MAJOR < 54
   100         // FIXME: theese doesn't work for some reason
   102         // FIXME: theese doesn't work for some reason
   101         if (strcmp(pCodec->name, "libx264") == 0)
   103         if (strcmp(pCodec->name, "libx264") == 0)
   102             continue;
   104             continue;
   103         if (strcmp(pCodec->name, "libxvid") == 0)
   105         if (strcmp(pCodec->name, "libxvid") == 0)
   192             if (!codec->isAudio)
   194             if (!codec->isAudio)
   193                 hasVideoCodec = true;
   195                 hasVideoCodec = true;
   194         }
   196         }
   195         if (!hasVideoCodec)
   197         if (!hasVideoCodec)
   196             continue;
   198             continue;
   197         format.shortName = pFormat->name;
       
   198 
   199 
   199         QString ext(pFormat->extensions);
   200         QString ext(pFormat->extensions);
   200         ext.truncate(strcspn(pFormat->extensions, ","));
   201         ext.truncate(strcspn(pFormat->extensions, ","));
       
   202         format.extension = ext;
       
   203         format.shortName = pFormat->name;
   201         format.longName = QString("%1 (*.%2)").arg(pFormat->long_name).arg(ext);
   204         format.longName = QString("%1 (*.%2)").arg(pFormat->long_name).arg(ext);
   202 
   205 
   203         // FIXME: remove next line
   206         // FIXME: remove next line
   204         format.longName += QString(" (%1)").arg(format.shortName);
   207         format.longName += QString(" (%1)").arg(format.shortName);
   205 
   208 
   207 
   210 
   208         formats[pFormat->name] = format;
   211         formats[pFormat->name] = format;
   209     }
   212     }
   210 }
   213 }
   211 
   214 
   212 void LibavIteraction::FillFormats(QComboBox * pFormats)
   215 void LibavIteraction::fillFormats(QComboBox * pFormats)
   213 {
   216 {
   214     // first insert recomended formats
   217     // first insert recomended formats
   215     foreach(const Format & format, formats)
   218     foreach(const Format & format, formats)
   216         if (format.isRecomended)
   219         if (format.isRecomended)
   217             pFormats->addItem(format.longName, format.shortName);
   220             pFormats->addItem(format.longName, format.shortName);
   227     // insert separator if necessary
   230     // insert separator if necessary
   228     if (sep != 0 && sep != pFormats->count())
   231     if (sep != 0 && sep != pFormats->count())
   229         pFormats->insertSeparator(sep);
   232         pFormats->insertSeparator(sep);
   230 }
   233 }
   231 
   234 
   232 void LibavIteraction::FillCodecs(const QVariant & fmt, QComboBox * pVCodecs, QComboBox * pACodecs)
   235 void LibavIteraction::fillCodecs(const QString & fmt, QComboBox * pVCodecs, QComboBox * pACodecs)
   233 {
   236 {
   234     Format & format = formats[fmt.toString()];
   237     Format & format = formats[fmt];
   235 
   238 
   236     // first insert recomended codecs
   239     // first insert recomended codecs
   237     foreach(Codec * codec, format.codecs)
   240     foreach(Codec * codec, format.codecs)
   238     {
   241     {
   239         if (codec->isRecomended)
   242         if (codec->isRecomended)
   265     if (vsep != 0 && vsep != pVCodecs->count())
   268     if (vsep != 0 && vsep != pVCodecs->count())
   266         pVCodecs->insertSeparator(vsep);
   269         pVCodecs->insertSeparator(vsep);
   267     if (asep != 0 && asep != pACodecs->count())
   270     if (asep != 0 && asep != pACodecs->count())
   268         pACodecs->insertSeparator(asep);
   271         pACodecs->insertSeparator(asep);
   269 }
   272 }
       
   273 
       
   274 QString LibavIteraction::getExtension(const QString & format)
       
   275 {
       
   276     return formats[format].extension;
       
   277 }
       
   278 
       
   279 QString tr(QString a)
       
   280 {
       
   281     return a;
       
   282 }
       
   283 
       
   284 // get information abaout file (duration, resolution etc) in multiline string
       
   285 QString LibavIteraction::getFileInfo(const QString & filepath)
       
   286 {
       
   287     AVFormatContext* pContext = NULL;
       
   288     QByteArray utf8path = filepath.toUtf8();
       
   289     if (avformat_open_input(&pContext, utf8path.data(), NULL, NULL) < 0)
       
   290         return "";
       
   291     if (avformat_find_stream_info(pContext, NULL) < 0)
       
   292         return "";
       
   293 
       
   294     int s = float(pContext->duration)/AV_TIME_BASE;
       
   295     QString desc = QString(tr("Duration: %1m %2s\n")).arg(s/60).arg(s%60);
       
   296     for (int i = 0; i < pContext->nb_streams; i++)
       
   297     {
       
   298         AVStream* pStream = pContext->streams[i];
       
   299         if (!pStream)
       
   300             continue;
       
   301         AVCodecContext* pCodec = pContext->streams[i]->codec;
       
   302         if (!pCodec)
       
   303             continue;
       
   304 
       
   305         if (pCodec->codec_type == AVMEDIA_TYPE_VIDEO)
       
   306         {
       
   307             desc += QString(tr("Video: %1x%2, ")).arg(pCodec->width).arg(pCodec->height);
       
   308             if (pStream->avg_frame_rate.den)
       
   309             {
       
   310                 float fps = float(pStream->avg_frame_rate.num)/pStream->avg_frame_rate.den;
       
   311                 desc += QString(tr("%1 fps, ")).arg(fps, 0, 'f', 2);
       
   312             }
       
   313         }
       
   314         else if (pCodec->codec_type == AVMEDIA_TYPE_AUDIO)
       
   315             desc += tr("Audio: ");
       
   316         else
       
   317             continue;
       
   318         AVCodec* pDecoder = avcodec_find_decoder(pCodec->codec_id);
       
   319         desc += pDecoder? pDecoder->name : "unknown";
       
   320         desc += "\n";
       
   321     }
       
   322     AVDictionaryEntry* pComment = av_dict_get(pContext->metadata, "comment", NULL, 0);
       
   323     if (pComment)
       
   324         desc += QString("\n") + pComment->value;
       
   325 #if LIBAVCODEC_VERSION_MAJOR < 54
       
   326     av_close_input_file(pContext);
       
   327 #else
       
   328     avformat_close_input(&pContext);
       
   329 #endif
       
   330     return desc;
       
   331 }