xref: /haiku/src/add-ons/media/plugins/ffmpeg/FFmpegPlugin.cpp (revision 323b65468e5836bb27a5e373b14027d902349437)
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 #include <Locker.h>
20 
21 extern "C" {
22 	#include "avcodec.h"
23 	#include "avformat.h"
24 }
25 
26 #include "AVCodecDecoder.h"
27 #include "AVCodecEncoder.h"
28 #include "AVFormatReader.h"
29 #include "AVFormatWriter.h"
30 #include "CodecTable.h"
31 #include "EncoderTable.h"
32 #include "MuxerTable.h"
33 
34 
35 //#define TRACE_FFMPEG_PLUGIN
36 #ifdef TRACE_FFMPEG_PLUGIN
37 #	define TRACE printf
38 #else
39 #	define TRACE(a...)
40 #endif
41 
42 #define ERROR(a...) fprintf(stderr, a)
43 
44 
45 static int
46 manage_locks(void** _lock, enum AVLockOp operation)
47 {
48 	TRACE("manage_locks(%p, %d)\n", *_lock, operation);
49 
50 	BLocker** lock = reinterpret_cast<BLocker**>(_lock);
51 
52 	switch (operation) {
53 		case AV_LOCK_CREATE:
54 			TRACE("  AV_LOCK_CREATE\n");
55 			*lock = new(std::nothrow) BLocker("FFmpeg lock");
56 		 	if (*lock == NULL)
57 				return 1;
58 			break;
59 
60 		case AV_LOCK_OBTAIN:
61 			TRACE("  AV_LOCK_OBTAIN\n");
62 			if (!(*lock)->Lock())
63 				return 1;
64 			break;
65 
66 		case AV_LOCK_RELEASE:
67 			TRACE("  AV_LOCK_RELEASE\n");
68 			(*lock)->Unlock();
69 			break;
70 
71 		case AV_LOCK_DESTROY:
72 			TRACE("  AV_LOCK_DESTROY\n");
73 			delete *lock;
74 			break;
75 
76 		default:
77 			return 1;
78 	}
79 	return 0;
80 }
81 
82 
83 FFmpegPlugin::GlobalInitilizer::GlobalInitilizer()
84 {
85 	if (av_lockmgr_register(manage_locks) != 0)
86 		ERROR("Failed to register lock management!\n");
87 
88 	av_register_all();
89 		// This will also call av_codec_init() by registering codecs.
90 }
91 
92 
93 FFmpegPlugin::GlobalInitilizer::~GlobalInitilizer()
94 {
95 	av_lockmgr_register(NULL);
96 }
97 
98 
99 FFmpegPlugin::GlobalInitilizer FFmpegPlugin::sInitilizer;
100 
101 
102 // #pragma mark -
103 
104 
105 Decoder*
106 FFmpegPlugin::NewDecoder(uint index)
107 {
108 // TODO: Confirm we can check index here.
109 //	if (index == 0)
110 		return new(std::nothrow) AVCodecDecoder();
111 //	return NULL;
112 }
113 
114 
115 Reader*
116 FFmpegPlugin::NewReader()
117 {
118 	return new(std::nothrow) AVFormatReader();
119 }
120 
121 
122 status_t
123 FFmpegPlugin::GetSupportedFormats(media_format** _formats, size_t* _count)
124 {
125 	return build_decoder_formats(_formats, _count);
126 }
127 
128 
129 Writer*
130 FFmpegPlugin::NewWriter()
131 {
132 	return new(std::nothrow) AVFormatWriter();
133 }
134 
135 
136 status_t
137 FFmpegPlugin::GetSupportedFileFormats(const media_file_format** _fileFormats,
138 	size_t* _count)
139 {
140 	*_fileFormats = gMuxerTable;
141 	*_count = gMuxerCount;
142 	return B_OK;
143 }
144 
145 
146 Encoder*
147 FFmpegPlugin::NewEncoder(const media_codec_info& codecInfo)
148 {
149 	for (size_t i = 0; i < gEncoderCount; i++) {
150 		if (codecInfo.sub_id == gEncoderTable[i].codec_info.sub_id) {
151 			return new(std::nothrow)AVCodecEncoder(codecInfo.sub_id,
152 				gEncoderTable[i].bit_rate_scale);
153 		}
154 	}
155 	return NULL;
156 }
157 
158 
159 status_t
160 FFmpegPlugin::RegisterNextEncoder(int32* cookie, media_codec_info* _codecInfo,
161 	media_format_family* _formatFamily, media_format* _inputFormat,
162 	media_format* _outputFormat)
163 {
164 	if (*cookie < 0 || *cookie >= (int32)gEncoderCount)
165 		return B_BAD_INDEX;
166 
167 	*_codecInfo = gEncoderTable[*cookie].codec_info;
168 	*_formatFamily = gEncoderTable[*cookie].format_family;
169 	_inputFormat->type = gEncoderTable[*cookie].input_type;
170 	_outputFormat->type = gEncoderTable[*cookie].output_type;;
171 
172 	*cookie = *cookie + 1;
173 
174 	return B_OK;
175 }
176 
177 
178 // #pragma mark -
179 
180 
181 MediaPlugin*
182 instantiate_plugin()
183 {
184 	return new(std::nothrow) FFmpegPlugin;
185 }
186 
187