xref: /haiku/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h (revision c020b0832caa68a63e600ec3cbd65fcac2c4c0e4)
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>.
79dd9b454SAdrien Destugues  * Copyright (C) 2015 Adrien Destugues <pulkomandy@pulkomandy.tk>.
827f6fb6cSStephan Aßmus  *
927f6fb6cSStephan Aßmus  * All rights reserved. Distributed under the terms of the MIT License.
1027f6fb6cSStephan Aßmus  */
1127f6fb6cSStephan Aßmus #ifndef AVCODEC_DECODER_H
1227f6fb6cSStephan Aßmus #define AVCODEC_DECODER_H
1327f6fb6cSStephan Aßmus 
1427f6fb6cSStephan Aßmus //! libavcodec based decoder for Haiku
1527f6fb6cSStephan Aßmus 
1627f6fb6cSStephan Aßmus 
17218a8c03SAugustin Cavalier #include <MediaFormats.h>
18218a8c03SAugustin Cavalier 
199dd9b454SAdrien Destugues 
20dfddb9f4SStephan Aßmus extern "C" {
21c1e73fbfSStephan Aßmus 	#include "avcodec.h"
220b6c89fbSJérôme Duval 	#include "avfilter.h"
230b6c89fbSJérôme Duval 	#include "buffersink.h"
240b6c89fbSJérôme Duval 	#include "buffersrc.h"
25e5bb653bSAugustin Cavalier 	#include "imgutils.h"
269dd9b454SAdrien Destugues 	#include "swresample.h"
27946163e3SJérôme Duval 	#include "swscale.h"
289e2c056cSAdrien Destugues 	#include "timestamp.h"
29dfddb9f4SStephan Aßmus }
30dfddb9f4SStephan Aßmus 
31218a8c03SAugustin Cavalier 
32218a8c03SAugustin Cavalier #include "DecoderPlugin.h"
33218a8c03SAugustin Cavalier #include "ReaderPlugin.h"
34218a8c03SAugustin Cavalier 
3527f6fb6cSStephan Aßmus #include "CodecTable.h"
36c1e73fbfSStephan Aßmus #include "gfx_util.h"
3727f6fb6cSStephan Aßmus 
3827f6fb6cSStephan Aßmus 
391fb7ddbbSAugustin Cavalier #if 1
40946163e3SJérôme Duval #define USE_SWS_FOR_COLOR_SPACE_CONVERSION 1
41946163e3SJérôme Duval #else
42946163e3SJérôme Duval #define USE_SWS_FOR_COLOR_SPACE_CONVERSION 0
43946163e3SJérôme Duval // NOTE: David's color space conversion is much faster than the FFmpeg
44946163e3SJérôme Duval // version. Perhaps the SWS code can be used for unsupported conversions?
45946163e3SJérôme Duval // Otherwise the alternative code could simply be removed from this file.
46946163e3SJérôme Duval #endif
47946163e3SJérôme Duval 
48946163e3SJérôme Duval 
49218a8c03SAugustin Cavalier class AVCodecDecoder : public Decoder {
5027f6fb6cSStephan Aßmus public:
5127f6fb6cSStephan Aßmus 						AVCodecDecoder();
5227f6fb6cSStephan Aßmus 
5327f6fb6cSStephan Aßmus 	virtual				~AVCodecDecoder();
5427f6fb6cSStephan Aßmus 
5527f6fb6cSStephan Aßmus 	virtual	void		GetCodecInfo(media_codec_info* mci);
5627f6fb6cSStephan Aßmus 
5727f6fb6cSStephan Aßmus 	virtual	status_t	Setup(media_format* ioEncodedFormat,
5827f6fb6cSStephan Aßmus 							const void* infoBuffer, size_t infoSize);
5927f6fb6cSStephan Aßmus 
606defcb6cSColin Günther 	virtual	status_t	NegotiateOutputFormat(media_format* inOutFormat);
6127f6fb6cSStephan Aßmus 
6227f6fb6cSStephan Aßmus 	virtual	status_t	Decode(void* outBuffer, int64* outFrameCount,
6327f6fb6cSStephan Aßmus 							media_header* mediaHeader,
6427f6fb6cSStephan Aßmus 							media_decode_info* info);
6527f6fb6cSStephan Aßmus 
662e54e93fSStephan Aßmus 	virtual	status_t	SeekedTo(int64 trame, bigtime_t time);
6727f6fb6cSStephan Aßmus 
6827f6fb6cSStephan Aßmus 
6912a9eb5dSStephan Aßmus private:
70f345d827SColin Günther 			void		_ResetTempPacket();
71f345d827SColin Günther 
726defcb6cSColin Günther 			status_t	_NegotiateAudioOutputFormat(media_format* inOutFormat);
7312a9eb5dSStephan Aßmus 
746defcb6cSColin Günther 			status_t	_NegotiateVideoOutputFormat(media_format* inOutFormat);
7512a9eb5dSStephan Aßmus 
766defcb6cSColin Günther 			status_t	_DecodeAudio(void* outBuffer, int64* outFrameCount,
7712a9eb5dSStephan Aßmus 							media_header* mediaHeader,
7812a9eb5dSStephan Aßmus 							media_decode_info* info);
7912a9eb5dSStephan Aßmus 
806defcb6cSColin Günther 			status_t	_DecodeVideo(void* outBuffer, int64* outFrameCount,
8112a9eb5dSStephan Aßmus 							media_header* mediaHeader,
8212a9eb5dSStephan Aßmus 							media_decode_info* info);
833c6f9c10SColin Günther 
8485371234SColin Günther 			status_t	_DecodeNextAudioFrame();
853c68ae7cSColin Günther 			void		_ApplyEssentialAudioContainerPropertiesToContext();
864ff7c2ccSColin Günther 			status_t	_ResetRawDecodedAudio();
871b8bbb50SColin Günther 			void		_CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow();
88ca5c686dSColin Günther 			void		_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes();
891a963de4SColin Günther 			status_t	_DecodeNextAudioFrameChunk();
90463f3402SColin Günther 			status_t	_DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer();
913c6f9c10SColin Günther 			void		_UpdateMediaHeaderForAudioFrame();
923c6f9c10SColin Günther 
93172c55faSColin Günther 			status_t	_DecodeNextVideoFrame();
9475bd62e8SColin Günther 			void		_ApplyEssentialVideoContainerPropertiesToContext();
95f7f67022SColin Günther 			status_t	_LoadNextChunkIfNeededAndAssignStartTime();
96f7f67022SColin Günther 			status_t	_CopyChunkToChunkBufferAndAddPadding(const void* chunk,
97f7f67022SColin Günther 							size_t chunkSize);
98fe1eb3c1SColin Günther 			status_t	_HandleNewVideoFrameAndUpdateSystemState();
99a335ec82SColin Günther 			status_t	_FlushOneVideoFrameFromDecoderBuffer();
100254a5340SColin Günther 			void		_UpdateMediaHeaderForVideoFrame();
101fe1eb3c1SColin Günther 			status_t	_DeinterlaceAndColorConvertVideoFrame();
102172c55faSColin Günther 
1030b6c89fbSJérôme Duval 			// video deinterlace filter graph
1040b6c89fbSJérôme Duval 			status_t	_InitFilterGraph(enum AVPixelFormat pixfmt,
1050b6c89fbSJérôme Duval 							int32 width, int32 height);
106e5bb653bSAugustin Cavalier 			status_t	_ProcessFilterGraph(AVFrame *dst,
107e5bb653bSAugustin Cavalier 							const AVFrame *src, enum AVPixelFormat pixfmt,
1080b6c89fbSJérôme Duval 							int32 width, int32 height);
10912a9eb5dSStephan Aßmus 
11027f6fb6cSStephan Aßmus 			media_header		fHeader;
111254a5340SColin Günther 									// Contains the properties of the current
112254a5340SColin Günther 									// decoded audio / video frame
113254a5340SColin Günther 
11427f6fb6cSStephan Aßmus 			media_format		fInputFormat;
11527f6fb6cSStephan Aßmus 
11627f6fb6cSStephan Aßmus 			int64				fFrame;
11712a9eb5dSStephan Aßmus 			bool				fIsAudio;
11827f6fb6cSStephan Aßmus 
11912a9eb5dSStephan Aßmus 			// FFmpeg related members
1203d6dc09dSPulkoMandy 			const AVCodec*		fCodec;
121e302fe32SBarrett17 			AVCodecContext*		fCodecContext;
1229dd9b454SAdrien Destugues 			SwrContext*			fResampleContext;
123172c55faSColin Günther 			uint8_t*			fDecodedData;
124172c55faSColin Günther 			size_t				fDecodedDataSizeInBytes;
125172c55faSColin Günther 			AVFrame*			fPostProcessedDecodedPicture;
126172c55faSColin Günther 			AVFrame*			fRawDecodedPicture;
127815d18fbSColin Günther 			AVFrame*			fRawDecodedAudio;
12827f6fb6cSStephan Aßmus 
12927f6fb6cSStephan Aßmus 			bool 				fCodecInitDone;
13027f6fb6cSStephan Aßmus 
13112a9eb5dSStephan Aßmus 			gfx_convert_func	fFormatConversionFunc;
1329dd9b454SAdrien Destugues #if USE_SWS_FOR_COLOR_SPACE_CONVERSION
133dfddb9f4SStephan Aßmus 			SwsContext*			fSwsContext;
1349dd9b454SAdrien Destugues #endif
13527f6fb6cSStephan Aßmus 
13627f6fb6cSStephan Aßmus 			char*				fExtraData;
13727f6fb6cSStephan Aßmus 			int					fExtraDataSize;
13827f6fb6cSStephan Aßmus 			int					fBlockAlign;
13927f6fb6cSStephan Aßmus 
14062320bdeSColin Günther 			color_space			fOutputColorSpace;
14127f6fb6cSStephan Aßmus 			int32				fOutputFrameCount;
14227f6fb6cSStephan Aßmus 			float				fOutputFrameRate;
143*c020b083SPulkoMandy 									// only for audio streams
14412a9eb5dSStephan Aßmus 			int					fOutputFrameSize;
14512a9eb5dSStephan Aßmus 									// sample size * channel count
146da455572SAdrien Destugues 			int					fInputFrameSize;
147da455572SAdrien Destugues 									// sample size * channel count
148da455572SAdrien Destugues 									// or just sample size for planar formats
14927f6fb6cSStephan Aßmus 
150f7f67022SColin Günther 			uint8_t*			fChunkBuffer;
15127f6fb6cSStephan Aßmus 			size_t				fChunkBufferSize;
152967fcd2cSStephan Aßmus 			bool				fAudioDecodeError;
15327f6fb6cSStephan Aßmus 
1543bca6098SColin Günther 			AVFrame*			fDecodedDataBuffer;
1558a822b7cSAugustin Cavalier 			int32				fDecodedDataBufferOffset;
1563bca6098SColin Günther 			int32				fDecodedDataBufferSize;
15727f6fb6cSStephan Aßmus 
1589bf436a2SPulkoMandy 			AVPacket*			fTempPacket;
1590b6c89fbSJérôme Duval 
1600b6c89fbSJérôme Duval 			// video deinterlace feature
1610b6c89fbSJérôme Duval 			AVFilterContext*	fBufferSinkContext;
1620b6c89fbSJérôme Duval 			AVFilterContext*	fBufferSourceContext;
1630b6c89fbSJérôme Duval 			AVFilterGraph*		fFilterGraph;
1640b6c89fbSJérôme Duval 			AVFrame*			fFilterFrame;
1650b6c89fbSJérôme Duval 			int32				fLastWidth;
1660b6c89fbSJérôme Duval 			int32				fLastHeight;
1670b6c89fbSJérôme Duval 			enum AVPixelFormat	fLastPixfmt;
16827f6fb6cSStephan Aßmus };
16927f6fb6cSStephan Aßmus 
17027f6fb6cSStephan Aßmus #endif // AVCODEC_DECODER_H
171