xref: /haiku/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.h (revision 3c68ae7c581191fbb32cd0da52c9a24c666b9814)
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"
19dfddb9f4SStephan Aßmus 	#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 
2927f6fb6cSStephan Aßmus class AVCodecDecoder : public Decoder {
3027f6fb6cSStephan Aßmus public:
3127f6fb6cSStephan Aßmus 						AVCodecDecoder();
3227f6fb6cSStephan Aßmus 
3327f6fb6cSStephan Aßmus 	virtual				~AVCodecDecoder();
3427f6fb6cSStephan Aßmus 
3527f6fb6cSStephan Aßmus 	virtual	void		GetCodecInfo(media_codec_info* mci);
3627f6fb6cSStephan Aßmus 
3727f6fb6cSStephan Aßmus 	virtual	status_t	Setup(media_format* ioEncodedFormat,
3827f6fb6cSStephan Aßmus 							const void* infoBuffer, size_t infoSize);
3927f6fb6cSStephan Aßmus 
406defcb6cSColin Günther 	virtual	status_t	NegotiateOutputFormat(media_format* inOutFormat);
4127f6fb6cSStephan Aßmus 
4227f6fb6cSStephan Aßmus 	virtual	status_t	Decode(void* outBuffer, int64* outFrameCount,
4327f6fb6cSStephan Aßmus 							media_header* mediaHeader,
4427f6fb6cSStephan Aßmus 							media_decode_info* info);
4527f6fb6cSStephan Aßmus 
462e54e93fSStephan Aßmus 	virtual	status_t	SeekedTo(int64 trame, bigtime_t time);
4727f6fb6cSStephan Aßmus 
4827f6fb6cSStephan Aßmus 
4912a9eb5dSStephan Aßmus private:
50f345d827SColin Günther 			void		_ResetTempPacket();
51f345d827SColin Günther 
526defcb6cSColin Günther 			status_t	_NegotiateAudioOutputFormat(media_format* inOutFormat);
5312a9eb5dSStephan Aßmus 
546defcb6cSColin Günther 			status_t	_NegotiateVideoOutputFormat(media_format* inOutFormat);
5512a9eb5dSStephan Aßmus 
566defcb6cSColin Günther 			status_t	_DecodeAudio(void* outBuffer, int64* outFrameCount,
5712a9eb5dSStephan Aßmus 							media_header* mediaHeader,
5812a9eb5dSStephan Aßmus 							media_decode_info* info);
5912a9eb5dSStephan Aßmus 
606defcb6cSColin Günther 			status_t	_DecodeVideo(void* outBuffer, int64* outFrameCount,
6112a9eb5dSStephan Aßmus 							media_header* mediaHeader,
6212a9eb5dSStephan Aßmus 							media_decode_info* info);
633c6f9c10SColin Günther 
6485371234SColin Günther 			status_t	_DecodeNextAudioFrame();
65*3c68ae7cSColin Günther 			void		_ApplyEssentialAudioContainerPropertiesToContext();
663c6f9c10SColin Günther 			void		_ResetRawDecodedAudio();
671b8bbb50SColin Günther 			void		_CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow();
68ca5c686dSColin Günther 			void		_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes();
691a963de4SColin Günther 			status_t	_DecodeNextAudioFrameChunk();
707dc2773cSColin Günther 			status_t	_LoadNextAudioChunkIfNeededAndAssignStartTime();
71463f3402SColin Günther 			status_t	_DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer();
723c6f9c10SColin Günther 			void		_UpdateMediaHeaderForAudioFrame();
733c6f9c10SColin Günther 
74172c55faSColin Günther 			status_t	_DecodeNextVideoFrame();
7575bd62e8SColin Günther 			void		_ApplyEssentialVideoContainerPropertiesToContext();
76ed9de7dfSColin Günther 			status_t	_LoadNextVideoChunkIfNeededAndAssignStartTime();
776defcb6cSColin Günther 							// TODO: Remove the "Video" word once
786defcb6cSColin Günther 							// the audio path is responsible for
796defcb6cSColin Günther 							// freeing the chunk buffer, too.
806063c02eSColin Günther 			status_t	_CopyChunkToVideoChunkBufferAndAddPadding(
816063c02eSColin Günther 							const void* chunk, size_t chunkSize);
822d83b841SColin Günther 							// TODO: Remove the "Video" word once
836defcb6cSColin Günther 							// the audio path is responsible for
842d83b841SColin Günther 							// freeing the chunk buffer, too.
85a335ec82SColin Günther 			void		_HandleNewVideoFrameAndUpdateSystemState();
86a335ec82SColin Günther 			status_t	_FlushOneVideoFrameFromDecoderBuffer();
87254a5340SColin Günther 			void		_UpdateMediaHeaderForVideoFrame();
880adda4f6SColin Günther 			void		_DeinterlaceAndColorConvertVideoFrame();
89172c55faSColin Günther 
9012a9eb5dSStephan Aßmus 
9127f6fb6cSStephan Aßmus 			media_header		fHeader;
92254a5340SColin Günther 									// Contains the properties of the current
93254a5340SColin Günther 									// decoded audio / video frame
94254a5340SColin Günther 
9527f6fb6cSStephan Aßmus 			media_format		fInputFormat;
9627f6fb6cSStephan Aßmus 
9727f6fb6cSStephan Aßmus 			int64				fFrame;
9812a9eb5dSStephan Aßmus 			bool				fIsAudio;
9927f6fb6cSStephan Aßmus 
10012a9eb5dSStephan Aßmus 			// FFmpeg related members
10127f6fb6cSStephan Aßmus 			AVCodec*			fCodec;
10212a9eb5dSStephan Aßmus 			AVCodecContext*		fContext;
103172c55faSColin Günther 			uint8_t*			fDecodedData;
104172c55faSColin Günther 			size_t				fDecodedDataSizeInBytes;
105172c55faSColin Günther 			AVFrame*			fPostProcessedDecodedPicture;
106172c55faSColin Günther 			AVFrame*			fRawDecodedPicture;
107815d18fbSColin Günther 			AVFrame*			fRawDecodedAudio;
10827f6fb6cSStephan Aßmus 
10927f6fb6cSStephan Aßmus 			bool 				fCodecInitDone;
11027f6fb6cSStephan Aßmus 
11112a9eb5dSStephan Aßmus 			gfx_convert_func	fFormatConversionFunc;
112dfddb9f4SStephan Aßmus 			SwsContext*			fSwsContext;
11327f6fb6cSStephan Aßmus 
11427f6fb6cSStephan Aßmus 			char*				fExtraData;
11527f6fb6cSStephan Aßmus 			int					fExtraDataSize;
11627f6fb6cSStephan Aßmus 			int					fBlockAlign;
11727f6fb6cSStephan Aßmus 
11862320bdeSColin Günther 			color_space			fOutputColorSpace;
11927f6fb6cSStephan Aßmus 			int32				fOutputFrameCount;
12027f6fb6cSStephan Aßmus 			float				fOutputFrameRate;
12112a9eb5dSStephan Aßmus 			int					fOutputFrameSize;
12212a9eb5dSStephan Aßmus 									// sample size * channel count
12327f6fb6cSStephan Aßmus 
12427f6fb6cSStephan Aßmus 			const void*			fChunkBuffer;
1252d83b841SColin Günther 			uint8_t*			fVideoChunkBuffer;
1262d83b841SColin Günther 									// TODO: Remove and use fChunkBuffer again
127b82ef8bcSColin Günther 									// (with type uint8_t*) once the audio path
128b82ef8bcSColin Günther 									// is responsible for freeing the chunk
129b82ef8bcSColin Günther 									// buffer, too.
13027f6fb6cSStephan Aßmus 			size_t				fChunkBufferSize;
131967fcd2cSStephan Aßmus 			bool				fAudioDecodeError;
13227f6fb6cSStephan Aßmus 
1333bca6098SColin Günther 			AVFrame*			fDecodedDataBuffer;
1343bca6098SColin Günther 			int32				fDecodedDataBufferOffset;
1353bca6098SColin Günther 			int32				fDecodedDataBufferSize;
13627f6fb6cSStephan Aßmus 
137954d70d8SStephan Aßmus 			AVPacket			fTempPacket;
13827f6fb6cSStephan Aßmus };
13927f6fb6cSStephan Aßmus 
14027f6fb6cSStephan Aßmus #endif // AVCODEC_DECODER_H
141