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 A��mus <superstippi@gmx.de>.
7 * Copyright (C) 2015 Adrien Destugues <pulkomandy@pulkomandy.tk>.
8 *
9 * All rights reserved. Distributed under the terms of the MIT License.
10 */
11#ifndef AVCODEC_DECODER_H
12#define AVCODEC_DECODER_H
13
14//! libavcodec based decoder for Haiku
15
16
17#include <MediaFormats.h>
18
19
20extern "C" {
21	#include "avcodec.h"
22	#include "avfilter.h"
23	#include "buffersink.h"
24	#include "buffersrc.h"
25	#include "imgutils.h"
26	#include "swresample.h"
27	#include "swscale.h"
28	#include "timestamp.h"
29}
30
31
32#include "DecoderPlugin.h"
33#include "ReaderPlugin.h"
34
35#include "CodecTable.h"
36#include "gfx_util.h"
37
38
39#if 1
40#define USE_SWS_FOR_COLOR_SPACE_CONVERSION 1
41#else
42#define USE_SWS_FOR_COLOR_SPACE_CONVERSION 0
43// NOTE: David's color space conversion is much faster than the FFmpeg
44// version. Perhaps the SWS code can be used for unsupported conversions?
45// Otherwise the alternative code could simply be removed from this file.
46#endif
47
48
49class AVCodecDecoder : public Decoder {
50public:
51						AVCodecDecoder();
52
53	virtual				~AVCodecDecoder();
54
55	virtual	void		GetCodecInfo(media_codec_info* mci);
56
57	virtual	status_t	Setup(media_format* ioEncodedFormat,
58							const void* infoBuffer, size_t infoSize);
59
60	virtual	status_t	NegotiateOutputFormat(media_format* inOutFormat);
61
62	virtual	status_t	Decode(void* outBuffer, int64* outFrameCount,
63							media_header* mediaHeader,
64							media_decode_info* info);
65
66	virtual	status_t	SeekedTo(int64 trame, bigtime_t time);
67
68
69private:
70			void		_ResetTempPacket();
71
72			status_t	_NegotiateAudioOutputFormat(media_format* inOutFormat);
73
74			status_t	_NegotiateVideoOutputFormat(media_format* inOutFormat);
75
76			status_t	_DecodeAudio(void* outBuffer, int64* outFrameCount,
77							media_header* mediaHeader,
78							media_decode_info* info);
79
80			status_t	_DecodeVideo(void* outBuffer, int64* outFrameCount,
81							media_header* mediaHeader,
82							media_decode_info* info);
83
84			status_t	_DecodeNextAudioFrame();
85			void		_ApplyEssentialAudioContainerPropertiesToContext();
86			status_t	_ResetRawDecodedAudio();
87			void		_CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow();
88			void		_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes();
89			status_t	_DecodeNextAudioFrameChunk();
90			status_t	_DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer();
91			void		_UpdateMediaHeaderForAudioFrame();
92
93			status_t	_DecodeNextVideoFrame();
94			void		_ApplyEssentialVideoContainerPropertiesToContext();
95			status_t	_LoadNextChunkIfNeededAndAssignStartTime();
96			status_t	_CopyChunkToChunkBufferAndAddPadding(const void* chunk,
97							size_t chunkSize);
98			status_t	_HandleNewVideoFrameAndUpdateSystemState();
99			status_t	_FlushOneVideoFrameFromDecoderBuffer();
100			void		_UpdateMediaHeaderForVideoFrame();
101			status_t	_DeinterlaceAndColorConvertVideoFrame();
102
103			// video deinterlace filter graph
104			status_t	_InitFilterGraph(enum AVPixelFormat pixfmt,
105							int32 width, int32 height);
106			status_t	_ProcessFilterGraph(AVFrame *dst,
107							const AVFrame *src, enum AVPixelFormat pixfmt,
108							int32 width, int32 height);
109
110			media_header		fHeader;
111									// Contains the properties of the current
112									// decoded audio / video frame
113
114			media_format		fInputFormat;
115
116			int64				fFrame;
117			bool				fIsAudio;
118
119			// FFmpeg related members
120			const AVCodec*		fCodec;
121			AVCodecContext*		fCodecContext;
122			SwrContext*			fResampleContext;
123			uint8_t*			fDecodedData;
124			size_t				fDecodedDataSizeInBytes;
125			AVFrame*			fPostProcessedDecodedPicture;
126			AVFrame*			fRawDecodedPicture;
127			AVFrame*			fRawDecodedAudio;
128
129			bool 				fCodecInitDone;
130
131			gfx_convert_func	fFormatConversionFunc;
132#if USE_SWS_FOR_COLOR_SPACE_CONVERSION
133			SwsContext*			fSwsContext;
134#endif
135
136			char*				fExtraData;
137			int					fExtraDataSize;
138			int					fBlockAlign;
139
140			color_space			fOutputColorSpace;
141			int32				fOutputFrameCount;
142			float				fOutputFrameRate;
143									// only for audio streams
144			int					fOutputFrameSize;
145									// sample size * channel count
146			int					fInputFrameSize;
147									// sample size * channel count
148									// or just sample size for planar formats
149
150			uint8_t*			fChunkBuffer;
151			size_t				fChunkBufferSize;
152			bool				fAudioDecodeError;
153
154			AVFrame*			fDecodedDataBuffer;
155			int32				fDecodedDataBufferOffset;
156			int32				fDecodedDataBufferSize;
157
158			AVPacket*			fTempPacket;
159
160			// video deinterlace feature
161			AVFilterContext*	fBufferSinkContext;
162			AVFilterContext*	fBufferSourceContext;
163			AVFilterGraph*		fFilterGraph;
164			AVFrame*			fFilterFrame;
165			int32				fLastWidth;
166			int32				fLastHeight;
167			enum AVPixelFormat	fLastPixfmt;
168};
169
170#endif // AVCODEC_DECODER_H
171