Author: rolf
Date: 2008-01-14 14:44:38 -0500 (Mon, 14 Jan 2008)
New Revision: 92897

Modified:
   trunk/moon/src/ChangeLog
   trunk/moon/src/media.cpp
   trunk/moon/src/media.h
   trunk/moon/src/mplayer2.cpp
   trunk/moon/src/pipeline.cpp
   trunk/moon/src/pipeline.h
Log:
* media.cpp, media.h, mplayer2.cpp, pipeline.cpp, pipeline.h: Make
  markers work again with the new pipeline.

Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2008-01-14 19:33:42 UTC (rev 92896)
+++ trunk/moon/src/ChangeLog    2008-01-14 19:44:38 UTC (rev 92897)
@@ -1,3 +1,8 @@
+2008-01-14  Rolf Bjarne Kvinge <[EMAIL PROTECTED]> 
+
+       * media.cpp, media.h, mplayer2.cpp, pipeline.cpp, pipeline.h: Make 
markers
+         work again with the new pipeline.
+
 2008-01-14  Sebastien Pouliot  <[EMAIL PROTECTED]>
 
        * shape.cpp|h: It looks like we stopped needing consider_fill a 

Modified: trunk/moon/src/media.cpp
===================================================================
--- trunk/moon/src/media.cpp    2008-01-14 19:33:42 UTC (rev 92896)
+++ trunk/moon/src/media.cpp    2008-01-14 19:44:38 UTC (rev 92897)
@@ -254,20 +254,27 @@
 int MediaElement::MediaFailedEvent = -1;
 int MediaElement::MediaOpenedEvent = -1;
 
-static void streamed_marker_callback (void* state, char* type, char* text, 
guint64 pts)
+#ifdef MOON_MEDIA
+static MediaResult marker_callback (MediaClosure* closure)
 {
-       MediaElement* me = (MediaElement*) state;
-       //printf ("embedded_script_callback (%p, %s, %s, %llu): id = %i.\n", 
state, type, text, pts, me->id);
+       MediaElement* element = (MediaElement*) closure->context;
+       MediaMarker* marker = closure->marker;
        
-       pts = (pts - me->mplayer->asf_parser->file_properties->preroll) * 10000;
+       if (marker == NULL)
+               return MEDIA_FAIL;
        
-       TimelineMarker* marker = new TimelineMarker ();
-       marker->SetValue (TimelineMarker::TextProperty, text);
-       marker->SetValue (TimelineMarker::TypeProperty, type);
-       marker->SetValue (TimelineMarker::TimeProperty, Value (pts, 
Type::TIMESPAN));
-       me->AddStreamedMarker (marker);
-       marker->unref ();
+       guint64 pts = (marker->Pts () - closure->media->GetStartTime ()) * 
10000;
+       
+       TimelineMarker* tl_marker = new TimelineMarker ();
+       tl_marker->SetValue (TimelineMarker::TextProperty, marker->Text ());
+       tl_marker->SetValue (TimelineMarker::TypeProperty, marker->Type ());
+       tl_marker->SetValue (TimelineMarker::TimeProperty, Value (pts, 
Type::TIMESPAN));
+       element->AddStreamedMarker (tl_marker);
+       tl_marker->unref ();
+       
+       return MEDIA_SUCCESS;
 }
+#endif
 
 void
 MediaElement::AddStreamedMarker (TimelineMarker* marker)
@@ -278,119 +285,59 @@
 }
 
 void
-MediaElement::ReadASFMarkers ()
+MediaElement::ReadMarkers ()
 {
-       /*
-               We can get markers from several places:
-                       - The header of the file, read before starting to play
-                               - As a SCRIPT_COMMAND
-                               - As a MARKER
-                               They are both treated the same way, added into 
the timeline marker collection when the media is loaded.
-                       - As data in the file (a separate stream whose type is 
ASF_COMMAND_MEDIA)
-                               These markers show up while playing the file, 
and they don't show up in the timeline marker collection,
-                               they only get to raise the MarkerReached event.
-                               currently the demuxer will call the 
streamed_marker_callback when it encounters any of these.    
-       */
-       
-       //printf ("MediaElement::ReadASFMarkers ()\n");
-       
-       if (mplayer != NULL && mplayer->asf_parser != NULL) {
-               // printf ("MediaElement::ReadASFMarkers (): setting 
callback.\n");
-               mplayer->asf_parser->embedded_script_command = 
streamed_marker_callback;
-               mplayer->asf_parser->embedded_script_command_state = this;
-       }
+#ifdef MOON_MEDIA
+       //printf ("MediaElement::ReadMarkers ()\n");
 
-       if (mplayer == NULL || mplayer->asf_parser == NULL || 
(mplayer->asf_parser->script_command == NULL && mplayer->asf_parser->marker == 
NULL)) {
-               //printf ("MediaElement::ReadASFMarkers (): not reading 
markers. mplayer = %p, asf_parser = %p, script_command = %p, marker = %p.\n", 
-               //      mplayer, 
-               //      mplayer ? mplayer->asf_parser : NULL, 
-               //      mplayer ? (mplayer->asf_parser ? 
mplayer->asf_parser->script_command : NULL) : NULL, 
-               //      mplayer ? (mplayer->asf_parser ? 
mplayer->asf_parser->marker : NULL) : NULL);
+       IMediaDemuxer* demuxer;
+       Media* media;
+       
+       if (mplayer == NULL || mplayer->media == NULL || 
mplayer->media->GetDemuxer () == NULL)
                return;
+
+       media = mplayer->media;
+       demuxer = media->GetDemuxer ();
+
+       for (int i = 0; i < demuxer->GetStreamCount (); i++) {
+               if (demuxer->GetStream (i)->GetType () == MediaTypeMarker) {
+                       MarkerStream* stream = (MarkerStream*) 
demuxer->GetStream (i);
+                       MediaClosure* closure = new MediaClosure ();
+                       closure->callback = marker_callback;
+                       closure->context = this;
+                       closure->media = media;
+                       stream->SetCallback (closure);
+                       break;
+               }
        }
-               
+       
        TimelineMarkerCollection *col = NULL;
-       int i = -1;
-       guint64 preroll = mplayer->asf_parser->file_properties->preroll;
+       MediaMarker::Node* current = (MediaMarker::Node*) media->GetMarkers 
()->First ();
        
-       // Read the SCRIPT COMMANDs
-       char **command_types = NULL;
-       asf_script_command_entry **commands = NULL;
-       asf_script_command *command = mplayer->asf_parser->script_command;
-
-       if (command != NULL) {
-               commands = command->get_commands (mplayer->asf_parser, 
&command_types);
-               
-               if (command_types == NULL) {
-                       //printf ("MediaElement::ReadASFMarkers (): No command 
types.\n");
-                       goto cleanup;
-               }
+       if (current == NULL) {
+               //printf ("MediaElement::ReadMarkers (): no markers.\n");
+               return;
        }
-
-       col = new TimelineMarkerCollection ();
        
-       i = -1;
-       while (commands != NULL && commands [++i] != NULL) {
-               asf_script_command_entry *entry = commands [i];
-               int64_t pts = (entry->pts - preroll) * 10000;
-               char* text = entry->get_name ();
-               const char* type = "";
-               
-               if (entry->type_index + 1 <= command->command_type_count) {
-                       type = command_types [entry->type_index];
-               }
-               
+       col = new TimelineMarkerCollection ();
+       while (current != NULL) {
+               MediaMarker* marker = current->marker;
                TimelineMarker *new_marker = new TimelineMarker ();
-               new_marker->SetValue (TimelineMarker::TextProperty, text);
-               new_marker->SetValue (TimelineMarker::TypeProperty, type);
-               new_marker->SetValue (TimelineMarker::TimeProperty, Value (pts, 
Type::TIMESPAN));
+               new_marker->SetValue (TimelineMarker::TextProperty, 
marker->Text ());
+               new_marker->SetValue (TimelineMarker::TypeProperty, 
marker->Type ());
+               new_marker->SetValue (TimelineMarker::TimeProperty, Value 
((marker->Pts () - media->GetStartTime ())* 10000, Type::TIMESPAN));
                col->Add (new_marker);
-               
-               //printf ("MediaElement::ReadMarkers () Added script command at 
%llu (text: %s, type: %s)\n", pts, text, type);
-               
+               //printf ("MediaElement::ReadMarkers (): Adding marker with 
Text: '%s', Type: '%s', Pts: %llu\n", new_marker->GetValue 
(TimelineMarker::TextProperty)->AsString (), new_marker->GetValue 
(TimelineMarker::TypeProperty)->AsString (), new_marker->GetValue 
(TimelineMarker::TimeProperty)->AsTimeSpan ());
                new_marker->unref ();
-               g_free (text);
-       }
-       
-       
-       // Read the MARKERs
-       asf_marker *asf_marker;
-       const asf_marker_entry* marker_entry;
-       
-       asf_marker = mplayer->asf_parser->marker;
-       if (asf_marker != NULL) {
-               for (i = 0; i < (int) asf_marker->marker_count; i++) {
-                       marker_entry = asf_marker->get_entry (i);
-                       int64_t pts = (marker_entry->pts - preroll * 10000);
-                       char* text = marker_entry->get_marker_description ();
-                       
-                       TimelineMarker *new_marker = new TimelineMarker ();
-                       new_marker->SetValue (TimelineMarker::TypeProperty, 
"Name");
-                       new_marker->SetValue (TimelineMarker::TextProperty, 
text);
-                       new_marker->SetValue (TimelineMarker::TimeProperty, 
Value (pts, Type::TIMESPAN));
-                       col->Add (new_marker);
-                       
-                       //printf ("MediaElement::ReadMarkers () Added marker at 
%llu (text: %s, type: %s)\n", pts, text, "Name");
                
-                       new_marker->unref ();
-                       g_free (text);
-               }
+               current = (MediaMarker::Node*) current->next;
        }
        
        // Docs says we overwrite whatever's been loaded already.
-       //printf ("MediaElement::ReadASFMarkers (): setting %i markers.\n", i);
+       //printf ("MediaElement::ReadMarkers (): setting %i markers.\n", 
collection_count (col));
        SetValue (MarkersProperty, col);
