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