Enabled any and all decoders and demuxers which are currently compiled into

FFmpeg. It's a bit sad, but this obsoletes pretty much all other decoder
and reader plugins. Some of them were built on external libraries as well
(AC3 (not part of default image anyway, since it's GPL), APE, MusePack),
so it's not really a big difference to using FFmpeg as external library.
The format matching is greatly simplified by using B_MISC_FORMAT_FAMILY
for everything but raw audio, and the actual FFmpeg CodecID as codec tag.
The downside of this is that the AVFormatReader can no longer be used with
other decoder plugins, but it would be easy to add special cases for native
decoders we wish to support. Obviously the out of the box support for file
formats and decoders has greatly increased with this change, so there has
to be a pretty good reason now for writing a "native" decoder or reader.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38786 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2010-09-22 11:10:51 +00:00
parent 190108e9c9
commit c1e73fbf52
8 changed files with 154 additions and 544 deletions

View File

@ -139,11 +139,7 @@ SYSTEM_ADD_ONS_MEDIA = cortex_audioadapter.media_addon
firewire_dv.media_addon
#legacy.media_addon
;
SYSTEM_ADD_ONS_MEDIA_PLUGINS = $(GPL_ONLY)ac3_decoder
aiff_reader asf_reader au_reader $(X86_ONLY)ffmpeg
mov_reader musepack raw_decoder $(X86_ONLY)ape_reader
wav_reader
;
SYSTEM_ADD_ONS_MEDIA_PLUGINS = $(X86_ONLY)ffmpeg raw_decoder ;
SYSTEM_ADD_ONS_PRINT = Canon\ LIPS3\ Compatible Canon\ LIPS4\ Compatible
PCL5\ Compatible PCL6\ Compatible PDF\ Writer PS\ Compatible Preview
;

View File

@ -73,7 +73,6 @@ AVCodecDecoder::AVCodecDecoder()
fOutputVideoFormat(),
fFrame(0),
fIsAudio(false),
fCodecIndexInTable(-1),
fCodec(NULL),
fContext(avcodec_alloc_context()),
fInputPicture(avcodec_alloc_frame()),
@ -141,11 +140,10 @@ AVCodecDecoder::~AVCodecDecoder()
void
AVCodecDecoder::GetCodecInfo(media_codec_info* mci)
{
sprintf(mci->short_name, "ff:%s", fCodec->name);
sprintf(mci->pretty_name, "%s (libavcodec %s)",
gCodecTable[fCodecIndexInTable].prettyname, fCodec->name);
snprintf(mci->short_name, 32, "%s", fCodec->name);
snprintf(mci->pretty_name, 96, "%s", fCodec->long_name);
mci->id = 0;
mci->sub_id = gCodecTable[fCodecIndexInTable].id;
mci->sub_id = fCodec->id;
}
@ -177,94 +175,62 @@ AVCodecDecoder::Setup(media_format* ioEncodedFormat, const void* infoBuffer,
ioEncodedFormat->MetaDataSize());
#endif
media_format_description descr;
for (int32 i = 0; gCodecTable[i].id; i++) {
fCodecIndexInTable = i;
uint64 cid;
media_format_description description;
if (BMediaFormats().GetCodeFor(*ioEncodedFormat,
B_MISC_FORMAT_FAMILY, &description) == B_OK) {
if (description.u.misc.file_format != 'ffmp')
return B_NOT_SUPPORTED;
fCodec = avcodec_find_decoder(static_cast<CodecID>(
description.u.misc.codec));
if (fCodec == NULL) {
TRACE(" unable to find the correct FFmpeg "
"decoder (id = %lu)\n", description.u.misc.codec);
return B_ERROR;
}
TRACE(" found decoder %s\n", fCodec->name);
if (BMediaFormats().GetCodeFor(*ioEncodedFormat,
gCodecTable[i].family, &descr) == B_OK
&& gCodecTable[i].type == ioEncodedFormat->type) {
switch(gCodecTable[i].family) {
case B_WAV_FORMAT_FAMILY:
cid = descr.u.wav.codec;
break;
case B_AIFF_FORMAT_FAMILY:
cid = descr.u.aiff.codec;
break;
case B_AVI_FORMAT_FAMILY:
cid = descr.u.avi.codec;
break;
case B_MPEG_FORMAT_FAMILY:
cid = descr.u.mpeg.id;
break;
case B_QUICKTIME_FORMAT_FAMILY:
cid = descr.u.quicktime.codec;
break;
case B_MISC_FORMAT_FAMILY:
cid = (((uint64)descr.u.misc.file_format) << 32)
| descr.u.misc.codec;
break;
default:
puts("ERR family");
return B_ERROR;
const void* extraData = infoBuffer;
fExtraDataSize = infoSize;
if (description.family == B_WAV_FORMAT_FAMILY
&& infoSize >= sizeof(wave_format_ex)) {
TRACE(" trying to use wave_format_ex\n");
// Special case extra data in B_WAV_FORMAT_FAMILY
const wave_format_ex* waveFormatData
= (const wave_format_ex*)infoBuffer;
size_t waveFormatSize = infoSize;
if (waveFormatData != NULL && waveFormatSize > 0) {
fBlockAlign = waveFormatData->block_align;
TRACE(" found block align: %d\n", fBlockAlign);
fExtraDataSize = waveFormatData->extra_size;
// skip the wave_format_ex from the extra data.
extraData = waveFormatData + 1;
}
if (gCodecTable[i].family == descr.family
&& gCodecTable[i].fourcc == cid) {
TRACE(" 0x%04lx codec id = \"%c%c%c%c\"\n", uint32(cid),
(char)((cid >> 24) & 0xff), (char)((cid >> 16) & 0xff),
(char)((cid >> 8) & 0xff), (char)(cid & 0xff));
fCodec = avcodec_find_decoder(gCodecTable[i].id);
if (fCodec == NULL) {
TRACE(" unable to find the correct FFmpeg "
"decoder (id = %d)\n", gCodecTable[i].id);
return B_ERROR;
}
TRACE(" found decoder %s\n", fCodec->name);
const void* extraData = infoBuffer;
fExtraDataSize = infoSize;
if (gCodecTable[i].family == B_WAV_FORMAT_FAMILY
&& infoSize >= sizeof(wave_format_ex)) {
TRACE(" trying to use wave_format_ex\n");
// Special case extra data in B_WAV_FORMAT_FAMILY
const wave_format_ex* waveFormatData
= (const wave_format_ex*)infoBuffer;
size_t waveFormatSize = infoSize;
if (waveFormatData != NULL && waveFormatSize > 0) {
fBlockAlign = waveFormatData->block_align;
TRACE(" found block align: %d\n", fBlockAlign);
fExtraDataSize = waveFormatData->extra_size;
// skip the wave_format_ex from the extra data.
extraData = waveFormatData + 1;
}
} else {
if (fIsAudio) {
fBlockAlign
= ioEncodedFormat->u.encoded_audio.output
.buffer_size;
TRACE(" using buffer_size as block align: %d\n",
fBlockAlign);
}
}
if (extraData != NULL && fExtraDataSize > 0) {
TRACE("AVCodecDecoder: extra data size %ld\n", infoSize);
fExtraData = new(std::nothrow) char[fExtraDataSize];
if (fExtraData != NULL)
memcpy(fExtraData, infoBuffer, fExtraDataSize);
else
fExtraDataSize = 0;
}
fInputFormat = *ioEncodedFormat;
return B_OK;
} else {
if (fIsAudio) {
fBlockAlign
= ioEncodedFormat->u.encoded_audio.output
.buffer_size;
TRACE(" using buffer_size as block align: %d\n",
fBlockAlign);
}
}
if (extraData != NULL && fExtraDataSize > 0) {
TRACE("AVCodecDecoder: extra data size %ld\n", infoSize);
delete[] fExtraData;
fExtraData = new(std::nothrow) char[fExtraDataSize];
if (fExtraData != NULL)
memcpy(fExtraData, infoBuffer, fExtraDataSize);
else
fExtraDataSize = 0;
}
fInputFormat = *ioEncodedFormat;
return B_OK;
} else {
TRACE("AVCodecDecoder: BMediaFormats().GetCodeFor() failed.\n");
}
printf("AVCodecDecoder::Setup failed!\n");
return B_ERROR;
}

View File

@ -15,6 +15,7 @@
#include <MediaFormats.h>
extern "C" {
#include "avcodec.h"
#include "swscale.h"
}
@ -22,6 +23,7 @@ extern "C" {
#include "ReaderPlugin.h"
#include "CodecTable.h"
#include "gfx_util.h"
class AVCodecDecoder : public Decoder {
@ -70,9 +72,6 @@ private:
int64 fFrame;
bool fIsAudio;
int fCodecIndexInTable;
// helps to find codecpretty
// FFmpeg related members
AVCodec* fCodec;
AVCodecContext* fContext;

View File

@ -264,15 +264,6 @@ AVFormatReader::StreamCookie::Open()
(inputFormat->flags & AVFMT_VARIABLE_FPS) ? " AVFMT_VARIABLE_FPS" : ""
);
const DemuxerFormat* demuxerFormat = demuxer_format_for(inputFormat);
if (demuxerFormat == NULL) {
// We could support this format, but we don't want to. Bail out.
ERROR("AVFormatReader::StreamCookie::Open() - "
"support for demuxer '%s' is not enabled. "
"See DemuxerTable.cpp\n", inputFormat->name);
return B_NOT_SUPPORTED;
}
// Init I/O context with buffer and hook functions, pass ourself as
// cookie.
if (init_put_byte(&fIOContext, probeBuffer, probeSize, 0, this,
@ -326,12 +317,6 @@ AVFormatReader::StreamCookie::Init(int32 virtualIndex)
TRACE(" context stream index: %ld\n", streamIndex);
const DemuxerFormat* demuxerFormat = demuxer_format_for(fContext->iformat);
if (demuxerFormat == NULL) {
TRACE(" unknown AVInputFormat!\n");
return B_NOT_SUPPORTED;
}
// We need to remember the virtual index so that
// AVFormatReader::FreeCookie() can clear the correct stream entry.
fVirtualIndex = virtualIndex;
@ -380,22 +365,26 @@ AVFormatReader::StreamCookie::Init(int32 virtualIndex)
// Set format family and type depending on codec_type of the stream.
switch (codecContext->codec_type) {
case CODEC_TYPE_AUDIO:
case AVMEDIA_TYPE_AUDIO:
if ((codecContext->codec_id >= CODEC_ID_PCM_S16LE)
&& (codecContext->codec_id <= CODEC_ID_PCM_U8)) {
TRACE(" raw audio\n");
format->type = B_MEDIA_RAW_AUDIO;
description.family = B_ANY_FORMAT_FAMILY;
// This will then apparently be handled by the (built into
// BMediaTrack) RawDecoder.
} else {
TRACE(" encoded audio\n");
format->type = B_MEDIA_ENCODED_AUDIO;
description.family = demuxerFormat->audio_family;
description.family = B_MISC_FORMAT_FAMILY;
description.u.misc.file_format = 'ffmp';
}
break;
case CODEC_TYPE_VIDEO:
case AVMEDIA_TYPE_VIDEO:
TRACE(" encoded video\n");
format->type = B_MEDIA_ENCODED_VIDEO;
description.family = demuxerFormat->video_family;
description.family = B_MISC_FORMAT_FAMILY;
description.u.misc.file_format = 'ffmp';
break;
default:
TRACE(" unknown type\n");
@ -404,6 +393,7 @@ AVFormatReader::StreamCookie::Init(int32 virtualIndex)
}
if (format->type == B_MEDIA_RAW_AUDIO) {
// We cannot describe all raw-audio formats, some are unsupported.
switch (codecContext->codec_id) {
case CODEC_ID_PCM_S16LE:
format->u.raw_audio.format
@ -444,126 +434,8 @@ AVFormatReader::StreamCookie::Init(int32 virtualIndex)
break;
}
} else {
uint32 codecTag = codecContext->codec_tag;
if (codecTag == 0) {
// Ugh, no codec_tag. Let's try to fake some known codecs.
// Such a situation seems to occur for the "mpegts" demuxer for
// example. These are some tags I could test with.
switch (codecContext->codec_id) {
case CODEC_ID_H264:
codecTag = 'h264';
break;
case CODEC_ID_DVVIDEO:
codecTag = 'pcvd';
break;
case CODEC_ID_AC3:
description.family = B_WAV_FORMAT_FAMILY;
codecTag = 0x2000;
break;
case CODEC_ID_FLAC:
description.family = B_WAV_FORMAT_FAMILY;
codecTag = 'flac';
break;
case CODEC_ID_VP6F:
description.family = B_QUICKTIME_FORMAT_FAMILY;
codecTag = B_BENDIAN_TO_HOST_INT32('VP6F');
break;
case CODEC_ID_MP3:
description.family = B_QUICKTIME_FORMAT_FAMILY;
codecTag = B_BENDIAN_TO_HOST_INT32('.mp3');
break;
case CODEC_ID_AAC:
description.family = B_MISC_FORMAT_FAMILY;
codecTag = 'mp4a';
break;
case CODEC_ID_DTS:
description.family = B_WAV_FORMAT_FAMILY;
codecTag = ' DTS';
break;
case CODEC_ID_THEORA:
// Use the same format description as the native Ogg
// reader and decoder did.
description.family = B_MISC_FORMAT_FAMILY;
// TODO: The rest of this plugin (Decoders/Encoders) does not support
// this yet, specifying it would throw off the format matching.
// description.u.misc.file_format = 'OggS';
codecTag = 'theo';
break;
case CODEC_ID_SPEEX:
// Use the same format description as the native Ogg
// reader and decoder did.
description.family = B_MISC_FORMAT_FAMILY;
// TODO: See above.
// description.u.misc.file_format = 'OggS';
codecTag = 'spex';
break;
case CODEC_ID_VORBIS:
// Use the same format description as the native Ogg
// reader and decoder did.
description.family = B_MISC_FORMAT_FAMILY;
// TODO: See above.
// description.u.misc.file_format = 'OggS';
codecTag = 'vorb';
break;
default:
fprintf(stderr, "ffmpeg codecTag is null, codec_id "
"unknown 0x%x\n", codecContext->codec_id);
// TODO: Add more...
break;
}
}
switch (description.family) {
case B_AIFF_FORMAT_FAMILY:
TRACE(" B_AIFF_FORMAT_FAMILY\n");
description.u.aiff.codec = codecTag;
break;
case B_ASF_FORMAT_FAMILY:
TRACE(" B_ASF_FORMAT_FAMILY\n");
// description.u.asf.guid = GUID(codecTag);
return B_NOT_SUPPORTED;
break;
case B_AVI_FORMAT_FAMILY:
TRACE(" B_AVI_FORMAT_FAMILY\n");
description.u.avi.codec = codecTag;
break;
case B_AVR_FORMAT_FAMILY:
TRACE(" B_AVR_FORMAT_FAMILY\n");
description.u.avr.id = codecTag;
break;
case B_MPEG_FORMAT_FAMILY:
TRACE(" B_MPEG_FORMAT_FAMILY\n");
if (codecContext->codec_id == CODEC_ID_MPEG1VIDEO)
description.u.mpeg.id = B_MPEG_1_VIDEO;
else if (codecContext->codec_id == CODEC_ID_MPEG2VIDEO)
description.u.mpeg.id = B_MPEG_2_VIDEO;
else if (codecContext->codec_id == CODEC_ID_MP2)
description.u.mpeg.id = B_MPEG_2_AUDIO_LAYER_2;
else if (codecContext->codec_id == CODEC_ID_MP3)
description.u.mpeg.id = B_MPEG_2_AUDIO_LAYER_3;
// TODO: Add some more...
else
description.u.mpeg.id = B_MPEG_ANY;
break;
case B_QUICKTIME_FORMAT_FAMILY:
TRACE(" B_QUICKTIME_FORMAT_FAMILY\n");
description.u.quicktime.codec
= B_HOST_TO_BENDIAN_INT32(codecTag);
break;
case B_WAV_FORMAT_FAMILY:
TRACE(" B_WAV_FORMAT_FAMILY\n");
description.u.wav.codec = codecTag;
break;
case B_MISC_FORMAT_FAMILY:
TRACE(" B_MISC_FORMAT_FAMILY\n");
description.u.misc.codec = codecTag;
break;
default:
break;
}
TRACE(" codecTag '%.4s' or %ld\n", (char*)&codecTag, codecTag);
TRACE(" fourcc '%.4s' or %d\n", (char*)&codecContext->codec_id,
codecContext->codec_id);
if (description.family == B_MISC_FORMAT_FAMILY)
description.u.misc.codec = codecContext->codec_id;
BMediaFormats formats;
status_t status = formats.GetFormatFor(description, format);
@ -571,11 +443,11 @@ AVFormatReader::StreamCookie::Init(int32 virtualIndex)
TRACE(" formats.GetFormatFor() error: %s\n", strerror(status));
format->user_data_type = B_CODEC_TYPE_INFO;
*(uint32*)format->user_data = codecTag;
*(uint32*)format->user_data = codecContext->codec_tag;
format->user_data[4] = 0;
}
// format->require_flags = 0;
format->require_flags = 0;
format->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
switch (format->type) {

View File

@ -1,234 +1,73 @@
/*
* Copyright (C) 2001 Carlos Hasan. All Rights Reserved.
* Copyright (C) 2001 François Revol. All Rights Reserved.
* Copyright (C) 2001 Axel Dörfler. All Rights Reserved.
*
* Copyright 2010 Stephan Aßmus <superstippi@gmx.de>. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include "CodecTable.h"
#define HAS_WMA_AUDIO
//#define HAS_MACE_AUDIO
#define HAS_PHOTO_JPEG
#define HAS_MOTION_JPEG
#define FOURCC(a) B_HOST_TO_BENDIAN_INT32(a)
const struct codec_table gCodecTable[] = {
{CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x06, "aLaw"},
{CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_AIFF_FORMAT_FAMILY, 'alaw' , "aLaw"},
{CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_AIFF_FORMAT_FAMILY, 'ALAW' , "aLaw"},
{CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, (uint64('au') << 32) | 27, "aLaw"},
{CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'ulaw', "µLaw"},
{CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'alaw', "aLaw"},
{CODEC_ID_PCM_ALAW, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'ALAW', "aLaw"},
{CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x07, "µLaw"},
{CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_AIFF_FORMAT_FAMILY, 'ulaw', "µLaw"},
{CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_AIFF_FORMAT_FAMILY, 'ULAW', "µLaw"},
{CODEC_ID_PCM_MULAW, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, (uint64('au') << 32) | 1, "µLaw"},
{CODEC_ID_ADPCM_IMA_WAV, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0011, "IMA ADPCM"},
{CODEC_ID_ADPCM_MS, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0002, "MS ADPCM"},
{CODEC_ID_ADPCM_IMA_WAV, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730011, "IMA ADPCM"},
{CODEC_ID_ADPCM_MS, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730002, "MS ADPCM"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730050, "MP Layer2"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 0x6D730055, "MP Layer3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, '.mp3', "MPEG Audio Layer 3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, '3pm.', "MPEG Audio Layer 3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_AVI_FORMAT_FAMILY, '.mp3', "MPEG Audio Layer 3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_AVI_FORMAT_FAMILY, '3pm.', "MPEG Audio Layer 3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, 0x6D730050, "MP Layer2"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, 0x6D730055, "MP Layer3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_1_AUDIO_LAYER_2, "MP Layer2"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_1_AUDIO_LAYER_3, "MP Layer3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_AUDIO_LAYER_2, "MP Layer2"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_AUDIO_LAYER_3, "MP Layer3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_5_AUDIO_LAYER_2, "MP Layer2"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_5_AUDIO_LAYER_3, "MP Layer3"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0050, "MPEG Audio Layer 2"},
{CODEC_ID_MP2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x0055, "MPEG Audio Layer 3"},
{CODEC_ID_ADPCM_IMA_QT, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'ima4', "Quicktime IMA4"},
{CODEC_ID_ADPCM_IMA_QT, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'IMA4', "Quicktime IMA4"},
{CODEC_ID_AAC, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'mp4a', "MPEG4 AAC"},
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'mp4v', "MPEG4 Video"},
{CODEC_ID_AAC, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'a4pm', "MPEG4 AAC"},
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'v4pm', "MPEG4 Video"},
{CODEC_ID_AAC, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, 'mp4a', "MPEG4 AAC"}, /* For matroska */
{CODEC_ID_AAC, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, 'a4pm', "MPEG4 AAC"}, /* For matroska */
// The native AC3 decoder works much more reliable, so don't claim support.
// {CODEC_ID_AC3, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x2000, "AC-3"},
// {CODEC_ID_AC3, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, '3-CA', "AC-3"},
{CODEC_ID_DTS, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 'STD ', "DTS"},
{CODEC_ID_DTS, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, ' DTS', "DTS"},
#ifdef HAS_MACE_AUDIO
{CODEC_ID_MACE3, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'MAC3', "MACE 3:1"},
{CODEC_ID_MACE6, B_MEDIA_ENCODED_AUDIO, B_QUICKTIME_FORMAT_FAMILY, 'MAC6', "MACE 6:1"},
#endif
{CODEC_ID_WMAV1, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x160, "MS WMA v1"},
{CODEC_ID_WMAV2, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 0x161, "MS WMA v2"},
{CODEC_ID_FLAC, B_MEDIA_ENCODED_AUDIO, B_WAV_FORMAT_FAMILY, 'flac', "FLAC"},
{CODEC_ID_CINEPAK, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('cvid'), "Cinepak Video"},
{CODEC_ID_CINEPAK, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'cvid', "Cinepak Video"},
{CODEC_ID_MSRLE, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, FOURCC(' elr'), "MS RLE"}, // ???
{CODEC_ID_MSRLE, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('RLE '), "MS RLE"}, // ???
{CODEC_ID_MSRLE, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('mrle'), "MS RLE"}, // ???
{CODEC_ID_MSVIDEO1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('MSVC'), "MS Video 1 (MSVC)"},
{CODEC_ID_MSVIDEO1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('msvc'), "MS Video 1 (msvc)"},
{CODEC_ID_MSVIDEO1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('CRAM'), "MS Video 1 (CRAM)"},
{CODEC_ID_MSVIDEO1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('cram'), "MS Video 1 (cram)"},
{CODEC_ID_MSVIDEO1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('WHAM'), "MS Video 1 (WHAM)"},
{CODEC_ID_MSVIDEO1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('wham'), "MS Video 1 (wham)"},
{CODEC_ID_MSVIDEO1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 0x01, "MS Video 1 (1)"},
{CODEC_ID_MSVIDEO1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC(0x01), "MS Video 1 (not 1)"},
{CODEC_ID_H263, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('U263'), "U263"},
{CODEC_ID_H263, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('H263'), "U263"},
// {CODEC_ID_H263P, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('U263'), "U263"},
{CODEC_ID_H263I, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('I263'), "Intel H263"}, /* intel h263 */
{CODEC_ID_H263, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'h263', "H263"},
{CODEC_ID_H263, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'H263', "H263"},
{CODEC_ID_H264, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('h264'), "H264"},
{CODEC_ID_H264, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('H264'), "H264"},
{CODEC_ID_H264, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('x264'), "H264"},
{CODEC_ID_H264, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, FOURCC('h264'), "H264"},
{CODEC_ID_H264, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'avc1', "AVC"}, /* MPEG-4 AVC */
{CODEC_ID_H264, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 'VMDH', "AVC"}, /* MPEG-4 AVC */
#ifdef HAS_PHOTO_JPEG
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'JPEG', "Photo-JPEG"},
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'jpeg', "Photo-JPEG"}, /* used in BeOS_BBC.mov */
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'GEPJ', "Photo-JPEG"},
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'gepj', "Photo-JPEG"}, /* used in BeOS_BBC.mov */
#endif
#ifdef HAS_MOTION_JPEG
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('MJPG'), "Motion JPEG"},
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('mjpg'), "Motion JPEG"},
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'AVDJ', "Motion JPEG"},
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'mjpa', "Motion JPEG"},
{CODEC_ID_MJPEGB, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'mjpb', "Motion JPEG"},
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'JDVA', "Motion JPEG"},
{CODEC_ID_MJPEG, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'apjm', "Motion JPEG"},
{CODEC_ID_MJPEGB, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'bpjm', "Motion JPEG"},
#endif
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'FMP4', "ffmpeg MPEG4"},
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, '4PMF', "ffmpeg MPEG4"},
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'DIVX', "MPEG4"}, /* OpenDivX */ /* XXX: doesn't seem to work */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'divx', "MPEG4"}, /* OpenDivX */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'mp4v', "MPEG4"}, /* MPEG-4 ASP */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'XVID', "XviD (MPEG4)"}, /* OpenDivX ??? XXX: test */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 'FMP4', "ffmpeg MPEG4"},
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, '4PMF', "ffmpeg MPEG4"},
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('DIVX'), "MPEG4"}, /* OpenDivX */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('divx'), "MPEG4"}, /* OpenDivX */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('XVID'), "XviD (MPEG4)"}, /* XVID */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('XviD'), "XviD (MPEG4)"}, /* XVID */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('xvid'), "XviD (MPEG4)"}, /* XVID */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('DX50'), "DivX 5 (MPEG4)"}, /* DivX 5.0 */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('dx50'), "DivX 5 (MPEG4)"}, /* DivX 5.0 */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('3IV2'), "3ivx v2"}, /* 3ivx v2 */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('3iv2'), "3ivx v2"}, /* 3ivx v2 */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('ffds'), "ff DirectShow"}, /* XVID Variant */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('\004\0\0\0'), "MPEG4"}, /* some broken avi use this */
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('DIV3'), "DivX ;-) (MS MPEG4 v3)"}, /* default signature when using MSMPEG4 */
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('div3'), "DivX ;-) (MS MPEG4 v3)"},
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('DIV4'), "DivX ;-) (MS MPEG4 v3)"},
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('div4'), "DivX ;-) (MS MPEG4 v3)"},
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('DIV5'), "DivX ;-) (MS MPEG4 v3)"},
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('div5'), "DivX ;-) (MS MPEG4 v3)"},
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('DIV6'), "DivX ;-) (MS MPEG4 v3)"},
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('div6'), "DivX ;-) (MS MPEG4 v3)"},
{CODEC_ID_MSMPEG4V1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('MP41'), "MS MPEG4 v1"}, /* microsoft mpeg4 v1 */
{CODEC_ID_MSMPEG4V1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('mp41'), "MS MPEG4 v1"}, /* microsoft mpeg4 v1 */
{CODEC_ID_MSMPEG4V2, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('MP42'), "MS MPEG4 v2"}, /* seems to be broken */
{CODEC_ID_MSMPEG4V2, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('mp42'), "MS MPEG4 v2"}, /* seems to be broken */
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('MP43'), "MS MPEG4 v3"}, /* microsoft mpeg4 v3 */
{CODEC_ID_MPEG4, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('S4PM'), "MPEG4"}, /* mpeg4 */
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('34PM'), "MS MPEG4 v3"}, /* microsoft mpeg4 v3 */
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('mp43'), "MS MPEG4 v3"}, /* microsoft mpeg4 v3 */
{CODEC_ID_MSMPEG4V1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('MPG4'), "MS MPEG4"},
{CODEC_ID_MSMPEG4V3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('AP41'), "Angel Potion (MS MPEG4 v3)"}, /* AngelPotion 1 (it's so simple to release a new codec... :^) ) */
{CODEC_ID_WMV1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('WMV1'), "Microsoft WMV v1"},
{CODEC_ID_WMV2, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('WMV2'), "Microsoft WMV v2"},
{CODEC_ID_WMV3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('WMV3'), "Microsoft WMV v3"},
//SVQ1
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 'SVQ1', "Sorenson Video v1"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 'svq1', "Sorenson Video v1"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'SVQ1', "Sorenson Video v1"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'svq1', "Sorenson Video v1"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'svqi', "Sorenson Video v1"}, /* (from QT specs) */
{CODEC_ID_SVQ3, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'SVQ3', "Sorenson Video v3"},
{CODEC_ID_SVQ3, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'svq3', "Sorenson Video v3"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, '1QVS', "Sorenson Video v1"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, '1qvs', "Sorenson Video v1"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, '1QVS', "Sorenson Video v1"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, '1qvs', "Sorenson Video v1"},
{CODEC_ID_SVQ1, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'iqvs', "Sorenson Video v1"}, /* (from QT specs) */
{CODEC_ID_SVQ3, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, '3QVS', "Sorenson Video v3"},
{CODEC_ID_SVQ3, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, '3qvs', "Sorenson Video v3"},
/*
{CODEC_ID_RV10, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 'RV10', "RealVideo v1"},
{CODEC_ID_RV10, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 'rv10', "RealVideo v1"},
{CODEC_ID_RV10, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'RV10', "RealVideo v1"},
{CODEC_ID_RV10, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'rv10', "RealVideo v1"},
*/
{CODEC_ID_DVVIDEO, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('dvsd'), "DV Video"},
{CODEC_ID_DVVIDEO, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('DVSD'), "DV Video"},
{CODEC_ID_DVVIDEO, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('dvhd'), "DV Video"},
{CODEC_ID_DVVIDEO, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('dvsl'), "DV Video"},
{CODEC_ID_DVVIDEO, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('dv25'), "DV Video"},
{CODEC_ID_DVVIDEO, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'dvc ', "DV Video"},
{CODEC_ID_DVVIDEO, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'dvcp', "DV Video"},
{CODEC_ID_MPEG1VIDEO, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'MPG1', "MPEG1 Video"},
{CODEC_ID_MPEG1VIDEO, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'MPG2', "MPEG1 Video"},
{CODEC_ID_MPEG1VIDEO, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'PIM1', "MPEG1 Video"},
{CODEC_ID_MPEG1VIDEO, B_MEDIA_ENCODED_VIDEO, B_MPEG_FORMAT_FAMILY, B_MPEG_1_VIDEO, "MPEG1 Video"},
{CODEC_ID_MPEG2VIDEO, B_MEDIA_ENCODED_VIDEO, B_MPEG_FORMAT_FAMILY, B_MPEG_2_VIDEO, "MPEG2 Video"},
{CODEC_ID_INDEO3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('iv31'), "Indeo 3"},
{CODEC_ID_INDEO3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('iv32'), "Indeo 3"},
{CODEC_ID_INDEO3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('IV31'), "Indeo 3"},
{CODEC_ID_INDEO3, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, FOURCC('IV32'), "Indeo 3"},
{CODEC_ID_THEORA, B_MEDIA_ENCODED_VIDEO, B_MISC_FORMAT_FAMILY, 'theo', "Theora"},
{CODEC_ID_VORBIS, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, 'vorb', "Vorbis"},
{CODEC_ID_SPEEX, B_MEDIA_ENCODED_AUDIO, B_MISC_FORMAT_FAMILY, 'spex', "Speex"},
{CODEC_ID_VP3, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'VP31', "On2 VP3"},
{CODEC_ID_VP6F, B_MEDIA_ENCODED_VIDEO, B_QUICKTIME_FORMAT_FAMILY, 'VP6F', "On2 VP6"},
{CODEC_ID_CYUV, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 'cyuv', "CYUV"},
{CODEC_ID_CYUV, B_MEDIA_ENCODED_VIDEO, B_AVI_FORMAT_FAMILY, 'CYUV', "CYUV"},
{CODEC_ID_NONE, B_MEDIA_UNKNOWN_TYPE, B_ANY_FORMAT_FAMILY, 0, "null codec !!!"}
};
const int gCodecCount = (sizeof(gCodecTable) / sizeof(codec_table) - 1);
extern "C" {
#include "avcodec.h"
}
media_format gAVCodecFormats[sizeof(gCodecTable)];
static const int32 sMaxFormatCount = 1024;
media_format gAVCodecFormats[sMaxFormatCount];
status_t
build_decoder_formats(media_format** _formats, size_t* _count)
{
BMediaFormats mediaFormats;
if (mediaFormats.InitCheck() != B_OK)
return B_ERROR;
int32 index = 0;
AVCodec* codec = NULL;
while ((codec = av_codec_next(codec)) != NULL) {
if (index >= sMaxFormatCount) {
fprintf(stderr, "Maximum format count reached for auto-generated "
"AVCodec to media_format mapping, but there are still more "
"AVCodecs compiled into libavcodec!\n");
break;
}
media_format format;
// Determine media type
switch (codec->type) {
case AVMEDIA_TYPE_VIDEO:
format.type = B_MEDIA_ENCODED_VIDEO;
break;
case AVMEDIA_TYPE_AUDIO:
format.type = B_MEDIA_ENCODED_AUDIO;
break;
default:
// ignore this AVCodec
continue;
}
media_format_description description;
memset(&description, 0, sizeof(description));
// Hard-code everything to B_MISC_FORMAT_FAMILY to ease matching
// later on.
description.family = B_MISC_FORMAT_FAMILY;
description.u.misc.file_format = 'ffmp';
description.u.misc.codec = codec->id;
format.require_flags = 0;
format.deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
if (mediaFormats.MakeFormatFor(&description, 1, &format) != B_OK)
return B_ERROR;
gAVCodecFormats[index] = format;
index++;
}
*_formats = gAVCodecFormats;
*_count = index;
return B_OK;
}

