From b4ef57412c8544a8d487a8b0d97b953d1cd45d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 2 Jul 2009 13:31:50 +0000 Subject: [PATCH] Work in Progress of trying to get libavformat to detect anything... unsuccessful so far. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31369 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/plugins/ffmpeg/AVFormatReader.cpp | 148 +++++++++++++++++- .../media/plugins/ffmpeg/AVFormatReader.h | 6 + .../media/plugins/ffmpeg/FFmpegPlugin.cpp | 6 + 3 files changed, 155 insertions(+), 5 deletions(-) diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp index 7a7683100b..25d7a10bee 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp @@ -18,12 +18,13 @@ extern "C" { #include "avformat.h" + #include "libavutil/avstring.h" } //#include "RawFormats.h" -//#define TRACE_AVFORMAT_READER +#define TRACE_AVFORMAT_READER #ifdef TRACE_AVFORMAT_READER # define TRACE printf #else @@ -40,7 +41,35 @@ extern "C" { static int position_io_open(URLContext* h, const char* filename, int flags) { - // always successful, priv_data is set elsewhere + TRACE("position_io_open(%s)\n", filename); + + // Strip the URL prefix + av_strstart(filename, "position_io:", &filename); + + void* pointer; + if (sscanf(filename, "%p", &pointer) != 1) { + TRACE("position_io_open(%s) - unable to scan BPositionIO pointer\n", + filename); + return AVERROR(ENOENT); + } + + // When the pointer was placed, it was a BDataIO*. Try to convert that + // into a BPositionIO. + // TODO: Later we may implement two different protocols, one which + // supports seeking (BPositionIO) and one that does not (BDataIO). + BDataIO* dataIO = reinterpret_cast(pointer); + BPositionIO* positionIO = dynamic_cast(dataIO); + if (positionIO == NULL) { + TRACE("position_io_open(%s) - unable to cast BDataIO pointer %p\n", + filename, dataIO); + return AVERROR(ENOENT); + } + + TRACE("position_io_open(%s) - success: BPositionIO: %p\n", + filename, positionIO); + + h->priv_data = reinterpret_cast(positionIO); + return 0; } @@ -48,6 +77,8 @@ position_io_open(URLContext* h, const char* filename, int flags) static int position_io_read(URLContext* h, unsigned char* buffer, int size) { + TRACE("position_io_read(%d)\n", size); + BPositionIO* source = reinterpret_cast(h->priv_data); return source->Read(buffer, size); } @@ -56,22 +87,28 @@ position_io_read(URLContext* h, unsigned char* buffer, int size) static int position_io_write(URLContext* h, unsigned char* buffer, int size) { + TRACE("position_io_write(%d)\n", size); + BPositionIO* source = reinterpret_cast(h->priv_data); return source->Write(buffer, size); } static int64_t -position_io_seek(URLContext *h, int64_t position, int whence) +position_io_seek(URLContext* h, int64_t position, int whence) { + TRACE("position_io_seek(%lld, %d)\n", position, whence); + BPositionIO* source = reinterpret_cast(h->priv_data); return source->Seek(position, whence); } static int -position_io_close(URLContext *h) +position_io_close(URLContext* h) { + TRACE("position_io_close()\n"); + // We do not close ourselves here. return 0; } @@ -122,6 +159,72 @@ AVFormatReader::Sniff(int32* streamCount) { TRACE("AVFormatReader::Sniff\n"); +#if 0 + // Construct an URL string that allows us to get the Source() + // BPositionIO pointer and try to open the stream. + char urlString[64]; + snprintf(urlString, sizeof(urlString), "position_io:%p", (void*)Source()); + + if (av_open_input_file(&fContext, urlString, NULL, 0, NULL) < 0) { + TRACE("AVFormatReader::Sniff() - av_open_input_file(%s) failed!\n", + urlString); + return B_ERROR; + } + +#else + size_t bufferSize = 64 * 1024; + uint8 buffer[bufferSize]; + AVProbeData probeData; + probeData.filename = ""; + probeData.buf = buffer; + probeData.buf_size = bufferSize; + + // Read a bit of the input + _ReadPacket(Source(), buffer, bufferSize); + + // Probe the input format + AVInputFormat* inputFormat = av_probe_input_format(&probeData, 1); + + if (inputFormat == NULL) { + TRACE("AVFormatReader::Sniff() - av_probe_input_format() failed!\n"); + return B_ERROR; + } + + TRACE("AVFormatReader::Sniff() - av_probe_input_format(): %s\n", + inputFormat->name); + + ByteIOContext ioContext; + + // Init io module for input + if (init_put_byte(&ioContext, buffer, bufferSize, 0, Source(), + _ReadPacket, 0, _Seek) != 0) { + TRACE("AVFormatReader::Sniff() - init_put_byte() failed!\n"); + return B_ERROR; + } + + AVFormatParameters params; + memset(¶ms, 0, sizeof(params)); + + if (av_open_input_stream(&fContext, &ioContext, "", inputFormat, + ¶ms) < 0) { + TRACE("AVFormatReader::Sniff() - av_open_input_file() failed!\n"); + return B_ERROR; + } +#endif + + TRACE("AVFormatReader::Sniff() - av_open_input_file() success!\n"); + + // Retrieve stream information + if (av_find_stream_info(fContext) < 0) { + TRACE("AVFormatReader::Sniff() - av_find_stream_info() failed!\n"); + return B_ERROR; + } + + TRACE("AVFormatReader::Sniff() - av_find_stream_info() success!\n"); + + // Dump information about stream onto standard error + dump_format(fContext, 0, "", 0); + return B_ERROR; } @@ -177,7 +280,7 @@ AVFormatReader::GetStreamInfo(void* _cookie, int64* frameCount, status_t AVFormatReader::Seek(void* _cookie, uint32 seekTo, int64* frame, - bigtime_t* time) + bigtime_t* time) { return B_ERROR; } @@ -199,3 +302,38 @@ AVFormatReader::GetNextChunk(void* _cookie, const void** chunkBuffer, } +// #pragma mark - + + +/*static*/ int +AVFormatReader::_ReadPacket(void* cookie, uint8* buffer, int bufferSize) +{ + TRACE("AVFormatReader::_ReadPacket(%p, %p, %d)\n", cookie, buffer, + bufferSize); + + BDataIO* dataIO = reinterpret_cast(cookie); + ssize_t read = dataIO->Read(buffer, bufferSize); + + TRACE(" read: %ld\n", read); + return read; +} + + +/*static*/ off_t +AVFormatReader::_Seek(void* cookie, off_t offset, int whence) +{ + TRACE("AVFormatReader::_Seek(%p, %lld, %d)\n", cookie, offset, whence); + + BDataIO* dataIO = reinterpret_cast(cookie); + BPositionIO* positionIO = dynamic_cast(dataIO); + if (positionIO == NULL) { + TRACE(" not a BPositionIO\n"); + return -1; + } + + off_t position = positionIO->Seek(offset, whence); + + TRACE(" position: %lld\n", position); + return position; +} + diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.h b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.h index 8dd134b256..0edfd6c180 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.h +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.h @@ -42,6 +42,12 @@ public: media_header* mediaHeader); private: + static int _ReadPacket(void* cookie, + uint8* buffer, int bufferSize); + + static off_t _Seek(void* cookie, + off_t offset, int whence); + AVFormatContext* fContext; }; diff --git a/src/add-ons/media/plugins/ffmpeg/FFmpegPlugin.cpp b/src/add-ons/media/plugins/ffmpeg/FFmpegPlugin.cpp index cb4157c07b..9a4708e8d6 100644 --- a/src/add-ons/media/plugins/ffmpeg/FFmpegPlugin.cpp +++ b/src/add-ons/media/plugins/ffmpeg/FFmpegPlugin.cpp @@ -32,6 +32,12 @@ FFmpegPlugin::GlobalInitilizer::GlobalInitilizer() extern URLProtocol sPositionIOProtocol; av_register_protocol(&sPositionIOProtocol); + +// // Dump the supported protocols to stdout. +// URLProtocol* p = NULL; +// while ((p = av_protocol_next(p)) != NULL) { +// printf("supported protocol: %s\n", p->name); +// } }