home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek 6
/
Geek-006.iso
/
linux
/
video
/
xmovie-1.5.3.tar.gz
/
xmovie-1.5.3.tar
/
xmovie-1.5.3
/
xmovie
/
mainwindow.C
< prev
next >
Wrap
C/C++ Source or Header
|
2000-11-29
|
13KB
|
556 lines
#include "asset.h"
#include "colormodels.h"
#include "defaults.h"
#include "file.h"
#include "filesystem.h"
#include "mainmenu.h"
#include "mainwindow.h"
#include "mwindowgui.h"
#include "playbackengine.h"
#include "playlist.h"
#include "settings.h"
#include "theme.h"
#include "vframe.h"
#include <string.h>
MainWindow::MainWindow(ArrayList<char*> *init_playlist)
{
this->init_playlist = init_playlist;
engine = new PlaybackEngine(this);
defaults = new Defaults("~/.xmovierc");
defaults->load();
reset_parameters();
}
MainWindow::~MainWindow()
{
delete error_thread;
delete defaults;
delete gui;
if(asset) delete asset;
if(audio_file) delete audio_file;
if(video_file) delete video_file;
if(frame) delete frame;
if(playlist) delete playlist;
reset_parameters();
}
int MainWindow::reset_parameters()
{
audio_file = 0;
video_file = 0;
asset = 0;
frame = 0;
samplerate = 44100;
frame_rate = 10;
playlist = 0;
return 0;
}
int MainWindow::create_objects()
{
load_defaults();
// Create theme
theme = new GoldTheme;
gui = new MWindowGUI(this,
defaults->get("X", INFINITY),
defaults->get("Y", INFINITY),
defaults->get("WIDTH", DEFAULTW),
defaults->get("HEIGHT", DEFAULTH));
gui->create_objects();
gui->load_defaults(defaults);
error_thread = new ErrorThread(gui);
gui->show_window();
return 0;
}
void MainWindow::load_defaults()
{
sprintf(default_path, "");
defaults->get("PATH", default_path);
every_frame = defaults->get("EVERYFRAME", 0);
aspect_w = defaults->get("ASPECTW", (float)4);
aspect_h = defaults->get("ASPECTH", (float)3);
letter_w = defaults->get("LETTERBOXW", (float)2.35);
letter_h = defaults->get("LETTERBOXH", (float)1);
smp = defaults->get("SMP", 0);
use_mmx = defaults->get("USE_MMX", 1);
square_pixels = defaults->get("ASPECTSQUARE", 0);
crop_letterbox = defaults->get("CROPLETTERBOX", 0);
convert_601 = defaults->get("601TORGB", 1);
audio_priority = defaults->get("AUDIOPRIORITY", 0);
software_sync = defaults->get("SOFTWARESYNC", 0);
prebuffer_size = defaults->get("PREBUFFER_SIZE", 2000000);
video_stream = defaults->get("VIDEOSTREAM", 0);
audio_stream = defaults->get("AUDIOSTREAM", 0);
}
void MainWindow::save_defaults()
{
gui->menu->save_loads(defaults);
gui->save_defaults(defaults);
defaults->update("EVERYFRAME", every_frame);
defaults->update("ASPECTW", aspect_w);
defaults->update("ASPECTH", aspect_h);
defaults->update("LETTERBOXW", letter_w);
defaults->update("LETTERBOXH", letter_h);
defaults->update("SMP", smp);
defaults->update("USE_MMX", use_mmx);
defaults->update("ASPECTSQUARE", square_pixels);
defaults->update("CROPLETTERBOX", crop_letterbox);
defaults->update("601TORGB", convert_601);
defaults->update("AUDIOPRIORITY", audio_priority);
defaults->update("PATH", default_path);
defaults->update("SOFTWARESYNC", software_sync);
defaults->update("CANVASW", canvas_w);
defaults->update("CANVASH", canvas_h);
defaults->update("PREBUFFER_SIZE", prebuffer_size);
defaults->update("VIDEOSTREAM", video_stream);
defaults->update("AUDIOSTREAM", audio_stream);
defaults->update("WIDTH", gui->get_w()),
defaults->update("HEIGHT", gui->get_h());
defaults->update("X", gui->get_x());
defaults->update("Y", gui->get_y());
defaults->save();
}
int MainWindow::run_program()
{
gui->run_window();
return 0;
}
int MainWindow::load_file(char *path, int use_locking)
{
if(use_locking) gui->unlock_window();
stop_playback();
if(use_locking) gui->lock_window();
close_file();
// Check for playlist
playlist = new Playlist;
if(!playlist->load(path))
{
delete playlist;
playlist = 0;
}
asset = new Asset(path);
File *test_file = new File(this);
current_percentage = 0;
current_time = 0;
gui->update_position();
// Load asset with information
test_file->set_prebuffer(prebuffer_size);
test_file->set_processors(smp ? 2 : 1);
test_file->set_mmx(use_mmx);
int result = test_file->open_file(asset);
// Open real files
if(!result)
{
// success
if(asset->audio_data)
{
audio_file = test_file;
test_file = 0;
samplerate = asset->rate;
if(audio_stream >= asset->audio_streams) audio_stream = 0;
audio_file->set_audio_stream(audio_stream);
gui->menu->update_audio_streams(asset->audio_streams);
}
// Must open audio before this so FileMPEG can copy the tables
if(asset->video_data)
{
if(test_file)
video_file = test_file;
else
{
video_file = new File(this);
video_file->set_prebuffer(prebuffer_size);
video_file->set_processors(smp ? 2 : 1);
video_file->set_mmx(use_mmx);
video_file->open_file(asset);
}
frame_rate = asset->frame_rate;
if(video_stream >= asset->video_streams) video_stream = 0;
video_file->set_video_stream(video_stream);
gui->menu->update_video_streams(asset->video_streams);
}
if(asset->video_data)
{
// resize frame for video
get_canvas_sizes(canvas_w);
gui->resize_canvas(canvas_w, canvas_h);
}
else
{
// Shrink for audio
gui->resize_canvas(canvas_w, 0);
}
FileSystem fs;
char string1[1024], string2[1024];
fs.extract_name(string1, asset->path);
sprintf(string2, "XMovie: %s", string1);
gui->set_title(string2);
gui->resize_scrollbar();
if(asset->video_data) flash_frame(current_percentage);
gui->update_position();
if(asset->video_data) gui->canvas->flash();
gui->menu->add_load(path);
return 0;
}
else
{
// failure
switch(result)
{
case 1:
error_thread->show_error("No such file or directory.");
break;
case 2:
error_thread->show_error("Unsupported file format.");
break;
case 3:
error_thread->show_error("The file contains no supported codecs.");
break;
}
delete asset;
asset = 0;
return 1;
}
return 0;
}
int MainWindow::set_audio_stream(int stream_number)
{
this->audio_stream = stream_number;
audio_file->set_audio_stream(stream_number);
gui->menu->update_audio_streams(asset->audio_streams);
return 0;
}
int MainWindow::set_video_stream(int stream_number)
{
this->video_stream = stream_number;
video_file->set_video_stream(stream_number);
gui->menu->update_video_streams(asset->video_streams);
return 0;
}
float MainWindow::get_aspect_ratio()
{
if(square_pixels && asset && asset->video_data)
return (float)asset->width / asset->height;
else
return aspect_w / aspect_h;
return 0;
}
int MainWindow::get_canvas_sizes(int width_given)
{
float aspect_ratio = get_aspect_ratio();
float letterbox_ratio = letter_w / letter_h;
if(!asset || !asset->video_data) return 1;
// Scale sizes to aspect ratio
canvas_w = width_given;
canvas_h = (int)((float)width_given / aspect_ratio);
input_w = asset->width;
input_h = asset->height;
// Crop sizes to letterbox ratio
if(crop_letterbox)
{
int old_canvas_h = canvas_h, old_canvas_w = canvas_w;
if(letterbox_ratio > aspect_ratio)
{
canvas_h = (int)(canvas_w / letterbox_ratio);
input_h = (int)(input_h * (float)canvas_h / old_canvas_h);
}
else
{
input_w = (int)(input_w * ((float)canvas_h * letterbox_ratio) / old_canvas_w);
canvas_h = (int)(canvas_w / letterbox_ratio);
}
}
return 0;
}
int MainWindow::get_full_size(int &full_w, int &full_h)
{
float aspect_ratio = get_aspect_ratio();
float letterbox_ratio = letter_w / letter_h;
if(!asset) return 1;
if(aspect_ratio > (float)asset->width / asset->height)
{
full_w = (int)((float)asset->height * aspect_ratio + 0.5);
full_h = asset->height;
}
else
{
full_w = asset->width;
full_h = (int)((float)asset->width / aspect_ratio + 0.5);
}
if(crop_letterbox)
{
full_h = (int)(full_w / letterbox_ratio);
}
return 0;
}
int MainWindow::get_yuv_cropping(int &x, int &y, int &w, int &h)
{
x = 0;
w = asset->width;
if(crop_letterbox && letter_w > letter_h)
{
float aspect_ratio = get_aspect_ratio();
float letterbox_ratio = letter_w / letter_h;
h = (int)(((float)asset->width / letterbox_ratio) / ((float)asset->width / aspect_ratio) * asset->height + 0.5);
y = (int)((float)(asset->height - h) / 2 + 0.5);
}
else
{
h = asset->height;
y = 0;
}
return 0;
}
int MainWindow::original_size(float percent)
{
if(asset && asset->video_data)
{
if(!gui->yuv_bitmap)
{
gui->unlock_window();
stop_playback();
gui->lock_window();
}
get_full_size(canvas_w, canvas_h);
gui->resize_canvas((int)(canvas_w * percent), (int)(canvas_h * percent));
if(!gui->canvas->video_is_on())
{
flash_frame(current_percentage);
gui->canvas->flash();
}
}
return 0;
}
// Display frame when paused
int MainWindow::flash_frame(double percentage)
{
if(asset && asset->video_data)
{
double fake_percentage;
if(!frame) this->frame = new VFrame(0, asset->width, asset->height, BC_RGB888);
video_file->lock_read();
video_file->set_position(percentage);
video_file->read_frame(this->frame->get_data());
video_file->unlock_read();
gui->flash_frame(this->frame);
video_file->get_position(fake_percentage, current_time);
gui->update_position();
}
else
if(asset && asset->audio_data)
{
audio_file->set_position(percentage);
audio_file->get_position(current_percentage, current_time);
gui->update_position();
}
return 0;
}
int MainWindow::frame_forward()
{
if(asset)
{
if(asset->video_data)
{
// Read the next frame
if(!frame) this->frame = new VFrame(0, asset->width, asset->height, BC_RGB888);
video_file->lock_read();
video_file->read_frame(this->frame->get_data());
video_file->unlock_read();
gui->flash_frame(this->frame);
gui->canvas->flash();
video_file->get_position(current_percentage, current_time);
gui->update_position();
}
else
if(asset->audio_data)
{
// Read a second of audio
video_file->set_position(current_percentage);
video_file->set_audio_position(video_file->get_audio_position() + asset->rate);
video_file->get_position(current_percentage, current_time);
gui->update_position();
}
}
return 0;
}
int MainWindow::frame_backward()
{
if(asset)
{
if(asset->video_data)
{
if(!frame) this->frame = new VFrame(0, asset->width, asset->height, BC_RGB888);
video_file->lock_read();
video_file->frame_back();
video_file->read_frame(this->frame->get_data());
video_file->frame_back();
video_file->frame_back();
video_file->unlock_read();
gui->flash_frame(this->frame);
gui->canvas->flash();
video_file->get_position(current_percentage, current_time);
gui->update_position();
}
else
if(asset->audio_data)
{
video_file->set_position(current_percentage);
video_file->set_audio_position(video_file->get_audio_position() - asset->rate);
video_file->get_position(current_percentage, current_time);
gui->update_position();
}
}
return 0;
}
// Arm frame during playback
int MainWindow::arm_frame()
{
if(asset && asset->video_data)
{
if(gui->playback_colormodel == BC_YUV420P)
{
char *y_output = (char*)gui->yuv_bitmap->get_y_plane();
char *u_output = (char*)gui->yuv_bitmap->get_u_plane();
char *v_output = (char*)gui->yuv_bitmap->get_v_plane();
int in_x, in_y, in_w, in_h;
get_yuv_cropping(in_x, in_y, in_w, in_h);
in_w = gui->yuv_bitmap->get_w() < in_w ? gui->yuv_bitmap->get_w() : in_w;
in_h = gui->yuv_bitmap->get_h() < in_h ? gui->yuv_bitmap->get_h() : in_h;
video_file->lock_read();
video_file->read_yuv_buffer(y_output, u_output, v_output, in_x, in_y, in_w, in_h);
video_file->unlock_read();
}
else
if(video_file->frame_buffer_copy_possible(gui->bitmap->get_color_model()))
{
unsigned char **frame_buffer = gui->bitmap->get_row_pointers();
int color_model = gui->bitmap->get_color_model();
video_file->lock_read();
video_file->read_frame_buffer(frame_buffer,
gui->bitmap->get_w(),
gui->bitmap->get_h(),
color_model);
video_file->unlock_read();
}
else
{
if(!frame) this->frame = new VFrame(0, asset->width, asset->height, BC_RGB888);
video_file->lock_read();
video_file->read_frame(this->frame->get_data());
video_file->unlock_read();
}
}
return 0;
}
// Show frame during playback
int MainWindow::flash_armed_frame()
{
if(asset && asset->video_data)
{
if(video_file->frame_buffer_copy_possible(gui->bitmap->get_color_model()))
{
gui->flash_frame(0);
}
else
{
if(this->frame)
gui->flash_frame(this->frame);
}
}
return 0;
}
int MainWindow::close_file()
{
if(audio_file)
{
audio_file->close_file();
delete audio_file;
}
if(video_file)
{
video_file->close_file();
delete video_file;
}
if(playlist)
{
delete playlist;
}
if(asset) delete asset;
if(frame) delete frame;
reset_parameters();
return 0;
}
int MainWindow::exit_cleanly()
{
close_file();
save_defaults();
return 0;
}
int MainWindow::start_playback()
{
if(asset)
engine->start_playback();
return 0;
}
int MainWindow::stop_playback()
{
if(asset)
engine->stop_playback();
gui->lock_window();
gui->playbutton->set_mode(0);
gui->unlock_window();
return 0;
}