Merge lp:~jpakkane/thumbnailer/embedded_out_of_process into lp:thumbnailer

Proposed by Jussi Pakkanen
Status: Merged
Approved by: Pete Woods
Approved revision: 99
Merged at revision: 99
Proposed branch: lp:~jpakkane/thumbnailer/embedded_out_of_process
Merge into: lp:thumbnailer
Diff against target: 281 lines (+135/-70)
4 files modified
debian/changelog (+15/-0)
src/CMakeLists.txt (+1/-2)
src/audioimageextractor.cpp (+18/-60)
src/vs-thumb.cpp (+101/-8)
To merge this branch: bzr merge lp:~jpakkane/thumbnailer/embedded_out_of_process
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
James Henstridge Approve
Review via email: mp+233173@code.launchpad.net

Commit message

Move embedded thumbnail extraction to a helper binary to avoid linking main library with gstreamer.

Description of the change

Move embedded thumbnail extraction to a helper binary to avoid linking main library with gstreamer.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
James Henstridge (jamesh) wrote :

Looks good. One optional optimisation mentioned in inline comments, but overall this looks good.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
99. By Jussi Pakkanen

Bring in changelog entries from manual revert uploads.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2014-09-01 07:32:23 +0000
+++ debian/changelog 2014-09-03 11:24:10 +0000
@@ -1,3 +1,18 @@
1thumbnailer (1.2+14.10.20140901.is.1.2+14.10.20140814-0ubuntu2) utopic; urgency=medium
2
3 * Reintroduce the pthread linkage fix from 1.2+14.10.20140827.1-0ubuntu1,
4 required for the package to build.
5
6 -- Steve Langasek <steve.langasek@ubuntu.com> Tue, 02 Sep 2014 13:26:28 -0700
7
8thumbnailer (1.2+14.10.20140901.is.1.2+14.10.20140814-0ubuntu1) utopic; urgency=medium
9
10 * Revert the last two landings. The 1.2+14.10.20140827.1 version
11 introduced a serious regression breaking many projects, indirectly
12 caused by thumbnailer using gst. LP: #1363314.
13
14 -- Ɓukasz 'sil2100' Zemczak <lukasz.zemczak@canonical.com> Tue, 02 Sep 2014 21:50:08 +0200
15
1thumbnailer (1.2+14.10.20140901-0ubuntu1) utopic; urgency=medium16thumbnailer (1.2+14.10.20140901-0ubuntu1) utopic; urgency=medium
217
3 [ Pawel Stolowski ]18 [ Pawel Stolowski ]
419
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2014-08-18 14:46:38 +0000
+++ src/CMakeLists.txt 2014-09-03 11:24:10 +0000
@@ -13,7 +13,6 @@
13set(symbol_map "${CMAKE_CURRENT_SOURCE_DIR}/libthumbnailer.map")13set(symbol_map "${CMAKE_CURRENT_SOURCE_DIR}/libthumbnailer.map")
1414
15target_link_libraries(thumbnailer15target_link_libraries(thumbnailer
16 ${GST_DEPS_LDFLAGS}
17 ${GLIB_DEPS_LDFLAGS}16 ${GLIB_DEPS_LDFLAGS}
18 ${GIO_DEPS_LDFLAGS}17 ${GIO_DEPS_LDFLAGS}
19 ${IMG_DEPS_LDFLAGS}18 ${IMG_DEPS_LDFLAGS}
@@ -32,7 +31,7 @@
32)31)
3332
34add_executable(vs-thumb vs-thumb.cpp)33add_executable(vs-thumb vs-thumb.cpp)
35target_link_libraries(vs-thumb ${GST_DEPS_LDFLAGS} ${IMG_DEPS_LDFLAGS})34target_link_libraries(vs-thumb ${GST_DEPS_LDFLAGS} ${IMG_DEPS_LDFLAGS} ${GIO_DEPS_LDFLAGS})
36install(35install(
37 TARGETS vs-thumb36 TARGETS vs-thumb
38 ARCHIVE DESTINATION ${SHARE_PRIV_DIR}37 ARCHIVE DESTINATION ${SHARE_PRIV_DIR}
3938
=== modified file 'src/audioimageextractor.cpp'
--- src/audioimageextractor.cpp 2013-10-08 08:13:11 +0000
+++ src/audioimageextractor.cpp 2014-09-03 11:24:10 +0000
@@ -21,39 +21,30 @@
21#include<unistd.h>21#include<unistd.h>
22#include<stdexcept>22#include<stdexcept>
23#include<memory>23#include<memory>
24#include <gst/pbutils/pbutils.h>24#include"internal/videoscreenshotter.h"
2525
26using namespace std;26using namespace std;
2727
28class GstInitializer {28class AudioImageExtractorPrivate {
29
29public:30public:
30 GstInitializer() { gst_init(nullptr, nullptr); };31
31};32 bool extract(const string &ifname, const string &ofname);
3233
33class AudioImageExtractorPrivate {34private:
34};35 // Use the external binary to extract the embedded image.
3536 // We could use the vs object in the Thumbnailer class and remove
36static bool has_tag(const GstTagList *tlist, const gchar *tagname) {37 // AudioImageExtractor completely but it is possible that
37 const GValue *val = gst_tag_list_get_value_index(tlist, tagname, 0);38 // this is refactored to use a dbus service for efficiency
38 return val;39 // so having this class around will make that refactoring easier.
39}40 VideoScreenshotter vs;
4041};
41static void extract_image(const GstTagList *tlist, FILE *outf) {42
42 const GValue *val = gst_tag_list_get_value_index(tlist, GST_TAG_IMAGE, 0);43bool AudioImageExtractorPrivate::extract(const string &ifname, const string &ofname) {
43 GstSample *sample = (GstSample*)g_value_get_boxed(val);44 return vs.extract(ifname, ofname);
44 GstBuffer *buf = gst_sample_get_buffer(sample);
45
46 for(guint i=0; i<gst_buffer_n_memory(buf); i++) {
47 GstMemory *mem = gst_buffer_peek_memory(buf, i);
48 GstMapInfo mi;
49 gst_memory_map(mem, &mi, GST_MAP_READ);
50 fwrite(mi.data, 1, mi.size, outf);
51 gst_memory_unmap(mem, &mi);
52 }
53}45}
5446
55AudioImageExtractor::AudioImageExtractor() {47AudioImageExtractor::AudioImageExtractor() {
56 static GstInitializer i; // C++ standard guarantees this to be lazy and thread safe.
57 p = new AudioImageExtractorPrivate();48 p = new AudioImageExtractorPrivate();
58}49}
5950
@@ -63,38 +54,5 @@
6354
6455
65bool AudioImageExtractor::extract(const string &ifname, const string &ofname) {56bool AudioImageExtractor::extract(const string &ifname, const string &ofname) {
66 string uri("file://");57 return p->extract(ifname, ofname);
67 if(ifname[0] != '/') {
68 uri += getcwd(nullptr, 0);
69 uri += '/';
70 }
71 uri += ifname;
72 GError *err = nullptr;
73 unique_ptr<GstDiscoverer, void(*)(GstDiscoverer*)> dsc(
74 gst_discoverer_new(GST_SECOND, &err),
75 [](GstDiscoverer *t) {g_object_unref(G_OBJECT(t));});
76 if(err) {
77 string msg(err->message);
78 g_error_free(err);
79 throw runtime_error(msg);
80 }
81 unique_ptr<GstDiscovererInfo, void(*)(GstDiscovererInfo*)> info(
82 gst_discoverer_discover_uri(dsc.get(), uri.c_str(), &err),
83 [](GstDiscovererInfo *t) {g_object_unref(G_OBJECT(t));});
84 if(err) {
85 string msg(err->message);
86 g_error_free(err);
87 throw runtime_error(msg);
88 }
89 const GstTagList *tlist = gst_discoverer_info_get_tags(info.get());
90 if(!tlist) {
91 return false;
92 }
93 if(!has_tag(tlist, GST_TAG_IMAGE)) {
94 return false;
95 }
96 FILE *outfile = fopen(ofname.c_str(), "wb");
97 extract_image(tlist, outfile);
98 fclose(outfile);
99 return true;
100}58}
10159
=== modified file 'src/vs-thumb.cpp'
--- src/vs-thumb.cpp 2014-08-14 11:26:33 +0000
+++ src/vs-thumb.cpp 2014-09-03 11:24:10 +0000
@@ -23,10 +23,15 @@
23#include<gst/gst.h>23#include<gst/gst.h>
24#include<gst/app/gstappsink.h>24#include<gst/app/gstappsink.h>
25#include<gdk-pixbuf/gdk-pixbuf.h>25#include<gdk-pixbuf/gdk-pixbuf.h>
26#include<gio/gio.h>
27#include<glib.h>
28#include<gst/pbutils/pbutils.h>
2629
27using namespace std;30using namespace std;
2831
29bool extract(const std::string &ifname, const std::string &ofname) {32namespace {
33
34bool extract_video(const std::string &ifname, const std::string &ofname) {
30 string caps_string = "video/x-raw,format=RGB,pixel-aspect-ratio=1/1";35 string caps_string = "video/x-raw,format=RGB,pixel-aspect-ratio=1/1";
31 GstElement *sink;36 GstElement *sink;
32 gint64 duration, seek_point;37 gint64 duration, seek_point;
@@ -106,6 +111,64 @@
106 return true;111 return true;
107}112}
108113
114bool has_tag(const GstTagList *tlist, const gchar *tagname) {
115 const GValue *val = gst_tag_list_get_value_index(tlist, tagname, 0);
116 return val;
117}
118
119void extract_embedded_image(const GstTagList *tlist, FILE *outf) {
120 const GValue *val = gst_tag_list_get_value_index(tlist, GST_TAG_IMAGE, 0);
121 GstSample *sample = (GstSample*)g_value_get_boxed(val);
122 GstBuffer *buf = gst_sample_get_buffer(sample);
123
124 for(guint i=0; i<gst_buffer_n_memory(buf); i++) {
125 GstMemory *mem = gst_buffer_peek_memory(buf, i);
126 GstMapInfo mi;
127 gst_memory_map(mem, &mi, GST_MAP_READ);
128 fwrite(mi.data, 1, mi.size, outf);
129 gst_memory_unmap(mem, &mi);
130 }
131}
132
133bool extract_audio(const std::string &ifname, const std::string &ofname) {
134 string uri("file://");
135 if(ifname[0] != '/') {
136 uri += getcwd(nullptr, 0);
137 uri += '/';
138 }
139 uri += ifname;
140 GError *err = nullptr;
141 unique_ptr<GstDiscoverer, void(*)(GstDiscoverer*)> dsc(
142 gst_discoverer_new(GST_SECOND, &err),
143 [](GstDiscoverer *t) {g_object_unref(G_OBJECT(t));});
144 if(err) {
145 string msg(err->message);
146 g_error_free(err);
147 throw runtime_error(msg);
148 }
149 unique_ptr<GstDiscovererInfo, void(*)(GstDiscovererInfo*)> info(
150 gst_discoverer_discover_uri(dsc.get(), uri.c_str(), &err),
151 [](GstDiscovererInfo *t) {g_object_unref(G_OBJECT(t));});
152 if(err) {
153 string msg(err->message);
154 g_error_free(err);
155 throw runtime_error(msg);
156 }
157 const GstTagList *tlist = gst_discoverer_info_get_tags(info.get());
158 if(!tlist) {
159 return false;
160 }
161 if(!has_tag(tlist, GST_TAG_IMAGE)) {
162 return false;
163 }
164 FILE *outfile = fopen(ofname.c_str(), "wb");
165 extract_embedded_image(tlist, outfile);
166 fclose(outfile);
167 return true;
168}
169
170}
171
109int main(int argc, char **argv) {172int main(int argc, char **argv) {
110 gst_init(&argc, &argv);173 gst_init(&argc, &argv);
111 if(argc != 3) {174 if(argc != 3) {
@@ -114,13 +177,43 @@
114 }177 }
115 string infile(argv[1]);178 string infile(argv[1]);
116 string outfile(argv[2]);179 string outfile(argv[2]);
117 bool success;180 bool success = false;
118 try {181
119 success = extract(infile, outfile);182 // Determine file type.
120 } catch(runtime_error &e) {183 std::unique_ptr<GFile, void(*)(void *)> file(
121 printf("Error creating thumbnail: %s\n", e.what());184 g_file_new_for_path(infile.c_str()), g_object_unref);
122 return 2;185 if(!file) {
123 }186 return 1;
187 }
188
189 std::unique_ptr<GFileInfo, void(*)(void *)> info(
190 g_file_query_info(file.get(), G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
191 G_FILE_QUERY_INFO_NONE, /* cancellable */ NULL, /* error */NULL),
192 g_object_unref);
193 if(!info) {
194 return 1;
195 }
196
197 std::string content_type(g_file_info_get_content_type(info.get()));
198
199 if (content_type.find("audio/") == 0) {
200 try {
201 success = extract_audio(infile, outfile);
202 } catch(runtime_error &e) {
203 printf("Error creating thumbnail: %s\n", e.what());
204 return 2;
205 }
206 }
207
208 if (content_type.find("video/") == 0) {
209 try {
210 success = extract_video(infile, outfile);
211 } catch(runtime_error &e) {
212 printf("Error creating thumbnail: %s\n", e.what());
213 return 2;
214 }
215 }
216
124 if(success) {217 if(success) {
125 return 0;218 return 0;
126 }219 }

Subscribers

People subscribed via source and target branches

to all changes: