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