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

📄 video_dialog.cpp

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 * 
 * The Original Code is MPEG4IP.
 * 
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
 * 
 * Contributor(s): 
 *		Dave Mackie		dmackie@cisco.com
 *		Bill May 		wmay@cisco.com
 */

#define __STDC_LIMIT_MACROS
#include "mp4live.h"
#include "mp4live_gui.h"
#include "video_v4l_source.h"

static GtkWidget *dialog;

static char* source_type;
static char* source_name;
static GtkWidget *source_combo;
static GtkWidget *source_entry;
static GtkWidget *source_list;
static GtkWidget *browse_button;
static bool source_modified;
static bool default_file_audio_dialog = false;
static int32_t default_file_audio_source = -1;
static GtkWidget *input_label;
static GtkWidget *input_menu;
static GtkWidget *signal_label;
static GtkWidget *signal_menu;
static GSList* signal_menu_items;
static GtkWidget *channel_list_label;
static GtkWidget *channel_list_menu;
static GtkWidget *channel_label;
static GtkWidget *channel_combo;
static GtkWidget *track_label;
static GtkWidget *track_menu;
static GtkWidget *size_menu;
static GtkWidget *aspect_menu;
static GtkObject *frame_rate_ntsc_adjustment;
static GtkObject *frame_rate_pal_adjustment;
static GtkWidget *frame_rate_spinner;
static GtkWidget *bit_rate_spinner;

static CVideoCapabilities* pVideoCaps;

static char** inputNames = NULL;
static u_int8_t inputIndex = 0;
static u_int8_t inputNumber = 0;	// how many inputs total

static char* signalNames[] = {
	"PAL", "NTSC", "SECAM"
};
static u_int8_t signalIndex;

static u_int8_t channelListIndex;

static u_int8_t channelIndex;

static u_int32_t trackIndex;
static u_int32_t trackNumber;	// how many tracks total
static u_int32_t* trackValues = NULL;

static u_int16_t sizeWidthValues[] = {
	128, 176, 320, 352, 352,
	640, 704, 704, 720, 720, 768
};
static u_int16_t sizeHeightValues[] = {
	96, 144, 240, 288, 480,
	480, 480, 576, 480, 576, 576
};
static char* sizeNames[] = {
	"128 x 96 SQCIF", 
	"176 x 144 QCIF",
	"320 x 240 SIF",
	"352 x 288 CIF",
	"352 x 480 Half D1",
	"640 x 480 4SIF",
	"704 x 480 D1",
	"704 x 576 4CIF",
	"720 x 480 NTSC CCIR601",
	"720 x 576 PAL CCIR601",
	"768 x 576 PAL SQ Pixel"
};
static u_int8_t sizeIndex;
static u_int8_t sizeMaxIndex;

static float aspectValues[] = {
	VIDEO_STD_ASPECT_RATIO, VIDEO_LB1_ASPECT_RATIO, 
	VIDEO_LB2_ASPECT_RATIO, VIDEO_LB3_ASPECT_RATIO
}; 
static char* aspectNames[] = {
	"Standard 4:3", "Letterbox 2.35", "Letterbox 1.85", "HDTV 16:9"
};
static u_int8_t aspectIndex;

// forward declarations
static void SetAvailableSignals(void);

static void on_destroy_dialog (GtkWidget *widget, gpointer *data)
{
	gtk_grab_remove(dialog);
	gtk_widget_destroy(dialog);
	dialog = NULL;
} 

static bool SourceIsDevice()
{
	return IsDevice(gtk_entry_get_text(GTK_ENTRY(source_entry)));
}

static void ShowSourceSpecificSettings()
{
	if (SourceIsDevice()) {
		gtk_widget_show(input_label);
		gtk_widget_show(input_menu);
		gtk_widget_show(signal_label);
		gtk_widget_show(signal_menu);
		gtk_widget_show(channel_list_label);
		gtk_widget_show(channel_list_menu);
		gtk_widget_show(channel_label);
		gtk_widget_show(channel_combo);

		gtk_widget_hide(track_label);
		gtk_widget_hide(track_menu);
	} else {
		gtk_widget_hide(input_label);
		gtk_widget_hide(input_menu);
		gtk_widget_hide(signal_label);
		gtk_widget_hide(signal_menu);
		gtk_widget_hide(channel_list_label);
		gtk_widget_hide(channel_list_menu);
		gtk_widget_hide(channel_label);
		gtk_widget_hide(channel_combo);

		gtk_widget_show(track_label);
		gtk_widget_show(track_menu);
	}
}