View File

@ -1,34 +1,14 @@
/*
* Copyright (C) 2001 Carlos Hasan. All Rights Reserved.
* Copyright (C) 2001 François Revol. All Rights Reserved.
* Copyright (C) 2001 Axel Dörfler. All Rights Reserved.
* Copyright (C) 2004 Marcus Overhagen. All Rights Reserved.
*
* Copyright 2010 Stephan Aßmus <superstippi@gmx.de>. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
//! libavcodec based decoder for Haiku
#ifndef CODEC_TABLE_H
#define CODEC_TABLE_H
#include <MediaDefs.h>
#include <MediaFormats.h>
#include "gfx_util.h"
struct codec_table {
CodecID id;
media_type type;
media_format_family family;
uint64 fourcc;
const char* prettyname;
};
extern const struct codec_table gCodecTable[];
extern const int gCodecCount;
extern media_format gAVCodecFormats[];
status_t build_decoder_formats(media_format** _formats, size_t* _count);
#endif // CODEC_TABLE_H

View File

@ -1,5 +1,5 @@
/*
* Copyright 2009 Stephan Aßmus <superstippi@gmx.de>
* Copyright 2009-2010 Stephan Aßmus <superstippi@gmx.de>
* All rights reserved. Distributed under the terms of the MIT license.
*/
@ -10,19 +10,18 @@ extern "C" {
}
// 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.
// NOTE: AVFormatReader uses this table only for better pretty names and
// the MIME type info, the latter which is unavailable from AVInputFormat.
static const DemuxerFormat gDemuxerTable[] = {
// {
// // Tested with a limited number of streams. Some videos show bad
// // artifacts on keyframes with our own ASF Reader, while they play
// // fine with this Reader. But seeking seems to be a problem.
// "asf", "ASF Movie", "video/x-asf",
// B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
// },
{
// Tested with a limited number of streams. Some videos show bad
// artifacts on keyframes with our own ASF Reader, while they play
// fine with this Reader. But seeking seems to be a problem.
"asf", "ASF Movie", "video/x-asf",
B_WAV_FORMAT_FAMILY, B_AVI_FORMAT_FAMILY
},
{
// Tested with many streams and works very well, with many older
// files, the native AVI reader does not work.
@ -51,11 +50,11 @@ static const DemuxerFormat gDemuxerTable[] = {
"matroska", "Matroska movie", "video/x-matroska",
B_MISC_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
},
// {
// // Plays the limited amount of files I could test with.
// "mov", "Quicktime Movie", "video/x-mov",
// B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
// },
{
// Plays the limited amount of files I could test with.
"mov", "Quicktime Movie", "video/x-mov",
B_QUICKTIME_FORMAT_FAMILY, B_QUICKTIME_FORMAT_FAMILY
},
{
// Plays all files I could test with perfectly.
"mp4", "MPEG-4 movie", "video/x-mp4",

View File

@ -19,6 +19,7 @@
#include <Locker.h>
extern "C" {
#include "avcodec.h"
#include "avformat.h"
}
@ -121,49 +122,7 @@ FFmpegPlugin::NewReader()
status_t
FFmpegPlugin::GetSupportedFormats(media_format** _formats, size_t* _count)
{
BMediaFormats mediaFormats;
if (mediaFormats.InitCheck() != B_OK)
return B_ERROR;
for (int i = 0; i < gCodecCount; i++) {
media_format_description description;
description.family = gCodecTable[i].family;
switch(description.family) {
case B_WAV_FORMAT_FAMILY:
description.u.wav.codec = gCodecTable[i].fourcc;
break;
case B_AIFF_FORMAT_FAMILY:
description.u.aiff.codec = gCodecTable[i].fourcc;
break;
case B_AVI_FORMAT_FAMILY:
description.u.avi.codec = gCodecTable[i].fourcc;
break;
case B_MPEG_FORMAT_FAMILY:
description.u.mpeg.id = gCodecTable[i].fourcc;
break;
case B_QUICKTIME_FORMAT_FAMILY:
description.u.quicktime.codec = gCodecTable[i].fourcc;
break;
case B_MISC_FORMAT_FAMILY:
description.u.misc.file_format =
(uint32)(gCodecTable[i].fourcc >> 32);
description.u.misc.codec = (uint32) gCodecTable[i].fourcc;
break;
default:
break;
}
media_format format;
format.type = gCodecTable[i].type;
format.require_flags = 0;
format.deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
if (mediaFormats.MakeFormatFor(&description, 1, &format) != B_OK)
return B_ERROR;
gAVCodecFormats[i] = format;
}
*_formats = gAVCodecFormats;
*_count = gCodecCount;
return B_OK;
return build_decoder_formats(_formats, _count);
}