$OpenBSD: patch-src_gmtk_media_player_c,v 1.13 2013/07/12 09:58:56 dcoppa Exp $

If the user gives some mplayer video output driver (vo) options in
the "Video Output" preferences they should be passed along on the
mplayer command line (upstream svn revision r222)

Use case-insensitive parsing of metadata attributes
(upstream svn revision r212)

Fix OSD messages so they only displayed for level 1 and higher
(upstream svn revision r216)

Exclude input.conf from file not found message
(upstream svn revision r213)

Fix issue #682: item names in "Items to Play" replaced with CPUID
string (upstream svn revision r220)

--- src/gmtk_media_player.c.orig	Tue Feb 19 18:02:13 2013
+++ src/gmtk_media_player.c	Fri Jul 12 11:31:22 2013
@@ -75,6 +75,22 @@ static void alignment_realized(GtkWidget * widget, gpo
 
 }
 
+static gboolean vodesc_looks_like_vo(gchar const*const desc, gchar const*const vo) {
+   if(g_strcmp0(desc, vo) == 0) {
+      return TRUE;
+   }
+   if(!g_str_has_prefix(desc, vo)) {
+      return FALSE;
+   }
+   /* we know that they are not equal but desc starts with vo, i.e. desc is longer than vo */
+   /* now to check that desc looks like vo: */
+   const size_t vol = strlen(vo);
+   if(desc[vol] == ':') {
+      return TRUE;
+   }
+   return FALSE;
+}
+
 static void socket_realized(GtkWidget * widget, gpointer data)
 {
     GmtkMediaPlayer *player = GMTK_MEDIA_PLAYER(data);
@@ -83,7 +99,7 @@ static void socket_realized(GtkWidget * widget, gpoint
     player->socket_id = GPOINTER_TO_INT(gtk_socket_get_id(GTK_SOCKET(widget)));
     style = gtk_widget_get_style(widget);
     if (player->vo != NULL) {
-        if (!(g_ascii_strncasecmp(player->vo, "vdpau", strlen("vdpau")) == 0)) {
+        if (!vodesc_looks_like_vo(player->vo, "vdpau")) {
             gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &(style->black));
             gtk_widget_modify_bg(widget, GTK_STATE_ACTIVE, &(style->black));
             gtk_widget_modify_bg(widget, GTK_STATE_SELECTED, &(style->black));
@@ -477,6 +493,13 @@ static void gmtk_media_player_init(GmtkMediaPlayer * p
     player->album = NULL;
     player->disposed = FALSE;
     player->player_lock = g_mutex_new();
+    player->name_regex = g_regex_new(".*name\\s*:\\s*(.*)\n", G_REGEX_CASELESS, 0, NULL);
+    player->genre_regex = g_regex_new(".*genre\\s*:\\s*(.*)\n", G_REGEX_CASELESS, 0, NULL);
+    player->title_regex = g_regex_new(".*title\\s*:\\s*(.*)\n", G_REGEX_CASELESS, 0, NULL);
+    player->artist_regex = g_regex_new(".*artist\\s*:\\s*(.*)\n", G_REGEX_CASELESS, 0, NULL);
+    player->album_regex = g_regex_new(".*album\\s*:\\s*(.*)\n", G_REGEX_CASELESS, 0, NULL);
+    player->deintN_regex = g_regex_new("(.*)(:deint=[0-9]+)\\b(.*)", G_REGEX_CASELESS, 0, NULL);
+
     gmtk_media_player_log_state(player, "after init");
 }
 
@@ -741,7 +764,7 @@ static gboolean player_key_press_event_callback(GtkWid
         case GDK_d:
             write_to_mplayer(player, "frame_drop\n");
             cmd =
-                g_strdup_printf("osd_show_property_text \"%s: ${framedropping}\"\n",
+                g_strdup_printf("osd_show_property_text \"%s: ${framedropping}\" 1000 1\n",
                                 g_dgettext(GETTEXT_PACKAGE, "Frame Dropping"));
             write_to_mplayer(player, cmd);
             g_free(cmd);
@@ -755,7 +778,7 @@ static gboolean player_key_press_event_callback(GtkWid
         case GDK_D:
             write_to_mplayer(player, "step_property deinterlace\n");
             cmd =
-                g_strdup_printf("osd_show_property_text \"%s: ${deinterlace}\"\n",
+                g_strdup_printf("osd_show_property_text \"%s: ${deinterlace}\" 1000 1\n",
                                 g_dgettext(GETTEXT_PACKAGE, "Deinterlace"));
             write_to_mplayer(player, cmd);
             g_free(cmd);
@@ -1119,7 +1142,7 @@ void gmtk_media_player_send_command(GmtkMediaPlayer * 
         case COMMAND_SWITCH_FRAME_DROP:
             write_to_mplayer(player, "frame_drop\n");
             cmd =
-                g_strdup_printf("osd_show_property_text \"%s ${framedropping}\"\n",
+                g_strdup_printf("osd_show_property_text \"%s ${framedropping}\" 1000 1\n",
                                 g_dgettext(GETTEXT_PACKAGE, "Frame Dropping"));
             write_to_mplayer(player, cmd);
             g_free(cmd);
@@ -1147,11 +1170,12 @@ void gmtk_media_player_set_attribute_boolean(GmtkMedia
             cmd = NULL;
             if (value) {
                 cmd =
-                    g_strdup_printf("osd_show_property_text \"%s\"\n",
+                    g_strdup_printf("osd_show_property_text \"%s\" 1000 1\n",
                                     g_dgettext(GETTEXT_PACKAGE, "Subtitles Visible"));
             } else {
                 cmd =
-                    g_strdup_printf("osd_show_property_text \"%s\"\n", g_dgettext(GETTEXT_PACKAGE, "Subtitles Hidden"));
+                    g_strdup_printf("osd_show_property_text \"%s\" 1000 1\n",
+                                    g_dgettext(GETTEXT_PACKAGE, "Subtitles Hidden"));
             }
             write_to_mplayer(player, cmd);
             g_free(cmd);
@@ -1775,6 +1799,14 @@ const gchar *gmtk_media_player_get_attribute_string(Gm
         }
         break;
 
+    case ATTRIBUTE_GENRE:
+        if (player->genre == NULL || strlen(player->genre) == 0) {
+            value = NULL;
+        } else {
+            value = player->genre;
+        }
+        break;
+
     case ATTRIBUTE_PROFILE:
         value = player->profile;
         break;
@@ -2208,8 +2240,50 @@ static const gchar *playback_error_to_string(const Gmt
 
 }
 
+/* if it contains a deint=N leave as is, otherwise add deint=2
+   returns newly-allocated string, passing ownership to caller */
+static gchar* vdpau_compute_vo_with_deint(GmtkMediaPlayer * player, gchar const*const vodesc) {
+   gchar* ret;
+   if(g_regex_match(player->deintN_regex, vodesc, 0, NULL)) { 
+      ret = g_strdup(vodesc);
+   } else {
+      ret = g_strdup_printf("%s:deint=2", vodesc);
+   }
+   return ret;
+}
 
+/* if it contains a deint=N  remove that, otherwise leave as is
+   returns newly-allocated string, passing ownership to caller */
+static gchar* vdpau_compute_vo_without_deint(GmtkMediaPlayer * player, gchar const*const vodesc) {
+   GMatchInfo *match_info = NULL;
+   gchar *ret;
+   if(g_regex_match(player->deintN_regex, vodesc, 0, &match_info)) { 
+      gchar *before = g_match_info_fetch(match_info, 1);
+      gchar *after  = g_match_info_fetch(match_info, 3);
+      ret = g_strdup_printf("%s%s", before, after);
+      g_free(before);
+      g_free(after);
+   } else {
+      ret = g_strdup(vodesc);
+   }
+   g_match_info_free(match_info);
+   return ret;
+}
 
+/* replace the vo part with "gl_nosw"
+   returns newly-allocated string, passing ownership to caller */
+static gchar* vodesc_replace_gl_with_gl_nosw(GmtkMediaPlayer * player, gchar const*const vodesc) {
+   /* find the first colon : and replace the part before that with gl_nosw */
+   char *colonptr = strchr(vodesc, ':');
+   gchar *ret;
+   if(colonptr == NULL) {
+      ret = g_strdup("gl_nosw");
+   } else {
+      ret = g_strdup_printf("gl_nosw%s", colonptr);
+   }
+   return ret;   
+}
+
 gpointer launch_mplayer(gpointer data)
 {
     GmtkMediaPlayer *player = GMTK_MEDIA_PLAYER(data);
@@ -2321,12 +2395,18 @@ gpointer launch_mplayer(gpointer data)
         if (player->vo != NULL) {
             argv[argn++] = g_strdup_printf("-vo");
 
-            if (g_ascii_strncasecmp(player->vo, "vdpau", strlen("vdpau")) == 0) {
+            if (vodesc_looks_like_vo(player->vo, "vdpau")) {
 
                 if (player->deinterlace) {
-                    argv[argn++] = g_strdup_printf("vdpau:deint=2,%s,gl,x11", player->vo);
+                    /* if it contains a deint=N leave as is, otherwise add deint=2 */
+                    gchar* vo_with_deint = vdpau_compute_vo_with_deint(player, player->vo);
+                    argv[argn++] = g_strdup_printf("%s,gl,x11,", player->vo);
+                    g_free(vo_with_deint);
                 } else {
-                    argv[argn++] = g_strdup_printf("%s,gl,x11", player->vo);
+                    /* if it contains a deint=N remove that, otherwise leave as is */
+                    gchar* vo_without_deint = vdpau_compute_vo_without_deint(player, player->vo);
+                    argv[argn++] = g_strdup_printf("%s,gl,x11,", player->vo);
+                    g_free(vo_without_deint);
                 }
 
                 // told by uau that vdpau without hardware decoding is often what you want
@@ -2339,12 +2419,12 @@ gpointer launch_mplayer(gpointer data)
                     }
                 }
 
-            } else if (g_ascii_strncasecmp(player->vo, "vaapi", strlen("vaapi")) == 0) {
+            } else if (vodesc_looks_like_vo(player->vo, "vaapi")) {
                 argv[argn++] = g_strdup_printf("%s,", player->vo);
                 argv[argn++] = g_strdup_printf("-va");
                 argv[argn++] = g_strdup_printf("vaapi");
 
-            } else if (g_ascii_strncasecmp(player->vo, "xvmc", strlen("xvmc")) == 0) {
+            } else if (vodesc_looks_like_vo(player->vo, "xvmc")) {
 
                 if (player->disable_xvmc) {
                     argv[argn++] = g_strdup_printf("xv,");
@@ -2354,13 +2434,15 @@ gpointer launch_mplayer(gpointer data)
 
             } else {
 
-                if (g_ascii_strncasecmp(player->vo, "gl", strlen("gl")) == 0 && player->enable_hardware_codecs) {
-                    argv[argn++] = g_strdup_printf("gl_nosw");
-                } else if (g_ascii_strncasecmp(player->vo, "gl2", strlen("gl2")) == 0 && player->enable_hardware_codecs) {
-                    argv[argn++] = g_strdup_printf("gl_nosw");
+                if (vodesc_looks_like_vo(player->vo, "gl") && player->enable_hardware_codecs) {
+                    gchar *vodesc = vodesc_replace_gl_with_gl_nosw(player, player->vo);
+                    argv[argn++]  = vodesc;
+                } else if (vodesc_looks_like_vo(player->vo, "gl2") && player->enable_hardware_codecs) {
+                    gchar *vodesc = vodesc_replace_gl_with_gl_nosw(player, player->vo);
+                    argv[argn++]  = vodesc;
                 } else {
                     argv[argn++] = g_strdup_printf("%s", player->vo);
-                    if (g_ascii_strncasecmp(player->vo, "x11", strlen("x11")) == 0) {
+                    if (vodesc_looks_like_vo(player->vo, "x11")) {
                         argv[argn++] = g_strdup_printf("-zoom");
                     }
                 }
@@ -3010,7 +3092,7 @@ gboolean thread_reader_error(GIOChannel * source, GIOC
         }
 
         if (strstr(mplayer_output->str, "Failed creating VDPAU decoder") != NULL) {
-            if (player->enable_divx && (g_ascii_strncasecmp(player->vo, "vdpau", strlen("vdpau")) == 0))
+            if (player->enable_divx && vodesc_looks_like_vo(player->vo, "vdpau"))
                 player->playback_error = ERROR_RETRY_WITHOUT_DIVX_VDPAU;
         }
 
@@ -3020,7 +3102,7 @@ gboolean thread_reader_error(GIOChannel * source, GIOC
         }
 
         if (strstr(mplayer_output->str, "The selected video_out device is incompatible with this codec") != NULL) {
-            if (!player->disable_xvmc && (g_ascii_strncasecmp(player->vo, "xvmc", strlen("xvmc")) == 0))
+            if (!player->disable_xvmc && vodesc_looks_like_vo(player->vo, "xvmc"))
                 player->playback_error = ERROR_RETRY_WITHOUT_XVMC;
         }
 
@@ -3042,6 +3124,7 @@ gboolean thread_reader_error(GIOChannel * source, GIOC
 
         if (strstr(mplayer_output->str, "Failed to open") != NULL) {
             if (strstr(mplayer_output->str, "LIRC") == NULL &&
+                strstr(mplayer_output->str, "input.conf") == NULL &&
                 strstr(mplayer_output->str, "/dev/rtc") == NULL &&
                 strstr(mplayer_output->str, "VDPAU") == NULL && strstr(mplayer_output->str, "registry file") == NULL) {
                 if (strstr(mplayer_output->str, "<") == NULL && strstr(mplayer_output->str, ">") == NULL
@@ -3161,6 +3244,8 @@ gboolean thread_reader(GIOChannel * source, GIOConditi
     GmtkMediaPlayerAudioTrack *audio_track = NULL;
     GList *iter;
     GtkWidget *dialog;
+    gchar **split;
+    gint index;
 
     if (player == NULL) {
         gm_log(player->debug, G_LOG_LEVEL_MESSAGE, "player is NULL");
@@ -3635,94 +3720,120 @@ gboolean thread_reader(GIOChannel * source, GIOConditi
             gtk_widget_destroy(dialog);
         }
 
-        if (strstr(mplayer_output->str, "Name   : ") != 0) {
-            buf = strstr(mplayer_output->str, "Name   : ");
-            buf = strstr(mplayer_output->str, "Name   : ") + strlen("Name   : ");
-            buf = g_strchomp(buf);
-            if (player->title != NULL) {
-                g_free(player->title);
-                player->title = NULL;
-            }
+        if (g_regex_match(player->name_regex, mplayer_output->str, 0, NULL) \
+        && (g_strrstr(mplayer_output->str, "CPU vendor name:") == NULL)) {
+            split = g_regex_split(player->name_regex, mplayer_output->str, 0);
+            index = 0;
+            while (split[index]) {
+                if (strlen(split[index]) > 0) {
+                    if (player->title != NULL) {
+                        g_free(player->title);
+                        player->title = NULL;
+                    }
 
-            player->title = g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
-            if (player->title == NULL) {
-                player->title = g_strdup(buf);
-                gm_str_strip_unicode(player->title, strlen(player->title));
+                    player->title = g_locale_to_utf8(split[index], -1, NULL, NULL, NULL);
+                    if (player->title == NULL) {
+                        player->title = g_strdup(split[index]);
+                        gm_str_strip_unicode(player->title, strlen(player->title));
+                    }
+                    player->has_metadata = TRUE;
+                    create_event_int(player, "attribute-changed", ATTRIBUTE_TITLE);
+                }
+                index++;
             }
-            player->has_metadata = TRUE;
-            create_event_int(player, "attribute-changed", ATTRIBUTE_TITLE);
+            g_strfreev(split);
         }
 
-        if (strstr(mplayer_output->str, "Genre  : ") != 0) {
-            buf = strstr(mplayer_output->str, "Genre  : ");
-            buf = strstr(mplayer_output->str, "Genre  : ") + strlen("Genre  : ");
-            buf = g_strchomp(buf);
-            if (player->artist != NULL) {
-                g_free(player->artist);
-                player->artist = NULL;
-            }
+        if (g_regex_match(player->genre_regex, mplayer_output->str, 0, NULL)) {
+            split = g_regex_split(player->genre_regex, mplayer_output->str, 0);
+            index = 0;
+            while (split[index]) {
+                if (strlen(split[index]) > 0) {
+                    if (player->title != NULL) {
+                        g_free(player->genre);
+                        player->title = NULL;
+                    }
 
-            player->artist = g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
-            if (player->artist == NULL) {
-                player->artist = g_strdup(buf);
-                gm_str_strip_unicode(player->artist, strlen(player->artist));
+                    player->genre = g_locale_to_utf8(split[index], -1, NULL, NULL, NULL);
+                    if (player->genre == NULL) {
+                        player->genre = g_strdup(split[index]);
+                        gm_str_strip_unicode(player->genre, strlen(player->genre));
+                    }
+                    player->has_metadata = TRUE;
+                    create_event_int(player, "attribute-changed", ATTRIBUTE_GENRE);
+                }
+                index++;
             }
-            player->has_metadata = TRUE;
-            create_event_int(player, "attribute-changed", ATTRIBUTE_ARTIST);
+            g_strfreev(split);
         }
 
-        if (strstr(mplayer_output->str, "Title: ") != 0) {
-            buf = strstr(mplayer_output->str, "Title:");
-            buf = strstr(mplayer_output->str, "Title: ") + strlen("Title: ");
-            buf = g_strchomp(buf);
-            if (player->title != NULL) {
-                g_free(player->title);
-                player->title = NULL;
-            }
+        if (g_regex_match(player->title_regex, mplayer_output->str, 0, NULL)) {
+            split = g_regex_split(player->title_regex, mplayer_output->str, 0);
+            index = 0;
+            while (split[index]) {
+                if (strlen(split[index]) > 0) {
+                    if (player->title != NULL) {
+                        g_free(player->title);
+                        player->title = NULL;
+                    }
 
-            player->title = g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
-            if (player->title == NULL) {
-                player->title = g_strdup(buf);
-                gm_str_strip_unicode(player->title, strlen(player->title));
+                    player->title = g_locale_to_utf8(split[index], -1, NULL, NULL, NULL);
+                    if (player->title == NULL) {
+                        player->title = g_strdup(split[index]);
+                        gm_str_strip_unicode(player->title, strlen(player->title));
+                    }
+                    player->has_metadata = TRUE;
+                    create_event_int(player, "attribute-changed", ATTRIBUTE_TITLE);
+                }
+                index++;
             }
-            player->has_metadata = TRUE;
-            create_event_int(player, "attribute-changed", ATTRIBUTE_TITLE);
+            g_strfreev(split);
         }
 
-        if (strstr(mplayer_output->str, "Artist: ") != 0) {
-            buf = strstr(mplayer_output->str, "Artist:");
-            buf = strstr(mplayer_output->str, "Artist: ") + strlen("Artist: ");
-            buf = g_strchomp(buf);
-            if (player->artist != NULL) {
-                g_free(player->artist);
-                player->artist = NULL;
-            }
+        if (g_regex_match(player->artist_regex, mplayer_output->str, 0, NULL)) {
+            split = g_regex_split(player->artist_regex, mplayer_output->str, 0);
+            index = 0;
+            while (split[index]) {
+                if (strlen(split[index]) > 0) {
+                    if (player->artist != NULL) {
+                        g_free(player->artist);
+                        player->artist = NULL;
+                    }
 
-            player->artist = g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
-            if (player->artist == NULL) {
-                player->artist = g_strdup(buf);
-                gm_str_strip_unicode(player->artist, strlen(player->artist));
+                    player->artist = g_locale_to_utf8(split[index], -1, NULL, NULL, NULL);
+                    if (player->artist == NULL) {
+                        player->artist = g_strdup(split[index]);
+                        gm_str_strip_unicode(player->artist, strlen(player->artist));
+                    }
+                    player->has_metadata = TRUE;
+                    create_event_int(player, "attribute-changed", ATTRIBUTE_ARTIST);
+                }
+                index++;
             }
-            player->has_metadata = TRUE;
-            create_event_int(player, "attribute-changed", ATTRIBUTE_ARTIST);
+            g_strfreev(split);
         }
 
-        if (strstr(mplayer_output->str, "Album: ") != 0) {
-            buf = strstr(mplayer_output->str, "Album:");
-            buf = strstr(mplayer_output->str, "Album: ") + strlen("Album: ");
-            buf = g_strchomp(buf);
-            if (player->album != NULL) {
-                g_free(player->album);
-                player->album = NULL;
-            }
+        if (g_regex_match(player->album_regex, mplayer_output->str, 0, NULL)) {
+            split = g_regex_split(player->album_regex, mplayer_output->str, 0);
+            index = 0;
+            while (split[index]) {
+                if (strlen(split[index]) > 0) {
+                    if (player->album != NULL) {
+                        g_free(player->album);
+                        player->album = NULL;
+                    }
 
-            player->album = g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
-            if (player->album == NULL) {
-                player->album = g_strdup(buf);
-                gm_str_strip_unicode(player->album, strlen(player->album));
+                    player->album = g_locale_to_utf8(split[index], -1, NULL, NULL, NULL);
+                    if (player->album == NULL) {
+                        player->album = g_strdup(split[index]);
+                        gm_str_strip_unicode(player->album, strlen(player->album));
+                    }
+                    player->has_metadata = TRUE;
+                    create_event_int(player, "attribute-changed", ATTRIBUTE_ALBUM);
+                }
+                index++;
             }
-            player->has_metadata = TRUE;
-            create_event_int(player, "attribute-changed", ATTRIBUTE_ALBUM);
+            g_strfreev(split);
         }
 
         if (player->minimum_mplayer == FALSE) {
