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

Subscribers

People subscribed via source and target branches

to all changes: