⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plugin.cpp

📁 由bmp生成mpeg2 的I_frame 数据
💻 CPP
字号:
#include <memory>
#include "mpeg_video.h"
#include "mpeg_audio.h"
#include "input.h"

//////////////////////////////////////////////////////////////////////////////

class M2V {
	MPEG_VIDEO *video;

	void ReadFields(int frame, OUT_BUFFER_ELEMENT *& top, OUT_BUFFER_ELEMENT *& bottom) const {
		top = bottom = read_frame(video, frame);

		if(top == NULL)
			return;

		switch(video->config.field_mode) {
		case 0: // keep original frame
			break;

		case 1: // top field first
			if(!top->prm.top_field_first && !top->prm.repeat_first_field)
				bottom = read_frame(video, frame + 1);

			if(bottom == NULL)
				bottom = top;

			break;

		case 2: // bottom field first
			if(bottom->prm.top_field_first && !bottom->prm.repeat_first_field)
				top = read_frame(video, frame + 1);

			if(top == NULL)
				top = bottom;

			break;
		}
	}

public:
	M2V(const char *file) {
		video = open_mpeg_video((char *)file);
	}

	~M2V() {
		if(video != NULL)
			close_mpeg_video(video);
	}

	MPEG_VIDEO *operator->() const {
		return video;
	}

	operator MPEG_VIDEO *() const {
		return video;
	}

	bool ReadYUV422(int frame, void *buf, int pitch) const {
		
		OUT_BUFFER_ELEMENT *fields[2];

		ReadFields(frame, fields[0], fields[1]);

		if(fields[0] == NULL) {
			__asm {emms};
			return false;
		}

		video->bgr_prm.prm.out_step = pitch;
		video->to_yuy2(fields[0]->data, fields[1]->data, (unsigned char *)buf, &(video->bgr_prm.prm));
		video->yuy2_cc((unsigned char *)buf, pitch, video->bgr_prm.prm.height, &(video->ycc_prm));
		
		__asm {emms};
		
		return true;
	}
};

//////////////////////////////////////////////////////////////////////////////

class M2A {
	MPEG_AUDIO *audio;

public:
	M2A(const char *file) {
		audio = open_mpeg_audio((char *)file);
	}

	~M2A() {
		if(audio != NULL)
			close_mpeg_audio(audio);
	}

	MPEG_AUDIO *operator->() const {
		return audio;
	}

	operator MPEG_AUDIO *() const {
		return audio;
	}

	int GetChannels() const {
		return 2;
	}

	int GetBitsPerSample() const {
		return 16;
	}
};

//////////////////////////////////////////////////////////////////////////////

class ForAviutl {
	M2V m2v;
	M2A m2a;
	BITMAPINFOHEADER bih;
	WAVEFORMATEX wfex;
	int pitch;

	ForAviutl(LPSTR file) : m2v(file), m2a(file) {
		memset(&bih, 0, sizeof(bih));
		memset(&wfex, 0, sizeof(wfex));

		if(m2v != NULL) {
			bih.biSize = sizeof(bih);
			bih.biWidth = m2v->width;
			bih.biHeight = m2v->height;
			bih.biPlanes = 1;
			bih.biBitCount = 16;
			bih.biCompression = '2YUY';

			pitch = ((bih.biBitCount * bih.biWidth + 31) & ~31) >> 3;
			bih.biSizeImage = pitch * bih.biHeight;
		}

		if(m2a != NULL) {
			wfex.wFormatTag = WAVE_FORMAT_PCM;
			wfex.nChannels = m2a->channel;
			wfex.wBitsPerSample = m2a.GetBitsPerSample();
			wfex.nBlockAlign = wfex.nChannels * wfex.wBitsPerSample / 8;
			wfex.nSamplesPerSec = m2a->frequency;
			wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign;
		}
	}

	bool GetInfo(INPUT_INFO *iip) {
		iip->flag = 0;

		if(m2v != NULL) {
			iip->flag |= INPUT_INFO_FLAG_VIDEO;
			iip->rate = m2v->rate;
			iip->scale = m2v->scale;
			iip->n = m2v->total;
			iip->format = &bih;
			iip->format_size = sizeof(bih);
			iip->handler = 0;
		}

		if(m2a != NULL) {
			iip->flag |= INPUT_INFO_FLAG_AUDIO;
			iip->audio_n = m2a->sample;
			iip->audio_format = &wfex;
			iip->audio_format_size = sizeof(wfex);
		}

		return true;
	}

	int ReadVideo(int frame, void *buf) {
		int bytes = 0;

		if(m2v != NULL && m2v.ReadYUV422(frame, buf, pitch))
			bytes = bih.biSizeImage;

		return bytes;
	}

	int ReadAudio(int start, int length, void *buf) {
		int samples = 0;

		if(m2a != NULL)
			samples = read_mpeg_audio(m2a, start, buf, length);

		return samples;
	}

	static INPUT_HANDLE __cdecl func_open(LPSTR file) {
		std::auto_ptr<ForAviutl> handle(new ForAviutl(file));
		return (handle->m2v != NULL || handle->m2a != NULL) ? handle.release() : NULL;
	}

	static BOOL __cdecl func_close(INPUT_HANDLE ih) {
		delete (ForAviutl *)ih;
		return TRUE;
	}

	static BOOL __cdecl func_info_get(INPUT_HANDLE ih, INPUT_INFO *iip) {
		return ((ForAviutl *)ih)->GetInfo(iip);
	}

	static int __cdecl func_read_video(INPUT_HANDLE ih, int frame, void *buf) {
		return ((ForAviutl *)ih)->ReadVideo(frame, buf);
	}

	static int __cdecl func_read_audio(INPUT_HANDLE ih, int start, int length, void *buf) {
		return ((ForAviutl *)ih)->ReadAudio(start, length, buf);
	}

public:
	static INPUT_PLUGIN_TABLE *GetInputPluginTable() {
		#define _FILE_TYPE_ "*.mpeg;*.mpg;*.m2p;*.mp2;*.vob;*.vro;*.m2v;*.m1v;*.mpv;*.ves;*.m2t;*.ssg;*.ts;*.bs"
		static INPUT_PLUGIN_TABLE table = {
			INPUT_PLUGIN_FLAG_VIDEO | INPUT_PLUGIN_FLAG_AUDIO,
			"MPEG-2 VIDEO File Reader",
			"MPEG-2 VIDEO File (" _FILE_TYPE_ ")\0" _FILE_TYPE_ "\0",
			"MPEG-2 VIDEO File Reader",
			NULL,
			NULL,
			(INPUT_HANDLE (*)(LPSTR))func_open,
			(BOOL (*)(INPUT_HANDLE))func_close,
			(BOOL (*)(INPUT_HANDLE, INPUT_INFO *))func_info_get,
			(int (*)(INPUT_HANDLE, int, void *))func_read_video,
			(int (*)(INPUT_HANDLE, int, int, void *))func_read_audio,
			NULL,
			NULL,
		};
		#undef _FILE_TYPE_
		return &table;
	}
};

//////////////////////////////////////////////////////////////////////////////

extern "C" __declspec(dllexport)
INPUT_PLUGIN_TABLE * __stdcall GetInputPluginTable() {
	return ForAviutl::GetInputPluginTable();
}

//////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -