Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 665518
Collapse All | Expand All

(-)a/src/extractors/ffmpegextractor.cpp (-1 / +1 lines)
Lines 1-179 Link Here
1
/*
1
/*
2
    Copyright (C) 2012-2014  Vishesh Handa <me@vhanda.in>
2
    Copyright (C) 2012-2014  Vishesh Handa <me@vhanda.in>
3
3
4
    Code adapted from Strigi FFmpeg Analyzer -
4
    Code adapted from Strigi FFmpeg Analyzer -
5
    Copyright (C) 2010 Evgeny Egorochkin <phreedom.stdin@gmail.com>
5
    Copyright (C) 2010 Evgeny Egorochkin <phreedom.stdin@gmail.com>
6
    Copyright (C) 2011 Tirtha Chatterjee <tirtha.p.chatterjee@gmail.com>
6
    Copyright (C) 2011 Tirtha Chatterjee <tirtha.p.chatterjee@gmail.com>
7
7
8
    This library is free software; you can redistribute it and/or
8
    This library is free software; you can redistribute it and/or
9
    modify it under the terms of the GNU Lesser General Public
9
    modify it under the terms of the GNU Lesser General Public
10
    License as published by the Free Software Foundation; either
10
    License as published by the Free Software Foundation; either
11
    version 2.1 of the License, or (at your option) any later version.
11
    version 2.1 of the License, or (at your option) any later version.
12
12
13
    This library is distributed in the hope that it will be useful,
13
    This library is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
    Lesser General Public License for more details.
16
    Lesser General Public License for more details.
17
17
18
    You should have received a copy of the GNU Lesser General Public
18
    You should have received a copy of the GNU Lesser General Public
19
    License along with this library; if not, write to the Free Software
19
    License along with this library; if not, write to the Free Software
20
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
*/
21
*/
22
22
23
23
24
#include "ffmpegextractor.h"
24
#include "ffmpegextractor.h"
25
25
26
#ifdef __cplusplus
26
#ifdef __cplusplus
27
#define __STDC_CONSTANT_MACROS
27
#define __STDC_CONSTANT_MACROS
28
#ifdef _STDINT_H
28
#ifdef _STDINT_H
29
#undef _STDINT_H
29
#undef _STDINT_H
30
#endif
30
#endif
31
# include <stdint.h>
31
# include <stdint.h>
32
#endif
32
#endif
33
33
34
extern "C" {
34
extern "C" {
35
#include <libavformat/avformat.h>
35
#include <libavformat/avformat.h>
36
#include <libavutil/dict.h>
36
#include <libavutil/dict.h>
37
#include <libavcodec/avcodec.h>
37
#include <libavcodec/avcodec.h>
38
}
38
}
39
39
40
#include <QDateTime>
40
#include <QDateTime>
41
#include <QDebug>
41
#include <QDebug>
42
42
43
using namespace KFileMetaData;
43
using namespace KFileMetaData;
44
44
45
FFmpegExtractor::FFmpegExtractor(QObject* parent)
45
FFmpegExtractor::FFmpegExtractor(QObject* parent)
46
: ExtractorPlugin(parent)
46
: ExtractorPlugin(parent)
47
{
47
{
48
}
48
}
49
49
50
QStringList FFmpegExtractor::mimetypes() const
50
QStringList FFmpegExtractor::mimetypes() const
51
{
51
{
52
    QStringList types;
52
    QStringList types;
53
53
54
    types << QStringLiteral("video/x-ms-asf");
54
    types << QStringLiteral("video/x-ms-asf");
55
    types << QStringLiteral("video/x-msvideo");
55
    types << QStringLiteral("video/x-msvideo");
56
    types << QStringLiteral("video/x-flv");
56
    types << QStringLiteral("video/x-flv");
57
    types << QStringLiteral("video/quicktime");
57
    types << QStringLiteral("video/quicktime");
58
    types << QStringLiteral("video/mpeg");
58
    types << QStringLiteral("video/mpeg");
59
    types << QStringLiteral("video/x-ms-wmv");
59
    types << QStringLiteral("video/x-ms-wmv");
60
    types << QStringLiteral("video/mp4");
60
    types << QStringLiteral("video/mp4");
61
    types << QStringLiteral("video/x-matroska");
61
    types << QStringLiteral("video/x-matroska");
62
    types << QStringLiteral("video/webm");
62
    types << QStringLiteral("video/webm");
63
63
64
    return types;
64
    return types;
65
}
65
}
66
66
67
void FFmpegExtractor::extract(ExtractionResult* result)
67
void FFmpegExtractor::extract(ExtractionResult* result)
68
{
68
{
69
    AVFormatContext* fmt_ctx = NULL;
69
    AVFormatContext* fmt_ctx = NULL;
70
70
71
    av_register_all();
71
    av_register_all();
72
72
73
    QByteArray arr = result->inputUrl().toUtf8();
73
    QByteArray arr = result->inputUrl().toUtf8();
74
74
75
    fmt_ctx = avformat_alloc_context();
75
    fmt_ctx = avformat_alloc_context();
76
    if (int ret = avformat_open_input(&fmt_ctx, arr.data(), NULL, NULL)) {
76
    if (int ret = avformat_open_input(&fmt_ctx, arr.data(), NULL, NULL)) {
77
        qWarning() << "avformat_open_input error: " << ret;
77
        qWarning() << "avformat_open_input error: " << ret;
78
        return;
78
        return;
79
    }
79
    }
80
80
81
    int ret = avformat_find_stream_info(fmt_ctx, NULL);
81
    int ret = avformat_find_stream_info(fmt_ctx, NULL);
82
    if (ret < 0) {
82
    if (ret < 0) {
83
        qWarning() << "avform_find_stream_info error: " << ret;
83
        qWarning() << "avform_find_stream_info error: " << ret;
84
        return;
84
        return;
85
    }
85
    }
86
86
87
    result->addType(Type::Video);
87
    result->addType(Type::Video);
88
88
89
    int totalSecs = fmt_ctx->duration / AV_TIME_BASE;
89
    int totalSecs = fmt_ctx->duration / AV_TIME_BASE;
90
    int bitrate = fmt_ctx->bit_rate;
90
    int bitrate = fmt_ctx->bit_rate;
91
91
92
    result->add(Property::Duration, totalSecs);
92
    result->add(Property::Duration, totalSecs);
93
    result->add(Property::BitRate, bitrate);
93
    result->add(Property::BitRate, bitrate);
94
94
95
    for (uint i = 0; i < fmt_ctx->nb_streams; i++) {
95
    for (uint i = 0; i < fmt_ctx->nb_streams; i++) {
96
        const AVStream* stream = fmt_ctx->streams[i];
96
        const AVStream* stream = fmt_ctx->streams[i];
97
        const AVCodecParameters* codec = stream->codecpar;
97
        const AVCodecContext* codec = stream->codec;
98
98
99
        if (codec->codec_type == AVMEDIA_TYPE_AUDIO || codec->codec_type == AVMEDIA_TYPE_VIDEO) {
99
        if (codec->codec_type == AVMEDIA_TYPE_AUDIO || codec->codec_type == AVMEDIA_TYPE_VIDEO) {
100
            /*
100
            /*
101
            if( codec->codec_type == AVMEDIA_TYPE_AUDIO ) {
101
            if( codec->codec_type == AVMEDIA_TYPE_AUDIO ) {
102
                subRes.addType( NFO::Audio() );
102
                subRes.addType( NFO::Audio() );
103
                subRes.addProperty( NFO::sampleRate(), codec->sample_rate );
103
                subRes.addProperty( NFO::sampleRate(), codec->sample_rate );
104
                subRes.addProperty( NFO::channels(), codec->channels );
104
                subRes.addProperty( NFO::channels(), codec->channels );
105
105
106
                //TODO: Fetch Sample Format
106
                //TODO: Fetch Sample Format
107
            }*/
107
            }*/
108
108
109
            if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
109
            if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
110
                int aspectRatio = codec->sample_aspect_ratio.num;
110
                int aspectRatio = codec->sample_aspect_ratio.num;
111
                int frameRate = stream->avg_frame_rate.num;
111
                int frameRate = stream->avg_frame_rate.num;
112
112
113
                if (codec->sample_aspect_ratio.den)
113
                if (codec->sample_aspect_ratio.den)
114
                    aspectRatio /= codec->sample_aspect_ratio.den;
114
                    aspectRatio /= codec->sample_aspect_ratio.den;
115
                if (stream->avg_frame_rate.den)
115
                if (stream->avg_frame_rate.den)
116
                    frameRate /= stream->avg_frame_rate.den;
116
                    frameRate /= stream->avg_frame_rate.den;
117
117
118
                result->add(Property::Width, codec->width);
118
                result->add(Property::Width, codec->width);
119
                result->add(Property::Height, codec->height);
119
                result->add(Property::Height, codec->height);
120
                if (aspectRatio)
120
                if (aspectRatio)
121
                    result->add(Property::AspectRatio, aspectRatio);
121
                    result->add(Property::AspectRatio, aspectRatio);
122
                if (frameRate)
122
                if (frameRate)
123
                    result->add(Property::FrameRate, frameRate);
123
                    result->add(Property::FrameRate, frameRate);
124
            }
124
            }
125
        }
125
        }
126
    }