static void EnableChannels()
{
	bool hasTuner = false;

	if (pVideoCaps && pVideoCaps->m_inputHasTuners[inputIndex]) {
		hasTuner = true;
	}

	gtk_widget_set_sensitive(GTK_WIDGET(channel_list_menu), hasTuner);
	gtk_widget_set_sensitive(GTK_WIDGET(channel_combo), hasTuner);
}

static void ChangeInput(u_int8_t newIndex)
{
	inputIndex = newIndex;
	SetAvailableSignals();
	EnableChannels();
}

static void on_input_menu_activate(GtkWidget *widget, gpointer data)
{
	ChangeInput(((unsigned int)data) & 0xFF);
}

void CreateInputMenu(CVideoCapabilities* pNewVideoCaps)
{
	u_int8_t newInputNumber;
	if (pNewVideoCaps) {
		newInputNumber = pNewVideoCaps->m_numInputs;
	} else {
		newInputNumber = 0;
	}

	if (inputIndex >= newInputNumber) {
		inputIndex = 0; 
	}

	// create new menu item names
	char** newInputNames = (char**)malloc(sizeof(char*) * newInputNumber);

	for (u_int8_t i = 0; i < newInputNumber; i++) {
		char buf[64];
		snprintf(buf, sizeof(buf), "%u - %s",
			i, pNewVideoCaps->m_inputNames[i]);
		newInputNames[i] = stralloc(buf);
	}

	// (re)create the menu
	input_menu = CreateOptionMenu(
		input_menu,
		newInputNames, 
		newInputNumber,
		inputIndex,
		GTK_SIGNAL_FUNC(on_input_menu_activate));

	// free up old names
	for (u_int8_t i = 0; i < inputNumber; i++) {
		free(inputNames[i]);
	}
	free(inputNames);
	inputNames = newInputNames;
	inputNumber = newInputNumber;
}

static void SourceV4LDevice()
{
	char *newSourceName =
		gtk_entry_get_text(GTK_ENTRY(source_entry));

	// don't probe the already open device!
	if (!strcmp(newSourceName, 
	  MyConfig->GetStringValue(CONFIG_VIDEO_SOURCE_NAME))) {
		return;
	}

	// probe new source device
	CVideoCapabilities* pNewVideoCaps = 
		new CVideoCapabilities(newSourceName);
	
	// check for errors
	if (!pNewVideoCaps->IsValid()) {
		if (!pNewVideoCaps->m_canOpen) {
			ShowMessage("Change Video Source",
				"Specified video source can't be opened, check name");
		} else {
			ShowMessage("Change Video Source",
				"Specified video source doesn't support capture");
		}
		delete pNewVideoCaps;
		return;
	}

	// change inputs menu
	CreateInputMenu(pNewVideoCaps);

	if (pVideoCaps != MyConfig->m_videoCapabilities) {
		delete pVideoCaps;
	}
	pVideoCaps = pNewVideoCaps;

	ChangeInput(inputIndex);
}

static void on_yes_default_file_audio_source (GtkWidget *widget, gpointer *data)
{
	default_file_audio_source = 
		FileDefaultAudio(gtk_entry_get_text(GTK_ENTRY(source_entry)));

	default_file_audio_dialog = false;
}

static void on_no_default_file_audio_source (GtkWidget *widget, gpointer *data)
{
	default_file_audio_dialog = false;
}

static void ChangeSource()
{
	char* new_source_name =
		gtk_entry_get_text(GTK_ENTRY(source_entry));

	if (!strcmp(new_source_name, source_name)) {
		source_modified = false;
		return;
	}

	free(source_name);
	source_name = stralloc(new_source_name);

	default_file_audio_source = -1;

	// decide what type of source we have
	if (SourceIsDevice()) {
		source_type = VIDEO_SOURCE_V4L;

		SourceV4LDevice();
	} else {
		if (pVideoCaps != MyConfig->m_videoCapabilities) {
			delete pVideoCaps;
		}
		pVideoCaps = NULL;

		if (IsUrl(source_name)) {
			source_type = URL_SOURCE;
		} else {
			if (access(source_name, R_OK) != 0) {
				ShowMessage("Change Video Source",
					"Specified video source can't be opened, check name");
			}
			source_type = FILE_SOURCE;
		}

		if (!default_file_audio_dialog
		  && FileDefaultAudio(source_name) >= 0) {
			YesOrNo(
				"Change Video Source",
				"Do you want to use this for the audio source also?",
				true,
				GTK_SIGNAL_FUNC(on_yes_default_file_audio_source),
				GTK_SIGNAL_FUNC(on_no_default_file_audio_source));
		}
	}

	track_menu = CreateTrackMenu(
		track_menu,
		'V',
		source_name,
		&trackIndex,
		&trackNumber,
		&trackValues);

	ShowSourceSpecificSettings();

	source_modified = false;
}

static void on_source_browse_button (GtkWidget *widget, gpointer *data)
{
	FileBrowser(source_entry, GTK_SIGNAL_FUNC(ChangeSource));
}

static void on_source_entry_changed(GtkWidget *widget, gpointer *data)
{
	if (widget == source_entry) {
		source_modified = true;
	}
}

static void on_source_leave(GtkWidget *widget, gpointer *data)
{
	if (source_modified) {
		ChangeSource();
	}
}

static void on_source_list_changed(GtkWidget *widget, gpointer *data)
{
	if (widget == source_list) {
		ChangeSource();
	}
}


char* GetChannelName(size_t index, void* pUserData)
{
	return ((struct CHANNEL*)pUserData)[index].name;
}

static void CreateChannelCombo()
{
	struct CHANNEL_LIST* pChannelList =
		ListOfChannelLists[signalIndex];

	GList* list = NULL;
	for (int i = 0; i < pChannelList[channelListIndex].count; i++) {
		list = g_list_append(list, 
			pChannelList[channelListIndex].list[i].name);
	}

	channel_combo = gtk_combo_new();
	gtk_combo_set_popdown_strings(GTK_COMBO(channel_combo), list);
	// although we do want to limit the combo choices to the ones we provide
	// this call results is some odd UI behaviors
	// gtk_combo_set_value_in_list(GTK_COMBO(channel_combo), 1, 0);
	gtk_combo_set_use_arrows_always(GTK_COMBO(channel_combo), 1);

	GtkWidget* entry = GTK_COMBO(channel_combo)->entry;
	gtk_entry_set_text(GTK_ENTRY(entry), 
		pChannelList[channelListIndex].list[channelIndex].name);

	gtk_widget_show(channel_combo);
}

void ChangeChannelList(u_int8_t newIndex)
{
	channelListIndex = newIndex;

	// change channel index to zero
	channelIndex = 0;

	// recreate channel menu
	CreateChannelCombo();
}

static void on_channel_list_menu_activate(GtkWidget *widget, gpointer data)
{
	ChangeChannelList((unsigned int)data & 0xFF);
}

char* GetChannelListName(size_t index, void* pUserData)
{
	return ((struct CHANNEL_LIST*)pUserData)[index].name;
}

static void CreateChannelListMenu()
{
	struct CHANNEL_LIST* pChannelList =
		ListOfChannelLists[signalIndex];

	channel_list_menu = CreateOptionMenu(
		channel_list_menu,
		GetChannelListName,
		pChannelList,
		0xFF,
		channelListIndex,
		GTK_SIGNAL_FUNC(on_channel_list_menu_activate));
}

static void on_size_menu_activate(GtkWidget *widget, gpointer data)
{
	sizeIndex = ((unsigned int)data) & 0xFF;
}

static void CreateSizeMenu()
{
	sizeMaxIndex = sizeof(sizeNames) / sizeof(char*);
	if (signalIndex == 1) {
		// NTSC can't support the two largest sizes
		sizeMaxIndex -= 2;
	}

	if (sizeIndex >= sizeMaxIndex) {
		sizeIndex = sizeMaxIndex - 1;
	}

	size_menu = CreateOptionMenu(
		size_menu,
		sizeNames, 
		sizeMaxIndex,
		sizeIndex,
		GTK_SIGNAL_FUNC(on_size_menu_activate));
}

void ChangeSignal(u_int8_t newIndex)
{
	signalIndex = newIndex;

	CreateChannelListMenu();
	ChangeChannelList(0);
	
	CreateSizeMenu();

	// change max frame rate spinner
	if (signalIndex == 1) {
		// NTSC 
		gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(frame_rate_spinner),
			GTK_ADJUSTMENT(frame_rate_ntsc_adjustment));
	} else {
		// PAL or SECAM
		float frameRate = gtk_spin_button_get_value_as_float(

⌨️ 快捷键说明

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