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
/
filempeg.C
< prev
next >
Wrap
C/C++ Source or Header
|
2000-11-29
|
9KB
|
470 lines
#include "asset.h"
#include "colormodels.h"
#include "file.h"
#include "filempeg.h"
#include "mainwindow.h"
#include "mwindowgui.h"
#include "vframe.h"
FileMPEG::FileMPEG(Asset *asset, File *file)
: FileBase(asset, file)
{
reset_parameters();
asset->format = MPEG;
asset->byte_order = 0;
}
FileMPEG::~FileMPEG()
{
close_file();
}
int FileMPEG::reset_parameters_derived()
{
file = 0;
audio_stream = 0;
video_stream = 0;
return 0;
}
int FileMPEG::open_file()
{
// Copy tables if a file is already opened by MWindow
if(mwindow->audio_file && mwindow->video_file)
{
if(!(file = mpeg3_open_copy(asset->path,
(mpeg3_t*)((FileMPEG*)mwindow->audio_file->file)->file)))
{
perror("FileMPEG::open_file");
return 1;
}
}
else
if(!(file = mpeg3_open(asset->path)))
{
perror("FileMPEG::open_file");
return 1;
}
mpeg3_set_cpus(file, FileBase::file->cpus);
mpeg3_set_mmx(file, FileBase::file->use_mmx);
read_header();
if(!asset->video_data && !asset->audio_data)
{
mpeg3_close(file);
return 3;
}
return 0;
}
int FileMPEG::close_file_derived()
{
if(file) mpeg3_close(file);
file = 0;
return 0;
}
int FileMPEG::set_cpus(int cpus)
{
if(file) mpeg3_set_cpus(file, cpus);
return 0;
}
int FileMPEG::set_mmx(int use_mmx)
{
if(file) mpeg3_set_mmx(file, use_mmx);
return 0;
}
int FileMPEG::read_header()
{
if(mpeg3_has_audio(file)) asset->audio_data = 1;
if(asset->audio_data)
{
asset->audio_streams = mpeg3_total_astreams(file);
asset->channels = mpeg3_audio_channels(file, audio_stream);
asset->rate = mpeg3_sample_rate(file, audio_stream);
asset->bits = 16;
asset->signed_ = 1;
asset->byte_order = internal_byte_order;
}
if(mpeg3_has_video(file)) asset->video_data = 1;
if(asset->video_data)
{
asset->video_streams = mpeg3_total_vstreams(file);
asset->width = mpeg3_video_width(file, video_stream);
asset->height = mpeg3_video_height(file, video_stream);
asset->frame_rate = mpeg3_frame_rate(file, video_stream);
asset->compression[0] = 0;
}
if(asset->channels > 2) asset->channels = 2;
return 0;
}
int FileMPEG::set_video_stream(int stream)
{
this->video_stream = stream;
return 0;
}
int FileMPEG::set_audio_stream(int stream)
{
this->audio_stream = stream;
return 0;
}
long FileMPEG::get_audio_length()
{
long result = mpeg3_audio_samples(file, audio_stream);
return result;
}
long FileMPEG::get_video_length()
{
long result = mpeg3_video_frames(file, video_stream);
return result;
}
int FileMPEG::get_position(double &percentage, double &seconds)
{
if(file)
{
if(asset->video_data)
{
percentage = mpeg3_tell_percentage(file);
seconds = mpeg3_get_time(file);
}
// Audio only
else
if(asset->audio_data)
{
percentage = (double)mpeg3_get_sample(file, 0) / mpeg3_audio_samples(file, 0);
seconds = (double)mpeg3_get_sample(file, 0) / asset->rate;
}
}
else
{
percentage = seconds = 0;
}
return 0;
}
long FileMPEG::get_video_position()
{
return mpeg3_get_frame(file, video_stream);
}
long FileMPEG::get_audio_position()
{
return mpeg3_get_sample(file, audio_stream);
}
int FileMPEG::end_of_audio()
{
return mpeg3_end_of_audio(file, audio_stream);
}
int FileMPEG::end_of_video()
{
return mpeg3_end_of_video(file, video_stream);
}
int FileMPEG::set_position(double percentage)
{
int result = 0;
if(file)
{
if(asset->video_data)
result = mpeg3_seek_percentage(file, percentage);
else
if(asset->audio_data)
{
result = mpeg3_set_sample(file, (long)(percentage * mpeg3_audio_samples(file, audio_stream)), audio_stream);
}
}
return result;
}
int FileMPEG::set_audio_position(long x)
{
audio_position = x;
return mpeg3_set_sample(file, x, audio_stream);
}
int FileMPEG::set_video_position(long x)
{
video_position = x;
return mpeg3_set_frame(file, x, video_stream);
}
int FileMPEG::drop_frames(int frames)
{
if(file)
{
mpeg3_drop_frames(file, frames, 0);
}
return 0;
}
int FileMPEG::frame_back()
{
return mpeg3_previous_frame(file, 0);
}
// Optimization strategies
int FileMPEG::yuv_copy_possible()
{
if(mwindow->convert_601 && mwindow->gui->accel_available(BC_YUV420P))
{
return 1;
}
return 0;
}
int FileMPEG::frame_buffer_copy_possible(int color_model)
{
if(color_model == BC_RGB565 ||
color_model == BC_BGR888 ||
color_model == BC_BGR8888)
return 1;
else
return 0;
}
int FileMPEG::translate_color_model(int color_model)
{
switch(color_model)
{
case BC_RGB565:
return MPEG3_RGB565;
break;
case BC_BGR888:
if(mwindow->convert_601) return MPEG3_601_BGR888;
else return MPEG3_BGR888;
break;
case BC_BGR8888:
if(mwindow->convert_601) return MPEG3_601_BGRA8888;
else return MPEG3_BGRA8888;
break;
}
return -1;
}
int FileMPEG::read_yuv_buffer(char *y_output,
char *u_output,
char *v_output,
int in_x,
int in_y,
int in_w,
int in_h)
{
video_position++;
return mpeg3_read_yuvframe(file,
y_output,
u_output,
v_output,
in_x,
in_y,
in_w,
in_h,
video_stream);
}
int FileMPEG::read_frame_buffer(unsigned char **frame_buffer, int w, int h, int bitmap_color_model)
{
int result;
if(mwindow->crop_letterbox)
{
result = mpeg3_read_frame(file,
frame_buffer,
(asset->width - mwindow->input_w) / 2,
(asset->height - mwindow->input_h) / 2,
mwindow->input_w,
mwindow->input_h,
w,
h,
translate_color_model(bitmap_color_model),
video_stream);
}
else
{
result = mpeg3_read_frame(file,
frame_buffer,
0,
0,
asset->width,
asset->height,
w,
h,
translate_color_model(bitmap_color_model),
video_stream);
}
video_position++;
return result;
}
int FileMPEG::read_frame(unsigned char *frame)
{
int result, i, input_x, input_y, input_w, input_h;
unsigned char **row_pointers;
if(mwindow->crop_letterbox)
{
input_x = (asset->width - mwindow->input_w) / 2;
input_y = (asset->height - mwindow->input_h) / 2;
input_w = mwindow->input_w;
input_h = mwindow->input_h;
}
else
{
input_x = 0;
input_y = 0;
input_w = asset->width;
input_h = asset->height;
}
row_pointers = new unsigned char*[asset->height];
for(i = 0; i < asset->height; i++)
row_pointers[i] = &frame[i * asset->width * 3];
result = mpeg3_read_frame(file,
row_pointers,
input_x,
input_y,
input_w,
input_h,
asset->width,
asset->height,
mwindow->convert_601 ? MPEG3_601_RGB888 : MPEG3_RGB888,
video_stream);
delete row_pointers;
video_position++;
return result;
}
int FileMPEG::read_audio(char *buffer, long len)
{
int channel;
int i, j;
int result = 0;
int downmix51 = 0;
BCBASE_INT16 *output_ptr;
BCBASE_INT16 *output_end;
BCBASE_INT16 *input_ptr;
BCBASE_INT16 *input_end;
int total_channels;
get_read_buffer(len);
// Zero output channels
output_ptr = (BCBASE_INT16*)buffer + channel;
input_ptr = (BCBASE_INT16*)read_buffer;
input_end = input_ptr + len;
if(mpeg3_audio_channels(file, audio_stream) > asset->channels )
{
downmix51 = 1;
for(channel = 0; channel < asset->channels; channel++)
{
output_ptr = (BCBASE_INT16*)buffer + channel;
output_end = (BCBASE_INT16*)output_ptr + len * asset->channels;
while(output_ptr < output_end)
{
*output_ptr++ = 0;
}
}
}
total_channels = (downmix51 ? mpeg3_audio_channels(file, audio_stream) : asset->channels);
for(channel = 0;
channel < total_channels && !result;
channel++)
{
if(channel == 0)
result = mpeg3_read_audio(file,
0,
read_buffer,
channel,
len,
audio_stream);
else
result = mpeg3_reread_audio(file,
0,
read_buffer,
channel,
len,
audio_stream);
// Prepare for next channel
// Incompatible with percentage seeking
// if(channel < total_channels - 1 && !result) mpeg3_set_sample(file,
// mpeg3_get_sample(file, 0) - len,
// audio_stream);
// Interlace the audio for the sound driver.
if(downmix51)
{
input_ptr = (BCBASE_INT16*)read_buffer;
input_end = input_ptr + len;
switch(channel)
{
case 0: output_ptr = (BCBASE_INT16*)buffer; break; // Left
case 1: output_ptr = (BCBASE_INT16*)buffer; break; // Center
case 2: output_ptr = (BCBASE_INT16*)buffer + 1; break; // Right
case 3: output_ptr = (BCBASE_INT16*)buffer; break; // Left
case 4: output_ptr = (BCBASE_INT16*)buffer + 1; break; // Right
}
if(channel == 1)
while(input_ptr < input_end)
{
*output_ptr++ += *input_ptr;
*output_ptr++ += *input_ptr++;
}
else
while(input_ptr < input_end)
{
*output_ptr += *input_ptr++;
output_ptr += asset->channels;
}
}
else
{
output_ptr = (BCBASE_INT16*)buffer + channel;
input_ptr = (BCBASE_INT16*)read_buffer;
input_end = input_ptr + len;
while(input_ptr < input_end)
{
*output_ptr = *input_ptr++;
output_ptr += asset->channels;
}
}
}
audio_position += len;
return 0;
}
int FileMPEG::load_into_ram()
{
if(asset->video_data)
{
// quicktime_cache_frames(file, 0);
}
return 0;
}