126
    }
127
127
128
    AVDictionary* dict = fmt_ctx->metadata;
128
    AVDictionary* dict = fmt_ctx->metadata;
129
    AVDictionaryEntry* entry;
129
    AVDictionaryEntry* entry;
130
130
131
    entry = av_dict_get(dict, "title", NULL, 0);
131
    entry = av_dict_get(dict, "title", NULL, 0);
132
    if (entry) {
132
    if (entry) {
133
        result->add(Property::Title, QString::fromUtf8(entry->value));
133
        result->add(Property::Title, QString::fromUtf8(entry->value));
134
    }
134
    }
135
135
136
136
137
    entry = av_dict_get(dict, "author", NULL, 0);
137
    entry = av_dict_get(dict, "author", NULL, 0);
138
    if (entry) {
138
    if (entry) {
139
        result->add(Property::Author, QString::fromUtf8(entry->value));
139
        result->add(Property::Author, QString::fromUtf8(entry->value));
140
    }
140
    }
141
141
142
    entry = av_dict_get(dict, "copyright", NULL, 0);
142
    entry = av_dict_get(dict, "copyright", NULL, 0);
143
    if (entry) {
143
    if (entry) {
144
        result->add(Property::Copyright, QString::fromUtf8(entry->value));
144
        result->add(Property::Copyright, QString::fromUtf8(entry->value));
145
    }
145
    }