-       
-cleanup:
        col->unref ();
-       if (command_types) {
-               i = -1;
-               while (command_types [++i] != NULL)
-                       g_free (command_types [i]);
-               g_free (command_types);
-       }
-       
-       g_free (commands);
+#endif
 }
 
 void
@@ -435,6 +382,8 @@
                        
                int64_t pts = (int64_t) val->AsTimeSpan ();
                
+               //printf ("MediaElement::CheckMarkers (%llu, %llu): Checking 
pts: %llu\n", from, to, pts);
+               
                if (pts >= from && pts <= to) {
                        marker->ref ();
                        //printf ("MediaElement::CheckMarkers (%llu, %llu): 
Found marker, text = %s.\n", from, to, marker->GetValue 
(TimelineMarker::TextProperty)->AsString ());
@@ -744,7 +693,7 @@
        
        UpdateProgress ();
        
-       ReadASFMarkers ();
+       ReadMarkers ();
        
        Emit (MediaElement::MediaOpenedEvent);
        

Modified: trunk/moon/src/media.h
===================================================================
--- trunk/moon/src/media.h      2008-01-14 19:33:42 UTC (rev 92896)
+++ trunk/moon/src/media.h      2008-01-14 19:44:38 UTC (rev 92897)
@@ -203,7 +203,7 @@
        static void downloader_complete (EventObject *sender, gpointer 
calldata, gpointer closure);
        static void size_notify (int64_t size, gpointer data);
        
-       void ReadASFMarkers ();
+       void ReadMarkers ();
        void CheckMarkers (int64_t from, int64_t to);
        void CheckMarkers (int64_t from, int64_t to, TimelineMarkerCollection* 
col, bool remove);
        

Modified: trunk/moon/src/mplayer2.cpp
===================================================================
--- trunk/moon/src/mplayer2.cpp 2008-01-14 19:33:42 UTC (rev 92896)
+++ trunk/moon/src/mplayer2.cpp 2008-01-14 19:44:38 UTC (rev 92897)
@@ -16,7 +16,7 @@
                jeff - make 1 thread play all audio (and don't exit when audio 
finishes).
                make markers work again
                write a progressive source
-               try decoding on main thread
+               done - try decoding on main thread
                jeff - write an mp3 demuxer
 */
 
@@ -357,7 +357,7 @@
        MediaResult result;
        Media* media;
        
