diff --git a/AUTHORS b/AUTHORS index 4fc2a9eafa..fcf63c0836 100644 --- a/AUTHORS +++ b/AUTHORS @@ -12,3 +12,4 @@ Bastien Nocera Christian Fredrik Kalager Schaller Thomas Vander Stichele Andy Wingo +Cameron Hutchison diff --git a/ext/dvdnav/Makefile.am b/ext/dvdnav/Makefile.am index 7cae63e275..1ed82745d6 100644 --- a/ext/dvdnav/Makefile.am +++ b/ext/dvdnav/Makefile.am @@ -7,6 +7,4 @@ libgstdvdnavsrc_la_CFLAGS = $(GST_CFLAGS) $(DVDNAV_CFLAGS) libgstdvdnavsrc_la_LIBADD = $(DVDNAV_LIBS) libgstdvdnavsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -noinst_HEADERS = dvdnavsrc.h - EXTRA_DIST = README diff --git a/ext/dvdnav/README b/ext/dvdnav/README index acf8d08cc5..01a64a269c 100644 --- a/ext/dvdnav/README +++ b/ext/dvdnav/README @@ -3,3 +3,9 @@ Various Info http://members.aol.com/mpucoder/DVD/index.html http://dvd.sourceforge.net/ + +Try this: + +./gst-launch dvdnavsrc location=/dev/dvd ! mpegdemux video_%02d! { queue ! mpeg2dec ! sdlvideosink } mpegdemux0.private_stream_1_%02d! { queue ! a52dec ! osssink } + +You can give title, chapter, and angle parameters to dvdnavsrc. diff --git a/ext/dvdnav/dvdnavsrc.c b/ext/dvdnav/dvdnavsrc.c index 9bef217b0c..da20486683 100644 --- a/ext/dvdnav/dvdnavsrc.c +++ b/ext/dvdnav/dvdnavsrc.c @@ -22,23 +22,31 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include - -#include +#include #include "config.h" #include -struct _DVDNavSrcPrivate { +#define GST_TYPE_DVDNAVSRC \ + (dvdnavsrc_get_type()) +#define DVDNAVSRC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DVDNAVSRC,DVDNavSrc)) +#define DVDNAVSRC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DVDNAVSRC,DVDNavSrcClass)) +#define GST_IS_DVDNAVSRC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DVDNAVSRC)) +#define GST_IS_DVDNAVSRC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DVDNAVSRC)) + +typedef struct _DVDNavSrc DVDNavSrc; +typedef struct _DVDNavSrcClass DVDNavSrcClass; + +struct _DVDNavSrc { GstElement element; + /* pads */ GstPad *srcpad; @@ -51,6 +59,9 @@ struct _DVDNavSrcPrivate { dvdnav_t *dvdnav; }; +struct _DVDNavSrcClass { + GstElementClass parent_class; +}; GstElementDetails dvdnavsrc_details = { "DVD Source", @@ -76,7 +87,14 @@ enum { ARG_ANGLE }; +typedef enum { + DVDNAVSRC_OPEN = GST_ELEMENT_FLAG_LAST, + DVDNAVSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2, +} DVDNavSrcFlags; + + +GType dvdnavsrc_get_type (void); static void dvdnavsrc_class_init (DVDNavSrcClass *klass); static void dvdnavsrc_init (DVDNavSrc *dvdnavsrc); @@ -86,6 +104,9 @@ static void dvdnavsrc_get_property (GObject *object, guint prop_id, GValue *v /*static GstBuffer * dvdnavsrc_get (GstPad *pad); */ static void dvdnavsrc_loop (GstElement *element); /*static GstBuffer * dvdnavsrc_get_region (GstPad *pad,gulong offset,gulong size); */ +//static void dvdnavsrc_event (GstPad *pad, GstEvent *event); +static gboolean dvdnavsrc_close (DVDNavSrc *src); +static gboolean dvdnavsrc_open (DVDNavSrc *src); static GstElementStateReturn dvdnavsrc_change_state (GstElement *element); @@ -147,16 +168,16 @@ dvdnavsrc_class_init (DVDNavSrcClass *klass) static void dvdnavsrc_init (DVDNavSrc *dvdnavsrc) { - dvdnavsrc->priv = g_new(DVDNavSrcPrivate, 1); - dvdnavsrc->priv->srcpad = gst_pad_new ("src", GST_PAD_SRC); - gst_element_add_pad (GST_ELEMENT (dvdnavsrc), dvdnavsrc->priv->srcpad); gst_element_set_loop_function (GST_ELEMENT(dvdnavsrc), GST_DEBUG_FUNCPTR(dvdnavsrc_loop)); + dvdnavsrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_element_add_pad (GST_ELEMENT (dvdnavsrc), dvdnavsrc->srcpad); + //gst_pad_set_event_function (dvdnavsrc->srcpad, dvdnavsrc_event); - dvdnavsrc->priv->location = g_strdup("/dev/dvd"); - dvdnavsrc->priv->new_seek = FALSE; - dvdnavsrc->priv->title = 1; - dvdnavsrc->priv->chapter = 1; - dvdnavsrc->priv->angle = 1; + dvdnavsrc->location = g_strdup("/dev/dvd"); + dvdnavsrc->new_seek = FALSE; + dvdnavsrc->title = 1; + dvdnavsrc->chapter = 1; + dvdnavsrc->angle = 1; } /* FIXME: this code is not being used */ @@ -166,46 +187,52 @@ dvdnavsrc_destroy (DVDNavSrc *dvdnavsrc) { /* FIXME */ g_print("FIXME\n"); - g_free(dvdnavsrc->priv); } #endif +static gboolean +dvdnavsrc_is_open (DVDNavSrc *src) +{ + g_return_val_if_fail (src != NULL, FALSE); + g_return_val_if_fail (GST_IS_DVDNAVSRC (src), FALSE); + + return GST_FLAG_IS_SET (src, DVDNAVSRC_OPEN); +} + static void dvdnavsrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { DVDNavSrc *src; - DVDNavSrcPrivate *priv; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_DVDNAVSRC (object)); src = DVDNAVSRC (object); - priv = src->priv; switch (prop_id) { case ARG_LOCATION: /* the element must be stopped in order to do this */ /*g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); */ - if (priv->location) - g_free (priv->location); + if (src->location) + g_free (src->location); /* clear the filename if we get a NULL (is that possible?) */ if (g_value_get_string (value) == NULL) - priv->location = g_strdup("/dev/dvd"); + src->location = g_strdup("/dev/dvd"); /* otherwise set the new filename */ else - priv->location = g_strdup (g_value_get_string (value)); + src->location = g_strdup (g_value_get_string (value)); break; case ARG_TITLE: - priv->title = g_value_get_int (value); - priv->new_seek = TRUE; + src->title = g_value_get_int (value); + src->new_seek = TRUE; break; case ARG_CHAPTER: - priv->chapter = g_value_get_int (value); - priv->new_seek = TRUE; + src->chapter = g_value_get_int (value); + src->new_seek = TRUE; break; case ARG_ANGLE: - priv->angle = g_value_get_int (value); + src->angle = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -218,26 +245,24 @@ static void dvdnavsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { DVDNavSrc *src; - DVDNavSrcPrivate *priv; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_DVDNAVSRC (object)); src = DVDNAVSRC (object); - priv = src->priv; switch (prop_id) { case ARG_LOCATION: - g_value_set_string (value, priv->location); + g_value_set_string (value, src->location); break; case ARG_TITLE: - g_value_set_int (value, priv->title); + g_value_set_int (value, src->title); break; case ARG_CHAPTER: - g_value_set_int (value, priv->chapter); + g_value_set_int (value, src->chapter); break; case ARG_ANGLE: - g_value_set_int (value, priv->angle); + g_value_set_int (value, src->angle); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -245,122 +270,148 @@ dvdnavsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpe } } -static int -_open(DVDNavSrcPrivate *priv, const gchar *location) -{ - g_return_val_if_fail(priv != NULL, -1); - g_return_val_if_fail(location != NULL, -1); - - if (dvdnav_open ( &priv->dvdnav, (char*)location ) != DVDNAV_STATUS_OK) { - fprintf( stderr, "dvdnav_open error: %s location: %s\n", dvdnav_err_to_string(priv->dvdnav), location); - return -1; - } - - return 0; -} - -static int -_close(DVDNavSrcPrivate *priv) -{ - g_return_val_if_fail(priv != NULL, -1); - g_return_val_if_fail(priv->dvdnav != NULL, -1); - - if (dvdnav_close ( priv->dvdnav ) != DVDNAV_STATUS_OK) { - fprintf( stderr, "dvdnav_close error: %s\n", dvdnav_err_to_string(priv->dvdnav)); - return -1; - } - return 0; -} - -static int -_seek(DVDNavSrcPrivate *priv, int title, int chapter, int angle) +static gboolean +dvdnavsrc_tca_seek(DVDNavSrc *src, int title, int chapter, int angle) { int titles, programs, curangle, angles; - g_return_val_if_fail(priv != NULL, -1); - g_return_val_if_fail(priv->dvdnav != NULL, -1); + g_return_val_if_fail (src != NULL, FALSE); + g_return_val_if_fail (src->dvdnav != NULL, FALSE); + g_return_val_if_fail (dvdnavsrc_is_open (src), FALSE); - /** - * Make sure our title number is valid. - */ - if (dvdnav_get_number_of_titles (priv->dvdnav, &titles) != DVDNAV_STATUS_OK) { - fprintf (stderr, "dvdnav_get_number_of_titles error: %s\n", dvdnav_err_to_string(priv->dvdnav)); - return -1; + fprintf (stderr, "dvdnav: seeking to %d/%d/%d\n", title, chapter, angle); + /** + * Make sure our title number is valid. + */ + if (dvdnav_get_number_of_titles (src->dvdnav, &titles) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_get_number_of_titles error: %s\n", dvdnav_err_to_string(src->dvdnav)); + return FALSE; } fprintf (stderr, "There are %d titles on this DVD.\n", titles); - if (title < 0 || title >= titles) { - fprintf (stderr, "Invalid title %d.\n", title + 1); - _close (priv); - return -1; + if (title < 1 || title > titles) { + fprintf (stderr, "Invalid title %d.\n", title); + dvdnavsrc_close (src); + return FALSE; + } + + /** + * Before we can get the number of chapters (programs) we need to call + * dvdnav_title_play so that dvdnav_get_number_of_programs knows which title + * to operate on (also needed to get the number of angles) + */ + if (dvdnav_title_play (src->dvdnav, title) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_title_play error: %s\n", + dvdnav_err_to_string(src->dvdnav)); + return FALSE; } /** * Make sure the chapter number is valid for this title. */ - if (dvdnav_get_number_of_programs (priv->dvdnav, &programs) != DVDNAV_STATUS_OK) { - fprintf( stderr, "dvdnav_get_number_of_programs error: %s\n", dvdnav_err_to_string(priv->dvdnav)); - return -1; + if (dvdnav_get_number_of_programs (src->dvdnav, &programs) != DVDNAV_STATUS_OK) { + fprintf( stderr, "dvdnav_get_number_of_programs error: %s\n", dvdnav_err_to_string(src->dvdnav)); + return FALSE; } fprintf (stderr, "There are %d chapters in this title.\n", programs); - if (chapter < 0 || chapter >= programs) { - fprintf (stderr, "Invalid chapter %d\n", chapter + 1); - _close (priv); - return -1; + if (chapter < 1 || chapter > programs) { + fprintf (stderr, "Invalid chapter %d\n", chapter); + dvdnavsrc_close (src); + return FALSE; } /** * Make sure the angle number is valid for this title. */ - if (dvdnav_get_angle_info (priv->dvdnav, &curangle, &angles) != DVDNAV_STATUS_OK) { - fprintf (stderr, "dvdnav_get_angle_info error: %s\n", dvdnav_err_to_string(priv->dvdnav)); - return -1; + if (dvdnav_get_angle_info (src->dvdnav, &curangle, &angles) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_get_angle_info error: %s\n", dvdnav_err_to_string(src->dvdnav)); + return FALSE; } fprintf (stderr, "There are %d angles in this title.\n", angles); - if( angle < 0 || angle >= angles) { - fprintf (stderr, "Invalid angle %d\n", angle + 1); - _close (priv); - return -1; + if( angle < 1 || angle > angles) { + fprintf (stderr, "Invalid angle %d\n", angle); + dvdnavsrc_close (src); + return FALSE; } /** * We've got enough info, time to open the title set data. */ - if (dvdnav_part_play (priv->dvdnav, title, chapter) != DVDNAV_STATUS_OK) { - fprintf (stderr, "dvdnav_part_play error: %s\n", dvdnav_err_to_string(priv->dvdnav)); - return -1; + if (dvdnav_part_play (src->dvdnav, title, chapter) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_part_play error: %s\n", dvdnav_err_to_string(src->dvdnav)); + return FALSE; } - if (dvdnav_angle_change (priv->dvdnav, angle) != DVDNAV_STATUS_OK) { - fprintf (stderr, "dvdnav_angle_change error: %s\n", dvdnav_err_to_string(priv->dvdnav)); - return -1; + if (dvdnav_angle_change (src->dvdnav, angle) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_angle_change error: %s\n", dvdnav_err_to_string(src->dvdnav)); + return FALSE; } /* - if (dvdnav_physical_audio_stream_change (priv->dvdnav, 0) != DVDNAV_STATUS_OK) { - fprintf (stderr, "dvdnav_physical_audio_stream_change error: %s\n", dvdnav_err_to_string(priv->dvdnav)); - return -1; + if (dvdnav_physical_audio_stream_change (src->dvdnav, 0) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_physical_audio_stream_change error: %s\n", dvdnav_err_to_string(src->dvdnav)); + return FALSE; } - if (dvdnav_logical_audio_stream_change (priv->dvdnav, 0) != DVDNAV_STATUS_OK) { - fprintf (stderr, "dvdnav_logical_audio_stream_change error: %s\n", dvdnav_err_to_string(priv->dvdnav)); - return -1; + if (dvdnav_logical_audio_stream_change (src->dvdnav, 0) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_logical_audio_stream_change error: %s\n", dvdnav_err_to_string(src->dvdnav)); + return FALSE; } */ - return 0; + return TRUE; +} + +/* +static void +dvdnavsrc_event (GstPad *pad, GstElement *element) +{ +} +*/ + +#if 0 +static gchar * +dvdnav_get_event_name(int event) +{ + switch (event) { + case DVDNAV_BLOCK_OK: return "DVDNAV_BLOCK_OK"; break; + case DVDNAV_NOP: return "DVDNAV_NOP"; break; + case DVDNAV_STILL_FRAME: return "DVDNAV_STILL_FRAME"; break; + case DVDNAV_SPU_STREAM_CHANGE: return "DVDNAV_SPU_STREAM_CHANGE"; break; + case DVDNAV_AUDIO_STREAM_CHANGE: return "DVDNAV_AUDIO_STREAM_CHANGE"; break; + case DVDNAV_VTS_CHANGE: return "DVDNAV_VTS_CHANGE"; break; + case DVDNAV_CELL_CHANGE: return "DVDNAV_CELL_CHANGE"; break; + case DVDNAV_NAV_PACKET: return "DVDNAV_NAV_PACKET"; break; + case DVDNAV_STOP: return "DVDNAV_STOP"; break; + case DVDNAV_HIGHLIGHT: return "DVDNAV_HIGHLIGHT"; break; + case DVDNAV_SPU_CLUT_CHANGE: return "DVDNAV_SPU_CLUT_CHANGE"; break; + case DVDNAV_SEEK_DONE: return "DVDNAV_SEEK_DONE"; break; + case DVDNAV_HOP_CHANNEL: return "DVDNAV_HOP_CHANNEL"; break; + } + return "UNKNOWN"; +} +#endif + +static gchar * +dvdnav_get_read_domain_name(dvd_read_domain_t domain) +{ + switch (domain) { + case DVD_READ_INFO_FILE: return "DVD_READ_INFO_FILE"; break; + case DVD_READ_INFO_BACKUP_FILE: return "DVD_READ_INFO_BACKUP_FILE"; break; + case DVD_READ_MENU_VOBS: return "DVD_READ_MENU_VOBS"; break; + case DVD_READ_TITLE_VOBS: return "DVD_READ_TITLE_VOBS"; break; + } + return "UNKNOWN"; } static void dvdnavsrc_loop (GstElement *element) { - DVDNavSrc *dvdnavsrc; - DVDNavSrcPrivate *priv; + DVDNavSrc *src; int done; g_return_if_fail (element != NULL); g_return_if_fail (GST_IS_DVDNAVSRC (element)); - dvdnavsrc = DVDNAVSRC (element); - priv = dvdnavsrc->priv; - g_return_if_fail (GST_FLAG_IS_SET (dvdnavsrc, DVDNAVSRC_OPEN)); + src = DVDNAVSRC (element); + g_return_if_fail (dvdnavsrc_is_open (src)); done = 0; @@ -370,10 +421,11 @@ dvdnavsrc_loop (GstElement *element) unsigned char *data; /* allocate the space for the buffer data */ + /* FIXME: mem leak on non BLOCK_OK events */ data = g_malloc (DVD_VIDEO_LB_LEN); - if (dvdnav_get_next_block (priv->dvdnav, data, &event, &len) != DVDNAV_STATUS_OK) { - fprintf (stderr, "dvdnav_get_next_block error: %s\n", dvdnav_err_to_string(priv->dvdnav)); + if (dvdnav_get_next_block (src->dvdnav, data, &event, &len) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_get_next_block error: %s\n", dvdnav_err_to_string(src->dvdnav)); return; } @@ -386,34 +438,116 @@ dvdnavsrc_loop (GstElement *element) GST_BUFFER_DATA (buf) = data; GST_BUFFER_SIZE (buf) = DVD_VIDEO_LB_LEN; - gst_pad_push(priv->srcpad, buf); + gst_pad_push(src->srcpad, buf); + break; + case DVDNAV_NOP: + printf("dvdnav: received NOP event\n"); + break; + case DVDNAV_STILL_FRAME: + /* FIXME: we should pause for event->length seconds before dvdnav_still_skip */ + { + dvdnav_still_event_t *event = (dvdnav_still_event_t *)data; + fprintf (stderr, "dvdnav: still frame: %d seconds\n", event->length); + if (dvdnav_still_skip (src->dvdnav) != DVDNAV_STATUS_OK) { + fprintf (stderr, "dvdnav_still_skip error: %s\n", dvdnav_err_to_string(src->dvdnav)); + /* FIXME: close the stream??? */ + } + } + break; + case DVDNAV_SPU_STREAM_CHANGE: + { + dvdnav_spu_stream_change_event_t * event = (dvdnav_spu_stream_change_event_t *)data; + fprintf (stderr, "dvdnav: spu_stream_change:\n"); + fprintf (stderr, " physical_wide: %d\n", event->physical_wide); + fprintf (stderr, " physical_letterbox: %d\n", event->physical_letterbox); + fprintf (stderr, " physical_pan_scan: %d\n", event->physical_pan_scan); + fprintf (stderr, " logical: %d\n", event->logical); + } + break; + case DVDNAV_AUDIO_STREAM_CHANGE: + { + dvdnav_audio_stream_change_event_t * event = (dvdnav_audio_stream_change_event_t *)data; + fprintf (stderr, "dvdnav: audio_stream_change:\n"); + fprintf (stderr, " physical: %d\n", event->physical); + fprintf (stderr, " logical: %d\n", event->logical); + } + break; + case DVDNAV_VTS_CHANGE: + { + dvdnav_vts_change_event_t *event = (dvdnav_vts_change_event_t *)data; + fprintf (stderr, "dvdnav: vts_change\n"); + fprintf (stderr, " old_vtsN: %d\n", event->old_vtsN); + fprintf (stderr, " old_domain: %s\n", dvdnav_get_read_domain_name(event->old_domain)); + fprintf (stderr, " new_vtsN: %d\n", event->new_vtsN); + fprintf (stderr, " new_domain: %s\n", dvdnav_get_read_domain_name(event->new_domain)); + } + break; + case DVDNAV_CELL_CHANGE: + { + dvdnav_cell_change_event_t *event = (dvdnav_cell_change_event_t *)data; + fprintf (stderr, "dvdnav: cell_change:\n"); + fprintf (stderr, " old_cell: %p\n", event->old_cell); + fprintf (stderr, " new_cell: %p\n", event->new_cell); + } + break; + case DVDNAV_NAV_PACKET: + { + dvdnav_nav_packet_event_t *event = (dvdnav_nav_packet_event_t *)data; + fprintf (stderr, "dvdnav: nav_packet:\n"); + fprintf (stderr, " pci: %p\n", event->pci); + fprintf (stderr, " dsi: %p\n", event->dsi); + } break; case DVDNAV_STOP: done = 1; - gst_element_set_eos (GST_ELEMENT (dvdnavsrc)); - _close(priv); + gst_element_set_eos (GST_ELEMENT (src)); + dvdnavsrc_close(src); + break; + case DVDNAV_HIGHLIGHT: + { + dvdnav_highlight_event_t *event = (dvdnav_highlight_event_t *)data; + fprintf (stderr, "dvdnav: highlight:\n"); + fprintf (stderr, " display: %s\n", + event->display == 0 ? "hide" : (event->display == 1 ? "show" : "unknown") + ); + if (event->display == 1) { + fprintf (stderr, " palette: %08x\n", event->palette); + fprintf (stderr, " coords (%d, %d) - (%d, %d)\n", event->sx, event->sy, event->ex, event->ey); + fprintf (stderr, " pts: %d\n", event->pts); + fprintf (stderr, " button: %d\n", event->buttonN); + } + } + break; + case DVDNAV_SPU_CLUT_CHANGE: + /* ignore the change events. I'm dont know what I'm meant to do with them */ + /* and there's no struct for it */ + fprintf (stderr, "dvdnav: spu_clut_change\n"); + break; + case DVDNAV_SEEK_DONE: + fprintf (stderr, "dvdnav: seek_done\n"); + break; + case DVDNAV_HOP_CHANNEL: + fprintf (stderr, "dvdnav: hop_channel\n"); break; default: - fprintf (stderr, "dvdnavsrc event: %d\n", event); - break; + fprintf (stderr, "dvdnavsrc event: %d\n", event); + break; } } } #if 0 -static GstBuffer * + static GstBuffer * dvdnavsrc_get (GstPad *pad) { - DVDNavSrc *dvdnavsrc; - DVDNavSrcPrivate *priv; + DVDNavSrc *src; GstBuffer *buf; g_return_val_if_fail (pad != NULL, NULL); g_return_val_if_fail (GST_IS_PAD (pad), NULL); - dvdnavsrc = DVDNAVSRC (gst_pad_get_parent (pad)); - priv = dvdnavsrc->priv; - g_return_val_if_fail (GST_FLAG_IS_SET (dvdnavsrc, DVDNAVSRC_OPEN),NULL); + src = DVDNAVSRC (gst_pad_get_parent (pad)); + g_return_val_if_fail (gstdvdnav_is_open (src), NULL); /* create the buffer */ /* FIXME: should eventually use a bufferpool for this */ @@ -424,18 +558,18 @@ dvdnavsrc_get (GstPad *pad) GST_BUFFER_DATA (buf) = g_malloc (1024 * DVD_VIDEO_LB_LEN); g_return_val_if_fail (GST_BUFFER_DATA (buf) != NULL, NULL); - if (priv->new_seek) { - _seek(priv, priv->titleid, priv->chapid, priv->angle); + if (src->new_seek) { + _seek(src, src->titleid, src->chapid, src->angle); } /* read it in from the file */ - if (_read (priv, priv->angle, priv->new_seek, buf)) { - gst_element_signal_eos (GST_ELEMENT (dvdnavsrc)); + if (_read (src, src->angle, src->new_seek, buf)) { + gst_element_signal_eos (GST_ELEMENT (src)); return NULL; } - if (priv->new_seek) { - priv->new_seek = FALSE; + if (src->new_seek) { + src->new_seek = FALSE; } return buf; @@ -444,18 +578,21 @@ dvdnavsrc_get (GstPad *pad) /* open the file, necessary to go to RUNNING state */ static gboolean -dvdnavsrc_open_file (DVDNavSrc *src) +dvdnavsrc_open (DVDNavSrc *src) { g_return_val_if_fail (src != NULL, FALSE); g_return_val_if_fail (GST_IS_DVDNAVSRC(src), FALSE); - g_return_val_if_fail (!GST_FLAG_IS_SET (src, DVDNAVSRC_OPEN), FALSE); + g_return_val_if_fail (!dvdnavsrc_is_open (src), FALSE); + g_return_val_if_fail (src->location != NULL, FALSE); - if (_open(src->priv, src->priv->location)) + if (dvdnav_open (&src->dvdnav, (char*)src->location) != DVDNAV_STATUS_OK) { + fprintf( stderr, "dvdnav_open error: %s location: %s\n", dvdnav_err_to_string(src->dvdnav), src->location); return FALSE; - if (_seek(src->priv, - src->priv->title, - src->priv->chapter, - src->priv->angle)) + } + if (dvdnavsrc_tca_seek(src, + src->title, + src->chapter, + src->angle)) return FALSE; GST_FLAG_SET (src, DVDNAVSRC_OPEN); @@ -464,33 +601,53 @@ dvdnavsrc_open_file (DVDNavSrc *src) } /* close the file */ -static void -dvdnavsrc_close_file (DVDNavSrc *src) +static gboolean +dvdnavsrc_close (DVDNavSrc *src) { - g_return_if_fail (GST_FLAG_IS_SET (src, DVDNAVSRC_OPEN)); + g_return_val_if_fail (src != NULL, FALSE); + g_return_val_if_fail (GST_IS_DVDNAVSRC(src), FALSE); + g_return_val_if_fail (dvdnavsrc_is_open (src), FALSE); + g_return_val_if_fail (src->dvdnav != NULL, FALSE); - _close(src->priv); + if (dvdnav_close (src->dvdnav) != DVDNAV_STATUS_OK) { + fprintf( stderr, "dvdnav_close error: %s\n", + dvdnav_err_to_string (src->dvdnav)); + return FALSE; + } GST_FLAG_UNSET (src, DVDNAVSRC_OPEN); + + return TRUE; } static GstElementStateReturn dvdnavsrc_change_state (GstElement *element) { + DVDNavSrc *src; + g_return_val_if_fail (GST_IS_DVDNAVSRC (element), GST_STATE_FAILURE); - GST_DEBUG (0,"gstdvdnavsrc: state pending %d", GST_STATE_PENDING (element)); + src = DVDNAVSRC (element); - /* if going down into NULL state, close the file if it's open */ - if (GST_STATE_PENDING (element) == GST_STATE_NULL) { - if (GST_FLAG_IS_SET (element, DVDNAVSRC_OPEN)) - dvdnavsrc_close_file (DVDNAVSRC (element)); - /* otherwise (READY or higher) we need to open the file */ - } else { - if (!GST_FLAG_IS_SET (element, DVDNAVSRC_OPEN)) { - if (!dvdnavsrc_open_file (DVDNAVSRC (element))) - return GST_STATE_FAILURE; - } + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + break; + case GST_STATE_READY_TO_PAUSED: + if (!GST_FLAG_IS_SET (element, DVDNAVSRC_OPEN)) { + if (!dvdnavsrc_open (src)) + return GST_STATE_FAILURE; + } + break; + case GST_STATE_PAUSED_TO_PLAYING: + break; + case GST_STATE_PLAYING_TO_PAUSED: + break; + case GST_STATE_PAUSED_TO_READY: + if (GST_FLAG_IS_SET (element, DVDNAVSRC_OPEN)) + dvdnavsrc_close (src); + break; + case GST_STATE_READY_TO_NULL: + break; } /* if we haven't failed already, give the parent class a chance to ;-) */ diff --git a/ext/dvdnav/dvdnavsrc.h b/ext/dvdnav/dvdnavsrc.h deleted file mode 100644 index abb8bfabec..0000000000 --- a/ext/dvdnav/dvdnavsrc.h +++ /dev/null @@ -1,69 +0,0 @@ -/* GStreamer - * Copyright (C) 2002 David I. Lehn - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#ifndef __DVDNAVSRC_H__ -#define __DVDNAVSRC_H__ - - -#include -#include - - -G_BEGIN_DECLS - -GstElementDetails dvdnavsrc_details; - - -#define GST_TYPE_DVDNAVSRC \ - (dvdnavsrc_get_type()) -#define DVDNAVSRC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DVDNAVSRC,DVDNavSrc)) -#define DVDNAVSRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DVDNAVSRC,DVDNavSrcClass)) -#define GST_IS_DVDNAVSRC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DVDNAVSRC)) -#define GST_IS_DVDNAVSRC_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DVDNAVSRC)) - -/* NOTE: per-element flags start with 16 for now */ -typedef enum { - DVDNAVSRC_OPEN = GST_ELEMENT_FLAG_LAST, - - DVDNAVSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2, -} DVDNavSrcFlags; - -typedef struct _DVDNavSrc DVDNavSrc; -typedef struct _DVDNavSrcPrivate DVDNavSrcPrivate; -typedef struct _DVDNavSrcClass DVDNavSrcClass; - -struct _DVDNavSrc { - GstElement element; - DVDNavSrcPrivate *priv; -}; - -struct _DVDNavSrcClass { - GstElementClass parent_class; -}; - -GType dvdnavsrc_get_type(void); - -G_END_DECLS - -#endif /* __DVDNAVSRC_H__ */