changeset 12104:fdce1dd97638

Support for selecting subtitles with -slang. Patch by Andriy N Gritsenko <andrej at lucky onedot net>
author mosu
date Fri, 02 Apr 2004 19:20:34 +0000
parents c34eafa805d5
children 8e2fa34b6d11
files libmpdemux/demux_ogg.c
diffstat 1 files changed, 86 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_ogg.c	Fri Apr 02 10:55:13 2004 +0000
+++ b/libmpdemux/demux_ogg.c	Fri Apr 02 19:20:34 2004 +0000
@@ -113,6 +113,7 @@
   int vorbis;
   int theora;
   int flac;
+  int text;
 } ogg_stream_t;
 
 typedef struct ogg_demuxer {
@@ -140,6 +141,8 @@
 
 extern int index_mode;
 
+extern char *dvdsub_lang, *audio_lang;
+
 //-------- subtitle support - should be moved to decoder layer, and queue
 //                          - subtitles up in demuxer buffer...
 
@@ -393,9 +396,69 @@
   return data;
 }
 
+// check if clang has substring from comma separated langlist
+static int demux_ogg_check_lang(char *clang, char *langlist)
+{
+  char *c;
+
+  if (!langlist || !*langlist)
+    return 0;
+  while ((c = strchr(langlist, ',')))
+  {
+    if (!strncasecmp(clang, langlist, c - langlist))
+      return 1;
+    langlist = &c[1];
+  }
+  if (!strncasecmp(clang, langlist, strlen(langlist)))
+    return 1;
+  return 0;
+}
+
+/// Try to print out comments and also check for LANGUAGE= tag
+static void demux_ogg_check_comments(demuxer_t *d, ogg_stream_t *os, int id, vorbis_comment *vc)
+{
+  char *hdr, *val;
+  char **cmt = vc->user_comments;
+
+  while(*cmt)
+  {
+    hdr = NULL;
+    if (!strncasecmp(*cmt, "ENCODED_USING=", 14))
+    {
+      hdr = "Software";
+      val = *cmt + 14;
+    }
+    else if (!strncasecmp(*cmt, "LANGUAGE=", 9))
+    {
+      val = *cmt + 9;
+      // check for -slang if subs are uninitialized yet
+      if (os->text && d->sub->id == -1 && demux_ogg_check_lang(val, dvdsub_lang))
+      {
+	d->sub->id = id;
+	mp_msg(MSGT_DEMUX, MSGL_V, "Stream language matched -slang: %s\n", val);
+      }
+      else
+	hdr = "Language";
+    }
+    else if (!strncasecmp(*cmt, "ENCODER_URL=", 12))
+    {
+      hdr = "Encoder URL";
+      val = *cmt + 12;
+    }
+    else if (!strncasecmp(*cmt, "TITLE=", 6))
+    {
+      hdr = "Name";
+      val = *cmt + 6;
+    }
+    if (hdr)
+      mp_msg(MSGT_DEMUX, MSGL_V, " %s: %s\n", hdr, val);
+    cmt++;
+  }
+}
+
 /// Calculate the timestamp and add the packet to the demux stream
 // return 1 if the packet was added, 0 otherwise
-static int demux_ogg_add_packet(demux_stream_t* ds,ogg_stream_t* os,ogg_packet* pack) {
+static int demux_ogg_add_packet(demux_stream_t* ds,ogg_stream_t* os,int id,ogg_packet* pack) {
   demuxer_t* d = ds->demuxer;
   demux_packet_t* dp;
   unsigned char* data;
@@ -403,8 +466,23 @@
   int flags = 0;
   void *context = NULL;
 
-  if (ds == d->sub) { // don't want to add subtitles to the demuxer for now
-    demux_ogg_add_sub(os,pack);
+  // If packet is an comment header then we try to get comments at first
+  if (pack->bytes >= 7 && !memcmp(pack->packet, "\003vorbis", 7))
+  {
+    vorbis_info vi;
+    vorbis_comment vc;
+
+    vorbis_info_init(&vi);
+    vorbis_comment_init(&vc);
+    vi.rate = 1L; // it's checked by vorbis_synthesis_headerin()
+    if(vorbis_synthesis_headerin(&vi, &vc, pack) == 0) // if no errors
+      demux_ogg_check_comments(d, os, id, &vc);
+    vorbis_comment_clear(&vc);
+    vorbis_info_clear(&vi);
+  }
+  if (os->text) {
+    if (id == d->sub->id) // don't want to add subtitles to the demuxer for now
+      demux_ogg_add_sub(os,pack);
     return 0;
   }
   // If packet is an header we jump it except for vorbis and theora
@@ -810,6 +888,7 @@
       } else if (strncmp(st->streamtype, "text", 4) == 0) {
           mp_msg(MSGT_DEMUX, MSGL_V, "OGG stream %d is text\n", ogg_d->num_sub);
 	  ogg_d->subs[ogg_d->num_sub].samplerate= get_uint64(&st->time_unit)/10;
+	  ogg_d->subs[ogg_d->num_sub].text = 1;
           n_text++;
           demux_ogg_init_sub();
 	//// Unknown header type
@@ -850,7 +929,7 @@
       if(ds && !s->end_pos) {
 	/// Finish the page, otherwise packets will be lost
 	do {
-	  demux_ogg_add_packet(ds,&ogg_d->subs[ogg_d->num_sub],&pack);
+	  demux_ogg_add_packet(ds,&ogg_d->subs[ogg_d->num_sub],ogg_d->num_sub,&pack);
 	} while(ogg_stream_packetout(&ogg_d->subs[ogg_d->num_sub].stream,&pack) == 1);
       }
     }
@@ -954,11 +1033,11 @@
       ds = d->audio;
     else if(id == d->video->id)
       ds = d->video;
-    else if (id == d->sub->id)
+    else if (ogg_d->subs[id].text)
       ds = d->sub;
 
     if(ds) {
-      if(!demux_ogg_add_packet(ds,&ogg_d->subs[id],&pack))
+      if(!demux_ogg_add_packet(ds,&ogg_d->subs[id],id,&pack))
 	continue; /// Unuseful packet, get another
       d->filepos = ogg_d->pos;
       return 1;
@@ -1180,7 +1259,7 @@
         vo_sub = &ogg_sub;
         vo_osd_changed(OSDTYPE_SUBTITLE);
         clear_sub = -1;
-	demux_ogg_add_packet(ds,os,&op);
+	demux_ogg_add_packet(ds,os,ds->id,&op);
 	if(sh_audio)
 	  resync_audio_stream(sh_audio); 
 	return;