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