Get the AVFormatReader into a usable state. DemuxerTable.cpp controls which

container formats we support. I hope I have turned on only those that don't
have an implementation already (did we support ASF already?). I mostly tested
with AVI and that works reasonably well, but I only tested raw audio so far.
However, the backend for Marcus' avi_reader is much nicer than FFmpeg, so I
think it should stay and have disabled the support for AVI in AVFormatReader.
A big disappointment is that MPG containers only give scrambled video. It may
be a problem of the AVCodecDecoder, but I am not so sure. After all, it works
fine for other container formats. If I am not mistaken, VLC also does not use
the mpeg demuxer from FFmpeg. :-\ On top of that, libavformat detects the
time_base and stream duration wrongly for one of my test MPGs.
As for the implementation: Although seeking in libavformat happens for an
individual stream, in reality, the packets for all other streams need to be
flushed (that's also what happens in the libavformat tutorials I've seen).
Since our MediaKit API allows to seek tracks indivually, this is of course
a no-go, since then all other tracks would be out of sync. My solution is to
simply open the demuxer once for each stream and then completely ignore the
packets of the respective other streams. This also works around the problem
that libavformat is unable to provide packets by stream, requiring the
API user to queue the packets that he needs not now, but later for other
streams. It also means we have to no memory copies, since we can directly
use the packet buffer until the next call to GetNextChunk().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31421 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2009-07-06 13:43:02 +00:00
parent db627302b7
commit 7965dde0ca
5 changed files with 1013 additions and 264 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6,11 +6,9 @@
#define AV_FORMAT_READER_H
#include "ReaderPlugin.h"
#include <Locker.h>
extern "C" {
#include "avformat.h"
}
#include "ReaderPlugin.h"
class AVFormatReader : public Reader {
@ -39,31 +37,15 @@ public:
int64* frame, bigtime_t* time);
virtual status_t GetNextChunk(void* cookie,
const void** chunkBuffer, size_t* chunkSize,
const void** chunkBuffer,
size_t* chunkSize,
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;
AVFormatParameters fFormatParameters;
ByteIOContext fIOContext;
uint8* fIOBuffer;
struct StreamCookie {
AVStream* stream;
AVCodecContext* codecContext;
AVCodec* codec;
media_format format;
// TODO: Maybe we don't need the codec after all, maybe we do
// for getting stream information...
// TODO: Some form of packet queue
};
class StreamCookie;
StreamCookie** fStreams;
BLocker fStreamLock;
};

View File

@ -0,0 +1,81 @@
/*
* Copyright 2009 Stephan Aßmus <superstippi@gmx.de>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "DemuxerTable.h"
extern "C" {
#include "avformat.h"
}
// NOTE: AVFormatReader will refuse any streams which do not match to any
// of these formats from the table. It could very well be that it could play
// these streams, but testing has to be done first.
static const DemuxerFormat gDemuxerTable[] = {
{
// TODO: untested!
"asf", "ASF Movie", "video/x-asf",
B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
},
// {
// // Tested with a limited amount of streams and works ok, keep using
// // the avi_reader implementation by Marcus Overhagen.
// "avi", "AVI (Audio Video Interleaved)", "video/x-msvideo",
// B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
// },
// {
// TODO: untested!
// "mov", "MOV (Quicktime Movie)", "video/x-mov",
// B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
// },
// {
// // TODO: Broken because of buggy FindKeyFrame() or Seek() support.
// "mp3", "MPEG (Motion Picture Experts Group)", "audio/mpg",
// B_MPEG_FORMAT_FAMILY, B_MPEG_FORMAT_FAMILY
// },
{
// NOTE: Tested with a couple of files and only audio works ok.
// On some files, the duration and time_base is detected incorrectly
// by libavformat and those streams don't play at all.
"mpg", "MPEG (Motion Picture Experts Group)", "video/mpg",
B_MPEG_FORMAT_FAMILY, B_MPEG_FORMAT_FAMILY
},
{
// TODO: Also covers "mpegvideo", plus see above.
"mpeg", "MPEG (Motion Picture Experts Group)", "video/mpg",
B_MPEG_FORMAT_FAMILY, B_MPEG_FORMAT_FAMILY
},
{
// TODO: untested!
"nsv", "NSV (NullSoft Video File)", "video/nsv",
B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
},
{
// TODO: untested!
"rm", "RM (RealVideo Clip)", "video/vnd.rn-realvideo",
B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
},
{
// TODO: untested!
"vob", "VOB Movie", "video/x-vob",
B_MPEG_FORMAT_FAMILY, B_MPEG_FORMAT_FAMILY
},
};
const DemuxerFormat*
demuxer_format_for(AVInputFormat* format)
{
int32 demuxerFormatCount = sizeof(gDemuxerTable) / sizeof(DemuxerFormat);
for (int32 i = 0; i < demuxerFormatCount; i++) {
const DemuxerFormat* demuxerFormat = &gDemuxerTable[i];
if (strstr(format->name, demuxerFormat->demuxer_name) != NULL)
return demuxerFormat;
}
return NULL;
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2009 Stephan Aßmus <superstippi@gmx.de>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef DEMUXER_TABLE_H
#define DEMUXER_TABLE_H
#include <MediaDefs.h>
struct DemuxerFormat {
const char* demuxer_name;
const char* pretty_name;
const char* mime_type;
media_format_family audio_family;
media_format_family video_family;
};
struct AVInputFormat;
const DemuxerFormat* demuxer_format_for(AVInputFormat* format);
#endif // DEMUXER_TABLE_H

View File

@ -2,7 +2,7 @@ SubDir HAIKU_TOP src add-ons media plugins ffmpeg ;
SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders media ;
UsePrivateHeaders media shared ;
SubDirHdrs [ FDirName $(SUBDIR) libavcodec ] ;
SubDirHdrs [ FDirName $(SUBDIR) libavformat ] ;
@ -13,7 +13,7 @@ Addon ffmpeg :
AVCodecDecoder.cpp
AVFormatReader.cpp
CodecTable.cpp
DemuxerTable.cpp
FFmpegPlugin.cpp
gfx_conv_c.cpp