From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by yocto-www.yoctoproject.org (Postfix, from userid 118) id B488DE0083E; Mon, 21 Dec 2015 11:04:14 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on yocto-www.yoctoproject.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_PASS autolearn=ham version=3.3.1 X-Spam-HAM-Report: * -0.0 SPF_HELO_PASS SPF: HELO matches SPF record * -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% * [score: 0.0000] Received: from ptmx.org (ptmx.org [178.63.28.110]) by yocto-www.yoctoproject.org (Postfix) with ESMTP id 078CFE00457 for ; Mon, 21 Dec 2015 11:04:10 -0800 (PST) Received: from [192.168.178.14] (chello062178118086.5.14.vie.surfer.at [62.178.118.86]) by ptmx.org (Postfix) with ESMTPSA id 19BC533FF3; Mon, 21 Dec 2015 20:04:05 +0100 (CET) To: Vikas Patil References: <564B3FD3.1030607@pseudoterminal.org> <564B5C5E.60309@pseudoterminal.org> <564C78B6.2000700@pseudoterminal.org> <564CAE4C.3040005@pseudoterminal.org> From: Carlos Rafael Giani Message-ID: <56784D25.3040608@pseudoterminal.org> Date: Mon, 21 Dec 2015 20:04:05 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 In-Reply-To: Cc: meta-freescale@yoctoproject.org Subject: Re: imxvpudec crash with 3.14.28 and gstreamer1.0 X-BeenThere: meta-freescale@yoctoproject.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Usage and development list for the meta-fsl-* layers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Dec 2015 19:04:14 -0000 X-Groupsio-MsgNum: 16892 Content-Type: multipart/mixed; boundary="------------080100000305020103080505" --------------080100000305020103080505 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Can you try out the example program I attached? Just run it like this: GST_DEBUG=2,*imx*:5 ./loop-videos -i 5000 -v "imxipuvideotransform ! imxeglvivsink" /home/root/B01_Baseline1.0_1280_720.MP4 This will run the mp4 video for 5 seconds and then start again. Note that you have to build it with the -std=c++11 compiler flag. On 2015-12-21 16:18, Vikas Patil wrote: > Hi Carlos, > > I have checked with following pipeline playing it via application for > 5 second and restating playing (in loop), however still see the memory > failure issues. Could you please give some inputs? Also allocation and > deallocation from VPU kernel driver seems ok. Attached here the logs > with eglvivsink. > > Also tried with updated version and new front end for vpu and observer > the same behavior. > > i.e. > https://github.com/Freescale/gstreamer-imx/commits/master > (sha:813756a0cb70d7aa609c3d35427179e75ca10013) > > https://github.com/Freescale/libimxvpuapi/commit/dba696e9775444eb1ff4ddbf2799a8a47a505527 > (with memory leak fix) > > gst-launch-1.0 -m filesrc > location=/home/root/B01_Baseline1.0_1280_720.MP4 ! qtdemux ! h264parse > ! imxvpudec ! imxipuvideotransform ! imxeglvivsink (gets memory > allocation failure in between 6th to 9th loop) > gst-launch-1.0 filesrc > location=/home/root/B01_Baseline1.0_1280_720.MP4 ! qtdemux ! h264parse > ! imxvpudec ! imxipuvideotransform ! imxg2dvideosink (gets memory > allocation failure on 62nd loop iteration) > > > Thanks & Regards, > Vikas > > On Wed, Nov 18, 2015 at 10:28 PM, Carlos Rafael Giani > wrote: >> This actually looks more like a problem in imx-vpu or in the VPU driver's >> DMA memory pool. DMA buffer allocation fails. >> Perhaps this affects other allocators as well. Try these pipelines: >> >> GST_DEBUG=2,*imx*:5 gst-launch-1.0 videotestsrc ! imxg2dvideosink >> GST_DEBUG=2,*imx*:5 gst-launch-1.0 videotestsrc ! imxipuvideosink >> >> If they fail, post logs. >> >> >> On 11/18/2015 04:00 PM, Vikas Patil wrote: >>> I changed the setup now. so don't have log with latest master. >>> Attaching log which was missing. >>> >>> Regards, >>> Vikash >>> > > --------------080100000305020103080505 Content-Type: text/x-c++src; name="loop-videos.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="loop-videos.cpp" #include #include #include #include #include #include #include gboolean sigint(gpointer ptr) { g_main_loop_quit(static_cast < GMainLoop* > (ptr)); return TRUE; } class video_carousel { public: typedef std::vector < std::string > uris; explicit video_carousel(uris const &p_uris, guint const p_interval, std::string const &p_video_sink, std::string const &p_audio_sink, GMainLoop *p_loop) : m_pipeline(nullptr) , m_uris(p_uris) , m_interval(p_interval) , m_loop(p_loop) , m_timeout_source(nullptr) { GError *error; g_assert(!(m_uris.empty())); m_pipeline = gst_element_factory_make("playbin", "pipeline"); g_object_set(G_OBJECT(m_pipeline), "flags", gint(0x57), nullptr); if (!(p_video_sink.empty())) { GstElement *sink = gst_parse_bin_from_description(p_video_sink.c_str(), TRUE, &error); if (sink == nullptr) { gst_object_unref(GST_OBJECT(m_pipeline)); std::string str = std::string("Could not create video sink element: ") + error->message; g_clear_error(&error); throw std::runtime_error(str); } g_object_set(G_OBJECT(m_pipeline), "video-sink", sink, nullptr); } if (!(p_audio_sink.empty())) { GstElement *sink = gst_element_factory_make(p_audio_sink.c_str(), "audio-sink"); if (sink == nullptr) { gst_object_unref(GST_OBJECT(m_pipeline)); std::string str = std::string("Could not create audio sink element: ") + error->message; g_clear_error(&error); throw std::runtime_error(str); } g_object_set(G_OBJECT(m_pipeline), "audio-sink", sink, nullptr); } GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline)); gst_bus_add_watch(bus, static_bus_watch, this); gst_object_unref(GST_OBJECT(bus)); } void start() { gst_element_set_state(m_pipeline, GST_STATE_NULL); m_cur_uri = m_uris.begin(); g_object_set(G_OBJECT(m_pipeline), "uri", m_cur_uri->c_str(), nullptr); gst_element_set_state(m_pipeline, GST_STATE_PLAYING); } gint64 get_current_position() const { gint64 position; gboolean success = gst_element_query_position(GST_ELEMENT(m_pipeline), GST_FORMAT_TIME, &position); return success ? position : -1; } ~video_carousel() { if (m_pipeline != nullptr) { stop_timeout(); gst_element_set_state(m_pipeline, GST_STATE_NULL); gst_object_unref(GST_OBJECT(m_pipeline)); } } private: void start_timeout() { if ((m_timeout_source != nullptr) || (m_interval == 0)) return; m_timeout_source = g_timeout_source_new(250); g_source_set_callback(m_timeout_source, static_timeout_cb, gpointer(this), nullptr); g_source_attach(m_timeout_source, nullptr); } void stop_timeout() { if (m_timeout_source == nullptr) return; g_source_destroy(m_timeout_source); g_source_unref(m_timeout_source); m_timeout_source = nullptr; } void advance_uri() { m_cur_uri++; if (m_cur_uri == m_uris.end()) m_cur_uri = m_uris.begin(); } void move_to_next_video() { gst_element_set_state(m_pipeline, GST_STATE_READY); advance_uri(); std::cerr << "=========== next URI: " << m_cur_uri->c_str() << " ===========\n"; g_object_set(G_OBJECT(m_pipeline), "uri", m_cur_uri->c_str(), nullptr); gst_element_set_state(m_pipeline, GST_STATE_PLAYING); } void update_duration() { gint64 duration; gboolean success = gst_element_query_duration(GST_ELEMENT(m_pipeline), GST_FORMAT_TIME, &duration); m_duration = success ? duration : -1; } static gboolean static_timeout_cb(gpointer p_user_data) { video_carousel *self = static_cast < video_carousel* > (p_user_data); gint64 cur_pos = self->get_current_position(); if (cur_pos != -1) { if ((cur_pos) >= (GST_MSECOND * self->m_interval)) { GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(self->m_pipeline)); gst_bus_post( bus, gst_message_new_application( GST_OBJECT(self->m_pipeline), gst_structure_new_empty("switch") ) ); gst_object_unref(GST_OBJECT(bus)); } } return G_SOURCE_CONTINUE; } static gboolean static_bus_watch(GstBus *, GstMessage *p_msg, gpointer p_user_data) { video_carousel *self = static_cast < video_carousel* > (p_user_data); switch (GST_MESSAGE_TYPE(p_msg)) { case GST_MESSAGE_STATE_CHANGED: { if (GST_MESSAGE_SRC(p_msg) != GST_OBJECT(self->m_pipeline)) break; GstState old_gstreamer_state, new_gstreamer_state, pending_gstreamer_state; gst_message_parse_state_changed( p_msg, &old_gstreamer_state, &new_gstreamer_state, &pending_gstreamer_state ); std::string dot_fn = std::string("pipeline") + "__old-" + gst_element_state_get_name(old_gstreamer_state) + "__new-" + gst_element_state_get_name(new_gstreamer_state) + "__pending-" + gst_element_state_get_name(pending_gstreamer_state); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(self->m_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, dot_fn.c_str()); switch (new_gstreamer_state) { case GST_STATE_PAUSED: self->stop_timeout(); break; case GST_STATE_PLAYING: self->start_timeout(); break; default: break; } break; } case GST_MESSAGE_STREAM_START: self->m_duration = -1; self->update_duration(); break; case GST_MESSAGE_APPLICATION: { if (gst_message_has_name(p_msg, "switch")) self->move_to_next_video(); break; } case GST_MESSAGE_EOS: { self->move_to_next_video(); break; } case GST_MESSAGE_BUFFERING: { gint percent = 0; gst_message_parse_buffering(p_msg, &percent); if (percent < 100) gst_element_set_state(self->m_pipeline, GST_STATE_PAUSED); else gst_element_set_state(self->m_pipeline, GST_STATE_PLAYING); break; } case GST_MESSAGE_LATENCY: gst_bin_recalculate_latency(GST_BIN(self->m_pipeline)); break; case GST_MESSAGE_REQUEST_STATE: { GstState requested_state; gst_message_parse_request_state(p_msg, &requested_state); gst_element_set_state(self->m_pipeline, requested_state); break; } case GST_MESSAGE_DURATION: self->update_duration(); break; case GST_MESSAGE_INFO: case GST_MESSAGE_WARNING: case GST_MESSAGE_ERROR: { GError *error = nullptr; gchar *debug_info = nullptr; gchar const *desc; switch (GST_MESSAGE_TYPE(p_msg)) { case GST_MESSAGE_INFO: desc = "info"; gst_message_parse_info(p_msg, &error, &debug_info); break; case GST_MESSAGE_WARNING: desc = "warning"; gst_message_parse_warning(p_msg, &error, &debug_info); break; case GST_MESSAGE_ERROR: { desc = "error"; gst_message_parse_error(p_msg, &error, &debug_info); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(self->m_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline-error"); g_main_loop_quit(self->m_loop); break; } default: break; } std::cerr << "GStreamer " << desc; if (error != nullptr) std::cerr << " message: " << error->message; else std::cerr << " "; if (debug_info != nullptr) std::cerr << " " << debug_info; else std::cerr << " "; std::cerr << std::endl; if (error != nullptr) g_error_free(error); if (debug_info != nullptr) g_free(debug_info); break; } default: break; } return TRUE; } GstElement *m_pipeline; uris m_uris; uris::iterator m_cur_uri; guint m_interval; GMainLoop *m_loop; gint64 m_duration; GSource *m_timeout_source; }; int main(int argc, char *argv[]) { GError *error = nullptr; if (!gst_init_check(&argc, &argv, &error)) { std::cerr << "Could not initialize GStreamer: " << error->message << "\n"; return -1; } GMainLoop *loop = nullptr; try { guint interval = 0; std::string video_sink, audio_sink; int c; while ((c = getopt(argc, argv, "i:v:a:h")) != -1) { switch (c) { case 'i': interval = std::stoul(optarg); break; case 'v': video_sink = optarg; break; case 'a': audio_sink = optarg; break; case 'h': std::cerr << "Usage: " << argv[0] << " [OPTION]... [URI/FILE]...\n" "Plays a list of videos specified via URI or filename in a loop,\n" "optionally with a fixed interval.\n" "\n" "Options:\n" " -h This help\n" " -i INTERVAL Use fixed interval of INTERVAL milliseconds.\n" " Default value 0 plays the videos until they end.\n" " -v VIDEOSINK Use the specified GStreamer video sink element.\n" " Default: let GStreamer pick one automatically\n" " -a AUDIOSINK Use the specified GStreamer audio sink element.\n" " Default: let GStreamer pick one automatically\n" ; return -1; default: break; } } if (optind >= argc) { std::cerr << "At least one URI/filename must be specified\n"; return -1; } video_carousel::uris uris; while (optind < argc) { std::string uri = argv[optind++]; if (!gst_uri_is_valid(uri.c_str())) { error = nullptr; gchar *uri_cstr = gst_filename_to_uri(uri.c_str(), &error); if (uri_cstr != nullptr) { uri = uri_cstr; g_free(uri_cstr); } if (error != nullptr) { std::string message = error->message; g_error_free(error); throw std::invalid_argument(message); } } uris.push_back(uri); } loop = g_main_loop_new(nullptr, TRUE); g_unix_signal_add(SIGINT, sigint, loop); video_carousel carousel(uris, interval, video_sink, audio_sink, loop); carousel.start(); g_main_loop_run(loop); } catch (std::exception const &p_exc) { std::cerr << "Exception raised: " << p_exc.what() << "\n"; } if (loop != nullptr) g_main_loop_unref(loop); std::cerr << "Quitting\n"; return 0; } --------------080100000305020103080505--