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

📄 m2v.c

📁 由bmp生成mpeg2 的I_frame 数据
💻 C
字号:
/*******************************************************************
           Killer Tomate - MPEG-2 VIDEO VFAPI Plug-In
 *******************************************************************/
#include <windows.h>
#include <string.h>
#include <stdio.h>

#include "vfapi.h"
#include "vfapi_edit_ext.h"
#include "mpeg2edit.h"
#include "mpeg_video.h"
#include "mpeg_audio.h"

typedef struct {
	MPEG_VIDEO *video;
	MPEG_AUDIO *audio;
} MPEG_DECODER;

HRESULT __stdcall vfGetPluginInfo(LPVF_PluginInfo info);
HRESULT __stdcall vfGetPluginFunc(LPVF_PluginFunc func);
HRESULT __stdcall vfGetPluginFuncEditExt(LPVF_PluginFuncEditExt func_edit_ext);

HRESULT __stdcall open_file(char *path, LPVF_FileHandle out);
HRESULT __stdcall close_file(VF_FileHandle p);
HRESULT __stdcall get_file_info(VF_FileHandle in, LPVF_FileInfo out);
HRESULT __stdcall get_stream_info(VF_FileHandle in, DWORD s, void *out);
static HRESULT get_stream_info_video(MPEG_VIDEO *in, VF_StreamInfo_Video *out);
static HRESULT get_stream_info_audio(MPEG_AUDIO *in, VF_StreamInfo_Audio *out);

HRESULT __stdcall read_data(VF_FileHandle in, DWORD s, void *out);
static HRESULT read_data_video(MPEG_VIDEO *in, VF_ReadData_Video *out);
static HRESULT read_data_audio(MPEG_AUDIO *in, VF_ReadData_Audio *out);

HRESULT __stdcall get_frame_type(VF_FileHandle in, LPVF_FrameType out);
HRESULT __stdcall cut(VF_FileHandle in, LPVF_CutOption opt);

HRESULT __stdcall vfGetPluginInfo(LPVF_PluginInfo info)
{
	if(info == NULL){
		return VF_ERROR;
	}

	if(info->dwSize != sizeof(VF_PluginInfo)){
		return VF_ERROR;
	}

	info->dwAPIVersion = 1;
	info->dwVersion = 1;
	info->dwSupportStreamType = VF_STREAM_VIDEO|VF_STREAM_AUDIO;

	strcpy(info->cPluginInfo, "MPEG-2 VIDEO Plug-In");
	strcpy(info->cFileType, "MPEG-1/2 File |*.mpeg;*.mpg;*.m2p;*.mp2;*.vob;*.vro;*.m2v;*.m1v;*.mpv;*.ves;*.m2t;*.ssg;*.ts;*.bs");

	return VF_OK;
}

HRESULT __stdcall vfGetPluginFunc(LPVF_PluginFunc func)
{
	if(func == NULL){
		return VF_ERROR;
	}

	if(func->dwSize != sizeof(VF_PluginFunc)){
		return VF_ERROR;
	}

	func->OpenFile = open_file;
	func->CloseFile = close_file;
	func->GetFileInfo = get_file_info;
	func->GetStreamInfo = get_stream_info;
	func->ReadData = read_data;

	return VF_OK;
}

HRESULT __stdcall vfGetPluginFuncEditExt(LPVF_PluginFuncEditExt func_edit_ext)
{
	if(func_edit_ext == NULL){
		return VF_ERROR;
	}

	if(func_edit_ext->dwSize != sizeof(VF_PluginFuncEditExt)){
		return VF_ERROR;
	}

	func_edit_ext->GetFrameType = get_frame_type;
	func_edit_ext->Cut = cut;
	
	return VF_OK;
}

HRESULT __stdcall open_file(char *path, LPVF_FileHandle out)
{
	MPEG_DECODER **w;

	w = (MPEG_DECODER **)out;

	*w = (MPEG_DECODER *)malloc(sizeof(MPEG_DECODER));
	if(*w == NULL){
		return VF_ERROR;
	}

	(*w)->video = open_mpeg_video(path);
	(*w)->audio = open_mpeg_audio(path);

	if( ((*w)->video == NULL) && ((*w)->audio == NULL) ){
		free(*w);
		*w = NULL;
		return VF_ERROR;
	}

	return VF_OK;
}

HRESULT __stdcall close_file(VF_FileHandle p)
{
	MPEG_DECODER *w;

	w = (MPEG_DECODER *)p;

	if(w->video){
		close_mpeg_video(w->video);
		w->video = NULL;
	}
	if(w->audio){
		close_mpeg_audio(w->audio);
		w->audio = NULL;
	}

	free(w);
	
	return VF_OK;
}

HRESULT __stdcall get_file_info(VF_FileHandle in, LPVF_FileInfo out)
{
	MPEG_DECODER *w;

	w = (MPEG_DECODER *)in;
	
	if(out == NULL){
		return VF_ERROR;
	}

	if(out->dwSize != sizeof(VF_FileInfo)){
		return VF_ERROR;
	}
	out->dwHasStreams = 0;
	if(w->video){
		out->dwHasStreams |= VF_STREAM_VIDEO;
	}
	if(w->audio){
		out->dwHasStreams |= VF_STREAM_AUDIO;
	}

	return VF_OK;
}

HRESULT __stdcall get_stream_info(VF_FileHandle in, DWORD s, void *out)
{
	MPEG_DECODER *w;

	w = (MPEG_DECODER *)in;
	
	if(s == VF_STREAM_VIDEO){
		return get_stream_info_video(w->video, (VF_StreamInfo_Video *)out);
	}else if(s == VF_STREAM_AUDIO){
		return get_stream_info_audio(w->audio, (VF_StreamInfo_Audio *)out);
	}
	return VF_ERROR;
}

static HRESULT get_stream_info_video(MPEG_VIDEO *in, VF_StreamInfo_Video *out)
{
	if(out == NULL){
		return VF_ERROR;
	}
	
	if(out->dwSize != sizeof(VF_StreamInfo_Video)){
		return VF_ERROR;
	}

	out->dwLengthL = (DWORD)(in->total & 0xffffffff);
	out->dwLengthH = (DWORD)(in->total >> 32);
	out->dwRate = in->rate;
	out->dwScale = in->scale;
	out->dwWidth = in->width;
	out->dwHeight = in->height;
	out->dwBitCount = 24;

	return VF_OK;
}

static HRESULT get_stream_info_audio(MPEG_AUDIO *in, VF_StreamInfo_Audio *out)
{
	if(out == NULL){
		return VF_ERROR;
	}

	if(out->dwSize != sizeof(VF_StreamInfo_Audio)){
		return VF_ERROR;
	}

	out->dwLengthL = (DWORD)(in->sample & 0xffffffff);
	out->dwLengthH = (DWORD)(in->sample >> 32);
	out->dwRate = in->frequency;
	out->dwScale = 1;
	out->dwChannels = in->channel;
	out->dwBitsPerSample = 16;
	out->dwBlockAlign = in->channel * sizeof(short);

	return VF_OK;
}
	
HRESULT __stdcall read_data(VF_FileHandle in, DWORD s, void *out)
{
	MPEG_DECODER *w;

	w = (MPEG_DECODER *)in;
	
	if(s == VF_STREAM_VIDEO){
		return read_data_video(w->video, (VF_ReadData_Video *)out);
	}else if(s == VF_STREAM_AUDIO){
		return read_data_audio(w->audio, (VF_ReadData_Audio *)out);
	}

	return VF_ERROR;
}

