Administrator
|
My application adds an uridecodebin instance to the pipeline, and then removes it, if the element doesn't go to the paused state (this can happen, if a non-media file was supplied to the uridecodebin) and returns GST_STATE_CHANGE_FAILURE.
I call gst_object_unref(uridecodebin_inst); uridecodebin_inst=NULL; after the removal. And the problem is that my application sometimes crashes with the system error message saying, it attempted writing to the location 0x0000010. Or, the location 0xfeeefef6. I am using MS Visual Studio 2008, and the latter address is very close to the 0xfeeefeee - the value, CRT fills the just released memory. Call stack is useless, it contains only some addresses in the GLib DLL and in windows system libraries. I suspect, this is because the bus contains some messages related to the recently removed uridecodebin. How can I flush these messages or wait for finishing of all threads, related to the element removal? |
Administrator
|
On Thu, 2010-04-22 at 22:52 -0800, wl2776 wrote:
> My application adds an uridecodebin instance to the pipeline, and then > removes it, if the element doesn't go to the paused state (this can happen, > if a non-media file was supplied to the uridecodebin) and returns > GST_STATE_CHANGE_FAILURE. > > I call > gst_object_unref(uridecodebin_inst); > uridecodebin_inst=NULL; > after the removal. Have you set uridecodebin to NULL before removing it ? Have you made sure it didn't connect to anything ? Did you hold an extra reference to uridecodebin before adding it to the pipeline (if not, the pipeline *stole* your reference and you shouldn't have to unref it after removing it from the pipeline). > > And the problem is that my application sometimes crashes with the system > error message saying, it attempted writing to the location 0x0000010. Or, > the location 0xfeeefef6. > I am using MS Visual Studio 2008, and the latter address is very close to > the 0xfeeefeee - the value, CRT fills the just released memory. > Call stack is useless, it contains only some addresses in the GLib DLL and > in windows system libraries. Those addresses are really useful... *NOT* ! > > I suspect, this is because the bus contains some messages related to the > recently removed uridecodebin. Most likely due to the double-unreferencing I explained above. > > How can I flush these messages or wait for finishing of all threads, related > to the element removal? > ------------------------------------------------------------------------------ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
Administrator
|
The exact code. while(<have a file in a directory and no video or audio stream>) { gboolean rb=FALSE; uridecodebin[1]=gst_element_factory_make("uridecodebin", (m_video_present)?"audio_decodebin":"video_decodebin"); if(uridecodebin[1]) rb=gst_bin_add(GST_BIN(m_player),uridecodebin[1]); if(rb){ g_object_set(G_OBJECT(uridecodebin[1]),"uri",file_uri,NULL); h_id2=g_signal_connect(G_OBJECT(uridecodebin[1]),"no-more-pads", G_CALLBACK(no_more_pads_cb),this); h_id3=g_signal_connect(G_OBJECT(uridecodebin[1]),"unknown-type", G_CALLBACK(unknown_type_cb),this); rs=gst_element_set_state(m_player,GST_STATE_PAUSED); while(m_player->current_state!=GST_STATE_PAUSED && !(m_flags & FLAG_DORENDER_COMPLETE) && rs!=GST_STATE_CHANGE_FAILURE){ g_usleep(100000); } g_signal_handler_disconnect(G_OBJECT(uridecodebin[1]),h_id2); g_signal_handler_disconnect(G_OBJECT(uridecodebin[1]),h_id3); if(rs==GST_STATE_CHANGE_FAILURE){ gst_element_set_state(GST_ELEMENT(m_player),GST_STATE_NULL); gst_bin_remove(GST_BIN(m_player),uridecodebin[1]); gst_object_unref(uridecodebin[1]); uridecodebin[1]=NULL; } } } So, yes, I've put the uridecodebin to NULL. No, I didn't hold the extra reference - will remove gst_object_unref(uridecodebin[1]); What not? How can I use these addresses? It shouldn't be a problem, gst_object_unref() contains the checks for ref_count field and doesn't do anything if it's <=0 void gst_object_unref (gpointer object) { g_return_if_fail (object != NULL); g_return_if_fail (((GObject *) object)->ref_count > 0); ... |
Administrator
|
I have removed gst_object_unref(uridecodebin[1]); Then, the application run successfully two times, and I've got an Error message box from GLib, saying it has "recursed", on the third run. Unfortunately, I could not read the whole message, as this message box was covered by the Studio's windows and didn't redraw completely. Studio's debug output contained about 10 messages about the first chance exception Reading location 0xaddress and Writing location 0xanoter_address The my system has become almost unresponsive, only Alt-Tab has shown a window, but nothing else happens, so I had to reboot it. |
Administrator
|
Looks like I have won :) The problem was a bit earlier, related to the similar memory freeing. My application created playbin2 instance, then looked at its n-video and n-audio properties, and depending on them, destroyed playbin2 and created a pipeline with two uridecodebins and two playing chains for video and audio. However, I wanted to save the video-sink, since it was created separately, as my player is embedded. Currently the code is the following, seems it's stable. GstElement *m_player; GstBus *m_bus; GstElement *m_videosink; m_player=gst_element_factory_make("playbin2","player"); m_bus = gst_pipeline_get_bus(GST_PIPELINE(m_player)); gst_bus_enable_sync_message_emission(m_bus); gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler)gst_bus_sync_handler, this); gst_bus_add_watch (m_bus, bus_call, this); if(!m_videosink){ m_videosink = gst_element_factory_make("directdrawsink","videosink"); if(m_videosink){ gst_object_ref(m_videosink); g_object_set(m_videosink,"sync",TRUE,"force-aspect-ratio",TRUE,"preroll-queue-len",1,NULL); if(!m_hwnd && m_parent) m_hwnd=m_parent->hwnd(); if(m_hwnd) gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (m_videosink),m_hwnd); g_object_set(G_OBJECT(m_player),"video-sink",m_videosink,NULL); } } ..... rs=gst_element_set_state(GST_ELEMENT(m_player),GST_STATE_NULL); GstElement *bin=(GstElement *)gst_element_get_parent(m_videosink); if(bin){ rb=gst_bin_remove(GST_BIN(bin),GST_ELEMENT(m_videosink)); } gst_object_unref(GST_OBJECT(m_player)); gst_object_unref(GST_OBJECT(m_bus)); |
Free forum by Nabble | Edit this page |