mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 23:13:16 +02:00
generic gestreamer align to armbox
This commit is contained in:
@@ -71,9 +71,10 @@ typedef enum
|
||||
GstElement * m_gst_playbin = NULL;
|
||||
GstElement * audioSink = NULL;
|
||||
GstElement * videoSink = NULL;
|
||||
|
||||
gchar * uri = NULL;
|
||||
GstTagList * m_stream_tags = NULL;
|
||||
pthread_mutex_t mutex_tag_ist;
|
||||
|
||||
static int end_eof = 0;
|
||||
#define HTTP_TIMEOUT 30
|
||||
// taken from record.h
|
||||
@@ -112,7 +113,7 @@ void processMpegTsSection(GstMpegtsSection* section)
|
||||
}
|
||||
}
|
||||
|
||||
void playbinNotifySource(GObject *object, GParamSpec *unused, gpointer user_data)
|
||||
void playbinNotifySource(GObject *object, GParamSpec *param_spec, gpointer user_data)
|
||||
{
|
||||
GstElement *source = NULL;
|
||||
cPlayback *_this = (cPlayback*)user_data;
|
||||
@@ -190,10 +191,8 @@ void playbinNotifySource(GObject *object, GParamSpec *unused, gpointer user_data
|
||||
}
|
||||
}
|
||||
|
||||
GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
GstBusSyncReply Gst_bus_call(GstBus *bus, GstMessage *msg, gpointer user_data)
|
||||
{
|
||||
gchar * sourceName;
|
||||
|
||||
// source
|
||||
GstObject * source;
|
||||
source = GST_MESSAGE_SRC(msg);
|
||||
@@ -201,8 +200,6 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
if (!GST_IS_OBJECT(source))
|
||||
return GST_BUS_DROP;
|
||||
|
||||
sourceName = gst_object_get_name(source);
|
||||
|
||||
switch (GST_MESSAGE_TYPE(msg))
|
||||
{
|
||||
case GST_MESSAGE_EOS:
|
||||
@@ -218,6 +215,7 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
GError *err;
|
||||
gst_message_parse_error(msg, &err, &debug);
|
||||
g_free (debug);
|
||||
gchar * sourceName = gst_object_get_name(source);
|
||||
lt_info_c( "%s:%s - GST_MESSAGE_ERROR: %s (%i) from %s\n", FILENAME, __FUNCTION__, err->message, err->code, sourceName );
|
||||
if ( err->domain == GST_STREAM_ERROR )
|
||||
{
|
||||
@@ -230,6 +228,8 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
}
|
||||
}
|
||||
g_error_free(err);
|
||||
if(sourceName)
|
||||
g_free(sourceName);
|
||||
|
||||
end_eof = 1; // NOTE: just to exit
|
||||
|
||||
@@ -245,8 +245,12 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
g_free (debug);
|
||||
if ( inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
|
||||
{
|
||||
gchar * sourceName = gst_object_get_name(source);
|
||||
if ( g_strrstr(sourceName, "videosink") )
|
||||
lt_info_c( "%s:%s - GST_MESSAGE_INFO: videosink\n", FILENAME, __FUNCTION__ ); //FIXME: how shall playback handle this event???
|
||||
if(sourceName)
|
||||
g_free(sourceName);
|
||||
|
||||
}
|
||||
g_error_free(inf);
|
||||
break;
|
||||
@@ -254,9 +258,16 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
|
||||
case GST_MESSAGE_TAG:
|
||||
{
|
||||
GstTagList *tags, *result;
|
||||
GstTagList *tags = NULL, *result = NULL;
|
||||
gst_message_parse_tag(msg, &tags);
|
||||
|
||||
if(tags == NULL)
|
||||
break;
|
||||
if(!GST_IS_TAG_LIST(tags))
|
||||
break;
|
||||
|
||||
pthread_mutex_lock (&mutex_tag_ist);
|
||||
|
||||
result = gst_tag_list_merge(m_stream_tags, tags, GST_TAG_MERGE_REPLACE);
|
||||
if (result)
|
||||
{
|
||||
@@ -264,6 +275,8 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
{
|
||||
gst_tag_list_unref(tags);
|
||||
gst_tag_list_unref(result);
|
||||
|
||||
pthread_mutex_unlock (&mutex_tag_ist);
|
||||
break;
|
||||
}
|
||||
if (m_stream_tags)
|
||||
@@ -272,6 +285,8 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
gst_tag_list_unref(result);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&mutex_tag_ist);
|
||||
|
||||
const GValue *gv_image = gst_tag_list_get_value_index(tags, GST_TAG_IMAGE, 0);
|
||||
if ( gv_image )
|
||||
{
|
||||
@@ -294,7 +309,8 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
lt_info_c("%s:%s - /tmp/.id3coverart %d bytes written\n", FILENAME, __FUNCTION__, ret);
|
||||
}
|
||||
}
|
||||
gst_tag_list_unref(tags);
|
||||
if (tags)
|
||||
gst_tag_list_unref(tags);
|
||||
lt_debug_c( "%s:%s - GST_MESSAGE_INFO: update info tags\n", FILENAME, __FUNCTION__); //FIXME: how shall playback handle this event???
|
||||
break;
|
||||
}
|
||||
@@ -341,7 +357,7 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
{
|
||||
GstIterator *children;
|
||||
GValue r = { 0, };
|
||||
GValue r = G_VALUE_INIT;
|
||||
|
||||
if (audioSink)
|
||||
{
|
||||
@@ -355,8 +371,7 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
videoSink = NULL;
|
||||
}
|
||||
children = gst_bin_iterate_recurse(GST_BIN(m_gst_playbin));
|
||||
|
||||
if (gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, &r, (gpointer)"GstDVBAudioSink"))
|
||||
if (children && gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, &r, (gpointer)"GstDVBAudioSink"))
|
||||
{
|
||||
audioSink = GST_ELEMENT_CAST(g_value_dup_object (&r));
|
||||
g_value_unset (&r);
|
||||
@@ -365,8 +380,7 @@ GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
|
||||
|
||||
gst_iterator_free(children);
|
||||
children = gst_bin_iterate_recurse(GST_BIN(m_gst_playbin));
|
||||
|
||||
if (gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, &r, (gpointer)"GstDVBVideoSink"))
|
||||
if (children && gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, &r, (gpointer)"GstDVBVideoSink"))
|
||||
{
|
||||
videoSink = GST_ELEMENT_CAST(g_value_dup_object (&r));
|
||||
g_value_unset (&r);
|
||||
@@ -421,6 +435,10 @@ cPlayback::cPlayback(int num)
|
||||
|
||||
gst_version (&major, &minor, µ, &nano);
|
||||
|
||||
gst_mpegts_initialize();
|
||||
|
||||
pthread_mutex_init (&mutex_tag_ist, NULL);
|
||||
|
||||
if (nano == 1)
|
||||
nano_str = "(CVS)";
|
||||
else if (nano == 2)
|
||||
@@ -445,8 +463,10 @@ cPlayback::~cPlayback()
|
||||
{
|
||||
lt_info( "%s:%s\n", FILENAME, __FUNCTION__);
|
||||
//FIXME: all deleting stuff is done in Close()
|
||||
pthread_mutex_lock (&mutex_tag_ist);
|
||||
if (m_stream_tags)
|
||||
gst_tag_list_unref(m_stream_tags);
|
||||
pthread_mutex_unlock (&mutex_tag_ist);
|
||||
}
|
||||
|
||||
//Used by Fileplay
|
||||
@@ -471,7 +491,8 @@ void cPlayback::Close(void)
|
||||
// disconnect sync handler callback
|
||||
GstBus * bus = gst_pipeline_get_bus(GST_PIPELINE (m_gst_playbin));
|
||||
gst_bus_set_sync_handler(bus, NULL, NULL, NULL);
|
||||
gst_object_unref(bus);
|
||||
if (bus)
|
||||
gst_object_unref(bus);
|
||||
lt_info( "%s:%s - GST bus handler closed\n", FILENAME, __FUNCTION__);
|
||||
}
|
||||
|
||||
@@ -524,8 +545,11 @@ bool cPlayback::Start(char *filename, int /*vpid*/, int /*vtype*/, int /*apid*/,
|
||||
mAudioStream = 0;
|
||||
init_jump = -1;
|
||||
|
||||
gst_tag_list_unref(m_stream_tags);
|
||||
pthread_mutex_lock (&mutex_tag_ist);
|
||||
if (m_stream_tags)
|
||||
gst_tag_list_unref(m_stream_tags);
|
||||
m_stream_tags = NULL;
|
||||
pthread_mutex_unlock (&mutex_tag_ist);
|
||||
|
||||
unlink("/tmp/.id3coverart");
|
||||
|
||||
@@ -568,8 +592,7 @@ bool cPlayback::Start(char *filename, int /*vpid*/, int /*vtype*/, int /*apid*/,
|
||||
|
||||
lt_info("%s:%s - filename=%s\n", FILENAME, __FUNCTION__, filename);
|
||||
|
||||
guint flags = GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_VIDEO | \
|
||||
GST_PLAY_FLAG_TEXT | GST_PLAY_FLAG_NATIVE_VIDEO;
|
||||
guint flags = GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_NATIVE_VIDEO;
|
||||
|
||||
/* increase the default 2 second / 2 MB buffer limitations to 5s / 5MB */
|
||||
int m_buffer_size = 5*1024*1024;
|
||||
@@ -598,7 +621,8 @@ bool cPlayback::Start(char *filename, int /*vpid*/, int /*vtype*/, int /*apid*/,
|
||||
//gstbus handler
|
||||
GstBus * bus = gst_pipeline_get_bus( GST_PIPELINE(m_gst_playbin) );
|
||||
gst_bus_set_sync_handler(bus, Gst_bus_call, NULL, NULL);
|
||||
gst_object_unref(bus);
|
||||
if (bus)
|
||||
gst_object_unref(bus);
|
||||
|
||||
first = true;
|
||||
|
||||
@@ -673,13 +697,19 @@ bool cPlayback::SetAPid(int pid, bool /*ac3*/)
|
||||
{
|
||||
lt_info("%s: pid %i\n", __func__, pid);
|
||||
|
||||
int current_audio;
|
||||
int to_audio = pid;
|
||||
|
||||
if(pid != mAudioStream)
|
||||
for (unsigned int i = 0; i < REC_MAX_APIDS; i++) {
|
||||
if (real_apids[i])
|
||||
if (real_apids[i] == pid)
|
||||
to_audio = i;
|
||||
}
|
||||
|
||||
if(to_audio != mAudioStream)
|
||||
{
|
||||
g_object_set (G_OBJECT (m_gst_playbin), "current-audio", pid, NULL);
|
||||
printf("%s: switched to audio stream %i\n", __FUNCTION__, pid);
|
||||
mAudioStream = pid;
|
||||
g_object_set (G_OBJECT (m_gst_playbin), "current-audio", to_audio, NULL);
|
||||
printf("%s: switched to audio stream %i\n", __FUNCTION__, to_audio);
|
||||
mAudioStream = to_audio;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -807,7 +837,9 @@ bool cPlayback::GetPosition(int &position, int &duration)
|
||||
else
|
||||
{
|
||||
if(!gst_element_query_position(m_gst_playbin, fmt, &pts))
|
||||
{
|
||||
lt_info( "%s - %d failed\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
}
|
||||
position = pts / 1000000.0;
|
||||
// duration
|
||||
@@ -830,21 +862,23 @@ bool cPlayback::SetPosition(int position, bool absolute)
|
||||
{
|
||||
lt_info("%s: pos %d abs %d playing %d\n", __func__, position, absolute, playing);
|
||||
|
||||
gint64 time_nanoseconds;
|
||||
gint64 pos;
|
||||
GstFormat fmt = GST_FORMAT_TIME;
|
||||
GstState state;
|
||||
|
||||
if(m_gst_playbin)
|
||||
{
|
||||
gst_element_get_state(m_gst_playbin, &state, NULL, GST_CLOCK_TIME_NONE);
|
||||
|
||||
if ( (state == GST_STATE_PAUSED) && first)
|
||||
{
|
||||
init_jump = position;
|
||||
first = false;
|
||||
return false;
|
||||
if(first){
|
||||
GstState state;
|
||||
gst_element_get_state(m_gst_playbin, &state, NULL, GST_CLOCK_TIME_NONE);
|
||||
if ( (state == GST_STATE_PAUSED) && first)
|
||||
{
|
||||
init_jump = position;
|
||||
first = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
gint64 time_nanoseconds;
|
||||
gint64 pos;
|
||||
GstFormat fmt = GST_FORMAT_TIME;
|
||||
if (!absolute)
|
||||
{
|
||||
gst_element_query_position(m_gst_playbin, fmt, &pos);
|
||||
@@ -857,7 +891,7 @@ bool cPlayback::SetPosition(int position, bool absolute)
|
||||
time_nanoseconds = position * 1000000.0;
|
||||
}
|
||||
|
||||
gst_element_seek(m_gst_playbin, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, time_nanoseconds, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
|
||||
gst_element_seek(m_gst_playbin, 1.0, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), GST_SEEK_TYPE_SET, time_nanoseconds, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -880,7 +914,7 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu
|
||||
|
||||
language->clear();
|
||||
|
||||
for (i = 0; i < n_audio; i++)
|
||||
for (i = 0; i < n_audio && i < *numpida; i++)
|
||||
{
|
||||
// apids
|
||||
apids[i]= real_apids[i] ? real_apids[i] : i;
|
||||
@@ -889,7 +923,8 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu
|
||||
g_signal_emit_by_name (m_gst_playbin, "get-audio-pad", i, &pad);
|
||||
|
||||
GstCaps * caps = gst_pad_get_current_caps(pad);
|
||||
gst_object_unref(pad);
|
||||
if (pad)
|
||||
gst_object_unref(pad);
|
||||
|
||||
if (!caps)
|
||||
continue;
|
||||
@@ -897,12 +932,11 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu
|
||||
GstStructure * structure = gst_caps_get_structure(caps, 0);
|
||||
GstTagList * tags = NULL;
|
||||
gchar * g_lang = NULL;
|
||||
gchar * g_codec = NULL;
|
||||
|
||||
// ac3flags
|
||||
if ( gst_structure_has_name (structure, "audio/mpeg"))
|
||||
{
|
||||
gint mpegversion, layer = -1;
|
||||
gint mpegversion;
|
||||
|
||||
if (!gst_structure_get_int (structure, "mpegversion", &mpegversion))
|
||||
ac3flags[i] = 0;
|
||||
@@ -932,14 +966,15 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu
|
||||
//return atPCM;
|
||||
ac3flags[i] = 0;
|
||||
|
||||
gst_caps_unref(caps);
|
||||
if (caps)
|
||||
gst_caps_unref(caps);
|
||||
|
||||
//(ac3flags[i] > 2) ? ac3flags[i] = 1 : ac3flags[i] = 0;
|
||||
|
||||
g_signal_emit_by_name (m_gst_playbin, "get-audio-tags", i, &tags);
|
||||
if (tags && GST_IS_TAG_LIST(tags))
|
||||
if (tags)
|
||||
{
|
||||
if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
|
||||
if (GST_IS_TAG_LIST(tags) && gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang))
|
||||
{
|
||||
std::string slang;
|
||||
if (gst_tag_check_language_code(g_lang))
|
||||
@@ -1002,22 +1037,40 @@ void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::str
|
||||
{
|
||||
keys.clear();
|
||||
values.clear();
|
||||
if (gst_tag_list_is_empty (m_stream_tags))
|
||||
|
||||
GstTagList *meta_list = NULL;
|
||||
pthread_mutex_lock (&mutex_tag_ist);
|
||||
|
||||
if(m_stream_tags){
|
||||
meta_list = gst_tag_list_copy(m_stream_tags);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&mutex_tag_ist);
|
||||
|
||||
if (meta_list == NULL)
|
||||
return;
|
||||
|
||||
for (guint i = 0, icnt = gst_tag_list_n_tags(m_stream_tags); i < icnt; i++)
|
||||
if (gst_tag_list_is_empty(meta_list)){
|
||||
gst_tag_list_unref(meta_list);
|
||||
return;
|
||||
}
|
||||
|
||||
for (guint i = 0, icnt = gst_tag_list_n_tags(meta_list); i < icnt; i++)
|
||||
{
|
||||
const gchar *name = gst_tag_list_nth_tag_name(m_stream_tags, i);
|
||||
const gchar *name = gst_tag_list_nth_tag_name(meta_list, i);
|
||||
if (!name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (guint j = 0, jcnt = gst_tag_list_get_tag_size(m_stream_tags, name); j < jcnt; j++)
|
||||
for (guint j = 0, jcnt = gst_tag_list_get_tag_size(meta_list, name); j < jcnt; j++)
|
||||
{
|
||||
const GValue *val;
|
||||
|
||||
val = gst_tag_list_get_value_index(m_stream_tags, name, j);
|
||||
val = gst_tag_list_get_value_index(meta_list, name, j);
|
||||
|
||||
if (val == NULL)
|
||||
continue;
|
||||
|
||||
if (G_VALUE_HOLDS_STRING(val))
|
||||
{
|
||||
@@ -1057,6 +1110,7 @@ void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::str
|
||||
|
||||
}
|
||||
}
|
||||
gst_tag_list_unref(meta_list);
|
||||
printf("%s:%s %d tags found\n", FILENAME, __func__, (int)keys.size());
|
||||
}
|
||||
|
||||
@@ -1094,7 +1148,7 @@ int cPlayback::GetAPid(void)
|
||||
gint current_audio = 0;
|
||||
g_object_get (m_gst_playbin, "current-audio", ¤t_audio, NULL);
|
||||
lt_info("%s: %d audio\n", __FUNCTION__, current_audio);
|
||||
return current_audio;
|
||||
return real_apids[current_audio] ? real_apids[current_audio] : current_audio;
|
||||
}
|
||||
|
||||
int cPlayback::GetVPid(void)
|
||||
|
Reference in New Issue
Block a user