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