X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fcinelerra%2Ffileffmpeg.C;fp=cinelerra-5.0%2Fcinelerra%2Ffileffmpeg.C;h=0000000000000000000000000000000000000000;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=1972a9eca9634824856e1427aecf285b0860e038;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/cinelerra/fileffmpeg.C b/cinelerra-5.0/cinelerra/fileffmpeg.C deleted file mode 100644 index 1972a9ec..00000000 --- a/cinelerra-5.0/cinelerra/fileffmpeg.C +++ /dev/null @@ -1,679 +0,0 @@ - -#include -#include -#include -#include -#include -// work around for __STDC_CONSTANT_MACROS -#include - -#include "asset.h" -#include "bcwindowbase.h" -#include "bcprogressbox.h" -#include "bitspopup.h" -#include "ffmpeg.h" -#include "filebase.h" -#include "file.h" -#include "fileffmpeg.h" -#include "filesystem.h" -#include "format.inc" -#include "indexfile.h" -#include "mutex.h" -#include "preferences.h" -#include "videodevice.inc" - -FileFFMPEG::FileFFMPEG(Asset *asset, File *file) - : FileBase(asset, file) -{ - ff = 0; - if(asset->format == FILE_UNKNOWN) - asset->format = FILE_FFMPEG; -} - -FileFFMPEG::~FileFFMPEG() -{ - delete ff; -} - - -FFMpegConfigNum::FFMpegConfigNum(BC_Window *window, - int x, int y, char *title_text, int *output) - : BC_TumbleTextBox(window, (int64_t)*output, - (int64_t)-1, (int64_t)25000000, 100, y, 100) -{ - this->window = window; - this->x = x; this->y = y; - this->title_text = title_text; - this->output = output; -} - -FFMpegConfigNum::~FFMpegConfigNum() -{ -} - -void FFMpegConfigNum::create_objects() -{ - window->add_subwindow(title = new BC_Title(x, y, title_text)); - BC_TumbleTextBox::create_objects(); -} - -int FFMpegConfigNum::handle_event() -{ - *output = atol(get_text()); - return 1; -} - -FFMpegAudioNum::FFMpegAudioNum(BC_Window *window, - int x, int y, char *title_text, int *output) - : FFMpegConfigNum(window, x, y, title_text, output) -{ -} - -int FFMpegAudioBitrate::handle_event() -{ - int ret = FFMpegAudioNum::handle_event(); - return ret; -} - -FFMpegVideoNum::FFMpegVideoNum(BC_Window *window, - int x, int y, char *title_text, int *output) - : FFMpegConfigNum(window, x, y, title_text, output) -{ -} - -int FFMpegVideoBitrate::handle_event() -{ - int ret = FFMpegVideoNum::handle_event(); - Asset *asset = window()->asset; - if( asset->ff_video_bitrate ) - window()->quality->disable(); - else - window()->quality->enable(); - return ret; -} - -int FFMpegVideoQuality::handle_event() -{ - int ret = FFMpegVideoNum::handle_event(); - Asset *asset = window()->asset; - if( asset->ff_video_quality ) - window()->bitrate->disable(); - else - window()->bitrate->enable(); - return ret; -} - -void FileFFMPEG::get_parameters(BC_WindowBase *parent_window, - Asset *asset, BC_WindowBase *&format_window, - int audio_options, int video_options) -{ - if(audio_options) { - FFMPEGConfigAudio *window = new FFMPEGConfigAudio(parent_window, asset); - format_window = window; - window->create_objects(); - window->run_window(); - delete window; - } - else if(video_options) { - FFMPEGConfigVideo *window = new FFMPEGConfigVideo(parent_window, asset); - format_window = window; - window->create_objects(); - window->run_window(); - delete window; - } -} - -int FileFFMPEG::check_sig(Asset *asset) -{ - char *ptr = strstr(asset->path, ".pcm"); - if( ptr ) return 0; - ptr = strstr(asset->path, ".raw"); - if( ptr ) return 0; - - FFMPEG ffmpeg(0); - int ret = !ffmpeg.init_decoder(asset->path) && - !ffmpeg.open_decoder() ? 1 : 0; - return ret; -} - -void FileFFMPEG::get_info(char *path, char *text, int len) -{ - char *cp = text; - FFMPEG ffmpeg(0); - cp += sprintf(cp, _("file path: %s\n"), path); - struct stat st; - int ret = 0; - if( stat(path, &st) < 0 ) { - cp += sprintf(cp, _(" err: %s\n"), strerror(errno)); - ret = 1; - } - else { - cp += sprintf(cp, _(" %jd bytes\n"), st.st_size); - } - if( !ret ) ret = ffmpeg.init_decoder(path); - if( !ret ) ret = ffmpeg.open_decoder(); - if( !ret ) { - cp += sprintf(cp, _("info:\n")); - ffmpeg.info(cp, len-(cp-text)); - } - else - sprintf(cp, _("== open failed\n")); -} - -int FileFFMPEG::get_video_info(int track, int &pid, double &framerate, - int &width, int &height, char *title) -{ - if( !ff ) return -1; - pid = ff->ff_video_pid(track); - framerate = ff->ff_frame_rate(track); - width = ff->ff_video_width(track); - height = ff->ff_video_height(track); - if( title ) *title = 0; - return 0; -} - -int FileFFMPEG::get_audio_for_video(int vstream, int astream, int64_t &channel_mask) -{ - if( !ff ) return 1; - return ff->ff_audio_for_video(vstream, astream, channel_mask); -} - -int FileFFMPEG::select_video_stream(Asset *asset, int vstream) -{ - if( !ff || !asset->video_data ) return 1; - asset->width = ff->ff_video_width(vstream); - asset->height = ff->ff_video_height(vstream); - asset->video_length = ff->ff_video_frames(vstream); - asset->frame_rate = ff->ff_frame_rate(vstream); - return 0; -} - -int FileFFMPEG::select_audio_stream(Asset *asset, int astream) -{ - if( !ff || !asset->audio_data ) return 1; - asset->sample_rate = ff->ff_sample_rate(astream); - asset->audio_length = ff->ff_audio_samples(astream); - return 0; -} - -int FileFFMPEG::open_file(int rd, int wr) -{ - int result = 0; - if( ff ) return 1; - ff = new FFMPEG(this); - - if( rd ) { - result = ff->init_decoder(asset->path); - if( !result ) result = ff->open_decoder(); - if( !result ) { - int audio_channels = ff->ff_total_audio_channels(); - if( audio_channels > 0 ) { - asset->audio_data = 1; - asset->channels = audio_channels; - asset->sample_rate = ff->ff_sample_rate(0); - asset->audio_length = ff->ff_audio_samples(0); - } - int video_layers = ff->ff_total_video_layers(); - if( video_layers > 0 ) { - asset->video_data = 1; - if( !asset->layers ) asset->layers = video_layers; - asset->actual_width = ff->ff_video_width(0); - asset->actual_height = ff->ff_video_height(0); - if( !asset->width ) asset->width = asset->actual_width; - if( !asset->height ) asset->height = asset->actual_height; - if( !asset->video_length ) asset->video_length = ff->ff_video_frames(0); - if( !asset->frame_rate ) asset->frame_rate = ff->ff_frame_rate(0); - } - IndexState *index_state = asset->index_state; - index_state->read_markers(file->preferences->index_directory, asset->path); - } - } - else if( wr ) { - result = ff->init_encoder(asset->path); - // must be in this order or dvdauthor will fail - if( !result && asset->video_data ) - result = ff->open_encoder("video", asset->vcodec); - if( !result && asset->audio_data ) - result = ff->open_encoder("audio", asset->acodec); - } - return result; -} - -int FileFFMPEG::close_file() -{ - delete ff; - ff = 0; - return 0; -} - - -int FileFFMPEG::write_samples(double **buffer, int64_t len) -{ - if( !ff || len < 0 ) return -1; - int stream = 0; - int ret = ff->encode(stream, buffer, len); - return ret; -} - -int FileFFMPEG::write_frames(VFrame ***frames, int len) -{ - if( !ff ) return -1; - int ret = 0, layer = 0; - for(int i = 0; i < 1; i++) { - for(int j = 0; j < len && !ret; j++) { - VFrame *frame = frames[i][j]; - ret = ff->encode(layer, frame); - } - } - return ret; -} - - -int FileFFMPEG::read_samples(double *buffer, int64_t len) -{ - if( !ff || len < 0 ) return -1; - int ch = file->current_channel; - int64_t pos = file->current_sample; - int ret = ff->decode(ch, pos, buffer, len); - if( ret > 0 ) return 0; - memset(buffer,0,len*sizeof(*buffer)); - return -1; -} - -int FileFFMPEG::read_frame(VFrame *frame) -{ - if( !ff ) return -1; - int layer = file->current_layer; - int64_t pos = file->current_frame; - int ret = ff->decode(layer, pos, frame); - frame->set_status(ret); - if( ret >= 0 ) return 0; - frame->clear_frame(); - return -1; -} - - -int64_t FileFFMPEG::get_memory_usage() -{ - return 0; -} - -int FileFFMPEG::colormodel_supported(int colormodel) -{ - return colormodel; -} - -int FileFFMPEG::get_best_colormodel(Asset *asset, int driver) -{ - switch(driver) { - case PLAYBACK_X11: return BC_RGB888; - case PLAYBACK_X11_GL: return BC_YUV888; - } - return BC_YUV420P; -} - -//====== - -FFMPEGConfigAudio::FFMPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset) - : BC_Window(_(PROGRAM_NAME ": Audio Preset"), - parent_window->get_abs_cursor_x(1), - parent_window->get_abs_cursor_y(1), - 420, 420) -{ - this->parent_window = parent_window; - this->asset = asset; - preset_popup = 0; - - bitrate = 0; - audio_options = 0; -} - -FFMPEGConfigAudio::~FFMPEGConfigAudio() -{ - lock_window("FFMPEGConfigAudio::~FFMPEGConfigAudio"); - if(preset_popup) delete preset_popup; - presets.remove_all_objects(); - unlock_window(); -} - -void FFMPEGConfigAudio::create_objects() -{ - int x = 10, y = 10; - lock_window("FFMPEGConfigAudio::create_objects"); - - FileSystem fs; - char option_path[BCTEXTLEN]; - FFMPEG::set_option_path(option_path, "audio"); - fs.update(option_path); - int total_files = fs.total_files(); - for(int i = 0; i < total_files; i++) { - const char *name = fs.get_entry(i)->get_name(); - if( asset->fformat[0] != 0 ) { - const char *ext = strrchr(name,'.'); - if( !ext ) continue; - if( strcmp(asset->fformat, ++ext) ) continue; - } - presets.append(new BC_ListBoxItem(name)); - } - - if( asset->acodec[0] ) { - int k = presets.size(); - while( --k >= 0 && strcmp(asset->acodec, presets[k]->get_text()) ); - if( k < 0 ) asset->acodec[0] = 0; - } - - if( !asset->acodec[0] && presets.size() > 0 ) - strcpy(asset->acodec, presets[0]->get_text()); - - add_tool(new BC_Title(x, y, _("Preset:"))); - y += 25; - preset_popup = new FFMPEGConfigAudioPopup(this, x, y); - preset_popup->create_objects(); - - y += 50; - bitrate = new FFMpegAudioBitrate(this, x, y, _("Bitrate:"), &asset->ff_audio_bitrate); - bitrate->create_objects(); - bitrate->set_increment(1000); - - y += bitrate->get_h() + 10; - add_subwindow(new BC_Title(x, y, _("Audio Options:"))); - y += 25; - if( !asset->ff_audio_options[0] && asset->acodec[0] ) { - FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec); - FFMPEG::load_options(option_path, asset->ff_audio_options, - sizeof(asset->ff_audio_options)); - } - add_subwindow(audio_options = new FFAudioOptions(this, x, y, get_w()-x-20, 10, - sizeof(asset->ff_audio_options)-1, asset->ff_audio_options)); - add_subwindow(new BC_OKButton(this)); - show_window(1); - bitrate->handle_event(); - unlock_window(); -} - -int FFMPEGConfigAudio::close_event() -{ - set_done(0); - return 1; -} - - -FFAudioOptions::FFAudioOptions(FFMPEGConfigAudio *audio_popup, - int x, int y, int w, int rows, int size, char *text) - : BC_TextBox(x, y, w, rows, size, text) -{ - this->audio_popup = audio_popup; -} - -int FFAudioOptions::handle_event() -{ - strcpy(audio_popup->asset->ff_audio_options, get_text()); - return 1; -} - - -FFMPEGConfigAudioPopup::FFMPEGConfigAudioPopup(FFMPEGConfigAudio *popup, int x, int y) - : BC_PopupTextBox(popup, &popup->presets, popup->asset->acodec, x, y, 300, 300) -{ - this->popup = popup; -} - -int FFMPEGConfigAudioPopup::handle_event() -{ - strcpy(popup->asset->acodec, get_text()); - Asset *asset = popup->asset; - char option_path[BCTEXTLEN]; - FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec); - FFMPEG::load_options(option_path, asset->ff_audio_options, - sizeof(asset->ff_audio_options)); - popup->audio_options->update(asset->ff_audio_options); - return 1; -} - - -FFMPEGConfigAudioToggle::FFMPEGConfigAudioToggle(FFMPEGConfigAudio *popup, - char *title_text, int x, int y, int *output) - : BC_CheckBox(x, y, *output, title_text) -{ - this->popup = popup; - this->output = output; -} -int FFMPEGConfigAudioToggle::handle_event() -{ - *output = get_value(); - return 1; -} - - -//====== - -FFMPEGConfigVideo::FFMPEGConfigVideo(BC_WindowBase *parent_window, Asset *asset) - : BC_Window(_(PROGRAM_NAME ": Video Preset"), - parent_window->get_abs_cursor_x(1), - parent_window->get_abs_cursor_y(1), - 420, 420) -{ - this->parent_window = parent_window; - this->asset = asset; - preset_popup = 0; - - bitrate = 0; - quality = 0; - video_options = 0; -} - -FFMPEGConfigVideo::~FFMPEGConfigVideo() -{ - lock_window("FFMPEGConfigVideo::~FFMPEGConfigVideo"); - if(preset_popup) delete preset_popup; - presets.remove_all_objects(); - unlock_window(); -} - -void FFMPEGConfigVideo::create_objects() -{ - int x = 10, y = 10; - lock_window("FFMPEGConfigVideo::create_objects"); - - add_subwindow(new BC_Title(x, y, _("Compression:"))); - y += 25; - - FileSystem fs; - char option_path[BCTEXTLEN]; - FFMPEG::set_option_path(option_path, "video"); - fs.update(option_path); - int total_files = fs.total_files(); - for(int i = 0; i < total_files; i++) { - const char *name = fs.get_entry(i)->get_name(); - if( asset->fformat[0] != 0 ) { - const char *ext = strrchr(name,'.'); - if( !ext ) continue; - if( strcmp(asset->fformat, ++ext) ) continue; - } - presets.append(new BC_ListBoxItem(name)); - } - - if( asset->vcodec[0] ) { - int k = presets.size(); - while( --k >= 0 && strcmp(asset->vcodec, presets[k]->get_text()) ); - if( k < 0 ) asset->vcodec[0] = 0; - } - - if( !asset->vcodec[0] && presets.size() > 0 ) - strcpy(asset->vcodec, presets[0]->get_text()); - - preset_popup = new FFMPEGConfigVideoPopup(this, x, y); - preset_popup->create_objects(); - - if( asset->ff_video_bitrate && asset->ff_video_quality ) { - asset->ff_video_bitrate = 0; - asset->ff_video_quality = 0; - } - - y += 50; - bitrate = new FFMpegVideoBitrate(this, x, y, _("Bitrate:"), &asset->ff_video_bitrate); - bitrate->create_objects(); - bitrate->set_increment(100000); - y += bitrate->get_h() + 5; - quality = new FFMpegVideoQuality(this, x, y, _("Quality:"), &asset->ff_video_quality); - quality->create_objects(); - quality->set_increment(1); - quality->set_boundaries((int64_t)0, (int64_t)31); - - y += quality->get_h() + 10; - add_subwindow(new BC_Title(x, y, _("Video Options:"))); - y += 25; - if( !asset->ff_video_options[0] && asset->vcodec[0] ) { - FFMPEG::set_option_path(option_path, "video/%s", asset->vcodec); - FFMPEG::load_options(option_path, asset->ff_video_options, - sizeof(asset->ff_video_options)); - } - add_subwindow(video_options = new FFVideoOptions(this, x, y, get_w()-x-20, 10, - sizeof(asset->ff_video_options)-1, asset->ff_video_options)); - - add_subwindow(new BC_OKButton(this)); - show_window(1); - if( asset->ff_video_bitrate ) - quality->disable(); - if( asset->ff_video_quality ) - bitrate->disable(); - unlock_window(); -} - -int FFMPEGConfigVideo::close_event() -{ - set_done(0); - return 1; -} - - -FFVideoOptions::FFVideoOptions(FFMPEGConfigVideo *video_popup, - int x, int y, int w, int rows, int size, char *text) - : BC_TextBox(x, y, w, rows, size, text) -{ - this->video_popup = video_popup; -} - -int FFVideoOptions::handle_event() -{ - strcpy(video_popup->asset->ff_video_options, get_text()); - return 1; -} - - -FFMPEGConfigVideoPopup::FFMPEGConfigVideoPopup(FFMPEGConfigVideo *popup, int x, int y) - : BC_PopupTextBox(popup, &popup->presets, popup->asset->vcodec, x, y, 300, 300) -{ - this->popup = popup; -} - -int FFMPEGConfigVideoPopup::handle_event() -{ - strcpy(popup->asset->vcodec, get_text()); - Asset *asset = popup->asset; - char option_path[BCTEXTLEN]; - FFMPEG::set_option_path(option_path, "video/%s", asset->vcodec); - FFMPEG::load_options(option_path, asset->ff_video_options, - sizeof(asset->ff_video_options)); - popup->video_options->update(asset->ff_video_options); - return 1; -} - - -FFMPEGConfigVideoToggle::FFMPEGConfigVideoToggle(FFMPEGConfigVideo *popup, - char *title_text, int x, int y, int *output) - : BC_CheckBox(x, y, *output, title_text) -{ - this->popup = popup; - this->output = output; -} -int FFMPEGConfigVideoToggle::handle_event() -{ - *output = get_value(); - return 1; -} - -FFMPEGScanProgress::FFMPEGScanProgress(const char *title, int64_t length, int64_t *position, int *canceled) - : Thread(1, 0, 0) -{ - strcpy(this->progress_title, title); - this->length = length; - this->position = position; - this->canceled = canceled; - done = 0; - progress = 0; - start(); -} - -FFMPEGScanProgress::~FFMPEGScanProgress() -{ - done = 1; - cancel(); - join(); -} - -void FFMPEGScanProgress::run() -{ - BC_ProgressBox *progress = new BC_ProgressBox(-1, -1, progress_title, length); - progress->start(); - - struct timeval start_time, now, then; - gettimeofday(&start_time, 0); - then = start_time; - - while( !done ) { - if( progress->update(*position, 1) ) { - *canceled = done = 1; - break; - } - gettimeofday(&now, 0); - if(now.tv_sec - then.tv_sec >= 1) { - int64_t elapsed = now.tv_sec - start_time.tv_sec; - int64_t byte_rate = *position / elapsed; - int64_t eta = !byte_rate ? 0 : (length - *position) / byte_rate; - char string[BCTEXTLEN]; - sprintf(string, "%s\nETA: " _LD "m" _LD "s", - progress_title, eta / 60, eta % 60); - progress->update_title(string, 1); - then = now; - } - usleep(500000); - } - - progress->stop_progress(); - delete progress; -} - -int FileFFMPEG::get_index(char *index_path) -{ - if( !ff ) return -1; - if( !file->preferences->ffmpeg_marker_indecies ) return 1; - - IndexState *index_state = asset->index_state; - if( index_state->index_status != INDEX_NOTTESTED ) return 0; - index_state->index_status = INDEX_BUILDING; - - for( int aidx=0; aidxffaudio.size(); ++aidx ) { - FFAudioStream *aud = ff->ffaudio[aidx]; - index_state->add_audio_stream(aud->channels, aud->length); - } - - char progress_title[BCTEXTLEN]; - sprintf(progress_title, _("Creating %s\n"), index_path); - FileSystem fs; - int64_t file_bytes = fs.get_size(ff->fmt_ctx->filename); - int64_t scan_position = 0; - int canceled = 0; - FFMPEGScanProgress scan_progress(progress_title, file_bytes, &scan_position, &canceled); - - index_state->index_bytes = file_bytes; - index_state->init_scan(file->preferences->index_size); - if( ff->scan(index_state, &scan_position, &canceled) || canceled ) { - index_state->reset_index(); - index_state->reset_markers(); - return 1; - } - index_state->marker_status = MARKERS_READY; - return index_state->create_index(index_path, asset); -} -