static HRESULT read_data_video(MPEG_VIDEO *in, VF_ReadData_Video *out)
{
	OUT_BUFFER_ELEMENT *top;
	OUT_BUFFER_ELEMENT *bottom;
	
	unsigned char *dst;

	__int64 frame;
	
	if(out == NULL){
		return VF_ERROR;
	}
	
	if(out->dwSize != sizeof(VF_ReadData_Video)){
		return VF_ERROR;
	}

	frame = out->dwFrameNumberL;
	frame += ((__int64)out->dwFrameNumberH) << 32;

	switch(in->config.field_mode){
	case 0: /* keep original frame */
		top = read_frame(in, frame);
		bottom = top;
		if(top == NULL){
			__asm{emms};
			return VF_ERROR;
		}
		break;
	case 1: /* top field first */
		top = read_frame(in, frame);
		if(top == NULL){
			__asm{emms};
			return VF_ERROR;
		}
		bottom = NULL;
		if( (!top->prm.top_field_first) && (!top->prm.repeat_first_field) ){
			bottom = read_frame(in, frame+1);
		}
		if(bottom == NULL){
			bottom = top;
		}

		break;
	case 2: /* bottom field first */
		bottom = read_frame(in, frame);
		if(bottom == NULL){
			__asm{emms};
			return VF_ERROR;
		}
		top = NULL;
		if( bottom->prm.top_field_first && (!bottom->prm.repeat_first_field) ){
			top = read_frame(in, frame+1);
		}
		if(top == NULL){
			top = bottom;
		}
		break;
	default:
		top = read_frame(in, frame);
		bottom = top;
		if(top == NULL){
			__asm{emms};
			return VF_ERROR;
		}
	}
	
	dst = (unsigned char *)out->lpData;
	
	in->bgr_prm.prm.out_step = out->lPitch;
	in->to_bgr(top->data, bottom->data, dst, &(in->bgr_prm));

	__asm{emms};

	return VF_OK;
}

static HRESULT read_data_audio(MPEG_AUDIO *in, VF_ReadData_Audio *out)
{
	__int64 sample;
	
	if(in == NULL){
		return VF_ERROR;
	}
	if(out == NULL){
		return VF_ERROR;
	}
	if(out->dwSize != sizeof(VF_ReadData_Audio)){
		return VF_ERROR;
	}

	sample = out->dwSamplePosL;
	sample |= ((__int64)out->dwSamplePosH) << 32;

	out->dwReadedSampleCount = read_mpeg_audio(in, sample, out->lpBuf, out->dwSampleCount);
	if(out->dwReadedSampleCount){
		return VF_OK;
	}

	return VF_ERROR;
}

HRESULT __stdcall get_frame_type(VF_FileHandle in, LPVF_FrameType out)
{
	__int64 frame;

	MPEG_VIDEO *w;
	int type;

	if(out == NULL){
		return VF_ERROR;
	}

	if(out->dwSize != sizeof(VF_FrameType)){
		return VF_ERROR;
	}

	w = ((MPEG_DECODER *)in)->video;
	if(w == NULL){
		return VF_ERROR;
	}

	frame = out->dwFrameNumberL;
	frame += ((__int64)(out->dwFrameNumberH)) << 32;

	type = get_picture_coding_type(w, frame);

	switch(type){
	case 1:
		/* I picture */
		out->dwFrameType = VF_FRAME_TYPE_STARTABLE|VF_FRAME_TYPE_ENDABLE;
		break;
	case 2:
		/* P picture */
		out->dwFrameType = VF_FRAME_TYPE_ENDABLE;
		break;
	case 3:
		/* B picture */
		out->dwFrameType = VF_FRAME_TYPE_UNEDITABLE;
		break;
	case 4:
		/* B picture with closed gop */
		out->dwFrameType = VF_FRAME_TYPE_STARTABLE;
		break;
	default:
		/* unknown picture */
		out->dwFrameType = VF_FRAME_TYPE_UNEDITABLE;
	}

	return VF_OK;
}

HRESULT __stdcall cut(VF_FileHandle in, LPVF_CutOption opt)
{
	__int64 in_frame;
	__int64 out_frame;
	
	MPEG_VIDEO *w;
	MPEG2EDIT mpeg2edit;

	if(opt == NULL){
		return VF_ERROR;
	}

	if(opt->dwSize != sizeof(VF_CutOption)){
		return VF_ERROR;
	}

	w = ((MPEG_DECODER *)in)->video;
	if(w == NULL){
		return VF_ERROR;
	}

	if( !open_mpeg2edit(w->bitstream.path, &mpeg2edit) ){
		return VF_ERROR;
	}

	if(opt->Callback != NULL){
		mpeg2edit.callback = opt->Callback;
	}

	in_frame = opt->dwInPointH;
	in_frame <<= 32;
	in_frame += opt->dwInPointL;

	out_frame = opt->dwOutPointH;
	out_frame <<= 32;
	out_frame += opt->dwOutPointL;

	mpeg2edit.edit(&mpeg2edit, opt->lpOutputFileName, in_frame, out_frame);

	mpeg2edit.close(&mpeg2edit);

	return VF_OK;
}

⌨️ 快捷键说明

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