4 * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "assetedit.h"
25 #include "awindowgui.h"
26 #include "bcprogressbox.h"
27 #include "bcsignals.h"
28 #include "bitspopup.h"
31 #include "cplayback.h"
34 #include "edlsession.h"
37 #include "fileffmpeg.h"
38 #include "filesystem.h"
40 #include "indexable.h"
41 #include "indexfile.h"
42 #include "indexstate.h"
44 #include "mainindexes.h"
46 #include "mwindowgui.h"
48 #include "preferences.h"
49 #include "resizetrackthread.h"
50 #include "removefile.h"
52 #include "transportque.h"
58 AssetEdit::AssetEdit(MWindow *mwindow)
61 this->mwindow = mwindow;
64 changed_params = new Asset;
69 AssetEdit::~AssetEdit()
72 changed_params->remove_user();
76 void AssetEdit::edit_asset(Indexable *indexable)
83 this->indexable = indexable;
84 this->indexable->add_user();
86 // Copy asset parameters into temporary storage for editing.
87 if(indexable->is_asset)
89 changed_params->copy_from((Asset*)indexable, 0);
93 EDL *nested_edl = (EDL*)indexable;
95 strcpy(changed_params->path, nested_edl->path);
96 changed_params->sample_rate = nested_edl->session->sample_rate;
97 changed_params->channels = nested_edl->session->audio_channels;
99 //printf("AssetEdit::edit_asset %d %f\n", __LINE__, nested_edl->session->frame_rate);
100 changed_params->frame_rate = nested_edl->session->frame_rate;
101 changed_params->width = nested_edl->session->output_w;
102 changed_params->height = nested_edl->session->output_h;
105 BC_DialogThread::start();
108 void AssetEdit::handle_close_event(int result)
116 if(indexable->is_asset)
118 asset = (Asset*)indexable;
119 if(!changed_params->equivalent(*asset, 1, 1))
124 nested_edl = (EDL*)indexable;
125 if(strcmp(changed_params->path, nested_edl->path)
127 // changed_params->sample_rate != nested_edl->session->sample_rate ||
128 // !EQUIV(changed_params->frame_rate, nested_edl->session->frame_rate)
132 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
136 mwindow->gui->lock_window();
137 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
139 // Omit index status from copy since an index rebuild may have been
140 // happening when new_asset was created but not be happening anymore.
143 mwindow->remove_asset_from_caches(asset);
144 //printf("AssetEdit::handle_close_event %d %f\n", __LINE__, asset->get_frame_rate());
145 asset->copy_from(changed_params, 0);
146 //printf("AssetEdit::handle_close_event %d %d %d\n", __LINE__, changed_params->bits, asset->bits);
150 strcpy(nested_edl->path, changed_params->path);
151 // Other parameters can't be changed because they're defined in the other EDL
152 // nested_edl->session->frame_rate = changed_params->frame_rate;
153 // nested_edl->session->sample_rate = changed_params->sample_rate;
155 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
157 mwindow->gui->update(0,
164 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
166 // Start index rebuilding
167 if( (asset && asset->audio_data) || nested_edl)
169 char source_filename[BCTEXTLEN];
170 char index_filename[BCTEXTLEN];
171 IndexFile::get_index_filename(source_filename,
172 mwindow->preferences->index_directory,
175 remove_file(index_filename);
176 indexable->index_state->index_status = INDEX_NOTTESTED;
177 mwindow->mainindexes->add_next_asset(0, indexable);
178 mwindow->mainindexes->start_build();
180 mwindow->gui->unlock_window();
181 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
184 mwindow->awindow->gui->lock_window();
185 mwindow->awindow->gui->update_assets();
186 mwindow->awindow->gui->unlock_window();
187 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
189 mwindow->restart_brender();
190 mwindow->sync_parameters(CHANGE_ALL);
191 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
195 this->indexable->remove_user();
197 //printf("AssetEdit::handle_close_event %d\n", __LINE__);
200 BC_Window* AssetEdit::new_gui()
202 window = new AssetEditWindow(mwindow, this);
203 window->create_objects();
215 AssetEditWindow::AssetEditWindow(MWindow *mwindow, AssetEdit *asset_edit)
216 : BC_Window(_(PROGRAM_NAME ": Asset Info"),
217 mwindow->gui->get_abs_cursor_x(1) - 400 / 2,
218 mwindow->gui->get_abs_cursor_y(1) - 500 / 2,
227 this->mwindow = mwindow;
228 this->asset_edit = asset_edit;
242 AssetEditWindow::~AssetEditWindow()
244 lock_window("AssetEditWindow::~AssetEditWindow");
245 if(bitspopup) delete bitspopup;
246 if(detail_thread) delete detail_thread;
253 void AssetEditWindow::create_objects()
255 int y = 10, x = 10, x1 = 10, x2 = 150;
256 char string[BCTEXTLEN];
263 if(asset_edit->indexable->is_asset)
264 asset = (Asset*)asset_edit->indexable;
266 nested_edl = (EDL*)asset_edit->indexable;
268 if(asset && asset->format == FILE_PCM)
273 lock_window("AssetEditWindow::create_objects");
279 add_subwindow(path_text = new AssetEditPathText(this, y));
280 add_subwindow(path_button = new AssetEditPath(mwindow,
284 asset_edit->indexable->path,
285 _(PROGRAM_NAME ": Asset path"), _("Select a file for this asset:")));
290 add_subwindow(new BC_Title(x, y, _("File format:")));
292 add_subwindow(new BC_Title(x, y, File::formattostr(mwindow->plugindb,
295 mwindow->theme->assetedit_color));
299 int64_t bytes = fs.get_size(asset->path);
300 add_subwindow(new BC_Title(x, y, _("Bytes:")));
301 sprintf(string, "" _LD "", bytes);
302 Units::punctuate(string);
305 add_subwindow(new BC_Title(x2, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
306 if(asset->format == FILE_MPEG || asset->format == FILE_FFMPEG)
308 detail_thread = new DetailAssetThread(mwindow);
309 BC_GenericButton *detail = new DetailAssetButton(this, x2+120, y);
310 add_subwindow(detail);
320 if(asset->audio_length > 0)
321 length = (double)asset->audio_length / asset->sample_rate;
322 if(asset->video_length > 0)
323 length = MAX(length, (double)asset->video_length / asset->frame_rate);
325 if(!EQUIV(length, 0))
326 bitrate = (int64_t)(bytes * 8 / length);
329 add_subwindow(new BC_Title(x, y, _("Bitrate (bits/sec):")));
330 sprintf(string, "" _LD "", bitrate);
332 Units::punctuate(string);
333 add_subwindow(new BC_Title(x2, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
339 if((asset && asset->audio_data) || nested_edl)
341 add_subwindow(new BC_Bar(x, y, get_w() - x * 2));
344 add_subwindow(new BC_Title(x, y, _("Audio:"), LARGEFONT, RED));
350 if(asset->get_compression_text(1, 0))
352 add_subwindow(new BC_Title(x, y, _("Compression:")));
354 add_subwindow(new BC_Title(x,
356 asset->get_compression_text(1, 0),
358 mwindow->theme->assetedit_color));
364 add_subwindow(new BC_Title(x, y, _("Channels:")));
365 sprintf(string, "%d", asset_edit->changed_params->channels);
370 BC_TumbleTextBox *textbox = new AssetEditChannels(this,
374 textbox->create_objects();
379 add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
384 add_subwindow(new BC_Title(x, y, _("Sample rate:")));
385 sprintf(string, "%d", asset_edit->changed_params->sample_rate);
391 add_subwindow(textbox = new AssetEditRate(this, string, x, y));
392 x += textbox->get_w();
393 add_subwindow(new SampleRatePulldown(mwindow, textbox, x, y));
397 add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
405 add_subwindow(new BC_Title(x, y, _("Bits:")));
409 bitspopup = new BitsPopup(this,
412 &asset_edit->changed_params->bits,
418 bitspopup->create_objects();
421 add_subwindow(new BC_Title(x, y, File::bitstostr(asset->bits), MEDIUMFONT, mwindow->theme->assetedit_color));
426 add_subwindow(new BC_Title(x, y, _("Header length:")));
427 sprintf(string, "%d", asset->header);
431 add_subwindow(new AssetEditHeader(this, string, x, y));
433 add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
438 add_subwindow(new BC_Title(x, y, _("Byte order:")));
444 add_subwindow(lohi = new AssetEditByteOrderLOHI(this,
449 add_subwindow(hilo = new AssetEditByteOrderHILO(this,
458 if(asset->byte_order)
459 add_subwindow(new BC_Title(x, y, _("Lo-Hi"), MEDIUMFONT, mwindow->theme->assetedit_color));
461 add_subwindow(new BC_Title(x, y, _("Hi-Lo"), MEDIUMFONT, mwindow->theme->assetedit_color));
469 // add_subwindow(new BC_Title(x, y, _("Values are signed:")));
470 add_subwindow(new AssetEditSigned(this, asset->signed_, x, y));
474 if(!asset->signed_ && asset->bits == 8)
475 add_subwindow(new BC_Title(x, y, _("Values are unsigned")));
477 add_subwindow(new BC_Title(x, y, _("Values are signed")));
485 if((asset && asset->video_data) || nested_edl)
487 add_subwindow(new BC_Bar(x, y, get_w() - x * 2));
490 add_subwindow(new BC_Title(x, y, _("Video:"), LARGEFONT, RED));
495 if(asset && asset->get_compression_text(0,1))
497 add_subwindow(new BC_Title(x, y, _("Compression:")));
499 add_subwindow(new BC_Title(x,
501 asset->get_compression_text(0,1),
503 mwindow->theme->assetedit_color));
508 add_subwindow(new BC_Title(x, y, _("Frame rate:")));
510 sprintf(string, "%.2f", asset_edit->changed_params->frame_rate);
512 //printf("AssetEditWindow::create_objects %d %f\n", __LINE__, asset_edit->changed_params->frame_rate);
515 BC_TextBox *framerate;
516 add_subwindow(framerate = new AssetEditFRate(this, string, x, y));
518 add_subwindow(new FrameRatePulldown(mwindow, framerate, x, y));
522 add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
527 add_subwindow(new BC_Title(x, y, _("Width:")));
529 sprintf(string, "%d", asset_edit->changed_params->width);
530 win_width = new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color);
531 add_subwindow(win_width);
535 add_subwindow(new BC_Title(x, y, _("Height:")));
537 sprintf(string, "%d", asset_edit->changed_params->height);
538 win_height = new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color);
539 add_subwindow(win_height);
540 y += win_height->get_h() + 5;
542 if(asset && (asset->format == FILE_MPEG || asset->format == FILE_FFMPEG ) )
546 add_subwindow(new BC_Title(x, y, _("Actual width:")));
548 sprintf(string, "%d", asset->actual_width);
549 add_subwindow(new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color));
551 BC_GenericButton *resize = new ResizeAssetButton(this, x+64, y);
552 add_subwindow(resize);
556 add_subwindow(new BC_Title(x, y, _("Actual height:")));
558 sprintf(string, "%d", asset->actual_height);
559 title = new BC_Title(x, y, string, MEDIUMFONT, mwindow->theme->assetedit_color);
560 add_subwindow(title);
561 y += title->get_h() + 5;
565 add_subwindow(new BC_OKButton(this));
566 add_subwindow(new BC_CancelButton(this));
571 void AssetEditWindow::show_info_detail()
573 detail_thread->start((Asset*)asset_edit->indexable);
577 AssetEditChannels::AssetEditChannels(AssetEditWindow *fwindow,
581 : BC_TumbleTextBox(fwindow,
589 this->fwindow = fwindow;
592 int AssetEditChannels::handle_event()
594 Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
595 asset->channels = atol(get_text());
599 AssetEditRate::AssetEditRate(AssetEditWindow *fwindow, char *text, int x, int y)
600 : BC_TextBox(x, y, 100, 1, text)
602 this->fwindow = fwindow;
605 int AssetEditRate::handle_event()
607 Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
608 asset->sample_rate = atol(get_text());
612 AssetEditFRate::AssetEditFRate(AssetEditWindow *fwindow, char *text, int x, int y)
613 : BC_TextBox(x, y, 100, 1, text)
615 this->fwindow = fwindow;
618 int AssetEditFRate::handle_event()
620 Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
621 asset->frame_rate = atof(get_text());
625 AssetEditHeader::AssetEditHeader(AssetEditWindow *fwindow, char *text, int x, int y)
626 : BC_TextBox(x, y, 100, 1, text)
628 this->fwindow = fwindow;
631 int AssetEditHeader::handle_event()
633 Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
634 asset->header = atol(get_text());
638 AssetEditByteOrderLOHI::AssetEditByteOrderLOHI(AssetEditWindow *fwindow,
642 : BC_Radial(x, y, value, _("Lo-Hi"))
644 this->fwindow = fwindow;
647 int AssetEditByteOrderLOHI::handle_event()
649 Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
650 asset->byte_order = 1;
651 fwindow->hilo->update(0);
656 AssetEditByteOrderHILO::AssetEditByteOrderHILO(AssetEditWindow *fwindow,
660 : BC_Radial(x, y, value, _("Hi-Lo"))
662 this->fwindow = fwindow;
665 int AssetEditByteOrderHILO::handle_event()
667 Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
668 asset->byte_order = 0;
669 fwindow->lohi->update(0);
674 AssetEditSigned::AssetEditSigned(AssetEditWindow *fwindow,
678 : BC_CheckBox(x, y, value, _("Values are signed"))
680 this->fwindow = fwindow;
683 int AssetEditSigned::handle_event()
685 Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
686 asset->signed_ = get_value();
696 AssetEditPathText::AssetEditPathText(AssetEditWindow *fwindow, int y)
697 : BC_TextBox(5, y, 300, 1, fwindow->asset_edit->changed_params->path)
699 this->fwindow = fwindow;
701 AssetEditPathText::~AssetEditPathText()
704 int AssetEditPathText::handle_event()
706 strcpy(fwindow->asset_edit->changed_params->path, get_text());
710 AssetEditPath::AssetEditPath(MWindow *mwindow,
711 AssetEditWindow *fwindow,
715 const char *window_title,
716 const char *window_caption)
717 : BrowseButton(mwindow,
727 this->fwindow = fwindow;
729 AssetEditPath::~AssetEditPath() {}
736 AssetEditFormat::AssetEditFormat(AssetEditWindow *fwindow, char* default_, int y)
737 : FormatPopup(fwindow->mwindow->plugindb, 90, y)
739 this->fwindow = fwindow;
741 AssetEditFormat::~AssetEditFormat()
744 int AssetEditFormat::handle_event()
746 Asset *asset = (Asset*)fwindow->asset_edit->changed_params;
747 asset->format = File::strtoformat(fwindow->mwindow->plugindb,
748 get_selection(0, 0)->get_text());
755 DetailAssetButton::DetailAssetButton(AssetEditWindow *fwindow, int x, int y)
756 : BC_GenericButton(x, y, _("Detail"))
758 this->fwindow = fwindow;
762 DetailAssetButton::~DetailAssetButton()
766 int DetailAssetButton::handle_event()
768 fwindow->show_info_detail();
772 DetailAssetWindow::DetailAssetWindow(MWindow *mwindow, Asset *asset)
773 : BC_Window(_("Asset Detail"),
774 mwindow->gui->get_abs_cursor_x(1) - 600/2,
775 mwindow->gui->get_abs_cursor_y(1) - 500/2,
778 this->mwindow = mwindow;
785 DetailAssetWindow::~DetailAssetWindow()
787 asset->remove_user();
791 DetailAssetThread::DetailAssetThread(MWindow *mwindow)
794 this->mwindow = mwindow;
798 DetailAssetThread::~DetailAssetThread()
803 void DetailAssetThread::stop()
805 if( Thread::running() ) {
806 dwindow->lock_window("DetailAssetThread::stop");
807 dwindow->set_done(1);
808 dwindow->unlock_window();
813 void DetailAssetWindow::create_objects()
816 char file_name[BCTEXTLEN];
817 int len = sizeof(info);
818 strncpy(info,_("no info available"),len);
819 if( !mwindow->preferences->get_asset_file_path(asset, file_name) ) {
820 switch( asset->format ) {
822 FileMPEG::get_info(asset->path, file_name, &info[0],len);
825 FileFFMPEG::get_info(asset->path, &info[0],len);
829 lock_window("DetailAssetThread::create_objects");
830 text = new BC_ScrollTextBox(this, x, y, get_w()-32, 23, info, -len);
831 text->create_objects(); text->set_text_row(0);
832 add_subwindow(new BC_OKButton(this));
837 void DetailAssetThread::start(Asset *asset)
841 dwindow = new DetailAssetWindow(mwindow, asset);
845 void DetailAssetThread::run()
847 // Get length from TOC
848 dwindow->create_objects();
849 dwindow->run_window();