Merge lp:~phablet-team/ubuntu/trusty/qtmultimedia-opensource-src/use-camerabin1 into lp:ubuntu/trusty-proposed/qtmultimedia-opensource-src

Proposed by Ugo Riboni
Status: Needs review
Proposed branch: lp:~phablet-team/ubuntu/trusty/qtmultimedia-opensource-src/use-camerabin1
Merge into: lp:ubuntu/trusty-proposed/qtmultimedia-opensource-src
Diff against target: 430 lines (+418/-0)
2 files modified
debian/patches/series (+1/-0)
debian/patches/use-camerabin1.diff (+417/-0)
To merge this branch: bzr merge lp:~phablet-team/ubuntu/trusty/qtmultimedia-opensource-src/use-camerabin1
Reviewer Review Type Date Requested Status
Jim Hodapp (community) code Approve
Review via email: mp+221863@code.launchpad.net

Commit message

Use camerabin1 instead of camerabin2 for more stability and better control over resolution and framerate settings.

Description of the change

Use camerabin1 instead of camerabin2 for more stability and better control over resolution and framerate settings.

To post a comment you must log in.
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Looks good, thanks!

review: Approve (code)

Unmerged revisions

18. By Ugo Riboni

Use camerabin1 instead of camerabin2 to all more control over resolution and frame rate settings, and for more stability

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/patches/series'
2--- debian/patches/series 2014-03-16 12:42:25 +0000
3+++ debian/patches/series 2014-06-03 11:21:24 +0000
4@@ -1,3 +1,4 @@
5 skip_failing_tests.patch
6 fix_failing_test.diff
7 bigendian_support.diff
8+use-camerabin1.diff
9
10=== added file 'debian/patches/use-camerabin1.diff'
11--- debian/patches/use-camerabin1.diff 1970-01-01 00:00:00 +0000
12+++ debian/patches/use-camerabin1.diff 2014-06-03 11:21:24 +0000
13@@ -0,0 +1,417 @@
14+Description: Use camerabin1 instead of camerabin2 to improve success in querying and setting resolution and framerate
15+Author: Ugo Riboni <ugo.riboni@canonical.com>
16+Last-Update: 2014-06-03
17+
18+=== modified file 'src/plugins/gstreamer/camerabin/camerabinsession.cpp'
19+--- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp 2014-05-20 12:02:34 +0000
20++++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp 2014-06-03 10:59:01 +0000
21+@@ -82,31 +82,25 @@
22+ //#define CAMERABIN_DEBUG_DUMP_BIN 1
23+ #define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
24+
25+-#define FILENAME_PROPERTY "location"
26++#define FILENAME_PROPERTY "filename"
27+ #define MODE_PROPERTY "mode"
28+ #define MUTE_PROPERTY "mute"
29+ #define IMAGE_PP_PROPERTY "image-post-processing"
30+ #define IMAGE_ENCODER_PROPERTY "image-encoder"
31+ #define VIDEO_PP_PROPERTY "video-post-processing"
32+ #define VIEWFINDER_SINK_PROPERTY "viewfinder-sink"
33+-#define CAMERA_SOURCE_PROPERTY "camera-source"
34+ #define AUDIO_SOURCE_PROPERTY "audio-source"
35+ #define SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-supported-caps"
36+-#define SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-supported-caps"
37+-#define SUPPORTED_VIEWFINDER_CAPS_PROPERTY "viewfinder-supported-caps"
38+-#define AUDIO_CAPTURE_CAPS_PROPERTY "audio-capture-caps"
39+-#define IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-caps"
40+-#define VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-caps"
41+-#define VIEWFINDER_CAPS_PROPERTY "viewfinder-caps"
42++#define SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY "video-source-caps"
43++#define AUDIO_CAPTURE_CAPS_PROPERTY "caps"
44+ #define PREVIEW_CAPS_PROPERTY "preview-caps"
45+ #define POST_PREVIEWS_PROPERTY "post-previews"
46+
47+-
48+-#define CAPTURE_START "start-capture"
49+-#define CAPTURE_STOP "stop-capture"
50+-
51+-#define CAMERABIN_IMAGE_MODE 1
52+-#define CAMERABIN_VIDEO_MODE 2
53++#define CAPTURE_START "capture-start"
54++#define CAPTURE_STOP "capture-stop"
55++
56++#define CAMERABIN_IMAGE_MODE 0
57++#define CAMERABIN_VIDEO_MODE 1
58+
59+ #define gstRef(element) { gst_object_ref(GST_OBJECT(element)); gst_object_sink(GST_OBJECT(element)); }
60+ #define gstUnref(element) { if (element) { gst_object_unref(GST_OBJECT(element)); element = 0; } }
61+@@ -144,7 +138,7 @@
62+ m_audioEncoder(0),
63+ m_muxer(0)
64+ {
65+- m_camerabin = gst_element_factory_make("camerabin2", "camerabin2");
66++ m_camerabin = gst_element_factory_make("camerabin", "camerabin");
67+ g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this);
68+ gstRef(m_camerabin);
69+
70+@@ -182,6 +176,29 @@
71+ GstCaps *previewCaps = gst_caps_from_string("video/x-raw-rgb");
72+ g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL);
73+ gst_caps_unref(previewCaps);
74++
75++ /* Setup the audio input as a bin capable of filtering audio coming from the
76++ * automatically selected audio source with the audio settings configured by the
77++ * user (see setAudioCaptureCaps()) */
78++ GstElement* audiosrc = gst_element_factory_make("autoaudiosrc", "audio_source");
79++ GstElement* filter = gst_element_factory_make("capsfilter", "filter");
80++ GstElement* convert = gst_element_factory_make("audioconvert", "convert");
81++ GstElement* bin = gst_bin_new ("audiofilterbin2");
82++ if (audiosrc && filter && convert && bin) {
83++ gst_bin_add_many(GST_BIN (bin), audiosrc, filter, convert, NULL);
84++ gst_element_link_many (audiosrc, filter, convert, NULL);
85++ GstPad* pad = gst_element_get_static_pad (convert, "src");
86++ if (pad) {
87++ GstPad* ghost_pad = gst_ghost_pad_new ("src", pad);
88++ gst_pad_set_active (ghost_pad, TRUE);
89++ gst_element_add_pad (bin, ghost_pad);
90++ gst_object_unref (pad);
91++
92++ g_object_set(G_OBJECT(m_camerabin), AUDIO_SOURCE_PROPERTY, bin, NULL);
93++ m_audioSrc = bin;
94++ m_capsFilter = filter;
95++ } else qWarning() << "Can't setup audio pipeline correctly, audio settings will not be respected.";
96++ } else qWarning() << "Can't setup audio pipeline correctly, audio settings will not be respected.";
97+ }
98+
99+ CameraBinSession::~CameraBinSession()
100+@@ -247,108 +264,32 @@
101+ return true;
102+ }
103+
104+-static GstCaps *resolutionToCaps(const QSize &resolution, const QPair<int, int> &rate = qMakePair<int,int>(0,0))
105+-{
106+- if (resolution.isEmpty())
107+- return gst_caps_new_any();
108+-
109+- GstCaps *caps = 0;
110+- if (rate.second > 0) {
111+- caps = gst_caps_new_full(gst_structure_new("video/x-raw-yuv",
112+- "width", G_TYPE_INT, resolution.width(),
113+- "height", G_TYPE_INT, resolution.height(),
114+- "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
115+- NULL),
116+- gst_structure_new("video/x-raw-rgb",
117+- "width", G_TYPE_INT, resolution.width(),
118+- "height", G_TYPE_INT, resolution.height(),
119+- "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
120+- NULL),
121+- gst_structure_new("video/x-raw-data",
122+- "width", G_TYPE_INT, resolution.width(),
123+- "height", G_TYPE_INT, resolution.height(),
124+- "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
125+- NULL),
126+- gst_structure_new("video/x-android-buffer",
127+- "width", G_TYPE_INT, resolution.width(),
128+- "height", G_TYPE_INT, resolution.height(),
129+- "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
130+- NULL),
131+- gst_structure_new("image/jpeg",
132+- "width", G_TYPE_INT, resolution.width(),
133+- "height", G_TYPE_INT, resolution.height(),
134+- "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
135+- NULL),
136+- NULL);
137+- } else {
138+- caps = gst_caps_new_full (gst_structure_new ("video/x-raw-yuv",
139+- "width", G_TYPE_INT, resolution.width(),
140+- "height", G_TYPE_INT, resolution.height(),
141+- NULL),
142+- gst_structure_new ("video/x-raw-rgb",
143+- "width", G_TYPE_INT, resolution.width(),
144+- "height", G_TYPE_INT, resolution.height(),
145+- NULL),
146+- gst_structure_new("video/x-raw-data",
147+- "width", G_TYPE_INT, resolution.width(),
148+- "height", G_TYPE_INT, resolution.height(),
149+- NULL),
150+- gst_structure_new ("video/x-android-buffer",
151+- "width", G_TYPE_INT, resolution.width(),
152+- "height", G_TYPE_INT, resolution.height(),
153+- NULL),
154+- gst_structure_new ("image/jpeg",
155+- "width", G_TYPE_INT, resolution.width(),
156+- "height", G_TYPE_INT, resolution.height(),
157+- NULL),
158+- NULL);
159+- }
160+-
161+- return caps;
162+-}
163+-
164+ void CameraBinSession::setupCaptureResolution()
165+ {
166+ QSize resolution = m_imageEncodeControl->imageSettings().resolution();
167+ if (!resolution.isEmpty()) {
168+- GstCaps *caps = resolutionToCaps(resolution);
169+-#if CAMERABIN_DEBUG
170+- qDebug() << Q_FUNC_INFO << "set image resolution" << resolution << gst_caps_to_string(caps);
171+-#endif
172+- g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, caps, NULL);
173+- gst_caps_unref(caps);
174+- } else {
175+- g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, NULL, NULL);
176++ g_signal_emit_by_name (m_camerabin, "set-image-resolution",
177++ resolution.width(),resolution.height(), 0);
178+ }
179+
180+ resolution = m_videoEncodeControl->actualVideoSettings().resolution();
181+- //qreal framerate = m_videoEncodeControl->videoSettings().frameRate();
182+- if (!resolution.isEmpty()) {
183+- GstCaps *caps = resolutionToCaps(resolution /*, framerate*/); //convert to rational
184+-#if CAMERABIN_DEBUG
185+- qDebug() << Q_FUNC_INFO << "set video resolution" << resolution << gst_caps_to_string(caps);
186+-#endif
187+- g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, caps, NULL);
188+- gst_caps_unref(caps);
189+- } else {
190+- g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, NULL, NULL);
191+- }
192+-
193+- resolution = m_viewfinderSettingsControl->resolution();
194+- if (!resolution.isEmpty()) {
195+- GstCaps *caps = resolutionToCaps(resolution);
196+-#if CAMERABIN_DEBUG
197+- qDebug() << Q_FUNC_INFO << "set viewfinder resolution" << resolution << gst_caps_to_string(caps);
198+-#endif
199+- g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, caps, NULL);
200+- gst_caps_unref(caps);
201+- } else {
202+- g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, NULL, NULL);
203++ qreal framerate = m_videoEncodeControl->actualVideoSettings().frameRate();
204++
205++ if (!resolution.isEmpty()) {
206++#if CAMERABIN_DEBUG
207++ qDebug() << Q_FUNC_INFO << "set video resolution" << resolution << framerate;
208++#endif
209++
210++ QPair<int, int> rate = m_videoEncodeControl->rateAsRational(framerate);
211++ g_signal_emit_by_name (m_camerabin, "set-video-resolution-fps", resolution.width(),
212++ resolution.height(), rate.first, rate.second, NULL);
213+ }
214+ }
215+
216+ void CameraBinSession::setAudioCaptureCaps()
217+ {
218++ if (!m_capsFilter) return;
219++
220+ QAudioEncoderSettings settings = m_audioEncodeControl->audioSettings();
221+ const int sampleRate = settings.sampleRate();
222+ const int channelCount = settings.channelCount();
223+@@ -369,7 +310,7 @@
224+ gst_structure_set(structure, "channels", G_TYPE_INT, channelCount, NULL);
225+
226+ GstCaps *caps = gst_caps_new_full(structure, NULL);
227+- g_object_set(G_OBJECT(m_camerabin), AUDIO_CAPTURE_CAPS_PROPERTY, caps, NULL);
228++ g_object_set(G_OBJECT(m_capsFilter), AUDIO_CAPTURE_CAPS_PROPERTY, caps, NULL);
229+ gst_caps_unref(caps);
230+ }
231+
232+@@ -383,7 +324,7 @@
233+ m_videoInputHasChanged = false;
234+
235+ GstElement *videoSrc = 0;
236+- g_object_get(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, &videoSrc, NULL);
237++ g_object_get(G_OBJECT(m_camerabin), "video-source", &videoSrc, NULL);
238+
239+ // If the QT_GSTREAMER_CAMERABIN_SRC environment variable has been set use the source
240+ // it recommends.
241+@@ -435,9 +376,6 @@
242+ }
243+ }
244+
245+- if (m_videoSrc != videoSrc)
246+- g_object_set(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, m_videoSrc, NULL);
247+-
248+ return m_videoSrc;
249+ }
250+
251+@@ -624,6 +562,83 @@
252+ return m_pendingState;
253+ }
254+
255++static gint compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
256++{
257++ gint diff;
258++ const gchar *rname1, *rname2;
259++
260++ diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
261++ if (diff != 0)
262++ return diff;
263++
264++ rname1 = gst_plugin_feature_get_name (f1);
265++ rname2 = gst_plugin_feature_get_name (f2);
266++
267++ diff = g_strcmp0 (rname1, rname2);
268++
269++ return diff;
270++}
271++
272++QString CameraBinSession::findPlugin(const QString &category, const QString &MIMEType) const
273++{
274++#ifdef CAMERABIN_DEBUG_FIND_CODECS
275++ qDebug() << "Trying to find codec for category" << category << "and type" << MIMEType;
276++#endif
277++
278++ GstCaps *wanted = gst_caps_from_string(MIMEType.toLatin1());
279++ GList *feature_list;
280++ GList *walk;
281++
282++ feature_list = gst_registry_get_feature_list(gst_registry_get_default(), GST_TYPE_ELEMENT_FACTORY);
283++ feature_list = g_list_sort(feature_list, (GCompareFunc) compare_ranks);
284++
285++ for (walk = feature_list; walk != NULL; walk = walk->next) {
286++ GstElementFactory *factory;
287++ const gchar *klass;
288++
289++ factory = GST_ELEMENT_FACTORY(walk->data);
290++ klass = gst_element_factory_get_klass(factory);
291++
292++ if (category == klass) {
293++#ifdef CAMERABIN_DEBUG_FIND_CODECS
294++ qDebug() << " element" << GST_PLUGIN_FEATURE_NAME(factory) << ":" << gst_plugin_feature_get_rank((GstPluginFeature*)walk->data);
295++#endif
296++
297++ const GList *list;
298++ const GList *walkpads;
299++ list = gst_element_factory_get_static_pad_templates(factory);
300++ for (walkpads = list; walkpads != NULL; walkpads = walkpads->next) {
301++ GstStaticPadTemplate *pad = (GstStaticPadTemplate*) walkpads->data;
302++ if (pad->direction == GST_PAD_SRC) {
303++ GstCaps *padcaps = gst_static_pad_template_get_caps(pad);
304++
305++#ifdef CAMERABIN_DEBUG_FIND_CODECS
306++ unsigned int padcapslen = gst_caps_get_size(padcaps);
307++ for (unsigned int i = 0; i < padcapslen; i++) {
308++ GstStructure *structure = gst_caps_get_structure(padcaps, i);
309++ qDebug() << " " << gst_structure_get_name(structure);
310++ }
311++#endif
312++ if (gst_caps_can_intersect(padcaps, wanted)) {
313++#ifdef CAMERABIN_DEBUG_FIND_CODECS
314++ qDebug() << " ^^^^ MATCH";
315++#endif
316++ gst_caps_unref(wanted);
317++ gst_caps_unref(padcaps);
318++ gst_plugin_feature_list_free(feature_list);
319++ return GST_PLUGIN_FEATURE_NAME(factory);
320++ }
321++ gst_caps_unref(padcaps);
322++ }
323++ }
324++ }
325++ }
326++ gst_plugin_feature_list_free(feature_list);
327++ gst_caps_unref(wanted);
328++
329++ return QString();
330++}
331++
332+ void CameraBinSession::setState(QCamera::State newState)
333+ {
334+ if (newState == m_pendingState)
335+@@ -680,10 +695,35 @@
336+
337+ m_recorderControl->applySettings();
338+
339+- g_object_set (G_OBJECT(m_camerabin),
340+- "video-profile",
341+- m_recorderControl->videoProfile(),
342+- NULL);
343++ QString videoCodec = findPlugin("Codec/Encoder/Video", m_videoEncodeControl->actualVideoSettings().codec());
344++ if (videoCodec.isEmpty()) {
345++ qWarning() << "No video encoder found for MIME type" << m_videoEncodeControl->actualVideoSettings().codec();
346++ } else {
347++ g_object_set (G_OBJECT(m_camerabin),
348++ "video-encoder",
349++ gst_element_factory_make(videoCodec.toLatin1(), NULL),
350++ NULL);
351++ }
352++
353++ QString audioCodec = findPlugin("Codec/Encoder/Audio", m_audioEncodeControl->actualAudioSettings().codec());
354++ if (audioCodec.isEmpty()) {
355++ qWarning() << "No audio encoder found for MIME type" << m_audioEncodeControl->actualAudioSettings().codec();
356++ } else {
357++ g_object_set (G_OBJECT(m_camerabin),
358++ "audio-encoder",
359++ gst_element_factory_make(audioCodec.toLatin1(), NULL),
360++ NULL);
361++ }
362++
363++ QString containerFormat = findPlugin("Codec/Muxer", m_mediaContainerControl->actualContainerFormat());
364++ if (containerFormat.isEmpty()) {
365++ qWarning() << "No muxer found for MIME type" << m_mediaContainerControl->actualContainerFormat();
366++ } else {
367++ g_object_set (G_OBJECT(m_camerabin),
368++ "video-muxer",
369++ gst_element_factory_make(containerFormat.toLatin1(), NULL),
370++ NULL);
371++ }
372+
373+ setAudioCaptureCaps();
374+
375+@@ -1049,11 +1089,8 @@
376+ {
377+ QList< QPair<int,int> > res;
378+
379+- GstCaps *supportedCaps = 0;
380+- g_object_get(G_OBJECT(m_camerabin),
381+- SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY,
382+- &supportedCaps, NULL);
383+-
384++ GstCaps *supportedCaps;
385++ g_object_get(G_OBJECT(m_camerabin), SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY, &supportedCaps, NULL);
386+ if (!supportedCaps)
387+ return res;
388+
389+@@ -1161,10 +1198,12 @@
390+ *continuous = false;
391+
392+ GstCaps *supportedCaps = 0;
393+- g_object_get(G_OBJECT(m_camerabin),
394+- (mode == QCamera::CaptureStillImage) ?
395+- SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY : SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY,
396+- &supportedCaps, NULL);
397++
398++ if (mode == QCamera::CaptureStillImage) {
399++ g_object_get(G_OBJECT(m_camerabin), SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY, &supportedCaps, NULL);
400++ } else {
401++ g_object_get(G_OBJECT(m_camerabin), SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY, &supportedCaps, NULL);
402++ }
403+
404+ if (!supportedCaps)
405+ return res;
406+@@ -1235,10 +1274,9 @@
407+ res << maxSize;
408+ }
409+
410+-
411+ qSort(res.begin(), res.end(), resolutionLessThan);
412+
413+- //if the range is continuos, populate is with the common rates
414++ //if the range is continuous, populate is with the common rates
415+ if (isContinuous && res.size() >= 2) {
416+ //fill the ragne with common value
417+ static QList<QSize> commonSizes =
418+
419+=== modified file 'src/plugins/gstreamer/camerabin/camerabinsession.h'
420+--- a/src/plugins/gstreamer/camerabin/camerabinsession.h 2014-05-20 12:02:34 +0000
421++++ b/src/plugins/gstreamer/camerabin/camerabinsession.h 2014-05-20 12:53:53 +0000
422+@@ -195,6 +195,7 @@
423+ void setupCaptureResolution();
424+ void setAudioCaptureCaps();
425+ static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d);
426++ QString findPlugin(const QString &category, const QString &MIMEType) const;
427+
428+ QUrl m_sink;
429+ QUrl m_actualSink;
430+

Subscribers

People subscribed via source and target branches