⛏️ index : haiku.git

/*
 * Copyright 2009, Stephan Aßmus <superstippi@gmx.de>.
 * All rights reserved. Distributed under the terms of the MIT license.
 */
#ifndef AVCODEC_ENCODER_H
#define AVCODEC_ENCODER_H


#include <MediaFormats.h>

extern "C" {
	#include "avcodec.h"
	#include "swscale.h"
	#include "libavutil/fifo.h"
}

#include "EncoderPlugin.h"


typedef AVCodecID CodecID;


class AVCodecEncoder : public Encoder {
public:
								AVCodecEncoder(uint32 codecID,
									int bitRateScale);

	virtual						~AVCodecEncoder();

	virtual	status_t			AcceptedFormat(
									const media_format* proposedInputFormat,
									media_format* _acceptedInputFormat = NULL);

	virtual	status_t			SetUp(const media_format* inputFormat);

	virtual status_t			GetEncodeParameters(
									encode_parameters* parameters) const;
	virtual status_t			SetEncodeParameters(
									encode_parameters* parameters);

	virtual status_t			Encode(const void* buffer, int64 frameCount,
									media_encode_info* info);

	// TODO: Turns out we need Flush() after all. We buffer encoded audio
	// in a FIFO, since the user suggested buffer size may not fit the
	// codec buffer size.

private:
			void				_Init();
			status_t			_Setup();

			bool				_OpenCodecIfNeeded();

			status_t			_EncodeAudio(const void* buffer,
									int64 frameCount,
									media_encode_info* info);
			status_t			_EncodeAudio(const uint8* buffer,
									size_t bufferSize, int64 frameCount,
									media_encode_info* info);

			status_t			_EncodeVideo(const void* buffer,
									int64 frameCount,
									media_encode_info* info);
			status_t			_EncodeVideoFrame(AVFrame* frame,
									AVPacket* pkt,
									media_encode_info* info);

private:
			media_format		fInputFormat;
			encode_parameters	fEncodeParameters;
			int					fBitRateScale;

			// FFmpeg related members
			// TODO: Refactor common base class from AVCodec[De|En]Coder!
			CodecID				fCodecID;
			const AVCodec*		fCodec;
			AVCodecContext*		fCodecContext;
			
			enum {
				CODEC_INIT_NEEDED = 0,
				CODEC_INIT_DONE,
				CODEC_INIT_FAILED
			};
			uint32                          fCodecInitStatus;

			// For video (color space conversion):
			AVFrame*			fFrame;
			SwsContext*			fSwsContext;

			// For encoded audio:
#if LIBAVCODEC_VERSION_MAJOR >= 60
			AVFifo*				fAudioFifo;
#else
			AVFifoBuffer*		fAudioFifo;
#endif

			int64				fFramesWritten;

			uint8*				fChunkBuffer;
};

#endif // AVCODEC_ENCODER_H