~ci-train-bot/mediascanner2/mediascanner2-ubuntu-yakkety-landing-063

« back to all changes in this revision

Viewing changes to test/test_extractorbackend.cc

  • Committer: CI Train Bot
  • Author(s): James Henstridge
  • Date: 2016-02-25 01:53:20 UTC
  • mfrom: (320.2.12 taglib-extractor)
  • Revision ID: ci-train-bot@canonical.com-20160225015320-lw52fiyl9pt7bejq
Use taglib to extract metadata from Vorbis, Opus, Flac, MP3 and MP4 audio files.  Other formats will fall back to the existing GStreamer code path. Fixes: #1536832
Approved by: Michi Henning

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
#include <mediascanner/MediaFile.hh>
 
22
#include <mediascanner/MediaFileBuilder.hh>
22
23
#include <extractor/DetectedFile.hh>
23
24
#include <extractor/ExtractorBackend.hh>
 
25
#include <extractor/GStreamerExtractor.hh>
 
26
#include <extractor/TaglibExtractor.hh>
24
27
 
25
28
#include "test_config.h"
26
29
 
33
36
using namespace std;
34
37
using namespace mediascanner;
35
38
 
 
39
namespace {
 
40
 
 
41
bool supports_decoder(const std::string& format)
 
42
{
 
43
    typedef std::unique_ptr<GstCaps, decltype(&gst_caps_unref)> CapsPtr;
 
44
    static std::vector<CapsPtr> formats;
 
45
 
 
46
    if (formats.empty())
 
47
    {
 
48
        std::unique_ptr<GList, decltype(&gst_plugin_feature_list_free)> decoders(
 
49
            gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER, GST_RANK_NONE),
 
50
            gst_plugin_feature_list_free);
 
51
        for (const GList* l = decoders.get(); l != nullptr; l = l->next)
 
52
        {
 
53
            const auto factory = static_cast<GstElementFactory*>(l->data);
 
54
 
 
55
            const GList* templates = gst_element_factory_get_static_pad_templates(factory);
 
56
            for (const GList* l = templates; l != nullptr; l = l->next)
 
57
            {
 
58
                const auto t = static_cast<GstStaticPadTemplate*>(l->data);
 
59
                if (t->direction != GST_PAD_SINK)
 
60
                {
 
61
                    continue;
 
62
                }
 
63
                CapsPtr caps(gst_static_caps_get(&t->static_caps),
 
64
                             gst_caps_unref);
 
65
                if (gst_caps_is_any(caps.get())) {
 
66
                    continue;
 
67
                }
 
68
                formats.emplace_back(std::move(caps));
 
69
            }
 
70
        }
 
71
    }
 
72
 
 
73
    char *end = nullptr;
 
74
    GstStructure *structure = gst_structure_from_string(format.c_str(), &end);
 
75
    assert(structure != nullptr);
 
76
    assert(end == format.c_str() + format.size());
 
77
    // GstCaps adopts the GstStructure
 
78
    CapsPtr caps(gst_caps_new_full(structure, nullptr), gst_caps_unref);
 
79
 
 
80
    for (const auto &other : formats) {
 
81
        if (gst_caps_is_always_compatible(caps.get(), other.get())) {
 
82
            return true;
 
83
        }
 
84
    }
 
85
    return false;
 
86
}
 
87
 
 
88
}
 
89
 
