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