Author: rolf
Date: 2008-01-11 09:50:22 -0500 (Fri, 11 Jan 2008)
New Revision: 92670
Modified:
trunk/moon/src/ChangeLog
trunk/moon/src/media.cpp
trunk/moon/src/mplayer.cpp
trunk/moon/src/mplayer2.cpp
trunk/moon/src/pipeline-ffmpeg.cpp
trunk/moon/src/pipeline-ffmpeg.h
trunk/moon/src/pipeline.cpp
trunk/moon/src/pipeline.h
Log:
* media.cpp: Initialize Media too upon initialization.
* pipeline.cpp, pipeline.h, pipeline-ffmpeg.cpp, pipeline-ffmpeg.h,
mplayer2.cpp, mplayer.cpp: Implement registration of components,
making it possible to completely remove ffmpeg.
Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog 2008-01-11 14:48:10 UTC (rev 92669)
+++ trunk/moon/src/ChangeLog 2008-01-11 14:50:22 UTC (rev 92670)
@@ -1,5 +1,12 @@
2008-01-11 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
+ * media.cpp: Initialize Media too upon initialization.
+ * pipeline.cpp, pipeline.h, pipeline-ffmpeg.cpp, pipeline-ffmpeg.h,
+ mplayer2.cpp, mplayer.cpp: Implement registration of components,
making
+ it possible to completely remove ffmpeg.
+
+2008-01-11 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
+
* pipeline.cpp: Remove stray character.
2008-01-11 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
Modified: trunk/moon/src/media.cpp
===================================================================
--- trunk/moon/src/media.cpp 2008-01-11 14:48:10 UTC (rev 92669)
+++ trunk/moon/src/media.cpp 2008-01-11 14:50:22 UTC (rev 92670)
@@ -26,6 +26,7 @@
#include "downloader.h"
#include "playlist.h"
#include "geometry.h"
+#include "pipeline.h"
// still too ugly to be exposed in the header files ;-)
cairo_pattern_t *image_brush_create_pattern (cairo_t *cairo, cairo_surface_t
*surface, int sw, int sh, double opacity);
@@ -1831,4 +1832,8 @@
t = Type::Find (Type::IMAGE);
Image::ImageFailedEvent = t->LookupEvent ("ImageFailed");
+
+#ifdef MOON_MEDIA
+ Media::Initialize ();
+#endif
}
Modified: trunk/moon/src/mplayer.cpp
===================================================================
--- trunk/moon/src/mplayer.cpp 2008-01-11 14:48:10 UTC (rev 92669)
+++ trunk/moon/src/mplayer.cpp 2008-01-11 14:50:22 UTC (rev 92670)
@@ -12,6 +12,9 @@
#include <config.h>
#endif
+#include "pipeline.h"
+#ifndef MOON_MEDIA
+
#include <glib.h>
#include <poll.h>
@@ -34,13 +37,11 @@
#include "clock.h"
#include "mplayer.h"
-#include "pipeline.h"
//#include "stream.h"
#include "asf/asf-ffmpeg.h"
#include "runtime.h"
#include "list.h"
-#ifndef MOON_MEDIA
#if GLIB_SIZEOF_VOID_P == 8
#define ALIGN(addr,size) (uint8_t *) (((uint64_t) (((uint8_t *) (addr)) +
(size) - 1)) & ~((size) - 1))
@@ -593,8 +594,10 @@
video->queue->Unlock ();
- if (update)
+ if (update) {
+ //printf ("advancing to video frame with pts: %lld\n",
current_pts);
convert_to_rgb (video, frame);
+ }
if (frame != NULL) {
av_free (frame);
Modified: trunk/moon/src/mplayer2.cpp
===================================================================
--- trunk/moon/src/mplayer2.cpp 2008-01-11 14:48:10 UTC (rev 92669)
+++ trunk/moon/src/mplayer2.cpp 2008-01-11 14:50:22 UTC (rev 92670)
@@ -29,7 +29,6 @@
G_BEGIN_DECLS
#include <stdint.h>
#include <limits.h>
-#include <swscale.h>
G_END_DECLS
#include "clock.h"
@@ -193,7 +192,7 @@
IMediaDecoder *codec;
// rendering
- struct SwsContext *scaler;
+ //struct SwsContext *scaler;
cairo_surface_t *surface;
uint8_t *rgb_buffer;
@@ -213,7 +212,7 @@
stream = NULL;
codec = NULL;
- scaler = NULL;
+ //scaler = NULL;
surface = NULL;
rgb_buffer = NULL;
@@ -275,13 +274,15 @@
g_free (uri);
+ Media* media = NULL;
if (audio->media != NULL) {
- delete audio->media;
+ media = audio->media;
} else if (video->media != NULL) {
- delete video->media;
+ media = video->media;
}
delete audio;
delete video;
+ delete media;
}
MediaResult
@@ -380,10 +381,10 @@
// for conversion to rgb32 format needed for rendering
video->rgb_buffer = (uint8_t *) g_malloc0 (width *
height * 4);
- video->scaler = sws_getContext (width, height,
encoding->pixel_format,
+ /*video->scaler = sws_getContext (width, height,
encoding->pixel_format,
width, height,
PIX_FMT_RGB32,
SWS_BICUBIC, NULL,
NULL, NULL);
-
+ */
// rendering surface
video->surface = cairo_image_surface_create_for_data (
video->rgb_buffer, CAIRO_FORMAT_ARGB32,
Modified: trunk/moon/src/pipeline-ffmpeg.cpp
===================================================================
--- trunk/moon/src/pipeline-ffmpeg.cpp 2008-01-11 14:48:10 UTC (rev 92669)
+++ trunk/moon/src/pipeline-ffmpeg.cpp 2008-01-11 14:50:22 UTC (rev 92670)
@@ -35,6 +35,7 @@
#include "debug.h"
bool ffmpeg_initialized = false;
+bool ffmpeg_registered = false;
void
initialize_ffmpeg ()
@@ -48,7 +49,25 @@
ffmpeg_initialized = true;
}
+void
+register_ffmpeg ()
+{
+ initialize_ffmpeg ();
+
+ if (ffmpeg_registered)
+ return;
+
+ Media::RegisterConverter (new FfmpegConverterInfo ());
+ Media::RegisterDecoder (new FfmpegDecoderInfo ());
+ //Media::RegisterDemuxer (new FfmpegDemuxerInfo ());
+
+ ffmpeg_registered = true;
+}
+/*
+ * FfmpegDecoder
+ */
+
FfmpegDecoder::FfmpegDecoder (Media* media, IMediaStream* stream)
: IMediaDecoder (media, stream),
audio_buffer (NULL)
@@ -156,6 +175,16 @@
audio_buffer = NULL;
}
+void
+FfmpegDecoder::Cleanup (MediaFrame* frame)
+{
+ AVFrame* av_frame = (AVFrame*) frame->decoder_specific_data;
+ if (av_frame != NULL) {
+ av_free (av_frame);
+ frame->decoder_specific_data = NULL;
+ }
+}
+
MediaResult
FfmpegDecoder::DecodeFrame (MediaFrame* media_frame)
{
@@ -173,7 +202,7 @@
//printf ("\n");
if (stream->GetType () == MediaTypeVideo) {
- VideoStream* vs = (VideoStream*) stream;
+ // VideoStream* vs = (VideoStream*) stream;
frame = avcodec_alloc_frame ();
@@ -190,8 +219,8 @@
media_frame->uncompressed_size = context->width *
context->height * 4;
media_frame->uncompressed_data = (uint8_t*) g_malloc
(media_frame->uncompressed_size);
- uint8_t *rgb_dest[3] = { (uint8_t*)
media_frame->uncompressed_data, NULL, NULL};
- int rgb_stride [3] = { context->width * 4, 0, 0 };
+ // uint8_t *rgb_dest[3] = { (uint8_t*)
media_frame->uncompressed_data, NULL, NULL};
+ // int rgb_stride [3] = { context->width * 4, 0, 0 };
for (int i = 0; i < 4; i++) {
media_frame->uncompressed_data_stride [i] =
frame->data [i];
@@ -236,5 +265,121 @@
return MEDIA_SUCCESS;
}
+/*
+ * FfmpegDecoderInfo
+ */
+
+bool
+FfmpegDecoderInfo::Supports (const char* codec)
+{
+ return avcodec_find_decoder_by_name (codec) != NULL;
+}
+
+IMediaDecoder*
+FfmpegDecoderInfo::Create (Media* media, IMediaStream* stream)
+{
+ return new FfmpegDecoder (media, stream);
+}
+
+
+/*
+ * FfmpegConverter
+ */
+
+FfmpegConverter::FfmpegConverter (Media* media, VideoStream* stream) :
IImageConverter (media, stream)
+{
+ scaler = NULL;
+}
+
+FfmpegConverter::~FfmpegConverter ()
+{
+ if (scaler != NULL) {
+ sws_freeContext (scaler);
+ scaler = NULL;
+ }
+}
+
+PixelFormat
+FfmpegConverter::ToFfmpegPixFmt (MoonPixelFormat format)
+{
+ switch (format) {
+ case MoonPixelFormatYUV420P: return PIX_FMT_YUV420P;
+ case MoonPixelFormatRGB32: return PIX_FMT_RGB32;
+ default:
+ printf ("FfmpegConverter::ToFfmpegPixFmt (%i): Unknown pixel
format.\n", format);
+ return PIX_FMT_NONE;
+ }
+}
+
+MoonPixelFormat
+FfmpegConverter::ToMoonPixFmt (PixelFormat format)
+{
+ switch (format) {
+ case PIX_FMT_YUV420P: return MoonPixelFormatYUV420P;
+ case PIX_FMT_RGB32: return MoonPixelFormatRGB32;
+ default:
+ printf ("FfmpegConverter::ToMoonPixFmt (%i): Unknown pixel
format.\n", format);
+ return MoonPixelFormatNone;
+ };
+}
+
+MediaResult
+FfmpegConverter::Open ()
+{
+ PixelFormat in_format = ToFfmpegPixFmt (input_format);
+ PixelFormat out_format = ToFfmpegPixFmt (output_format);
+
+ if (in_format == PIX_FMT_NONE) {
+ media->AddMessage (MEDIA_CONVERTER_ERROR, "Invalid input
format.");
+ return MEDIA_CONVERTER_ERROR;
+ }
+
+ if (out_format == PIX_FMT_NONE) {
+ media->AddMessage (MEDIA_CONVERTER_ERROR, "Invalid output
format.");
+ return MEDIA_CONVERTER_ERROR;
+ }
+
+ scaler = sws_getContext (stream->width, stream->height, in_format,
+ stream->width, stream->height, out_format,
+ SWS_BICUBIC, NULL, NULL, NULL);
+
+ return MEDIA_SUCCESS;
+}
+
+MediaResult
+FfmpegConverter::Convert (uint8_t *src[], int srcStride[], int srcSlideY, int
srcSlideH, uint8_t* dest[], int dstStride [])
+{
+ if (scaler == NULL) {
+ media->AddMessage (MEDIA_CONVERTER_ERROR, "Converter closed.");
+ return MEDIA_CONVERTER_ERROR;
+ }
+
+ //printf ("converting...\n");
+
+ // There seems to be no documentation about what
+ // sws_scale's return value means.
+ sws_scale (scaler, src, srcStride, srcSlideY, srcSlideH, dest,
dstStride);
+
+ return MEDIA_SUCCESS;
+}
+
+
+/*
+ * FfmpegConverterInfo
+ */
+
+bool
+FfmpegConverterInfo::Supports (MoonPixelFormat input, MoonPixelFormat output)
+{
+ return FfmpegConverter::ToFfmpegPixFmt (input) != PIX_FMT_NONE
+ && FfmpegConverter::ToFfmpegPixFmt (output) != PIX_FMT_NONE;
+}
+
+IImageConverter*
+FfmpegConverterInfo::Create (Media* media, VideoStream* stream)
+{
+ return new FfmpegConverter (media, stream);
+}
+
#endif // INCLUDE_FFMPEG
Modified: trunk/moon/src/pipeline-ffmpeg.h
===================================================================
--- trunk/moon/src/pipeline-ffmpeg.h 2008-01-11 14:48:10 UTC (rev 92669)
+++ trunk/moon/src/pipeline-ffmpeg.h 2008-01-11 14:50:22 UTC (rev 92670)
@@ -9,7 +9,12 @@
* See the LICENSE file included with the distribution for details.
*
*/
-
+
+#ifdef INCLUDE_FFMPEG
+
+#ifndef __MOON_PIPELINE_FFMPEG__
+#define __MOON_PIPELINE_FFMPEG__
+
#include <glib.h>
#include <unistd.h>
@@ -25,6 +30,8 @@
#define AUDIO_BUFFER_SIZE (AVCODEC_MAX_AUDIO_FRAME_SIZE * 2)
+void register_ffmpeg ();
+
class FfmpegDemuxer : public IMediaDemuxer {
public:
FfmpegDemuxer (Media* media) : IMediaDemuxer (media) {}
@@ -37,98 +44,42 @@
virtual MediaResult DecodeFrame (MediaFrame* frame);
virtual MediaResult Open ();
+ virtual void Cleanup (MediaFrame* frame);
- virtual void Cleanup (MediaFrame* frame)
- {
- AVFrame* av_frame = (AVFrame*) frame->decoder_specific_data;
- if (av_frame != NULL) {
- av_free (av_frame);
- frame->decoder_specific_data = NULL;
- }
- }
-
private:
AVCodecContext *context;
uint8_t* audio_buffer;
};
+class FfmpegDecoderInfo : public DecoderInfo {
+public:
+ virtual bool Supports (const char* codec);
+ virtual IMediaDecoder* Create (Media* media, IMediaStream* stream);
+ virtual const char* GetName () { return "FfmpegDecoder"; }
+};
+
class FfmpegConverter : public IImageConverter {
public:
- FfmpegConverter (Media* media, VideoStream* stream) : IImageConverter
(media, stream)
- {
- scaler = NULL;
- }
+ FfmpegConverter (Media* media, VideoStream* stream);
+ ~FfmpegConverter ();
- ~FfmpegConverter ()
- {
- if (scaler != NULL) {
- sws_freeContext (scaler);
- scaler = NULL;
- }
- }
+ MediaResult Open ();
+ MediaResult Convert (uint8_t *src[], int srcStride[], int srcSlideY,
int srcSlideH, uint8_t* dest[], int dstStride []);
- static PixelFormat ToFfmpegPixFmt (MoonPixelFormat format)
- {
- switch (format) {
- case MoonPixelFormatYUV420P: return PIX_FMT_YUV420P;
- case MoonPixelFormatRGB32: return PIX_FMT_RGB32;
- default:
- printf ("FfmpegConverter::ToFfmpegPixFmt (%i): Unknown
pixel format.\n", format);
- return PIX_FMT_NONE;
- }
- }
+ static PixelFormat ToFfmpegPixFmt (MoonPixelFormat format);
+ static MoonPixelFormat ToMoonPixFmt (PixelFormat format);
- static MoonPixelFormat ToMoonPixFmt (PixelFormat format)
- {
- switch (format) {
- case PIX_FMT_YUV420P: return MoonPixelFormatYUV420P;
- case PIX_FMT_RGB32: return MoonPixelFormatRGB32;
- default:
- printf ("FfmpegConverter::ToMoonPixFmt (%i): Unknown
pixel format.\n", format);
- return MoonPixelFormatNone;
- };
- }
-
- MediaResult Open ()
- {
- PixelFormat in_format = ToFfmpegPixFmt (input_format);
- PixelFormat out_format = ToFfmpegPixFmt (output_format);
-
- if (in_format == PIX_FMT_NONE) {
- media->AddMessage (MEDIA_CONVERTER_ERROR, "Invalid
input format.");
- return MEDIA_CONVERTER_ERROR;
- }
-
- if (out_format == PIX_FMT_NONE) {
- media->AddMessage (MEDIA_CONVERTER_ERROR, "Invalid
output format.");
- return MEDIA_CONVERTER_ERROR;
- }
-
- scaler = sws_getContext (stream->width, stream->height,
in_format,
- stream->width, stream->height, out_format,
- SWS_BICUBIC, NULL, NULL, NULL);
-
- return MEDIA_SUCCESS;
- }
-
- MediaResult Convert (uint8_t *src[], int srcStride[], int srcSlideY,
int srcSlideH, uint8_t* dest[], int dstStride [])
- {
- if (scaler == NULL) {
- media->AddMessage (MEDIA_CONVERTER_ERROR, "Converter
closed.");
- return MEDIA_CONVERTER_ERROR;
- }
-
- //printf ("converting...\n");
-
- // There seems to be no documentation about what
- // sws_scale's return value means.
- sws_scale (scaler, src, srcStride, srcSlideY, srcSlideH, dest,
dstStride);
-
- return MEDIA_SUCCESS;
- }
-
private:
struct SwsContext *scaler;
};
+class FfmpegConverterInfo : public ConverterInfo {
+public:
+ virtual bool Supports (MoonPixelFormat input, MoonPixelFormat output);
+ virtual IImageConverter* Create (Media* media, VideoStream* stream);
+ virtual const char* GetName () { return "FfmpegConverter"; }
+};
+
+#endif // __MOON_PIPELINE_FFMPEG__
+#endif // INCLUDE_FFMPEG
Modified: trunk/moon/src/pipeline.cpp
===================================================================
--- trunk/moon/src/pipeline.cpp 2008-01-11 14:48:10 UTC (rev 92669)
+++ trunk/moon/src/pipeline.cpp 2008-01-11 14:50:22 UTC (rev 92670)
@@ -27,21 +27,24 @@
#define CODEC_MP3 0x55
#define CODEC_WMAV1 0x160
#define CODEC_WMAV2 0x161
-
+
+/*
+ * Media
+ */
+DemuxerInfo* Media::registered_demuxers = NULL;
+DecoderInfo* Media::registered_decoders = NULL;
+ConverterInfo* Media::registered_converters = NULL;
+
Media::Media (void* el) :
source (NULL), demuxer (NULL), element (NULL),
file_or_url (NULL), queued_requests (NULL),
queue_closure (NULL)
{
- //if (element)
- // element->ref ();
}
Media::~Media ()
{
DeleteQueue ();
- //if (element)
- // element->unref ();
element = NULL;
delete source;
@@ -56,6 +59,95 @@
}
void
+Media::RegisterDemuxer (DemuxerInfo* info)
+{
+ printf ("Media::RegisterDecoder (%p)\n", info);
+ info->next = NULL;
+ if (registered_demuxers == NULL) {
+ registered_demuxers = info;
+ } else {
+ MediaInfo* current = registered_demuxers;
+ while (current->next != NULL)
+ current = current->next;
+ current->next = info;
+ }
+}
+
+void
+Media::RegisterConverter (ConverterInfo* info)
+{
+ printf ("Media::RegisterDecoder (%p)\n", info);
+ info->next = NULL;
+ if (registered_converters == NULL) {
+ registered_converters = info;
+ } else {
+ MediaInfo* current = registered_converters;
+ while (current->next != NULL)
+ current = current->next;
+ current->next = info;
+ }
+}
+
+void
+Media::RegisterDecoder (DecoderInfo* info)
+{
+ printf ("Media::RegisterDecoder (%p)\n", info);
+ info->next = NULL;
+ if (registered_decoders == NULL) {
+ registered_decoders = info;
+ } else {
+ MediaInfo* current = registered_decoders;
+ while (current->next != NULL)
+ current = current->next;
+ current->next = info;
+ }
+}
+
+void
+Media::Initialize ()
+{
+ // register stuff
+ Media::RegisterDemuxer (new ASFDemuxerInfo ());
+#ifdef INCLUDE_FFMPEG
+ register_ffmpeg ();
+#endif
+}
+
+void
+Media::Shutdown ()
+{
+ MediaInfo* current;
+ MediaInfo* next;
+
+ current = registered_decoders;
+ while (current != NULL) {
+ next = current->next;
+ delete current;
+ current = next;
+ }
+ registered_decoders = NULL;
+
+ current = registered_demuxers;
+ while (current != NULL) {
+ next = current->next;
+ delete current;
+ current = next;
+ }
+ registered_demuxers = NULL;
+
+
+ current = registered_converters;
+ while (current != NULL) {
+ next = current->next;
+ delete current;
+ current = next;
+ }
+ registered_converters = NULL;
+
+
+}
+
+void
Media::AddMessage (MediaResult result, const char* msg)
{
printf ("Media::AddMessage (%i, '%s').\n", result, msg);
@@ -141,15 +233,33 @@
{
printf ("Media::Open ().\n");
- MediaResult result = MEDIA_FAIL;
+ MediaResult result = MEDIA_FAIL; // We return success if at least 1
stream could be opened correctly (has decoder and, if applicable, converter)
if (source == NULL) {
- return MediaResult (MEDIA_INVALID_ARGUMENT);
+ return MEDIA_INVALID_ARGUMENT;
}
- // Determine the container format
- // Hard-code our own demuxer for the moment.
- demuxer = new ASFDemuxer (this);
+ // Select a demuxer
+ uint8_t buffer [16];
+ if (!source->Peek (&buffer [0], 16)) {
+ return MEDIA_FAIL;
+ }
+
+ DemuxerInfo* current_demuxer = registered_demuxers;
+ while (current_demuxer != NULL && !current_demuxer->Supports (&buffer
[0], 16)) {
+ printf ("Checking registered demuxer '%s' if it supports the
media file '%s': no.\n", current_demuxer->GetName (), file_or_url);
+ current_demuxer = (DemuxerInfo*) current_demuxer->next;
+ }
+
+ if (current_demuxer == NULL) {
+ AddMessage (MEDIA_UNKNOWN_MEDIA_TYPE, g_strdup_printf ("No
demuxers registered to handle the media file '%s'.", file_or_url));
+ return MEDIA_UNKNOWN_MEDIA_TYPE;
+ } else {
+ printf ("Checking registered demuxer '%s' if it supports the
media file '%s': yes.\n", current_demuxer->GetName (), file_or_url);
+ demuxer = current_demuxer->Create (this);
+ }
+
+ // Found a demuxer
result = demuxer->ReadHeader ();
if (!MEDIA_SUCCEEDED (result)) {
@@ -160,6 +270,8 @@
printf ("Media::Open (): Starting to select codecs...\n");
+ result = MEDIA_FAIL; // Only set to SUCCESS if at least 1 stream can be
used
+
// Select codecs for each stream
for (int i = 0; i < demuxer->GetStreamCount (); i++) {
IMediaStream* stream = demuxer->GetStream (i);
@@ -169,52 +281,70 @@
const char* codec = stream->GetCodec ();
IMediaDecoder* decoder = NULL;
- printf ("Media::Open (%p): Selecting codec for codec %s, id
%i.\n", source, codec, stream->codec_id);
-
- if (decoder == NULL) {
- if (strcmp (codec, "wmv") == 0
- || strcmp (codec, "wma") == 0
- || strcmp (codec, "mp3") == 0
- || strcmp (codec, "vc1") == 0
- || strcmp (codec, "wmav2") == 0
- ) {
- decoder = new FfmpegDecoder (this, stream);
- } else if (strcmp (codec, "ASFMARKER") == 0) {
- decoder = new ASFMarkerDecoder (this, stream);
- } else {
- AddMessage (MEDIA_UNKNOWN_CODEC,
g_strdup_printf ("Unknown codec: '%s'", codec));
- }
+ printf ("Media::Open (): Selecting codec for codec %s, id
%i.\n", codec, stream->codec_id);
+
+ DecoderInfo* current_decoder = registered_decoders;
+ while (current_decoder != NULL && !current_decoder->Supports
(codec)) {
+ printf ("Checking registered decoder '%s' if it
supports codec '%s': no.\n", current_decoder->GetName (), codec);
+ current_decoder = (DecoderInfo*) current_decoder->next;
}
-
+
+ if (current_decoder == NULL) {
+ AddMessage (MEDIA_UNKNOWN_CODEC, g_strdup_printf
("Unknown codec: '%s'.", codec));
+ } else {
+ printf ("Checking registered decoder '%s' if it
supports codec '%s': yes.\n", current_decoder->GetName (), codec);
+ decoder = current_decoder->Create (this, stream);
+ }
+
if (decoder != NULL) {
result = decoder->Open ();
if (!MEDIA_SUCCEEDED (result)) {
delete decoder;
decoder = NULL;
}
+ }
-
if (decoder != NULL) {
- stream->SetDecoder (decoder);
-
- if (stream->GetType () == MediaTypeVideo) {
+ // Select converter for this stream
+ if (stream->GetType () == MediaTypeVideo &&
decoder->pixel_format != MoonPixelFormatRGB32) {
VideoStream* vs = (VideoStream*) stream;
IImageConverter* converter;
- converter = new FfmpegConverter (this, vs);
- converter->input_format =
vs->decoder->pixel_format;
- converter->output_format = MoonPixelFormatRGB32;
- if (MEDIA_SUCCEEDED (converter->Open ())) {
- // FIXME: What should happen if there's
no available converter? No video?
+
+ ConverterInfo* current_conv =
registered_converters;
+ while (current_conv != NULL &&
!current_conv->Supports (decoder->pixel_format, MoonPixelFormatRGB32)) {
+ printf ("Checking registered converter
'%s' if it supports input '%i' and output '%i': no.\n", current_conv->GetName
(), decoder->pixel_format, MoonPixelFormatRGB32);
+ current_conv = (ConverterInfo*)
current_conv->next;
+ }
+
+ if (current_conv == NULL) {
+ AddMessage (MEDIA_UNKNOWN_CONVERTER,
g_strdup_printf ("Can't convert from %i to %i: No converter found.",
vs->decoder->pixel_format, MoonPixelFormatRGB32));
+ } else {
+ printf ("Checking registered converter
'%s' if it supports input '%i' and output '%i': yes.\n", current_conv->GetName
(), decoder->pixel_format, MoonPixelFormatRGB32);
+ converter = current_conv->Create (this,
vs);
+ converter->input_format =
decoder->pixel_format;
+ converter->output_format =
MoonPixelFormatRGB32;
+ if (!MEDIA_SUCCEEDED (converter->Open
())) {
+ delete converter;
+ converter = NULL;
+ }
+ }
+
+ if (converter != NULL) {
vs->converter = converter;
} else {
- delete converter;
- converter = NULL;
+ delete decoder;
+ decoder = NULL;
}
}
- }}
+ }
+
+ if (decoder != NULL) {
+ stream->SetDecoder (decoder);
+ result = MEDIA_SUCCESS;
+ }
}
- return MEDIA_SUCCESS;
+ return result;
}
MediaFrame*
@@ -602,6 +732,29 @@
}
/*
+ * ASFDemuxerInfo
+ */
+
+bool
+ASFDemuxerInfo::Supports (uint8_t* buffer, uint32_t length)
+{
+ if (length < 16)
+ return false;
+
+ bool result = asf_guid_compare (&asf_guids_header, (asf_guid*) buffer);
+
+ printf ("ASFDemuxerInfo::Supports (%p, %u): probing result: %s\n",
buffer, length, result ? "true" : "false");
+
+ return result;
+}
+
+IMediaDemuxer*
+ASFDemuxerInfo::Create (Media* media)
+{
+ return new ASFDemuxer (media);
+}
+
+/*
* FileSource
*/
@@ -672,9 +825,11 @@
bool
FileSource::Peek (void* buffer, guint32 size)
{
- printf ("FileSource::Seek (%p, %u).\n", buffer, size);
- printf ("FileSource::Peek (%p, %u): Not implemented.\n", buffer, size);
- return false;
+ // Simple implementation of peek: save position, read bytes, restore
position.
+ gint64 position = GetPosition ();
+ if (!Read (buffer, size))
+ return false;
+ return Seek (position, SEEK_SET);
}
guint64
@@ -693,22 +848,24 @@
}
bool
-FileSource::Seek (gint64 position)
+FileSource::Seek (gint64 offset)
{
//printf ("FileSource::Seek (%llu).\n", position);
- return Seek (position, SEEK_CUR);
+ return Seek (offset, SEEK_CUR);
}
bool
-FileSource::Seek (gint64 position, int mode)
+FileSource::Seek (gint64 offset, int mode)
{
- //printf ("FileSource::Seek (%llu, %i).\n", position, mode);
+ printf ("FileSource::Seek (%llu, %i).\n", offset, mode);
- if (fseek (fd, position, mode) != 0) {
- media->AddMessage (MEDIA_SEEK_ERROR, g_strdup_printf ("Can't
seek to offset %llu with mode %i in '%s': %s.\n", position, mode, filename,
strerror (errno)));
+ int result = fseek (fd, offset, mode);
+ if (result != 0) {
+ media->AddMessage (MEDIA_SEEK_ERROR, g_strdup_printf ("Can't
seek to offset %llu with mode %i in '%s': %s.\n", offset, mode, filename,
strerror (errno)));
return false;
}
+ printf ("fseek returned: %i, position: %llu\n", result, GetPosition
());
return true;
}
@@ -797,7 +954,11 @@
uncompressed_data = NULL;
if (decoder_specific_data != NULL) {
- stream->decoder->Cleanup (this);
+ if (stream != NULL && stream->decoder != NULL) {
+ stream->decoder->Cleanup (this);
+ } else {
+ printf ("MediaFrame::~MediaFrame (): Couldn't call
decoder->Cleanup.\n");
+ }
}
}
Modified: trunk/moon/src/pipeline.h
===================================================================
--- trunk/moon/src/pipeline.h 2008-01-11 14:48:10 UTC (rev 92669)
+++ trunk/moon/src/pipeline.h 2008-01-11 14:50:22 UTC (rev 92670)
@@ -111,6 +111,8 @@
#define MEDIA_OUT_OF_MEMORY ((MediaResult) 10)
#define MEDIA_DEMUXER_ERROR ((MediaResult) 11)
#define MEDIA_CONVERTER_ERROR ((MediaResult) 12)
+#define MEDIA_UNKNOWN_CONVERTER ((MediaResult) 13)
+#define MEDIA_UNKNOWN_MEDIA_TYPE ((MediaResult) 14)
#define MEDIA_SUCCEEDED(x) ((x == 0))
@@ -144,6 +146,38 @@
MediaResult Call ();
};
+/*
+ * *Info classes used to register codecs, demuxers and converters.
+ */
+
+class MediaInfo {
+public:
+ MediaInfo* next; // Used internally by Media.
+ MediaInfo () : next (NULL) {}
+ virtual ~MediaInfo () {}
+ virtual const char* GetName () { return "Unknown"; }
+};
+
+class DecoderInfo : public MediaInfo {
+public:
+ virtual bool Supports (const char* codec) = 0;
+ virtual IMediaDecoder* Create (Media* media, IMediaStream* stream) = 0;
+};
+
+class DemuxerInfo : public MediaInfo {
+public:
+ // <buffer> points to the first <length> bytes of a file.
+ // <length> is guaranteed to be at least 16 bytes.
+ virtual bool Supports (uint8_t* buffer, uint32_t length) = 0;
+ virtual IMediaDemuxer* Create (Media* media) = 0;
+};
+
+class ConverterInfo : public MediaInfo {
+public:
+ virtual bool Supports (MoonPixelFormat input, MoonPixelFormat output) =
0;
+ virtual IImageConverter* Create (Media* media, VideoStream* stream) = 0;
+};
+
class Media {
public:
Media (void* element);
@@ -193,7 +227,22 @@
void AddMessage (MediaResult result, const char* msg);
void AddMessage (MediaResult result, char* msg);
+
+public:
+ // Registration functions
+ // This class takes ownership of the infos and will delete them (not free)
when the Media is shutdown.
+ static void RegisterDemuxer (DemuxerInfo *info);
+ static void RegisterDecoder (DecoderInfo *info);
+ static void RegisterConverter (ConverterInfo *info);
+
+ static void Initialize ();
+ static void Shutdown ();
private:
+ static DemuxerInfo* registered_demuxers;
+ static DecoderInfo* registered_decoders;
+ static ConverterInfo* registered_converters;
+
+private:
// Called on another thread, loops the queue of requested frames
// and calls GetNextFrame and FrameReadCallback.
// If there are any requests for audio frames in the queue
@@ -310,11 +359,12 @@
IMediaSource (Media* med) : media (med) {}
virtual ~IMediaSource () {}
virtual bool IsSeekable () = 0;
- virtual bool Seek (gint64 position) = 0;
- virtual bool Seek (gint64 position, int mode) = 0;
+ virtual bool Seek (gint64 offset) = 0; // Seeks to the offset from the
current position
+ virtual bool Seek (gint64 offset, int mode) = 0;
virtual bool Read (void* buffer, guint32 size) = 0;
virtual bool Peek (void* buffer, guint32 size) = 0;
virtual guint64 GetPosition () = 0;
+ virtual void SetPosition (guint64 position) { Seek (position,
SEEK_SET); }
virtual bool Eof () = 0;
protected:
@@ -467,6 +517,13 @@
gint32* stream_to_asf_index;
};
+class ASFDemuxerInfo : public DemuxerInfo {
+public:
+ virtual bool Supports (uint8_t* buffer, uint32_t length);
+ virtual IMediaDemuxer* Create (Media* media);
+ virtual const char* GetName () { return "ASFDemuxer"; }
+};
+
class ASFMarkerStream : public IMediaStream {
public:
ASFMarkerStream (Media* media) : IMediaStream (media) {}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches