xref: /haiku/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp (revision 1214ef1b2100f2b3299fc9d8d6142e46f70a4c3f)
1 /*
2  * Copyright (c) 2003-2004, Marcus Overhagen
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  *  * Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23  * OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include <stdio.h>
26 #include <string.h>
27 #include <DataIO.h>
28 #include <OS.h>
29 #include <MediaRoster.h>
30 #include "RawFormats.h"
31 #include "RawDecoderPlugin.h"
32 #include "AudioConversion.h"
33 
34 //#define TRACE_RAW_DECODER
35 #ifdef TRACE_RAW_DECODER
36   #define TRACE printf
37 #else
38   #define TRACE(a...)
39 #endif
40 
41 inline size_t
42 AudioBufferSize(int32 channel_count, uint32 sample_format, float frame_rate, bigtime_t buffer_duration = 50000 /* 50 ms */)
43 {
44 	return (sample_format & 0xf) * channel_count * (size_t)((frame_rate * buffer_duration) / 1000000.0);
45 }
46 
47 
48 void
49 RawDecoder::GetCodecInfo(media_codec_info *info)
50 {
51 	strcpy(info->short_name, "raw");
52 
53 	if (fInputFormat.IsAudio())
54 		strcpy(info->pretty_name, "Raw audio decoder");
55 	else
56 		strcpy(info->pretty_name, "Raw video decoder");
57 }
58 
59 
60 status_t
61 RawDecoder::Setup(media_format *ioEncodedFormat,
62 				  const void *infoBuffer, size_t infoSize)
63 {
64 	char s[200];
65 	string_for_format(*ioEncodedFormat, s, sizeof(s));
66 	TRACE("RawDecoder::Setup: %s\n", s);
67 
68 	if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO)
69 		return B_ERROR;
70 
71 	fInputFormat = *ioEncodedFormat;
72 
73 	if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO) {
74 		fInputSampleSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row;
75 		fInputFrameSize = fInputSampleSize;
76 	} else {
77 		fInputSampleSize = (ioEncodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
78 		fInputFrameSize = fInputSampleSize * ioEncodedFormat->u.raw_audio.channel_count;
79 	}
80 
81 	// since ioEncodedFormat is later passed to the application by BMediaTrack::EncodedFormat()
82 	// we need to remove non public format specifications
83 
84 	// remove non format bits, like channel order
85 	ioEncodedFormat->u.raw_audio.format &= B_AUDIO_FORMAT_MASK;
86 
87 	switch (ioEncodedFormat->u.raw_audio.format) {
88 		case B_AUDIO_FORMAT_UINT8:
89 		case B_AUDIO_FORMAT_INT8:
90 		case B_AUDIO_FORMAT_INT16:
91 		case B_AUDIO_FORMAT_INT32:
92 		case B_AUDIO_FORMAT_FLOAT32:
93 			break; // ok to pass through
94 
95 		case B_AUDIO_FORMAT_INT24:
96 			ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_INT32;
97 			break;
98 
99 		case B_AUDIO_FORMAT_FLOAT64:
100 			ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_FLOAT32;
101 			break;
102 
103 		default:
104 			TRACE("RawDecoder::Setup: unknown input format\n");
105 			return B_ERROR;
106 	}
107 
108 	// since we can translate to a different buffer size,
109 	// suggest something nicer than delivered by the
110 	// file reader (perhaps we should even report wildcard?)
111 	ioEncodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
112 														ioEncodedFormat->u.raw_audio.channel_count,
113 														ioEncodedFormat->u.raw_audio.format,
114 														ioEncodedFormat->u.raw_audio.frame_rate);
115 	return B_OK;
116 }
117 
118 
119 status_t
120 RawDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat)
121 {
122 	// BeBook says: The codec will find and return in ioFormat its best matching format
123 	// => This means, we never return an error, and always change the format values
124 	//    that we don't support to something more applicable
125 	if (fInputFormat.type == B_MEDIA_RAW_VIDEO)
126 		return NegotiateVideoOutputFormat(ioDecodedFormat);
127 	if (fInputFormat.type == B_MEDIA_RAW_AUDIO)
128 		return NegotiateAudioOutputFormat(ioDecodedFormat);
129 	debugger("RawDecoder::NegotiateOutputFormat: wrong encoded format type");
130 	return B_ERROR;
131 }
132 
133 
134 status_t
135 RawDecoder::NegotiateVideoOutputFormat(media_format *ioDecodedFormat)
136 {
137 	return B_ERROR;
138 }
139 
140 
141 status_t
142 RawDecoder::NegotiateAudioOutputFormat(media_format *ioDecodedFormat)
143 {
144 	char s[1024];
145 
146 	string_for_format(*ioDecodedFormat, s, sizeof(s));
147 	TRACE("RawDecoder::NegotiateAudioOutputFormat enter: %s\n", s);
148 
149 	ioDecodedFormat->type = B_MEDIA_RAW_AUDIO;
150 	switch (ioDecodedFormat->u.raw_audio.format) {
151 		case media_raw_audio_format::B_AUDIO_FLOAT:
152 		case media_raw_audio_format::B_AUDIO_SHORT:
153 		case media_raw_audio_format::B_AUDIO_UCHAR:
154 		case media_raw_audio_format::B_AUDIO_CHAR:
155 			ioDecodedFormat->u.raw_audio.valid_bits = 0;
156 			break; // we can produce this on request
157 
158 		case media_raw_audio_format::B_AUDIO_INT:
159 			ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
160 			break; // we can produce this on request
161 
162 		default:
163 			switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
164 				case media_raw_audio_format::B_AUDIO_SHORT:
165 				case media_raw_audio_format::B_AUDIO_UCHAR:
166 				case media_raw_audio_format::B_AUDIO_CHAR:
167 					ioDecodedFormat->u.raw_audio.format = fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK;
168 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
169 					break;
170 
171 				case media_raw_audio_format::B_AUDIO_INT:
172 				case B_AUDIO_FORMAT_INT24:
173 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_INT;
174 					ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
175 					break;
176 
177 				case media_raw_audio_format::B_AUDIO_FLOAT:
178 				case B_AUDIO_FORMAT_FLOAT64:
179 				default:
180 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
181 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
182 					break;
183 			}
184 			break;
185 	}
186 
187 	ioDecodedFormat->u.raw_audio.frame_rate = fInputFormat.u.raw_audio.frame_rate;
188 	ioDecodedFormat->u.raw_audio.channel_count = fInputFormat.u.raw_audio.channel_count;
189 
190 	fFrameRate = (int32) ioDecodedFormat->u.raw_audio.frame_rate;
191 
192 	fOutputSampleSize = (ioDecodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
193 	fOutputFrameSize = fOutputSampleSize * ioDecodedFormat->u.raw_audio.channel_count;
194 
195 	if (ioDecodedFormat->u.raw_audio.byte_order == 0)
196 		ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
197 
198 	ioDecodedFormat->u.raw_audio.channel_mask = 0;
199 	ioDecodedFormat->u.raw_audio.matrix_mask = 0;
200 
201 	if (ioDecodedFormat->u.raw_audio.buffer_size < 128 || ioDecodedFormat->u.raw_audio.buffer_size > 65536) {
202 		ioDecodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
203 														ioDecodedFormat->u.raw_audio.channel_count,
204 														ioDecodedFormat->u.raw_audio.format,
205 														ioDecodedFormat->u.raw_audio.frame_rate);
206 	} else {
207 		// round down to exact multiple of output frame size
208 		ioDecodedFormat->u.raw_audio.buffer_size = (ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize) * fOutputFrameSize;
209 	}
210 
211 	fOutputBufferFrameCount = ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize;
212 
213 	// setup input swapping function
214 	if (fInputFormat.u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
215 		fSwapInput = 0;
216 	} else {
217 		switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
218 			case B_AUDIO_FORMAT_INT16:
219 				fSwapInput = &swap_int16;
220 				break;
221 			case B_AUDIO_FORMAT_INT24:
222 				fSwapInput = &swap_int24;
223 				break;
224 			case B_AUDIO_FORMAT_INT32:
225 				fSwapInput = &swap_int32;
226 				break;
227 			case B_AUDIO_FORMAT_FLOAT32:
228 				fSwapInput = &swap_float32;
229 				break;
230 			case B_AUDIO_FORMAT_FLOAT64:
231 				fSwapInput = &swap_float64;
232 				break;
233 			case B_AUDIO_FORMAT_UINT8:
234 			case B_AUDIO_FORMAT_INT8:
235 				fSwapInput = 0;
236 				break;
237 			default:
238 				debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n");
239 				break;
240 		}
241 	}
242 
243 	// setup output swapping function
244 	if (ioDecodedFormat->u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
245 		fSwapOutput = 0;
246 	} else {
247 		switch (ioDecodedFormat->u.raw_audio.format) {
248 			case B_AUDIO_FORMAT_INT16:
249 				fSwapOutput = &swap_int16;
250 				break;
251 			case B_AUDIO_FORMAT_INT32:
252 				fSwapOutput = &swap_int32;
253 				break;
254 			case B_AUDIO_FORMAT_FLOAT32:
255 				fSwapOutput = &swap_float32;
256 				break;
257 			case B_AUDIO_FORMAT_UINT8:
258 			case B_AUDIO_FORMAT_INT8:
259 				fSwapOutput = 0;
260 				break;
261 			default:
262 				debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
263 				break;
264 		}
265 	}
266 
267 	// setup sample conversation function
268 	switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
269 		case B_AUDIO_FORMAT_UINT8:
270 			switch (ioDecodedFormat->u.raw_audio.format) {
271 				case B_AUDIO_FORMAT_UINT8:
272 					fConvert = &uint8_to_uint8;
273 					break;
274 				case B_AUDIO_FORMAT_INT8:
275 					fConvert = &uint8_to_int8;
276 					break;
277 				case B_AUDIO_FORMAT_INT16:
278 					fConvert = &uint8_to_int16;
279 					break;
280 				case B_AUDIO_FORMAT_INT32:
281 					fConvert = &uint8_to_int32;
282 					break;
283 				case B_AUDIO_FORMAT_FLOAT32:
284 					fConvert = &uint8_to_float32;
285 					break;
286 				default:
287 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
288 					break;
289 			}
290 			break;
291 
292 		case B_AUDIO_FORMAT_INT8:
293 			switch (ioDecodedFormat->u.raw_audio.format) {
294 				case B_AUDIO_FORMAT_UINT8:
295 					fConvert = &int8_to_uint8;
296 					break;
297 				case B_AUDIO_FORMAT_INT8:
298 					fConvert = &int8_to_int8;
299 					break;
300 				case B_AUDIO_FORMAT_INT16:
301 					fConvert = &int8_to_int16;
302 					break;
303 				case B_AUDIO_FORMAT_INT32:
304 					fConvert = &int8_to_int32;
305 					break;
306 				case B_AUDIO_FORMAT_FLOAT32:
307 					fConvert = &int8_to_float32;
308 					break;
309 				default:
310 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
311 					break;
312 			}
313 			break;
314 
315 		case B_AUDIO_FORMAT_INT16:
316 			switch (ioDecodedFormat->u.raw_audio.format) {
317 				case B_AUDIO_FORMAT_UINT8:
318 					fConvert = &int16_to_uint8;
319 					break;
320 				case B_AUDIO_FORMAT_INT8:
321 					fConvert = &int16_to_int8;
322 					break;
323 				case B_AUDIO_FORMAT_INT16:
324 					fConvert = &int16_to_int16;
325 					break;
326 				case B_AUDIO_FORMAT_INT32:
327 					fConvert = &int16_to_int32;
328 					break;
329 				case B_AUDIO_FORMAT_FLOAT32:
330 					fConvert = &int16_to_float32;
331 					break;
332 				default:
333 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
334 					break;
335 			}
336 			break;
337 
338 		case B_AUDIO_FORMAT_INT24:
339 			switch (ioDecodedFormat->u.raw_audio.format) {
340 				case B_AUDIO_FORMAT_UINT8:
341 					fConvert = &int24_to_uint8;
342 					break;
343 				case B_AUDIO_FORMAT_INT8:
344 					fConvert = &int24_to_int8;
345 					break;
346 				case B_AUDIO_FORMAT_INT16:
347 					fConvert = &int24_to_int16;
348 					break;
349 				case B_AUDIO_FORMAT_INT32:
350 					fConvert = &int24_to_int32;
351 					break;
352 				case B_AUDIO_FORMAT_FLOAT32:
353 					fConvert = &int24_to_float32;
354 					break;
355 				default:
356 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
357 					break;
358 			}
359 			break;
360 
361 		case B_AUDIO_FORMAT_INT32:
362 			switch (ioDecodedFormat->u.raw_audio.format) {
363 				case B_AUDIO_FORMAT_UINT8:
364 					fConvert = &int32_to_uint8;
365 					break;
366 				case B_AUDIO_FORMAT_INT8:
367 					fConvert = &int32_to_int8;
368 					break;
369 				case B_AUDIO_FORMAT_INT16:
370 					fConvert = &int32_to_int16;
371 					break;
372 				case B_AUDIO_FORMAT_INT32:
373 					fConvert = &int32_to_int32;
374 					break;
375 				case B_AUDIO_FORMAT_FLOAT32:
376 					fConvert = &int32_to_float32;
377 					break;
378 				default:
379 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
380 					break;
381 			}
382 			break;
383 
384 		case B_AUDIO_FORMAT_FLOAT32:
385 			switch (ioDecodedFormat->u.raw_audio.format) {
386 				case B_AUDIO_FORMAT_UINT8:
387 					fConvert = &float32_to_uint8;
388 					break;
389 				case B_AUDIO_FORMAT_INT8:
390 					fConvert = &float32_to_int8;
391 					break;
392 				case B_AUDIO_FORMAT_INT16:
393 					fConvert = &float32_to_int16;
394 					break;
395 				case B_AUDIO_FORMAT_INT32:
396 					fConvert = &float32_to_int32;
397 					break;
398 				case B_AUDIO_FORMAT_FLOAT32:
399 					fConvert = &float32_to_float32;
400 					break;
401 				default:
402 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
403 					break;
404 			}
405 			break;
406 
407 		case B_AUDIO_FORMAT_FLOAT64:
408 			switch (ioDecodedFormat->u.raw_audio.format) {
409 				case B_AUDIO_FORMAT_UINT8:
410 					fConvert = &float64_to_uint8;
411 					break;
412 				case B_AUDIO_FORMAT_INT8:
413 					fConvert = &float64_to_int8;
414 					break;
415 				case B_AUDIO_FORMAT_INT16:
416 					fConvert = &float64_to_int16;
417 					break;
418 				case B_AUDIO_FORMAT_INT32:
419 					fConvert = &float64_to_int32;
420 					break;
421 				case B_AUDIO_FORMAT_FLOAT32:
422 					fConvert = &float64_to_float32;
423 					break;
424 				default:
425 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
426 					break;
427 			}
428 			break;
429 
430 		default:
431 			debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n");
432 			break;
433 	}
434 
435 	fChunkBuffer = 0;
436 	fChunkSize = 0;
437 	fStartTime = 0;
438 
439 	string_for_format(*ioDecodedFormat, s, sizeof(s));
440 	TRACE("RawDecoder::NegotiateAudioOutputFormat leave: %s\n", s);
441 
442 	if (ioDecodedFormat->type == 0)
443 		debugger("RawDecoder::NegotiateAudioOutputFormat ioDecodedFormat->type == 0");
444 /*
445 	TRACE("fFrameRate              %ld\n", fFrameRate);
446 	TRACE("fInputFrameSize         %ld\n", fInputFrameSize);
447 	TRACE("fOutputFrameSize        %ld\n", fOutputFrameSize);
448 	TRACE("fInputSampleSize        %ld\n", fInputSampleSize);
449 	TRACE("fOutputSampleSize       %ld\n", fOutputSampleSize);
450 	TRACE("fOutputBufferFrameCount %ld\n", fOutputBufferFrameCount);
451 	TRACE("fSwapInput              %p\n", fSwapInput);
452 	TRACE("fConvert                %p\n", fConvert);
453 	TRACE("fSwapOutput             %p\n", fSwapOutput);
454 */
455 	return B_OK;
456 }
457 
458 
459 status_t
460 RawDecoder::Seek(uint32 seekTo,
461 				 int64 seekFrame, int64 *frame,
462 				 bigtime_t seekTime, bigtime_t *time)
463 {
464 	fChunkSize = 0;
465 	fStartTime = *time;
466 	return B_OK;
467 }
468 
469 
470 status_t
471 RawDecoder::Decode(void *buffer, int64 *frameCount,
472 				   media_header *mediaHeader, media_decode_info *info /* = 0 */)
473 {
474 	char *output_buffer = (char *)buffer;
475 	mediaHeader->start_time = fStartTime;
476 	*frameCount = 0;
477 	while (*frameCount < fOutputBufferFrameCount) {
478 		if (fChunkSize == 0) {
479 			media_header mh;
480 			status_t err;
481 			err = GetNextChunk(&fChunkBuffer, &fChunkSize, &mh);
482 			if (err != B_OK || fChunkSize < fInputFrameSize) {
483 				fChunkSize = 0;
484 				break;
485 			}
486 			if (fSwapInput)
487 				fSwapInput(const_cast<void *>(fChunkBuffer), fChunkSize / fInputSampleSize); // XXX TODO! FIX THIS, we write to a const buffer!!!
488 			fStartTime = mh.start_time;
489 			continue;
490 		}
491 		int32 frames = min_c(fOutputBufferFrameCount - *frameCount, fChunkSize / fInputFrameSize);
492 		int32 samples = frames * fInputFormat.u.raw_audio.channel_count;
493 		fConvert(output_buffer, fChunkBuffer, samples);
494 		fChunkBuffer = (const char *)fChunkBuffer + frames * fInputFrameSize;
495 		fChunkSize -= frames * fInputFrameSize;
496 		output_buffer += frames * fOutputFrameSize;
497 		*frameCount += frames;
498 		fStartTime +=  (1000000LL * frames) / fFrameRate;
499 	}
500 	// XXX should change channel order here for
501 	// B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE and B_AUDIO_FORMAT_CHANNEL_ORDER_AIFF
502 
503 	if (fSwapOutput)
504 		fSwapOutput(buffer, *frameCount * fInputFormat.u.raw_audio.channel_count);
505 	return *frameCount ? B_OK : B_ERROR;
506 }
507 
508 
509 Decoder *
510 RawDecoderPlugin::NewDecoder(uint index)
511 {
512 	return new RawDecoder;
513 }
514 
515 
516 static media_format raw_formats[2];
517 
518 status_t
519 RawDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
520 {
521 	BMediaFormats mediaFormats;
522 	media_format_description description;
523 	media_format format;
524 
525 	// audio decoder
526 
527 	description.family = B_BEOS_FORMAT_FAMILY;
528 	description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO;
529 	format.type = B_MEDIA_RAW_AUDIO;
530 	format.u.raw_audio = media_multi_audio_format::wildcard;
531 
532 	status_t status = mediaFormats.MakeFormatFor(&description, 1, &format);
533 	if (status < B_OK)
534 		return status;
535 	raw_formats[0] = format;
536 
537 	// video decoder
538 
539 	description.u.beos.format = B_BEOS_FORMAT_RAW_VIDEO;
540 	format.type = B_MEDIA_RAW_VIDEO;
541 	format.u.raw_video = media_raw_video_format::wildcard;
542 
543 	status = mediaFormats.MakeFormatFor(&description, 1, &format);
544 	if (status < B_OK)
545 		return status;
546 	raw_formats[1] = format;
547 
548 	*formats = raw_formats;
549 	*count = 2;
550 
551 	return B_OK;
552 }
553 
554 MediaPlugin *instantiate_plugin()
555 {
556 	return new RawDecoderPlugin;
557 }
558