146
146
147
    entry = av_dict_get(dict, "comment", NULL, 0);
147
    entry = av_dict_get(dict, "comment", NULL, 0);
148
    if (entry) {
148
    if (entry) {
149
        result->add(Property::Comment, QString::fromUtf8(entry->value));
149
        result->add(Property::Comment, QString::fromUtf8(entry->value));
150
    }
150
    }
151
151
152
    entry = av_dict_get(dict, "album", NULL, 0);
152
    entry = av_dict_get(dict, "album", NULL, 0);
153
    if (entry) {
153
    if (entry) {
154
        result->add(Property::Album, QString::fromUtf8(entry->value));
154
        result->add(Property::Album, QString::fromUtf8(entry->value));
155
    }
155
    }
156
156
157
    entry = av_dict_get(dict, "genre", NULL, 0);
157
    entry = av_dict_get(dict, "genre", NULL, 0);
158
    if (entry) {
158
    if (entry) {
159
        result->add(Property::Genre, QString::fromUtf8(entry->value));
159
        result->add(Property::Genre, QString::fromUtf8(entry->value));
160
    }
160
    }
161
161
162
    entry = av_dict_get(dict, "track", NULL, 0);
162
    entry = av_dict_get(dict, "track", NULL, 0);
163
    if (entry) {
163
    if (entry) {
164
        QString value = QString::fromUtf8(entry->value);
164
        QString value = QString::fromUtf8(entry->value);
165
165
166
        bool ok = false;
166
        bool ok = false;
167
        int track = value.toInt(&ok);
167
        int track = value.toInt(&ok);
168
        if (ok && track)
168
        if (ok && track)
169
            result->add(Property::TrackNumber, track);
169
            result->add(Property::TrackNumber, track);
170
    }
170
    }
171
171
172
    entry = av_dict_get(dict, "year", NULL, 0);
172
    entry = av_dict_get(dict, "year", NULL, 0);
173
    if (entry) {
173
    if (entry) {
174
        int year = QString::fromUtf8(entry->value).toInt();
174
        int year = QString::fromUtf8(entry->value).toInt();
175
        result->add(Property::ReleaseYear, year);
175
        result->add(Property::ReleaseYear, year);
176
    }
176
    }
177
177
178
    avformat_close_input(&fmt_ctx);
178
    avformat_close_input(&fmt_ctx);
179
}
179
}

Return to bug 665518