1 /* 2 * Copyright 2010 Stephan Aßmus <superstippi@gmx.de>. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "CodecTable.h" 8 9 extern "C" { 10 #include "avcodec.h" 11 #include "libavformat/internal.h" 12 #include "avformat.h" 13 } 14 15 //XXX: newer versions have it in libavformat/internal.h 16 typedef struct AVCodecTag { 17 enum CodecID id; 18 unsigned int tag; 19 } AVCodecTag; 20 21 22 struct AVInputFamily gAVInputFamilies[] = { 23 { B_AIFF_FORMAT_FAMILY, "aiff" }, 24 { B_AVI_FORMAT_FAMILY, "avi" }, 25 { B_MPEG_FORMAT_FAMILY, "mpeg" }, 26 { B_QUICKTIME_FORMAT_FAMILY, "mov" }, 27 { B_ANY_FORMAT_FAMILY, NULL} 28 }; 29 30 static const int32 sMaxFormatCount = 1024; 31 media_format gAVCodecFormats[sMaxFormatCount]; 32 33 34 status_t 35 register_avcodec_tags(media_format_family family, const char *avname, int &index) 36 { 37 AVInputFormat *inputFormat = av_find_input_format(avname); 38 if (inputFormat == NULL) 39 return B_MEDIA_NO_HANDLER; 40 41 BMediaFormats mediaFormats; 42 if (mediaFormats.InitCheck() != B_OK) 43 return B_ERROR; 44 45 for (int tagSet = 0; inputFormat->codec_tag[tagSet]; tagSet++) { 46 const AVCodecTag *tags = inputFormat->codec_tag[tagSet]; 47 if (tags == NULL) 48 continue; 49 50 for (; tags->id != CODEC_ID_NONE; tags++) { 51 // XXX: we might want to keep some strange PCM codecs too... 52 // skip unwanted codec tags 53 if (tags->tag == CODEC_ID_RAWVIDEO 54 || (tags->tag >= CODEC_ID_PCM_S16LE 55 && tags->tag < CODEC_ID_ADPCM_IMA_QT) 56 || tags->tag >= CODEC_ID_DVD_SUBTITLE) 57 continue; 58 59 if (index >= sMaxFormatCount) { 60 fprintf(stderr, "Maximum format count reached for auto-generated " 61 "AVCodec to media_format mapping, but there are still more " 62 "AVCodecs compiled into libavcodec!\n"); 63 break; 64 } 65 66 media_format format; 67 // Determine media type 68 if (tags->tag < CODEC_ID_PCM_S16LE) 69 format.type = B_MEDIA_ENCODED_VIDEO; 70 else 71 format.type = B_MEDIA_ENCODED_AUDIO; 72 73 media_format_description description; 74 memset(&description, 0, sizeof(description)); 75 76 // Hard-code everything to B_MISC_FORMAT_FAMILY to ease matching 77 // later on. 78 description.family = family; 79 switch (family) { 80 case B_AIFF_FORMAT_FAMILY: 81 description.u.aiff.codec = tags->tag; 82 break; 83 case B_AVI_FORMAT_FAMILY: 84 description.u.avi.codec = tags->tag; 85 break; 86 case B_MPEG_FORMAT_FAMILY: 87 description.u.mpeg.id = tags->tag; 88 break; 89 case B_QUICKTIME_FORMAT_FAMILY: 90 description.u.quicktime.codec = tags->tag; 91 break; 92 case B_WAV_FORMAT_FAMILY: 93 description.u.wav.codec = tags->tag; 94 break; 95 default: 96 break; 97 } 98 99 format.require_flags = 0; 100 format.deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 101 102 if (mediaFormats.MakeFormatFor(&description, 1, &format) != B_OK) 103 return B_ERROR; 104 105 gAVCodecFormats[index] = format; 106 107 index++; 108 } 109 } 110 return B_OK; 111 } 112 113 114 status_t 115 build_decoder_formats(media_format** _formats, size_t* _count) 116 { 117 BMediaFormats mediaFormats; 118 if (mediaFormats.InitCheck() != B_OK) 119 return B_ERROR; 120 121 int32 index = 0; 122 AVCodec* codec = NULL; 123 while ((codec = av_codec_next(codec)) != NULL) { 124 if (index >= sMaxFormatCount) { 125 fprintf(stderr, "Maximum format count reached for auto-generated " 126 "AVCodec to media_format mapping, but there are still more " 127 "AVCodecs compiled into libavcodec!\n"); 128 break; 129 } 130 media_format format; 131 // Determine media type 132 switch (codec->type) { 133 case AVMEDIA_TYPE_VIDEO: 134 format.type = B_MEDIA_ENCODED_VIDEO; 135 break; 136 case AVMEDIA_TYPE_AUDIO: 137 format.type = B_MEDIA_ENCODED_AUDIO; 138 break; 139 default: 140 // ignore this AVCodec 141 continue; 142 } 143 144 media_format_description description; 145 memset(&description, 0, sizeof(description)); 146 147 // Hard-code everything to B_MISC_FORMAT_FAMILY to ease matching 148 // later on. 149 description.family = B_MISC_FORMAT_FAMILY; 150 description.u.misc.file_format = 'ffmp'; 151 description.u.misc.codec = codec->id; 152 153 format.require_flags = 0; 154 format.deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 155 156 if (mediaFormats.MakeFormatFor(&description, 1, &format) != B_OK) 157 return B_ERROR; 158 159 gAVCodecFormats[index] = format; 160 161 index++; 162 } 163 164 *_formats = gAVCodecFormats; 165 *_count = index; 166 167 return B_OK; 168 } 169 170