From: Carlos Rafael Giani <dv@pseudoterminal.org>
To: Vikas Patil <vikasmpatil@gmail.com>
Cc: meta-freescale@yoctoproject.org
Subject: Re: imxvpudec crash with 3.14.28 and gstreamer1.0
Date: Mon, 21 Dec 2015 20:04:05 +0100 [thread overview]
Message-ID: <56784D25.3040608@pseudoterminal.org> (raw)
In-Reply-To: <CA+kt3u25h3bfjBRO4GHgn79N-CJmShmZY_Lg5WhWjzoBw09oBw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2203 bytes --]
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
> <dv@pseudoterminal.org> 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
>>>
> >
[-- Attachment #2: loop-videos.cpp --]
[-- Type: text/x-c++src, Size: 10494 bytes --]
#include <stdexcept>
#include <vector>
#include <string>
#include <iostream>
#include <unistd.h>
#include <gst/gst.h>
#include <glib-unix.h>
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 << " <no message>";
if (debug_info != nullptr)
std::cerr << " " << debug_info;
else
std::cerr << " <no debug info>";
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;
}
next prev parent reply other threads:[~2015-12-21 19:04 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-17 14:41 imxvpudec crash with 3.14.28 and gstreamer1.0 Vikas Patil
2015-11-17 14:55 ` Carlos Rafael Giani
2015-11-17 16:55 ` Vikas Patil
2015-11-17 16:57 ` Carlos Rafael Giani
2015-11-17 17:53 ` Vikas Patil
2015-11-18 12:15 ` Vikas Patil
2015-11-18 13:10 ` Carlos Rafael Giani
2015-11-18 15:00 ` Vikas Patil
2015-11-18 16:58 ` Carlos Rafael Giani
[not found] ` <CA+kt3u25h3bfjBRO4GHgn79N-CJmShmZY_Lg5WhWjzoBw09oBw@mail.gmail.com>
2015-12-21 19:04 ` Carlos Rafael Giani [this message]
2015-12-22 6:22 ` Vikas Patil
2015-12-22 9:39 ` Vikas Patil
2015-12-22 9:48 ` Carlos Rafael Giani
2015-12-22 10:19 ` Vikas Patil
2015-12-22 10:41 ` Carlos Rafael Giani
[not found] ` <CA+kt3u1Bo3VtdKj0DQDjU6T5-esOtX3xKGnEt-Q4M3Z4MVPV_g@mail.gmail.com>
2015-12-22 12:17 ` Carlos Rafael Giani
2015-12-29 12:31 ` Carlos Rafael Giani
2015-11-18 13:08 ` Carlos Rafael Giani
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56784D25.3040608@pseudoterminal.org \
--to=dv@pseudoterminal.org \
--cc=meta-freescale@yoctoproject.org \
--cc=vikasmpatil@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.