* It actually helps a lot to turn on all the demuxers if you want to use any.

* The URLProtocol idea seems not to work out, so I removed that code, but
  the other idea of setting up a ByteIOContext actually works, once I seek
  back to the beginning of the stream after reading the initial probe buffer,
  we may also offset the buffer pointer in the ByteIOContext to where we
  have already read, but I am not sure of possible side effects of that.

We can now probe for the correct demuxer and detect streams.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31379 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2009-07-03 00:26:11 +00:00
parent f207162e07
commit a244fc3ac7
5 changed files with 143 additions and 247 deletions

View File

@ -27,106 +27,15 @@ extern "C" {
#define TRACE_AVFORMAT_READER #define TRACE_AVFORMAT_READER
#ifdef TRACE_AVFORMAT_READER #ifdef TRACE_AVFORMAT_READER
# define TRACE printf # define TRACE printf
# define TRACE_IO(a...)
#else #else
# define TRACE(a...) # define TRACE(a...)
# define TRACE_IO(a...)
#endif #endif
#define ERROR(a...) fprintf(stderr, a) #define ERROR(a...) fprintf(stderr, a)
// #pragma mark - BPositionIO protocol
static int
position_io_open(URLContext* h, const char* filename, int flags)
{
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<BDataIO*>(pointer);
BPositionIO* positionIO = dynamic_cast<BPositionIO*>(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<void*>(positionIO);
return 0;
}
static int
position_io_read(URLContext* h, unsigned char* buffer, int size)
{
TRACE("position_io_read(%d)\n", size);
BPositionIO* source = reinterpret_cast<BPositionIO*>(h->priv_data);
return source->Read(buffer, size);
}
static int
position_io_write(URLContext* h, unsigned char* buffer, int size)
{
TRACE("position_io_write(%d)\n", size);
BPositionIO* source = reinterpret_cast<BPositionIO*>(h->priv_data);
return source->Write(buffer, size);
}
static int64_t
position_io_seek(URLContext* h, int64_t position, int whence)
{
TRACE("position_io_seek(%lld, %d)\n", position, whence);
BPositionIO* source = reinterpret_cast<BPositionIO*>(h->priv_data);
return source->Seek(position, whence);
}
static int
position_io_close(URLContext* h)
{
TRACE("position_io_close()\n");
// We do not close ourselves here.
return 0;
}
URLProtocol sPositionIOProtocol = {
"position_io",
position_io_open,
position_io_read,
position_io_write,
position_io_seek,
position_io_close
};
// #pragma mark - AVFormatReader
AVFormatReader::AVFormatReader() AVFormatReader::AVFormatReader()
: :
fContext(NULL) fContext(NULL)
@ -159,28 +68,19 @@ AVFormatReader::Sniff(int32* streamCount)
{ {
TRACE("AVFormatReader::Sniff\n"); 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; size_t bufferSize = 64 * 1024;
size_t probeSize = 1024;
uint8 buffer[bufferSize]; uint8 buffer[bufferSize];
AVProbeData probeData; AVProbeData probeData;
probeData.filename = ""; probeData.filename = "";
probeData.buf = buffer; probeData.buf = buffer;
probeData.buf_size = bufferSize; probeData.buf_size = probeSize;
// Read a bit of the input // Read a bit of the input...
_ReadPacket(Source(), buffer, bufferSize); if (_ReadPacket(Source(), buffer, probeSize) != (ssize_t)probeSize)
return B_IO_ERROR;
// ...and seek back to the beginning of the file.
_Seek(Source(), 0, SEEK_SET);
// Probe the input format // Probe the input format
AVInputFormat* inputFormat = av_probe_input_format(&probeData, 1); AVInputFormat* inputFormat = av_probe_input_format(&probeData, 1);
@ -202,17 +102,14 @@ AVFormatReader::Sniff(int32* streamCount)
return B_ERROR; return B_ERROR;
} }
AVFormatParameters params; AVFormatParameters formatParameters;
memset(&params, 0, sizeof(params)); memset(&formatParameters, 0, sizeof(formatParameters));
if (av_open_input_stream(&fContext, &ioContext, "", inputFormat, if (av_open_input_stream(&fContext, &ioContext, "", inputFormat,
&params) < 0) { &formatParameters) < 0) {
TRACE("AVFormatReader::Sniff() - av_open_input_file() failed!\n"); TRACE("AVFormatReader::Sniff() - av_open_input_stream() failed!\n");
return B_ERROR; return B_ERROR;
} }
#endif
TRACE("AVFormatReader::Sniff() - av_open_input_file() success!\n");
// Retrieve stream information // Retrieve stream information
if (av_find_stream_info(fContext) < 0) { if (av_find_stream_info(fContext) < 0) {
@ -308,21 +205,21 @@ AVFormatReader::GetNextChunk(void* _cookie, const void** chunkBuffer,
/*static*/ int /*static*/ int
AVFormatReader::_ReadPacket(void* cookie, uint8* buffer, int bufferSize) AVFormatReader::_ReadPacket(void* cookie, uint8* buffer, int bufferSize)
{ {
TRACE("AVFormatReader::_ReadPacket(%p, %p, %d)\n", cookie, buffer, TRACE_IO("AVFormatReader::_ReadPacket(%p, %p, %d)\n", cookie, buffer,
bufferSize); bufferSize);
BDataIO* dataIO = reinterpret_cast<BDataIO*>(cookie); BDataIO* dataIO = reinterpret_cast<BDataIO*>(cookie);
ssize_t read = dataIO->Read(buffer, bufferSize); ssize_t read = dataIO->Read(buffer, bufferSize);
TRACE(" read: %ld\n", read); TRACE_IO(" read: %ld\n", read);
return read; return (int)read;
} }
/*static*/ off_t /*static*/ off_t
AVFormatReader::_Seek(void* cookie, off_t offset, int whence) AVFormatReader::_Seek(void* cookie, off_t offset, int whence)
{ {
TRACE("AVFormatReader::_Seek(%p, %lld, %d)\n", cookie, offset, whence); TRACE_IO("AVFormatReader::_Seek(%p, %lld, %d)\n", cookie, offset, whence);
BDataIO* dataIO = reinterpret_cast<BDataIO*>(cookie); BDataIO* dataIO = reinterpret_cast<BDataIO*>(cookie);
BPositionIO* positionIO = dynamic_cast<BPositionIO*>(dataIO); BPositionIO* positionIO = dynamic_cast<BPositionIO*>(dataIO);
@ -331,9 +228,17 @@ AVFormatReader::_Seek(void* cookie, off_t offset, int whence)
return -1; return -1;
} }
// Support for special file size retrieval API without seeking anywhere:
if (whence == AVSEEK_SIZE) {
off_t size;
if (positionIO->GetSize(&size) == B_OK)
return size;
return -1;
}
off_t position = positionIO->Seek(offset, whence); off_t position = positionIO->Seek(offset, whence);
TRACE(" position: %lld\n", position); TRACE_IO(" position: %lld\n", position);
return position; return position;
} }

View File

@ -42,7 +42,7 @@ public:
media_header* mediaHeader); media_header* mediaHeader);
private: private:
static int _ReadPacket(void* cookie, static int _ReadPacket(void* cookie,
uint8* buffer, int bufferSize); uint8* buffer, int bufferSize);
static off_t _Seek(void* cookie, static off_t _Seek(void* cookie,

View File

@ -29,15 +29,6 @@ FFmpegPlugin::GlobalInitilizer::GlobalInitilizer()
{ {
av_register_all(); av_register_all();
// This will also call av_codec_init() by registering codecs. // This will also call av_codec_init() by registering codecs.
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);
// }
} }

View File

@ -514,126 +514,126 @@
#define CONFIG_NOISE_BSF 1 #define CONFIG_NOISE_BSF 1
#define CONFIG_REMOVE_EXTRADATA_BSF 1 #define CONFIG_REMOVE_EXTRADATA_BSF 1
#define CONFIG_TEXT2MOVSUB_BSF 1 #define CONFIG_TEXT2MOVSUB_BSF 1
#define CONFIG_AAC_DEMUXER 0 #define CONFIG_AAC_DEMUXER 1
#define CONFIG_AC3_DEMUXER 0 #define CONFIG_AC3_DEMUXER 1
#define CONFIG_AIFF_DEMUXER 0 #define CONFIG_AIFF_DEMUXER 1
#define CONFIG_AMR_DEMUXER 0 #define CONFIG_AMR_DEMUXER 1
#define CONFIG_APC_DEMUXER 0 #define CONFIG_APC_DEMUXER 1
#define CONFIG_APE_DEMUXER 0 #define CONFIG_APE_DEMUXER 1
#define CONFIG_ASF_DEMUXER 0 #define CONFIG_ASF_DEMUXER 1
#define CONFIG_ASS_DEMUXER 0 #define CONFIG_ASS_DEMUXER 1
#define CONFIG_AU_DEMUXER 0 #define CONFIG_AU_DEMUXER 1
#define CONFIG_AVI_DEMUXER 0 #define CONFIG_AVI_DEMUXER 1
#define CONFIG_AVISYNTH_DEMUXER 0 #define CONFIG_AVISYNTH_DEMUXER 0
#define CONFIG_AVS_DEMUXER 0 #define CONFIG_AVS_DEMUXER 1
#define CONFIG_BETHSOFTVID_DEMUXER 0 #define CONFIG_BETHSOFTVID_DEMUXER 1
#define CONFIG_BFI_DEMUXER 0 #define CONFIG_BFI_DEMUXER 1
#define CONFIG_C93_DEMUXER 0 #define CONFIG_C93_DEMUXER 1
#define CONFIG_CAVSVIDEO_DEMUXER 0 #define CONFIG_CAVSVIDEO_DEMUXER 1
#define CONFIG_DAUD_DEMUXER 0 #define CONFIG_DAUD_DEMUXER 1
#define CONFIG_DIRAC_DEMUXER 0 #define CONFIG_DIRAC_DEMUXER 1
#define CONFIG_DNXHD_DEMUXER 0 #define CONFIG_DNXHD_DEMUXER 1
#define CONFIG_DSICIN_DEMUXER 0 #define CONFIG_DSICIN_DEMUXER 1
#define CONFIG_DTS_DEMUXER 0 #define CONFIG_DTS_DEMUXER 1
#define CONFIG_DV_DEMUXER 0 #define CONFIG_DV_DEMUXER 1
#define CONFIG_DXA_DEMUXER 0 #define CONFIG_DXA_DEMUXER 1
#define CONFIG_EA_DEMUXER 0 #define CONFIG_EA_DEMUXER 1
#define CONFIG_EA_CDATA_DEMUXER 0 #define CONFIG_EA_CDATA_DEMUXER 1
#define CONFIG_EAC3_DEMUXER 0 #define CONFIG_EAC3_DEMUXER 1
#define CONFIG_FFM_DEMUXER 0 #define CONFIG_FFM_DEMUXER 1
#define CONFIG_FLAC_DEMUXER 0 #define CONFIG_FLAC_DEMUXER 1
#define CONFIG_FLIC_DEMUXER 0 #define CONFIG_FLIC_DEMUXER 1
#define CONFIG_FLV_DEMUXER 0 #define CONFIG_FLV_DEMUXER 1
#define CONFIG_FOURXM_DEMUXER 0 #define CONFIG_FOURXM_DEMUXER 1
#define CONFIG_GSM_DEMUXER 0 #define CONFIG_GSM_DEMUXER 1
#define CONFIG_GXF_DEMUXER 0 #define CONFIG_GXF_DEMUXER 1
#define CONFIG_H261_DEMUXER 0 #define CONFIG_H261_DEMUXER 1
#define CONFIG_H263_DEMUXER 0 #define CONFIG_H263_DEMUXER 1
#define CONFIG_H264_DEMUXER 0 #define CONFIG_H264_DEMUXER 1
#define CONFIG_IDCIN_DEMUXER 0 #define CONFIG_IDCIN_DEMUXER 1
#define CONFIG_IFF_DEMUXER 0 #define CONFIG_IFF_DEMUXER 1
#define CONFIG_IMAGE2_DEMUXER 0 #define CONFIG_IMAGE2_DEMUXER 1
#define CONFIG_IMAGE2PIPE_DEMUXER 0 #define CONFIG_IMAGE2PIPE_DEMUXER 1
#define CONFIG_INGENIENT_DEMUXER 0 #define CONFIG_INGENIENT_DEMUXER 1
#define CONFIG_IPMOVIE_DEMUXER 0 #define CONFIG_IPMOVIE_DEMUXER 1
#define CONFIG_ISS_DEMUXER 0 #define CONFIG_ISS_DEMUXER 1
#define CONFIG_LMLM4_DEMUXER 0 #define CONFIG_LMLM4_DEMUXER 0
#define CONFIG_M4V_DEMUXER 0 #define CONFIG_M4V_DEMUXER 1
#define CONFIG_MATROSKA_DEMUXER 0 #define CONFIG_MATROSKA_DEMUXER 1
#define CONFIG_MJPEG_DEMUXER 0 #define CONFIG_MJPEG_DEMUXER 1
#define CONFIG_MLP_DEMUXER 0 #define CONFIG_MLP_DEMUXER 1
#define CONFIG_MM_DEMUXER 0 #define CONFIG_MM_DEMUXER 1
#define CONFIG_MMF_DEMUXER 0 #define CONFIG_MMF_DEMUXER 1
#define CONFIG_MOV_DEMUXER 0 #define CONFIG_MOV_DEMUXER 1
#define CONFIG_MP3_DEMUXER 0 #define CONFIG_MP3_DEMUXER 1
#define CONFIG_MPC_DEMUXER 0 #define CONFIG_MPC_DEMUXER 1
#define CONFIG_MPC8_DEMUXER 0 #define CONFIG_MPC8_DEMUXER 1
#define CONFIG_MPEGPS_DEMUXER 0 #define CONFIG_MPEGPS_DEMUXER 1
#define CONFIG_MPEGTS_DEMUXER 0 #define CONFIG_MPEGTS_DEMUXER 1
#define CONFIG_MPEGTSRAW_DEMUXER 0 #define CONFIG_MPEGTSRAW_DEMUXER 1
#define CONFIG_MPEGVIDEO_DEMUXER 0 #define CONFIG_MPEGVIDEO_DEMUXER 1
#define CONFIG_MSNWC_TCP_DEMUXER 0 #define CONFIG_MSNWC_TCP_DEMUXER 1
#define CONFIG_MTV_DEMUXER 0 #define CONFIG_MTV_DEMUXER 1
#define CONFIG_MVI_DEMUXER 0 #define CONFIG_MVI_DEMUXER 1
#define CONFIG_MXF_DEMUXER 0 #define CONFIG_MXF_DEMUXER 1
#define CONFIG_NC_DEMUXER 0 #define CONFIG_NC_DEMUXER 1
#define CONFIG_NSV_DEMUXER 0 #define CONFIG_NSV_DEMUXER 1
#define CONFIG_NUT_DEMUXER 0 #define CONFIG_NUT_DEMUXER 0
#define CONFIG_NUV_DEMUXER 0 #define CONFIG_NUV_DEMUXER 1
#define CONFIG_OGG_DEMUXER 0 #define CONFIG_OGG_DEMUXER 1
#define CONFIG_OMA_DEMUXER 0 #define CONFIG_OMA_DEMUXER 1
#define CONFIG_PCM_ALAW_DEMUXER 0 #define CONFIG_PCM_ALAW_DEMUXER 1
#define CONFIG_PCM_MULAW_DEMUXER 0 #define CONFIG_PCM_MULAW_DEMUXER 1
#define CONFIG_PCM_F64BE_DEMUXER 0 #define CONFIG_PCM_F64BE_DEMUXER 1
#define CONFIG_PCM_F64LE_DEMUXER 0 #define CONFIG_PCM_F64LE_DEMUXER 1
#define CONFIG_PCM_F32BE_DEMUXER 0 #define CONFIG_PCM_F32BE_DEMUXER 1
#define CONFIG_PCM_F32LE_DEMUXER 0 #define CONFIG_PCM_F32LE_DEMUXER 1
#define CONFIG_PCM_S32BE_DEMUXER 0 #define CONFIG_PCM_S32BE_DEMUXER 1
#define CONFIG_PCM_S32LE_DEMUXER 0 #define CONFIG_PCM_S32LE_DEMUXER 1
#define CONFIG_PCM_S24BE_DEMUXER 0 #define CONFIG_PCM_S24BE_DEMUXER 1
#define CONFIG_PCM_S24LE_DEMUXER 0 #define CONFIG_PCM_S24LE_DEMUXER 1
#define CONFIG_PCM_S16BE_DEMUXER 0 #define CONFIG_PCM_S16BE_DEMUXER 1
#define CONFIG_PCM_S16LE_DEMUXER 0 #define CONFIG_PCM_S16LE_DEMUXER 1
#define CONFIG_PCM_S8_DEMUXER 0 #define CONFIG_PCM_S8_DEMUXER 1
#define CONFIG_PCM_U32BE_DEMUXER 0 #define CONFIG_PCM_U32BE_DEMUXER 1
#define CONFIG_PCM_U32LE_DEMUXER 0 #define CONFIG_PCM_U32LE_DEMUXER 1
#define CONFIG_PCM_U24BE_DEMUXER 0 #define CONFIG_PCM_U24BE_DEMUXER 1
#define CONFIG_PCM_U24LE_DEMUXER 0 #define CONFIG_PCM_U24LE_DEMUXER 1
#define CONFIG_PCM_U16BE_DEMUXER 0 #define CONFIG_PCM_U16BE_DEMUXER 1
#define CONFIG_PCM_U16LE_DEMUXER 0 #define CONFIG_PCM_U16LE_DEMUXER 1
#define CONFIG_PCM_U8_DEMUXER 0 #define CONFIG_PCM_U8_DEMUXER 1
#define CONFIG_PVA_DEMUXER 0 #define CONFIG_PVA_DEMUXER 1
#define CONFIG_R3D_DEMUXER 0 #define CONFIG_R3D_DEMUXER 1
#define CONFIG_RAWVIDEO_DEMUXER 0 #define CONFIG_RAWVIDEO_DEMUXER 1
#define CONFIG_REDIR_DEMUXER 0 #define CONFIG_REDIR_DEMUXER 0
#define CONFIG_RL2_DEMUXER 0 #define CONFIG_RL2_DEMUXER 1
#define CONFIG_RM_DEMUXER 0 #define CONFIG_RM_DEMUXER 1
#define CONFIG_ROQ_DEMUXER 0 #define CONFIG_ROQ_DEMUXER 1
#define CONFIG_RPL_DEMUXER 0 #define CONFIG_RPL_DEMUXER 1
#define CONFIG_RTSP_DEMUXER 0 #define CONFIG_RTSP_DEMUXER 0
#define CONFIG_SDP_DEMUXER 0 #define CONFIG_SDP_DEMUXER 0
#define CONFIG_SEGAFILM_DEMUXER 0 #define CONFIG_SEGAFILM_DEMUXER 1
#define CONFIG_SHORTEN_DEMUXER 0 #define CONFIG_SHORTEN_DEMUXER 1
#define CONFIG_SIFF_DEMUXER 0 #define CONFIG_SIFF_DEMUXER 1
#define CONFIG_SMACKER_DEMUXER 0 #define CONFIG_SMACKER_DEMUXER 1
#define CONFIG_SOL_DEMUXER 0 #define CONFIG_SOL_DEMUXER 1
#define CONFIG_STR_DEMUXER 0 #define CONFIG_STR_DEMUXER 1
#define CONFIG_SWF_DEMUXER 0 #define CONFIG_SWF_DEMUXER 1
#define CONFIG_THP_DEMUXER 0 #define CONFIG_THP_DEMUXER 1
#define CONFIG_TIERTEXSEQ_DEMUXER 0 #define CONFIG_TIERTEXSEQ_DEMUXER 1
#define CONFIG_TTA_DEMUXER 0 #define CONFIG_TTA_DEMUXER 1
#define CONFIG_TXD_DEMUXER 0 #define CONFIG_TXD_DEMUXER 1
#define CONFIG_VC1_DEMUXER 0 #define CONFIG_VC1_DEMUXER 1
#define CONFIG_VC1T_DEMUXER 0 #define CONFIG_VC1T_DEMUXER 1
#define CONFIG_VMD_DEMUXER 0 #define CONFIG_VMD_DEMUXER 1
#define CONFIG_VOC_DEMUXER 0 #define CONFIG_VOC_DEMUXER 1
#define CONFIG_WAV_DEMUXER 0 #define CONFIG_WAV_DEMUXER 1
#define CONFIG_WC3_DEMUXER 0 #define CONFIG_WC3_DEMUXER 1
#define CONFIG_WSAUD_DEMUXER 0 #define CONFIG_WSAUD_DEMUXER 1
#define CONFIG_WSVQA_DEMUXER 0 #define CONFIG_WSVQA_DEMUXER 1
#define CONFIG_WV_DEMUXER 0 #define CONFIG_WV_DEMUXER 1
#define CONFIG_XA_DEMUXER 0 #define CONFIG_XA_DEMUXER 1
#define CONFIG_YUV4MPEGPIPE_DEMUXER 0 #define CONFIG_YUV4MPEGPIPE_DEMUXER 1
#define CONFIG_LIBNUT_DEMUXER 0 #define CONFIG_LIBNUT_DEMUXER 0
#define CONFIG_AC3_MUXER 0 #define CONFIG_AC3_MUXER 0
#define CONFIG_ADTS_MUXER 0 #define CONFIG_ADTS_MUXER 0

View File

@ -161,8 +161,8 @@ StaticLibrary libavformat.a :
rtpenc.c rtpenc.c
rtpenc_h264.c rtpenc_h264.c
# rtpproto.c # (I/O protocol) # rtpproto.c # (I/O protocol)
rtsp.c # rtsp.c
sdp.c # sdp.c
segafilm.c segafilm.c
sierravmd.c sierravmd.c
siff.c siff.c