36
90
class ExtractorBackendTest : public ::testing::Test {
37
91
protected:
38
92
    ExtractorBackendTest() {
53
107
    ExtractorBackend extractor;
54
108
}
55
109
 
56
 
TEST_F(ExtractorBackendTest, extract_audio) {
 
110
TEST_F(ExtractorBackendTest, extract_vorbis) {
57
111
    ExtractorBackend e;
58
112
    string testfile = SOURCE_DIR "/media/testfile.ogg";
59
113
    DetectedFile df(testfile, "etag", "audio/ogg", 42, AudioMedia);
68
122
    EXPECT_EQ(file.getDuration(), 5);
69
123
}
70
124
 
 
125
TEST_F(ExtractorBackendTest, extract_mp3) {
 
126
    ExtractorBackend e;
 
127
    string testfile = SOURCE_DIR "/media/testfile.mp3";
 
128
    DetectedFile df(testfile, "etag", "audio/mpeg", 42, AudioMedia);
 
129
    MediaFile file = e.extract(df);
 
130
 
 
131
    EXPECT_EQ(file.getType(), AudioMedia);
 
132
    EXPECT_EQ(file.getTitle(), "track1");
 
133
    EXPECT_EQ(file.getAuthor(), "artist1");
 
134
    EXPECT_EQ(file.getAlbum(), "album1");
 
135
    EXPECT_EQ(file.getGenre(), "Hip-Hop");
 
136
    EXPECT_EQ(file.getDate(), "2013-06-03");
 
137
    EXPECT_EQ(file.getTrackNumber(), 1);
 
138
    EXPECT_EQ(file.getDuration(), 1);
 
139
}
 
140
 
 
141
TEST_F(ExtractorBackendTest, extract_m4a) {
 
142
    ExtractorBackend e;
 
143
    string testfile = SOURCE_DIR "/media/testfile.m4a";
 
144
    DetectedFile df(testfile, "etag", "audio/mpeg4", 42, AudioMedia);
 
145
    MediaFile file = e.extract(df);
 
146
 
 
147
    EXPECT_EQ(file.getType(), AudioMedia);
 
148
    EXPECT_EQ(file.getTitle(), "Title");
 
149
    EXPECT_EQ(file.getAuthor(), "Artist");
 
150
    EXPECT_EQ(file.getAlbum(), "Album");
 
151
    EXPECT_EQ(file.getGenre(), "Rock");
 
152
    EXPECT_EQ(file.getDate(), "2015-10-07");
 
153
    EXPECT_EQ(file.getTrackNumber(), 4);
 
154
    EXPECT_EQ(file.getDuration(), 1);
 
155
}
 
156
 
71
157
TEST_F(ExtractorBackendTest, extract_video) {
72
158
    ExtractorBackend e;
73
159
 
117
203
    EXPECT_DOUBLE_EQ(153.1727346, file.getLongitude());
118
204
}
119
205
 
 
206
void compare_taglib_gst(const DetectedFile d) {
 
207
    GStreamerExtractor gst(5);
 
208
    MediaFileBuilder builder_gst(d.filename);
 
209
    gst.extract(d, builder_gst);
 
210
 
 
211
    TaglibExtractor taglib;
 
212
    MediaFileBuilder builder_taglib(d.filename);
 
213
    ASSERT_TRUE(taglib.extract(d, builder_taglib));
 
214
 
 
215
    MediaFile media_gst(builder_gst);
 
216
    MediaFile media_taglib(builder_taglib);
 
217
    EXPECT_EQ(media_gst, media_taglib);
 
218
 
 
219
    // And check individual keys to improve error handling:
 
220
    EXPECT_EQ(media_gst.getTitle(), media_taglib.getTitle());
 
221
    EXPECT_EQ(media_gst.getAuthor(), media_taglib.getAuthor());
 
222
    EXPECT_EQ(media_gst.getAlbum(), media_taglib.getAlbum());
 
223
    EXPECT_EQ(media_gst.getAlbumArtist(), media_taglib.getAlbumArtist());
 
224
    EXPECT_EQ(media_gst.getDate(), media_taglib.getDate());
 
225
    EXPECT_EQ(media_gst.getGenre(), media_taglib.getGenre());
 
226
    EXPECT_EQ(media_gst.getDiscNumber(), media_taglib.getDiscNumber());
 
227
    EXPECT_EQ(media_gst.getTrackNumber(), media_taglib.getTrackNumber());
 
228
    EXPECT_EQ(media_gst.getDuration(), media_taglib.getDuration());
 
229
    EXPECT_EQ(media_gst.getHasThumbnail(), media_taglib.getHasThumbnail());
 
230
}
 
231
 
 
232
TEST_F(ExtractorBackendTest, check_taglib_gst_vorbis) {
 
233
    DetectedFile d(SOURCE_DIR "/media/testfile.ogg", "etag", "audio/ogg", 42, AudioMedia);
 
234
    compare_taglib_gst(d);
 
235
}
 
236
 
 
237
TEST_F(ExtractorBackendTest, check_taglib_gst_mp3) {
 
238
    if (!supports_decoder("audio/mpeg, mpegversion=(int)1, layer=(int)3")) {
 
239
        printf("MP3 codec not supported\n");
 
240
        return;
 
241
    }
 
242
    DetectedFile d(SOURCE_DIR "/media/testfile.mp3", "etag", "audio/mpeg", 42, AudioMedia);
 
243
    compare_taglib_gst(d);
 
244
}
 
245
 
 
246
TEST_F(ExtractorBackendTest, check_taglib_gst_m4a) {
 
247
    if (!supports_decoder("audio/mpeg, mpegversion=(int)4, stream-format=(string)raw")) {
 
248
        printf("M4A codec not supported\n");
 
249
        return;
 
250
    }
 
251
    DetectedFile d(SOURCE_DIR "/media/testfile.m4a", "etag", "audio/mp4", 42, AudioMedia);
 
252
    compare_taglib_gst(d);
 
253
}
 
254
 
 
255
 
120
256
int main(int argc, char **argv) {
121
257
    gst_init(&argc, &argv);
122
258
    ::testing::InitGoogleTest(&argc, argv);