From 1828f3d72cde2d24454a699d48533f06b013dd2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 19 Dec 2010 04:26:46 +0000 Subject: [PATCH] Add a function to register media codec descriptions for the usual format families using the tag lists from libavformat itself. Untested. the plugin will also have to use av_codec_get_id() to get the codec ID from the tag. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39888 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/plugins/ffmpeg/CodecTable.cpp | 96 +++++++++++++++++++ src/add-ons/media/plugins/ffmpeg/CodecTable.h | 6 ++ 2 files changed, 102 insertions(+) diff --git a/src/add-ons/media/plugins/ffmpeg/CodecTable.cpp b/src/add-ons/media/plugins/ffmpeg/CodecTable.cpp index 6721927818..8424e81f88 100644 --- a/src/add-ons/media/plugins/ffmpeg/CodecTable.cpp +++ b/src/add-ons/media/plugins/ffmpeg/CodecTable.cpp @@ -8,13 +8,109 @@ extern "C" { #include "avcodec.h" + #include "libavformat/internal.h" + #include "avformat.h" } +//XXX: newer versions have it in libavformat/internal.h +typedef struct AVCodecTag { + enum CodecID id; + unsigned int tag; +} AVCodecTag; + + +struct AVInputFamily gAVInputFamilies[] = { + { B_AIFF_FORMAT_FAMILY, "aiff" }, + { B_AVI_FORMAT_FAMILY, "avi" }, + { B_MPEG_FORMAT_FAMILY, "mpeg" }, + { B_QUICKTIME_FORMAT_FAMILY, "mov" }, + { B_ANY_FORMAT_FAMILY, NULL} +}; static const int32 sMaxFormatCount = 1024; media_format gAVCodecFormats[sMaxFormatCount]; +status_t +register_avcodec_tags(media_format_family family, const char *avname, int &index) +{ + AVInputFormat *inputFormat = av_find_input_format(avname); + if (inputFormat == NULL) + return B_MEDIA_NO_HANDLER; + + BMediaFormats mediaFormats; + if (mediaFormats.InitCheck() != B_OK) + return B_ERROR; + + for (int tagSet = 0; inputFormat->codec_tag[tagSet]; tagSet++) { + const AVCodecTag *tags = inputFormat->codec_tag[tagSet]; + if (tags == NULL) + continue; + + for (; tags->id != CODEC_ID_NONE; tags++) { + // XXX: we might want to keep some strange PCM codecs too... + // skip unwanted codec tags + if (tags->tag == CODEC_ID_RAWVIDEO + || (tags->tag >= CODEC_ID_PCM_S16LE + && tags->tag < CODEC_ID_ADPCM_IMA_QT) + || tags->tag >= CODEC_ID_DVD_SUBTITLE) + continue; + + 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 + if (tags->tag < CODEC_ID_PCM_S16LE) + format.type = B_MEDIA_ENCODED_VIDEO; + else + format.type = B_MEDIA_ENCODED_AUDIO; + + media_format_description description; + memset(&description, 0, sizeof(description)); + + // Hard-code everything to B_MISC_FORMAT_FAMILY to ease matching + // later on. + description.family = family; + switch (family) { + case B_AIFF_FORMAT_FAMILY: + description.u.aiff.codec = tags->tag; + break; + case B_AVI_FORMAT_FAMILY: + description.u.avi.codec = tags->tag; + break; + case B_MPEG_FORMAT_FAMILY: + description.u.mpeg.id = tags->tag; + break; + case B_QUICKTIME_FORMAT_FAMILY: + description.u.quicktime.codec = tags->tag; + break; + case B_WAV_FORMAT_FAMILY: + description.u.wav.codec = tags->tag; + break; + default: + break; + } + + 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++; + } + } + return B_OK; +} + + status_t build_decoder_formats(media_format** _formats, size_t* _count) { diff --git a/src/add-ons/media/plugins/ffmpeg/CodecTable.h b/src/add-ons/media/plugins/ffmpeg/CodecTable.h index 2bd2d031b9..a11b760e9f 100644 --- a/src/add-ons/media/plugins/ffmpeg/CodecTable.h +++ b/src/add-ons/media/plugins/ffmpeg/CodecTable.h @@ -8,6 +8,12 @@ #include +struct AVInputFamily { + media_format_family family; + const char *avname; +}; +extern struct AVInputFamily gAVInputFamilies[]; + status_t build_decoder_formats(media_format** _formats, size_t* _count);