-       media = new Media (NULL);
+       media = new Media ();
        result = media->Open (uri);
        if (!MEDIA_SUCCEEDED (result)) {
                fprintf (stderr, "MediaPlayer::Open ('%s'): cannot open uri: 
%i\n", uri, result);

Modified: trunk/moon/src/pipeline.cpp
===================================================================
--- trunk/moon/src/pipeline.cpp 2008-01-14 19:33:42 UTC (rev 92896)
+++ trunk/moon/src/pipeline.cpp 2008-01-14 19:44:38 UTC (rev 92897)
@@ -16,6 +16,7 @@
 #include "uri.h"
 #include "media.h"
 #include "asf/asf.h"
+#include "asf/asf-structures.h"
 
 #define MAKE_CODEC_ID(a, b, c, d) (a | (b << 8) | (c << 16) | (d << 24))
 
@@ -35,8 +36,8 @@
 DecoderInfo* Media::registered_decoders = NULL;
 ConverterInfo* Media::registered_converters = NULL;
  
-Media::Media (void* el) :
-               source (NULL), demuxer (NULL), element (NULL),
+Media::Media () :
+               source (NULL), demuxer (NULL), markers (NULL),
                file_or_url (NULL), queued_requests (NULL),
                queue_closure (NULL)
 {
@@ -46,7 +47,6 @@
 {
        DeleteQueue ();
                
-       element = NULL;
        delete source;
        source = NULL;
        delete demuxer;
@@ -56,8 +56,20 @@
        
        delete queue_closure;
        queue_closure = NULL;
+       
+       delete markers;
+       markers = NULL;
 }
 
+List* 
+Media::GetMarkers ()
+{
+       if (markers == NULL)
+               markers = new List ();
+       
+       return markers;
+}
+
 void
 Media::RegisterDemuxer (DemuxerInfo* info)
 {
@@ -550,6 +562,90 @@
        return MEDIA_FAIL;
 }
 
+void
+ASFDemuxer::ReadMarkers ()
+{
+       /*
+               We can get markers from several places:
+                       - The header of the file, read before starting to play
+                               - As a SCRIPT_COMMAND
+                               - As a MARKER
+                               They are both treated the same way, added into 
the timeline marker collection when the media is loaded.
+                       - As data in the file (a separate stream whose type is 
ASF_COMMAND_MEDIA)
+                               These markers show up while playing the file, 
and they don't show up in the timeline marker collection,
+                               they only get to raise the MarkerReached event.
+                               currently the demuxer will call the 
streamed_marker_callback when it encounters any of these.    
+       */
+       
+       // Read the markers (if any)
+       int i = -1;
+       guint64 preroll = parser->file_properties->preroll;
+       List* markers = media->GetMarkers ();
+       
+       // Read the SCRIPT COMMANDs
+       char **command_types = NULL;
+       asf_script_command_entry **commands = NULL;
+       asf_script_command *command = parser->script_command;
+
+       if (command != NULL) {
+               commands = command->get_commands (parser, &command_types);
+               
+               if (command_types == NULL) {
+                       //printf ("MediaElement::ReadASFMarkers (): No command 
types.\n");
+                       goto cleanup;
+               }
+       }
+       
+       i = -1;
+       while (commands != NULL && commands [++i] != NULL) {
+               asf_script_command_entry *entry = commands [i];
+               int64_t pts = entry->pts; //(entry->pts - preroll) * 10000;
+               char* text = entry->get_name ();
+               const char* type = "";
+               
+               if (entry->type_index + 1 <= command->command_type_count) {
+                       type = command_types [entry->type_index];
+               }
+               
+               markers->Append (new MediaMarker::Node (new MediaMarker (type, 
text, pts)));
+               
+               //printf ("MediaElement::ReadMarkers () Added script command at 
%llu (text: %s, type: %s)\n", pts, text, type);
+               
+               g_free (text);
+       }
+       
+       
+       // Read the MARKERs
+       asf_marker *asf_marker;
+       const asf_marker_entry* marker_entry;
+       
+       asf_marker = parser->marker;
+       if (asf_marker != NULL) {
+               for (i = 0; i < (int) asf_marker->marker_count; i++) {
+                       marker_entry = asf_marker->get_entry (i);
+                       int64_t pts = marker_entry->pts / 10000; // 
(marker_entry->pts - preroll * 10000);
+                       char* text = marker_entry->get_marker_description ();
+                       
+                       markers->Append (new MediaMarker::Node (new MediaMarker 
("Name", text, pts)));
+                       
+                       //printf ("MediaElement::ReadMarkers () Added marker at 
%llu (text: %s, type: %s)\n", pts, text, "Name");
+               
+                       g_free (text);
+               }
+       }
+       
+               
+cleanup:
+       if (command_types) {
+               i = -1;
+               while (command_types [++i] != NULL)
+                       g_free (command_types [i]);
+               g_free (command_types);
+       }
+       
+       g_free (commands);
+}
+
 MediaResult
 ASFDemuxer::ReadHeader ()
 {
@@ -572,6 +668,8 @@
                goto failure;
        }
        
+       media->SetStartTime (asf_parser->file_properties->preroll);
+                       
        // Count the number of streams
        stream_count = 0;
        for (int i = 1; i <= 127; i++) {
@@ -657,23 +755,26 @@
                                }
                        }
                } else if (stream_properties->is_command ()) {
-                       ASFMarkerStream* marker = new ASFMarkerStream (GetMedia 
());
+                       MarkerStream* marker = new MarkerStream (GetMedia ());
                        stream = marker;
+                       stream->codec = "asf-marker";
                } else {
                        // Unknown stream, ignore it.
                }
                
                if (stream != NULL) {
-                       switch (stream->codec_id) {
-                       case CODEC_WMV1: stream->codec = "wmv1"; break;
-                       case CODEC_WMV2: stream->codec = "wmv2"; break;
-                       case CODEC_WMV3: stream->codec = "wmv3"; break;
-                       case CODEC_WMVA: stream->codec = "wmva"; break;
-                       case CODEC_WVC1: stream->codec = "vc1"; break;
-                       case CODEC_MP3: stream->codec = "mp3"; break;
-                       case CODEC_WMAV1: stream->codec = "wmav1"; break;
-                       case CODEC_WMAV2: stream->codec = "wmav2"; break;
-                       default: stream->codec = "unknown"; break;
+                       if (stream_properties->is_video () || 
stream_properties->is_audio ()) {
+                               switch (stream->codec_id) {
+                               case CODEC_WMV1: stream->codec = "wmv1"; break;
+                               case CODEC_WMV2: stream->codec = "wmv2"; break;
+                               case CODEC_WMV3: stream->codec = "wmv3"; break;
+                               case CODEC_WMVA: stream->codec = "wmva"; break;
+                               case CODEC_WVC1: stream->codec = "vc1"; break;
+                               case CODEC_MP3: stream->codec = "mp3"; break;
+                               case CODEC_WMAV1: stream->codec = "wmav1"; 
break;
+                               case CODEC_WMAV2: stream->codec = "wmav2"; 
break;
+                               default: stream->codec = "unknown"; break;
+                               }
                        }
                        stream->start_time = 
asf_parser->file_properties->preroll;
                        streams [i] = stream;
@@ -696,6 +797,8 @@
        this->stream_to_asf_index = stream_to_asf_index;
        this->parser = asf_parser;
        
+       ReadMarkers ();
+       
        return result;
        
 failure:
@@ -1070,4 +1173,47 @@
  */
 
 
+/*
+ * MediaMarker
+ */ 
 
+MediaMarker::MediaMarker (const char* type, const char* text, guint64 pts)
+{
+       this->type = g_strdup (type);
+       this->text = g_strdup (text);
+       this->pts = pts;
+}
+
+MediaMarker::~MediaMarker ()
+{
+       g_free (type);
+       type = NULL;
+       g_free (text);
+       text = NULL;
+}
+
+/*
+ * MarkerStream
+ */
+ 
+MarkerStream::MarkerStream (Media* media) 
+       : IMediaStream (media),
+       closure (NULL)
+{
+}
+
+MarkerStream::~MarkerStream ()
+{
+       delete closure;
+       closure = NULL;
+}
+
+void
+MarkerStream::SetCallback (MediaClosure* cl)
+{
+       if (closure != NULL)
+               delete closure;
+       closure = cl;
+}
+
+

Modified: trunk/moon/src/pipeline.h
===================================================================
--- trunk/moon/src/pipeline.h   2008-01-14 19:33:42 UTC (rev 92896)
+++ trunk/moon/src/pipeline.h   2008-01-14 19:44:38 UTC (rev 92897)
@@ -90,6 +90,7 @@
 class MediaFrame;
 class VideoStream;
 class IImageConverter;
+class MediaMarker;
 
 #include "list.h"
 #include "asf/asf.h"
@@ -149,9 +150,10 @@
        ~MediaClosure ();
        
        MediaCallback* callback;
-       MediaFrame* frame;
-       Media* media;
-       void* context;
+       MediaFrame* frame; // Set when this is the callback in 
Media::GetNextFrameAsync
+       Media* media; // Set when this is the callback in 
Media::GetNextFrameAsync
+       MediaMarker* marker; // Set when this is the callback in MarkerStream
+       void* context; // The property of whoever creates the closure.
        
        // Calls the callback and returns the callback's return value
        // If no callback is set, returns MEDIA_NO_CALLBACK
@@ -192,7 +194,7 @@
 
 class Media {
 public:
-       Media (void* element);
+       Media ();
        ~Media ();
        
        //      Opens the file using a FileSource
@@ -235,13 +237,20 @@
        
        IMediaSource* GetSource () { return source; }
        IMediaDemuxer* GetDemuxer () { return demuxer; }
-       void* GetElement () { return element; }
        const char* GetFileOrUrl () { return file_or_url; }
     
     void AddMessage (MediaResult result, const char* msg);
     void AddMessage (MediaResult result, char* msg);
     
+    // A list of MediaMarker::Node.
+    // This is the list of markers found in the metadata/headers (not as a 
separate stream).
+    // Will never return NULL.
+    List* GetMarkers ();
     
+    // If the start time is the same for all streams, the demuxer should set 
this value
+    guint64 GetStartTime () { return start_time; }
+    void SetStartTime (guint64 value) { start_time = value; } 
+    
 public:
     // Registration functions
     // This class takes ownership of the infos and will delete them (not free) 
when the Media is shutdown.
@@ -266,9 +275,11 @@
 
        IMediaSource* source;
        IMediaDemuxer* demuxer;
-       void* element;
+       List* markers;
        char* file_or_url;
+       guint64 start_time;
        
+       
        List* queued_requests;
        pthread_t queue_thread;
        pthread_cond_t queue_condition;
@@ -315,6 +326,28 @@
        int srcStride [4]; // Set by the decoder
 };
 
+class MediaMarker {
+public:
+       MediaMarker (const char* type, const char* text, guint64 pts);
+       ~MediaMarker ();
+       const char* Type () { return type; }
+       const char* Text () { return text; }
+       guint64 Pts () { return pts; }
+       
+private:
+       char* type;
+       char* text;
+       guint64 pts;
+       
+public:
+       class Node : public List::Node {
+       public:
+               Node (MediaMarker* m) : marker (m) {}
+               virtual ~Node () { delete marker; }
+               MediaMarker* marker;
+       };
+};
+
 // Interfaces
 
 class IMediaObject {
@@ -430,7 +463,7 @@
        MoonPixelFormat pixel_format; // The pixel format this codec outputs. 
Open () should fill this in.
        IMediaStream* stream;
        Media* media;
-};
+}; // Set when this is the callback in Media::GetNextFrameAsync
 
 
 /*
@@ -536,8 +569,11 @@
        virtual MediaResult ReadHeader ();
        virtual MediaResult ReadFrame (MediaFrame* frame);
        virtual MediaResult Seek (guint64 pts);
+       ASFParser* GetParser () { return parser; }
        
 private:
+       void ReadMarkers ();
+
        ASFParser* parser;
        ASFFrameReader* reader;
        gint32* stream_to_asf_index;
@@ -550,10 +586,16 @@
        virtual const char* GetName () { return "ASFDemuxer"; }
 };
 
-class ASFMarkerStream : public IMediaStream {
+class MarkerStream : public IMediaStream {
 public:
-       ASFMarkerStream (Media* media) : IMediaStream (media) {}
-       virtual MoonMediaType GetType () { return MediaTypeMarker; } 
+       MarkerStream (Media* media);
+       ~MarkerStream ();
+       virtual MoonMediaType GetType () { return MediaTypeMarker; }
+       
+       void SetCallback (MediaClosure* closure);
+       
+private:
+       MediaClosure* closure;
 };
 
 class ASFMarkerDecoder : public IMediaDecoder {

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to