diff --git a/ChangeLog b/ChangeLog index 977c4ea55c..622edaf58b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,45 @@ +2005-01-05 Ronald S. Bultje + + * examples/gstplay/player.c: (main): + Don't iterate. + * examples/seeking/seek.c: (fixate), (make_playerbin_pipeline): + Add visualizations. + * ext/a52dec/gsta52dec.c: (gst_a52dec_push), + (gst_a52dec_handle_frame): + Set duration. + * ext/dvdnav/gst-dvd: + Add audioconvert. Fixes #161325. + * ext/dvdread/dvdreadsrc.c: (dvdreadsrc_get): + Explicitely case to gint64. Possible valgrind error. + * gst-libs/gst/play/play.c: (caps_set), (setup_size), + (gst_play_tick_callback), (gst_play_change_state), + (gst_play_dispose), (gst_play_init), (gst_play_class_init), + (gst_play_set_location), (gst_play_get_location), + (gst_play_seek_to_time), (gst_play_set_data_src), + (gst_play_set_video_sink), (gst_play_set_audio_sink), + (gst_play_set_visualization), (gst_play_connect_visualization), + (gst_play_get_framerate), (gst_play_get_all_by_interface), + (gst_play_new): + Use playbin. Fixes #139749 and #147744. + * gst/apetag/apedemux.c: (gst_ape_demux_parse_tags): + Add genre tag. + * gst/audioscale/gstaudioscale.c: (gst_audioscale_method_get_type), + (audioscale_get_type), (gst_audioscale_base_init), + (gst_audioscale_class_init), (gst_audioscale_expand_caps), + (gst_audioscale_getcaps), (gst_audioscale_fixate), + (gst_audioscale_link), (gst_audioscale_get_buffer), + (gst_audioscale_decrease_rate), (gst_audioscale_increase_rate), + (gst_audioscale_init), (gst_audioscale_dispose), + (gst_audioscale_chain), (gst_audioscale_set_property), + (gst_audioscale_get_property), (plugin_init): + Indent properly. + * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_process_private): + Fix LPCM. + * gst/qtdemux/qtdemux.c: (qtdemux_parse_udta), + (qtdemux_tag_add_str), (qtdemux_tag_add_num), + (qtdemux_tag_add_gnre), (qtdemux_video_caps): + Add more metadata (fixes #162656). + 2005-01-05 Thomas Vander Stichele * configure.ac: diff --git a/examples/gstplay/player.c b/examples/gstplay/player.c index 7a018fe0fa..e0bdd413ad 100644 --- a/examples/gstplay/player.c +++ b/examples/gstplay/player.c @@ -90,13 +90,6 @@ seek_timer (GstPlay * play) return FALSE; } -static gboolean -idle_iterate (GstPlay * play) -{ - gst_bin_iterate (GST_BIN (play)); - return (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING); -} - int main (int argc, char *argv[]) { @@ -168,7 +161,6 @@ main (int argc, char *argv[]) GST_STATE_PLAYING) == GST_STATE_FAILURE) g_error ("Could not set state to PLAYING"); - g_idle_add ((GSourceFunc) idle_iterate, play); g_timeout_add (20000, (GSourceFunc) seek_timer, play); g_main_loop_run (loop); diff --git a/examples/seeking/seek.c b/examples/seeking/seek.c index c85ca8b02d..4a5d51ab01 100644 --- a/examples/seeking/seek.c +++ b/examples/seeking/seek.c @@ -551,15 +551,45 @@ make_mpegnt_pipeline (const gchar * location) return pipeline; } +static GstCaps * +fixate (GstPad * pad, const GstCaps * in_caps, gpointer data) +{ + GstCaps *caps; + GstStructure *s; + + if (gst_caps_get_size (in_caps) > 1) + return NULL; + + /* nothing if fixed already */ + s = gst_caps_get_structure (in_caps, 0); + if (gst_structure_has_field_typed (s, "width", G_TYPE_INT) && + gst_structure_has_field_typed (s, "height", G_TYPE_INT) && + gst_structure_has_field_typed (s, "framerate", G_TYPE_DOUBLE)) + return NULL; + + /* fixate */ + caps = gst_caps_copy (in_caps); + s = gst_caps_get_structure (caps, 0); + gst_caps_structure_fixate_field_nearest_int (s, "width", 200); + gst_caps_structure_fixate_field_nearest_int (s, "height", 150); + gst_caps_structure_fixate_field_nearest_double (s, "framerate", 10.0); + + return caps; +} + static GstElement * make_playerbin_pipeline (const gchar * location) { - GstElement *player; + GstElement *player, *vis; player = gst_element_factory_make ("playbin", "player"); + vis = gst_element_factory_make ("synaesthesia", "vis"); g_assert (player); + g_assert (vis); - g_object_set (G_OBJECT (player), "uri", location, NULL); + g_signal_connect (gst_element_get_pad (vis, "src"), "fixate", + G_CALLBACK (fixate), NULL); + g_object_set (G_OBJECT (player), "uri", location, "vis-plugin", vis, NULL); seekable_elements = g_list_prepend (seekable_elements, player); diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index 82e4a31805..7412650fd1 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -162,8 +162,13 @@ static QtNodeType *qtdemux_type_get (guint32 fourcc); static void qtdemux_node_dump (GstQTDemux * qtdemux, GNode * node); static void qtdemux_parse_tree (GstQTDemux * qtdemux); static void qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta); -static void qtdemux_tag_add (GstQTDemux * qtdemux, const char *tag, +static void qtdemux_tag_add_str (GstQTDemux * qtdemux, const char *tag, GNode * node); +static void qtdemux_tag_add_num (GstQTDemux * qtdemux, const char *tag1, + const char *tag2, GNode * node); +static void qtdemux_tag_add_gnre (GstQTDemux * qtdemux, const char *tag, + GNode * node); + static void gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * esds); static GstCaps *qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc, @@ -899,8 +904,11 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux, QtDemuxStream * stream) #define FOURCC_ilst GST_MAKE_FOURCC('i','l','s','t') #define FOURCC__nam GST_MAKE_FOURCC(0xa9,'n','a','m') #define FOURCC__ART GST_MAKE_FOURCC(0xa9,'A','R','T') +#define FOURCC__wrt GST_MAKE_FOURCC(0xa9,'w','r','t') +#define FOURCC__grp GST_MAKE_FOURCC(0xa9,'g','r','p') #define FOURCC__alb GST_MAKE_FOURCC(0xa9,'a','l','b') #define FOURCC_gnre GST_MAKE_FOURCC('g','n','r','e') +#define FOURCC_disc GST_MAKE_FOURCC('d','i','s','c') #define FOURCC_trkn GST_MAKE_FOURCC('t','r','k','n') #define FOURCC_cpil GST_MAKE_FOURCC('c','p','i','l') #define FOURCC_tmpo GST_MAKE_FOURCC('t','m','p','o') @@ -997,9 +1005,12 @@ QtNodeType qt_node_types[] = { {FOURCC_ilst, "ilst", QT_CONTAINER,}, {FOURCC__nam, "Name", QT_CONTAINER,}, {FOURCC__ART, "Artist", QT_CONTAINER,}, + {FOURCC__wrt, "Writer", QT_CONTAINER,}, + {FOURCC__grp, "Group", QT_CONTAINER,}, {FOURCC__alb, "Album", QT_CONTAINER,}, {FOURCC_gnre, "Genre", QT_CONTAINER,}, {FOURCC_trkn, "Track Number", QT_CONTAINER,}, + {FOURCC_disc, "Disc Number", QT_CONTAINER,}, {FOURCC_cpil, "cpil", QT_CONTAINER,}, {FOURCC_tmpo, "Tempo", QT_CONTAINER,}, {FOURCC__too, "too", QT_CONTAINER,}, @@ -2302,24 +2313,49 @@ qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta) node = qtdemux_tree_get_child_by_type (ilst, FOURCC__nam); if (node) { - qtdemux_tag_add (qtdemux, GST_TAG_TITLE, node); + qtdemux_tag_add_str (qtdemux, GST_TAG_TITLE, node); } node = qtdemux_tree_get_child_by_type (ilst, FOURCC__ART); if (node) { - qtdemux_tag_add (qtdemux, GST_TAG_ARTIST, node); + qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node); + } else { + node = qtdemux_tree_get_child_by_type (ilst, FOURCC__wrt); + if (node) { + qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node); + } else { + node = qtdemux_tree_get_child_by_type (ilst, FOURCC__grp); + if (node) { + qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node); + } + } } node = qtdemux_tree_get_child_by_type (ilst, FOURCC__alb); if (node) { - qtdemux_tag_add (qtdemux, GST_TAG_ALBUM, node); + qtdemux_tag_add_str (qtdemux, GST_TAG_ALBUM, node); } + node = qtdemux_tree_get_child_by_type (ilst, FOURCC_trkn); + if (node) { + qtdemux_tag_add_num (qtdemux, GST_TAG_TRACK_NUMBER, + GST_TAG_TRACK_COUNT, node); + } + node = qtdemux_tree_get_child_by_type (ilst, FOURCC_disc); + if (node) { + qtdemux_tag_add_num (qtdemux, GST_TAG_ALBUM_VOLUME_NUMBER, + GST_TAG_ALBUM_VOLUME_COUNT, node); + } + + node = qtdemux_tree_get_child_by_type (ilst, FOURCC_gnre); + if (node) { + qtdemux_tag_add_gnre (qtdemux, GST_TAG_GENRE, node); + } } static void -qtdemux_tag_add (GstQTDemux * qtdemux, const char *tag, GNode * node) +qtdemux_tag_add_str (GstQTDemux * qtdemux, const char *tag, GNode * node) { GNode *data; char *s; @@ -2339,6 +2375,83 @@ qtdemux_tag_add (GstQTDemux * qtdemux, const char *tag, GNode * node) } } +static void +qtdemux_tag_add_num (GstQTDemux * qtdemux, const char *tag1, + const char *tag2, GNode * node) +{ + GNode *data; + int len; + int type; + int n1, n2; + + data = qtdemux_tree_get_child_by_type (node, FOURCC_data); + if (data) { + len = QTDEMUX_GUINT32_GET (data->data); + type = QTDEMUX_GUINT32_GET (data->data + 8); + if (type == 0x00000000 && len >= 22) { + n1 = GST_READ_UINT16_BE (data->data + 18); + n2 = GST_READ_UINT16_BE (data->data + 20); + GST_DEBUG ("adding tag %d/%d\n", n1, n2); + gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, + tag1, n1, tag2, n2, NULL); + } + } +} + +static void +qtdemux_tag_add_gnre (GstQTDemux * qtdemux, const char *tag, GNode * node) +{ + const gchar *genres[] = { + "N/A", "Blues", "Classic Rock", "Country", "Dance", "Disco", + "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", + "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", + "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", + "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", + "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", + "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", + "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", + "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", + "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", + "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", + "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", + "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", + "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", + "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", + "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", "Bebob", + "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", + "Gothic Rock", "Progressive Rock", "Psychedelic Rock", + "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", + "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", + "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", + "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", + "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", + "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella", + "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club House", + "Hardcore", "Terror", "Indie", "BritPop", "NegerPunk", + "Polsk Punk", "Beat", "Christian Gangsta", "Heavy Metal", + "Black Metal", "Crossover", "Contemporary C", "Christian Rock", + "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "SynthPop" + }; + GNode *data; + int len; + int type; + int n; + + data = qtdemux_tree_get_child_by_type (node, FOURCC_data); + if (data) { + len = QTDEMUX_GUINT32_GET (data->data); + type = QTDEMUX_GUINT32_GET (data->data + 8); + if (type == 0x00000000 && len >= 18) { + n = GST_READ_UINT16_BE (data->data + 16); + if (n > 0 && n < sizeof (genres) / sizeof (char *)) { + GST_DEBUG ("adding %d [%s]\n", n, genres[n]); + gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, + tag, genres[n], NULL); + } + } + } +} + /* taken from ffmpeg */ static unsigned int get_size (guint8 * ptr, guint8 ** end) @@ -2527,6 +2640,9 @@ qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc, case GST_MAKE_FOURCC ('r', 'p', 'z', 'a'): /* Apple Video */ return gst_caps_from_string ("video/x-apple-video"); + case GST_MAKE_FOURCC ('a', 'v', 'c', '1'): + /* H.264/AVC */ + return gst_caps_from_string ("video/x-h264"); case GST_MAKE_FOURCC ('r', 'l', 'e', ' '): /* Run-length encoding */ case GST_MAKE_FOURCC ('s', 'm', 'c', ' '):