AVTranscoder.h 2.9 KB
#pragma once
#include "AVDecoder.h"


class CAVTranscoder
{
public:
	CAVTranscoder(bool bOne2One, bool one2one_same_size, int width_teacher, int height_teacher, int student_width,int student_height, bool has_teacher, int max_audio);
	virtual ~CAVTranscoder();

	int add(media_info & info);
	double transcode();
	bool all_processed();
	int close();
	int open_output_file(const char *filename);

protected:
	vector < CAVDecoder *> _decoders;

	AVFormatContext * _ofmt_ctx;
	int64_t _start_time;
	double _cur_a_time;
	double _cur_v_time;
	int _nOutputWidth;
	int _nOutputHeight;
	int64_t _cur_out_v_ts;
	int64_t _cur_out_a_ts;

private:
	int mix_and_output_vframe(vector<CAVDecoder *> & decoders_got_frame);
	int mix_and_output_aframe(vector<CAVDecoder *> & decoders_got_frame);
	bool _all_processed;
	bool _one2one;
	int mix_and_output_one2one_vframe(vector<CAVDecoder *> & decoders_got_frame);
	int mix_and_output_one2many_vframe(vector<CAVDecoder *> & decoders_got_frame);

	int scale_fill_one2one_teacherframe(AVFrame *pDstFrame);
	int fillDestFrame(AVFrame * pDstFrame, AVFrame * pSrcFrame, int x, int y);
	int fillDestFrame(AVFrame * pDstFrame, AVFrame * pSrcFrame, int destx, int desty, int srcx,int srcy,int w,int h);
	int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame);
	int flush_encoder(unsigned int stream_index);

	int init_scale_context(struct SwsContext ** ctx, AVFrame ** frame, int src_w, int src_h, int dest_w, int dest_h);
	int free_scale_context(struct SwsContext ** ctx, AVFrame ** frame);

	void * _a_frame_pool;
	int _max_audio;
	int _scaled_width;
	int	_scaled_height;
	int _pip_width;
	int _pip_height;
	int	_teacher_width;
	int	_teacher_height;
	int _student_width;
	int _student_height;
	bool _one2one_same_size;//top and bottom are same size ,if not ,scale the smaller to the larger
	struct SwsContext * _sws_ctx_w_h; //for one2many student frame
	struct SwsContext * _sws_ctx_h_w;
	struct SwsContext * _sws_ctx_h_h;
	AVFrame * _scaled_frame_w_h;
	AVFrame * _scaled_frame_h_w;
	AVFrame * _scaled_frame_h_h;
	int _last_videos_got;

	AVFrame * _teacherFrame;
	AVFrame * _studentFrame; // for one2one,keep the last frame

	struct SwsContext * _sws_ctx_teacher;//for one2one teacher frame
	AVFrame * _scaled_frame_teacher;
	int _src_width_teacher;
	int _src_height_teacher;
	struct SwsContext * _sws_ctx_student;//for one2one teacher frame
	AVFrame * _scaled_frame_student;
	int _src_width_student;
	int _src_height_student;

	uint8_t _blank_y, _blank_u, _blank_v;
public:
	void set_max_audio(int max_audio);
private:
	int scale_fill_one2one_studentframe(AVFrame * pDstFrame, int y);
	int fill_one2one_student_frame(AVFrame * pDstFrame, int y);
	void get_scaled_dest_size(AVFrame * pFrame, int dest_width, int dest_height, int* scaled_width, int* scaled_height);
	int fill_one2many_scaled_teacher_frame(AVFrame * pDstFrame);
};