📄 gui_main.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
*/
/*
* gui_main.cpp - Contains the gtk based gui
*/
#define __STDC_LIMIT_MACROS
#include "mp4live.h"
#include "mp4live_gui.h"
#include "gdk/gdkx.h"
CLiveConfig* MyConfig;
CAVMediaFlow* AVFlow;
/* Local variables */
static bool started = false;
static GtkWidget *main_window;
static GtkWidget *main_hbox;
static GtkWidget *main_vbox1;
static GtkWidget *main_vbox2;
static GtkWidget *video_preview;
static GtkWidget *video_enabled_button;
static GSList *video_preview_radio_group;
static GtkWidget *video_none_preview_button;
static GtkWidget *video_raw_preview_button;
static GtkWidget *video_encoded_preview_button;
static GtkWidget *video_settings_label1;
static GtkWidget *video_settings_label2;
static GtkWidget *video_settings_label3;
static GtkWidget *video_settings_button;
static GtkWidget *audio_enabled_button;
static GtkWidget *audio_mute_button;
static GtkWidget *audio_settings_label1;
static GtkWidget *audio_settings_label2;
static GtkWidget *audio_settings_label3;
static GtkWidget *audio_settings_button;
static GtkWidget *record_enabled_button;
static GtkWidget *record_settings_label;
static GtkWidget *record_settings_button;
static GtkWidget *transmit_enabled_button;
static GtkWidget *transmit_settings_label;
static GtkWidget *transmit_settings_button;
static GtkWidget *start_button;
static GtkWidget *start_button_label;
static GtkWidget *duration_spinner;
static GtkWidget *duration_units_menu;
static GtkWidget *config_file_entry;
static GtkWidget *load_config_button;
static GtkWidget *save_config_button;
static u_int16_t durationUnitsValues[] = {
1, 60, 3600
};
static char* durationUnitsNames[] = {
"Seconds", "Minutes", "Hours"
};
static u_int8_t durationUnitsIndex = 1;
static GtkWidget *media_source_label;
static GtkWidget *media_source;
static GtkWidget *start_time_label;
static GtkWidget *start_time;
static GtkWidget *start_time_units;
static GtkWidget *duration_label;
static GtkWidget *duration;
static GtkWidget *duration_units;
static GtkWidget *current_time_label;
static GtkWidget *current_time;
static GtkWidget *current_time_units;
static GtkWidget *finish_time_label;
static GtkWidget *finish_time;
static GtkWidget *finish_time_units;
static GtkWidget *current_size_label;
static GtkWidget *current_size;
static GtkWidget *current_size_units;
static GtkWidget *final_size_label;
static GtkWidget *final_size;
static GtkWidget *final_size_units;
static GtkWidget *actual_fps_label;
static GtkWidget *actual_fps;
static GtkWidget *actual_fps_units;
static Timestamp StartTime;
static Timestamp StopTime;
static Duration FlowDuration;
static u_int32_t StartEncodedFrameNumber;
static u_int64_t StartFileSize;
static u_int64_t StopFileSize;
/*
* delete_event - called when window closed
*/
static void delete_event (GtkWidget *widget, gpointer *data)
{
gtk_main_quit();
}
void NewVideoWindow()
{
// We use the Gtk Preview widget to get the right type of window created
// and then hand it over to SDL to actually do the blitting
if (video_preview != NULL) {
gtk_container_remove(GTK_CONTAINER(main_vbox1),
GTK_WIDGET(video_preview));
video_preview = NULL;
}
video_preview = gtk_preview_new(GTK_PREVIEW_COLOR);
gtk_preview_size(GTK_PREVIEW(video_preview),
MyConfig->m_videoWidth, MyConfig->m_videoHeight);
gtk_widget_show(video_preview);
gtk_box_pack_start(GTK_BOX(main_vbox1), video_preview, FALSE, FALSE, 5);
// Let video source know which window to draw into
gtk_widget_realize(video_preview); // so XCreateWindow() is called
if (video_preview->window) {
MyConfig->m_videoPreviewWindowId =
GDK_WINDOW_XWINDOW(video_preview->window);
}
}
void DisplayVideoSettings(void)
{
char buffer[256];
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(video_enabled_button),
MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE));
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(video_none_preview_button),
!MyConfig->GetBoolValue(CONFIG_VIDEO_PREVIEW));
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(video_raw_preview_button),
MyConfig->GetBoolValue(CONFIG_VIDEO_PREVIEW)
&& MyConfig->GetBoolValue(CONFIG_VIDEO_RAW_PREVIEW));
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(video_encoded_preview_button),
MyConfig->GetBoolValue(CONFIG_VIDEO_PREVIEW)
&& MyConfig->GetBoolValue(CONFIG_VIDEO_ENCODED_PREVIEW));
snprintf(buffer, sizeof(buffer), " MPEG-4 at %u kbps",
MyConfig->GetIntegerValue(CONFIG_VIDEO_BIT_RATE));
gtk_label_set_text(GTK_LABEL(video_settings_label1), buffer);
gtk_widget_show(video_settings_label1);
snprintf(buffer, sizeof(buffer), " %u x %u @ %.2f fps",
MyConfig->m_videoWidth,
MyConfig->m_videoHeight,
MyConfig->GetFloatValue(CONFIG_VIDEO_FRAME_RATE));
gtk_label_set_text(GTK_LABEL(video_settings_label2), buffer);
gtk_widget_show(video_settings_label2);
}
void DisplayAudioSettings(void)
{
char buffer[256];
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(audio_enabled_button),
MyConfig->GetBoolValue(CONFIG_AUDIO_ENABLE));
char* encoding;
if (!strcasecmp(MyConfig->GetStringValue(CONFIG_AUDIO_ENCODING),
AUDIO_ENCODING_AAC)) {
encoding = "AAC";
} else {
encoding = "MP3";
}
snprintf(buffer, sizeof(buffer), " %s at %u kbps",
encoding,
MyConfig->GetIntegerValue(CONFIG_AUDIO_BIT_RATE));
gtk_label_set_text(GTK_LABEL(audio_settings_label1), buffer);
gtk_widget_show(audio_settings_label1);
snprintf(buffer, sizeof(buffer), " %s @ %u Hz",
(MyConfig->GetIntegerValue(CONFIG_AUDIO_CHANNELS) == 2
? "Stereo" : "Mono"),
MyConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE));
gtk_label_set_text(GTK_LABEL(audio_settings_label2), buffer);
gtk_widget_show(audio_settings_label2);
}
void DisplayTransmitSettings (void)
{
char buffer[256];
const char *addr = MyConfig->GetStringValue(CONFIG_RTP_DEST_ADDRESS);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(transmit_enabled_button),
MyConfig->GetBoolValue(CONFIG_RTP_ENABLE));
if (addr == NULL) {
gtk_label_set_text(GTK_LABEL(transmit_settings_label),
"RTP/UDP to <Automatic Multicast>");
} else {
snprintf(buffer, sizeof(buffer), " RTP/UDP to %s", addr);
gtk_label_set_text(GTK_LABEL(transmit_settings_label), buffer);
}
gtk_widget_show(transmit_settings_label);
}
void DisplayRecordingSettings(void)
{
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_enabled_button),
MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE));
char* fileName = strrchr(
MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME), '/');
if (!fileName) {
fileName = MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME);
} else {
fileName++;
}
char buffer[256];
snprintf(buffer, sizeof(buffer), " %s", fileName);
gtk_label_set_text(GTK_LABEL(record_settings_label), buffer);
gtk_widget_show(record_settings_label);
}
void DisplayControlSettings(void)
{
// duration
gtk_spin_button_set_value(
GTK_SPIN_BUTTON(duration_spinner),
(gfloat)MyConfig->GetIntegerValue(CONFIG_APP_DURATION));
// duration units
for (u_int8_t i = 0;
i < sizeof(durationUnitsValues) / sizeof(u_int16_t); i++) {
if (MyConfig->GetIntegerValue(CONFIG_APP_DURATION_UNITS)
== durationUnitsValues[i]) {
durationUnitsIndex = i;
break;
}
}
gtk_option_menu_set_history(
GTK_OPTION_MENU(duration_units_menu),
durationUnitsIndex);
gtk_widget_show(duration_units_menu);
}
void DisplayStatusSettings(void)
{
// media source
char buffer[128];
buffer[0] = '\0';
if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)
&& MyConfig->GetBoolValue(CONFIG_AUDIO_ENABLE)
&& strcmp(MyConfig->GetStringValue(CONFIG_VIDEO_SOURCE_NAME),
MyConfig->GetStringValue(CONFIG_AUDIO_SOURCE_NAME))) {
snprintf(buffer, sizeof(buffer), "%s & %s",
MyConfig->GetStringValue(CONFIG_VIDEO_SOURCE_NAME),
MyConfig->GetStringValue(CONFIG_AUDIO_SOURCE_NAME));
gtk_label_set_text(GTK_LABEL(media_source), buffer);
} else if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
gtk_label_set_text(GTK_LABEL(media_source),
MyConfig->GetStringValue(CONFIG_VIDEO_SOURCE_NAME));
} else if (MyConfig->GetBoolValue(CONFIG_AUDIO_ENABLE)) {
gtk_label_set_text(GTK_LABEL(media_source),
MyConfig->GetStringValue(CONFIG_AUDIO_SOURCE_NAME));
}
}
void DisplayAllSettings()
{
DisplayVideoSettings();
DisplayAudioSettings();
DisplayRecordingSettings();
DisplayTransmitSettings();
DisplayControlSettings();
DisplayStatusSettings();
}
void DisplayFinishTime(Timestamp t)
{
time_t secs;
const struct tm *local;
char buffer[128];
secs = (time_t)GetSecsFromTimestamp(t);
local = localtime(&secs);
strftime(buffer, sizeof(buffer), "%l:%M:%S", local);
gtk_label_set_text(GTK_LABEL(finish_time), buffer);
gtk_widget_show(finish_time);
strftime(buffer, sizeof(buffer), "%p", local);
gtk_label_set_text(GTK_LABEL(finish_time_units), buffer);
gtk_widget_show(finish_time_units);
}
static void on_video_enabled_button (GtkWidget *widget, gpointer *data)
{
MyConfig->SetBoolValue(CONFIG_VIDEO_ENABLE,
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
AVFlow->StartVideoPreview();
} else {
AVFlow->StopVideoPreview();
}
}
static void on_video_preview_button (GtkWidget *widget, gpointer *data)
{
MyConfig->SetBoolValue(CONFIG_VIDEO_PREVIEW,
!gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(video_none_preview_button)));
MyConfig->SetBoolValue(CONFIG_VIDEO_RAW_PREVIEW,
gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(video_raw_preview_button)));
MyConfig->SetBoolValue(CONFIG_VIDEO_ENCODED_PREVIEW,
gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(video_encoded_preview_button)));
MyConfig->UpdateVideo();
}
static void on_video_settings_button (GtkWidget *widget, gpointer *data)
{
CreateVideoDialog();
}
static void on_audio_enabled_button (GtkWidget *widget, gpointer *data)
{
MyConfig->SetBoolValue(CONFIG_AUDIO_ENABLE,
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
}
static void on_audio_mute_button (GtkWidget *widget, gpointer *data)
{
AVFlow->SetAudioOutput(
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
}
static void on_audio_settings_button (GtkWidget *widget, gpointer *data)
{
CreateAudioDialog();
}
static void on_record_enabled_button (GtkWidget *widget, gpointer *data)
{
MyConfig->SetBoolValue(CONFIG_RECORD_ENABLE,
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
}
static void on_record_settings_button (GtkWidget *widget, gpointer *data)
{
CreateRecordingDialog();
}
static void on_transmit_enabled_button (GtkWidget *widget, gpointer *data)
{
MyConfig->SetBoolValue(CONFIG_RTP_ENABLE,
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
}
static void on_transmit_settings_button (GtkWidget *widget, gpointer *data)
{
CreateTransmitDialog();
}
static void LockoutChanges(bool lockout)
{
gtk_widget_set_sensitive(GTK_WIDGET(video_enabled_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(video_settings_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(audio_enabled_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(audio_settings_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(record_enabled_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(record_settings_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(transmit_enabled_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(transmit_settings_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(duration_spinner), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(duration_units_menu), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(config_file_entry), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(load_config_button), !lockout);
gtk_widget_set_sensitive(GTK_WIDGET(save_config_button), !lockout);
}
static guint status_timer_id;
// forward declaration
static void on_start_button (GtkWidget *widget, gpointer *data);
static void status_start()
{
time_t secs;
const struct tm *local;
char buffer[128];
// start time
secs = (time_t)GetSecsFromTimestamp(StartTime);
local = localtime(&secs);
strftime(buffer, sizeof(buffer), "%l:%M:%S", local);
gtk_label_set_text(GTK_LABEL(start_time), buffer);
gtk_widget_show(start_time);
strftime(buffer, sizeof(buffer), "%p", local);
gtk_label_set_text(GTK_LABEL(start_time_units), buffer);
gtk_widget_show(start_time_units);
// finish time
if (StopTime) {
DisplayFinishTime(StopTime);
}
// file size
StartFileSize = 0;
StopFileSize = 0;
if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)) {
if (!MyConfig->GetBoolValue(CONFIG_RECORD_MP4_OVERWRITE)) {
struct stat stats;
stat(MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME), &stats);
StartFileSize = stats.st_size;
}
snprintf(buffer, sizeof(buffer), " %llu",
StartFileSize / 1000000);
gtk_label_set_text(GTK_LABEL(current_size), buffer);
gtk_widget_show(current_size);
gtk_label_set_text(GTK_LABEL(current_size_units), "MB");
gtk_widget_show(current_size_units);
StopFileSize = MyConfig->m_recordEstFileSize;
snprintf(buffer, sizeof(buffer), " %llu",
StopFileSize / 1000000);
gtk_label_set_text(GTK_LABEL(final_size), buffer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -