tag:blogger.com,1999:blog-39333316720896036232024-03-13T08:08:46.935+05:30Ghosh blogVadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-3933331672089603623.post-10167829420651606212019-11-29T18:39:00.002+05:302019-11-29T19:23:37.919+05:30IllegalStateException: The specified child already has a parent<div dir="ltr" style="text-align: left;" trbidi="on">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #000000}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style> <br />
<div class="p1">
<span class="s1" style="font-family: "trebuchet ms" , sans-serif;">If your app suddenly starts crashing with the following exception, and you have ruled out the usual suspects, its probably due to an appcompat issue.</span><br />
<span class="s1"><br />
</span></div>
<div class="p1">
<code><span style="color: #666666;"> <span class="s1">java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first</span></span></code></div>
<br />
<span style="font-family: "trebuchet ms" , sans-serif;">I updated our andridx.appcompat version from 1.0.0 to 1.1.0 and was greeted with this crash. Unfortunately for me, that commit included multiple changes like enabling leak canary, updating the versions of various dependency libraries, and enabling multidex. So it took me some time to narrow down the offending change. The crash went away when I rolled back appcompat version to 1.0.0</span><br />
<h3 style="text-align: left;">
<span style="font-family: "trebuchet ms" , sans-serif;"><br /></span></h3>
<h3 style="text-align: left;">
<span style="font-family: "trebuchet ms" , sans-serif;">But I want to use the latest version of appcompat!</span></h3>
<span style="font-family: "trebuchet ms" , sans-serif;">In my case, the root cause was that we were reusing fragment's layout view object. In the first call to onCreateView, I'd inflate the layout xml and store the resulting view in a field. In the If the subsequent calls to this method, we would just return it instead of inflating again. Something like the following snippet. </span><br />
<br />
<pre style="background-color: white; font-family: Menlo-Regular;"><span style="font-size: x-small;"><span style="color: navy; font-weight: bold;">public </span>View onCreateView(LayoutInflater inflater,</span>
<span style="font-size: x-small;"> ViewGroup container, Bundle savedState) {
<span style="color: navy; font-weight: bold;">if </span>(<span style="color: #660e7a; font-weight: bold;">mFragmentView </span>!= <span style="color: navy; font-weight: bold;">null</span>) {
<span style="color: navy; font-weight: bold;">return </span><span style="color: #660e7a; font-weight: bold;">mFragmentView</span>;
}
<span style="color: #660e7a; font-weight: bold;">mFragmentView </span>= inflater.inflate(R.layout.<span style="color: #660e7a; font-style: italic; font-weight: bold;">fragment_main</span>, container, <span style="color: navy; font-weight: bold;">false</span>);</span>
<span style="font-size: x-small;"> <span style="color: navy; font-weight: bold;">return </span><span style="color: #660e7a; font-weight: bold;">mFragmentView</span>;
}</span><span style="font-size: 13.5pt;">
</span></pre>
<br />
<span style="font-family: "trebuchet ms" , sans-serif;">The crash happens when `mFragmentView` is not null. This happens whenever the user navigates back to this fragment using the back button. I removed that line so that we always inflated the layout, and it fixed the crash. Looks like reusing is not encouraged in this context. I was relying on this logic to preserve the fragment's state (text etc) in some cases, so I think it is time for a 'minor' refactoring.</span><br />
<div style="font-family: Times; white-space: normal;">
<span style="font-family: "trebuchet ms" , sans-serif;"><br />
</span></div>
<div style="font-family: Times; text-align: left; white-space: normal;">
<span style="font-family: "trebuchet ms" , sans-serif;">Removing the root view from its parent in onDestroyView also seems to work, but that sounds like cheating. I am going to keep that change on a branch until I figure out why appcompat team decided that we should not be reusing fragment layout objects like this. I couldn't find anything on StackOverflow that explains this behaviour. If you think reusing layouts is not a good idea, or know why appcompat changed its behaviour, please leave a comment.</span></div>
</div>
Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com0Belfast54.074012434389736 -2.562920950000034334.945518934389739 -43.871514950000034 73.202505934389734 38.745673049999965tag:blogger.com,1999:blog-3933331672089603623.post-83491615528004216302013-09-27T12:14:00.002+05:302013-09-27T12:48:56.876+05:30MP4 Viewer<div dir="ltr" style="text-align: left;" trbidi="on">MP4Viewer is an open-source ISO base media file format viewer. It parses the isobmf file and displays the metadata on the console or in a separate window. It is written in python and uses pygtk for displaying the box information in a window. MP4Viewer is <a href="https://github.com/amarghosh/mp4viewer" target="_blank">hosted in github</a><br />
<br />
<div style="text-align:center; margin:auto; width:100%;">Screenshots<br />
<div class="separator" style="clear:both; text-align: center; width:720; height:360;"><div style="float:left; "><a href="http://3.bp.blogspot.com/-APb-4LsE9LM/UkUoome4U4I/AAAAAAAADFk/ZkTpd7JkF24/s1600/mp4viewer_shell.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; float:left"><img border="0" height="319" src="http://3.bp.blogspot.com/-APb-4LsE9LM/UkUoome4U4I/AAAAAAAADFk/ZkTpd7JkF24/s320/mp4viewer_shell.png" width="320" /></a><br />
</div><div style="float:left; "><a href="http://2.bp.blogspot.com/-4Uu3eMfMPCQ/UkUpUrfTlKI/AAAAAAAADFs/pxQSh5U81lQ/s1600/mp4viewer_gtk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;float:left"><img border="0" height="320" src="http://2.bp.blogspot.com/-4Uu3eMfMPCQ/UkUpUrfTlKI/AAAAAAAADFs/pxQSh5U81lQ/s320/mp4viewer_gtk.png" width="320" /></a><br />
</div></div></div><div style="display:block; clear:both; margin-top:2em;">Usage: cd into <code>src</code> folder and run <br />
<pre class="brush: bash">$ ./showboxes.py [-h] [-o {stdout,gui}] [-e] [-c {on,off}] iso-base-media-file
Positional arguments:
iso-base-media-file Path to iso media file
Optional arguments:
-o {stdout,gui} Select output format (console or windows). Default is console.
TODO: Add XML output
-c {on,off} Turn on/off colors in stdout; on by default.
-e Long arrays such as sample sizes are truncated by default.
This flag expands them.
-h, --help Help!
</pre><br />
You need to have pygtk2.0 installed for viewing the results in a window.<br />
<br />
The definitions of structures used in the code can be found in the publicly available standard <a href="http://standards.iso.org/ittf/PubliclyAvailableStandards/index.html">ISO/IEC 14496-12 - ISO base media file format</a><br />
</div></div>Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com2tag:blogger.com,1999:blog-3933331672089603623.post-43545683442939595602012-08-23T22:23:00.000+05:302015-12-24T13:36:10.798+05:30Search+<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white;"><span style="font-family: arial, sans-serif;"><span style="line-height: 1.25em;">When I am not writing code, I find myself going through log files trying to make some sense out of it... er, unless I am browsing Reddit or Facebook, but I digress. The editor of choice is notepad++ as it is powerful and lightweight. However, the search functionality in notepad++ sometimes fails to meet my needs as I end up searching for a word, bookmark it and search for another word from that point, and then a third one from there and so on until I give up and copy the file to a Linux machine and grep for it in a loop</span><span style="line-height: 1.25em;">. Things would be easier if one could search for multiple keywords at the same time and filter out the matching lines in npp itself. Maybe it is my poor googfu, but I couldn't find anything that would let me do that; but what I did find was that notepad++ provides a nice <a href="http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=Messages_And_Notifications">plugin interface</a> with a <a href="http://www.scintilla.org/ScintillaDoc.html">decent documentation</a>. So I decided to get my hands dirty and write a plugin that does this. I have been using it for sometime and found it helpful so I thought I'd share it.</span></span></span><br />
<div style="background-color: white; font-family: arial, sans-serif; line-height: 1.25em; max-width: 64em;">
<br /></div>
<div style="background-color: white; font-family: arial, sans-serif; line-height: 1.25em; max-width: 64em;">
As described above, Search+ is a notepad++ plugin that lets you search for multiple keywords in a single shot. You can specify a list of patterns and filter out all lines from the current document that match any of the keywords in that list.</div>
<ul style="background-color: white; font-family: arial, sans-serif; max-width: 62em; padding-left: 25px; text-align: left;">
<li style="margin-bottom: 0.3em;">Keywords are interpreted as regex</li>
<li style="margin-bottom: 0.3em;">Search is case insensitive</li>
<li style="margin-bottom: 0.3em;">Matching lines are listed in a separate ListBox</li>
<li style="margin-bottom: 0.3em;">Option to highlight matched strings in the original document</li>
</ul>
<div>
<span style="font-family: arial, sans-serif;">Here is a screenshot of the plugin in action</span><sub><span style="font-size: xx-small;">(click the image for full size)</span>.</sub></div>
<div>
<span style="font-family: arial, sans-serif;"><br />
</span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-9vB1IuQWAxA/UDZH5fC3jCI/AAAAAAAACEs/QwVRpOSb_gQ/s1600/searchplus.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="139" src="http://1.bp.blogspot.com/-9vB1IuQWAxA/UDZH5fC3jCI/AAAAAAAACEs/QwVRpOSb_gQ/s320/searchplus.png" width="320" /></a></div>
<div>
<br /></div>
<ul style="background-color: white; font-family: arial, sans-serif; max-width: 62em; padding-left: 25px; text-align: left;">
<li><span style="line-height: 1.25em;">You can download Search+ from </span><a href="http://code.google.com/p/searchplus/downloads/list" style="line-height: 1.25em;">Google code</a></li>
<li><span style="line-height: 1.25em;">For more information regarding installation and usage, </span><a href="http://code.google.com/p/searchplus/wiki/Installation" rel="nofollow" style="color: #0000cc; line-height: 1.25em;">read this wiki</a><span style="line-height: 1.25em;"> page.</span></li>
<li>Search+ is written in C++ and this is kinda my first work in that language. Feel f<span style="line-height: 1.25em;">ree to b</span><span style="line-height: 1.25em;">rowse the </span><a href="http://code.google.com/p/searchplus/source/browse/trunk" style="line-height: 1.25em;">source code</a> and point out any issues there :-)</li>
</ul>
<div style="background-color: white; font-family: arial, sans-serif; line-height: 1.25em; max-width: 64em;">
In case of any issues or suggestions, please leave a comment here. And if you find this useful, do spread the word.</div>
<br />
<div style="background-color: white; font-family: arial, sans-serif; line-height: 1.25em; max-width: 64em;">
<i>Update (December 2015):</i> The project was initially hosted in google code; back then, you could just download the dll and put it in the npp plugins folder to install this. After moving the hosting to github when google discontinued their code hosting service, I haven't had a chance to add compiled dll to github. As of now, you'd have to download the source code and compile it yourself. I don't have access to windows compiler as I am working in Linux nowadays.</div>
</div>
Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com30tag:blogger.com,1999:blog-3933331672089603623.post-49367986844264966322012-01-13T23:35:00.000+05:302012-01-13T23:35:56.820+05:30gstreamer appsrc in action<div dir="ltr" style="text-align: left;" trbidi="on">
Lately I have been exploring gstreamer to play AV from a transport stream demultiplexer that I am developing (mostly for fun, slightly for work). After some research (read googling for play video using gstreamer), I concluded that <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html">gstreamer-appsrc</a> is the way to go. Since I had a hard time finding a working example in the Internet on using this plugin, I thought I would share my test application here. If you are new to gstreamer, keep in mind that I am only couple of days ahead of you and I might have overlooked or missed even basic things in this post; and if you in fact know gstreamer, feel free to mention any such omissions you notice here so that I can correct them.<br />
<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
Here is a quick intro to gstreamer for new comers. It is a media framework based on plugins - you can read <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/part-introduction.html">all about gstreamer here</a>. That page says prior knowledge of glib and gobject is assumed; while proper knowledge of these two will help you progress faster, I didn't know either and I survived. The point is, you can (and you have to) learn those parallelly. In a nutshell, you work on a gstreamer <i>pipeline </i>which is basically a series of plugins where each one takes its input from the previous plugin, does something with it and gives the output to the next one. The data is passed around in <i>buffers </i>through the <i>source </i>and <i>sink pads </i>of the plugins. Usually at the left end of a pipeline there will be a pure source (like filesrc that reads data from a file and feeds the pipeline) and the last one would be a pure sink that plays the media. The typical steps in creating a gstreamer based player can be summarized as:<br />
<ol style="text-align: left;">
<li>Create your elements and set their properties, signal handlers and callbacks</li>
<li>Add them to a bin (pipeline is a bin)</li>
<li>Get a reference to the bin's bus and add bus callback for messages - at the minimum, an application should handle error messages and end of stream messages so as to stop the main loop on error and <i>eos</i>.</li>
<li>Link their source and sink pads in the correct order</li>
<li>Set the state of bin to playing and start the glib main loop.</li>
</ol>
You can find a <a href="http://felipec.wordpress.com/2008/01/19/gstreamer-hello-world/">gstreamer helloworld application and its explanation here</a>. It uses a playbin, a readymade pipeline that does most of the work for us. It is good enough as long as you are not producing any media. But if you are producing some media data in your application and you need to play it using gstreamer, you need a way to feed this data to the pipeline. That is where <i>appsrc </i>comes into picture. The appsrc element allows applications to inject buffers into a pipeline.<br />
<br />
There is this <a href="https://gist.github.com/725122/16ceee88aafae389bab207818e0661328921e1ab">gstreamer appsrc example code</a> in github, but unfortunately it didn't work for me - and based on the comment in that page, I am not the only one. It uses udpsink to stream data over a network. Since I just wanted to play it on my desktop, I replaced it with an xvimagesink which is used by most of the desktop based gstreamer video examples. But that didn't make any difference either - whenever I run the code, it exits with the following error:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">ERROR from element mysource: Internal data flow error.</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Debugging info: gstbasesrc.c(2582): gst_base_src_loop (): /GstPipeline:pipeline0/GstAppSrc:mysource:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">streaming task paused, reason not-negotiated (-4)</span><br />
<br />
As usual I resorted to <a href="http://stackoverflow.com/questions/8746719/gstreamer-appsrc-test-application">StackOverflow for an answer</a>, but apparently there aren't many gstreamer enthusiasts roaming in there. After earning my first <a href="http://stackoverflow.com/badges/63/tumbleweed">tumbleweed badge</a> for this question, I decided to do it myself. I started with this <a href="http://www.offminor.de/gstreamer-avi.html">simple gstreamer AVI player</a>. It uses the following pipeline:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">filesrc -> avidemux -> decodebin -> customfilter -> ffmpegcolorspace -> videoscale -> autovideosink </span><br />
<br />
This pipeline is sort of self explanatory. The <i>filesrc </i>reads the avi file and passes the data to the demux where it gets split into audio and video. To keep things short, let us ignore audio. The video data is decoded in <i>decodebin </i>and the raw data is processed further and displayed using the last three plugins (gotta admit that I don't know nittygritties of those three; there are detailed websites out there explaining them - help yourself). If you look at the code in that page, you can see that not all the elements are linked together at the beginning. This is because in some plugins the source (output) pads are created dynamically based on the input data. So you have to listen for appropriate signals like <i>pad-added</i> on such elements and do the linking from the callbacks.<br />
<br />
Since we are dealing with mpeg video, we don't need <i>avidemux</i>. And we can replace <i>videoscale </i>and <i>autovideosink </i>with an <i>xvimagesink </i>for the sake of brevity. So it comes down to replacing <i>filesrc </i>with an <i>appsrc </i>and feeding the data to the decoder. Let us create the elements:<br />
<br />
<pre class="brush: c">/* Start by creating a new pipeline and the elements */
app->pipeline = (GstPipeline*)gst_pipeline_new("mypipeline");
/* Add bus callback */
bus = gst_pipeline_get_bus(app->pipeline);
gst_bus_add_watch(bus, (GstBusFunc)bus_callback, app);
gst_object_unref(bus);
/* Add signal handlers on appsrc */
g_signal_connect(app->src, "need-data", G_CALLBACK(start_feed), app);
g_signal_connect(app->src, "enough-data", G_CALLBACK(stop_feed), app);
/* Create the elements */
app->src = (GstAppSrc*)gst_element_factory_make("appsrc", "mysrc");
app->decoder = gst_element_factory_make("decodebin", "mydecoder");
app->ffmpeg = gst_element_factory_make("ffmpegcolorspace", "myffmpeg");
app->xvimagesink = gst_element_factory_make("xvimagesink", "myvsink");
/* Add elements to the pipeline */
gst_bin_add_many(GST_BIN(app->pipeline), (GstElement*)app->src, app->decoder, app->ffmpeg, app->xvimagesink, NULL);
/* Link them together - this should be done after adding to the bin */
if(!gst_element_link((GstElement*)app->src, app->decoder)){
g_warning("failed to link src anbd decoder");
}
if(!gst_element_link(app->ffmpeg, app->xvimagesink)){
g_warning("failed to link ffmpeg and xvsink");
}
/* Note that we haven't linked decoder to color-space element
- that's done from pad-added signal callback. */
g_signal_connect(app->decoder, "pad-added", G_CALLBACK(on_pad_added), app->decoder);
</pre>
<br />
Applications can feed the data to appsrc plugin using two methods; by calling gst_app_src_push_buffer function or by emitting push-buffer signals. I used the first approach since I am not fluent with signals and it gave intermittent warning messages while running. We start by writing a read_data function that reads chunks of data from a global file pointer and creates a GstBuffer and pushes them to the appsrc.<br />
<br />
<pre class="brush: c">static gboolean read_data(gst_app_t *app)
{
GstBuffer *buffer;
guint8 *ptr;
gint size;
GstFlowReturn ret;
ptr = g_malloc(BUFF_SIZE);
g_assert(ptr);
size = fread(ptr, 1, BUFF_SIZE, app->file);
if(size == 0){
ret = gst_app_src_end_of_stream(app->src);
g_debug("eos returned %d at %d\n", ret, __LINE__);
return FALSE;
}
buffer = gst_buffer_new();
GST_BUFFER_MALLOCDATA(buffer) = ptr;
GST_BUFFER_SIZE(buffer) = size;
GST_BUFFER_DATA(buffer) = GST_BUFFER_MALLOCDATA(buffer);
ret = gst_app_src_push_buffer(app->src, buffer);
if(ret != GST_FLOW_OK){
g_debug("push buffer returned %d for %d bytes \n", ret, size);
return FALSE;
}
if(size != BUFF_SIZE){
ret = gst_app_src_end_of_stream(app->src);
g_debug("eos returned %d at %d\n", ret, __LINE__);
return FALSE;
}
return TRUE;
}
</pre>
<br />
The appsrc element emits mainly two signals namely <i>need-data</i> and <i>enough-data</i> to tell the application to start and stop feeding data. We need to listen to these callbacks. In the need-data callback, we add our read_data function as an idle handler to the main loop. The glib main loop will call this function from its main loop. When appsrc emits enough-data signal, we just remove this idle handler so that it is not called anymore. The boolean return value of read_data function is used by the main loop to decide whether to call it in the future - so we should return FALSE in case of any errors in pushing the data or we reach end of file.<br />
<br />
<pre class="brush: c">static void start_feed (GstElement * pipeline, guint size, gst_app_t *app)
{
if (app->sourceid == 0) {
/* add idle handle to the main loop */
app->sourceid = g_idle_add ((GSourceFunc) read_data, app);
}
}
static void stop_feed (GstElement * pipeline, gst_app_t *app)
{
if (app->sourceid != 0) {
GST_DEBUG ("stop feeding");
g_source_remove (app->sourceid);
app->sourceid = 0;
}
}
</pre>
<br />
Now, start the pipeline, create a main loop and run it<br />
<pre class="brush: c">gst_element_set_state((GstElement*)app->pipeline, GST_STATE_PLAYING);
app->loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(app->loop);
/* the previous call will return when we call quit from bus_callback -
set the pipeline to null to do the cleanup */
gst_element_set_state((GstElement*)app->pipeline, GST_STATE_NULL);
</pre>
<br />
<br />
And that's it, we got appsrc working. The source should be compiled using appropriate cflags and libs - you can use package config for getting them.<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">gcc -o testapp gst-testapp.c `pkg-config --cflags --libs gstreamer-0.10 gstreamer-app-0.10`</span><br />
<br />
If you get compiler or linker errors related to gstreamer, you probably don't have the necessary gstreamer development libraries installed. You can apt-get them using:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">sudo apt-get install libgstreamer0.10-dev</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">sudo apt-get install libgstreamer-plugins-base0.10-dev</span><br />
<br />
Here is the full source code.<br />
<br />
<pre class="brush: c">/*
I don't know if it is syntax highlighter or blogger, but I can't seem to
put angle brackets around header file names properly.
*/
#include stdio.h
#include gst/gst.h
#include gst/app/gstappsrc.h
typedef struct {
GstPipeline *pipeline;
GstAppSrc *src;
GstElement *sink;
GstElement *decoder;
GstElement *ffmpeg;
GstElement *xvimagesink;
GMainLoop *loop;
guint sourceid;
FILE *file;
}gst_app_t;
static gst_app_t gst_app;
#define BUFF_SIZE (1024)
static gboolean read_data(gst_app_t *app)
{
GstBuffer *buffer;
guint8 *ptr;
gint size;
GstFlowReturn ret;
ptr = g_malloc(BUFF_SIZE);
g_assert(ptr);
size = fread(ptr, 1, BUFF_SIZE, app->file);
if(size == 0){
ret = gst_app_src_end_of_stream(app->src);
g_debug("eos returned %d at %d\n", ret, __LINE__);
return FALSE;
}
buffer = gst_buffer_new();
GST_BUFFER_MALLOCDATA(buffer) = ptr;
GST_BUFFER_SIZE(buffer) = size;
GST_BUFFER_DATA(buffer) = GST_BUFFER_MALLOCDATA(buffer);
ret = gst_app_src_push_buffer(app->src, buffer);
if(ret != GST_FLOW_OK){
g_debug("push buffer returned %d for %d bytes \n", ret, size);
return FALSE;
}
if(size != BUFF_SIZE){
ret = gst_app_src_end_of_stream(app->src);
g_debug("eos returned %d at %d\n", ret, __LINE__);
return FALSE;
}
return TRUE;
}
static void start_feed (GstElement * pipeline, guint size, gst_app_t *app)
{
if (app->sourceid == 0) {
GST_DEBUG ("start feeding");
app->sourceid = g_idle_add ((GSourceFunc) read_data, app);
}
}
static void stop_feed (GstElement * pipeline, gst_app_t *app)
{
if (app->sourceid != 0) {
GST_DEBUG ("stop feeding");
g_source_remove (app->sourceid);
app->sourceid = 0;
}
}
static void on_pad_added(GstElement *element, GstPad *pad)
{
GstCaps *caps;
GstStructure *str;
gchar *name;
GstPad *ffmpegsink;
GstPadLinkReturn ret;
g_debug("pad added");
caps = gst_pad_get_caps(pad);
str = gst_caps_get_structure(caps, 0);
g_assert(str);
name = (gchar*)gst_structure_get_name(str);
g_debug("pad name %s", name);
if(g_strrstr(name, "video")){
ffmpegsink = gst_element_get_pad(gst_app.ffmpeg, "sink");
g_assert(ffmpegsink);
ret = gst_pad_link(pad, ffmpegsink);
g_debug("pad_link returned %d\n", ret);
gst_object_unref(ffmpegsink);
}
gst_caps_unref(caps);
}
static gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer *ptr)
{
gst_app_t *app = (gst_app_t*)ptr;
switch(GST_MESSAGE_TYPE(message)){
case GST_MESSAGE_ERROR:{
gchar *debug;
GError *err;
gst_message_parse_error(message, &err, &debug);
g_print("Error %s\n", err->message);
g_error_free(err);
g_free(debug);
g_main_loop_quit(app->loop);
}
break;
case GST_MESSAGE_WARNING:{
gchar *debug;
GError *err;
gchar *name;
gst_message_parse_warning(message, &err, &debug);
g_print("Warning %s\nDebug %s\n", err->message, debug);
name = GST_MESSAGE_SRC_NAME(message);
g_print("Name of src %s\n", name ? name : "nil");
g_error_free(err);
g_free(debug);
}
break;
case GST_MESSAGE_EOS:
g_print("End of stream\n");
g_main_loop_quit(app->loop);
break;
case GST_MESSAGE_STATE_CHANGED:
break;
default:
g_print("got message %s\n", \
gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
break;
}
return TRUE;
}
int main(int argc, char *argv[])
{
gst_app_t *app = &gst_app;
GstBus *bus;
GstStateChangeReturn state_ret;
if(argc != 2){
printf("File name not specified\n");
return 1;
}
app->file = fopen(argv[1], "r");
g_assert(app->file);
gst_init(NULL, NULL);
app->pipeline = (GstPipeline*)gst_pipeline_new("mypipeline");
bus = gst_pipeline_get_bus(app->pipeline);
gst_bus_add_watch(bus, (GstBusFunc)bus_callback, app);
gst_object_unref(bus);
app->src = (GstAppSrc*)gst_element_factory_make("appsrc", "mysrc");
app->decoder = gst_element_factory_make("decodebin", "mydecoder");
app->ffmpeg = gst_element_factory_make("ffmpegcolorspace", "myffmpeg");
app->xvimagesink = gst_element_factory_make("xvimagesink", "myvsink");
g_assert(app->src);
g_assert(app->decoder);
g_assert(app->ffmpeg);
g_assert(app->xvimagesink);
g_signal_connect(app->src, "need-data", G_CALLBACK(start_feed), app);
g_signal_connect(app->src, "enough-data", G_CALLBACK(stop_feed), app);
g_signal_connect(app->decoder, "pad-added",
G_CALLBACK(on_pad_added), app->decoder);
gst_bin_add_many(GST_BIN(app->pipeline), (GstElement*)app->src,
app->decoder, app->ffmpeg, app->xvimagesink, NULL);
if(!gst_element_link((GstElement*)app->src, app->decoder)){
g_warning("failed to link src anbd decoder");
}
if(!gst_element_link(app->ffmpeg, app->xvimagesink)){
g_warning("failed to link ffmpeg and xvsink");
}
state_ret = gst_element_set_state((GstElement*)app->pipeline, GST_STATE_PLAYING);
g_warning("set state returned %d\n", state_ret);
app->loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(app->loop);
state_ret = gst_element_set_state((GstElement*)app->pipeline, GST_STATE_NULL);
g_warning("set state null returned %d\n", state_ret);
return 0;
}
</pre>
<br />
This just shows <i>appsrc</i> in action - the real work is integrating it with your application. Remember that g_main_loop_run will return only when you call g_main_loop_quit - so you might want to call it from its own thread.<br />
<br />
If you find it helpful or wrong, please share your feedback.<br />
<br /></div>
</div>Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com32tag:blogger.com,1999:blog-3933331672089603623.post-71880215703703043382010-10-06T22:10:00.000+05:302010-10-06T22:10:15.100+05:30Redmine, Apache and passenger<p>We've been running <a href="http://www.redmine.org/">Redmine</a> on Apache2 with <a href="http://www.modrails.com/">mode-passenger</a> for a while. Everything was running smooth until yesterday, when we installed PHP and PostgreSQL on the same server. Redmine started giving <i>Connection refused</i> messages upon installing these. I promptly restarted Apache, to see the following error message:</p><code>Invalid command 'RailsEnv', perhaps misspelled or defined by a module not included in the server configuration</code><br/>
<p>Staring at Apache configuration files for half an hour didn't really help, as I hardly know anything about them. I resorted to Google as usual and it took a while to figure out the issue. Apparently, the passenger module somehow got disabled when PHP and PostgreSQL were installed. Thanks to <a href="http://www.redmine.org/boards/2/topics/5254">this page in Redmine forums</a>, I was able to fix it by enabling it back. Just in case anyone have the same issue, here's how to do it:</p>
<pre class="brush: bash">
# install passenger (if you don't have it already). I'm sure I already had
# it installed, but the apt-get downloaded and installed it again.
# I say do it anyway.
sudo apt-get install libapache2-mod-passenger
#enable passenger explicitly
sudo a2enmod passenger
#restart apache
sudo /etc/init.d/apache2 restart
# Check redmine:
# Still not working....? I'm sorry, the problem is somewhere else :(
</pre>Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com3tag:blogger.com,1999:blog-3933331672089603623.post-30242722956627206512010-01-06T17:07:00.003+05:302010-01-06T17:20:33.749+05:30Icons in Flex MenuBar<p>I came across this strange behavior (I'm not sure if it qualifies to be called a bug, but it definitely is not a feature) in Flex while trying to add icons to the <code>MenuBar</code> control.</p><p>The icons are displayed properly if both the <code>MenuBar</code> and the icon-embed variables are declared in the main application class. But if they are nested inside another component, only the top level menu-items' icons are displayed - child menu items' icons are not displayed.</p><p>After some debugging I realized that only the top-level menu items are displayed using the <code>itemToIcon</code> method of the <code>MenuBar</code> class; child menu-items are displayed using the <code>itemToIcon</code> method of the <code>Menu</code> class. The problem here is that even though both of these methods use <code>document[data[iconField]]</code> to grab the icon-embed class, the <a href="http://livedocs.adobe.com/flex/3/langref/mx/core/UIComponent.html#document"><code>document</code></a> properties of these two objects point to different items. The <code>document</code> property of the <code>MenuBar</code> points correctly to the enclosing component (<code>MyPanel</code>). Whereas, for some reason that I don't understand, the <code>document</code> property for nested <code>Menu</code> points to the <code>MainApplication</code> class.</p><p><strong>In short</strong>, while rendering icons of a <code>MenuBar</code> within a component, flex searches the component class for icons of top-level menu items, and the main-application class for icons of its nested menu items. The obvious workaround is to embed all icons to <code>public static const</code> in some class and to keep appropriate references to them in both application and component classes. But that doesn't sound so pretty to me (even though that's what I am doing now). Does anyone know better?</p><p>Here is example code and screenshots to demonstrate the issue:</p><pre class="brush: html"><!--The main Application class-->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
creationComplete="create()" xmlns:local="*">
<mx:Label text="MenuBar in the Application works fine"/>
<mx:MenuBar id="menuBar" top="10" left="10"
dataProvider="{menuBarCollection}" labelField="@label"
iconField="@icon" />
<local:MyPanel/>
<mx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
[Bindable]
protected var menuBarCollection:XMLListCollection;
[Embed(source="assets/icon_one.png")]
public var iconOne_App:Class;
[Embed(source="assets/icon_two.png")]
public var iconTwo_App:Class;
private function create():void
{
menuBarCollection = new XMLListCollection(XMLList(
'<menuitem label="One" icon="iconOne_App">' +
'<menuitem label="Two" icon="iconTwo_App"/>' +
'<menuitem label="Three" icon="iconTwo_App"/>' +
'</menuitem>'
));
}
]]>
</mx:Script>
</mx:Application>
</pre>
<p style="text-align: center;"><img src="http://lh4.ggpht.com/_dMvpiHJOOxw/S0RC_szZ8MI/AAAAAAAAA4w/qJ-E5EgRH70/menu1.jpg" alt="MenuBar in the Application" title="MenuBar directly in the Application" /></p><pre class="brush: html">
<!--MyPanel.mxml-->
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" height="144"
creationComplete="create();" horizontalAlign="center" verticalAlign="middle">
<mx:Text text="MenuBar inside a component doesn't display icons properly"/>
<mx:MenuBar id="menuBar" top="10" left="10"
dataProvider="{menuBarCollection}" labelField="@label"
iconField="@icon" />
<mx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
[Bindable]
protected var menuBarCollection:XMLListCollection;
[Embed(source="assets/icon_one.png")]
public var iconOne_Panel:Class;
[Embed(source="assets/icon_two.png")]
public var iconTwo_Panel:Class;
private function create():void
{
menuBarCollection = new XMLListCollection(XMLList(
//top level item referring to component
//this icon is displayed
'<menuitem label="ParentIcon_panel" icon="iconOne_Panel">' +
//nested item referring to component
//this icon is not displayed
'<menuitem label="ChildIcon_panel" icon="iconTwo_Panel"/>' +
//nested item referring to application
//this icon is displayed
'<menuitem label="ChildIcon-app" icon="iconTwo_App"/>' +
'</menuitem>' +
//top level item referring to Application
//this icon is not displayed
'<menuitem label="ParentIcon_app" icon="iconOne_App"/>'
));
}
]]>
</mx:Script>
</mx:Panel>
</pre>
<p style="text-align: center;"><img src="http://lh4.ggpht.com/_dMvpiHJOOxw/S0RC_iZtE2I/AAAAAAAAA40/3F7-6NUiHzg/menu2.jpg" alt="MenuBar inside a Component" title="MenuBar inside a Component" /></p>Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com10tag:blogger.com,1999:blog-3933331672089603623.post-30225844671431273692009-11-18T22:10:00.006+05:302009-11-18T22:44:12.196+05:30Generating getters and setters in Flex Builder<span style="font-weight:bold;">Fine print:</span> <span style="font-style:italic;">This post discusses not so thoroughly tested regexes that the author used to edit his source code (and to fulfill his newly found affection for exploring regular expressions). Author cannot be held responsible or abused for the damages that these regexes might incur to your code and/or job.</span>
Eclipse has this cool feature that lets you generate getters and setters for the variables in your source code. Flex Builder 3, though based on Eclipse platform, doesn't have such an option. For those interested, here is a way to generate get and set methods for your <code>ActionScript</code> <code>private/protected</code> variables using the inbuilt Find/Replace and regular expressions.
Though it assumes that you're using tabs for indenting the code (which is the default in FB), you can modify it for spaces easily. Open the Find/Replace window (<code>Ctrl-F</code>) and add the following regular expression to the Find field.<p><pre style="background-color:#EEEEEE;margin-bottom:10px;overflow:auto;padding:5px;width:auto;"><code style="white-space:nowrap;">^((\t)+)(?:private|protected)\s+var\s+_(\w+):(\w+)\s*;\s*(\n)</code></pre></p>Now add the following pattern to the Replace field.
<p><pre style="background-color:#EEEEEE;margin-bottom:10px;overflow:auto;padding:5px;width:auto;"><code style="white-space:nowrap;">$0$5$1public function set $3(value:$4):void$5$1{$5$1$2_$3 = value;$5$1}$5$5$1public function get $3():$4$5$1{$5$1$2return _$3;$5$1}$5$5</code></pre></p>Don't forget to select the Regular expressions check box in the options box. The replace pattern doesn't accept any meta characters other than $, and hence we need to capture a tab and a new-line using the regex itself.
Now use the Find, (<code>Alt-N</code>), Replace (<code>Alt-R</code>) and Replace/Find (<code>Alt-D</code>) to generate get and set methods for the required properties. If you want to generate get/set methods for all the <code>private/protected</code> variables in your class - and you're really courageous, use Replace All (<code>Alt-A</code>).Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com4tag:blogger.com,1999:blog-3933331672089603623.post-10491502650808886022009-10-27T21:45:00.003+05:302014-06-13T14:40:28.869+05:30StackOverflow Reputation Tracker<div dir="ltr" style="text-align: left;" trbidi="on">Did I say that I've gotten addicted to <a href="http://stackoverflow.com/">StackOverflow</a>? Here is a snippet of shell script to check your <code>StackOverflow</code> reputation from the comfort of your Linux console. Replace <i>165297</i> with your user ID. <br />
<pre class="brush: bash">#!/bin/sh
json=$(curl -s http://stackoverflow.com/users/flair/165297.json)
echo $json | sed 's/.*"reputation":"\([0-9,]\{1,\}\)".*/\1/' | sed s/,//
</pre>Haven't tested this for other sites in the trilogy, but I believe this would work for all the three sites and also the meta. Now onto writing an AIR app that would track reps and alert about new questions with your favorite tags... :)</div>Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com0tag:blogger.com,1999:blog-3933331672089603623.post-86398468026370216542009-04-03T16:59:00.010+05:302009-04-03T19:29:46.405+05:30VerifyError 1102<span style="color: rgb(255, 0, 0);">VerifyError: Error #1102: Illegal default value for type *</span>
If you ever get this rather unusual run-time error, here's what to do.
If you are using default values for arguments in a method's declaration part, make sure that the types match well. For instance, I wanted to explicitly call an event handler from the code and hence used null as the default value for the event parameter - only I typed it <span style="font-style: italic;">false</span> instead of <span style="font-style: italic;">null</span> (yeah, its Friday evening here). I don't know why the compiler thinks its okay to assign false (or a String or AnyThing) to an Event variable.
<code><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 127, 0);">function</span> init(<span style="text-decoration: underline;">e:Event = <span style="color: rgb(0, 0, 255);">false</span></span>):<span style="color: rgb(0, 0, 255);">void</span></code>
So check your code for something silly like this, fix it and you are good to go.
This run-time error is strange because <a href="http://livedocs.adobe.com/flex/3/langref/VerifyError.html" title="VerifyError (Flex 3.3)">livedocs</a> says that "The VerifyError class represents an error that occurs when a malformed or corrupted SWF file is encountered". So you conclude that the SWF is having its issues on the Friday evening and rebuild the project to fix it. But no matter what you do to fix the "corrupted" SWF, you will get the same error again and again.
Also, Flex doesn't show the corresponding MXML/AS file name or the line of code that caused this error, which it normally does with errors. It in fact traces the call stack, but that's not quite useful. One would normally expect the bug to be in the top most method of the call stack or in a method called from that. But here it seems that the top most method in the stack trace is the method that accesses <span style="font-weight: bold;">any</span> method/property from the buggy class for the first time in application. Adobe's <a href="http://livedocs.adobe.com/flex/3/langref/runtimeErrors.html#1102">documentation</a> on Flex run-time errors says that "ActionScript in the SWF is invalid. If you believe that the file has not been corrupted, please report the problem to Adobe." - not really helpful either.
But fortunately this is not even a run-time error - or this wouldn't have been one, had the compiler done its job well. And it turns out that the error message - Illegal default value for type * - is in fact correct.
Compiler will detect wrong assignments in the case of basic types. For instance, if it was <code>function(t:String = 3)</code> you will get a compiler error <code>1184: Incompatible default value of type int where String is expected</code> along with file name and the exact line of code that went wrong. But if its anything other than basic types, compiler just ignores it and you get this scary "malformed SWF".
Hope this helps someone.
<div style="text-align: right;"><code>Links added with <a href="http://www.cdacbangalore.in/%7Eamarghosh/LinkIt/">LinkIt</a></code></div>Vadakkoothttp://www.blogger.com/profile/13275601115835915939noreply@blogger.com8tag:blogger.com,1999:blog-3933331672089603623.post-3835272580567750682009-02-25T14:38:00.005+05:302009-04-06T10:18:53.391+05:30Hello WorldThis, ladies and gentlemen, would be my <span style="font-style:italic;">attempted</span> English blog. (I am <span style="font-style:italic;">attempting</span> one in Malayalam <a href="http://vadakkoodan.blogspot.com/" title="അമരകോശം">here</a>). Be warned that this is the first time I am writing anything completely by myself in English - other than exam papers and assignments, of course. Err, I can't really make that claim - quite a few of them were actually not <span style="font-style:italic;">completely written by myself</span> ;)
The first question that I had upon deciding to start this blog was what would I write about, and unfortunately that still remains unanswered. Normally new bloggers complain about not having anything to write about after few posts; but I'm doing that in my very first post itself - quite impressive, isn't it?
I guess I would start by jotting down some FYIs about Flash/Flex that I had to learn the hard way.
<div style="text-align: right;"><code>Links added with <a href="http://www.cdacbangalore.in/%7Eamarghosh/LinkIt/">LinkIt</a></code></div>Unknownnoreply@blogger.com2