xref: /haiku/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp (revision a07cdb6e9f8e484b6ba9f209fbeb144e906d3405)
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 Amßus <superstippi@gmx.de>
7  * Copyright (C) 2014 Colin Günther <coling@gmx.de>
8  *
9  * All rights reserved. Distributed under the terms of the MIT License.
10  */
11 
12 //! libavcodec based decoder for Haiku
13 
14 #include "AVCodecDecoder.h"
15 
16 #include <new>
17 
18 #include <assert.h>
19 #include <string.h>
20 
21 #include <Bitmap.h>
22 #include <Debug.h>
23 
24 
25 #undef TRACE
26 //#define TRACE_AV_CODEC
27 #ifdef TRACE_AV_CODEC
28 #	define TRACE(x...)	printf(x)
29 #	define TRACE_AUDIO(x...)	printf(x)
30 #	define TRACE_VIDEO(x...)	printf(x)
31 #else
32 #	define TRACE(x...)
33 #	define TRACE_AUDIO(x...)
34 #	define TRACE_VIDEO(x...)
35 #endif
36 
37 //#define LOG_STREAM_TO_FILE
38 #ifdef LOG_STREAM_TO_FILE
39 #	include <File.h>
40 	static BFile sStreamLogFile("/boot/home/Desktop/AVCodecDebugStream.raw",
41 		B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
42 	static int sDumpedPackets = 0;
43 #endif
44 
45 #ifdef __x86_64
46 #define USE_SWS_FOR_COLOR_SPACE_CONVERSION 1
47 #else
48 #define USE_SWS_FOR_COLOR_SPACE_CONVERSION 0
49 // NOTE: David's color space conversion is much faster than the FFmpeg
50 // version. Perhaps the SWS code can be used for unsupported conversions?
51 // Otherwise the alternative code could simply be removed from this file.
52 #endif
53 
54 
55 struct wave_format_ex {
56 	uint16 format_tag;
57 	uint16 channels;
58 	uint32 frames_per_sec;
59 	uint32 avg_bytes_per_sec;
60 	uint16 block_align;
61 	uint16 bits_per_sample;
62 	uint16 extra_size;
63 	// extra_data[extra_size]
64 } _PACKED;
65 
66 
67 // profiling related globals
68 #define DO_PROFILING 0
69 
70 static bigtime_t decodingTime = 0;
71 static bigtime_t conversionTime = 0;
72 static long profileCounter = 0;
73 
74 
75 AVCodecDecoder::AVCodecDecoder()
76 	:
77 	fHeader(),
78 	fInputFormat(),
79 	fOutputVideoFormat(),
80 	fFrame(0),
81 	fIsAudio(false),
82 	fCodec(NULL),
83 	fContext(avcodec_alloc_context3(NULL)),
84 	fDecodedData(NULL),
85 	fDecodedDataSizeInBytes(0),
86 	fPostProcessedDecodedPicture(avcodec_alloc_frame()),
87 	fRawDecodedPicture(avcodec_alloc_frame()),
88 
89 	fCodecInitDone(false),
90 
91 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
92 	fSwsContext(NULL),
93 #else
94 	fFormatConversionFunc(NULL),
95 #endif
96 
97 	fExtraData(NULL),
98 	fExtraDataSize(0),
99 	fBlockAlign(0),
100 
101 	fStartTime(0),
102 	fOutputFrameCount(0),
103 	fOutputFrameRate(1.0),
104 	fOutputFrameSize(0),
105 
106 	fChunkBuffer(NULL),
107 	fChunkBufferOffset(0),
108 	fChunkBufferSize(0),
109 	fAudioDecodeError(false),
110 
111 	fOutputFrame(avcodec_alloc_frame()),
112 	fOutputBufferOffset(0),
113 	fOutputBufferSize(0)
114 {
115 	TRACE("AVCodecDecoder::AVCodecDecoder()\n");
116 
117 	system_info info;
118 	get_system_info(&info);
119 
120 	fContext->err_recognition = AV_EF_CAREFUL;
121 	fContext->error_concealment = 3;
122 	fContext->thread_count = info.cpu_count;
123 }
124 
125 
126 AVCodecDecoder::~AVCodecDecoder()
127 {
128 	TRACE("[%c] AVCodecDecoder::~AVCodecDecoder()\n", fIsAudio?('a'):('v'));
129 
130 #ifdef DO_PROFILING
131 	if (profileCounter > 0) {
132 		printf("[%c] profile: d1 = %lld, d2 = %lld (%Ld)\n",
133 			fIsAudio?('a'):('v'), decodingTime / profileCounter,
134 			conversionTime / profileCounter, fFrame);
135 	}
136 #endif
137 
138 	if (fCodecInitDone)
139 		avcodec_close(fContext);
140 
141 	free(fDecodedData);
142 
143 	av_free(fPostProcessedDecodedPicture);
144 	av_free(fRawDecodedPicture);
145 	av_free(fContext);
146 	av_free(fOutputFrame);
147 
148 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
149 	if (fSwsContext != NULL)
150 		sws_freeContext(fSwsContext);
151 #endif
152 
153 	delete[] fExtraData;
154 }
155 
156 
157 void
158 AVCodecDecoder::GetCodecInfo(media_codec_info* mci)
159 {
160 	snprintf(mci->short_name, 32, "%s", fCodec->name);
161 	snprintf(mci->pretty_name, 96, "%s", fCodec->long_name);
162 	mci->id = 0;
163 	mci->sub_id = fCodec->id;
164 }
165 
166 
167 status_t
168 AVCodecDecoder::Setup(media_format* ioEncodedFormat, const void* infoBuffer,
169 	size_t infoSize)
170 {
171 	if (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO
172 		&& ioEncodedFormat->type != B_MEDIA_ENCODED_VIDEO)
173 		return B_ERROR;
174 
175 	fIsAudio = (ioEncodedFormat->type == B_MEDIA_ENCODED_AUDIO);
176 	TRACE("[%c] AVCodecDecoder::Setup()\n", fIsAudio?('a'):('v'));
177 
178 #ifdef TRACE_AV_CODEC
179 	char buffer[1024];
180 	string_for_format(*ioEncodedFormat, buffer, sizeof(buffer));
181 	TRACE("[%c]   input_format = %s\n", fIsAudio?('a'):('v'), buffer);
182 	TRACE("[%c]   infoSize = %ld\n", fIsAudio?('a'):('v'), infoSize);
183 	TRACE("[%c]   user_data_type = %08lx\n", fIsAudio?('a'):('v'),
184 		ioEncodedFormat->user_data_type);
185 	TRACE("[%c]   meta_data_size = %ld\n", fIsAudio?('a'):('v'),
186 		ioEncodedFormat->MetaDataSize());
187 #endif
188 
189 	media_format_description description;
190 	if (BMediaFormats().GetCodeFor(*ioEncodedFormat,
191 			B_MISC_FORMAT_FAMILY, &description) == B_OK) {
192 		if (description.u.misc.file_format != 'ffmp')
193 			return B_NOT_SUPPORTED;
194 		fCodec = avcodec_find_decoder(static_cast<CodecID>(
195 			description.u.misc.codec));
196 		if (fCodec == NULL) {
197 			TRACE("  unable to find the correct FFmpeg "
198 				"decoder (id = %lu)\n", description.u.misc.codec);
199 			return B_ERROR;
200 		}
201 		TRACE("  found decoder %s\n", fCodec->name);
202 
203 		const void* extraData = infoBuffer;
204 		fExtraDataSize = infoSize;
205 		if (description.family == B_WAV_FORMAT_FAMILY
206 				&& infoSize >= sizeof(wave_format_ex)) {
207 			TRACE("  trying to use wave_format_ex\n");
208 			// Special case extra data in B_WAV_FORMAT_FAMILY
209 			const wave_format_ex* waveFormatData
210 				= (const wave_format_ex*)infoBuffer;
211 
212 			size_t waveFormatSize = infoSize;
213 			if (waveFormatData != NULL && waveFormatSize > 0) {
214 				fBlockAlign = waveFormatData->block_align;
215 				TRACE("  found block align: %d\n", fBlockAlign);
216 				fExtraDataSize = waveFormatData->extra_size;
217 				// skip the wave_format_ex from the extra data.
218 				extraData = waveFormatData + 1;
219 			}
220 		} else {
221 			if (fIsAudio) {
222 				fBlockAlign
223 					= ioEncodedFormat->u.encoded_audio.output
224 						.buffer_size;
225 				TRACE("  using buffer_size as block align: %d\n",
226 					fBlockAlign);
227 			}
228 		}
229 		if (extraData != NULL && fExtraDataSize > 0) {
230 			TRACE("AVCodecDecoder: extra data size %ld\n", infoSize);
231 			delete[] fExtraData;
232 			fExtraData = new(std::nothrow) char[fExtraDataSize];
233 			if (fExtraData != NULL)
234 				memcpy(fExtraData, infoBuffer, fExtraDataSize);
235 			else
236 				fExtraDataSize = 0;
237 		}
238 
239 		fInputFormat = *ioEncodedFormat;
240 		return B_OK;
241 	} else {
242 		TRACE("AVCodecDecoder: BMediaFormats().GetCodeFor() failed.\n");
243 	}
244 
245 	printf("AVCodecDecoder::Setup failed!\n");
246 	return B_ERROR;
247 }
248 
249 
250 status_t
251 AVCodecDecoder::SeekedTo(int64 frame, bigtime_t time)
252 {
253 	status_t ret = B_OK;
254 	// Reset the FFmpeg codec to flush buffers, so we keep the sync
255 	if (fCodecInitDone) {
256 		avcodec_flush_buffers(fContext);
257 		_ResetTempPacket();
258 	}
259 
260 	// Flush internal buffers as well.
261 	fChunkBuffer = NULL;
262 	fChunkBufferOffset = 0;
263 	fChunkBufferSize = 0;
264 	fOutputBufferOffset = 0;
265 	fOutputBufferSize = 0;
266 	fDecodedDataSizeInBytes = 0;
267 
268 	fFrame = frame;
269 	fStartTime = time;
270 
271 	return ret;
272 }
273 
274 
275 status_t
276 AVCodecDecoder::NegotiateOutputFormat(media_format* inOutFormat)
277 {
278 	TRACE("AVCodecDecoder::NegotiateOutputFormat() [%c] \n",
279 		fIsAudio?('a'):('v'));
280 
281 #ifdef TRACE_AV_CODEC
282 	char buffer[1024];
283 	string_for_format(*inOutFormat, buffer, sizeof(buffer));
284 	TRACE("  [%c]  requested format = %s\n", fIsAudio?('a'):('v'), buffer);
285 #endif
286 
287 	if (fIsAudio)
288 		return _NegotiateAudioOutputFormat(inOutFormat);
289 	else
290 		return _NegotiateVideoOutputFormat(inOutFormat);
291 }
292 
293 
294 status_t
295 AVCodecDecoder::Decode(void* outBuffer, int64* outFrameCount,
296 	media_header* mediaHeader, media_decode_info* info)
297 {
298 	if (!fCodecInitDone)
299 		return B_NO_INIT;
300 
301 //	TRACE("[%c] AVCodecDecoder::Decode() for time %Ld\n", fIsAudio?('a'):('v'),
302 //		fStartTime);
303 
304 	mediaHeader->start_time = fStartTime;
305 
306 	status_t ret;
307 	if (fIsAudio)
308 		ret = _DecodeAudio(outBuffer, outFrameCount, mediaHeader, info);
309 	else
310 		ret = _DecodeVideo(outBuffer, outFrameCount, mediaHeader, info);
311 
312 	return ret;
313 }
314 
315 
316 // #pragma mark -
317 
318 
319 void
320 AVCodecDecoder::_ResetTempPacket()
321 {
322 	av_init_packet(&fTempPacket);
323 	fTempPacket.size = 0;
324 	fTempPacket.data = NULL;
325 }
326 
327 
328 status_t
329 AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* inOutFormat)
330 {
331 	TRACE("AVCodecDecoder::_NegotiateAudioOutputFormat()\n");
332 
333 	media_multi_audio_format outputAudioFormat;
334 	outputAudioFormat = media_raw_audio_format::wildcard;
335 	outputAudioFormat.byte_order = B_MEDIA_HOST_ENDIAN;
336 	outputAudioFormat.frame_rate
337 		= fInputFormat.u.encoded_audio.output.frame_rate;
338 	outputAudioFormat.channel_count
339 		= fInputFormat.u.encoded_audio.output.channel_count;
340 	outputAudioFormat.format = fInputFormat.u.encoded_audio.output.format;
341 	outputAudioFormat.buffer_size
342 		= inOutFormat->u.raw_audio.buffer_size;
343 	// Check that format is not still a wild card!
344 	if (outputAudioFormat.format == 0) {
345 		TRACE("  format still a wild-card, assuming B_AUDIO_SHORT.\n");
346 		outputAudioFormat.format = media_raw_audio_format::B_AUDIO_SHORT;
347 	}
348 	size_t sampleSize = outputAudioFormat.format
349 		& media_raw_audio_format::B_AUDIO_SIZE_MASK;
350 	// Check that channel count is not still a wild card!
351 	if (outputAudioFormat.channel_count == 0) {
352 		TRACE("  channel_count still a wild-card, assuming stereo.\n");
353 		outputAudioFormat.channel_count = 2;
354 	}
355 
356 	if (outputAudioFormat.buffer_size == 0) {
357 		outputAudioFormat.buffer_size = 512
358 			* sampleSize * outputAudioFormat.channel_count;
359 	}
360 	inOutFormat->type = B_MEDIA_RAW_AUDIO;
361 	inOutFormat->u.raw_audio = outputAudioFormat;
362 
363 	fContext->bit_rate = (int)fInputFormat.u.encoded_audio.bit_rate;
364 	fContext->frame_size = (int)fInputFormat.u.encoded_audio.frame_size;
365 	fContext->sample_rate
366 		= (int)fInputFormat.u.encoded_audio.output.frame_rate;
367 	fContext->channels = outputAudioFormat.channel_count;
368 	fContext->block_align = fBlockAlign;
369 	fContext->extradata = (uint8_t*)fExtraData;
370 	fContext->extradata_size = fExtraDataSize;
371 
372 	// TODO: This probably needs to go away, there is some misconception
373 	// about extra data / info buffer and meta data. See
374 	// Reader::GetStreamInfo(). The AVFormatReader puts extradata and
375 	// extradata_size into media_format::MetaData(), but used to ignore
376 	// the infoBuffer passed to GetStreamInfo(). I think this may be why
377 	// the code below was added.
378 	if (fInputFormat.MetaDataSize() > 0) {
379 		fContext->extradata = (uint8_t*)fInputFormat.MetaData();
380 		fContext->extradata_size = fInputFormat.MetaDataSize();
381 	}
382 
383 	TRACE("  bit_rate %d, sample_rate %d, channels %d, block_align %d, "
384 		"extradata_size %d\n", fContext->bit_rate, fContext->sample_rate,
385 		fContext->channels, fContext->block_align, fContext->extradata_size);
386 
387 	// close any previous instance
388 	if (fCodecInitDone) {
389 		fCodecInitDone = false;
390 		avcodec_close(fContext);
391 	}
392 
393 	// open new
394 	int result = avcodec_open2(fContext, fCodec, NULL);
395 	fCodecInitDone = (result >= 0);
396 
397 	fStartTime = 0;
398 	fOutputFrameSize = sampleSize * outputAudioFormat.channel_count;
399 	fOutputFrameCount = outputAudioFormat.buffer_size / fOutputFrameSize;
400 	fOutputFrameRate = outputAudioFormat.frame_rate;
401 
402 	TRACE("  bit_rate = %d, sample_rate = %d, channels = %d, init = %d, "
403 		"output frame size: %d, count: %ld, rate: %.2f\n",
404 		fContext->bit_rate, fContext->sample_rate, fContext->channels,
405 		result, fOutputFrameSize, fOutputFrameCount, fOutputFrameRate);
406 
407 	fChunkBuffer = NULL;
408 	fChunkBufferOffset = 0;
409 	fChunkBufferSize = 0;
410 	fAudioDecodeError = false;
411 	fOutputBufferOffset = 0;
412 	fOutputBufferSize = 0;
413 
414 	_ResetTempPacket();
415 
416 	inOutFormat->require_flags = 0;
417 	inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
418 
419 	if (!fCodecInitDone) {
420 		TRACE("avcodec_open() failed!\n");
421 		return B_ERROR;
422 	}
423 
424 	return B_OK;
425 }
426 
427 
428 status_t
429 AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat)
430 {
431 	TRACE("AVCodecDecoder::_NegotiateVideoOutputFormat()\n");
432 
433 	fOutputVideoFormat = fInputFormat.u.encoded_video.output;
434 
435 	fContext->width = fOutputVideoFormat.display.line_width;
436 	fContext->height = fOutputVideoFormat.display.line_count;
437 //	fContext->frame_rate = (int)(fOutputVideoFormat.field_rate
438 //		* fContext->frame_rate_base);
439 
440 	fOutputFrameRate = fOutputVideoFormat.field_rate;
441 
442 	fContext->extradata = (uint8_t*)fExtraData;
443 	fContext->extradata_size = fExtraDataSize;
444 
445 	bool codecCanHandleIncompleteFrames
446 		= (fCodec->capabilities & CODEC_CAP_TRUNCATED) != 0;
447 	if (codecCanHandleIncompleteFrames) {
448 		// Expect and handle video frames to be splitted across consecutive
449 		// data chunks.
450 		fContext->flags |= CODEC_FLAG_TRUNCATED;
451 	}
452 
453 	TRACE("  requested video format 0x%x\n",
454 		inOutFormat->u.raw_video.display.format);
455 
456 	// Make MediaPlayer happy (if not in rgb32 screen depth and no overlay,
457 	// it will only ask for YCbCr, which DrawBitmap doesn't handle, so the
458 	// default colordepth is RGB32).
459 	if (inOutFormat->u.raw_video.display.format == B_YCbCr422)
460 		fOutputVideoFormat.display.format = B_YCbCr422;
461 	else
462 		fOutputVideoFormat.display.format = B_RGB32;
463 
464 	// Search for a pixel-format the codec handles
465 	// TODO: We should try this a couple of times until it succeeds, each
466 	// time using another pixel-format that is supported by the decoder.
467 	// But libavcodec doesn't seem to offer any way to tell the decoder
468 	// which format it should use.
469 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
470 	if (fSwsContext != NULL)
471 		sws_freeContext(fSwsContext);
472 	fSwsContext = NULL;
473 #else
474 	fFormatConversionFunc = 0;
475 #endif
476 	// Iterate over supported codec formats
477 	for (int i = 0; i < 1; i++) {
478 		// close any previous instance
479 		if (fCodecInitDone) {
480 			fCodecInitDone = false;
481 			avcodec_close(fContext);
482 		}
483 		// TODO: Set n-th fContext->pix_fmt here
484 		if (avcodec_open2(fContext, fCodec, NULL) >= 0) {
485 			fCodecInitDone = true;
486 
487 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
488 			fSwsContext = sws_getContext(fContext->width, fContext->height,
489 				fContext->pix_fmt, fContext->width, fContext->height,
490 				colorspace_to_pixfmt(fOutputVideoFormat.display.format),
491 				SWS_FAST_BILINEAR, NULL, NULL, NULL);
492 		}
493 #else
494 			fFormatConversionFunc = resolve_colorspace(
495 				fOutputVideoFormat.display.format, fContext->pix_fmt,
496 				fContext->width, fContext->height);
497 		}
498 		if (fFormatConversionFunc != NULL)
499 			break;
500 #endif
501 	}
502 
503 	if (!fCodecInitDone) {
504 		TRACE("avcodec_open() failed to init codec!\n");
505 		return B_ERROR;
506 	}
507 
508 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
509 	if (fSwsContext == NULL) {
510 		TRACE("No SWS Scale context or decoder has not set the pixel format "
511 			"yet!\n");
512 	}
513 #else
514 	if (fFormatConversionFunc == NULL) {
515 		TRACE("no pixel format conversion function found or decoder has "
516 			"not set the pixel format yet!\n");
517 	}
518 #endif
519 
520 	if (fOutputVideoFormat.display.format == B_YCbCr422) {
521 		fOutputVideoFormat.display.bytes_per_row
522 			= 2 * fOutputVideoFormat.display.line_width;
523 	} else {
524 		fOutputVideoFormat.display.bytes_per_row
525 			= 4 * fOutputVideoFormat.display.line_width;
526 	}
527 
528 	inOutFormat->type = B_MEDIA_RAW_VIDEO;
529 	inOutFormat->u.raw_video = fOutputVideoFormat;
530 
531 	inOutFormat->require_flags = 0;
532 	inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
533 
534 	_ResetTempPacket();
535 
536 #ifdef TRACE_AV_CODEC
537 	char buffer[1024];
538 	string_for_format(*inOutFormat, buffer, sizeof(buffer));
539 	TRACE("[v]  outFormat = %s\n", buffer);
540 	TRACE("  returned  video format 0x%x\n",
541 		inOutFormat->u.raw_video.display.format);
542 #endif
543 
544 	return B_OK;
545 }
546 
547 
548 status_t
549 AVCodecDecoder::_DecodeAudio(void* _buffer, int64* outFrameCount,
550 	media_header* mediaHeader, media_decode_info* info)
551 {
552 	TRACE_AUDIO("AVCodecDecoder::_DecodeAudio(audio start_time %.6fs)\n",
553 		mediaHeader->start_time / 1000000.0);
554 
555 	*outFrameCount = 0;
556 
557 	uint8* buffer = reinterpret_cast<uint8*>(_buffer);
558 	while (*outFrameCount < fOutputFrameCount) {
559 		// Check conditions which would hint at broken code below.
560 		if (fOutputBufferSize < 0) {
561 			fprintf(stderr, "Decoding read past the end of the output buffer! "
562 				"%ld\n", fOutputBufferSize);
563 			fOutputBufferSize = 0;
564 		}
565 		if (fChunkBufferSize < 0) {
566 			fprintf(stderr, "Decoding read past the end of the chunk buffer! "
567 				"%ld\n", fChunkBufferSize);
568 			fChunkBufferSize = 0;
569 		}
570 
571 		if (fOutputBufferSize > 0) {
572 			// We still have decoded audio frames from the last
573 			// invokation, which start at fOutputBufferOffset
574 			// and are of fOutputBufferSize. Copy those into the buffer,
575 			// but not more than it can hold.
576 			int32 frames = min_c(fOutputFrameCount - *outFrameCount,
577 				fOutputBufferSize / fOutputFrameSize);
578 			if (frames == 0)
579 				debugger("fOutputBufferSize not multiple of frame size!");
580 			size_t remainingSize = frames * fOutputFrameSize;
581 			memcpy(buffer, fOutputFrame->data[0] + fOutputBufferOffset,
582 				remainingSize);
583 			fOutputBufferOffset += remainingSize;
584 			fOutputBufferSize -= remainingSize;
585 			buffer += remainingSize;
586 			*outFrameCount += frames;
587 			fStartTime += (bigtime_t)((1000000LL * frames) / fOutputFrameRate);
588 			continue;
589 		}
590 		if (fChunkBufferSize == 0) {
591 			// Time to read the next chunk buffer. We use a separate
592 			// media_header, since the chunk header may not belong to
593 			// the start of the decoded audio frames we return. For
594 			// example we may have used frames from a previous invokation,
595 			// or we may have to read several chunks until we fill up the
596 			// output buffer.
597 			media_header chunkMediaHeader;
598 			status_t err = GetNextChunk(&fChunkBuffer, &fChunkBufferSize,
599 				&chunkMediaHeader);
600 			if (err == B_LAST_BUFFER_ERROR) {
601 				TRACE_AUDIO("  Last Chunk with chunk size %ld\n",
602 					fChunkBufferSize);
603 				fChunkBufferSize = 0;
604 				return err;
605 			}
606 			if (err != B_OK || fChunkBufferSize < 0) {
607 				printf("GetNextChunk error %ld\n",fChunkBufferSize);
608 				fChunkBufferSize = 0;
609 				break;
610 			}
611 			fChunkBufferOffset = 0;
612 			fStartTime = chunkMediaHeader.start_time;
613 		}
614 
615 		fTempPacket.data = (uint8_t*)fChunkBuffer + fChunkBufferOffset;
616 		fTempPacket.size = fChunkBufferSize;
617 
618 		avcodec_get_frame_defaults(fOutputFrame);
619 		int gotFrame = 0;
620 		int usedBytes = avcodec_decode_audio4(fContext,
621 			fOutputFrame, &gotFrame, &fTempPacket);
622 		if (usedBytes < 0 && !fAudioDecodeError) {
623 			// Report failure if not done already
624 			printf("########### audio decode error, "
625 				"fChunkBufferSize %ld, fChunkBufferOffset %ld\n",
626 				fChunkBufferSize, fChunkBufferOffset);
627 			fAudioDecodeError = true;
628 		}
629 		if (usedBytes <= 0) {
630 			// Error or failure to produce decompressed output.
631 			// Skip the chunk buffer data entirely.
632 			usedBytes = fChunkBufferSize;
633 			fOutputBufferSize = 0;
634 			// Assume the audio decoded until now is broken.
635 			memset(_buffer, 0, buffer - (uint8*)_buffer);
636 		} else {
637 			// Success
638 			fAudioDecodeError = false;
639 			if (gotFrame == 1) {
640 				fOutputBufferSize = av_samples_get_buffer_size(NULL,
641 					fContext->channels, fOutputFrame->nb_samples,
642 					fContext->sample_fmt, 1);
643 				if (fOutputBufferSize < 0)
644 					fOutputBufferSize = 0;
645 			} else
646 				fOutputBufferSize = 0;
647 		}
648 //printf("  chunk size: %d, decoded: %d, used: %d\n",
649 //fTempPacket.size, decodedBytes, usedBytes);
650 
651 		fChunkBufferOffset += usedBytes;
652 		fChunkBufferSize -= usedBytes;
653 		fOutputBufferOffset = 0;
654 	}
655 	fFrame += *outFrameCount;
656 	TRACE_AUDIO("  frame count: %lld current: %lld\n", *outFrameCount, fFrame);
657 
658 	return B_OK;
659 }
660 
661 
662 /*! \brief Fills the outBuffer with an already decoded video frame.
663 
664 	Besides the main duty described above, this method also fills out the other
665 	output parameters as documented below.
666 
667 	\param outBuffer Pointer to the output buffer to copy the decoded video
668 		frame to.
669 	\param outFrameCount Pointer to the output variable to assign the number of
670 		copied video frames (usually one video frame).
671 	\param mediaHeader Pointer to the output media header that contains the
672 		decoded video frame properties.
673 	\param info TODO (not used at the moment)
674 
675 	\returns B_OK Decoding a video frame succeeded.
676 	\returns B_LAST_BUFFER_ERROR There are no more video frames available.
677 	\returns other error codes
678 */
679 status_t
680 AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount,
681 	media_header* mediaHeader, media_decode_info* info)
682 {
683 	status_t videoDecodingStatus
684 		= fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextVideoFrame();
685 
686 	if (videoDecodingStatus != B_OK)
687 		return videoDecodingStatus;
688 
689 	*outFrameCount = 1;
690 	*mediaHeader = fHeader;
691 	memcpy(outBuffer, fDecodedData, fDecodedDataSizeInBytes);
692 
693 	fDecodedDataSizeInBytes = 0;
694 
695 	return B_OK;
696 }
697 
698 
699 /*! \brief Decode next video frame
700 
701     We decode exactly one video frame into fDecodedData. To achieve this goal,
702     we might need to request several chunks of encoded data resulting in a
703     variable execution time of this function.
704 
705     The length of the decoded video frame is stored in
706     fDecodedDataSizeInBytes. If this variable is greater than zero, you can
707     assert that there is a valid video frame available in fDecodedData.
708 
709     The decoded video frame in fDecodedData has color space conversion and
710     deinterlacing already applied.
711 
712     To every decoded video frame there is a media_header populated in
713     fHeader, containing the corresponding video frame properties.
714 
715 	Normally every decoded video frame has a start_time field populated in the
716 	associated fHeader, that determines the presentation time of the frame.
717 	This relationship will only hold true, when each data chunk that is
718 	provided via GetNextChunk() contains data for exactly one encoded video
719 	frame (one complete frame) - not more and not less.
720 
721 	We can decode data chunks that contain partial video frame data, too. In
722 	that case, you cannot trust the value of the start_time field in fHeader.
723 	We simply have no logic in place to establish a meaningful relationship
724 	between an incomplete frame and the start time it should be presented.
725 	Though this	might change in the future.
726 
727 	We can decode data chunks that contain more than one video frame, too. In
728 	that case, you cannot trust the value of the start_time field in fHeader.
729 	We simply have no logic in place to track the start_time across multiple
730 	video frames. So a meaningful relationship between the 2nd, 3rd, ... frame
731 	and the start time it should be presented isn't established at the moment.
732 	Though this	might change in the future.
733 
734 	\return B_OK, when we successfully decoded one video frame
735  */
736 status_t
737 AVCodecDecoder::_DecodeNextVideoFrame()
738 {
739 	assert(fTempPacket.size >= 0);
740 
741 	while (true) {
742 		media_header chunkMediaHeader;
743 
744 		if (fTempPacket.size == 0) {
745 			// Our packet buffer is empty, so fill it now.
746 			status_t getNextChunkStatus = GetNextChunk(&fChunkBuffer,
747 				&fChunkBufferSize, &chunkMediaHeader);
748 			if (getNextChunkStatus != B_OK) {
749 				TRACE("AVCodecDecoder::_DecodeNextVideoFrame(): error from "
750 					"GetNextChunk(): %s\n", strerror(err));
751 				return getNextChunkStatus;
752 			}
753 
754 			fTempPacket.data = static_cast<uint8_t*>(const_cast<void*>(
755 				fChunkBuffer));
756 			fTempPacket.size = fChunkBufferSize;
757 
758 			fContext->reordered_opaque = chunkMediaHeader.start_time;
759 				// Let ffmpeg handle the relationship between start_time and
760 				// decoded video frame.
761 				//
762 				// Explanation:
763 				// The received chunk buffer may not contain the next video
764 				// frame to be decoded, due to frame reordering (e.g. MPEG1/2
765 				// provides encoded video frames in a different order than the
766 				// decoded video frame).
767 				//
768 				// FIXME: Research how to establish a meaningful relationship
769 				// between start_time and decoded video frame when the received
770 				// chunk buffer contains partial video frames. Maybe some data
771 				// formats contain time stamps (ake pts / dts fields) that can
772 				// be evaluated by FFMPEG. But as long as I don't have such
773 				// video data to test it, it makes no sense to implement it.
774 				//
775 				// FIXME: Implement tracking start_time of video frames
776 				// originating in data chunks that encode more than one video
777 				// frame at a time. In that case on would increment the
778 				// start_time for each consecutive frame of such a data chunk
779 				// (like it is done for audio frame decoding). But as long as
780 				// I don't have such video data to test it, it makes no sense
781 				// to implement it.
782 
783 #ifdef LOG_STREAM_TO_FILE
784 			if (sDumpedPackets < 100) {
785 				sStreamLogFile.Write(fChunkBuffer, fChunkBufferSize);
786 				printf("wrote %ld bytes\n", fChunkBufferSize);
787 				sDumpedPackets++;
788 			} else if (sDumpedPackets == 100)
789 				sStreamLogFile.Unset();
790 #endif
791 		}
792 
793 #if DO_PROFILING
794 		bigtime_t startTime = system_time();
795 #endif
796 
797 		// NOTE: In the FFMPEG 0.10.2 code example decoding_encoding.c, the
798 		// length returned by avcodec_decode_video2() is used to update the
799 		// packet buffer size (here it is fTempPacket.size). This way the
800 		// packet buffer is allowed to contain incomplete frames so we are
801 		// required to buffer the packets between different calls to
802 		// _DecodeNextVideoFrame().
803 		int gotPicture = 0;
804 		int decodedDataSizeInBytes = avcodec_decode_video2(fContext,
805 			fRawDecodedPicture, &gotPicture, &fTempPacket);
806 		if (decodedDataSizeInBytes < 0) {
807 			TRACE("[v] AVCodecDecoder: ignoring error in decoding frame %lld:"
808 				" %d\n", fFrame, len);
809 			// NOTE: An error from avcodec_decode_video2() is ignored by the
810 			// FFMPEG 0.10.2 example decoding_encoding.c. Only the packet
811 			// buffers are flushed accordingly
812 			fTempPacket.data = NULL;
813 			fTempPacket.size = 0;
814 			continue;
815 		}
816 
817 		fTempPacket.size -= decodedDataSizeInBytes;
818 		fTempPacket.data += decodedDataSizeInBytes;
819 
820 //TRACE("FFDEC: PTS = %d:%d:%d.%d - fContext->frame_number = %ld "
821 //	"fContext->frame_rate = %ld\n", (int)(fContext->pts / (60*60*1000000)),
822 //	(int)(fContext->pts / (60*1000000)), (int)(fContext->pts / (1000000)),
823 //	(int)(fContext->pts % 1000000), fContext->frame_number,
824 //	fContext->frame_rate);
825 //TRACE("FFDEC: PTS = %d:%d:%d.%d - fContext->frame_number = %ld "
826 //	"fContext->frame_rate = %ld\n",
827 //	(int)(fRawDecodedPicture->pts / (60*60*1000000)),
828 //	(int)(fRawDecodedPicture->pts / (60*1000000)),
829 //	(int)(fRawDecodedPicture->pts / (1000000)),
830 //	(int)(fRawDecodedPicture->pts % 1000000), fContext->frame_number,
831 //	fContext->frame_rate);
832 
833 		if (gotPicture) {
834 #if DO_PROFILING
835 			bigtime_t formatConversionStart = system_time();
836 #endif
837 //			TRACE("ONE FRAME OUT !! len=%d size=%ld (%s)\n", len, size,
838 //				pixfmt_to_string(fContext->pix_fmt));
839 
840 			_UpdateMediaHeaderForVideoFrame();
841 			_DeinterlaceAndColorConvertVideoFrame();
842 
843 #ifdef DEBUG
844 			dump_ffframe(fRawDecodedPicture, "ffpict");
845 //			dump_ffframe(fPostProcessedDecodedPicture, "opict");
846 #endif
847 			fFrame++;
848 
849 #if DO_PROFILING
850 			bigtime_t doneTime = system_time();
851 			decodingTime += formatConversionStart - startTime;
852 			conversionTime += doneTime - formatConversionStart;
853 			profileCounter++;
854 			if (!(fFrame % 5)) {
855 				if (info) {
856 					printf("[v] profile: d1 = %lld, d2 = %lld (%lld) required "
857 						"%Ld\n",
858 						decodingTime / profileCounter,
859 						conversionTime / profileCounter,
860 						fFrame, info->time_to_decode);
861 				} else {
862 					printf("[v] profile: d1 = %lld, d2 = %lld (%lld) required "
863 						"%Ld\n",
864 						decodingTime / profileCounter,
865 						conversionTime / profileCounter,
866 						fFrame, bigtime_t(1000000LL / fOutputFrameRate));
867 				}
868 				decodingTime = 0;
869 				conversionTime = 0;
870 				profileCounter = 0;
871 			}
872 #endif
873 			return B_OK;
874 		} else {
875 			TRACE("frame %lld - no picture yet, len: %d, chunk size: %ld\n",
876 				fFrame, len, size);
877 		}
878 	}
879 }
880 
881 
882 /*! \brief Updates relevant fields of the class member fHeader with the properties of
883 	the most recently decoded video frame.
884 
885 	It is assumed that this function is called in _DecodeNextVideoFrame() only
886 	when the following asserts hold true:
887 		1. We actually got a new picture decoded by the video decoder.
888 		2. fHeader wasn't updated for the new picture yet. You MUST call this
889 		   method only once per decoded video frame.
890 		3. This function MUST be called before
891 		   _DeinterlaceAndColorConvertVideoFrame() as the later one relys on an
892 		   updated fHeader.
893 		4. There will be at maximumn only one decoded video frame in our cache
894 		   at any single point in time. Otherwise you couldn't tell to which
895 		   cached decoded video frame the properties in fHeader relate to.
896 */
897 void
898 AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
899 {
900 	fHeader.type = B_MEDIA_RAW_VIDEO;
901 	fHeader.file_pos = 0;
902 	fHeader.orig_size = 0;
903 	fHeader.start_time = fRawDecodedPicture->reordered_opaque;
904 	fHeader.u.raw_video.field_gamma = 1.0;
905 	fHeader.u.raw_video.field_sequence = fFrame;
906 	fHeader.u.raw_video.field_number = 0;
907 	fHeader.u.raw_video.pulldown_number = 0;
908 	fHeader.u.raw_video.first_active_line = 1;
909 	fHeader.u.raw_video.line_count = fRawDecodedPicture->height;
910 
911 	TRACE("[v] start_time=%02d:%02d.%02d field_sequence=%lu\n",
912 		int((fHeader.start_time / 60000000) % 60),
913 		int((fHeader.start_time / 1000000) % 60),
914 		int((fHeader.start_time / 10000) % 100),
915 		fHeader.u.raw_video.field_sequence);
916 }
917 
918 
919 /*! \brief This function applies deinterlacing (only if needed) and color conversion
920     to the video frame in fRawDecodedPicture.
921 
922 	It is assumed that fRawDecodedPicture wasn't deinterlaced and color
923 	converted yet (otherwise this function behaves in unknown manners).
924 
925 	You should only call this function in _DecodeNextVideoFrame() when we
926 	got a new picture decoded by the video decoder and the fHeader variable was
927 	updated accordingly (@see _UpdateMediaHeaderForVideoFrame()).
928 
929 	When this function finishes the postprocessed video frame will be available
930 	in fPostProcessedDecodedPicture and fDecodedData (fDecodedDataSizeInBytes
931 	will be set accordingly).
932 */
933 void
934 AVCodecDecoder::_DeinterlaceAndColorConvertVideoFrame()
935 {
936 	int width = fOutputVideoFormat.display.line_width;
937 	int height = fOutputVideoFormat.display.line_count;
938 	AVPicture deinterlacedPicture;
939 	bool useDeinterlacedPicture = false;
940 
941 	if (fRawDecodedPicture->interlaced_frame) {
942 		AVPicture rawPicture;
943 		rawPicture.data[0] = fRawDecodedPicture->data[0];
944 		rawPicture.data[1] = fRawDecodedPicture->data[1];
945 		rawPicture.data[2] = fRawDecodedPicture->data[2];
946 		rawPicture.data[3] = fRawDecodedPicture->data[3];
947 		rawPicture.linesize[0] = fRawDecodedPicture->linesize[0];
948 		rawPicture.linesize[1] = fRawDecodedPicture->linesize[1];
949 		rawPicture.linesize[2] = fRawDecodedPicture->linesize[2];
950 		rawPicture.linesize[3] = fRawDecodedPicture->linesize[3];
951 
952 		avpicture_alloc(&deinterlacedPicture,
953 			fContext->pix_fmt, width, height);
954 
955 		if (avpicture_deinterlace(&deinterlacedPicture, &rawPicture,
956 				fContext->pix_fmt, width, height) < 0) {
957 			TRACE("[v] avpicture_deinterlace() - error\n");
958 		} else
959 			useDeinterlacedPicture = true;
960 	}
961 
962 	// Some decoders do not set pix_fmt until they have decoded 1 frame
963 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
964 	if (fSwsContext == NULL) {
965 		fSwsContext = sws_getContext(fContext->width, fContext->height,
966 			fContext->pix_fmt, fContext->width, fContext->height,
967 			colorspace_to_pixfmt(fOutputVideoFormat.display.format),
968 			SWS_FAST_BILINEAR, NULL, NULL, NULL);
969 	}
970 #else
971 	if (fFormatConversionFunc == NULL) {
972 		fFormatConversionFunc = resolve_colorspace(
973 			fOutputVideoFormat.display.format, fContext->pix_fmt,
974 			fContext->width, fContext->height);
975 	}
976 #endif
977 
978 	fDecodedDataSizeInBytes = avpicture_get_size(
979 		colorspace_to_pixfmt(fOutputVideoFormat.display.format),
980 		fContext->width, fContext->height);
981 
982 	if (fDecodedData == NULL)
983 		fDecodedData
984 			= static_cast<uint8_t*>(malloc(fDecodedDataSizeInBytes));
985 
986 	fPostProcessedDecodedPicture->data[0] = fDecodedData;
987 	fPostProcessedDecodedPicture->linesize[0]
988 		= fOutputVideoFormat.display.bytes_per_row;
989 
990 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
991 	if (fSwsContext != NULL) {
992 #else
993 	if (fFormatConversionFunc != NULL) {
994 #endif
995 		if (useDeinterlacedPicture) {
996 			AVFrame deinterlacedFrame;
997 			deinterlacedFrame.data[0] = deinterlacedPicture.data[0];
998 			deinterlacedFrame.data[1] = deinterlacedPicture.data[1];
999 			deinterlacedFrame.data[2] = deinterlacedPicture.data[2];
1000 			deinterlacedFrame.data[3] = deinterlacedPicture.data[3];
1001 			deinterlacedFrame.linesize[0]
1002 				= deinterlacedPicture.linesize[0];
1003 			deinterlacedFrame.linesize[1]
1004 				= deinterlacedPicture.linesize[1];
1005 			deinterlacedFrame.linesize[2]
1006 				= deinterlacedPicture.linesize[2];
1007 			deinterlacedFrame.linesize[3]
1008 				= deinterlacedPicture.linesize[3];
1009 
1010 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
1011 			sws_scale(fSwsContext, deinterlacedFrame.data,
1012 				deinterlacedFrame.linesize, 0, fContext->height,
1013 				fPostProcessedDecodedPicture->data,
1014 				fPostProcessedDecodedPicture->linesize);
1015 #else
1016 			(*fFormatConversionFunc)(&deinterlacedFrame,
1017 				fPostProcessedDecodedPicture, width, height);
1018 #endif
1019 		} else {
1020 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
1021 			sws_scale(fSwsContext, fRawDecodedPicture->data,
1022 				fRawDecodedPicture->linesize, 0, fContext->height,
1023 				fPostProcessedDecodedPicture->data,
1024 				fPostProcessedDecodedPicture->linesize);
1025 #else
1026 			(*fFormatConversionFunc)(fRawDecodedPicture,
1027 				fPostProcessedDecodedPicture, width, height);
1028 #endif
1029 		}
1030 	}
1031 
1032 	if (fRawDecodedPicture->interlaced_frame)
1033 		avpicture_free(&deinterlacedPicture);
1034 }
1035