QTfrontend/util/LibavInteraction.cpp
author Wuzzy <Wuzzy2@mail.ru>
Fri, 27 Oct 2017 05:03:58 +0200
changeset 12782 389453e1e09e
parent 12239 8db93a3a29dc
child 13226 4028d7f85233
permissions -rw-r--r--
ACF7: Fix possible Lua error spam in intro sequence This was caused by a race of onGearDelete vs AnimationSetup. If AnimationSetup came first, it uses old values from the natives table. The solution is to force the code to guarantee that AnimationSetup always coms after deleting gears in the natives table.
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
11046
47a8c19ecb60 more copyright fixes
sheepluva
parents: 10108
diff changeset
     3
 * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
7897
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
10108
c68cf030eded update FSF address. note: two sdl include files (by Sam Lantinga) still have the old FSF address in their copyright - but I ain't gonna touch their copyright headers
sheepluva
parents: 9998
diff changeset
    16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
7897
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
11852
d7227dc3b397 fix build
sheepluva
parents: 11356
diff changeset
    21
#ifdef VIDEOREC
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    22
extern "C"
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    23
{
11298
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    24
#include "libavcodec/avcodec.h"
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    25
#include "libavformat/avformat.h"
11298
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    26
#include "libavutil/avutil.h"
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    27
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    28
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    29
#include <QVector>
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    30
#include <QList>
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    31
#include <QComboBox>
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    32
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    33
#include "HWApplication.h"
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    34
11298
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    35
// compatibility section
11356
ac423fd2b9a3 libavinteraction: Adjust version guard for av_codec_is_encoder()
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11299
diff changeset
    36
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 8, 0)
ac423fd2b9a3 libavinteraction: Adjust version guard for av_codec_is_encoder()
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11299
diff changeset
    37
#define av_codec_is_encoder(x)          x->encode
ac423fd2b9a3 libavinteraction: Adjust version guard for av_codec_is_encoder()
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11299
diff changeset
    38
#endif
ac423fd2b9a3 libavinteraction: Adjust version guard for av_codec_is_encoder()
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11299
diff changeset
    39
11298
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    40
#if LIBAVCODEC_VERSION_MAJOR < 55
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    41
#define AVCodecID                       CodecID
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    42
#endif
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    43
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    44
#if LIBAVFORMAT_VERSION_MAJOR < 54
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    45
#define avformat_find_stream_info(x, y) av_find_stream_info(x)
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    46
#define avformat_close_input(x)         av_close_input_file(*(x))
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    47
#endif
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    48
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    49
#if LIBAVUTIL_VERSION_MAJOR < 54
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    50
#define AVPixelFormat                   PixelFormat
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    51
#define AV_PIX_FMT_YUV420P              PIX_FMT_YUV420P
9429
7a97a554ac80 libavinteraction: fix typo and and compiling with modern libav
koda
parents: 9107
diff changeset
    52
#endif
7a97a554ac80 libavinteraction: fix typo and and compiling with modern libav
koda
parents: 9107
diff changeset
    53
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    54
struct Codec
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    55
{
11298
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    56
    AVCodecID id;
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    57
    bool isAudio;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    58
    QString shortName; // used for identification
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    59
    QString longName; // used for displaying to user
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    60
    bool isRecomended;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    61
};
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    62
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    63
struct Format
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    64
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    65
    QString shortName;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    66
    QString longName;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    67
    bool isRecomended;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    68
    QString extension;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    69
    QVector<Codec*> codecs;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    70
};
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    71
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    72
QList<Codec> codecs;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    73
QMap<QString,Format> formats;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    74
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    75
// test if given format supports given codec
11298
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
    76
bool FormatQueryCodec(AVOutputFormat *ofmt, enum AVCodecID codec_id)
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    77
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    78
#if LIBAVFORMAT_VERSION_MAJOR >= 54
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    79
    return avformat_query_codec(ofmt, codec_id, FF_COMPLIANCE_NORMAL) == 1;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    80
#else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    81
    if (ofmt->codec_tag)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    82
        return !!av_codec_get_tag(ofmt->codec_tag, codec_id);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    83
    return codec_id == ofmt->video_codec || codec_id == ofmt->audio_codec;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    84
