📄 video_dialog.cpp
字号:
/*
* 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 + -