X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fcinelerra%2Frecordvideo.C;fp=cinelerra-5.0%2Fcinelerra%2Frecordvideo.C;h=0000000000000000000000000000000000000000;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=2abd343a564fddb34cf6f68bf1b928b24a3f3884;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/cinelerra/recordvideo.C b/cinelerra-5.0/cinelerra/recordvideo.C deleted file mode 100644 index 2abd343a..00000000 --- a/cinelerra-5.0/cinelerra/recordvideo.C +++ /dev/null @@ -1,311 +0,0 @@ - -/* - * CINELERRA - * Copyright (C) 2008 Adam Williams - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "asset.h" -#include "batch.h" -#include "bcsignals.h" -#include "clip.h" -#include "condition.h" -#include "edl.h" -#include "edlsession.h" -#include "errorbox.h" -#include "file.h" -#include "filethread.h" -#include "language.h" -#include "libmjpeg.h" -#include "mutex.h" -#include "mwindow.h" -#include "mwindowgui.h" -#include "preferences.h" -#include "record.h" -#include "recordaudio.h" -#include "recordgui.h" -#include "recordvideo.h" -#include "recordmonitor.h" -#include "units.h" -#include "vframe.h" -#include "videodevice.h" - -#include - - -RecordVideo::RecordVideo(MWindow *mwindow, Record *record) - : Thread(1, 0, 0) -{ - this->mwindow = mwindow; - this->record = record; - this->gui = record->record_gui; - trigger_lock = new Condition(0, "RecordVideo::trigger_lock"); - pause_record_lock = new Condition(0, "RecordVideo::pause_record_lock"); - record_paused_lock = new Condition(0, "RecordVideo::record_paused_lock"); - frame_ptr = 0; - buffer_frame = 0; - reset_parameters(); - done = -1; -} - -RecordVideo::~RecordVideo() -{ - stop_recording(); - delete_buffer(); - delete trigger_lock; - delete pause_record_lock; - delete record_paused_lock; -} - -void RecordVideo::reset_parameters() -{ - write_result = 0; - writing_file = 0; - grab_result = 0; - buffer_frames = mwindow->edl->session->video_write_length; - buffer_position = 0; - recording_paused = 0; - record_start = 0; - trigger_lock->reset(); - pause_record_lock->reset(); - record_paused_lock->reset(); -} - -void RecordVideo::arm_recording() -{ - reset_parameters(); - done = 0; - Thread::start(); -} - -void RecordVideo::start_recording() -{ - trigger_lock->unlock(); -} - -void RecordVideo::stop_recording() -{ - if( done ) return; -// Device won't exist if interrupting a cron job - done = 1; - if( record->vdevice ) { -// Interrupt IEEE1394 crashes - record->vdevice->interrupt_crash(); -// Interrupt video4linux crashes - if( record->vdevice->get_failed() ) - Thread::cancel(); - } - Thread::join(); -// Joined in RecordThread -} - - -VFrame *RecordVideo::get_buffer() -{ - VFrame *result = 0; - record->file_lock->lock(); - writing_file = record->writing_file > 0 && record->do_video ? 1 : 0; - if( writing_file ) { - if( !frame_ptr ) { - frame_ptr = record->file->get_video_buffer(); - buffer_position = 0; - } - result = frame_ptr[0][buffer_position]; - - } - record->file_lock->unlock(); - if( !result ) { - if( !buffer_frame ) { - if( !record->fixed_compression ) { - Asset *asset = record->default_asset; - int w = asset->width, h = asset->height; - int cmodel = record->vdevice->get_best_colormodel(asset); - buffer_frame = new VFrame(w, h, cmodel); - } - else - buffer_frame = new VFrame; - } - buffer_position = 0; - result = buffer_frame; - } - return result; -} - -void RecordVideo::delete_buffer() -{ - RecordMonitorThread *thr = !record->record_monitor ? - 0 : record->record_monitor->thread; - if( thr && thr->running() ) thr->lock_input(); - frame_ptr = 0; - if( buffer_frame ) { - delete buffer_frame; - buffer_frame = 0; - } - if( thr && thr->running() ) thr->unlock_input(); -} - -void RecordVideo::config_update() -{ - VideoDevice *vdevice = record->vdevice; - vdevice->config_update(); - int width = vdevice->get_iwidth(); - int height = vdevice->get_iheight(); - double frame_rate = vdevice->get_irate(); - float awidth, aheight; - MWindow::create_aspect_ratio(awidth, aheight, width, height); - EDLSession *session = record->edl->session; - SESSION->aspect_w = session->aspect_w = awidth; - SESSION->aspect_h = session->aspect_h = aheight; - SESSION->output_w = session->output_w = width; - SESSION->output_h = session->output_h = height; - Asset *rf_asset = SESSION->recording_format; - Asset *df_asset = record->default_asset; - rf_asset->width = df_asset->width = width; - rf_asset->height = df_asset->height = height; - rf_asset->frame_rate = df_asset->frame_rate = frame_rate; -} - -void RecordVideo::run() -{ -// Number of frames for user to know about. - gui->reset_video(); - -// Wait for trigger - trigger_lock->lock("RecordVideo::run"); - - while( !done && !write_result ) { - if( recording_paused ) { - pause_record_lock->unlock(); - record_paused_lock->lock(); - } - if( done ) break; - VideoDevice *vdevice = record->vdevice; - VFrame *capture_frame = get_buffer(); - vdevice->set_field_order(record->reverse_interlace); -// Capture a frame - grab_result = read_buffer(capture_frame); - if( done ) break; - if( vdevice->config_updated() ) { - flush_buffer(); - delete_buffer(); - config_update(); - gui->reset_video(); - record->record_monitor->reconfig(); - continue; - } - if( grab_result ) { - Timer::delay(250); - continue; - } - decompress_buffer(capture_frame); - record->resync(); - write_buffer(); - if( record->monitor_video && capture_frame->get_data() ) - if( !writing_file || !record->is_behind() ) - record->record_monitor->update(capture_frame); - if( writing_file && record->fill_underrun_frames ) { - VFrame *last_frame = capture_frame; - int fill = record->dropped; - while( --fill >= 0 ) { - capture_frame = get_buffer(); - capture_frame->copy_from(last_frame); - last_frame = capture_frame; - write_buffer(); - } - } - else - record->written_frames += record->dropped; - if( record->single_frame ) { - record->single_frame = 0; - record->stop_writing_file(); - } - if( done ) break; - if( !done ) done = write_result; - if( done ) break; - record->check_batch_complete(); - } - -SET_TRACE - flush_buffer(); - delete_buffer(); -SET_TRACE -//TRACE("RecordVideo::run 2"); - if( write_result ) { - ErrorBox error_box(_(PROGRAM_NAME ": Error"), - mwindow->gui->get_abs_cursor_x(1), - mwindow->gui->get_abs_cursor_y(1)); - error_box.create_objects(_("No space left on disk.")); - error_box.run_window(); - } -SET_TRACE -} - -int RecordVideo::read_buffer(VFrame *frame) -{ - return record->vdevice->read_buffer(frame); -} - -void RecordVideo::decompress_buffer(VFrame *frame) -{ - if( !strcmp(record->default_asset->vcodec, CODEC_TAG_MJPEG) && - record->vdevice->is_compressed(0, 1)) { - unsigned char *data = frame->get_data(); - int64_t size = frame->get_compressed_size(); - //int64_t allocation = frame->get_compressed_allocated(); - if( data ) { - int64_t field2_offset = mjpeg_get_field2(data, size); - frame->set_compressed_size(size); - frame->set_field2_offset(field2_offset); - } - } -} - -int RecordVideo::flush_buffer() -{ - record->file_lock->lock(); - if( writing_file && frame_ptr ) { - int result = record->file->write_video_buffer(buffer_position); - if( result ) write_result = 1; - frame_ptr = 0; - } - record->file_lock->unlock(); - buffer_position = 0; - return write_result; -} - -int RecordVideo::write_buffer() -{ - ++record->written_frames; - if( ++buffer_position >= buffer_frames ) - flush_buffer(); -// HACK -write_result = 0; - return write_result; -} - -void RecordVideo::pause_recording() -{ - recording_paused = 1; - pause_record_lock->lock(); -} - -void RecordVideo::resume_recording() -{ - recording_paused = 0; - record_paused_lock->unlock(); -} -