QTfrontend/util/LibavInteraction.cpp
author koda
Sat, 09 Mar 2013 00:57:09 +0100
changeset 8702 a28966180a29
parent 8362 89a6b7cc6f95
child 9080 9b42757d7e71
permissions -rw-r--r--
have fpc work in the right directory instead of passing the full path of the main module (avoids having full paths in debug build backtraces for the first module only)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     1
/*
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     2
 * Hedgewars, a free turn based strategy game
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     3
 * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     4
 *
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     5
 * This program is free software; you can redistribute it and/or modify
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     6
 * it under the terms of the GNU General Public License as published by
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     7
 * the Free Software Foundation; version 2 of the License
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     8
 *
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
     9
 * This program is distributed in the hope that it will be useful,
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    12
 * GNU General Public License for more details.
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    13
 *
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    14
 * You should have received a copy of the GNU General Public License
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    15
 * along with this program; if not, write to the Free Software
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    17
 */
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    18
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    19
#include "LibavInteraction.h"
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    20
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    21
#if VIDEOREC
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    22
extern "C"
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    23
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    24
#include "libavformat/avformat.h"
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    25
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    26
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    27
#include <QVector>
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    28
#include <QList>
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    29
#include <QComboBox>
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    30
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    31
#include "HWApplication.h"
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    32
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    33
struct Codec
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    34
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    35
    CodecID id;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    36
    bool isAudio;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    37
    QString shortName; // used for identification
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    38
    QString longName; // used for displaying to user
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    39
    bool isRecomended;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    40
};
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    41
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    42
struct Format
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    43
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    44
    QString shortName;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    45
    QString longName;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    46
    bool isRecomended;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    47
    QString extension;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    48
    QVector<Codec*> codecs;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    49
};
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    50
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    51
QList<Codec> codecs;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    52
QMap<QString,Format> formats;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    53
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    54
// test if given format supports given codec
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    55
bool FormatQueryCodec(AVOutputFormat *ofmt, enum CodecID codec_id)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    56
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    57
#if LIBAVFORMAT_VERSION_MAJOR >= 54
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    58
    return avformat_query_codec(ofmt, codec_id, FF_COMPLIANCE_NORMAL) == 1;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    59
#else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    60
    if (ofmt->codec_tag)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    61
        return !!av_codec_get_tag(ofmt->codec_tag, codec_id);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    62
    return codec_id == ofmt->video_codec || codec_id == ofmt->audio_codec;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    63
#endif
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    64
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    65
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    66
LibavInteraction::LibavInteraction() : QObject()
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    67
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    68
    // initialize libav and register all codecs and formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    69
    av_register_all();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    70
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    71
    // get list of all codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    72
    AVCodec* pCodec = NULL;
8065
609d07b337b5 fix deprecation warnings for libav sources
koda
parents: 7897
diff changeset
    73
    while ((pCodec = av_codec_next(pCodec)))
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    74
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    75
#if LIBAVCODEC_VERSION_MAJOR >= 54
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    76
        if (!av_codec_is_encoder(pCodec))
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    77
#else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    78
        if (!pCodec->encode)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    79
