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