#endif
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    85
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    86
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    87
LibavInteraction::LibavInteraction() : QObject()
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    88
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    89
    // initialize libav and register all codecs and formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    90
    av_register_all();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    91
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    92
    // get list of all codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    93
    AVCodec* pCodec = NULL;
8065
609d07b337b5 fix deprecation warnings for libav sources
koda
parents: 7897
diff changeset
    94
    while ((pCodec = av_codec_next(pCodec)))
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    95
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    96
        if (!av_codec_is_encoder(pCodec))
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    97
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    98
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
    99
        if (pCodec->type != AVMEDIA_TYPE_VIDEO && pCodec->type != AVMEDIA_TYPE_AUDIO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   100
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   101
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   102
        // this encoders seems to be buggy
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   103
        if (strcmp(pCodec->name, "rv10") == 0 || strcmp(pCodec->name, "rv20") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   104
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   105
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   106
        // doesn't support stereo sound
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   107
        if (strcmp(pCodec->name, "real_144") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   108
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   109
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   110
        if (!pCodec->long_name || strlen(pCodec->long_name) == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   111
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   112
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   113
        if (pCodec->type == AVMEDIA_TYPE_VIDEO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   114
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   115
            if (pCodec->supported_framerates != NULL)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   116
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   117
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   118
            // check if codec supports yuv 4:2:0 format
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   119
            if (!pCodec->pix_fmts)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   120
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   121
            bool yuv420Supported = false;
11299
64ad779be7bf Specify the enum type for Pixel and Sample formats
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11298
diff changeset
   122
            for (const enum AVPixelFormat* pfmt = pCodec->pix_fmts; *pfmt != -1; pfmt++)
11298
9fcdf0969d53 Update libav API, keeping forward and backward compatibility
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11046
diff changeset
   123
                if (*pfmt == AV_PIX_FMT_YUV420P)
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   124
                {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   125
                    yuv420Supported = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   126
                    break;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   127
                }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   128
            if (!yuv420Supported)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   129
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   130
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   131
        if (pCodec->type == AVMEDIA_TYPE_AUDIO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   132
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   133
            // check if codec supports signed 16-bit format
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   134
            if (!pCodec->sample_fmts)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   135
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   136
            bool s16Supported = false;
11299
64ad779be7bf Specify the enum type for Pixel and Sample formats
Vittorio Giovara <vittorio.giovara@gmail.com>
parents: 11298
diff changeset
   137
            for (const enum AVSampleFormat* pfmt = pCodec->sample_fmts; *pfmt != -1; pfmt++)
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   138
                if (*pfmt == AV_SAMPLE_FMT_S16)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   139
                {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   140
                    s16Supported = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   141
                    break;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   142
                }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   143
            if (!s16Supported)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   144
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   145
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   146
        // add codec to list of codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   147
        codecs.push_back(Codec());
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   148
        Codec & codec = codecs.back();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   149
        codec.id = pCodec->id;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   150
        codec.isAudio = pCodec->type == AVMEDIA_TYPE_AUDIO;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   151
        codec.shortName = pCodec->name;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   152
        codec.longName = pCodec->long_name;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   153
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   154
        codec.isRecomended = false;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   155
        if (strcmp(pCodec->name, "libx264") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   156
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   157
            codec.longName = "H.264/MPEG-4 Part 10 AVC (x264)";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   158
            codec.isRecomended = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   159
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   160
        else if (strcmp(pCodec->name, "libxvid") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   161
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   162
            codec.longName = "MPEG-4 Part 2 (Xvid)";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   163
            codec.isRecomended = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   164
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   165
        else if (strcmp(pCodec->name, "libmp3lame") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   166
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   167
            codec.longName = "MP3 (MPEG audio layer 3) (LAME)";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   168
            codec.isRecomended = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   169
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   170
        else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   171
            codec.longName = pCodec->long_name;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   172
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   173
        if (strcmp(pCodec->name, "mpeg4") == 0 || strcmp(pCodec->name, "ac3_fixed") == 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   174
            codec.isRecomended = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   175
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   176
        // FIXME: remove next line
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   177
        //codec.longName += QString(" (%1)").arg(codec.shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   178
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   179
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   180
    // get list of all formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   181
    AVOutputFormat* pFormat = NULL;
8065
609d07b337b5 fix deprecation warnings for libav sources
koda
parents: 7897
diff changeset
   182
    while ((pFormat = av_oformat_next(pFormat)))
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   183
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   184
        if (!pFormat->extensions)
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
        // skip some strange formats to not confuse users
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   188
        if (strstr(pFormat->long_name, "raw"))
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   189
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   190
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   191
        Format format;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   192
        bool hasVideoCodec = false;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   193
        for (QList<Codec>::iterator codec = codecs.begin(); codec != codecs.end(); ++codec)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   194
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   195
            if (!FormatQueryCodec(pFormat, codec->id))
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   196
                continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   197
            format.codecs.push_back(&*codec);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   198
            if (!codec->isAudio)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   199
                hasVideoCodec = true;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   200
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   201
        if (!hasVideoCodec)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   202
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   203
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   204
        QString ext(pFormat->extensions);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   205
        ext.truncate(strcspn(pFormat->extensions, ","));
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   206
        format.extension = ext;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   207
        format.shortName = pFormat->name;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   208
        format.longName = QString("%1 (*.%2)").arg(pFormat->long_name).arg(ext);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   209
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   210
        // FIXME: remove next line
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   211
        //format.longName += QString(" (%1)").arg(format.shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   212
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   213
        format.isRecomended = strcmp(pFormat->name, "mp4") == 0 || strcmp(pFormat->name, "avi") == 0;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   214
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   215
        formats[pFormat->name] = format;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   216
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   217
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   218
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   219
void LibavInteraction::fillFormats(QComboBox * pFormats)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   220
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   221
    // first insert recomended formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   222
    foreach(const Format & format, formats)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   223
        if (format.isRecomended)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   224
            pFormats->addItem(format.longName, format.shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   225
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   226
    // remember where to place separator between recomended and other formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   227
    int sep = pFormats->count();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   228
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   229
    // insert remaining formats
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   230
    foreach(const Format & format, formats)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   231
        if (!format.isRecomended)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   232
            pFormats->addItem(format.longName, format.shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   233
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   234
    // insert separator if necessary
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   235
    if (sep != 0 && sep != pFormats->count())
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   236
        pFormats->insertSeparator(sep);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   237
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   238
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   239
void LibavInteraction::fillCodecs(const QString & fmt, QComboBox * pVCodecs, QComboBox * pACodecs)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   240
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   241
    Format & format = formats[fmt];
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   242
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   243
    // first insert recomended codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   244
    foreach(Codec * codec, format.codecs)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   245
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   246
        if (codec->isRecomended)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   247
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   248
            if (codec->isAudio)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   249
                pACodecs->addItem(codec->longName, codec->shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   250
            else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   251
                pVCodecs->addItem(codec->longName, codec->shortName);
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
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   255
    // remember where to place separators between recomended and other codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   256
    int vsep = pVCodecs->count();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   257
    int asep = pACodecs->count();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   258
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   259
    // insert remaining codecs
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   260
    foreach(Codec * codec, format.codecs)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   261
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   262
        if (!codec->isRecomended)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   263
        {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   264
            if (codec->isAudio)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   265
                pACodecs->addItem(codec->longName, codec->shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   266
            else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   267
                pVCodecs->addItem(codec->longName, codec->shortName);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   268
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   269
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   270
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   271
    // insert separators if necessary
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   272
    if (vsep != 0 && vsep != pVCodecs->count())
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   273
        pVCodecs->insertSeparator(vsep);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   274
    if (asep != 0 && asep != pACodecs->count())
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   275
        pACodecs->insertSeparator(asep);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   276
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   277
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   278
QString LibavInteraction::getExtension(const QString & format)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   279
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   280
    return formats[format].extension;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   281
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   282
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   283
// get information abaout file (duration, resolution etc) in multiline string
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   284
QString LibavInteraction::getFileInfo(const QString & filepath)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   285
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   286
    AVFormatContext* pContext = NULL;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   287
    QByteArray utf8path = filepath.toUtf8();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   288
    if (avformat_open_input(&pContext, utf8path.data(), NULL, NULL) < 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   289
        return "";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   290
    if (avformat_find_stream_info(pContext, NULL) < 0)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   291
        return "";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   292
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   293
    int s = float(pContext->duration)/AV_TIME_BASE;
12239
8db93a3a29dc Use standard units and abbreviations in frontend
Wuzzy <almikes@aol.com>
parents: 11852
diff changeset
   294
    //: Duration in minutes and seconds (SI units)
8db93a3a29dc Use standard units and abbreviations in frontend
Wuzzy <almikes@aol.com>
parents: 11852
diff changeset
   295
    QString desc = tr("Duration: %1min %2s").arg(s/60).arg(s%60) + "\n";
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   296
    for (int i = 0; i < (int)pContext->nb_streams; i++)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   297
    {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   298
        AVStream* pStream = pContext->streams[i];
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   299
        if (!pStream)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   300
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   301
        AVCodecContext* pCodec = pContext->streams[i]->codec;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   302
        if (!pCodec)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   303
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   304
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   305
        if (pCodec->codec_type == AVMEDIA_TYPE_VIDEO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   306
        {
9107
4dde5fecffe2 Less confusion to translators
unc0rr
parents: 9080
diff changeset
   307
            desc += QString(tr("Video: %1x%2")).arg(pCodec->width).arg(pCodec->height) + ", ";
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   308
            if (pStream->avg_frame_rate.den)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   309
            {
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   310
                float fps = float(pStream->avg_frame_rate.num)/pStream->avg_frame_rate.den;
12239
8db93a3a29dc Use standard units and abbreviations in frontend
Wuzzy <almikes@aol.com>
parents: 11852
diff changeset
   311
                desc += QString(tr("%1 FPS")).arg(fps, 0, 'f', 2) + ", ";
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   312
            }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   313
        }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   314
        else if (pCodec->codec_type == AVMEDIA_TYPE_AUDIO)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   315
            desc += tr("Audio: ");
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   316
        else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   317
            continue;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   318
        AVCodec* pDecoder = avcodec_find_decoder(pCodec->codec_id);
8362
89a6b7cc6f95 - Unbreak build with .pro file
unc0rr
parents: 8065
diff changeset
   319
        desc += pDecoder? pDecoder->name : tr("unknown");
7897
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   320
        desc += "\n";
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   321
    }
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   322
    AVDictionaryEntry* pComment = av_dict_get(pContext->metadata, "comment", NULL, 0);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   323
    if (pComment)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   324
        desc += QString("\n") + pComment->value;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   325
    avformat_close_input(&pContext);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   326
    return desc;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   327
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   328
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   329
#else
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   330
LibavInteraction::LibavInteraction() : QObject()
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   331
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   332
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   333
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   334
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   335
void LibavInteraction::fillFormats(QComboBox * pFormats)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   336
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   337
    Q_UNUSED(pFormats);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   338
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   339
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   340
void LibavInteraction::fillCodecs(const QString & format, QComboBox * pVCodecs, QComboBox * pACodecs)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   341
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   342
    Q_UNUSED(format);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   343
    Q_UNUSED(pVCodecs);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   344
    Q_UNUSED(pACodecs);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   345
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   346
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   347
QString LibavInteraction::getExtension(const QString & format)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   348
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   349
    Q_UNUSED(format);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   350
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   351
    return QString();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   352
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   353
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   354
QString LibavInteraction::getFileInfo(const QString & filepath)
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   355
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   356
    Q_UNUSED(filepath);
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   357
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   358
    return QString();
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   359
}
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   360
#endif
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   361
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   362
LibavInteraction & LibavInteraction::instance()
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   363
{
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   364
    static LibavInteraction instance;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   365
    return instance;
5e7c0810f365 libav name refactor
koda
parents:
diff changeset
   366
}