#endif
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    80
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    81
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    82
        if (pCodec->type != AVMEDIA_TYPE_VIDEO && pCodec->type != AVMEDIA_TYPE_AUDIO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    83
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    84
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    85
        // this encoders seems to be buggy
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    86
        if (strcmp(pCodec->name, "rv10") == 0 || strcmp(pCodec->name, "rv20") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    87
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    88
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    89
        // doesn't support stereo sound
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    90
        if (strcmp(pCodec->name, "real_144") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    91
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    92
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    93
        if (!pCodec->long_name || strlen(pCodec->long_name) == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    94
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    95
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    96
        if (pCodec->type == AVMEDIA_TYPE_VIDEO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    97
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    98
            if (pCodec->supported_framerates != NULL)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    99
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   100
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   101
            // check if codec supports yuv 4:2:0 format
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   102
            if (!pCodec->pix_fmts)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   103
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   104
            bool yuv420Supported = false;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   105
            for (const PixelFormat* pfmt = pCodec->pix_fmts; *pfmt != -1; pfmt++)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   106
                if (*pfmt == PIX_FMT_YUV420P)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   107
                {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   108
                    yuv420Supported = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   109
                    break;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   110
                }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   111
            if (!yuv420Supported)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   112
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   113
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   114
        if (pCodec->type == AVMEDIA_TYPE_AUDIO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   115
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   116
            // check if codec supports signed 16-bit format
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   117
            if (!pCodec->sample_fmts)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   118
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   119
            bool s16Supported = false;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   120
            for (const AVSampleFormat* pfmt = pCodec->sample_fmts; *pfmt != -1; pfmt++)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   121
                if (*pfmt == AV_SAMPLE_FMT_S16)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   122
                {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   123
                    s16Supported = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   124
                    break;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   125
                }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   126
            if (!s16Supported)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   127
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   128
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   129
        // add codec to list of codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   130
        codecs.push_back(Codec());
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   131
        Codec & codec = codecs.back();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   132
        codec.id = pCodec->id;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   133
        codec.isAudio = pCodec->type == AVMEDIA_TYPE_AUDIO;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   134
        codec.shortName = pCodec->name;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   135
        codec.longName = pCodec->long_name;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   136
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   137
        codec.isRecomended = false;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   138
        if (strcmp(pCodec->name, "libx264") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   139
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   140
            codec.longName = "H.264/MPEG-4 Part 10 AVC (x264)";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   141
            codec.isRecomended = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   142
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   143
        else if (strcmp(pCodec->name, "libxvid") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   144
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   145
            codec.longName = "MPEG-4 Part 2 (Xvid)";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   146
            codec.isRecomended = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   147
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   148
        else if (strcmp(pCodec->name, "libmp3lame") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   149
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   150
            codec.longName = "MP3 (MPEG audio layer 3) (LAME)";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   151
            codec.isRecomended = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   152
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   153
        else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   154
            codec.longName = pCodec->long_name;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   155
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   156
        if (strcmp(pCodec->name, "mpeg4") == 0 || strcmp(pCodec->name, "ac3_fixed") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   157
            codec.isRecomended = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   158
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   159
        // FIXME: remove next line
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   160
        //codec.longName += QString(" (%1)").arg(codec.shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   161
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   162
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   163
    // get list of all formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   164
    AVOutputFormat* pFormat = NULL;
8065
609d07b337b5 fix deprecation warnings for libav sources
koda
parents: 7897
diff changeset
   165
    while ((pFormat = av_oformat_next(pFormat)))
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   166
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   167
        if (!pFormat->extensions)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   168
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   169
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   170
        // skip some strange formats to not confuse users
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   171
        if (strstr(pFormat->long_name, "raw"))
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   172
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   173
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   174
        Format format;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   175
        bool hasVideoCodec = false;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   176
        for (QList<Codec>::iterator codec = codecs.begin(); codec != codecs.end(); ++codec)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   177
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   178
            if (!FormatQueryCodec(pFormat, codec->id))
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   179
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   180
            format.codecs.push_back(&*codec);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   181
            if (!codec->isAudio)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   182
                hasVideoCodec = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   183
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   184
        if (!hasVideoCodec)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   185
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   186
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   187
        QString ext(pFormat->extensions);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   188
        ext.truncate(strcspn(pFormat->extensions, ","));
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   189
        format.extension = ext;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   190
        format.shortName = pFormat->name;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   191
        format.longName = QString("%1 (*.%2)").arg(pFormat->long_name).arg(ext);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   192
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   193
        // FIXME: remove next line
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   194
        //format.longName += QString(" (%1)").arg(format.shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   195
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   196
        format.isRecomended = strcmp(pFormat->name, "mp4") == 0 || strcmp(pFormat->name, "avi") == 0;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   197
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   198
        formats[pFormat->name] = format;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   199
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   200
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   201
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   202
void LibavInteraction::fillFormats(QComboBox * pFormats)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   203
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   204
    // first insert recomended formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   205
    foreach(const Format & format, formats)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   206
        if (format.isRecomended)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   207
            pFormats->addItem(format.longName, format.shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   208
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   209
    // remember where to place separator between recomended and other formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   210
    int sep = pFormats->count();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   211
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   212
    // insert remaining formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   213
    foreach(const Format & format, formats)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   214
        if (!format.isRecomended)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   215
            pFormats->addItem(format.longName, format.shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   216
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   217
    // insert separator if necessary
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   218
    if (sep != 0 && sep != pFormats->count())
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   219
        pFormats->insertSeparator(sep);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   220
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   221
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   222
void LibavInteraction::fillCodecs(const QString & fmt, QComboBox * pVCodecs, QComboBox * pACodecs)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   223
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   224
    Format & format = formats[fmt];
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   225
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   226
    // first insert recomended codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   227
    foreach(Codec * codec, format.codecs)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   228
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   229
        if (codec->isRecomended)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   230
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   231
            if (codec->isAudio)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   232
                pACodecs->addItem(codec->longName, codec->shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   233
            else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   234
                pVCodecs->addItem(codec->longName, codec->shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   235
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   236
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   237
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   238
    // remember where to place separators between recomended and other codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   239
    int vsep = pVCodecs->count();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   240
    int asep = pACodecs->count();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   241
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   242
    // insert remaining codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   243
    foreach(Codec * codec, format.codecs)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   244
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   245
        if (!codec->isRecomended)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   246
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   247
            if (codec->isAudio)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   248
                pACodecs->addItem(codec->longName, codec->shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   249
            else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   250
                pVCodecs->addItem(codec->longName, codec->shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   251
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   252
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   253
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   254
    // insert separators if necessary
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   255
    if (vsep != 0 && vsep != pVCodecs->count())
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   256
        pVCodecs->insertSeparator(vsep);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   257
    if (asep != 0 && asep != pACodecs->count())
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   258
        pACodecs->insertSeparator(asep);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   259
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   260
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   261
QString LibavInteraction::getExtension(const QString & format)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   262
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   263
    return formats[format].extension;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   264
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   265
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   266
// get information abaout file (duration, resolution etc) in multiline string
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   267
QString LibavInteraction::getFileInfo(const QString & filepath)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   268
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   269
    AVFormatContext* pContext = NULL;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   270
    QByteArray utf8path = filepath.toUtf8();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   271
    if (avformat_open_input(&pContext, utf8path.data(), NULL, NULL) < 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   272
        return "";
8065
609d07b337b5 fix deprecation warnings for libav sources
koda
parents: 7897
diff changeset
   273
#if LIBAVFORMAT_VERSION_MAJOR < 53
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   274
    if (av_find_stream_info(pContext) < 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   275
#else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   276
    if (avformat_find_stream_info(pContext, NULL) < 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   277
#endif
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   278
        return "";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   279
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   280
    int s = float(pContext->duration)/AV_TIME_BASE;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   281
    QString desc = QString(tr("Duration: %1m %2s\n")).arg(s/60).arg(s%60);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   282
    for (int i = 0; i < (int)pContext->nb_streams; i++)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   283
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   284
        AVStream* pStream = pContext->streams[i];
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   285
        if (!pStream)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   286
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   287
        AVCodecContext* pCodec = pContext->streams[i]->codec;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   288
        if (!pCodec)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   289
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   290
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   291
        if (pCodec->codec_type == AVMEDIA_TYPE_VIDEO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   292
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   293
            desc += QString(tr("Video: %1x%2, ")).arg(pCodec->width).arg(pCodec->height);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   294
            if (pStream->avg_frame_rate.den)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   295
            {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   296
                float fps = float(pStream->avg_frame_rate.num)/pStream->avg_frame_rate.den;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   297
                desc += QString(tr("%1 fps, ")).arg(fps, 0, 'f', 2);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   298
            }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   299
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   300
        else if (pCodec->codec_type == AVMEDIA_TYPE_AUDIO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   301
            desc += tr("Audio: ");
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   302
        else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   303
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   304
        AVCodec* pDecoder = avcodec_find_decoder(pCodec->codec_id);
8362
89a6b7cc6f95 - Unbreak build with .pro file
unc0rr
parents: 8065
diff changeset
   305
        desc += pDecoder? pDecoder->name : tr("unknown");
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   306
        desc += "\n";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   307
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   308
    AVDictionaryEntry* pComment = av_dict_get(pContext->metadata, "comment", NULL, 0);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   309
    if (pComment)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   310
        desc += QString("\n") + pComment->value;
8065
609d07b337b5 fix deprecation warnings for libav sources
koda
parents: 7897
diff changeset
   311
#if LIBAVFORMAT_VERSION_MAJOR < 53
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   312
    av_close_input_file(pContext);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   313
#else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   314
    avformat_close_input(&pContext);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   315
#endif
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   316
    return desc;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   317
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   318
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   319
#else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   320
LibavInteraction::LibavInteraction() : QObject()
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   321
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   322
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   323
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   324
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   325
void LibavInteraction::fillFormats(QComboBox * pFormats)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   326
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   327
    Q_UNUSED(pFormats);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   328
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   329
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   330
void LibavInteraction::fillCodecs(const QString & format, QComboBox * pVCodecs, QComboBox * pACodecs)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   331
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   332
    Q_UNUSED(format);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   333
    Q_UNUSED(pVCodecs);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   334
    Q_UNUSED(pACodecs);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   335
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   336
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   337
QString LibavInteraction::getExtension(const QString & format)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   338
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   339
    Q_UNUSED(format);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   340
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   341
    return QString();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   342
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   343
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   344
QString LibavInteraction::getFileInfo(const QString & filepath)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   345
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   346
    Q_UNUSED(filepath);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   347
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   348
    return QString();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   349
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   350
#endif
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   351
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   352
LibavInteraction & LibavInteraction::instance()
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   353
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   354
    static LibavInteraction instance;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   355
    return instance;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   356
}