gui_main.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:43k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  * Bill May  wmay@cisco.com
  21.  */
  22. /*
  23.  * gui_main.cpp - Contains the gtk based gui 
  24.  */
  25. #define __STDC_LIMIT_MACROS
  26. #include "mp4live.h"
  27. #include "mp4live_gui.h"
  28. #include "gdk/gdkx.h"
  29. CLiveConfig* MyConfig;
  30. CAVMediaFlow* AVFlow;
  31. /* Local variables */
  32. static bool started = false;
  33. static GtkWidget *main_window;
  34. static GtkWidget *main_hbox;
  35. static GtkWidget *main_vbox1;
  36. static GtkWidget *main_vbox2;
  37. static GtkWidget *video_preview;
  38. static GtkWidget *video_enabled_button;
  39. static GSList  *video_preview_radio_group;
  40. static GtkWidget *video_none_preview_button;
  41. static GtkWidget *video_raw_preview_button;
  42. static GtkWidget *video_encoded_preview_button;
  43. static GtkWidget *video_settings_label1;
  44. static GtkWidget *video_settings_label2;
  45. static GtkWidget *video_settings_label3;
  46. static GtkWidget *video_settings_button;
  47. static GtkWidget *audio_enabled_button;
  48. static GtkWidget *audio_mute_button;
  49. static GtkWidget *audio_settings_label1;
  50. static GtkWidget *audio_settings_label2;
  51. static GtkWidget *audio_settings_label3;
  52. static GtkWidget *audio_settings_button;
  53. static GtkWidget *record_enabled_button;
  54. static GtkWidget *record_settings_label;
  55. static GtkWidget *record_settings_button;
  56. static GtkWidget *transmit_enabled_button;
  57. static GtkWidget *transmit_settings_label;
  58. static GtkWidget *transmit_settings_button;
  59. static GtkWidget *start_button;
  60. static GtkWidget *start_button_label;
  61. static GtkWidget *duration_spinner;
  62. static GtkWidget *duration_units_menu;
  63. static GtkWidget *config_file_entry;
  64. static GtkWidget *load_config_button;
  65. static GtkWidget *save_config_button;
  66. static u_int16_t durationUnitsValues[] = {
  67. 1, 60, 3600
  68. };
  69. static char* durationUnitsNames[] = {
  70. "Seconds", "Minutes", "Hours"
  71. };
  72. static u_int8_t durationUnitsIndex = 1;
  73. static GtkWidget *media_source_label;
  74. static GtkWidget *media_source;
  75. static GtkWidget *start_time_label;
  76. static GtkWidget *start_time;
  77. static GtkWidget *start_time_units;
  78. static GtkWidget *duration_label;
  79. static GtkWidget *duration;
  80. static GtkWidget *duration_units;
  81. static GtkWidget *current_time_label;
  82. static GtkWidget *current_time;
  83. static GtkWidget *current_time_units;
  84. static GtkWidget *finish_time_label;
  85. static GtkWidget *finish_time;
  86. static GtkWidget *finish_time_units;
  87. static GtkWidget *current_size_label;
  88. static GtkWidget *current_size;
  89. static GtkWidget *current_size_units;
  90. static GtkWidget *final_size_label;
  91. static GtkWidget *final_size;
  92. static GtkWidget *final_size_units;
  93. static GtkWidget *actual_fps_label;
  94. static GtkWidget *actual_fps;
  95. static GtkWidget *actual_fps_units;
  96. static Timestamp StartTime;
  97. static Timestamp StopTime;
  98. static Duration FlowDuration;
  99. static u_int32_t StartEncodedFrameNumber;
  100. static u_int64_t StartFileSize;
  101. static u_int64_t StopFileSize;
  102. /*
  103.  * delete_event - called when window closed
  104.  */
  105. static void delete_event (GtkWidget *widget, gpointer *data)
  106. {
  107. gtk_main_quit();
  108. }
  109. void NewVideoWindow()
  110. {
  111. // We use the Gtk Preview widget to get the right type of window created
  112. // and then hand it over to SDL to actually do the blitting
  113. if (video_preview != NULL) {
  114. gtk_container_remove(GTK_CONTAINER(main_vbox1), 
  115. GTK_WIDGET(video_preview));
  116. video_preview = NULL;
  117. }
  118. video_preview = gtk_preview_new(GTK_PREVIEW_COLOR);
  119. gtk_preview_size(GTK_PREVIEW(video_preview), 
  120. MyConfig->m_videoWidth, MyConfig->m_videoHeight);
  121. gtk_widget_show(video_preview);
  122. gtk_box_pack_start(GTK_BOX(main_vbox1), video_preview, FALSE, FALSE, 5);
  123. // Let video source know which window to draw into
  124. gtk_widget_realize(video_preview); // so XCreateWindow() is called
  125. if (video_preview->window) {
  126. MyConfig->m_videoPreviewWindowId = 
  127. GDK_WINDOW_XWINDOW(video_preview->window);
  128. }
  129. }
  130. void DisplayVideoSettings(void)
  131. {
  132. char buffer[256];
  133. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(video_enabled_button),
  134. MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE));
  135.   
  136. gtk_toggle_button_set_active(
  137. GTK_TOGGLE_BUTTON(video_none_preview_button), 
  138. !MyConfig->GetBoolValue(CONFIG_VIDEO_PREVIEW));
  139. gtk_toggle_button_set_active(
  140. GTK_TOGGLE_BUTTON(video_raw_preview_button), 
  141. MyConfig->GetBoolValue(CONFIG_VIDEO_PREVIEW)
  142. && MyConfig->GetBoolValue(CONFIG_VIDEO_RAW_PREVIEW));
  143. gtk_toggle_button_set_active(
  144. GTK_TOGGLE_BUTTON(video_encoded_preview_button), 
  145. MyConfig->GetBoolValue(CONFIG_VIDEO_PREVIEW)
  146. && MyConfig->GetBoolValue(CONFIG_VIDEO_ENCODED_PREVIEW));
  147. snprintf(buffer, sizeof(buffer), " MPEG-4 at %u kbps",
  148. MyConfig->GetIntegerValue(CONFIG_VIDEO_BIT_RATE));
  149. gtk_label_set_text(GTK_LABEL(video_settings_label1), buffer);
  150. gtk_widget_show(video_settings_label1);
  151. snprintf(buffer, sizeof(buffer), " %u x %u @ %.2f fps", 
  152. MyConfig->m_videoWidth,
  153. MyConfig->m_videoHeight,
  154. MyConfig->GetFloatValue(CONFIG_VIDEO_FRAME_RATE));
  155. gtk_label_set_text(GTK_LABEL(video_settings_label2), buffer);
  156. gtk_widget_show(video_settings_label2);
  157. }
  158. void DisplayAudioSettings(void)
  159. {
  160. char buffer[256];
  161.  
  162. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(audio_enabled_button),
  163. MyConfig->GetBoolValue(CONFIG_AUDIO_ENABLE));
  164.   
  165. char* encoding;
  166. if (!strcasecmp(MyConfig->GetStringValue(CONFIG_AUDIO_ENCODING),
  167.   AUDIO_ENCODING_AAC)) {
  168. encoding = "AAC";
  169. } else {
  170. encoding = "MP3";
  171. }
  172. snprintf(buffer, sizeof(buffer), " %s at %u kbps",
  173. encoding,
  174. MyConfig->GetIntegerValue(CONFIG_AUDIO_BIT_RATE));
  175. gtk_label_set_text(GTK_LABEL(audio_settings_label1), buffer);
  176. gtk_widget_show(audio_settings_label1);
  177. snprintf(buffer, sizeof(buffer), " %s @ %u Hz",
  178. (MyConfig->GetIntegerValue(CONFIG_AUDIO_CHANNELS) == 2
  179. ? "Stereo" : "Mono"),
  180. MyConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE));
  181. gtk_label_set_text(GTK_LABEL(audio_settings_label2), buffer);
  182. gtk_widget_show(audio_settings_label2);
  183. }
  184. void DisplayTransmitSettings (void)
  185. {
  186. char buffer[256];
  187. const char *addr = MyConfig->GetStringValue(CONFIG_RTP_DEST_ADDRESS);
  188. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(transmit_enabled_button),
  189. MyConfig->GetBoolValue(CONFIG_RTP_ENABLE));
  190.   
  191. if (addr == NULL) {
  192. gtk_label_set_text(GTK_LABEL(transmit_settings_label), 
  193. "RTP/UDP to <Automatic Multicast>");
  194. } else {
  195. snprintf(buffer, sizeof(buffer), " RTP/UDP to %s", addr); 
  196. gtk_label_set_text(GTK_LABEL(transmit_settings_label), buffer);
  197. }
  198. gtk_widget_show(transmit_settings_label);
  199. }
  200. void DisplayRecordingSettings(void)
  201. {
  202. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_enabled_button),
  203. MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE));
  204. char* fileName = strrchr(
  205. MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME), '/');
  206. if (!fileName) {
  207. fileName = MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME);
  208. } else {
  209. fileName++;
  210. }
  211. char buffer[256];
  212.     snprintf(buffer, sizeof(buffer), " %s", fileName);
  213. gtk_label_set_text(GTK_LABEL(record_settings_label), buffer);
  214. gtk_widget_show(record_settings_label);
  215. }
  216. void DisplayControlSettings(void)
  217. {
  218. // duration
  219. gtk_spin_button_set_value(
  220. GTK_SPIN_BUTTON(duration_spinner),
  221. (gfloat)MyConfig->GetIntegerValue(CONFIG_APP_DURATION));
  222. // duration units
  223. for (u_int8_t i = 0; 
  224.   i < sizeof(durationUnitsValues) / sizeof(u_int16_t); i++) {
  225. if (MyConfig->GetIntegerValue(CONFIG_APP_DURATION_UNITS) 
  226.   == durationUnitsValues[i]) {
  227. durationUnitsIndex = i;
  228. break;
  229. }
  230. }
  231. gtk_option_menu_set_history(
  232. GTK_OPTION_MENU(duration_units_menu), 
  233. durationUnitsIndex);
  234. gtk_widget_show(duration_units_menu);
  235. }
  236. void DisplayStatusSettings(void)
  237. {
  238. // media source
  239. char buffer[128];
  240. buffer[0] = '';
  241. if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)
  242.   && MyConfig->GetBoolValue(CONFIG_AUDIO_ENABLE)
  243.   && strcmp(MyConfig->GetStringValue(CONFIG_VIDEO_SOURCE_NAME),
  244. MyConfig->GetStringValue(CONFIG_AUDIO_SOURCE_NAME))) {
  245. snprintf(buffer, sizeof(buffer), "%s & %s",
  246. MyConfig->GetStringValue(CONFIG_VIDEO_SOURCE_NAME),
  247. MyConfig->GetStringValue(CONFIG_AUDIO_SOURCE_NAME));
  248. gtk_label_set_text(GTK_LABEL(media_source), buffer);
  249. } else if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
  250. gtk_label_set_text(GTK_LABEL(media_source),
  251. MyConfig->GetStringValue(CONFIG_VIDEO_SOURCE_NAME));
  252. } else if (MyConfig->GetBoolValue(CONFIG_AUDIO_ENABLE)) {
  253. gtk_label_set_text(GTK_LABEL(media_source),
  254. MyConfig->GetStringValue(CONFIG_AUDIO_SOURCE_NAME));
  255. }
  256. }
  257. void DisplayAllSettings()
  258. {
  259. DisplayVideoSettings();
  260. DisplayAudioSettings();
  261. DisplayRecordingSettings();
  262. DisplayTransmitSettings();
  263. DisplayControlSettings();
  264. DisplayStatusSettings();
  265. }
  266. void DisplayFinishTime(Timestamp t)
  267. {
  268. time_t secs;
  269. const struct tm *local;
  270. char buffer[128];
  271. secs = (time_t)GetSecsFromTimestamp(t);
  272. local = localtime(&secs);
  273. strftime(buffer, sizeof(buffer), "%l:%M:%S", local);
  274. gtk_label_set_text(GTK_LABEL(finish_time), buffer);
  275. gtk_widget_show(finish_time);
  276. strftime(buffer, sizeof(buffer), "%p", local);
  277. gtk_label_set_text(GTK_LABEL(finish_time_units), buffer);
  278. gtk_widget_show(finish_time_units);
  279. }
  280. static void on_video_enabled_button (GtkWidget *widget, gpointer *data)
  281. {
  282. MyConfig->SetBoolValue(CONFIG_VIDEO_ENABLE,
  283. gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
  284. if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
  285. AVFlow->StartVideoPreview();
  286. } else {
  287. AVFlow->StopVideoPreview();
  288. }
  289. }
  290. static void on_video_preview_button (GtkWidget *widget, gpointer *data)
  291. {
  292. MyConfig->SetBoolValue(CONFIG_VIDEO_PREVIEW,
  293. !gtk_toggle_button_get_active(
  294. GTK_TOGGLE_BUTTON(video_none_preview_button)));
  295. MyConfig->SetBoolValue(CONFIG_VIDEO_RAW_PREVIEW,
  296. gtk_toggle_button_get_active(
  297. GTK_TOGGLE_BUTTON(video_raw_preview_button)));
  298. MyConfig->SetBoolValue(CONFIG_VIDEO_ENCODED_PREVIEW,
  299. gtk_toggle_button_get_active(
  300. GTK_TOGGLE_BUTTON(video_encoded_preview_button)));
  301. MyConfig->UpdateVideo();
  302. }
  303. static void on_video_settings_button (GtkWidget *widget, gpointer *data)
  304. {
  305. CreateVideoDialog();
  306. }
  307. static void on_audio_enabled_button (GtkWidget *widget, gpointer *data)
  308. {
  309. MyConfig->SetBoolValue(CONFIG_AUDIO_ENABLE,
  310. gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
  311. }
  312. static void on_audio_mute_button (GtkWidget *widget, gpointer *data)
  313. {
  314. AVFlow->SetAudioOutput(
  315. gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
  316. }
  317. static void on_audio_settings_button (GtkWidget *widget, gpointer *data)
  318. {
  319. CreateAudioDialog();
  320. }
  321. static void on_record_enabled_button (GtkWidget *widget, gpointer *data)
  322. {
  323. MyConfig->SetBoolValue(CONFIG_RECORD_ENABLE,
  324. gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
  325. }
  326. static void on_record_settings_button (GtkWidget *widget, gpointer *data)
  327. {
  328. CreateRecordingDialog();
  329. }
  330. static void on_transmit_enabled_button (GtkWidget *widget, gpointer *data)
  331. {
  332. MyConfig->SetBoolValue(CONFIG_RTP_ENABLE, 
  333. gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
  334. }
  335. static void on_transmit_settings_button (GtkWidget *widget, gpointer *data)
  336. {
  337. CreateTransmitDialog();
  338. }
  339. static void LockoutChanges(bool lockout)
  340. {
  341. gtk_widget_set_sensitive(GTK_WIDGET(video_enabled_button), !lockout);
  342. gtk_widget_set_sensitive(GTK_WIDGET(video_settings_button), !lockout);
  343. gtk_widget_set_sensitive(GTK_WIDGET(audio_enabled_button), !lockout);
  344. gtk_widget_set_sensitive(GTK_WIDGET(audio_settings_button), !lockout);
  345. gtk_widget_set_sensitive(GTK_WIDGET(record_enabled_button), !lockout);
  346. gtk_widget_set_sensitive(GTK_WIDGET(record_settings_button), !lockout);
  347. gtk_widget_set_sensitive(GTK_WIDGET(transmit_enabled_button), !lockout);
  348. gtk_widget_set_sensitive(GTK_WIDGET(transmit_settings_button), !lockout);
  349. gtk_widget_set_sensitive(GTK_WIDGET(duration_spinner), !lockout);
  350. gtk_widget_set_sensitive(GTK_WIDGET(duration_units_menu), !lockout);
  351. gtk_widget_set_sensitive(GTK_WIDGET(config_file_entry), !lockout);
  352. gtk_widget_set_sensitive(GTK_WIDGET(load_config_button), !lockout);
  353. gtk_widget_set_sensitive(GTK_WIDGET(save_config_button), !lockout);
  354. }
  355. static guint status_timer_id;
  356. // forward declaration
  357. static void on_start_button (GtkWidget *widget, gpointer *data);
  358. static void status_start()
  359. {
  360. time_t secs;
  361. const struct tm *local;
  362. char buffer[128];
  363. // start time
  364. secs = (time_t)GetSecsFromTimestamp(StartTime);
  365. local = localtime(&secs);
  366. strftime(buffer, sizeof(buffer), "%l:%M:%S", local);
  367. gtk_label_set_text(GTK_LABEL(start_time), buffer);
  368. gtk_widget_show(start_time);
  369. strftime(buffer, sizeof(buffer), "%p", local);
  370. gtk_label_set_text(GTK_LABEL(start_time_units), buffer);
  371. gtk_widget_show(start_time_units);
  372. // finish time
  373. if (StopTime) {
  374. DisplayFinishTime(StopTime);
  375. }
  376. // file size
  377. StartFileSize = 0;
  378. StopFileSize = 0;
  379. if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)) {
  380. if (!MyConfig->GetBoolValue(CONFIG_RECORD_MP4_OVERWRITE)) {
  381. struct stat stats;
  382. stat(MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME), &stats);
  383. StartFileSize = stats.st_size;
  384. }
  385. snprintf(buffer, sizeof(buffer), " %llu",
  386. StartFileSize / 1000000);
  387. gtk_label_set_text(GTK_LABEL(current_size), buffer);
  388. gtk_widget_show(current_size);
  389. gtk_label_set_text(GTK_LABEL(current_size_units), "MB");
  390. gtk_widget_show(current_size_units);
  391. StopFileSize = MyConfig->m_recordEstFileSize;
  392. snprintf(buffer, sizeof(buffer), " %llu",
  393. StopFileSize / 1000000);
  394. gtk_label_set_text(GTK_LABEL(final_size), buffer);
  395. gtk_widget_show(final_size);
  396. gtk_label_set_text(GTK_LABEL(final_size_units), "MB");
  397. gtk_widget_show(final_size_units);
  398. }
  399. }
  400. /*
  401.  * Status timer routine
  402.  */
  403. static gint status_timer (gpointer raw)
  404. {
  405. time_t secs;
  406. const struct tm *local;
  407. char buffer[80];
  408. Timestamp now = GetTimestamp();
  409. secs = (time_t)GetSecsFromTimestamp(now);
  410. local = localtime(&secs);
  411. strftime(buffer, sizeof(buffer), "%l:%M:%S", local);
  412. gtk_label_set_text(GTK_LABEL(current_time), buffer);
  413. gtk_widget_show(current_time);
  414. strftime(buffer, sizeof(buffer), "%p", local);
  415. gtk_label_set_text(GTK_LABEL(current_time_units), buffer);
  416. gtk_widget_show(current_time);
  417. time_t duration_secs = (time_t)GetSecsFromTimestamp(now - StartTime);
  418. snprintf(buffer, sizeof(buffer), "%lu:%02lu:%02lu", 
  419. duration_secs / 3600, (duration_secs % 3600) / 60, duration_secs % 60);
  420. gtk_label_set_text(GTK_LABEL(duration), buffer);
  421. gtk_widget_show(duration);
  422. if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)) {
  423. struct stat stats;
  424. stat(MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME), &stats);
  425. snprintf(buffer, sizeof(buffer), " %lu", stats.st_size / 1000000);
  426. gtk_label_set_text(GTK_LABEL(current_size), buffer);
  427. gtk_widget_show(current_size);
  428. }
  429. if (!StopTime) {
  430. float progress;
  431. AVFlow->GetStatus(FLOW_STATUS_PROGRESS, &progress);
  432. if (progress > 0.0) {
  433. u_int32_t estDuration = (u_int32_t)(duration_secs / progress);
  434. DisplayFinishTime(StartTime + (estDuration * TimestampTicks));
  435. }
  436. }
  437. if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
  438. u_int32_t encodedFrames;
  439. AVFlow->GetStatus(FLOW_STATUS_VIDEO_ENCODED_FRAMES, &encodedFrames);
  440. u_int32_t totalFrames = encodedFrames - StartEncodedFrameNumber;
  441. snprintf(buffer, sizeof(buffer), " %.2f", 
  442. ((float)totalFrames / (float)(now - StartTime)) * TimestampTicks);
  443. gtk_label_set_text(GTK_LABEL(actual_fps), buffer);
  444. gtk_widget_show(actual_fps);
  445. gtk_label_set_text(GTK_LABEL(actual_fps_units), "fps");
  446. gtk_widget_show(actual_fps_units);
  447. }
  448. bool stop = false;
  449. if (StopTime) {
  450. stop = (now >= StopTime);
  451. if (!stop && duration_secs > 10) {
  452. AVFlow->GetStatus(FLOW_STATUS_DONE, &stop);
  453. }
  454. if (!stop) {
  455. Duration elapsedDuration;
  456. if (AVFlow->GetStatus(FLOW_STATUS_DURATION, &elapsedDuration)) {
  457. if (elapsedDuration >= FlowDuration) {
  458. stop = true;
  459. }
  460. }
  461. }
  462. if (stop) {
  463. // automatically "press" stop button
  464. DoStop();
  465. if (MyConfig->m_appAutomatic) {
  466. // In automatic mode, time to exit app
  467. gtk_main_quit();
  468. } else {
  469. // Make sure user knows that were done
  470. char *notice;
  471. if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)
  472.   && MyConfig->GetBoolValue(CONFIG_RTP_ENABLE)) {
  473. notice = "Recording and transmission completed";
  474. } else if (MyConfig->GetBoolValue(CONFIG_RTP_ENABLE)) {
  475. notice = "Transmission completed";
  476. } else {
  477. notice = "Recording completed";
  478. }
  479. ShowMessage("Completed", notice);
  480. }
  481. return (FALSE);
  482. }
  483. return (TRUE);  // keep timer going
  484. }
  485. void DoStart()
  486. {
  487. if (!MyConfig->GetBoolValue(CONFIG_AUDIO_ENABLE)
  488.   && !MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
  489. ShowMessage("No Media", "Neither audio nor video are enabled");
  490. return;
  491. }
  492. // lock out change to settings while media is running
  493. LockoutChanges(true);
  494. AVFlow->Start();
  495. StartTime = GetTimestamp(); 
  496. if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
  497. if (MyConfig->IsCaptureVideoSource()) {
  498. AVFlow->GetStatus(FLOW_STATUS_VIDEO_ENCODED_FRAMES, 
  499. &StartEncodedFrameNumber);
  500. } else {
  501. StartEncodedFrameNumber = 0;
  502. }
  503. }
  504. FlowDuration =
  505. gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_spinner))
  506. * durationUnitsValues[durationUnitsIndex] * TimestampTicks;
  507. if (!MyConfig->IsCaptureVideoSource() && !MyConfig->IsCaptureAudioSource()
  508.   && !MyConfig->GetBoolValue(CONFIG_RTP_ENABLE)) {
  509. // no real time constraints
  510. StopTime = 0;
  511. } else {
  512. StopTime = StartTime + FlowDuration;
  513. }
  514. status_start();
  515. gtk_label_set_text(GTK_LABEL(start_button_label), "  Stop  ");
  516. status_timer_id = gtk_timeout_add(1000, status_timer, main_window);
  517. started = true;
  518. }
  519. void DoStop()
  520. {
  521. gtk_timeout_remove(status_timer_id);
  522. if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)) {
  523. char* notice = "CLOSING";
  524. if (MyConfig->GetBoolValue(CONFIG_RECORD_MP4_HINT_TRACKS)) {
  525. notice = "HINTING";
  526. }
  527. // borrow finish time field
  528. gtk_label_set_text(GTK_LABEL(finish_time), notice);
  529. gtk_widget_show_now(finish_time);
  530. gtk_label_set_text(GTK_LABEL(finish_time_units), "");
  531. gtk_widget_show_now(finish_time_units);
  532. }
  533. AVFlow->Stop();
  534. if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)) {
  535. DisplayFinishTime(GetTimestamp());
  536. }
  537. // unlock changes to settings
  538. LockoutChanges(false);
  539. gtk_label_set_text(GTK_LABEL(start_button_label), "  Start  ");
  540. started = false;
  541. }
  542. static void on_start_button (GtkWidget *widget, gpointer *data)
  543. {
  544. if (!started) {
  545. DoStart();
  546. } else {
  547. DoStop();
  548. }
  549. }
  550. static void on_duration_changed(GtkWidget* widget, gpointer* data)
  551. {
  552. MyConfig->SetIntegerValue(CONFIG_APP_DURATION,
  553. gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_spinner)));
  554. MyConfig->UpdateRecord();
  555. }
  556. static void on_duration_units_menu_activate(GtkWidget *widget, gpointer data)
  557. {
  558. durationUnitsIndex = (unsigned int)data & 0xFF;;
  559. MyConfig->SetIntegerValue(CONFIG_APP_DURATION_UNITS,
  560. durationUnitsValues[durationUnitsIndex]);
  561. MyConfig->UpdateRecord();
  562. }
  563. static void LoadConfig()
  564. {
  565. AVFlow->StopVideoPreview();
  566. char* configFileName =
  567. gtk_entry_get_text(GTK_ENTRY(config_file_entry));
  568. MyConfig->ReadFromFile(configFileName);
  569. MyConfig->Update();
  570. DisplayAllSettings();
  571. NewVideoWindow();
  572. // restart video source
  573. if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
  574. AVFlow->StartVideoPreview();
  575. }
  576. }
  577. static void on_load_config_button (GtkWidget *widget, gpointer *data)
  578. {
  579. FileBrowser(config_file_entry, GTK_SIGNAL_FUNC(LoadConfig));
  580. }
  581. static void on_save_config_button (GtkWidget *widget, gpointer *data)
  582. {
  583. char* configFileName =
  584. gtk_entry_get_text(GTK_ENTRY(config_file_entry));
  585. MyConfig->WriteToFile(configFileName);
  586. char notice[512];
  587. sprintf(notice,
  588. "Current configuration saved to %s", configFileName);
  589. ShowMessage("Configuration Saved", notice);
  590. }
  591. static gfloat frameLabelAlignment = 0.025;
  592. static void LayoutVideoFrame(GtkWidget* box)
  593. {
  594. GtkWidget *frame;
  595. GtkWidget *vbox, *hbox, *vbox1, *vbox2;
  596. GtkWidget *label;
  597. frame = gtk_frame_new("Video");
  598. gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
  599. gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  600. gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 5);
  601. vbox = gtk_vbox_new(FALSE, 1);
  602. gtk_widget_show(vbox);
  603. // create first row
  604. hbox = gtk_hbox_new(FALSE, 1);
  605. gtk_widget_show(hbox);
  606. gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  607.   
  608. // enabled button
  609. video_enabled_button = gtk_check_button_new_with_label("Enabled");
  610. gtk_box_pack_start(GTK_BOX(hbox), video_enabled_button, TRUE, TRUE, 5);
  611. gtk_signal_connect(GTK_OBJECT(video_enabled_button), 
  612. "toggled",
  613. GTK_SIGNAL_FUNC(on_video_enabled_button),
  614. NULL);
  615. gtk_widget_show(video_enabled_button);
  616. // create second row
  617. hbox = gtk_hbox_new(FALSE, 1);
  618. gtk_widget_show(hbox);
  619. gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  620. // preview label
  621. label = gtk_label_new(" Preview:");
  622. gtk_widget_show(label);
  623. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  624. gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
  625. // none preview radio button
  626. video_none_preview_button = gtk_radio_button_new_with_label(NULL, "None");
  627. gtk_widget_show(video_none_preview_button);
  628. gtk_box_pack_start(GTK_BOX(hbox), video_none_preview_button,
  629. FALSE, FALSE, 0);
  630. // raw preview radio button
  631. video_preview_radio_group = 
  632. gtk_radio_button_group(GTK_RADIO_BUTTON(video_none_preview_button));
  633. video_raw_preview_button = 
  634. gtk_radio_button_new_with_label(video_preview_radio_group, "Raw");
  635. gtk_widget_show(video_raw_preview_button);
  636. gtk_box_pack_start(GTK_BOX(hbox), video_raw_preview_button,
  637. FALSE, FALSE, 0);
  638. // encoded preview radio button
  639. video_preview_radio_group = 
  640. gtk_radio_button_group(GTK_RADIO_BUTTON(video_none_preview_button));
  641. video_encoded_preview_button = 
  642. gtk_radio_button_new_with_label(video_preview_radio_group, "Encoded");
  643. gtk_widget_show(video_encoded_preview_button);
  644. gtk_box_pack_start(GTK_BOX(hbox), video_encoded_preview_button,
  645. FALSE, FALSE, 0);
  646. gtk_signal_connect(GTK_OBJECT(video_none_preview_button), 
  647. "toggled",
  648.  GTK_SIGNAL_FUNC(on_video_preview_button),
  649.  NULL);
  650. gtk_signal_connect(GTK_OBJECT(video_raw_preview_button), 
  651. "toggled",
  652.  GTK_SIGNAL_FUNC(on_video_preview_button),
  653.  NULL);
  654. gtk_signal_connect(GTK_OBJECT(video_encoded_preview_button), 
  655. "toggled",
  656.  GTK_SIGNAL_FUNC(on_video_preview_button),
  657.  NULL);
  658. // create third row
  659. hbox = gtk_hbox_new(FALSE, 1);
  660. gtk_widget_show(hbox);
  661. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
  662. // secondary vbox for two labels
  663. vbox1 = gtk_vbox_new(FALSE, 1);
  664. gtk_widget_show(vbox1);
  665. gtk_box_pack_start(GTK_BOX(hbox), vbox1, TRUE, TRUE, 5);
  666. video_settings_label1 = gtk_label_new("");
  667. gtk_misc_set_alignment(GTK_MISC(video_settings_label1), 0.0, 0.5);
  668. gtk_box_pack_start(GTK_BOX(vbox1), video_settings_label1, TRUE, TRUE, 0);
  669. video_settings_label2 = gtk_label_new("");
  670. gtk_misc_set_alignment(GTK_MISC(video_settings_label2), 0.0, 0.5);
  671. gtk_box_pack_start(GTK_BOX(vbox1), video_settings_label2, TRUE, TRUE, 0);
  672. // secondary vbox to match stacked labels
  673. vbox2 = gtk_vbox_new(FALSE, 1);
  674. gtk_widget_show(vbox2);
  675. gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 5);
  676. // settings button
  677. video_settings_button = gtk_button_new_with_label(" Settings... ");
  678. gtk_box_pack_start(GTK_BOX(vbox2), video_settings_button, FALSE, FALSE, 5);
  679. gtk_signal_connect(GTK_OBJECT(video_settings_button), 
  680. "clicked",
  681. GTK_SIGNAL_FUNC(on_video_settings_button),
  682. NULL);
  683. gtk_widget_show(video_settings_button);
  684. // empty label to get sizing correct
  685. video_settings_label3 = gtk_label_new("");
  686. gtk_box_pack_start(GTK_BOX(vbox2), video_settings_label3, TRUE, TRUE, 0);
  687. gtk_container_add(GTK_CONTAINER(frame), vbox);
  688. gtk_widget_show(frame);
  689. }
  690. static void LayoutAudioFrame(GtkWidget* box)
  691. {
  692. GtkWidget *frame;
  693. GtkWidget *vbox, *hbox, *vbox1, *vbox2;
  694. frame = gtk_frame_new("Audio");
  695. gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
  696. gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  697. gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 5);
  698. vbox = gtk_vbox_new(FALSE, 1);
  699. gtk_widget_show(vbox);
  700. // create first row, homogenous
  701. hbox = gtk_hbox_new(TRUE, 1);
  702. gtk_widget_show(hbox);
  703. gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  704.   
  705. // enabled button
  706. audio_enabled_button = gtk_check_button_new_with_label("Enabled");
  707. gtk_box_pack_start(GTK_BOX(hbox), audio_enabled_button, TRUE, TRUE, 5);
  708. gtk_signal_connect(GTK_OBJECT(audio_enabled_button), 
  709. "toggled",
  710. GTK_SIGNAL_FUNC(on_audio_enabled_button),
  711. NULL);
  712. gtk_widget_show(audio_enabled_button);
  713. // mute button
  714. audio_mute_button = gtk_check_button_new_with_label("Mute");
  715. gtk_box_pack_start(GTK_BOX(hbox), audio_mute_button, TRUE, TRUE, 5);
  716. gtk_signal_connect(GTK_OBJECT(audio_mute_button), 
  717. "toggled",
  718. GTK_SIGNAL_FUNC(on_audio_mute_button),
  719. NULL);
  720. gtk_widget_show(audio_mute_button);
  721. // create second row
  722. hbox = gtk_hbox_new(FALSE, 1);
  723. gtk_widget_show(hbox);
  724. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
  725. // settings summary
  726. // secondary vbox for two labels
  727. vbox1 = gtk_vbox_new(FALSE, 1);
  728. gtk_widget_show(vbox1);
  729. gtk_box_pack_start(GTK_BOX(hbox), vbox1, TRUE, TRUE, 5);
  730. audio_settings_label1 = gtk_label_new("");
  731. gtk_misc_set_alignment(GTK_MISC(audio_settings_label1), 0.0, 0.5);
  732. gtk_widget_show(audio_settings_label1);
  733. gtk_box_pack_start(GTK_BOX(vbox1), audio_settings_label1, TRUE, TRUE, 0);
  734. audio_settings_label2 = gtk_label_new("");
  735. gtk_misc_set_alignment(GTK_MISC(audio_settings_label2), 0.0, 0.5);
  736. gtk_widget_show(audio_settings_label2);
  737. gtk_box_pack_start(GTK_BOX(vbox1), audio_settings_label2, TRUE, TRUE, 0);
  738. // secondary vbox to match stacked labels
  739. vbox2 = gtk_vbox_new(FALSE, 1);
  740. gtk_widget_show(vbox2);
  741. gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 5);
  742. // settings button
  743. audio_settings_button = gtk_button_new_with_label(" Settings... ");
  744. gtk_box_pack_start(GTK_BOX(vbox2), audio_settings_button, FALSE, FALSE, 5);
  745. gtk_signal_connect(GTK_OBJECT(audio_settings_button), 
  746. "clicked",
  747. GTK_SIGNAL_FUNC(on_audio_settings_button),
  748. NULL);
  749. gtk_widget_show(audio_settings_button);
  750. // empty label to get sizing correct
  751. audio_settings_label3 = gtk_label_new("");
  752. gtk_box_pack_start(GTK_BOX(vbox2), audio_settings_label3, TRUE, TRUE, 0);
  753. // finalize
  754. gtk_container_add(GTK_CONTAINER(frame), vbox);
  755. gtk_widget_show(frame);
  756. }
  757. static void LayoutRecordingFrame(GtkWidget* box)
  758. {
  759. GtkWidget *frame;
  760. GtkWidget *vbox, *hbox;
  761. frame = gtk_frame_new("Recording");
  762. gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
  763. gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  764. gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 5);
  765. vbox = gtk_vbox_new(FALSE, 1);
  766. gtk_widget_show(vbox);
  767. // create first row, homogenous
  768. hbox = gtk_hbox_new(TRUE, 1);
  769. gtk_widget_show(hbox);
  770. gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  771.   
  772. // enabled button
  773. record_enabled_button = gtk_check_button_new_with_label("Enabled");
  774. gtk_box_pack_start(GTK_BOX(hbox), record_enabled_button, TRUE, TRUE, 5);
  775. gtk_signal_connect(GTK_OBJECT(record_enabled_button), 
  776. "toggled",
  777. GTK_SIGNAL_FUNC(on_record_enabled_button),
  778. NULL);
  779. gtk_widget_show(record_enabled_button);
  780. // create second row
  781. hbox = gtk_hbox_new(FALSE, 1);
  782. gtk_widget_show(hbox);
  783. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
  784. // settings summary
  785. record_settings_label = gtk_label_new("");
  786. gtk_misc_set_alignment(GTK_MISC(record_settings_label), 0.0, 0.5);
  787. gtk_widget_show(record_settings_label);
  788. gtk_box_pack_start(GTK_BOX(hbox), record_settings_label, TRUE, TRUE, 0);
  789. // settings button
  790. record_settings_button = gtk_button_new_with_label(" Settings... ");
  791. gtk_box_pack_start(GTK_BOX(hbox), record_settings_button, FALSE, FALSE, 5);
  792. gtk_signal_connect(GTK_OBJECT(record_settings_button), 
  793. "clicked",
  794. GTK_SIGNAL_FUNC(on_record_settings_button),
  795. NULL);
  796. gtk_widget_show(record_settings_button);
  797. // finalize
  798. gtk_container_add(GTK_CONTAINER(frame), vbox);
  799. gtk_widget_show(frame);
  800. }
  801. static void LayoutTransmitFrame(GtkWidget* box)
  802. {
  803. GtkWidget *frame;
  804. GtkWidget *vbox, *hbox;
  805. frame = gtk_frame_new("Transmission");
  806. gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
  807. gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  808. gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 5);
  809. vbox = gtk_vbox_new(FALSE, 1);
  810. gtk_widget_show(vbox);
  811. // create first row, homogenous
  812. hbox = gtk_hbox_new(TRUE, 1);
  813. gtk_widget_show(hbox);
  814. gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  815.   
  816. // enabled button
  817. transmit_enabled_button = gtk_check_button_new_with_label("Enabled");
  818. gtk_box_pack_start(GTK_BOX(hbox), transmit_enabled_button, TRUE, TRUE, 5);
  819. gtk_signal_connect(GTK_OBJECT(transmit_enabled_button), 
  820. "toggled",
  821. GTK_SIGNAL_FUNC(on_transmit_enabled_button),
  822. NULL);
  823. gtk_widget_show(transmit_enabled_button);
  824. // create second row
  825. hbox = gtk_hbox_new(FALSE, 1);
  826. gtk_widget_show(hbox);
  827. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
  828. // settings summary
  829. transmit_settings_label = gtk_label_new("");
  830. gtk_misc_set_alignment(GTK_MISC(transmit_settings_label), 0.0, 0.5);
  831. gtk_widget_show(transmit_settings_label);
  832. gtk_box_pack_start(GTK_BOX(hbox), transmit_settings_label, TRUE, TRUE, 0);
  833. // settings button
  834. transmit_settings_button = gtk_button_new_with_label(" Settings... ");
  835. gtk_box_pack_start(GTK_BOX(hbox), 
  836. transmit_settings_button, FALSE, FALSE, 5);
  837. gtk_signal_connect(GTK_OBJECT(transmit_settings_button), 
  838. "clicked",
  839. GTK_SIGNAL_FUNC(on_transmit_settings_button),
  840. NULL);
  841. gtk_widget_show(transmit_settings_button);
  842. // finalize
  843. gtk_container_add(GTK_CONTAINER(frame), vbox);
  844. gtk_widget_show(frame);
  845. }
  846. // Control frame
  847. void LayoutControlFrame(GtkWidget* box)
  848. {
  849. GtkWidget *frame;
  850. GtkWidget *vbox;
  851. GtkWidget *hbox;
  852. GtkWidget *label;
  853. GtkWidget *separator;
  854. GtkObject* adjustment;
  855. frame = gtk_frame_new("Control");
  856. gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
  857. gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  858. gtk_box_pack_end(GTK_BOX(box), frame, FALSE, FALSE, 5);
  859. vbox = gtk_vbox_new(FALSE, 1);
  860. gtk_widget_show(vbox);
  861. gtk_container_add(GTK_CONTAINER(frame), vbox);
  862. hbox = gtk_hbox_new(FALSE, 1);
  863. gtk_widget_show(hbox);
  864. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
  865. label = gtk_label_new(" Duration:");
  866. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  867. gtk_widget_show(label);
  868. gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
  869. adjustment = gtk_adjustment_new(
  870. MyConfig->GetIntegerValue(CONFIG_APP_DURATION),
  871. 1, 24 * 60 * 60, 1, 0, 0);
  872. duration_spinner = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 1, 0);
  873. gtk_signal_connect(GTK_OBJECT(duration_spinner),
  874. "changed",
  875. GTK_SIGNAL_FUNC(on_duration_changed),
  876. GTK_OBJECT(duration_spinner));
  877. gtk_widget_show(duration_spinner);
  878. gtk_box_pack_start(GTK_BOX(hbox), duration_spinner, FALSE, FALSE, 5);
  879. durationUnitsIndex = 0; // temporary
  880. duration_units_menu = CreateOptionMenu(NULL,
  881. durationUnitsNames, 
  882. sizeof(durationUnitsNames) / sizeof(char*),
  883. durationUnitsIndex,
  884. GTK_SIGNAL_FUNC(on_duration_units_menu_activate));
  885. gtk_box_pack_start(GTK_BOX(hbox), duration_units_menu, FALSE, FALSE, 5);
  886. // vertical separator
  887. separator = gtk_vseparator_new();
  888. gtk_widget_show(separator);
  889. gtk_box_pack_start(GTK_BOX(hbox), separator, FALSE, FALSE, 0);
  890. start_button = gtk_button_new();
  891. start_button_label = gtk_label_new("  Start  ");
  892. gtk_misc_set_alignment(GTK_MISC(start_button_label), 0.5, 0.5);
  893. gtk_container_add(GTK_CONTAINER(start_button), start_button_label);
  894. gtk_widget_show(start_button_label);
  895. gtk_box_pack_start(GTK_BOX(hbox), start_button, TRUE, TRUE, 5);
  896. gtk_signal_connect(GTK_OBJECT(start_button), 
  897. "clicked",
  898. GTK_SIGNAL_FUNC(on_start_button),
  899. NULL);
  900. gtk_widget_show(start_button);
  901. // separator
  902. separator = gtk_hseparator_new();
  903. gtk_widget_show(separator);
  904. gtk_box_pack_start(GTK_BOX(vbox), separator, TRUE, TRUE, 0);
  905. // second row
  906. hbox = gtk_hbox_new(FALSE, 1);
  907. gtk_widget_show(hbox);
  908. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
  909. label = gtk_label_new(" Configuration File:");
  910. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  911. gtk_widget_show(label);
  912. gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
  913. config_file_entry = gtk_entry_new_with_max_length(256);
  914. gtk_entry_set_text(GTK_ENTRY(config_file_entry), 
  915. MyConfig->GetFileName());
  916. gtk_widget_show(config_file_entry);
  917. gtk_box_pack_start(GTK_BOX(hbox), config_file_entry, TRUE, TRUE, 5);
  918. // config file load button
  919. load_config_button = gtk_button_new_with_label(" Load... ");
  920. gtk_signal_connect(GTK_OBJECT(load_config_button),
  921.  "clicked",
  922.  GTK_SIGNAL_FUNC(on_load_config_button),
  923.  NULL);
  924. gtk_widget_show(load_config_button);
  925. gtk_box_pack_start(GTK_BOX(hbox), load_config_button, FALSE, FALSE, 5);
  926. // config file save button
  927. save_config_button = gtk_button_new_with_label(" Save ");
  928. gtk_signal_connect(GTK_OBJECT(save_config_button),
  929.  "clicked",
  930.  GTK_SIGNAL_FUNC(on_save_config_button),
  931.  NULL);
  932. gtk_widget_show(save_config_button);
  933. gtk_box_pack_start(GTK_BOX(hbox), save_config_button, FALSE, FALSE, 5);
  934. gtk_widget_show(frame); // show control frame
  935. }
  936. // Status frame
  937. void LayoutStatusFrame(GtkWidget* box)
  938. {
  939. GtkWidget *frame;
  940. GtkWidget *frame_vbox;
  941. GtkWidget *vbox, *hbox;
  942. GtkWidget *separator;
  943. frame = gtk_frame_new("Status");
  944. gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
  945. gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  946. gtk_box_pack_end(GTK_BOX(box), frame, FALSE, FALSE, 5);
  947. // frame vbox
  948. frame_vbox = gtk_vbox_new(FALSE, 1);
  949. gtk_widget_show(frame_vbox);
  950. gtk_container_add(GTK_CONTAINER(frame), frame_vbox);
  951. // first row
  952. hbox = gtk_hbox_new(FALSE, 1);
  953. gtk_widget_show(hbox);
  954. gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, FALSE, FALSE, 2);
  955. media_source_label = gtk_label_new(" Source:");
  956. gtk_misc_set_alignment(GTK_MISC(media_source_label), 0.0, 0.5);
  957. gtk_widget_show(media_source_label);
  958. gtk_box_pack_start(GTK_BOX(hbox), media_source_label, TRUE, TRUE, 5);
  959. media_source = gtk_label_new("");
  960. gtk_misc_set_alignment(GTK_MISC(media_source), 1.0, 0.5);
  961. gtk_widget_show(media_source);
  962. gtk_box_pack_start(GTK_BOX(hbox), media_source, TRUE, TRUE, 5);
  963. // separator
  964. separator = gtk_hseparator_new();
  965. gtk_widget_show(separator);
  966. gtk_box_pack_start(GTK_BOX(frame_vbox), separator, TRUE, TRUE, 0);
  967. // second row
  968. hbox = gtk_hbox_new(FALSE, 1);
  969. gtk_widget_show(hbox);
  970. gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, FALSE, FALSE, 2);
  971. // vbox for time labels
  972. vbox = gtk_vbox_new(FALSE, 1);
  973. gtk_widget_show(vbox);
  974. gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5);
  975. start_time_label = gtk_label_new(" Start Time:");
  976. gtk_misc_set_alignment(GTK_MISC(start_time_label), 0.0, 0.5);
  977. gtk_widget_show(start_time_label);
  978. gtk_box_pack_start(GTK_BOX(vbox), start_time_label, TRUE, TRUE, 0);
  979. duration_label = gtk_label_new(" Current Duration:");
  980. gtk_misc_set_alignment(GTK_MISC(duration_label), 0.0, 0.5);
  981. gtk_widget_show(duration_label);
  982. gtk_box_pack_start(GTK_BOX(vbox), duration_label, TRUE, TRUE, 0);
  983. current_time_label = gtk_label_new(" Current Time:");
  984. gtk_misc_set_alignment(GTK_MISC(current_time_label), 0.0, 0.5);
  985. gtk_widget_show(current_time_label);
  986. gtk_box_pack_start(GTK_BOX(vbox), current_time_label, TRUE, TRUE, 0);
  987. finish_time_label = gtk_label_new(" Finish Time:");
  988. gtk_misc_set_alignment(GTK_MISC(finish_time_label), 0.0, 0.5);
  989. gtk_widget_show(finish_time_label);
  990. gtk_box_pack_start(GTK_BOX(vbox), finish_time_label, TRUE, TRUE, 0);
  991. // vbox for time values
  992. vbox = gtk_vbox_new(FALSE, 1);
  993. gtk_widget_show(vbox);
  994. gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
  995. start_time = gtk_label_new("");
  996. gtk_misc_set_alignment(GTK_MISC(start_time), 1.0, 0.5);
  997. gtk_widget_show(start_time);
  998. gtk_box_pack_start(GTK_BOX(vbox), start_time, TRUE, TRUE, 0);
  999. duration = gtk_label_new("");
  1000. gtk_misc_set_alignment(GTK_MISC(duration), 1.0, 0.5);
  1001. gtk_widget_show(duration);
  1002. gtk_box_pack_start(GTK_BOX(vbox), duration, TRUE, TRUE, 0);
  1003. current_time = gtk_label_new("                 ");
  1004. gtk_misc_set_alignment(GTK_MISC(current_time), 1.0, 0.5);
  1005. gtk_widget_show(current_time);
  1006. gtk_box_pack_start(GTK_BOX(vbox), current_time, TRUE, TRUE, 0);
  1007. finish_time = gtk_label_new("");
  1008. gtk_misc_set_alignment(GTK_MISC(finish_time), 1.0, 0.5);
  1009. gtk_widget_show(finish_time);
  1010. gtk_box_pack_start(GTK_BOX(vbox), finish_time, TRUE, TRUE, 0);
  1011. // vbox for time units
  1012. vbox = gtk_vbox_new(FALSE, 1);
  1013. gtk_widget_show(vbox);
  1014. gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 5);
  1015. start_time_units = gtk_label_new("");
  1016. gtk_misc_set_alignment(GTK_MISC(start_time_units), 1.0, 0.5);
  1017. gtk_widget_show(start_time_units);
  1018. gtk_box_pack_start(GTK_BOX(vbox), start_time_units, TRUE, TRUE, 0);
  1019. duration_units = gtk_label_new("");
  1020. gtk_misc_set_alignment(GTK_MISC(duration_units), 1.0, 0.5);
  1021. gtk_widget_show(duration_units);
  1022. gtk_box_pack_start(GTK_BOX(vbox), duration_units, TRUE, TRUE, 0);
  1023. current_time_units = gtk_label_new("");
  1024. gtk_misc_set_alignment(GTK_MISC(current_time_units), 1.0, 0.5);
  1025. gtk_widget_show(current_time_units);
  1026. gtk_box_pack_start(GTK_BOX(vbox), current_time_units, TRUE, TRUE, 0);
  1027. finish_time_units = gtk_label_new("");
  1028. gtk_misc_set_alignment(GTK_MISC(finish_time_units), 1.0, 0.5);
  1029. gtk_widget_show(finish_time_units);
  1030. gtk_box_pack_start(GTK_BOX(vbox), finish_time_units, TRUE, TRUE, 0);
  1031. // separator
  1032. separator = gtk_hseparator_new();
  1033. gtk_widget_show(separator);
  1034. gtk_box_pack_start(GTK_BOX(frame_vbox), separator, TRUE, TRUE, 0);
  1035. // third row
  1036. hbox = gtk_hbox_new(FALSE, 1);
  1037. gtk_widget_show(hbox);
  1038. gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, FALSE, FALSE, 2);
  1039. // vbox for size labels
  1040. vbox = gtk_vbox_new(FALSE, 1);
  1041. gtk_widget_show(vbox);
  1042. gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5);
  1043. current_size_label = gtk_label_new(" Current Size:");
  1044. gtk_misc_set_alignment(GTK_MISC(current_size_label), 0.0, 0.5);
  1045. gtk_widget_show(current_size_label);
  1046. gtk_box_pack_start(GTK_BOX(vbox), current_size_label, TRUE, TRUE, 0);
  1047. final_size_label = gtk_label_new(" Estimated Final Size:");
  1048. gtk_misc_set_alignment(GTK_MISC(final_size_label), 0.0, 0.5);
  1049. gtk_widget_show(final_size_label);
  1050. gtk_box_pack_start(GTK_BOX(vbox), final_size_label, TRUE, TRUE, 0);
  1051. // vbox for size values
  1052. vbox = gtk_vbox_new(FALSE, 1);
  1053. gtk_widget_show(vbox);
  1054. gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
  1055. current_size = gtk_label_new("");
  1056. gtk_misc_set_alignment(GTK_MISC(current_size), 1.0, 0.5);
  1057. gtk_widget_show(current_size);
  1058. gtk_box_pack_start(GTK_BOX(vbox), current_size, TRUE, TRUE, 0);
  1059. final_size = gtk_label_new("");
  1060. gtk_misc_set_alignment(GTK_MISC(final_size), 1.0, 0.5);
  1061. gtk_widget_show(final_size);
  1062. gtk_box_pack_start(GTK_BOX(vbox), final_size, TRUE, TRUE, 0);
  1063. // vbox for size units
  1064. vbox = gtk_vbox_new(FALSE, 1);
  1065. gtk_widget_show(vbox);
  1066. gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 5);
  1067. current_size_units = gtk_label_new("");
  1068. gtk_misc_set_alignment(GTK_MISC(current_size_units), 1.0, 0.5);
  1069. gtk_widget_show(current_size_units);
  1070. gtk_box_pack_start(GTK_BOX(vbox), current_size_units, TRUE, TRUE, 0);
  1071. final_size_units = gtk_label_new("");
  1072. gtk_misc_set_alignment(GTK_MISC(final_size_units), 1.0, 0.5);
  1073. gtk_widget_show(final_size_units);
  1074. gtk_box_pack_start(GTK_BOX(vbox), final_size_units, TRUE, TRUE, 0);
  1075. // separator
  1076. separator = gtk_hseparator_new();
  1077. gtk_widget_show(separator);
  1078. gtk_box_pack_start(GTK_BOX(frame_vbox), separator, TRUE, TRUE, 0);
  1079. // fourth row
  1080. hbox = gtk_hbox_new(FALSE, 1);
  1081. gtk_widget_show(hbox);
  1082. gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, FALSE, FALSE, 2);
  1083. actual_fps_label = gtk_label_new(" Video Frame Rate:");
  1084. gtk_misc_set_alignment(GTK_MISC(actual_fps_label), 0.0, 0.5);
  1085. gtk_widget_show(actual_fps_label);
  1086. gtk_box_pack_start(GTK_BOX(hbox), actual_fps_label, TRUE, TRUE, 5);
  1087. actual_fps = gtk_label_new("");
  1088. gtk_misc_set_alignment(GTK_MISC(actual_fps), 1.0, 0.5);
  1089. gtk_widget_show(actual_fps);
  1090. gtk_box_pack_start(GTK_BOX(hbox), actual_fps, FALSE, FALSE, 0);
  1091. actual_fps_units = gtk_label_new("");
  1092. gtk_misc_set_alignment(GTK_MISC(actual_fps_units), 1.0, 0.5);
  1093. gtk_widget_show(actual_fps_units);
  1094. gtk_box_pack_start(GTK_BOX(hbox), actual_fps_units, FALSE, FALSE, 5);
  1095. gtk_widget_show(frame); // show control frame
  1096. }
  1097. /*
  1098.  * Main routine - set up window
  1099.  */
  1100. int gui_main(int argc, char **argv, CLiveConfig* pConfig)
  1101. {
  1102. MyConfig = pConfig;
  1103. AVFlow = new CAVMediaFlow(pConfig);
  1104. gtk_init(&argc, &argv);
  1105. // Setup main window
  1106. main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  1107. gtk_window_set_policy(GTK_WINDOW(main_window), FALSE, FALSE, TRUE);
  1108. char buffer[80];
  1109. snprintf(buffer, sizeof(buffer), "cisco mp4live %s", VERSION);
  1110. gtk_window_set_title(GTK_WINDOW(main_window), buffer);
  1111. gtk_signal_connect(GTK_OBJECT(main_window),
  1112. "delete_event",
  1113. GTK_SIGNAL_FUNC(delete_event),
  1114. NULL);
  1115. // main boxes
  1116. main_hbox = gtk_hbox_new(FALSE, 1);
  1117. gtk_container_set_border_width(GTK_CONTAINER(main_hbox), 4);
  1118. gtk_widget_show(main_hbox);
  1119. gtk_container_add(GTK_CONTAINER(main_window), main_hbox);
  1120. main_vbox1 = gtk_vbox_new(FALSE, 1);
  1121. gtk_container_set_border_width(GTK_CONTAINER(main_vbox1), 4);
  1122. gtk_widget_show(main_vbox1);
  1123. gtk_box_pack_start(GTK_BOX(main_hbox), main_vbox1, FALSE, FALSE, 5);
  1124. main_vbox2 = gtk_vbox_new(FALSE, 1);
  1125. gtk_container_set_border_width(GTK_CONTAINER(main_vbox2), 4);
  1126. gtk_widget_show(main_vbox2);
  1127. gtk_box_pack_start(GTK_BOX(main_hbox), main_vbox2, FALSE, FALSE, 5);
  1128. // Video Preview
  1129. NewVideoWindow();
  1130. // Video Frame
  1131. LayoutVideoFrame(main_vbox2);
  1132. // Audio Frame
  1133. LayoutAudioFrame(main_vbox2);
  1134. // Recording Frame
  1135. LayoutRecordingFrame(main_vbox2);
  1136. // Transmission Frame
  1137. LayoutTransmitFrame(main_vbox2);
  1138. // Status frame
  1139. LayoutStatusFrame(main_vbox1);
  1140. // Control frame
  1141. LayoutControlFrame(main_vbox1);
  1142. DisplayAllSettings();
  1143. gtk_widget_show(main_window);
  1144. if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
  1145. AVFlow->StartVideoPreview();
  1146. }
  1147. // "press" start button
  1148. if (MyConfig->m_appAutomatic) {
  1149. on_start_button(start_button, NULL);
  1150. }
  1151. gtk_main();
  1152. delete AVFlow;
  1153. return 0;
  1154. }
  1155. /* end gui_main.cpp */