xref: /haiku/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h (revision 8a822b7c859482b7391ab7bad9423b6bbef2b237)
127f6fb6cSStephan Aßmus /*
227f6fb6cSStephan Aßmus  * Copyright (C) 2001 Carlos Hasan.
327f6fb6cSStephan Aßmus  * Copyright (C) 2001 François Revol.
427f6fb6cSStephan Aßmus  * Copyright (C) 2001 Axel Dörfler.
527f6fb6cSStephan Aßmus  * Copyright (C) 2004 Marcus Overhagen.
627f6fb6cSStephan Aßmus  * Copyright (C) 2009 Stephan Aßmus <superstippi@gmx.de>.
727f6fb6cSStephan Aßmus  *
827f6fb6cSStephan Aßmus  * All rights reserved. Distributed under the terms of the MIT License.
927f6fb6cSStephan Aßmus  */
1027f6fb6cSStephan Aßmus #ifndef AVCODEC_DECODER_H
1127f6fb6cSStephan Aßmus #define AVCODEC_DECODER_H
1227f6fb6cSStephan Aßmus 
1327f6fb6cSStephan Aßmus //! libavcodec based decoder for Haiku
1427f6fb6cSStephan Aßmus 
1527f6fb6cSStephan Aßmus #include <MediaFormats.h>
1627f6fb6cSStephan Aßmus 
17dfddb9f4SStephan Aßmus extern "C" {
18c1e73fbfSStephan Aßmus 	#include "avcodec.h"
19946163e3SJérôme Duval 	#include "swscale.h"
20dfddb9f4SStephan Aßmus }
21dfddb9f4SStephan Aßmus 
2227f6fb6cSStephan Aßmus #include "DecoderPlugin.h"
2327f6fb6cSStephan Aßmus #include "ReaderPlugin.h"
2427f6fb6cSStephan Aßmus 
2527f6fb6cSStephan Aßmus #include "CodecTable.h"
26c1e73fbfSStephan Aßmus #include "gfx_util.h"
2727f6fb6cSStephan Aßmus 
2827f6fb6cSStephan Aßmus 
29946163e3SJérôme Duval #ifdef __x86_64
30946163e3SJérôme Duval #define USE_SWS_FOR_COLOR_SPACE_CONVERSION 1
31946163e3SJérôme Duval #else
32946163e3SJérôme Duval #define USE_SWS_FOR_COLOR_SPACE_CONVERSION 0
33946163e3SJérôme Duval // NOTE: David's color space conversion is much faster than the FFmpeg
34946163e3SJérôme Duval // version. Perhaps the SWS code can be used for unsupported conversions?
35946163e3SJérôme Duval // Otherwise the alternative code could simply be removed from this file.
36946163e3SJérôme Duval #endif
37946163e3SJérôme Duval 
38946163e3SJérôme Duval 
3927f6fb6cSStephan Aßmus class AVCodecDecoder : public Decoder {
4027f6fb6cSStephan Aßmus public:
4127f6fb6cSStephan Aßmus 						AVCodecDecoder();
4227f6fb6cSStephan Aßmus 
4327f6fb6cSStephan Aßmus 	virtual				~AVCodecDecoder();
4427f6fb6cSStephan Aßmus 
4527f6fb6cSStephan Aßmus 	virtual	void		GetCodecInfo(media_codec_info* mci);
4627f6fb6cSStephan Aßmus 
4727f6fb6cSStephan Aßmus 	virtual	status_t	Setup(media_format* ioEncodedFormat,
4827f6fb6cSStephan Aßmus 							const void* infoBuffer, size_t infoSize);
4927f6fb6cSStephan Aßmus 
506defcb6cSColin Günther 	virtual	status_t	NegotiateOutputFormat(media_format* inOutFormat);
5127f6fb6cSStephan Aßmus 
5227f6fb6cSStephan Aßmus 	virtual	status_t	Decode(void* outBuffer, int64* outFrameCount,
5327f6fb6cSStephan Aßmus 							media_header* mediaHeader,
5427f6fb6cSStephan Aßmus 							media_decode_info* info);
5527f6fb6cSStephan Aßmus 
562e54e93fSStephan Aßmus 	virtual	status_t	SeekedTo(int64 trame, bigtime_t time);
5727f6fb6cSStephan Aßmus 
5827f6fb6cSStephan Aßmus 
5912a9eb5dSStephan Aßmus private:
60f345d827SColin Günther 			void		_ResetTempPacket();
61f345d827SColin Günther 
626defcb6cSColin Günther 			status_t	_NegotiateAudioOutputFormat(media_format* inOutFormat);
6312a9eb5dSStephan Aßmus 
646defcb6cSColin Günther 			status_t	_NegotiateVideoOutputFormat(media_format* inOutFormat);
6512a9eb5dSStephan Aßmus 
666defcb6cSColin Günther 			status_t	_DecodeAudio(void* outBuffer, int64* outFrameCount,
6712a9eb5dSStephan Aßmus 							media_header* mediaHeader,
6812a9eb5dSStephan Aßmus 							media_decode_info* info);
6912a9eb5dSStephan Aßmus 
706defcb6cSColin Günther 			status_t	_DecodeVideo(void* outBuffer, int64* outFrameCount,
7112a9eb5dSStephan Aßmus 							media_header* mediaHeader,
7212a9eb5dSStephan Aßmus 							media_decode_info* info);
733c6f9c10SColin Günther 
7485371234SColin Günther 			status_t	_DecodeNextAudioFrame();
753c68ae7cSColin Günther 			void		_ApplyEssentialAudioContainerPropertiesToContext();
764ff7c2ccSColin Günther 			status_t	_ResetRawDecodedAudio();
771b8bbb50SColin Günther 			void		_CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow();
78ca5c686dSColin Günther 			void		_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes();
791a963de4SColin Günther 			status_t	_DecodeNextAudioFrameChunk();
80463f3402SColin Günther 			status_t	_DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer();
813c6f9c10SColin Günther 			void		_UpdateMediaHeaderForAudioFrame();
823c6f9c10SColin Günther 
83172c55faSColin Günther 			status_t	_DecodeNextVideoFrame();
8475bd62e8SColin Günther 			void		_ApplyEssentialVideoContainerPropertiesToContext();
85f7f67022SColin Günther 			status_t	_LoadNextChunkIfNeededAndAssignStartTime();
86f7f67022SColin Günther 			status_t	_CopyChunkToChunkBufferAndAddPadding(const void* chunk,
87f7f67022SColin Günther 							size_t chunkSize);
88fe1eb3c1SColin Günther 			status_t	_HandleNewVideoFrameAndUpdateSystemState();
89a335ec82SColin Günther 			status_t	_FlushOneVideoFrameFromDecoderBuffer();
90254a5340SColin Günther 			void		_UpdateMediaHeaderForVideoFrame();
91fe1eb3c1SColin Günther 			status_t	_DeinterlaceAndColorConvertVideoFrame();
92172c55faSColin Günther 
9312a9eb5dSStephan Aßmus 
9427f6fb6cSStephan Aßmus 			media_header		fHeader;
95254a5340SColin Günther 									// Contains the properties of the current
96254a5340SColin Günther 									// decoded audio / video frame
97254a5340SColin Günther 
9827f6fb6cSStephan Aßmus 			media_format		fInputFormat;
9927f6fb6cSStephan Aßmus 
10027f6fb6cSStephan Aßmus 			int64				fFrame;
10112a9eb5dSStephan Aßmus 			bool				fIsAudio;
10227f6fb6cSStephan Aßmus 
10312a9eb5dSStephan Aßmus 			// FFmpeg related members
10427f6fb6cSStephan Aßmus 			AVCodec*			fCodec;
10512a9eb5dSStephan Aßmus 			AVCodecContext*		fContext;
106172c55faSColin Günther 			uint8_t*			fDecodedData;
107172c55faSColin Günther 			size_t				fDecodedDataSizeInBytes;
108172c55faSColin Günther 			AVFrame*			fPostProcessedDecodedPicture;
109172c55faSColin Günther 			AVFrame*			fRawDecodedPicture;
110815d18fbSColin Günther 			AVFrame*			fRawDecodedAudio;
11127f6fb6cSStephan Aßmus 
11227f6fb6cSStephan Aßmus 			bool 				fCodecInitDone;
11327f6fb6cSStephan Aßmus 
11412a9eb5dSStephan Aßmus 			gfx_convert_func	fFormatConversionFunc;
115dfddb9f4SStephan Aßmus 			SwsContext*			fSwsContext;
11627f6fb6cSStephan Aßmus 
11727f6fb6cSStephan Aßmus 			char*				fExtraData;
11827f6fb6cSStephan Aßmus 			int					fExtraDataSize;
11927f6fb6cSStephan Aßmus 			int					fBlockAlign;
12027f6fb6cSStephan Aßmus 
12162320bdeSColin Günther 			color_space			fOutputColorSpace;
12227f6fb6cSStephan Aßmus 			int32				fOutputFrameCount;
12327f6fb6cSStephan Aßmus 			float				fOutputFrameRate;
12412a9eb5dSStephan Aßmus 			int					fOutputFrameSize;
12512a9eb5dSStephan Aßmus 									// sample size * channel count
12627f6fb6cSStephan Aßmus 
127f7f67022SColin Günther 			uint8_t*			fChunkBuffer;
12827f6fb6cSStephan Aßmus 			size_t				fChunkBufferSize;
129967fcd2cSStephan Aßmus 			bool				fAudioDecodeError;
13027f6fb6cSStephan Aßmus 
1313bca6098SColin Günther 			AVFrame*			fDecodedDataBuffer;
132*8a822b7cSAugustin Cavalier 			int32				fDecodedDataBufferOffset;
1333bca6098SColin Günther 			int32				fDecodedDataBufferSize;
13427f6fb6cSStephan Aßmus 
135954d70d8SStephan Aßmus 			AVPacket			fTempPacket;
13627f6fb6cSStephan Aßmus };
13727f6fb6cSStephan Aßmus 
13827f6fb6cSStephan Aßmus #endif // AVCODEC_DECODER_H
139