xref: /haiku/src/add-ons/media/plugins/ffmpeg/FFmpegPlugin.cpp (revision 893988af824e65e49e55f517b157db8386e8002b)
1 /*
2  * Copyright (C) 2001 Carlos Hasan
3  * Copyright (C) 2001 François Revol
4  * Copyright (C) 2001 Axel Dörfler
5  * Copyright (C) 2004 Marcus Overhagen
6  * Copyright (C) 2009 Stephan Aßmus <superstippi@gmx.de>
7  *
8  * All rights reserved. Distributed under the terms of the MIT License.
9  */
10 
11 //! libavcodec/libavformat based Decoder and Reader plugin for Haiku
12 
13 #include "FFmpegPlugin.h"
14 
15 #include <stdio.h>
16 
17 #include <new>
18 
19 extern "C" {
20 	#include "avformat.h"
21 }
22 
23 #include "AVCodecDecoder.h"
24 #include "AVCodecEncoder.h"
25 #include "AVFormatReader.h"
26 #include "AVFormatWriter.h"
27 #include "CodecTable.h"
28 #include "EncoderTable.h"
29 #include "MuxerTable.h"
30 
31 
32 FFmpegPlugin::GlobalInitilizer::GlobalInitilizer()
33 {
34 	av_register_all();
35 		// This will also call av_codec_init() by registering codecs.
36 }
37 
38 
39 FFmpegPlugin::GlobalInitilizer::~GlobalInitilizer()
40 {
41 	// TODO: uninit anything here?
42 }
43 
44 
45 FFmpegPlugin::GlobalInitilizer FFmpegPlugin::sInitilizer;
46 
47 
48 // #pragma mark -
49 
50 
51 Decoder*
52 FFmpegPlugin::NewDecoder(uint index)
53 {
54 // TODO: Confirm we can check index here.
55 //	if (index == 0)
56 		return new(std::nothrow) AVCodecDecoder();
57 //	return NULL;
58 }
59 
60 
61 Reader*
62 FFmpegPlugin::NewReader()
63 {
64 	return new(std::nothrow) AVFormatReader();
65 }
66 
67 
68 status_t
69 FFmpegPlugin::GetSupportedFormats(media_format** _formats, size_t* _count)
70 {
71 	BMediaFormats mediaFormats;
72 	if (mediaFormats.InitCheck() != B_OK)
73 		return B_ERROR;
74 
75 	for (int i = 0; i < gCodecCount; i++) {
76 		media_format_description description;
77 		description.family = gCodecTable[i].family;
78 		switch(description.family) {
79 			case B_WAV_FORMAT_FAMILY:
80 				description.u.wav.codec = gCodecTable[i].fourcc;
81 				break;
82 			case B_AIFF_FORMAT_FAMILY:
83 				description.u.aiff.codec = gCodecTable[i].fourcc;
84 				break;
85 			case B_AVI_FORMAT_FAMILY:
86 				description.u.avi.codec = gCodecTable[i].fourcc;
87 				break;
88 			case B_MPEG_FORMAT_FAMILY:
89 				description.u.mpeg.id = gCodecTable[i].fourcc;
90 				break;
91 			case B_QUICKTIME_FORMAT_FAMILY:
92 				description.u.quicktime.codec = gCodecTable[i].fourcc;
93 				break;
94 			case B_MISC_FORMAT_FAMILY:
95 				description.u.misc.file_format =
96 					(uint32)(gCodecTable[i].fourcc >> 32);
97 				description.u.misc.codec = (uint32) gCodecTable[i].fourcc;
98 				break;
99 			default:
100 				break;
101 		}
102 		media_format format;
103 		format.type = gCodecTable[i].type;
104 		format.require_flags = 0;
105 		format.deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
106 		if (mediaFormats.MakeFormatFor(&description, 1, &format) != B_OK)
107 			return B_ERROR;
108 		gAVCodecFormats[i] = format;
109 	}
110 
111 	*_formats = gAVCodecFormats;
112 	*_count = gCodecCount;
113 	return B_OK;
114 }
115 
116 
117 Writer*
118 FFmpegPlugin::NewWriter()
119 {
120 	return new(std::nothrow) AVFormatWriter();
121 }
122 
123 
124 status_t
125 FFmpegPlugin::GetSupportedFileFormats(const media_file_format** _fileFormats,
126 	size_t* _count)
127 {
128 	*_fileFormats = gMuxerTable;
129 	*_count = gMuxerCount;
130 	return B_OK;
131 }
132 
133 
134 Encoder*
135 FFmpegPlugin::NewEncoder(const media_codec_info& codecInfo)
136 {
137 	for (size_t i = 0; i < gEncoderCount; i++) {
138 		if (codecInfo.sub_id == gEncoderTable[i].codec_info.sub_id) {
139 			return new(std::nothrow)AVCodecEncoder(codecInfo.sub_id,
140 				gEncoderTable[i].bit_rate_scale);
141 		}
142 	}
143 	return NULL;
144 }
145 
146 
147 status_t
148 FFmpegPlugin::RegisterNextEncoder(int32* cookie, media_codec_info* _codecInfo,
149 	media_format_family* _formatFamily, media_format* _inputFormat,
150 	media_format* _outputFormat)
151 {
152 	if (*cookie < 0 || *cookie >= (int32)gEncoderCount)
153 		return B_BAD_INDEX;
154 
155 	*_codecInfo = gEncoderTable[*cookie].codec_info;
156 	*_formatFamily = gEncoderTable[*cookie].format_family;
157 	_inputFormat->type = gEncoderTable[*cookie].input_type;
158 	_outputFormat->type = gEncoderTable[*cookie].output_type;;
159 
160 	*cookie = *cookie + 1;
161 
162 	return B_OK;
163 }
164 
165 
166 // #pragma mark -
167 
168 
169 MediaPlugin*
170 instantiate_plugin()
171 {
172 	return new(std::nothrow) FFmpegPlugin;
173 }
174 
175