xref: /haiku/src/add-ons/media/plugins/ffmpeg/FFmpegPlugin.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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  * Copyright (C) 2018 Dario Casalinuovo
8  *
9  * All rights reserved. Distributed under the terms of the MIT License.
10  */
11 
12 //! libavcodec/libavformat based Decoder and Reader plugin for Haiku
13 
14 #include "FFmpegPlugin.h"
15 
16 #include <stdio.h>
17 
18 #include <new>
19 
20 extern "C" {
21 	#include "avcodec.h"
22 	#include "avformat.h"
23 }
24 
25 #include "AVCodecDecoder.h"
26 #include "AVCodecEncoder.h"
27 #include "AVFormatReader.h"
28 #include "AVFormatWriter.h"
29 #include "CodecTable.h"
30 #include "EncoderTable.h"
31 #include "MuxerTable.h"
32 
33 
34 //#define TRACE_FFMPEG_PLUGIN
35 #ifdef TRACE_FFMPEG_PLUGIN
36 #	define TRACE printf
37 #else
38 #	define TRACE(a...)
39 #endif
40 
41 #define ERROR(a...) fprintf(stderr, a)
42 
43 
44 B_DECLARE_CODEC_KIT_PLUGIN(
45 	FFmpegPlugin,
46 	"ffmpeg",
47 	B_CODEC_KIT_PLUGIN_VERSION
48 );
49 
50 
51 // #pragma mark -
52 
53 
54 BDecoder*
55 FFmpegPlugin::NewDecoder(uint index)
56 {
57 // TODO: Confirm we can check index here.
58 //	if (index == 0)
59 		return new(std::nothrow) AVCodecDecoder();
60 //	return NULL;
61 }
62 
63 
64 BReader*
65 FFmpegPlugin::NewReader()
66 {
67 	return new(std::nothrow) AVFormatReader();
68 }
69 
70 
71 status_t
72 FFmpegPlugin::GetSupportedFormats(media_format** _formats, size_t* _count)
73 {
74 	return build_decoder_formats(_formats, _count);
75 }
76 
77 
78 BWriter*
79 FFmpegPlugin::NewWriter()
80 {
81 	return new(std::nothrow) AVFormatWriter();
82 }
83 
84 
85 status_t
86 FFmpegPlugin::GetSupportedFileFormats(const media_file_format** _fileFormats,
87 	size_t* _count)
88 {
89 	*_fileFormats = gMuxerTable;
90 	*_count = gMuxerCount;
91 	return B_OK;
92 }
93 
94 
95 BEncoder*
96 FFmpegPlugin::NewEncoder(const media_codec_info& codecInfo)
97 {
98 	for (size_t i = 0; i < gEncoderCount; i++) {
99 		if (codecInfo.sub_id == gEncoderTable[i].codec_info.sub_id) {
100 			return new(std::nothrow)AVCodecEncoder(codecInfo.sub_id,
101 				gEncoderTable[i].bit_rate_scale);
102 		}
103 	}
104 	return NULL;
105 }
106 
107 
108 BEncoder*
109 FFmpegPlugin::NewEncoder(const media_format& format)
110 {
111 	for (size_t i = 0; i < gEncoderCount; i++) {
112 		if (format.type == gEncoderTable[i].output_type) {
113 			return new(std::nothrow)AVCodecEncoder(
114 				gEncoderTable[i].codec_info.sub_id,
115 				gEncoderTable[i].bit_rate_scale);
116 		}
117 	}
118 	return NULL;
119 }
120 
121 
122 status_t
123 FFmpegPlugin::RegisterNextEncoder(int32* cookie, media_codec_info* _codecInfo,
124 	media_format_family* _formatFamily, media_format* _inputFormat,
125 	media_format* _outputFormat)
126 {
127 	if (*cookie < 0 || *cookie >= (int32)gEncoderCount)
128 		return B_BAD_INDEX;
129 
130 	*_codecInfo = gEncoderTable[*cookie].codec_info;
131 	*_formatFamily = gEncoderTable[*cookie].format_family;
132 	_inputFormat->type = gEncoderTable[*cookie].input_type;
133 	_outputFormat->type = gEncoderTable[*cookie].output_type;;
134 
135 	*cookie = *cookie + 1;
136 
137 	return B_OK;
138 }
139