xref: /haiku/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp (revision 95c9effd68127df2dce202d5e254a7c86560010a)
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  * Copyright (C) 2015 Adrien Destugues <pulkomandy@pulkomandy.tk>
9  *
10  * All rights reserved. Distributed under the terms of the MIT License.
11  */
12 
13 //! libavcodec based decoder for Haiku
14 
15 
16 #include "AVCodecDecoder.h"
17 
18 #include <new>
19 
20 #include <assert.h>
21 #include <string.h>
22 
23 #include <Bitmap.h>
24 #include <Debug.h>
25 #include <String.h>
26 
27 #include "Utilities.h"
28 
29 
30 #undef TRACE
31 //#define TRACE_AV_CODEC
32 #ifdef TRACE_AV_CODEC
33 #	define TRACE(x...)	printf(x)
34 #	define TRACE_AUDIO(x...)	printf(x)
35 #	define TRACE_VIDEO(x...)	printf(x)
36 #else
37 #	define TRACE(x...)
38 #	define TRACE_AUDIO(x...)
39 #	define TRACE_VIDEO(x...)
40 #endif
41 
42 //#define LOG_STREAM_TO_FILE
43 #ifdef LOG_STREAM_TO_FILE
44 #	include <File.h>
45 	static BFile sAudioStreamLogFile(
46 		"/boot/home/Desktop/AVCodecDebugAudioStream.raw",
47 		B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
48 	static BFile sVideoStreamLogFile(
49 		"/boot/home/Desktop/AVCodecDebugVideoStream.raw",
50 		B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
51 	static int sDumpedPackets = 0;
52 #endif
53 
54 
55 #if LIBAVCODEC_VERSION_INT > ((54 << 16) | (50 << 8))
56 typedef AVCodecID CodecID;
57 #endif
58 #if LIBAVCODEC_VERSION_INT < ((55 << 16) | (45 << 8))
59 #define av_frame_alloc avcodec_alloc_frame
60 #define av_frame_unref avcodec_get_frame_defaults
61 #define av_frame_free avcodec_free_frame
62 #endif
63 
64 
65 struct wave_format_ex {
66 	uint16 format_tag;
67 	uint16 channels;
68 	uint32 frames_per_sec;
69 	uint32 avg_bytes_per_sec;
70 	uint16 block_align;
71 	uint16 bits_per_sample;
72 	uint16 extra_size;
73 	// extra_data[extra_size]
74 } _PACKED;
75 
76 struct avformat_codec_context {
77 	int sample_rate;
78 	int channels;
79 };
80 
81 
82 // profiling related globals
83 #define DO_PROFILING 0
84 #if DO_PROFILING
85 static bigtime_t decodingTime = 0;
86 static bigtime_t conversionTime = 0;
87 static long profileCounter = 0;
88 #endif
89 
90 
91 AVCodecDecoder::AVCodecDecoder()
92 	:
93 	fHeader(),
94 	fInputFormat(),
95 	fFrame(0),
96 	fIsAudio(false),
97 	fCodec(NULL),
98 	fContext(avcodec_alloc_context3(NULL)),
99 	fResampleContext(NULL),
100 	fDecodedData(NULL),
101 	fDecodedDataSizeInBytes(0),
102 	fPostProcessedDecodedPicture(av_frame_alloc()),
103 	fRawDecodedPicture(av_frame_alloc()),
104 	fRawDecodedAudio(av_frame_alloc()),
105 
106 	fCodecInitDone(false),
107 
108 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
109 	fSwsContext(NULL),
110 #else
111 	fFormatConversionFunc(NULL),
112 #endif
113 
114 	fExtraData(NULL),
115 	fExtraDataSize(0),
116 	fBlockAlign(0),
117 
118 	fOutputColorSpace(B_NO_COLOR_SPACE),
119 	fOutputFrameCount(0),
120 	fOutputFrameRate(1.0),
121 	fOutputFrameSize(0),
122 	fInputFrameSize(0),
123 
124 	fChunkBuffer(NULL),
125 	fChunkBufferSize(0),
126 	fAudioDecodeError(false),
127 
128 	fDecodedDataBuffer(av_frame_alloc()),
129 	fDecodedDataBufferOffset(0),
130 	fDecodedDataBufferSize(0)
131 #if LIBAVCODEC_VERSION_INT >= ((57 << 16) | (0 << 8))
132 	,
133 	fBufferSinkContext(NULL),
134 	fBufferSourceContext(NULL),
135 	fFilterGraph(NULL),
136 	fFilterFrame(NULL)
137 #endif
138 {
139 	TRACE("AVCodecDecoder::AVCodecDecoder()\n");
140 
141 	system_info info;
142 	get_system_info(&info);
143 
144 	fContext->err_recognition = AV_EF_CAREFUL;
145 	fContext->error_concealment = 3;
146 	fContext->thread_count = info.cpu_count;
147 }
148 
149 
150 AVCodecDecoder::~AVCodecDecoder()
151 {
152 	TRACE("[%c] AVCodecDecoder::~AVCodecDecoder()\n", fIsAudio?('a'):('v'));
153 
154 #if DO_PROFILING
155 	if (profileCounter > 0) {
156 		printf("[%c] profile: d1 = %lld, d2 = %lld (%Ld)\n",
157 			fIsAudio?('a'):('v'), decodingTime / profileCounter,
158 			conversionTime / profileCounter, fFrame);
159 	}
160 #endif
161 
162 	if (fCodecInitDone)
163 		avcodec_close(fContext);
164 
165 	swr_free(&fResampleContext);
166 	free(fChunkBuffer);
167 	free(fDecodedData);
168 
169 	av_free(fPostProcessedDecodedPicture);
170 	av_free(fRawDecodedPicture);
171 	av_free(fRawDecodedAudio->opaque);
172 	av_free(fRawDecodedAudio);
173 	av_free(fContext);
174 	av_free(fDecodedDataBuffer);
175 
176 #if LIBAVCODEC_VERSION_INT >= ((57 << 16) | (0 << 8))
177 	av_frame_free(&fFilterFrame);
178 	avfilter_graph_free(&fFilterGraph);
179 #endif
180 
181 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
182 	if (fSwsContext != NULL)
183 		sws_freeContext(fSwsContext);
184 #endif
185 
186 	delete[] fExtraData;
187 }
188 
189 
190 void
191 AVCodecDecoder::GetCodecInfo(media_codec_info* mci)
192 {
193 	snprintf(mci->short_name, 32, "%s", fCodec->name);
194 	snprintf(mci->pretty_name, 96, "%s", fCodec->long_name);
195 	mci->id = 0;
196 	mci->sub_id = fCodec->id;
197 }
198 
199 
200 status_t
201 AVCodecDecoder::Setup(media_format* ioEncodedFormat, const void* infoBuffer,
202 	size_t infoSize)
203 {
204 	if (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO
205 		&& ioEncodedFormat->type != B_MEDIA_ENCODED_VIDEO)
206 		return B_ERROR;
207 
208 	fIsAudio = (ioEncodedFormat->type == B_MEDIA_ENCODED_AUDIO);
209 	TRACE("[%c] AVCodecDecoder::Setup()\n", fIsAudio?('a'):('v'));
210 
211 #ifdef TRACE_AV_CODEC
212 	char buffer[1024];
213 	string_for_format(*ioEncodedFormat, buffer, sizeof(buffer));
214 	TRACE("[%c]   input_format = %s\n", fIsAudio?('a'):('v'), buffer);
215 	TRACE("[%c]   infoSize = %ld\n", fIsAudio?('a'):('v'), infoSize);
216 	TRACE("[%c]   user_data_type = %08lx\n", fIsAudio?('a'):('v'),
217 		ioEncodedFormat->user_data_type);
218 	TRACE("[%c]   meta_data_size = %ld\n", fIsAudio?('a'):('v'),
219 		ioEncodedFormat->MetaDataSize());
220 #endif
221 
222 	media_format_description description;
223 	if (BMediaFormats().GetCodeFor(*ioEncodedFormat,
224 			B_MISC_FORMAT_FAMILY, &description) == B_OK) {
225 		if (description.u.misc.file_format != 'ffmp')
226 			return B_NOT_SUPPORTED;
227 		fCodec = avcodec_find_decoder(static_cast<CodecID>(
228 			description.u.misc.codec));
229 		if (fCodec == NULL) {
230 			TRACE("  unable to find the correct FFmpeg "
231 				"decoder (id = %lu)\n", description.u.misc.codec);
232 			return B_ERROR;
233 		}
234 		TRACE("  found decoder %s\n", fCodec->name);
235 
236 		const void* extraData = infoBuffer;
237 		fExtraDataSize = infoSize;
238 		if (description.family == B_WAV_FORMAT_FAMILY
239 				&& infoSize >= sizeof(wave_format_ex)) {
240 			TRACE("  trying to use wave_format_ex\n");
241 			// Special case extra data in B_WAV_FORMAT_FAMILY
242 			const wave_format_ex* waveFormatData
243 				= (const wave_format_ex*)infoBuffer;
244 
245 			size_t waveFormatSize = infoSize;
246 			if (waveFormatData != NULL && waveFormatSize > 0) {
247 				fBlockAlign = waveFormatData->block_align;
248 				TRACE("  found block align: %d\n", fBlockAlign);
249 				fExtraDataSize = waveFormatData->extra_size;
250 				// skip the wave_format_ex from the extra data.
251 				extraData = waveFormatData + 1;
252 			}
253 		} else {
254 			if (fIsAudio) {
255 				fBlockAlign
256 					= ioEncodedFormat->u.encoded_audio.output.buffer_size;
257 				TRACE("  using buffer_size as block align: %d\n",
258 					fBlockAlign);
259 			}
260 		}
261 		if (extraData != NULL && fExtraDataSize > 0) {
262 			TRACE("AVCodecDecoder: extra data size %ld\n", infoSize);
263 			delete[] fExtraData;
264 			fExtraData = new(std::nothrow) char[fExtraDataSize];
265 			if (fExtraData != NULL)
266 				memcpy(fExtraData, infoBuffer, fExtraDataSize);
267 			else
268 				fExtraDataSize = 0;
269 		}
270 
271 		fInputFormat = *ioEncodedFormat;
272 		return B_OK;
273 	} else {
274 		TRACE("AVCodecDecoder: BMediaFormats().GetCodeFor() failed.\n");
275 	}
276 
277 	printf("AVCodecDecoder::Setup failed!\n");
278 	return B_ERROR;
279 }
280 
281 
282 status_t
283 AVCodecDecoder::SeekedTo(int64 frame, bigtime_t time)
284 {
285 	status_t ret = B_OK;
286 	// Reset the FFmpeg codec to flush buffers, so we keep the sync
287 	if (fCodecInitDone) {
288 		avcodec_flush_buffers(fContext);
289 		_ResetTempPacket();
290 	}
291 
292 	// Flush internal buffers as well.
293 	free(fChunkBuffer);
294 	fChunkBuffer = NULL;
295 	fChunkBufferSize = 0;
296 	fDecodedDataBufferOffset = 0;
297 	fDecodedDataBufferSize = 0;
298 	fDecodedDataSizeInBytes = 0;
299 
300 	fFrame = frame;
301 
302 	return ret;
303 }
304 
305 
306 status_t
307 AVCodecDecoder::NegotiateOutputFormat(media_format* inOutFormat)
308 {
309 	TRACE("AVCodecDecoder::NegotiateOutputFormat() [%c] \n",
310 		fIsAudio?('a'):('v'));
311 
312 #ifdef TRACE_AV_CODEC
313 	char buffer[1024];
314 	string_for_format(*inOutFormat, buffer, sizeof(buffer));
315 	TRACE("  [%c]  requested format = %s\n", fIsAudio?('a'):('v'), buffer);
316 #endif
317 
318 	if (fIsAudio)
319 		return _NegotiateAudioOutputFormat(inOutFormat);
320 	else
321 		return _NegotiateVideoOutputFormat(inOutFormat);
322 }
323 
324 
325 status_t
326 AVCodecDecoder::Decode(void* outBuffer, int64* outFrameCount,
327 	media_header* mediaHeader, media_decode_info* info)
328 {
329 	if (!fCodecInitDone)
330 		return B_NO_INIT;
331 
332 	status_t ret;
333 	if (fIsAudio)
334 		ret = _DecodeAudio(outBuffer, outFrameCount, mediaHeader, info);
335 	else
336 		ret = _DecodeVideo(outBuffer, outFrameCount, mediaHeader, info);
337 
338 	return ret;
339 }
340 
341 
342 // #pragma mark -
343 
344 
345 void
346 AVCodecDecoder::_ResetTempPacket()
347 {
348 	av_init_packet(&fTempPacket);
349 	fTempPacket.size = 0;
350 	fTempPacket.data = NULL;
351 }
352 
353 
354 status_t
355 AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* inOutFormat)
356 {
357 	TRACE("AVCodecDecoder::_NegotiateAudioOutputFormat()\n");
358 
359 	_ApplyEssentialAudioContainerPropertiesToContext();
360 		// This makes audio formats play that encode the audio properties in
361 		// the audio container (e.g. WMA) and not in the audio frames
362 		// themself (e.g. MP3).
363 		// Note: Doing this step unconditionally is OK, because the first call
364 		// to _DecodeNextAudioFrameChunk() will update the essential audio
365 		// format properties accordingly regardless of the settings here.
366 
367 	// close any previous instance
368 	if (fCodecInitDone) {
369 		fCodecInitDone = false;
370 		avcodec_close(fContext);
371 	}
372 
373 	if (avcodec_open2(fContext, fCodec, NULL) >= 0)
374 		fCodecInitDone = true;
375 	else {
376 		TRACE("avcodec_open() failed to init codec!\n");
377 		return B_ERROR;
378 	}
379 
380 	free(fChunkBuffer);
381 	fChunkBuffer = NULL;
382 	fChunkBufferSize = 0;
383 	fAudioDecodeError = false;
384 	fDecodedDataBufferOffset = 0;
385 	fDecodedDataBufferSize = 0;
386 
387 	_ResetTempPacket();
388 
389 	status_t statusOfDecodingFirstFrameChunk = _DecodeNextAudioFrameChunk();
390 	if (statusOfDecodingFirstFrameChunk != B_OK) {
391 		TRACE("[a] decoding first audio frame chunk failed\n");
392 		return B_ERROR;
393 	}
394 
395 	media_multi_audio_format outputAudioFormat;
396 	outputAudioFormat = media_raw_audio_format::wildcard;
397 	outputAudioFormat.byte_order = B_MEDIA_HOST_ENDIAN;
398 	outputAudioFormat.frame_rate = fContext->sample_rate;
399 	outputAudioFormat.channel_count = fContext->channels;
400 	ConvertAVSampleFormatToRawAudioFormat(fContext->sample_fmt,
401 		outputAudioFormat.format);
402 	// Check that format is not still a wild card!
403 	if (outputAudioFormat.format == 0) {
404 		TRACE("  format still a wild-card, assuming B_AUDIO_SHORT.\n");
405 		outputAudioFormat.format = media_raw_audio_format::B_AUDIO_SHORT;
406 	}
407 	outputAudioFormat.buffer_size = inOutFormat->u.raw_audio.buffer_size;
408 	// Check that buffer_size has a sane value
409 	size_t sampleSize = outputAudioFormat.format
410 		& media_raw_audio_format::B_AUDIO_SIZE_MASK;
411 	if (outputAudioFormat.buffer_size == 0) {
412 		outputAudioFormat.buffer_size = 512 * sampleSize
413 			* outputAudioFormat.channel_count;
414 	}
415 
416 	inOutFormat->type = B_MEDIA_RAW_AUDIO;
417 	inOutFormat->u.raw_audio = outputAudioFormat;
418 	inOutFormat->require_flags = 0;
419 	inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
420 
421 	// Initialize variables needed to manage decoding as much audio frames as
422 	// needed to fill the buffer_size.
423 	fOutputFrameSize = sampleSize * outputAudioFormat.channel_count;
424 	fOutputFrameCount = outputAudioFormat.buffer_size / fOutputFrameSize;
425 	fOutputFrameRate = outputAudioFormat.frame_rate;
426 	if (av_sample_fmt_is_planar(fContext->sample_fmt))
427 		fInputFrameSize = sampleSize;
428 	else
429 		fInputFrameSize = fOutputFrameSize;
430 
431 	fRawDecodedAudio->opaque
432 		= av_realloc(fRawDecodedAudio->opaque, sizeof(avformat_codec_context));
433 	if (fRawDecodedAudio->opaque == NULL)
434 		return B_NO_MEMORY;
435 
436 	if (av_sample_fmt_is_planar(fContext->sample_fmt)) {
437 		fResampleContext = swr_alloc_set_opts(NULL,
438 			fContext->channel_layout, fContext->request_sample_fmt,
439 			fContext->sample_rate,
440 			fContext->channel_layout, fContext->sample_fmt, fContext->sample_rate,
441 			0, NULL);
442 		swr_init(fResampleContext);
443 	}
444 
445 	TRACE("  bit_rate = %d, sample_rate = %d, channels = %d, "
446 		"output frame size: %d, count: %ld, rate: %.2f\n",
447 		fContext->bit_rate, fContext->sample_rate, fContext->channels,
448 		fOutputFrameSize, fOutputFrameCount, fOutputFrameRate);
449 
450 	return B_OK;
451 }
452 
453 
454 status_t
455 AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat)
456 {
457 	TRACE("AVCodecDecoder::_NegotiateVideoOutputFormat()\n");
458 
459 	TRACE("  requested video format 0x%x\n",
460 		inOutFormat->u.raw_video.display.format);
461 
462 	_ApplyEssentialVideoContainerPropertiesToContext();
463 		// This makes video formats play that encode the video properties in
464 		// the video container (e.g. WMV) and not in the video frames
465 		// themself (e.g. MPEG2).
466 		// Note: Doing this step unconditionally is OK, because the first call
467 		// to _DecodeNextVideoFrame() will update the essential video format
468 		// properties accordingly regardless of the settings here.
469 
470 	bool codecCanHandleIncompleteFrames
471 		= (fCodec->capabilities & CODEC_CAP_TRUNCATED) != 0;
472 	if (codecCanHandleIncompleteFrames) {
473 		// Expect and handle video frames to be splitted across consecutive
474 		// data chunks.
475 		fContext->flags |= CODEC_FLAG_TRUNCATED;
476 	}
477 
478 	// close any previous instance
479 	if (fCodecInitDone) {
480 		fCodecInitDone = false;
481 		avcodec_close(fContext);
482 	}
483 
484 	if (avcodec_open2(fContext, fCodec, NULL) >= 0)
485 		fCodecInitDone = true;
486 	else {
487 		TRACE("avcodec_open() failed to init codec!\n");
488 		return B_ERROR;
489 	}
490 
491 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
492 	fOutputColorSpace = B_RGB32;
493 #else
494 	// Make MediaPlayer happy (if not in rgb32 screen depth and no overlay,
495 	// it will only ask for YCbCr, which DrawBitmap doesn't handle, so the
496 	// default colordepth is RGB32).
497 	if (inOutFormat->u.raw_video.display.format == B_YCbCr422)
498 		fOutputColorSpace = B_YCbCr422;
499 	else
500 		fOutputColorSpace = B_RGB32;
501 #endif
502 
503 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
504 	if (fSwsContext != NULL)
505 		sws_freeContext(fSwsContext);
506 	fSwsContext = NULL;
507 #else
508 	fFormatConversionFunc = 0;
509 #endif
510 
511 	free(fChunkBuffer);
512 	fChunkBuffer = NULL;
513 	fChunkBufferSize = 0;
514 
515 	_ResetTempPacket();
516 
517 	status_t statusOfDecodingFirstFrame = _DecodeNextVideoFrame();
518 	if (statusOfDecodingFirstFrame != B_OK) {
519 		TRACE("[v] decoding first video frame failed\n");
520 		return B_ERROR;
521 	}
522 
523 	// Note: fSwsContext / fFormatConversionFunc should have been initialized
524 	// by first call to _DecodeNextVideoFrame() above.
525 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
526 	if (fSwsContext == NULL) {
527 		TRACE("No SWS Scale context or decoder has not set the pixel format "
528 			"yet!\n");
529 	}
530 #else
531 	if (fFormatConversionFunc == NULL) {
532 		TRACE("no pixel format conversion function found or decoder has "
533 			"not set the pixel format yet!\n");
534 	}
535 #endif
536 
537 	inOutFormat->type = B_MEDIA_RAW_VIDEO;
538 	inOutFormat->require_flags = 0;
539 	inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
540 	inOutFormat->u.raw_video = fInputFormat.u.encoded_video.output;
541 	inOutFormat->u.raw_video.interlace = 1;
542 		// Progressive (non-interlaced) video frames are delivered
543 	inOutFormat->u.raw_video.first_active
544 		= fHeader.u.raw_video.first_active_line;
545 	inOutFormat->u.raw_video.last_active = fHeader.u.raw_video.line_count;
546 	inOutFormat->u.raw_video.pixel_width_aspect
547 		= fHeader.u.raw_video.pixel_width_aspect;
548 	inOutFormat->u.raw_video.pixel_height_aspect
549 		= fHeader.u.raw_video.pixel_height_aspect;
550 #if 0
551 	// This was added by Colin Günther in order to handle streams with a
552 	// variable frame rate. fOutputFrameRate is computed from the stream
553 	// time_base, but it actually assumes a timebase equal to the FPS. As far
554 	// as I can see, a stream with a variable frame rate would have a higher
555 	// resolution time_base and increment the pts (presentation time) of each
556 	// frame by a value bigger than one.
557 	//
558 	// Fixed rate stream:
559 	// time_base = 1/50s, frame PTS = 1, 2, 3... (for 50Hz)
560 	//
561 	// Variable rate stream:
562 	// time_base = 1/300s, frame PTS = 6, 12, 18, ... (for 50Hz)
563 	// time_base = 1/300s, frame PTS = 5, 10, 15, ... (for 60Hz)
564 	//
565 	// The fOutputFrameRate currently does not take this into account and
566 	// ignores the PTS. This results in playing the above sample at 300Hz
567 	// instead of 50 or 60.
568 	//
569 	// However, comparing the PTS for two consecutive implies we have already
570 	// decoded 2 frames, which may not be the case when this method is first
571 	// called.
572 	inOutFormat->u.raw_video.field_rate = fOutputFrameRate;
573 		// Was calculated by first call to _DecodeNextVideoFrame()
574 #endif
575 	inOutFormat->u.raw_video.display.format = fOutputColorSpace;
576 	inOutFormat->u.raw_video.display.line_width
577 		= fHeader.u.raw_video.display_line_width;
578 	inOutFormat->u.raw_video.display.line_count
579 		= fHeader.u.raw_video.display_line_count;
580 	inOutFormat->u.raw_video.display.bytes_per_row
581 		= fHeader.u.raw_video.bytes_per_row;
582 
583 #ifdef TRACE_AV_CODEC
584 	char buffer[1024];
585 	string_for_format(*inOutFormat, buffer, sizeof(buffer));
586 	TRACE("[v]  outFormat = %s\n", buffer);
587 	TRACE("  returned  video format 0x%x\n",
588 		inOutFormat->u.raw_video.display.format);
589 #endif
590 
591 	return B_OK;
592 }
593 
594 
595 /*! \brief Fills the outBuffer with one or more already decoded audio frames.
596 
597 	Besides the main duty described above, this method also fills out the other
598 	output parameters as documented below.
599 
600 	\param outBuffer Pointer to the output buffer to copy the decoded audio
601 		frames to.
602 	\param outFrameCount Pointer to the output variable to assign the number of
603 		copied audio frames (usually several audio frames at once).
604 	\param mediaHeader Pointer to the output media header that contains the
605 		properties of the decoded audio frame being the first in the outBuffer.
606 	\param info Specifies additional decoding parameters. (Note: unused).
607 
608 	\returns B_OK Decoding audio frames succeeded.
609 	\returns B_LAST_BUFFER_ERROR There are no more audio frames available.
610 	\returns Other error codes
611 */
612 status_t
613 AVCodecDecoder::_DecodeAudio(void* outBuffer, int64* outFrameCount,
614 	media_header* mediaHeader, media_decode_info* info)
615 {
616 	TRACE_AUDIO("AVCodecDecoder::_DecodeAudio(audio start_time %.6fs)\n",
617 		mediaHeader->start_time / 1000000.0);
618 
619 	status_t audioDecodingStatus
620 		= fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextAudioFrame();
621 
622 	if (audioDecodingStatus != B_OK)
623 		return audioDecodingStatus;
624 
625 	*outFrameCount = fDecodedDataSizeInBytes / fOutputFrameSize;
626 	*mediaHeader = fHeader;
627 	memcpy(outBuffer, fDecodedData, fDecodedDataSizeInBytes);
628 
629 	fDecodedDataSizeInBytes = 0;
630 
631 	return B_OK;
632 }
633 
634 
635 /*! \brief Fills the outBuffer with an already decoded video frame.
636 
637 	Besides the main duty described above, this method also fills out the other
638 	output parameters as documented below.
639 
640 	\param outBuffer Pointer to the output buffer to copy the decoded video
641 		frame to.
642 	\param outFrameCount Pointer to the output variable to assign the number of
643 		copied video frames (usually one video frame).
644 	\param mediaHeader Pointer to the output media header that contains the
645 		decoded video frame properties.
646 	\param info Specifies additional decoding parameters. (Note: unused).
647 
648 	\returns B_OK Decoding a video frame succeeded.
649 	\returns B_LAST_BUFFER_ERROR There are no more video frames available.
650 	\returns Other error codes
651 */
652 status_t
653 AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount,
654 	media_header* mediaHeader, media_decode_info* info)
655 {
656 	status_t videoDecodingStatus
657 		= fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextVideoFrame();
658 
659 	if (videoDecodingStatus != B_OK)
660 		return videoDecodingStatus;
661 
662 	*outFrameCount = 1;
663 	*mediaHeader = fHeader;
664 	memcpy(outBuffer, fDecodedData, mediaHeader->size_used);
665 
666 	fDecodedDataSizeInBytes = 0;
667 
668 	return B_OK;
669 }
670 
671 
672 /*!	\brief Decodes next audio frame.
673 
674 	We decode at least one audio frame into fDecodedData. To achieve this goal,
675     we might need to request several chunks of encoded data resulting in a
676     variable execution time of this function.
677 
678     The length of the decoded audio frame(s) is stored in
679     fDecodedDataSizeInBytes. If this variable is greater than zero you can
680     assert that all audio frames in fDecodedData are valid.
681 
682 	It is assumed that the number of expected audio frames is stored in
683 	fOutputFrameCount. So _DecodeNextAudioFrame() must be called only after
684 	fOutputFrameCount has been set.
685 
686 	Note: fOutputFrameCount contains the maximum number of frames a caller
687 	of BMediaDecoder::Decode() expects to receive. There is a direct
688 	relationship between fOutputFrameCount and the buffer size a caller of
689 	BMediaDecoder::Decode() will provide so we make sure to respect this limit
690 	for fDecodedDataSizeInBytes.
691 
692 	On return with status code B_OK the following conditions hold true:
693 		1. fDecodedData contains as much audio frames as the caller of
694 		   BMediaDecoder::Decode() expects.
695 		2. fDecodedData contains lesser audio frames as the caller of
696 		   BMediaDecoder::Decode() expects only when one of the following
697 		   conditions hold true:
698 		       i  No more audio frames left. Consecutive calls to
699 		          _DecodeNextAudioFrame() will then result in the return of
700 		          status code B_LAST_BUFFER_ERROR.
701 		       ii TODO: A change in the size of the audio frames.
702 		3. fHeader is populated with the audio frame properties of the first
703 		   audio frame in fDecodedData. Especially the start_time field of
704 		   fHeader relates to that first audio frame. Start times of
705 		   consecutive audio frames in fDecodedData have to be calculated
706 		   manually (using the frame rate and the frame duration) if the
707 		   caller needs them.
708 
709 	TODO: Handle change of channel_count. Such a change results in a change of
710 	the audio frame size and thus has different buffer requirements.
711 	The most sane approach for implementing this is to return the audio frames
712 	that were still decoded with the previous channel_count and inform the
713 	client of BMediaDecoder::Decode() about the change so that it can adapt to
714 	it. Furthermore we need to adapt our fDecodedData to the new buffer size
715 	requirements accordingly.
716 
717 	\returns B_OK when we successfully decoded enough audio frames
718 	\returns B_LAST_BUFFER_ERROR when there are no more audio frames available.
719 	\returns Other Errors
720 */
721 status_t
722 AVCodecDecoder::_DecodeNextAudioFrame()
723 {
724 	assert(fTempPacket.size >= 0);
725 	assert(fDecodedDataSizeInBytes == 0);
726 		// _DecodeNextAudioFrame needs to be called on empty fDecodedData only!
727 		// If this assert holds wrong we have a bug somewhere.
728 
729 	status_t resetStatus = _ResetRawDecodedAudio();
730 	if (resetStatus != B_OK)
731 		return resetStatus;
732 
733 	while (fRawDecodedAudio->nb_samples < fOutputFrameCount) {
734 		_CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow();
735 
736 		bool decodedDataBufferHasData = fDecodedDataBufferSize > 0;
737 		if (decodedDataBufferHasData) {
738 			_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes();
739 			continue;
740 		}
741 
742 		status_t decodeAudioChunkStatus = _DecodeNextAudioFrameChunk();
743 		if (decodeAudioChunkStatus != B_OK)
744 			return decodeAudioChunkStatus;
745 	}
746 
747 	fFrame += fRawDecodedAudio->nb_samples;
748 	fDecodedDataSizeInBytes = fRawDecodedAudio->linesize[0];
749 
750 	_UpdateMediaHeaderForAudioFrame();
751 
752 #ifdef DEBUG
753 	dump_ffframe_audio(fRawDecodedAudio, "ffaudi");
754 #endif
755 
756 	TRACE_AUDIO("  frame count: %ld current: %lld\n",
757 		fRawDecodedAudio->nb_samples, fFrame);
758 
759 	return B_OK;
760 }
761 
762 
763 /*!	\brief Applies all essential audio input properties to fContext that were
764 		passed to AVCodecDecoder when Setup() was called.
765 
766 	Note: This function must be called before the AVCodec is opened via
767 	avcodec_open2(). Otherwise the behaviour of FFMPEG's audio decoding
768 	function avcodec_decode_audio4() is undefined.
769 
770 	Essential properties applied from fInputFormat.u.encoded_audio:
771 		- bit_rate copied to fContext->bit_rate
772 		- frame_size copied to fContext->frame_size
773 		- output.format converted to fContext->sample_fmt
774 		- output.frame_rate copied to fContext->sample_rate
775 		- output.channel_count copied to fContext->channels
776 
777 	Other essential properties being applied:
778 		- fBlockAlign to fContext->block_align
779 		- fExtraData to fContext->extradata
780 		- fExtraDataSize to fContext->extradata_size
781 
782 	TODO: Either the following documentation section should be removed or this
783 	TODO when it is clear whether fInputFormat.MetaData() and
784 	fInputFormat.MetaDataSize() have to be applied to fContext. See the related
785 	TODO in the method implementation.
786 	Only applied when fInputFormat.MetaDataSize() is greater than zero:
787 		- fInputFormat.MetaData() to fContext->extradata
788 		- fInputFormat.MetaDataSize() to fContext->extradata_size
789 */
790 void
791 AVCodecDecoder::_ApplyEssentialAudioContainerPropertiesToContext()
792 {
793 	media_encoded_audio_format containerProperties
794 		= fInputFormat.u.encoded_audio;
795 
796 	fContext->bit_rate
797 		= static_cast<int>(containerProperties.bit_rate);
798 	fContext->frame_size
799 		= static_cast<int>(containerProperties.frame_size);
800 	ConvertRawAudioFormatToAVSampleFormat(
801 		containerProperties.output.format, fContext->sample_fmt);
802 #if LIBAVCODEC_VERSION_INT > ((52 << 16) | (114 << 8))
803 	ConvertRawAudioFormatToAVSampleFormat(
804 		containerProperties.output.format, fContext->request_sample_fmt);
805 #endif
806 	fContext->sample_rate
807 		= static_cast<int>(containerProperties.output.frame_rate);
808 	fContext->channels
809 		= static_cast<int>(containerProperties.output.channel_count);
810 	// Check that channel count is not still a wild card!
811 	if (fContext->channels == 0) {
812 		TRACE("  channel_count still a wild-card, assuming stereo.\n");
813 		fContext->channels = 2;
814 	}
815 
816 	fContext->block_align = fBlockAlign;
817 	fContext->extradata = reinterpret_cast<uint8_t*>(fExtraData);
818 	fContext->extradata_size = fExtraDataSize;
819 
820 	// TODO: This probably needs to go away, there is some misconception
821 	// about extra data / info buffer and meta data. See
822 	// Reader::GetStreamInfo(). The AVFormatReader puts extradata and
823 	// extradata_size into media_format::MetaData(), but used to ignore
824 	// the infoBuffer passed to GetStreamInfo(). I think this may be why
825 	// the code below was added.
826 	if (fInputFormat.MetaDataSize() > 0) {
827 		fContext->extradata = static_cast<uint8_t*>(
828 			const_cast<void*>(fInputFormat.MetaData()));
829 		fContext->extradata_size = fInputFormat.MetaDataSize();
830 	}
831 
832 	TRACE("  bit_rate %d, sample_rate %d, channels %d, block_align %d, "
833 		"extradata_size %d\n", fContext->bit_rate, fContext->sample_rate,
834 		fContext->channels, fContext->block_align, fContext->extradata_size);
835 }
836 
837 
838 /*!	\brief Resets important fields in fRawDecodedVideo to their default values.
839 
840 	Note: Also initializes fDecodedData if not done already.
841 
842 	\returns B_OK Resetting successfully completed.
843 	\returns B_NO_MEMORY No memory left for correct operation.
844 */
845 status_t
846 AVCodecDecoder::_ResetRawDecodedAudio()
847 {
848 	if (fDecodedData == NULL) {
849 		size_t maximumSizeOfDecodedData = fOutputFrameCount * fOutputFrameSize;
850 		fDecodedData
851 			= static_cast<uint8_t*>(malloc(maximumSizeOfDecodedData));
852 	}
853 	if (fDecodedData == NULL)
854 		return B_NO_MEMORY;
855 
856 	fRawDecodedAudio->data[0] = fDecodedData;
857 	fRawDecodedAudio->linesize[0] = 0;
858 	fRawDecodedAudio->format = AV_SAMPLE_FMT_NONE;
859 	fRawDecodedAudio->pkt_dts = AV_NOPTS_VALUE;
860 	fRawDecodedAudio->nb_samples = 0;
861 	memset(fRawDecodedAudio->opaque, 0, sizeof(avformat_codec_context));
862 
863 	return B_OK;
864 }
865 
866 
867 /*!	\brief Checks fDecodedDataBufferSize and fTempPacket for invalid values,
868 		reports them and assigns valid values.
869 
870 	Note: This method is intended to be called before any code is executed that
871 	deals with moving, loading or decoding any audio frames.
872 */
873 void
874 AVCodecDecoder::_CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow()
875 {
876 	if (fDecodedDataBufferSize < 0) {
877 		fprintf(stderr, "Decoding read past the end of the decoded data "
878 			"buffer! %" B_PRId32 "\n", fDecodedDataBufferSize);
879 		fDecodedDataBufferSize = 0;
880 	}
881 	if (fTempPacket.size < 0) {
882 		fprintf(stderr, "Decoding read past the end of the temp packet! %d\n",
883 			fTempPacket.size);
884 		fTempPacket.size = 0;
885 	}
886 }
887 
888 
889 /*!	\brief Moves audio frames from fDecodedDataBuffer to fRawDecodedAudio (and
890 		thus to fDecodedData) and updates the start times of fRawDecodedAudio,
891 		fDecodedDataBuffer and fTempPacket accordingly.
892 
893 	When moving audio frames to fRawDecodedAudio this method also makes sure
894 	that the following important fields of fRawDecodedAudio are populated and
895 	updated with correct values:
896 		- fRawDecodedAudio->data[0]: Points to first free byte of fDecodedData
897 		- fRawDecodedAudio->linesize[0]: Total size of frames in fDecodedData
898 		- fRawDecodedAudio->format: Format of first audio frame
899 		- fRawDecodedAudio->pkt_dts: Start time of first audio frame
900 		- fRawDecodedAudio->nb_samples: Number of audio frames
901 		- fRawDecodedAudio->opaque: Contains the following fields for the first
902 		  audio frame:
903 		      - channels: Channel count of first audio frame
904 		      - sample_rate: Frame rate of first audio frame
905 
906 	This function assumes to be called only when the following assumptions
907 	hold true:
908 		1. There are decoded audio frames available in fDecodedDataBuffer
909 		   meaning that fDecodedDataBufferSize is greater than zero.
910 		2. There is space left in fRawDecodedAudio to move some audio frames
911 		   in. This means that fRawDecodedAudio has lesser audio frames than
912 		   the maximum allowed (specified by fOutputFrameCount).
913 		3. The audio frame rate is known so that we can calculate the time
914 		   range (covered by the moved audio frames) to update the start times
915 		   accordingly.
916 		4. The field fRawDecodedAudio->opaque points to a memory block
917 		   representing a structure of type avformat_codec_context.
918 
919 	After this function returns the caller can safely make the following
920 	assumptions:
921 		1. The number of decoded audio frames in fDecodedDataBuffer is
922 		   decreased though it may still be greater then zero.
923 		2. The number of frames in fRawDecodedAudio has increased and all
924 		   important fields are updated (see listing above).
925 		3. Start times of fDecodedDataBuffer and fTempPacket were increased
926 		   with the time range covered by the moved audio frames.
927 
928 	Note: This function raises an exception (by calling the debugger), when
929 	fDecodedDataBufferSize is not a multiple of fOutputFrameSize.
930 */
931 void
932 AVCodecDecoder::_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes()
933 {
934 	assert(fDecodedDataBufferSize > 0);
935 	assert(fRawDecodedAudio->nb_samples < fOutputFrameCount);
936 	assert(fOutputFrameRate > 0);
937 
938 	int32 outFrames = fOutputFrameCount - fRawDecodedAudio->nb_samples;
939 	int32 inFrames = fDecodedDataBufferSize;
940 
941 	int32 frames = min_c(outFrames, inFrames);
942 	if (frames == 0)
943 		debugger("fDecodedDataBufferSize not multiple of frame size!");
944 
945 	// Some decoders do not support format conversion on themselves, or use
946 	// "planar" audio (each channel separated instead of interleaved samples).
947 	// In that case, we use swresample to convert the data
948 	if (av_sample_fmt_is_planar(fContext->sample_fmt)) {
949 #if 0
950 		const uint8_t* ptr[8];
951 		for (int i = 0; i < 8; i++) {
952 			if (fDecodedDataBuffer->data[i] == NULL)
953 				ptr[i] = NULL;
954 			else
955 				ptr[i] = fDecodedDataBuffer->data[i] + fDecodedDataBufferOffset;
956 		}
957 
958 		// When there are more input frames than space in the output buffer,
959 		// we could feed everything to swr and it would buffer the extra data.
960 		// However, there is no easy way to flush that data without feeding more
961 		// input, and it makes our timestamp computations fail.
962 		// So, we feed only as much frames as we can get out, and handle the
963 		// buffering ourselves.
964 		// TODO Ideally, we should try to size our output buffer so that it can
965 		// always hold all the output (swr provides helper functions for this)
966 		inFrames = frames;
967 		frames = swr_convert(fResampleContext, fRawDecodedAudio->data,
968 			outFrames, ptr, inFrames);
969 
970 		if (frames < 0)
971 			debugger("resampling failed");
972 #else
973 		// interleave planar audio with same format
974 		uintptr_t out = (uintptr_t)fRawDecodedAudio->data[0];
975 		int32 offset = fDecodedDataBufferOffset;
976 		for (int i = 0; i < frames; i++) {
977 			for (int j = 0; j < fContext->channels; j++) {
978 				memcpy((void*)out, fDecodedDataBuffer->data[j]
979 					+ offset, fInputFrameSize);
980 				out += fInputFrameSize;
981 			}
982 			offset += fInputFrameSize;
983 		}
984 		outFrames = frames;
985 		inFrames = frames;
986 #endif
987 	} else {
988 		memcpy(fRawDecodedAudio->data[0], fDecodedDataBuffer->data[0]
989 				+ fDecodedDataBufferOffset, frames * fOutputFrameSize);
990 		outFrames = frames;
991 		inFrames = frames;
992 	}
993 
994 	size_t remainingSize = inFrames * fInputFrameSize;
995 	size_t decodedSize = outFrames * fOutputFrameSize;
996 	fDecodedDataBufferSize -= inFrames;
997 
998 	bool firstAudioFramesCopiedToRawDecodedAudio
999 		= fRawDecodedAudio->data[0] != fDecodedData;
1000 	if (!firstAudioFramesCopiedToRawDecodedAudio) {
1001 		fRawDecodedAudio->format = fDecodedDataBuffer->format;
1002 		fRawDecodedAudio->pkt_dts = fDecodedDataBuffer->pkt_dts;
1003 
1004 		avformat_codec_context* codecContext
1005 			= static_cast<avformat_codec_context*>(fRawDecodedAudio->opaque);
1006 		codecContext->channels = fContext->channels;
1007 		codecContext->sample_rate = fContext->sample_rate;
1008 	}
1009 
1010 	fRawDecodedAudio->data[0] += decodedSize;
1011 	fRawDecodedAudio->linesize[0] += decodedSize;
1012 	fRawDecodedAudio->nb_samples += outFrames;
1013 
1014 	fDecodedDataBufferOffset += remainingSize;
1015 
1016 	// Update start times accordingly
1017 	bigtime_t framesTimeInterval = static_cast<bigtime_t>(
1018 		(1000000LL * frames) / fOutputFrameRate);
1019 	fDecodedDataBuffer->pkt_dts += framesTimeInterval;
1020 	// Start time of buffer is updated in case that it contains
1021 	// more audio frames to move.
1022 	fTempPacket.dts += framesTimeInterval;
1023 	// Start time of fTempPacket is updated in case the fTempPacket
1024 	// contains more audio frames to decode.
1025 }
1026 
1027 
1028 /*!	\brief Decodes next chunk of audio frames.
1029 
1030 	This method handles all the details of loading the input buffer
1031 	(fChunkBuffer) at the right time and of calling FFMPEG often engouh until
1032 	some audio frames have been decoded.
1033 
1034 	FFMPEG decides how much audio frames belong to a chunk. Because of that
1035 	it is very likely that _DecodeNextAudioFrameChunk has to be called several
1036 	times to decode enough audio frames to please the caller of
1037 	BMediaDecoder::Decode().
1038 
1039 	This function assumes to be called only when the following assumptions
1040 	hold true:
1041 		1. fDecodedDataBufferSize equals zero.
1042 
1043 	After this function returns successfully the caller can safely make the
1044 	following assumptions:
1045 		1. fDecodedDataBufferSize is greater than zero.
1046 		2. fDecodedDataBufferOffset is set to zero.
1047 		3. fDecodedDataBuffer contains audio frames.
1048 
1049 
1050 	\returns B_OK on successfully decoding one audio frame chunk.
1051 	\returns B_LAST_BUFFER_ERROR No more audio frame chunks available. From
1052 		this point on further calls will return this same error.
1053 	\returns B_ERROR Decoding failed
1054 */
1055 status_t
1056 AVCodecDecoder::_DecodeNextAudioFrameChunk()
1057 {
1058 	assert(fDecodedDataBufferSize == 0);
1059 
1060 	while (fDecodedDataBufferSize == 0) {
1061 		status_t loadingChunkStatus
1062 			= _LoadNextChunkIfNeededAndAssignStartTime();
1063 		if (loadingChunkStatus != B_OK)
1064 			return loadingChunkStatus;
1065 
1066 		status_t decodingStatus
1067 			= _DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer();
1068 		if (decodingStatus != B_OK) {
1069 			// Assume the audio decoded until now is broken so replace it with
1070 			// some silence.
1071 			memset(fDecodedData, 0, fRawDecodedAudio->linesize[0]);
1072 
1073 			if (!fAudioDecodeError) {
1074 				// Report failure if not done already
1075 				int32 chunkBufferOffset = fTempPacket.data - fChunkBuffer;
1076 				printf("########### audio decode error, "
1077 					"fTempPacket.size %d, fChunkBuffer data offset %" B_PRId32
1078 					"\n", fTempPacket.size, chunkBufferOffset);
1079 				fAudioDecodeError = true;
1080 			}
1081 
1082 			// Assume that next audio chunk can be decoded so keep decoding.
1083 			continue;
1084 		}
1085 
1086 		fAudioDecodeError = false;
1087 	}
1088 
1089 	return B_OK;
1090 }
1091 
1092 
1093 /*!	\brief Tries to decode at least one audio frame and store it in the
1094 		fDecodedDataBuffer.
1095 
1096 	This function assumes to be called only when the following assumptions
1097 	hold true:
1098 		1. fDecodedDataBufferSize equals zero.
1099 		2. fTempPacket.size is greater than zero.
1100 
1101 	After this function returns successfully the caller can safely make the
1102 	following assumptions:
1103 		1. fDecodedDataBufferSize is greater than zero in the common case.
1104 		   Also see "Note" below.
1105 		2. fTempPacket was updated to exclude the data chunk that was consumed
1106 		   by avcodec_decode_audio4().
1107 		3. fDecodedDataBufferOffset is set to zero.
1108 
1109 	When this function failed to decode at least one audio frame due to a
1110 	decoding error the caller can safely make the following assumptions:
1111 		1. fDecodedDataBufferSize equals zero.
1112 		2. fTempPacket.size equals zero.
1113 
1114 	Note: It is possible that there wasn't any audio frame decoded into
1115 	fDecodedDataBuffer after calling this function. This is normal and can
1116 	happen when there was either a decoding error or there is some decoding
1117 	delay in FFMPEGs audio decoder. Another call to this method is totally
1118 	safe and is even expected as long as the calling assumptions hold true.
1119 
1120 	\returns B_OK Decoding successful. fDecodedDataBuffer contains decoded
1121 		audio frames only when fDecodedDataBufferSize is greater than zero.
1122 		fDecodedDataBuffer is empty, when avcodec_decode_audio4() didn't return
1123 		audio frames due to delayed decoding or incomplete audio frames.
1124 	\returns B_ERROR Decoding failed thus fDecodedDataBuffer contains no audio
1125 		frames.
1126 */
1127 status_t
1128 AVCodecDecoder::_DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer()
1129 {
1130 	assert(fDecodedDataBufferSize == 0);
1131 
1132 	memset(fDecodedDataBuffer, 0, sizeof(AVFrame));
1133     av_frame_unref(fDecodedDataBuffer);
1134 	fDecodedDataBufferOffset = 0;
1135 	int gotAudioFrame = 0;
1136 
1137 	int encodedDataSizeInBytes = avcodec_decode_audio4(fContext,
1138 		fDecodedDataBuffer, &gotAudioFrame, &fTempPacket);
1139 	if (encodedDataSizeInBytes <= 0) {
1140 		// Error or failure to produce decompressed output.
1141 		// Skip the temp packet data entirely.
1142 		fTempPacket.size = 0;
1143 		return B_ERROR;
1144 	}
1145 
1146 	fTempPacket.data += encodedDataSizeInBytes;
1147 	fTempPacket.size -= encodedDataSizeInBytes;
1148 
1149 	bool gotNoAudioFrame = gotAudioFrame == 0;
1150 	if (gotNoAudioFrame)
1151 		return B_OK;
1152 
1153 	fDecodedDataBufferSize = fDecodedDataBuffer->nb_samples;
1154 	if (fDecodedDataBufferSize < 0)
1155 		fDecodedDataBufferSize = 0;
1156 
1157 	return B_OK;
1158 }
1159 
1160 
1161 /*! \brief Updates relevant fields of the class member fHeader with the
1162 		properties of the most recently decoded audio frame.
1163 
1164 	The following fields of fHeader are updated:
1165 		- fHeader.type
1166 		- fHeader.file_pos
1167 		- fHeader.orig_size
1168 		- fHeader.start_time
1169 		- fHeader.size_used
1170 		- fHeader.u.raw_audio.frame_rate
1171 		- fHeader.u.raw_audio.channel_count
1172 
1173 	It is assumed that this function is called only	when the following asserts
1174 	hold true:
1175 		1. We actually got a new audio frame decoded by the audio decoder.
1176 		2. fHeader wasn't updated for the new audio frame yet. You MUST call
1177 		   this method only once per decoded audio frame.
1178 		3. fRawDecodedAudio's fields relate to the first audio frame contained
1179 		   in fDecodedData. Especially the following fields are of importance:
1180 		       - fRawDecodedAudio->pkt_dts: Start time of first audio frame
1181 		       - fRawDecodedAudio->opaque: Contains the following fields for
1182 		         the first audio frame:
1183 			         - channels: Channel count of first audio frame
1184 			         - sample_rate: Frame rate of first audio frame
1185 */
1186 void
1187 AVCodecDecoder::_UpdateMediaHeaderForAudioFrame()
1188 {
1189 	fHeader.type = B_MEDIA_RAW_AUDIO;
1190 	fHeader.file_pos = 0;
1191 	fHeader.orig_size = 0;
1192 	fHeader.start_time = fRawDecodedAudio->pkt_dts;
1193 	fHeader.size_used = fRawDecodedAudio->linesize[0];
1194 
1195 	avformat_codec_context* codecContext
1196 		= static_cast<avformat_codec_context*>(fRawDecodedAudio->opaque);
1197 	fHeader.u.raw_audio.channel_count = codecContext->channels;
1198 	fHeader.u.raw_audio.frame_rate = codecContext->sample_rate;
1199 }
1200 
1201 
1202 /*! \brief Decodes next video frame.
1203 
1204     We decode exactly one video frame into fDecodedData. To achieve this goal,
1205     we might need to request several chunks of encoded data resulting in a
1206     variable execution time of this function.
1207 
1208     The length of the decoded video frame is stored in
1209     fDecodedDataSizeInBytes. If this variable is greater than zero, you can
1210     assert that there is a valid video frame available in fDecodedData.
1211 
1212     The decoded video frame in fDecodedData has color space conversion and
1213     deinterlacing already applied.
1214 
1215     To every decoded video frame there is a media_header populated in
1216     fHeader, containing the corresponding video frame properties.
1217 
1218 	Normally every decoded video frame has a start_time field populated in the
1219 	associated fHeader, that determines the presentation time of the frame.
1220 	This relationship will only hold true, when each data chunk that is
1221 	provided via GetNextChunk() contains data for exactly one encoded video
1222 	frame (one complete frame) - not more and not less.
1223 
1224 	We can decode data chunks that contain partial video frame data, too. In
1225 	that case, you cannot trust the value of the start_time field in fHeader.
1226 	We simply have no logic in place to establish a meaningful relationship
1227 	between an incomplete frame and the start time it should be presented.
1228 	Though this	might change in the future.
1229 
1230 	We can decode data chunks that contain more than one video frame, too. In
1231 	that case, you cannot trust the value of the start_time field in fHeader.
1232 	We simply have no logic in place to track the start_time across multiple
1233 	video frames. So a meaningful relationship between the 2nd, 3rd, ... frame
1234 	and the start time it should be presented isn't established at the moment.
1235 	Though this	might change in the future.
1236 
1237 	More over the fOutputFrameRate variable is updated for every decoded video
1238 	frame.
1239 
1240 	On first call the member variables fSwsContext / fFormatConversionFunc	are
1241 	initialized.
1242 
1243 	\returns B_OK when we successfully decoded one video frame
1244 	\returns B_LAST_BUFFER_ERROR when there are no more video frames available.
1245 	\returns B_NO_MEMORY when we have no memory left for correct operation.
1246 	\returns Other Errors
1247 */
1248 status_t
1249 AVCodecDecoder::_DecodeNextVideoFrame()
1250 {
1251 	while (true) {
1252 		status_t loadingChunkStatus
1253 			= _LoadNextChunkIfNeededAndAssignStartTime();
1254 		if (loadingChunkStatus == B_LAST_BUFFER_ERROR)
1255 			return _FlushOneVideoFrameFromDecoderBuffer();
1256 		if (loadingChunkStatus != B_OK) {
1257 			TRACE("AVCodecDecoder::_DecodeNextVideoFrame(): error from "
1258 				"GetNextChunk(): %s\n", strerror(loadingChunkStatus));
1259 			return loadingChunkStatus;
1260 		}
1261 
1262 #if DO_PROFILING
1263 		bigtime_t startTime = system_time();
1264 #endif
1265 
1266 		// NOTE: In the FFMPEG 0.10.2 code example decoding_encoding.c, the
1267 		// length returned by avcodec_decode_video2() is used to update the
1268 		// packet buffer size (here it is fTempPacket.size). This way the
1269 		// packet buffer is allowed to contain incomplete frames so we are
1270 		// required to buffer the packets between different calls to
1271 		// _DecodeNextVideoFrame().
1272 		int gotVideoFrame = 0;
1273 		int encodedDataSizeInBytes = avcodec_decode_video2(fContext,
1274 			fRawDecodedPicture, &gotVideoFrame, &fTempPacket);
1275 		if (encodedDataSizeInBytes < 0) {
1276 			TRACE("[v] AVCodecDecoder: ignoring error in decoding frame %lld:"
1277 				" %d\n", fFrame, encodedDataSizeInBytes);
1278 			// NOTE: An error from avcodec_decode_video2() is ignored by the
1279 			// FFMPEG 0.10.2 example decoding_encoding.c. Only the packet
1280 			// buffers are flushed accordingly
1281 			fTempPacket.data = NULL;
1282 			fTempPacket.size = 0;
1283 			continue;
1284 		}
1285 
1286 		fTempPacket.size -= encodedDataSizeInBytes;
1287 		fTempPacket.data += encodedDataSizeInBytes;
1288 
1289 		bool gotNoVideoFrame = gotVideoFrame == 0;
1290 		if (gotNoVideoFrame) {
1291 			TRACE("frame %lld - no picture yet, encodedDataSizeInBytes: %d, "
1292 				"chunk size: %ld\n", fFrame, encodedDataSizeInBytes,
1293 				fChunkBufferSize);
1294 			continue;
1295 		}
1296 
1297 #if DO_PROFILING
1298 		bigtime_t formatConversionStart = system_time();
1299 #endif
1300 
1301 		status_t handleStatus = _HandleNewVideoFrameAndUpdateSystemState();
1302 		if (handleStatus != B_OK)
1303 			return handleStatus;
1304 
1305 #if DO_PROFILING
1306 		bigtime_t doneTime = system_time();
1307 		decodingTime += formatConversionStart - startTime;
1308 		conversionTime += doneTime - formatConversionStart;
1309 		profileCounter++;
1310 		if (!(fFrame % 5)) {
1311 			printf("[v] profile: d1 = %lld, d2 = %lld (%lld) required %Ld\n",
1312 				decodingTime / profileCounter, conversionTime / profileCounter,
1313 				fFrame, bigtime_t(1000000LL / fOutputFrameRate));
1314 			decodingTime = 0;
1315 			conversionTime = 0;
1316 			profileCounter = 0;
1317 		}
1318 #endif
1319 		return B_OK;
1320 	}
1321 }
1322 
1323 
1324 /*!	\brief Applies all essential video input properties to fContext that were
1325 		passed to AVCodecDecoder when Setup() was called.
1326 
1327 	Note: This function must be called before the AVCodec is opened via
1328 	avcodec_open2(). Otherwise the behaviour of FFMPEG's video decoding
1329 	function avcodec_decode_video2() is undefined.
1330 
1331 	Essential properties applied from fInputFormat.u.encoded_video.output:
1332 		- display.line_width copied to fContext->width
1333 		- display.line_count copied to fContext->height
1334 		- pixel_width_aspect and pixel_height_aspect converted to
1335 		  fContext->sample_aspect_ratio
1336 		- field_rate converted to fContext->time_base and
1337 		  fContext->ticks_per_frame
1338 
1339 	Other essential properties being applied:
1340 		- fExtraData to fContext->extradata
1341 		- fExtraDataSize to fContext->extradata_size
1342 */
1343 void
1344 AVCodecDecoder::_ApplyEssentialVideoContainerPropertiesToContext()
1345 {
1346 	media_raw_video_format containerProperties
1347 		= fInputFormat.u.encoded_video.output;
1348 
1349 	fContext->width = containerProperties.display.line_width;
1350 	fContext->height = containerProperties.display.line_count;
1351 
1352 	if (containerProperties.pixel_width_aspect > 0
1353 		&& containerProperties.pixel_height_aspect > 0) {
1354 		ConvertVideoAspectWidthAndHeightToAVCodecContext(
1355 			containerProperties.pixel_width_aspect,
1356 			containerProperties.pixel_height_aspect, *fContext);
1357 	}
1358 
1359 	if (containerProperties.field_rate > 0.0) {
1360 		ConvertVideoFrameRateToAVCodecContext(containerProperties.field_rate,
1361 			*fContext);
1362 	}
1363 
1364 	fContext->extradata = reinterpret_cast<uint8_t*>(fExtraData);
1365 	fContext->extradata_size = fExtraDataSize;
1366 }
1367 
1368 
1369 /*! \brief Loads the next  chunk into fChunkBuffer and assigns it (including
1370 		the start time) to fTempPacket but only if fTempPacket is empty.
1371 
1372 	\returns B_OK
1373 		1. meaning: Next chunk is loaded.
1374 		2. meaning: No need to load and assign anything. Proceed as usual.
1375 	\returns B_LAST_BUFFER_ERROR No more chunks available. fChunkBuffer	and
1376 		fTempPacket are left untouched.
1377 	\returns Other errors Caller should bail out because fChunkBuffer and
1378 		fTempPacket are in unknown states. Normal operation cannot be
1379 		guaranteed.
1380 */
1381 status_t
1382 AVCodecDecoder::_LoadNextChunkIfNeededAndAssignStartTime()
1383 {
1384 	if (fTempPacket.size > 0)
1385 		return B_OK;
1386 
1387 	const void* chunkBuffer = NULL;
1388 	size_t chunkBufferSize = 0;
1389 		// In the case that GetNextChunk() returns an error fChunkBufferSize
1390 		// should be left untouched.
1391 	media_header chunkMediaHeader;
1392 
1393 	status_t getNextChunkStatus = GetNextChunk(&chunkBuffer, &chunkBufferSize,
1394 		&chunkMediaHeader);
1395 	if (getNextChunkStatus != B_OK)
1396 		return getNextChunkStatus;
1397 
1398 	status_t chunkBufferPaddingStatus
1399 		= _CopyChunkToChunkBufferAndAddPadding(chunkBuffer, chunkBufferSize);
1400 	if (chunkBufferPaddingStatus != B_OK)
1401 		return chunkBufferPaddingStatus;
1402 
1403 	fTempPacket.data = fChunkBuffer;
1404 	fTempPacket.size = fChunkBufferSize;
1405 	fTempPacket.dts = chunkMediaHeader.start_time;
1406 		// Let FFMPEG handle the correct relationship between start_time and
1407 		// decoded a/v frame. By doing so we are simply copying the way how it
1408 		// is implemented in ffplay.c for video frames (for audio frames it
1409 		// works, too, but isn't used by ffplay.c).
1410 		// \see http://git.videolan.org/?p=ffmpeg.git;a=blob;f=ffplay.c;h=09623db374e5289ed20b7cc28c262c4375a8b2e4;hb=9153b33a742c4e2a85ff6230aea0e75f5a8b26c2#l1502
1411 		//
1412 		// FIXME: Research how to establish a meaningful relationship between
1413 		// start_time and decoded a/v frame when the received chunk buffer
1414 		// contains partial a/v frames. Maybe some data formats do contain time
1415 		// stamps (ake pts / dts fields) that can be evaluated by FFMPEG. But
1416 		// as long as I don't have such video data to test it, it makes no
1417 		// sense trying to implement it.
1418 		//
1419 		// FIXME: Implement tracking start_time of video frames originating in
1420 		// data chunks that encode more than one video frame at a time. In that
1421 		// case on would increment the start_time for each consecutive frame of
1422 		// such a data chunk (like it is done for audio frame decoding). But as
1423 		// long as I don't have such video data to test it, it makes no sense
1424 		// to implement it.
1425 
1426 #ifdef LOG_STREAM_TO_FILE
1427 	BFile* logFile = fIsAudio ? &sAudioStreamLogFile : &sVideoStreamLogFile;
1428 	if (sDumpedPackets < 100) {
1429 		logFile->Write(chunkBuffer, fChunkBufferSize);
1430 		printf("wrote %ld bytes\n", fChunkBufferSize);
1431 		sDumpedPackets++;
1432 	} else if (sDumpedPackets == 100)
1433 		logFile->Unset();
1434 #endif
1435 
1436 	return B_OK;
1437 }
1438 
1439 
1440 /*! \brief Copies a chunk into fChunkBuffer and adds a "safety net" of
1441 		additional memory as required by FFMPEG for input buffers to video
1442 		decoders.
1443 
1444 	This is needed so that some decoders can read safely a predefined number of
1445 	bytes at a time for performance optimization purposes.
1446 
1447 	The additional memory has a size of FF_INPUT_BUFFER_PADDING_SIZE as defined
1448 	in avcodec.h.
1449 
1450 	Ownership of fChunkBuffer memory is with the class so it needs to be freed
1451 	at the right times (on destruction, on seeking).
1452 
1453 	Also update fChunkBufferSize to reflect the size of the contained data
1454 	(leaving out the padding).
1455 
1456 	\param chunk The chunk to copy.
1457 	\param chunkSize Size of the chunk in bytes
1458 
1459 	\returns B_OK Padding was successful. You are responsible for releasing the
1460 		allocated memory. fChunkBufferSize is set to chunkSize.
1461 	\returns B_NO_MEMORY Padding failed.
1462 		fChunkBuffer is set to NULL making it safe to call free() on it.
1463 		fChunkBufferSize is set to 0 to reflect the size of fChunkBuffer.
1464 */
1465 status_t
1466 AVCodecDecoder::_CopyChunkToChunkBufferAndAddPadding(const void* chunk,
1467 	size_t chunkSize)
1468 {
1469 	fChunkBuffer = static_cast<uint8_t*>(realloc(fChunkBuffer,
1470 		chunkSize + FF_INPUT_BUFFER_PADDING_SIZE));
1471 	if (fChunkBuffer == NULL) {
1472 		fChunkBufferSize = 0;
1473 		return B_NO_MEMORY;
1474 	}
1475 
1476 	memcpy(fChunkBuffer, chunk, chunkSize);
1477 	memset(fChunkBuffer + chunkSize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
1478 		// Establish safety net, by zero'ing the padding area.
1479 
1480 	fChunkBufferSize = chunkSize;
1481 
1482 	return B_OK;
1483 }
1484 
1485 
1486 /*! \brief Executes all steps needed for a freshly decoded video frame.
1487 
1488 	\see _UpdateMediaHeaderForVideoFrame() and
1489 	\see _DeinterlaceAndColorConvertVideoFrame() for when you are allowed to
1490 	call this method.
1491 
1492 	\returns B_OK when video frame was handled successfully
1493 	\returnb B_NO_MEMORY when no memory is left for correct operation.
1494 */
1495 status_t
1496 AVCodecDecoder::_HandleNewVideoFrameAndUpdateSystemState()
1497 {
1498 	_UpdateMediaHeaderForVideoFrame();
1499 	status_t postProcessStatus = _DeinterlaceAndColorConvertVideoFrame();
1500 	if (postProcessStatus != B_OK)
1501 		return postProcessStatus;
1502 
1503 	ConvertAVCodecContextToVideoFrameRate(*fContext, fOutputFrameRate);
1504 
1505 #ifdef DEBUG
1506 	dump_ffframe_video(fRawDecodedPicture, "ffpict");
1507 #endif
1508 
1509 	fFrame++;
1510 
1511 	return B_OK;
1512 }
1513 
1514 
1515 /*! \brief Flushes one video frame - if any - still buffered by the decoder.
1516 
1517 	Some FFMPEG decoder are buffering video frames. To retrieve those buffered
1518 	frames the decoder needs to be told so.
1519 
1520 	The intended use of this method is to call it, once there are no more data
1521 	chunks for decoding left. Reframed in other words: Once GetNextChunk()
1522 	returns with status B_LAST_BUFFER_ERROR it is time to start flushing.
1523 
1524 	\returns B_OK Retrieved one video frame, handled it accordingly and updated
1525 		the system state accordingly.
1526 		There maybe more video frames left. So it is valid for the client of
1527 		AVCodecDecoder to call it one more time.
1528 
1529 	\returns B_LAST_BUFFER_ERROR No video frame left.
1530 		The client of the AVCodecDecoder should stop calling it now.
1531 
1532 	\returns B_NO_MEMORY No memory left for correct operation.
1533 */
1534 status_t
1535 AVCodecDecoder::_FlushOneVideoFrameFromDecoderBuffer()
1536 {
1537 	// Create empty fTempPacket to tell the video decoder it is time to flush
1538 	fTempPacket.data = NULL;
1539 	fTempPacket.size = 0;
1540 
1541 	int gotVideoFrame = 0;
1542 	avcodec_decode_video2(fContext,	fRawDecodedPicture, &gotVideoFrame,
1543 		&fTempPacket);
1544 		// We are only interested in complete frames now, so ignore the return
1545 		// value.
1546 
1547 	bool gotNoVideoFrame = gotVideoFrame == 0;
1548 	if (gotNoVideoFrame) {
1549 		// video buffer is flushed successfully
1550 		return B_LAST_BUFFER_ERROR;
1551 	}
1552 
1553 	return _HandleNewVideoFrameAndUpdateSystemState();
1554 }
1555 
1556 
1557 /*! \brief Updates relevant fields of the class member fHeader with the
1558 		properties of the most recently decoded video frame.
1559 
1560 	It is assumed that this function is called only	when the following asserts
1561 	hold true:
1562 		1. We actually got a new picture decoded by the video decoder.
1563 		2. fHeader wasn't updated for the new picture yet. You MUST call this
1564 		   method only once per decoded video frame.
1565 		3. This function MUST be called after
1566 		   _DeinterlaceAndColorConvertVideoFrame() as it relys on an updated
1567 		    fDecodedDataSizeInBytes.
1568 		4. There will be at maximumn only one decoded video frame in our cache
1569 		   at any single point in time. Otherwise you couldn't tell to which
1570 		   cached decoded video frame the properties in fHeader relate to.
1571 		5. AVCodecContext is still valid for this video frame (This is the case
1572 		   when this function is called after avcodec_decode_video2() and
1573 		   before the next call to avcodec_decode_video2().
1574 */
1575 void
1576 AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
1577 {
1578 	fHeader.type = B_MEDIA_RAW_VIDEO;
1579 	fHeader.file_pos = 0;
1580 	fHeader.orig_size = 0;
1581 	fHeader.start_time = fRawDecodedPicture->pkt_dts;
1582 	fHeader.size_used = avpicture_get_size(
1583 		colorspace_to_pixfmt(fOutputColorSpace), fRawDecodedPicture->width,
1584 		fRawDecodedPicture->height);
1585 	fHeader.u.raw_video.display_line_width = fRawDecodedPicture->width;
1586 	fHeader.u.raw_video.display_line_count = fRawDecodedPicture->height;
1587 	fHeader.u.raw_video.bytes_per_row
1588 		= CalculateBytesPerRowWithColorSpaceAndVideoWidth(fOutputColorSpace,
1589 			fRawDecodedPicture->width);
1590 	fHeader.u.raw_video.field_gamma = 1.0;
1591 	fHeader.u.raw_video.field_sequence = fFrame;
1592 	fHeader.u.raw_video.field_number = 0;
1593 	fHeader.u.raw_video.pulldown_number = 0;
1594 	fHeader.u.raw_video.first_active_line = 1;
1595 	fHeader.u.raw_video.line_count = fRawDecodedPicture->height;
1596 
1597 	ConvertAVCodecContextToVideoAspectWidthAndHeight(*fContext,
1598 		fHeader.u.raw_video.pixel_width_aspect,
1599 		fHeader.u.raw_video.pixel_height_aspect);
1600 
1601 	TRACE("[v] start_time=%02d:%02d.%02d field_sequence=%lu\n",
1602 		int((fHeader.start_time / 60000000) % 60),
1603 		int((fHeader.start_time / 1000000) % 60),
1604 		int((fHeader.start_time / 10000) % 100),
1605 		fHeader.u.raw_video.field_sequence);
1606 }
1607 
1608 
1609 /*! \brief This function applies deinterlacing (only if needed) and color
1610 	conversion to the video frame in fRawDecodedPicture.
1611 
1612 	It is assumed that fRawDecodedPicture wasn't deinterlaced and color
1613 	converted yet (otherwise this function behaves in unknown manners).
1614 
1615 	This function MUST be called after _UpdateMediaHeaderForVideoFrame() as it
1616 	relys on the fHeader.size_used and fHeader.u.raw_video.bytes_per_row fields
1617 	for correct operation
1618 
1619 	You should only call this function when you	got a new picture decoded by
1620 	the video decoder.
1621 
1622 	When this function finishes the postprocessed video frame will be available
1623 	in fPostProcessedDecodedPicture and fDecodedData (fDecodedDataSizeInBytes
1624 	will be set accordingly).
1625 
1626 	\returns B_OK video frame successfully deinterlaced and color converted.
1627 	\returns B_NO_MEMORY Not enough memory available for correct operation.
1628 */
1629 status_t
1630 AVCodecDecoder::_DeinterlaceAndColorConvertVideoFrame()
1631 {
1632 	int displayWidth = fRawDecodedPicture->width;
1633 	int displayHeight = fRawDecodedPicture->height;
1634 	AVPicture deinterlacedPicture;
1635 	bool useDeinterlacedPicture = false;
1636 
1637 	if (fRawDecodedPicture->interlaced_frame) {
1638 		AVPicture rawPicture;
1639 		rawPicture.data[0] = fRawDecodedPicture->data[0];
1640 		rawPicture.data[1] = fRawDecodedPicture->data[1];
1641 		rawPicture.data[2] = fRawDecodedPicture->data[2];
1642 		rawPicture.data[3] = fRawDecodedPicture->data[3];
1643 		rawPicture.linesize[0] = fRawDecodedPicture->linesize[0];
1644 		rawPicture.linesize[1] = fRawDecodedPicture->linesize[1];
1645 		rawPicture.linesize[2] = fRawDecodedPicture->linesize[2];
1646 		rawPicture.linesize[3] = fRawDecodedPicture->linesize[3];
1647 
1648 		avpicture_alloc(&deinterlacedPicture, fContext->pix_fmt, displayWidth,
1649 			displayHeight);
1650 
1651 #if LIBAVCODEC_VERSION_INT < ((57 << 16) | (0 << 8))
1652 		if (avpicture_deinterlace(&deinterlacedPicture, &rawPicture,
1653 				fContext->pix_fmt, displayWidth, displayHeight) < 0) {
1654 			TRACE("[v] avpicture_deinterlace() - error\n");
1655 		} else
1656 			useDeinterlacedPicture = true;
1657 #else
1658 		// deinterlace implemented using avfilter
1659 		_ProcessFilterGraph(&deinterlacedPicture, &rawPicture,
1660 				fContext->pix_fmt, displayWidth, displayHeight);
1661 		useDeinterlacedPicture = true;
1662 #endif
1663 	}
1664 
1665 	// Some decoders do not set pix_fmt until they have decoded 1 frame
1666 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
1667 	if (fSwsContext == NULL) {
1668 		fSwsContext = sws_getContext(displayWidth, displayHeight,
1669 			fContext->pix_fmt, displayWidth, displayHeight,
1670 			colorspace_to_pixfmt(fOutputColorSpace),
1671 			SWS_FAST_BILINEAR, NULL, NULL, NULL);
1672 	}
1673 #else
1674 	if (fFormatConversionFunc == NULL) {
1675 		fFormatConversionFunc = resolve_colorspace(fOutputColorSpace,
1676 			fContext->pix_fmt, displayWidth, displayHeight);
1677 	}
1678 #endif
1679 
1680 	fDecodedDataSizeInBytes = fHeader.size_used;
1681 
1682 	if (fDecodedData == NULL) {
1683 		const size_t kOptimalAlignmentForColorConversion = 32;
1684 		posix_memalign(reinterpret_cast<void**>(&fDecodedData),
1685 			kOptimalAlignmentForColorConversion, fDecodedDataSizeInBytes);
1686 	}
1687 	if (fDecodedData == NULL)
1688 		return B_NO_MEMORY;
1689 
1690 	fPostProcessedDecodedPicture->data[0] = fDecodedData;
1691 	fPostProcessedDecodedPicture->linesize[0]
1692 		= fHeader.u.raw_video.bytes_per_row;
1693 
1694 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
1695 	if (fSwsContext != NULL) {
1696 #else
1697 	if (fFormatConversionFunc != NULL) {
1698 #endif
1699 		if (useDeinterlacedPicture) {
1700 			AVFrame deinterlacedFrame;
1701 			deinterlacedFrame.data[0] = deinterlacedPicture.data[0];
1702 			deinterlacedFrame.data[1] = deinterlacedPicture.data[1];
1703 			deinterlacedFrame.data[2] = deinterlacedPicture.data[2];
1704 			deinterlacedFrame.data[3] = deinterlacedPicture.data[3];
1705 			deinterlacedFrame.linesize[0]
1706 				= deinterlacedPicture.linesize[0];
1707 			deinterlacedFrame.linesize[1]
1708 				= deinterlacedPicture.linesize[1];
1709 			deinterlacedFrame.linesize[2]
1710 				= deinterlacedPicture.linesize[2];
1711 			deinterlacedFrame.linesize[3]
1712 				= deinterlacedPicture.linesize[3];
1713 
1714 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
1715 			sws_scale(fSwsContext, deinterlacedFrame.data,
1716 				deinterlacedFrame.linesize, 0, displayHeight,
1717 				fPostProcessedDecodedPicture->data,
1718 				fPostProcessedDecodedPicture->linesize);
1719 #else
1720 			(*fFormatConversionFunc)(&deinterlacedFrame,
1721 				fPostProcessedDecodedPicture, displayWidth, displayHeight);
1722 #endif
1723 		} else {
1724 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
1725 			sws_scale(fSwsContext, fRawDecodedPicture->data,
1726 				fRawDecodedPicture->linesize, 0, displayHeight,
1727 				fPostProcessedDecodedPicture->data,
1728 				fPostProcessedDecodedPicture->linesize);
1729 #else
1730 			(*fFormatConversionFunc)(fRawDecodedPicture,
1731 				fPostProcessedDecodedPicture, displayWidth, displayHeight);
1732 #endif
1733 		}
1734 	}
1735 
1736 	if (fRawDecodedPicture->interlaced_frame)
1737 		avpicture_free(&deinterlacedPicture);
1738 
1739 	return B_OK;
1740 }
1741 
1742 
1743 #if LIBAVCODEC_VERSION_INT >= ((57 << 16) | (0 << 8))
1744 
1745 /*! \brief Init the deinterlace filter graph.
1746 
1747 	\returns B_OK the filter graph could be built.
1748 	\returns B_BAD_VALUE something was wrong with building the graph.
1749 */
1750 status_t
1751 AVCodecDecoder::_InitFilterGraph(enum AVPixelFormat pixfmt, int32 width,
1752 	int32 height)
1753 {
1754 	if (fFilterGraph != NULL) {
1755 		av_frame_free(&fFilterFrame);
1756 		avfilter_graph_free(&fFilterGraph);
1757 	}
1758 
1759 	fFilterGraph = avfilter_graph_alloc();
1760 
1761 	BString arguments;
1762 	arguments.SetToFormat("buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:"
1763 		"pixel_aspect=0/1[in];[in]yadif[out];[out]buffersink", width, height,
1764 		pixfmt);
1765 	AVFilterInOut* inputs = NULL;
1766 	AVFilterInOut* outputs = NULL;
1767 	TRACE("[v] _InitFilterGraph(): %s\n", arguments.String());
1768 	int ret = avfilter_graph_parse2(fFilterGraph, arguments.String(), &inputs,
1769 		&outputs);
1770 	if (ret < 0) {
1771 		fprintf(stderr, "avfilter_graph_parse2() failed\n");
1772 		return B_BAD_VALUE;
1773 	}
1774 
1775 	ret = avfilter_graph_config(fFilterGraph, NULL);
1776 	if (ret < 0) {
1777 		fprintf(stderr, "avfilter_graph_config() failed\n");
1778 		return B_BAD_VALUE;
1779 	}
1780 
1781 	fBufferSourceContext = avfilter_graph_get_filter(fFilterGraph,
1782 		"Parsed_buffer_0");
1783 	fBufferSinkContext = avfilter_graph_get_filter(fFilterGraph,
1784 		"Parsed_buffersink_2");
1785 	if (fBufferSourceContext == NULL || fBufferSinkContext == NULL) {
1786 		fprintf(stderr, "avfilter_graph_get_filter() failed\n");
1787 		return B_BAD_VALUE;
1788 	}
1789 	fFilterFrame = av_frame_alloc();
1790 	fLastWidth = width;
1791 	fLastHeight = height;
1792 	fLastPixfmt = pixfmt;
1793 
1794 	return B_OK;
1795 }
1796 
1797 
1798 /*! \brief Process an AVPicture with the deinterlace filter graph.
1799 
1800     We decode exactly one video frame into dst.
1801 	Equivalent function for avpicture_deinterlace() from version 2.x.
1802 
1803 	\returns B_OK video frame successfully deinterlaced.
1804 	\returns B_BAD_DATA No frame could be output.
1805 	\returns B_NO_MEMORY Not enough memory available for correct operation.
1806 */
1807 status_t
1808 AVCodecDecoder::_ProcessFilterGraph(AVPicture *dst, const AVPicture *src,
1809 	enum AVPixelFormat pixfmt, int32 width, int32 height)
1810 {
1811 	if (fFilterGraph == NULL || width != fLastWidth
1812 		|| height != fLastHeight || pixfmt != fLastPixfmt) {
1813 
1814 		status_t err = _InitFilterGraph(pixfmt, width, height);
1815 		if (err != B_OK)
1816 			return err;
1817 	}
1818 
1819 	memcpy(fFilterFrame->data, src->data, sizeof(src->data));
1820 	memcpy(fFilterFrame->linesize, src->linesize, sizeof(src->linesize));
1821 	fFilterFrame->width = width;
1822 	fFilterFrame->height = height;
1823 	fFilterFrame->format = pixfmt;
1824 
1825 	int ret = av_buffersrc_add_frame(fBufferSourceContext, fFilterFrame);
1826 	if (ret < 0)
1827 		return B_NO_MEMORY;
1828 
1829 	ret = av_buffersink_get_frame(fBufferSinkContext, fFilterFrame);
1830 	if (ret < 0)
1831 		return B_BAD_DATA;
1832 
1833 	av_picture_copy(dst, (const AVPicture *)fFilterFrame, pixfmt, width,
1834 		height);
1835 	av_frame_unref(fFilterFrame);
1836 	return B_OK;
1837 }
1838 #endif
1839