diff --git a/configure.ac b/configure.ac index e605b7b..82df74a 100644 --- a/configure.ac +++ b/configure.ac @@ -24,20 +24,30 @@ if test x"$BOXTYPE" = x"tripledragon"; then TUXBOX_APPS_LIB_PKGCONFIG(DIRECTFB, directfb) fi -AC_ARG_ENABLE(gstreamer, - AS_HELP_STRING(--enable-gstreamer,use gstreamer playback), - ,[enable_gstreamer=no]) +AC_ARG_ENABLE(gstreamer_01, + AS_HELP_STRING(--enable-gstreamer_01,use gstreamer 0.10 playback), + ,[enable_gstreamer_01=no]) -AM_CONDITIONAL(ENABLE_GSTREAMER,test "$enable_gstreamer" = "yes") -if test "$enable_gstreamer" = "yes"; then - AC_DEFINE(ENABLE_GSTREAMER,1,[enable gstreamer]) +AM_CONDITIONAL(ENABLE_GSTREAMER_01,test "$enable_gstreamer_01" = "yes") +if test "$enable_gstreamer_01" = "yes"; then + AC_DEFINE(ENABLE_GSTREAMER_01,1,[use gstreamer 0.10 playback]) + PKG_CHECK_MODULES([GSTREAMER], [gstreamer-0.10]) + PKG_CHECK_MODULES([GSTREAMER_INTERFACES], [gstinterfaces-0.10]) +fi + +AC_ARG_ENABLE(gstreamer_10, + AS_HELP_STRING(--enable-gstreamer_10,use gstreamer 1.0 playback), + ,[enable_gstreamer_10=no]) + +AM_CONDITIONAL(ENABLE_GSTREAMER_10,test "$enable_gstreamer_10" = "yes") +if test "$enable_gstreamer_10" = "yes"; then + AC_DEFINE(ENABLE_GSTREAMER_10,1,[use gstreamer 1.0 playback]) + PKG_CHECK_MODULES([GSTREAMER], [gstreamer-1.0]) + PKG_CHECK_MODULES([GSTREAMER_AUDIO], [gstreamer-audio-1.0]) + PKG_CHECK_MODULES([GSTREAMER_VIDEO], [gstreamer-video-1.0]) fi if test x$BOXTYPE = xgeneric -a x$BOXMODEL != xraspi; then -if test x$ENABLE_GSTREAMER = x1; then - PKG_CHECK_MODULES([GSTREAMER], [gstreamer-0.10]) - PKG_CHECK_MODULES([GSTREAMER_INTERFACES], [gstinterfaces-0.10]) -fi PKG_CHECK_MODULES([AVFORMAT], [libavformat >= 53.21.1]) PKG_CHECK_MODULES([AVCODEC], [libavcodec >= 54.28.0]) # don't know which version is exactly needed here... diff --git a/generic-pc/Makefile.am b/generic-pc/Makefile.am index f00130d..58f5114 100644 --- a/generic-pc/Makefile.am +++ b/generic-pc/Makefile.am @@ -25,14 +25,21 @@ libgeneric_la_SOURCES = \ pwrmngr.cpp \ record.cpp -if ENABLE_GSTREAMER +if ENABLE_GSTREAMER_01 libgeneric_la_SOURCES += \ - playback_gst.cpp + playback_gst_01.cpp AM_LDFLAGS += \ -lgstreamer-0.10 \ -lgstinterfaces-0.10 else +if ENABLE_GSTREAMER_10 +libgeneric_la_SOURCES += \ + playback_gst_10.cpp +AM_LDFLAGS += \ + -lgstreamer-1.0 +else libgeneric_la_SOURCES += \ playback.cpp endif +endif diff --git a/generic-pc/playback_gst.cpp b/generic-pc/playback_gst_01.cpp similarity index 100% rename from generic-pc/playback_gst.cpp rename to generic-pc/playback_gst_01.cpp diff --git a/generic-pc/playback_gst_10.cpp b/generic-pc/playback_gst_10.cpp new file mode 100644 index 0000000..482a607 --- /dev/null +++ b/generic-pc/playback_gst_10.cpp @@ -0,0 +1,826 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include "dmx_lib.h" +#include "audio_lib.h" +#include "video_lib.h" +#include "glfb.h" + +#include "playback_gst.h" + +#include "lt_debug.h" +#define lt_debug(args...) _lt_debug(HAL_DEBUG_PLAYBACK, this, args) +#define lt_info(args...) _lt_info(HAL_DEBUG_PLAYBACK, this, args) +#define lt_debug_c(args...) _lt_debug(HAL_DEBUG_PLAYBACK, NULL, args) +#define lt_info_c(args...) _lt_info(HAL_DEBUG_PLAYBACK, NULL, args) + +static const char * FILENAME = "[playback.cpp]"; + +#include +#include +#include + +typedef enum +{ + GST_PLAY_FLAG_VIDEO = 0x00000001, + GST_PLAY_FLAG_AUDIO = 0x00000002, + GST_PLAY_FLAG_TEXT = 0x00000004, + GST_PLAY_FLAG_VIS = 0x00000008, + GST_PLAY_FLAG_SOFT_VOLUME = 0x00000010, + GST_PLAY_FLAG_NATIVE_AUDIO = 0x00000020, + GST_PLAY_FLAG_NATIVE_VIDEO = 0x00000040, + GST_PLAY_FLAG_DOWNLOAD = 0x00000080, + GST_PLAY_FLAG_BUFFERING = 0x000000100 +} GstPlayFlags; + + +GstElement * m_gst_playbin = NULL; +GstElement * audioSink = NULL; +GstElement * videoSink = NULL; +gchar * uri = NULL; +GstTagList * m_stream_tags = 0; +static int end_eof = 0; + +extern GLFramebuffer *glfb; + +gint match_sinktype(GstElement *element, gpointer type) +{ + return strcmp(g_type_name(G_OBJECT_TYPE(element)), (const char*)type); +} +GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data) +{ + gchar * sourceName; + + // source + GstObject * source; + source = GST_MESSAGE_SRC(msg); + + if (!GST_IS_OBJECT(source)) + return GST_BUS_DROP; + + sourceName = gst_object_get_name(source); + + switch (GST_MESSAGE_TYPE(msg)) + { + case GST_MESSAGE_EOS: + { + g_message("End-of-stream"); + end_eof = 1; + break; + } + + case GST_MESSAGE_ERROR: + { + gchar * debug; + GError *err; + gst_message_parse_error(msg, &err, &debug); + g_free (debug); + 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 ) + { + if ( err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND ) + { + if ( g_strrstr(sourceName, "videosink") ) + lt_info_c( "%s:%s - GST_MESSAGE_ERROR: videosink\n", FILENAME, __FUNCTION__ ); //FIXME: how shall playback handle this event??? + else if ( g_strrstr(sourceName, "audiosink") ) + lt_info_c( "%s:%s - GST_MESSAGE_ERROR: audioSink\n", FILENAME, __FUNCTION__ ); //FIXME: how shall playback handle this event??? + } + } + g_error_free(err); + + end_eof = 1; // NOTE: just to exit + + break; + } + + case GST_MESSAGE_INFO: + { + gchar *debug; + GError *inf; + + gst_message_parse_info (msg, &inf, &debug); + g_free (debug); + if ( inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE ) + { + if ( g_strrstr(sourceName, "videosink") ) + lt_info_c( "%s:%s - GST_MESSAGE_INFO: videosink\n", FILENAME, __FUNCTION__ ); //FIXME: how shall playback handle this event??? + } + g_error_free(inf); + break; + } + + case GST_MESSAGE_TAG: + { + GstTagList *tags, *result; + gst_message_parse_tag(msg, &tags); + + result = gst_tag_list_merge(m_stream_tags, tags, GST_TAG_MERGE_REPLACE); + if (result) + { + if (m_stream_tags) + gst_tag_list_free(m_stream_tags); + m_stream_tags = result; + } + + const GValue *gv_image = gst_tag_list_get_value_index(tags, GST_TAG_IMAGE, 0); + if ( gv_image ) + { + GstBuffer *buf_image; + buf_image = gst_value_get_buffer (gv_image); + int fd = open("/tmp/.id3coverart", O_CREAT|O_WRONLY|O_TRUNC, 0644); + if(fd >= 0) + { + GstMapInfo Info; + gst_buffer_map(buf_image, &Info,(GstMapFlags)( GST_MAP_READ)); + int ret = write(fd, Info.data, Info.size); + close(fd); + gst_buffer_unmap(buf_image, &Info); + lt_info_c( "%s:%s - GST_MESSAGE_INFO: cPlayback::state /tmp/.id3coverart %d bytes written\n", FILENAME, __FUNCTION__ , ret); + } + //FIXME: how shall playback handle this event??? + } + gst_tag_list_free(tags); + lt_info_c( "%s:%s - GST_MESSAGE_INFO: update info tags\n", FILENAME, __FUNCTION__); //FIXME: how shall playback handle this event??? + break; + } + + case GST_MESSAGE_STATE_CHANGED: + { + if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin)) + break; + + GstState old_state, new_state; + gst_message_parse_state_changed(msg, &old_state, &new_state, NULL); + + if(old_state == new_state) + break; + lt_info_c( "%s:%s - GST_MESSAGE_STATE_CHANGED: state transition %s -> %s\n", FILENAME, __FUNCTION__, gst_element_state_get_name(old_state), gst_element_state_get_name(new_state)); + + GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state); + + switch(transition) + { + case GST_STATE_CHANGE_NULL_TO_READY: + { + } break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + { + GstIterator *children; + if (audioSink) + { + gst_object_unref(GST_OBJECT(audioSink)); + audioSink = NULL; + } + + if (videoSink) + { + gst_object_unref(GST_OBJECT(videoSink)); + videoSink = NULL; + } + children = gst_bin_iterate_recurse(GST_BIN(m_gst_playbin)); + GValue *elem; + audioSink = GST_ELEMENT_CAST(gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, elem, (gpointer)"GstDVBAudioSink")); + videoSink = GST_ELEMENT_CAST(gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, elem, (gpointer)"GstDVBVideoSink")); + gst_iterator_free(children); + + } break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + { + } break; + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + { + } break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + { + if (audioSink) + { + gst_object_unref(GST_OBJECT(audioSink)); + audioSink = NULL; + } + if (videoSink) + { + gst_object_unref(GST_OBJECT(videoSink)); + videoSink = NULL; + } + } break; + case GST_STATE_CHANGE_READY_TO_NULL: + { + } break; + } + break; + } +#if 0 + case GST_MESSAGE_ELEMENT: + { + if(gst_structure_has_name(gst_message_get_structure(msg), "prepare-xwindow-id")) + { + // set window id + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(GST_MESSAGE_SRC (msg)), glfb->getWindowID()); + + // reshape window + gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(GST_MESSAGE_SRC (msg)), 0, 0, glfb->getOSDWidth(), glfb->getOSDHeight()); + + // sync frames + gst_video_overlay_expose(GST_VIDEO_OVERLAY(GST_MESSAGE_SRC (msg))); + } + } +#endif + break; + default: + break; + } + + return GST_BUS_DROP; +} + + +cPlayback::cPlayback(int num) +{ + lt_info( "%s:%s\n", FILENAME, __FUNCTION__); + const gchar *nano_str; + guint major, minor, micro, nano; + + gst_init(NULL, NULL); + + gst_version (&major, &minor, µ, &nano); + + if (nano == 1) + nano_str = "(CVS)"; + else if (nano == 2) + nano_str = "(Prerelease)"; + else + nano_str = ""; + + lt_info( "%s:%s - This program is linked against GStreamer %d.%d.%d %s\n", + FILENAME, __FUNCTION__, + major, minor, micro, nano_str); + + mAudioStream = 0; + mSpeed = 0; + + playing = false; + playstate = STATE_STOP; +} + +cPlayback::~cPlayback() +{ + lt_info( "%s:%s\n", FILENAME, __FUNCTION__); + //FIXME: all deleting stuff is done in Close() +} + +//Used by Fileplay +bool cPlayback::Open(playmode_t PlayMode) +{ + lt_info("%s: PlayMode %d\n", __func__, PlayMode); + return true; +} + +// used by movieplay +void cPlayback::Close(void) +{ + lt_info( "%s:%s\n", FILENAME, __FUNCTION__); + + Stop(); + + // disconnect bus handler + if (m_gst_playbin) + { + // 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); + lt_info( "%s:%s - GST bus handler closed\n", FILENAME, __FUNCTION__); + } + + if (m_stream_tags) + gst_tag_list_free(m_stream_tags); + + // close gst + if (m_gst_playbin) + { + if (audioSink) + { + gst_object_unref(GST_OBJECT(audioSink)); + audioSink = NULL; + + lt_info( "%s:%s - GST audio Sink closed\n", FILENAME, __FUNCTION__); + } + + if (videoSink) + { + gst_object_unref(GST_OBJECT(videoSink)); + videoSink = NULL; + + lt_info( "%s:%s - GST video Sink closed\n", FILENAME, __FUNCTION__); + } + + // unref m_gst_playbin + gst_object_unref (GST_OBJECT (m_gst_playbin)); + lt_info( "%s:%s - GST playbin closed\n", FILENAME, __FUNCTION__); + + m_gst_playbin = NULL; + } +} + +// start +bool cPlayback::Start(std::string filename, std::string headers) +{ + return Start((char*) filename.c_str(),0,0,0,0,0, headers); +} + +bool cPlayback::Start(char *filename, int /*vpid*/, int /*vtype*/, int /*apid*/, int /*ac3*/, int /*duration*/, std::string headers) +{ + lt_info( "%s:%s\n", FILENAME, __FUNCTION__); + + mAudioStream = 0; + + //create playback path + char file[400] = {""}; + bool isHTTP = false; + + if(!strncmp("http://", filename, 7)) + { + isHTTP = true; + } + else if(!strncmp("file://", filename, 7)) + { + isHTTP = false; + } + else if(!strncmp("upnp://", filename, 7)) + { + isHTTP = true; + } + else if(!strncmp("rtmp://", filename, 7)) + { + isHTTP = true; + } + else if(!strncmp("rtsp://", filename, 7)) + { + isHTTP = true; + } + else if(!strncmp("mms://", filename, 6)) + { + isHTTP = true; + } + else + strcat(file, "file://"); + + strcat(file, filename); + + if (isHTTP) + uri = g_uri_escape_string(filename, G_URI_RESERVED_CHARS_GENERIC_DELIMITERS, true); + else + uri = g_filename_to_uri(filename, NULL, NULL); + + lt_info("%s:%s - filename=%s\n", FILENAME, __FUNCTION__, filename); + + // create gst pipeline + m_gst_playbin = gst_element_factory_make ("playbin", "playbin"); + + if(m_gst_playbin) + { + lt_info("%s:%s - m_gst_playbin\n", FILENAME, __FUNCTION__); + + guint flags; + g_object_get(G_OBJECT (m_gst_playbin), "flags", &flags, NULL); + /* avoid video conversion, let the (hardware) sinks handle that */ + flags |= GST_PLAY_FLAG_NATIVE_VIDEO; + /* volume control is done by hardware */ + flags &= ~GST_PLAY_FLAG_SOFT_VOLUME; + + g_object_set(G_OBJECT (m_gst_playbin), "uri", uri, NULL); + g_object_set(G_OBJECT (m_gst_playbin), "flags", flags, NULL); + + //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); + + // state playing + gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING); + + playing = true; + playstate = STATE_PLAY; + } + else + { + lt_info("%s:%s - failed to create GStreamer pipeline!, sorry we can not play\n", FILENAME, __FUNCTION__); + playing = false; + + return false; + } + + g_free(uri); + + // set buffer size + /* increase the default 2 second / 2 MB buffer limitations to 5s / 5MB */ + int m_buffer_size = 5*1024*1024; + //g_object_set(G_OBJECT(m_gst_playbin), "buffer-duration", 5LL * GST_SECOND, NULL); + g_object_set(G_OBJECT(m_gst_playbin), "buffer-size", m_buffer_size, NULL); + + return true; +} + +bool cPlayback::Play(void) +{ + lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); + + if(playing == true) + return true; + + if(m_gst_playbin) + { + gst_element_set_state(GST_ELEMENT(m_gst_playbin), GST_STATE_PLAYING); + + playing = true; + playstate = STATE_PLAY; + } + lt_info("%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); + + return playing; +} + +bool cPlayback::Stop(void) +{ + if(playing == false) + return false; + lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); + + // stop + if(m_gst_playbin) + { + gst_element_set_state(m_gst_playbin, GST_STATE_NULL); + } + + playing = false; + + lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); + + playstate = STATE_STOP; + + return true; +} + +bool cPlayback::SetAPid(int pid , bool /*ac3*/) +{ + lt_info("%s: pid %i\n", __func__, pid); + + int current_audio; + + if(pid != 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; + } + + return true; +} + +void cPlayback::trickSeek(int ratio) +{ + bool validposition = false; + gint64 pos = 0; + int position; + int duration; + + if( GetPosition(position, duration) ) + { + validposition = true; + pos = position; + } + + gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING); + + if (validposition) + { + if(ratio >= 0.0) + gst_element_seek(m_gst_playbin, ratio, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP), GST_SEEK_TYPE_SET, pos, GST_SEEK_TYPE_SET, -1); + else + gst_element_seek(m_gst_playbin, ratio, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP), GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, pos); + } +} + +bool cPlayback::SetSpeed(int speed) +{ + lt_info( "%s:%s speed %d\n", FILENAME, __FUNCTION__, speed); + + if(playing == false) + return false; + + if(m_gst_playbin) + { + // pause + if(speed == 0) + { + gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED); + //trickSeek(0); + playstate = STATE_PAUSE; + } + // play/continue + else if(speed == 1) + { + trickSeek(1); + //gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING); + // + playstate = STATE_PLAY; + } + //ff + else if(speed > 1) + { + trickSeek(speed); + // + playstate = STATE_FF; + } + //rf + else if(speed < 0) + { + trickSeek(speed); + // + playstate = STATE_REW; + } + } + + mSpeed = speed; + + return true; +} + +bool cPlayback::SetSlow(int slow) +{ + lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); + + if(playing == false) + return false; + + if(m_gst_playbin) + { + trickSeek(0.5); + } + + playstate = STATE_SLOW; + + mSpeed = slow; + + return true; +} + +bool cPlayback::GetSpeed(int &speed) const +{ + speed = mSpeed; + + return true; +} + +// in milliseconds +bool cPlayback::GetPosition(int &position, int &duration) +{ + if(playing == false) + return false; + + //EOF + if(end_eof) + { + end_eof = 0; + return false; + } + + if(m_gst_playbin) + { + //position + GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs + + gint64 pts = 0; + unsigned long long int sec = 0; + + gst_element_query_position(m_gst_playbin, fmt, &pts); + position = pts / 1000000.0; + + // duration + GstFormat fmt_d = GST_FORMAT_TIME; //Returns time in nanosecs + double length = 0; + gint64 len; + + gst_element_query_duration(m_gst_playbin, fmt_d, &len); + length = len / 1000000.0; + if(length < 0) + length = 0; + + duration = (int)(length); + } + + return true; +} + +bool cPlayback::SetPosition(int position, bool absolute) +{ + lt_info("%s: pos %d abs %d playing %d\n", __func__, position, absolute, playing); + + if(playing == false) + return false; + + gint64 time_nanoseconds; + gint64 pos; + GstFormat fmt = GST_FORMAT_TIME; + + if(m_gst_playbin) + { + gst_element_query_position(m_gst_playbin, fmt, &pos); + time_nanoseconds = pos + (position * 1000000.0); + if(time_nanoseconds < 0) + time_nanoseconds = 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); + } + + return true; +} + +void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string * language) +{ + lt_info( "%s:%s\n", FILENAME, __FUNCTION__); + + if(m_gst_playbin) + { + gint i, n_audio = 0; + //GstStructure * structure = NULL; + + // get audio + g_object_get (m_gst_playbin, "n-audio", &n_audio, NULL); + printf("%s: %d audio\n", __FUNCTION__, n_audio); + + if(n_audio == 0) + return; + + for (i = 0; i < n_audio; i++) + { + // apids + apids[i]=i; + + GstPad * pad = 0; + g_signal_emit_by_name (m_gst_playbin, "get-audio-pad", i, &pad); + GstCaps * caps = gst_pad_get_current_caps(pad); + if (!caps) + continue; + + GstStructure * structure = gst_caps_get_structure(caps, 0); + //const gchar *g_type = gst_structure_get_name(structure); + + //if (!structure) + //return atUnknown; + //ac3flags[0] = 0; + + // ac3flags + if ( gst_structure_has_name (structure, "audio/mpeg")) + { + gint mpegversion, layer = -1; + + if (!gst_structure_get_int (structure, "mpegversion", &mpegversion)) + //return atUnknown; + ac3flags[i] = 0; + + switch (mpegversion) + { + case 1: + /* + { + gst_structure_get_int (structure, "layer", &layer); + if ( layer == 3 ) + return atMP3; + else + return atMPEG; + ac3flags[0] = 4; + break; + } + */ + ac3flags[i] = 4; + case 2: + //return atAAC; + ac3flags[i] = 5; + case 4: + //return atAAC; + ac3flags[i] = 5; + default: + //return atUnknown; + ac3flags[i] = 0; + } + } + else if ( gst_structure_has_name (structure, "audio/x-ac3") || gst_structure_has_name (structure, "audio/ac3") ) + //return atAC3; + ac3flags[i] = 1; + else if ( gst_structure_has_name (structure, "audio/x-dts") || gst_structure_has_name (structure, "audio/dts") ) + //return atDTS; + ac3flags[i] = 6; + else if ( gst_structure_has_name (structure, "audio/x-raw-int") ) + //return atPCM; + ac3flags[i] = 0; + + gst_caps_unref(caps); + } + + // numpids + *numpida=i; + } +} + +void cPlayback::getMeta() +{ + if(playing) + return; +} + +bool cPlayback::SyncAV(void) +{ + lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); + + if(playing == false ) + return false; + + return true; +} + +void cPlayback::RequestAbort() +{ +} + +void cPlayback::FindAllSubs(uint16_t *, unsigned short *, uint16_t *numpida, std::string *) +{ + printf("%s:%s\n", FILENAME, __func__); + *numpida = 0; +} + +void cPlayback::GetChapters(std::vector &positions, std::vector &titles) +{ + positions.clear(); + titles.clear(); +} + +bool cPlayback::SelectSubtitles(int pid) +{ + printf("%s:%s pid %i\n", FILENAME, __func__, pid); + return true; +} + +void cPlayback::GetMetadata(std::vector &keys, std::vector &values) +{ + keys.clear(); + values.clear(); +} + +void cPlayback::FindAllTeletextsubtitlePids(int *, unsigned int *numpids, std::string *, int *, int *) +{ + *numpids = 0; +} + +void cPlayback::FindAllSubtitlePids(int * /*pids*/, unsigned int *numpids, std::string * /*language*/) +{ + *numpids = 0; +} + +bool cPlayback::SetSubtitlePid(int /*pid*/) +{ + return true; +} + +void cPlayback::GetPts(uint64_t &/*pts*/) +{ +} + +bool cPlayback::SetTeletextPid(int /*pid*/) +{ + return true; +} + +uint64_t cPlayback::GetReadCount() +{ + return 0; +}