1/*
2 * Copyright 2009, Stephan A��mus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT license.
4 */
5#ifndef AVCODEC_ENCODER_H
6#define AVCODEC_ENCODER_H
7
8
9#include <MediaFormats.h>
10
11extern "C" {
12	#include "avcodec.h"
13	#include "swscale.h"
14	#include "libavutil/fifo.h"
15}
16
17#include "EncoderPlugin.h"
18
19
20typedef AVCodecID CodecID;
21
22
23class AVCodecEncoder : public Encoder {
24public:
25								AVCodecEncoder(uint32 codecID,
26									int bitRateScale);
27
28	virtual						~AVCodecEncoder();
29
30	virtual	status_t			AcceptedFormat(
31									const media_format* proposedInputFormat,
32									media_format* _acceptedInputFormat = NULL);
33
34	virtual	status_t			SetUp(const media_format* inputFormat);
35
36	virtual status_t			GetEncodeParameters(
37									encode_parameters* parameters) const;
38	virtual status_t			SetEncodeParameters(
39									encode_parameters* parameters);
40
41	virtual status_t			Encode(const void* buffer, int64 frameCount,
42									media_encode_info* info);
43
44	// TODO: Turns out we need Flush() after all. We buffer encoded audio
45	// in a FIFO, since the user suggested buffer size may not fit the
46	// codec buffer size.
47
48private:
49			void				_Init();
50			status_t			_Setup();
51
52			bool				_OpenCodecIfNeeded();
53
54			status_t			_EncodeAudio(const void* buffer,
55									int64 frameCount,
56									media_encode_info* info);
57			status_t			_EncodeAudio(const uint8* buffer,
58									size_t bufferSize, int64 frameCount,
59									media_encode_info* info);
60
61			status_t			_EncodeVideo(const void* buffer,
62									int64 frameCount,
63									media_encode_info* info);
64			status_t			_EncodeVideoFrame(AVFrame* frame,
65									AVPacket* pkt,
66									media_encode_info* info);
67
68private:
69			media_format		fInputFormat;
70			encode_parameters	fEncodeParameters;
71			int					fBitRateScale;
72
73			// FFmpeg related members
74			// TODO: Refactor common base class from AVCodec[De|En]Coder!
75			CodecID				fCodecID;
76			const AVCodec*		fCodec;
77			AVCodecContext*		fCodecContext;
78
79			enum {
80				CODEC_INIT_NEEDED = 0,
81				CODEC_INIT_DONE,
82				CODEC_INIT_FAILED
83			};
84			uint32                          fCodecInitStatus;
85
86			// For video (color space conversion):
87			AVFrame*			fFrame;
88			SwsContext*			fSwsContext;
89
90			// For encoded audio:
91#if LIBAVCODEC_VERSION_MAJOR >= 60
92			AVFifo*				fAudioFifo;
93#else
94			AVFifoBuffer*		fAudioFifo;
95#endif
96
97			int64				fFramesWritten;
98
99			uint8*				fChunkBuffer;
100};
101
102#endif // AVCODEC_ENCODER_H
103