+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
- * 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 "bcsignals.h"
-#include "bitspopup.h"
-#include "byteorder.h"
-#include "clip.h"
-#include "condition.h"
-#include "edit.h"
-#include "file.h"
-#include "filemov.h"
-#include "format.inc"
-#include "guicast.h"
-#include "language.h"
-#include "mutex.h"
-#include "mwindow.inc"
-#include "preferences.h"
-#include "vframe.h"
-#include "videodevice.inc"
-#include "mainerror.h"
-
-#include <unistd.h>
-#include <libdv/dv.h>
-#include <string.h>
-
-#if 0
-N_("MPEG-4")
-N_("Dual H.264")
-N_("Dual MPEG-4")
-N_("H.264")
-N_("H.263")
-N_("Microsoft MPEG-4")
-N_("DV")
-N_("PNG")
-N_("PNG with Alpha")
-N_("Uncompressed RGB")
-N_("Uncompressed RGBA")
-N_("YUV 4:2:0 Planar")
-N_("Component Y'CbCr 8-bit 4:2:2 (yuv2)")
-N_("Component Y'CbCr 8-bit 4:2:2 (2vuy)")
-N_("YUV 4:1:1 Packed")
-N_("Component Y'CbCr 8-bit 4:4:4")
-N_("Component Y'CbCrA 8-bit 4:4:4:4")
-N_("Component Y'CbCr 10-bit 4:4:4")
-N_("JPEG Photo")
-N_("Motion JPEG A")
-
-
-N_("Twos complement")
-N_("Unsigned")
-N_("IMA-4")
-N_("U-Law")
-N_("Vorbis")
-N_("MP3")
-N_("MPEG-4 Audio")
-#endif
-
-#define DIVX_NAME "MPEG-4"
-#define HV64_NAME "Dual H.264"
-#define MP4V_NAME "MPEG-4 Video"
-#define H264_NAME "H.264"
-#define H263_NAME "H.263"
-#define HV60_NAME "Dual MPEG-4"
-#define DIV3_NAME "Microsoft MPEG-4"
-#define DV_NAME "DV"
-#define PNG_NAME "PNG"
-#define PNGA_NAME "PNG with Alpha"
-#define RGB_NAME "Uncompressed RGB"
-#define RGBA_NAME "Uncompressed RGBA"
-#define YUV420_NAME "YUV 4:2:0 Planar"
-#define YUV422_NAME "Component Y'CbCr 8-bit 4:2:2 (yuv2)"
-#define TWOVUY_NAME "Component Y'CbCr 8-bit 4:2:2 (2vuy)"
-#define YUV411_NAME "YUV 4:1:1 Packed"
-#define YUV444_NAME "Component Y'CbCr 8-bit 4:4:4"
-#define YUVA4444_NAME "Component Y'CbCrA 8-bit 4:4:4:4"
-#define YUV444_10BIT_NAME "Component Y'CbCr 10-bit 4:4:4"
-#define QTJPEG_NAME "JPEG Photo"
-#define QTMJPEGP_NAME "MJPEG Photo"
-#define MJPA_NAME "Motion JPEG A"
-
-#define TWOS_NAME "Twos complement"
-#define RAW_NAME "Unsigned"
-#define IMA4_NAME "IMA-4"
-#define ULAW_NAME "U-Law"
-//#define VORBIS_NAME "Vorbis"
-#define MP3_NAME "MP3"
-#define MP4A_NAME "MPEG-4 Audio"
-#define VORBIS_NAME "OGG Vorbis"
-
-
-
-
-
-FileMOV::FileMOV(Asset *asset, File *file)
- : FileBase(asset, file)
-{
- reset_parameters();
- if(asset->format == FILE_UNKNOWN)
- asset->format = FILE_MOV;
- asset->byte_order = 0;
- suffix_number = 0;
- threadframe_lock = new Mutex("FileMOV::threadframe_lock");
-}
-
-FileMOV::~FileMOV()
-{
- close_file();
- delete threadframe_lock;
-}
-
-void FileMOV::get_parameters(BC_WindowBase *parent_window,
- Asset *asset,
- BC_WindowBase* &format_window,
- int audio_options,
- int video_options,
- const char *locked_compressor)
-{
- fix_codecs(asset);
- if(audio_options)
- {
- MOVConfigAudio *window = new MOVConfigAudio(parent_window, asset);
- format_window = window;
- window->create_objects();
- window->run_window();
- delete window;
- }
- else
- if(video_options)
- {
- MOVConfigVideo *window = new MOVConfigVideo(parent_window,
- asset,
- locked_compressor);
- format_window = window;
- window->create_objects();
- window->run_window();
- delete window;
- }
-}
-
-void FileMOV::fix_codecs(Asset *asset)
-{
- if(!strcasecmp(asset->vcodec, QUICKTIME_DV) ||
- !strcasecmp(asset->vcodec, QUICKTIME_DVSD) ||
- !strcasecmp(asset->vcodec, QUICKTIME_DVCP))
- {
-// printf("AF: %i, AH: %i, VC: %s\n", asset->format, asset->height, asset->vcodec);
- if (asset->format == FILE_AVI)
- strcpy (asset->vcodec, QUICKTIME_DVSD);
- else if (asset->format == FILE_MOV && asset->height == 576)
- strcpy (asset->vcodec, QUICKTIME_DVCP);
- else if (asset->format == FILE_MOV && asset->height == 480)
- strcpy (asset->vcodec, QUICKTIME_DV);
- }
-}
-
-int FileMOV::check_codec_params(Asset *asset)
-{
- if(!strcasecmp(asset->vcodec, QUICKTIME_DV) ||
- !strcasecmp(asset->vcodec, QUICKTIME_DVSD) ||
- !strcasecmp(asset->vcodec, QUICKTIME_DVCP))
- {
- if (!(asset->height == 576 && asset->width == 720) &&
- !(asset->height == 480 && asset->width == 720))
- {
- eprintf(_("DV in Quicktime container does not support following resolution: %ix%i\n"
- "Allowed resolutions are 720x576 (PAL) and 720x480 (NTSC)\n"),
- asset->width, asset->height);
- return 1;
- }
- }
- return 0;
-}
-
-
-int FileMOV::check_sig(Asset *asset)
-{
- int result = quicktime_check_sig(asset->path);
- if(result == 2) result = 0;
- return result;
-}
-
-int FileMOV::reset_parameters_derived()
-{
- fd = 0;
- prev_track = 0;
- quicktime_atracks = 0;
- quicktime_vtracks = 0;
- depth = 24;
- threads = 0;
- frames_correction = 0;
- samples_correction = 0;
- temp_float = 0;
- temp_allocated = 0;
- return 0;
-}
-
-
-// Just create the Quicktime objects since this routine is also called
-// for reopening.
-int FileMOV::open_file(int rd, int wr)
-{
-
- if(suffix_number == 0) strcpy(prefix_path, asset->path);
-
- if(!(fd = quicktime_open(asset->path, rd, wr)))
- {
- eprintf(_("Error while opening file \"%s\". \n%m\n"), asset->path);
- return 1;
- }
-
- if( !strcmp(asset->vcodec, QUICKTIME_DIV3) )
- file->cpus = 1;
- quicktime_set_cpus(fd, file->cpus);
- quicktime_set_cache_max(fd, file->preferences->cache_size);
-//printf("FileMOV::open_file %d %d\n", __LINE__, file->preferences->cache_size);
-
- if(rd) format_to_asset();
-
- if(wr)
- {
- asset_to_format();
- if (check_codec_params(asset))
- return 1;
- }
-
-// Set decoding parameter
- quicktime_set_parameter(fd, "divx_use_deblocking", &asset->divx_use_deblocking);
-// Set timecode offset
- quicktime_set_frame_start(fd, 0);
-
- return 0;
-}
-
-int FileMOV::close_file()
-{
-//printf("FileMOV::close_file 1 %s\n", asset->path);
- if(fd)
- {
- if(file->wr) quicktime_set_framerate(fd, asset->frame_rate);
- quicktime_close(fd);
- }
-
-//printf("FileMOV::close_file 1\n");
- if(threads)
- {
- for(int i = 0; i < file->cpus; i++)
- {
- threads[i]->stop_encoding();
- delete threads[i];
- }
- delete [] threads;
- threads = 0;
- }
-
-//printf("FileMOV::close_file 1\n");
- threadframes.remove_all_objects();
-
-
- if(temp_float)
- {
- for(int i = 0; i < asset->channels; i++)
- delete [] temp_float[i];
- delete [] temp_float;
- }
-
-//printf("FileMOV::close_file 1\n");
- reset_parameters();
- FileBase::close_file();
-//printf("FileMOV::close_file 2\n");
- return 0;
-}
-
-void FileMOV::set_frame_start(int64_t offset)
-{
- quicktime_set_frame_start(fd, offset);
-}
-
-void FileMOV::asset_to_format()
-{
- if(!fd) return;
-
- fix_codecs(asset);
-
-// Fix up the Quicktime file.
- quicktime_set_copyright(fd, _("Made with Cinelerra for Linux"));
- quicktime_set_info(fd, "Quicktime for Linux");
-
- if(asset->audio_data)
- {
- quicktime_atracks = quicktime_set_audio(fd,
- asset->channels,
- asset->sample_rate,
- asset->bits,
- asset->acodec);
- quicktime_set_parameter(fd, "vorbis_vbr", &asset->vorbis_vbr);
- quicktime_set_parameter(fd, "vorbis_min_bitrate", &asset->vorbis_min_bitrate);
- quicktime_set_parameter(fd, "vorbis_bitrate", &asset->vorbis_bitrate);
- quicktime_set_parameter(fd, "vorbis_max_bitrate", &asset->vorbis_max_bitrate);
- quicktime_set_parameter(fd, "mp3_bitrate", &asset->mp3_bitrate);
- quicktime_set_parameter(fd, "mp4a_bitrate", &asset->mp4a_bitrate);
- }
-
- if(asset->video_data)
- {
- char string[16];
-// Set up the alpha channel compressors
- if(!strcmp(asset->vcodec, MOV_RGBA))
- {
- strcpy(string, QUICKTIME_RAW);
- depth = 32;
- }
- else
- if(!strcmp(asset->vcodec, MOV_PNGA))
- {
- strcpy(string, QUICKTIME_PNG);
- depth = 32;
- }
- else
- if(!strcmp(asset->vcodec, QUICKTIME_YUVA4444))
- {
- strcpy(string, asset->vcodec);
- depth = 32;
- }
- else
- {
- strcpy(string, asset->vcodec);
- depth = 24;
- }
-
-
- quicktime_vtracks = quicktime_set_video(fd,
- asset->layers,
- asset->width,
- asset->height,
- asset->frame_rate,
- string);
-
-
-
- for(int i = 0; i < asset->layers; i++)
- quicktime_set_depth(fd, depth, i);
-
- quicktime_set_parameter(fd, "jpeg_quality", &asset->jpeg_quality);
-
-// set the compression parameters if there are any
- quicktime_set_parameter(fd, "divx_bitrate", &asset->divx_bitrate);
- quicktime_set_parameter(fd, "divx_rc_period", &asset->divx_rc_period);
- quicktime_set_parameter(fd, "divx_rc_reaction_ratio", &asset->divx_rc_reaction_ratio);
- quicktime_set_parameter(fd, "divx_rc_reaction_period", &asset->divx_rc_reaction_period);
- quicktime_set_parameter(fd, "divx_max_key_interval", &asset->divx_max_key_interval);
- quicktime_set_parameter(fd, "divx_max_quantizer", &asset->divx_max_quantizer);
- quicktime_set_parameter(fd, "divx_min_quantizer", &asset->divx_min_quantizer);
- quicktime_set_parameter(fd, "divx_quantizer", &asset->divx_quantizer);
- quicktime_set_parameter(fd, "divx_quality", &asset->divx_quality);
- quicktime_set_parameter(fd, "divx_fix_bitrate", &asset->divx_fix_bitrate);
-
-// printf("FileMOV::asset_to_format %d\n",
-// __LINE__);
-// asset->dump();
- quicktime_set_parameter(fd, "ffmpeg_bitrate", &asset->ms_bitrate);
- quicktime_set_parameter(fd, "ffmpeg_bitrate_tolerance", &asset->ms_bitrate_tolerance);
- quicktime_set_parameter(fd, "ffmpeg_interlaced", &asset->ms_interlaced);
- quicktime_set_parameter(fd, "ffmpeg_quantizer", &asset->ms_quantization);
- quicktime_set_parameter(fd, "ffmpeg_gop_size", &asset->ms_gop_size);
- quicktime_set_parameter(fd, "ffmpeg_fix_bitrate", &asset->ms_fix_bitrate);
-
- quicktime_set_parameter(fd, "h264_bitrate", &asset->h264_bitrate);
- quicktime_set_parameter(fd, "h264_quantizer", &asset->h264_quantizer);
- quicktime_set_parameter(fd, "h264_fix_bitrate", &asset->h264_fix_bitrate);
-
-
- }
-
- if(file->wr && asset->format == FILE_AVI)
- {
- quicktime_set_avi(fd, 1);
- }
-}
-
-
-void FileMOV::format_to_asset()
-{
- if(!fd) return;
-
- if(quicktime_is_avi(fd)) asset->format = FILE_AVI;
- asset->audio_data = quicktime_has_audio(fd);
- if(asset->audio_data)
- {
- asset->channels = 0;
- int qt_tracks = quicktime_audio_tracks(fd);
- for(int i = 0; i < qt_tracks; i++)
- asset->channels += quicktime_track_channels(fd, i);
-
- if(!asset->sample_rate)
- asset->sample_rate = quicktime_sample_rate(fd, 0);
- asset->bits = quicktime_audio_bits(fd, 0);
- asset->audio_length = quicktime_audio_length(fd, 0);
- strncpy(asset->acodec, quicktime_audio_compressor(fd, 0), 4);
- }
-
-// determine if the video can be read before declaring video data
- if(quicktime_has_video(fd) && quicktime_supported_video(fd, 0))
- asset->video_data = 1;
-
- if(asset->video_data)
- {
- depth = quicktime_video_depth(fd, 0);
- asset->layers = quicktime_video_tracks(fd);
- asset->width = quicktime_video_width(fd, 0);
- asset->height = quicktime_video_height(fd, 0);
- asset->video_length = quicktime_video_length(fd, 0);
-// Don't want a user configured frame rate to get destroyed
- if(EQUIV(asset->frame_rate, 0))
- asset->frame_rate = quicktime_frame_rate(fd, 0);
-
- strncpy(asset->vcodec, quicktime_video_compressor(fd, 0), 4);
-
- // If DV stream, get the timecode
- // This should become part of libquicktime functionality... for all formats
- if(match4(asset->vcodec, QUICKTIME_DV))
- {
- char tc[12];
- dv_decoder_t *tmp_decoder = dv_decoder_new(0,0,0);
- VFrame *frame = new VFrame(0, 0, BC_COMPRESSED);
- read_frame(frame);
- set_video_position(0);
- if(dv_parse_header(tmp_decoder, frame->get_data()) > -1)
- {
- dv_parse_packs(tmp_decoder, frame->get_data());
- dv_get_timestamp(tmp_decoder, tc);
-// printf("Timestamp %s\n", tc);
- }
- delete frame;
- dv_decoder_free(tmp_decoder);
- }
- }
-}
-
-
-int64_t FileMOV::get_memory_usage()
-{
- if(file->rd && fd)
- {
- int64_t result = quicktime_memory_usage(fd);
-//printf("FileMOV::get_memory_usage 1 %d\n", result);
- return result;
- }
- return 0;
-}
-
-
-int FileMOV::colormodel_supported(int colormodel)
-{
- return colormodel;
-}
-
-int FileMOV::get_best_colormodel(Asset *asset, int driver)
-{
- switch(driver)
- {
- case PLAYBACK_X11:
- return BC_RGB888;
- break;
- case PLAYBACK_X11_XV:
- case PLAYBACK_ASYNCHRONOUS:
- if(match4(asset->vcodec, QUICKTIME_YUV420)) return BC_YUV420P;
- if(match4(asset->vcodec, QUICKTIME_YUV422)) return BC_YUV422;
- if(match4(asset->vcodec, QUICKTIME_2VUY)) return BC_YUV422;
- if(match4(asset->vcodec, QUICKTIME_JPEG)) return BC_YUV420P;
- if(match4(asset->vcodec, QUICKTIME_MJPA)) return BC_YUV422P;
- if(match4(asset->vcodec, QUICKTIME_MJPG)) return BC_YUV422P;
- if(match4(asset->vcodec, QUICKTIME_DV)) return BC_YUV422;
- if(match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV422;
- if(match4(asset->vcodec, QUICKTIME_HV60)) return BC_YUV420P;
- if(match4(asset->vcodec, QUICKTIME_DIVX)) return BC_YUV420P;
- if(match4(asset->vcodec, QUICKTIME_DVCP)) return BC_YUV422;
- if(match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV422;
- if(match4(asset->vcodec, QUICKTIME_MP4V)) return BC_YUV420P;
- if(match4(asset->vcodec, QUICKTIME_H263)) return BC_YUV420P;
- if(match4(asset->vcodec, QUICKTIME_H264)) return BC_YUV420P;
- if(match4(asset->vcodec, QUICKTIME_HV64)) return BC_YUV420P;
- if(match4(asset->vcodec, QUICKTIME_DIV3) ||
- match4(asset->vcodec, QUICKTIME_SVQ3)) return BC_YUV420P;
- break;
- case PLAYBACK_X11_GL:
- if(match4(asset->vcodec, QUICKTIME_YUV420) ||
- match4(asset->vcodec, QUICKTIME_YUV422) ||
- match4(asset->vcodec, QUICKTIME_2VUY) ||
- match4(asset->vcodec, QUICKTIME_JPEG) ||
- match4(asset->vcodec, QUICKTIME_MJPA) ||
- match4(asset->vcodec, QUICKTIME_MJPG) ||
- match4(asset->vcodec, QUICKTIME_DV) ||
- match4(asset->vcodec, QUICKTIME_DVCP) ||
- match4(asset->vcodec, QUICKTIME_DVSD) ||
- match4(asset->vcodec, QUICKTIME_HV60) ||
- match4(asset->vcodec, QUICKTIME_DIVX) ||
- match4(asset->vcodec, QUICKTIME_DVSD) ||
- match4(asset->vcodec, QUICKTIME_MP4V) ||
- match4(asset->vcodec, QUICKTIME_H263) ||
- match4(asset->vcodec, QUICKTIME_H264) ||
- match4(asset->vcodec, QUICKTIME_HV64) ||
- match4(asset->vcodec, QUICKTIME_DIV3) ||
- match4(asset->vcodec, QUICKTIME_DVSD)) return BC_YUV888;
- break;
- case PLAYBACK_DV1394:
- case PLAYBACK_FIREWIRE:
- if(match4(asset->vcodec, QUICKTIME_DV) ||
- match4(asset->vcodec, QUICKTIME_DVSD) ||
- match4(asset->vcodec, QUICKTIME_DVCP)) return BC_COMPRESSED;
- return BC_YUV422P;
- break;
- case PLAYBACK_LML:
- case PLAYBACK_BUZ:
- if(match4(asset->vcodec, QUICKTIME_MJPA))
- return BC_COMPRESSED;
- else
- return BC_YUV422P;
- break;
- case VIDEO4LINUX:
- case VIDEO4LINUX2:
- if(!strncasecmp(asset->vcodec, QUICKTIME_YUV420, 4)) return BC_YUV422;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_YUV422, 4)) return BC_YUV422;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_YUV411, 4)) return BC_YUV411P;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_JPEG, 4)) return BC_YUV420P;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_MJPA, 4)) return BC_YUV422P;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_HV60, 4)) return BC_YUV420P;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_DIVX, 4)) return BC_YUV420P;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_H263, 4)) return BC_YUV420P;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_DIV3, 4)) return BC_YUV420P;
- else
- if(!strncasecmp(asset->vcodec, QUICKTIME_MP4V, 4)) return BC_YUV422P;
- break;
-
- case CAPTURE_BUZ:
- case CAPTURE_LML:
- case VIDEO4LINUX2JPEG:
- if(!strncasecmp(asset->vcodec, QUICKTIME_MJPA, 4))
- return BC_COMPRESSED;
- else
- return BC_YUV422;
- break;
-
- case CAPTURE_JPEG_WEBCAM:
- return BC_COMPRESSED;
- break;
-
- case CAPTURE_YUYV_WEBCAM:
- return BC_YUV422;
- break;
-
- case CAPTURE_FIREWIRE:
- case CAPTURE_IEC61883:
- if(!strncasecmp(asset->vcodec, QUICKTIME_DV, 4) ||
- !strncasecmp(asset->vcodec, QUICKTIME_DVSD, 4) ||
- !strncasecmp(asset->vcodec, QUICKTIME_DVCP, 4))
- return BC_COMPRESSED;
- else
- return BC_YUV422;
- break;
- case CAPTURE_DVB:
- case VIDEO4LINUX2MPEG:
- return BC_YUV422P;
- break;
- }
- return BC_RGB888;
-}
-
-int FileMOV::can_copy_from(Edit *edit, int64_t position)
-{
- if(!fd) return 0;
- Indexable *source = edit->get_source();
- if( !source->is_asset ) return 0;
- Asset *asset = (Asset *)source;
-
-//printf("FileMOV::can_copy_from 1 %d %s %s\n", asset->format, asset->vcodec, this->asset->vcodec);
- if(asset->format == FILE_JPEG_LIST &&
- match4(this->asset->vcodec, QUICKTIME_JPEG))
- return 1;
- else
- if((asset->format == FILE_MOV ||
- asset->format == FILE_AVI))
- {
-//printf("FileMOV::can_copy_from %s %s\n", asset->vcodec, this->asset->vcodec);
- if(match4(asset->vcodec, this->asset->vcodec))
- return 1;
-// there are combinations where the same codec has multiple fourcc codes
-// check for DV...
- int is_edit_dv = 0;
- int is_this_dv = 0;
- if (match4(asset->vcodec, QUICKTIME_DV) ||
- match4(asset->vcodec, QUICKTIME_DVSD) ||
- match4(asset->vcodec, QUICKTIME_DVCP))
- is_edit_dv = 1;
- if (match4(this->asset->vcodec, QUICKTIME_DV) ||
- match4(this->asset->vcodec, QUICKTIME_DVSD) ||
- match4(this->asset->vcodec, QUICKTIME_DVCP))
- is_this_dv = 1;
- if (is_this_dv && is_edit_dv)
- return 1;
- }
- else
- if(edit->asset->format == FILE_RAWDV)
- {
- if(match4(this->asset->vcodec, QUICKTIME_DV) ||
- match4(this->asset->vcodec, QUICKTIME_DVSD) ||
- match4(this->asset->vcodec, QUICKTIME_DVCP))
- return 1;
- }
-
- return 0;
-}
-
-
-int64_t FileMOV::get_audio_length()
-{
- if(!fd) return 0;
- int64_t result = quicktime_audio_length(fd, 0) + samples_correction;
-
- return result;
-}
-
-int FileMOV::set_audio_position(int64_t x)
-{
- if(!fd) return 1;
-// quicktime sets positions for each track seperately so store position in audio_position
- if(x >= 0 && x < asset->audio_length)
- return quicktime_set_audio_position(fd, x, 0);
- else
- return 1;
-}
-
-int FileMOV::set_video_position(int64_t x)
-{
- if(!fd) return 1;
- if(x >= 0 && x < asset->video_length)
- {
- int result = quicktime_set_video_position(fd, x, file->current_layer);
- return result;
- }else
- return 1;
-}
-
-
-void FileMOV::new_audio_temp(int64_t len)
-{
- if(temp_allocated && temp_allocated < len)
- {
- for(int i = 0; i < asset->channels; i++)
- delete [] temp_float[i];
- delete [] temp_float;
- temp_allocated = 0;
- }
-
- if(!temp_allocated)
- {
- temp_allocated = len;
- temp_float = new float*[asset->channels];
- for(int i = 0; i < asset->channels; i++)
- temp_float[i] = new float[len];
- }
-}
-
-
-
-int FileMOV::write_samples(double **buffer, int64_t len)
-{
- int i, j;
- int result = 0;
- int chunk_size;
-
- if(!fd) return 0;
-
- if(quicktime_supported_audio(fd, 0))
- {
-// Use Quicktime's compressor. (Always used)
-// Allocate temp buffer
- new_audio_temp(len);
-
-// Copy to float buffer
- for(i = 0; i < asset->channels; i++)
- {
- for(j = 0; j < len; j++)
- {
- temp_float[i][j] = buffer[i][j];
- }
- }
-
-// Because of the way Quicktime's compressors work we want to limit the chunk
-// size to speed up decompression.
- float **channel_ptr;
- channel_ptr = new float*[asset->channels];
-
- for(j = 0; j < len && !result; )
- {
- chunk_size = asset->sample_rate;
- if(j + chunk_size > len) chunk_size = len - j;
-
- for(i = 0; i < asset->channels; i++)
- {
- channel_ptr[i] = &temp_float[i][j];
- }
-
- result = quicktime_encode_audio(fd, 0, channel_ptr, chunk_size);
- j += asset->sample_rate;
- }
-
- delete [] channel_ptr;
- }
- return result;
-}
-
-int FileMOV::write_frames(VFrame ***frames, int len)
-{
- int i, j, result = 0;
- int default_compressor = 1;
- const int debug = 0;
-if(debug) printf("FileMOV::write_frames %d\n", __LINE__);
- if(!fd) return 0;
-if(debug) printf("FileMOV::write_frames %d layers=%d\n", __LINE__, asset->layers);
-
- for(i = 0; i < asset->layers && !result; i++)
- {
-
-
-if(debug) printf("FileMOV::write_frames %d colormodel=%d size=" _LD "\n",
- __LINE__, frames[i][0]->get_color_model(), frames[i][0]->get_compressed_size());
-
-
-
-// Fix direct copy cases for format conversions.
- if(frames[i][0]->get_color_model() == BC_COMPRESSED)
- {
-if(debug) printf("FileMOV::write_frames %d len=%d\n", __LINE__, len);
- default_compressor = 0;
- for(j = 0; j < len && !result; j++)
- {
- VFrame *frame = frames[i][j];
-
-
-if(debug) printf("FileMOV::write_frames %d %d colormodel=%d size=%d %02x %02x %02x %02x %02x %02x %02x %02x\n",
-__LINE__,
-frame->get_shmid(),
-(int)frame->get_color_model(),
-(int)frame->get_compressed_size(),
-frames[i][j]->get_data()[0],
-frames[i][j]->get_data()[1],
-frames[i][j]->get_data()[2],
-frames[i][j]->get_data()[3],
-frames[i][j]->get_data()[4],
-frames[i][j]->get_data()[5],
-frames[i][j]->get_data()[6],
-frames[i][j]->get_data()[7]);
-
-// Special handling for DIVX
-// Determine keyframe status.
-// Write VOL header in the first frame if none exists
- if(!strcmp(asset->vcodec, QUICKTIME_DIVX) ||
- !strcmp(asset->vcodec, QUICKTIME_H263) ||
- !strcmp(asset->vcodec, QUICKTIME_HV60))
- {
- if(quicktime_mpeg4_is_key(frame->get_data(),
- frame->get_compressed_size(),
- asset->vcodec))
- quicktime_insert_keyframe(fd, file->current_frame + j, i);
-
-
-// Write header
- if(!(file->current_frame + j) &&
- !quicktime_mpeg4_has_vol(frame->get_data()))
- {
- VFrame *temp_frame = new VFrame;
-
- temp_frame->allocate_compressed_data(frame->get_compressed_size() +
- 0xff);
- int bytes = quicktime_mpeg4_write_vol(temp_frame->get_data(),
- asset->width,
- asset->height,
- 60000,
- asset->frame_rate);
- memcpy(temp_frame->get_data() + bytes,
- frame->get_data(),
- frame->get_compressed_size());
- temp_frame->set_compressed_size(frame->get_compressed_size() + bytes);
-
- result = quicktime_write_frame(fd,
- temp_frame->get_data(),
- temp_frame->get_compressed_size(),
- i);
-
- delete temp_frame;
-
-
- }
- else
- {
- result = quicktime_write_frame(fd,
- frame->get_data(),
- frame->get_compressed_size(),
- i);
- }
- }
- else
-// Determine keyframe status
- if(!strcmp(asset->vcodec, QUICKTIME_H264) ||
- !strcmp(asset->vcodec, QUICKTIME_HV64) ||
- !strcmp(asset->vcodec, QUICKTIME_MP4V))
- {
- if(frame->get_keyframe() || file->current_frame + j == 0)
- quicktime_insert_keyframe(fd, file->current_frame + j, i);
-
-// Write frame
-if(debug) printf("FileMOV::write_frames %d result=%d data=%p size=%ld\n",
-__LINE__,
-result,
-frame->get_data(),
-frame->get_compressed_size());
- result = quicktime_write_frame(fd,
- frame->get_data(),
- frame->get_compressed_size(),
- i);
-
-if(debug) printf("FileMOV::write_frames %d result=%d\n", __LINE__, result);
- }
- else
- if(!strcmp(asset->vcodec, QUICKTIME_DIV3))
- {
- if(quicktime_mpeg4_is_key(frame->get_data(),
- frame->get_compressed_size(),
- asset->vcodec))
- quicktime_insert_keyframe(fd, file->current_frame + j, i);
- result = quicktime_write_frame(fd,
- frame->get_data(),
- frame->get_compressed_size(),
- i);
- }
- else
- if(!strcmp(asset->vcodec, QUICKTIME_MJPA))
- {
- long field2_offset;
-
-// Create extra space for markers
- if(frame->get_compressed_allocated() - frame->get_compressed_size() < 0x100)
- frame->allocate_compressed_data(frame->get_compressed_size() + 0x100);
-
- unsigned char *data = frame->get_data();
- long data_size = frame->get_compressed_size();
- long data_allocated = frame->get_compressed_allocated();
-
-// Sometimes get 0 length frames
- if(data_size)
- {
- if(asset->format == FILE_MOV)
- {
- mjpeg_insert_quicktime_markers(&data,
- &data_size,
- &data_allocated,
- 2,
- &field2_offset);
- }
- else
- {
- mjpeg_insert_avi_markers(&data,
- &data_size,
- &data_allocated,
- 2,
- &field2_offset);
- }
- frame->set_compressed_size(data_size);
- result = quicktime_write_frame(fd,
- frame->get_data(),
- frame->get_compressed_size(),
- i);
- }
- else
- printf("FileMOV::write_frames data_size=%ld\n", data_size);
- }
- else
- result = quicktime_write_frame(fd,
- frame->get_data(),
- frame->get_compressed_size(),
- i);
- }
-if(debug) printf("FileMOV::write_frames %d result=%d\n", __LINE__, result);
- }
- else
- if(match4(asset->vcodec, QUICKTIME_YUV420) ||
- match4(asset->vcodec, QUICKTIME_2VUY) ||
- match4(asset->vcodec, QUICKTIME_YUV422) ||
- match4(asset->vcodec, QUICKTIME_RAW))
- {
-// Direct copy planes where possible
- default_compressor = 0;
- for(j = 0; j < len && !result; j++)
- {
- VFrame *frame = frames[i][j];
-//printf("FileMOV::write_frames 1 %d\n", frame->get_color_model());
- quicktime_set_cmodel(fd, frame->get_color_model());
- if(cmodel_is_planar(frame->get_color_model()))
- {
- unsigned char *planes[3];
- planes[0] = frame->get_y();
- planes[1] = frame->get_u();
- planes[2] = frame->get_v();
- result = quicktime_encode_video(fd, planes, i);
- }
- else
- {
- result = quicktime_encode_video(fd, frame->get_rows(), i);
-//printf("FileMOV::write_frames 2 %d\n", result);
- }
-//printf("FileMOV::write_frames 2\n");
- }
- }
- else
- if(file->cpus > 1 &&
- (match4(asset->vcodec, QUICKTIME_JPEG) ||
- match4(asset->vcodec, QUICKTIME_MJPA)))
- {
- default_compressor = 0;
-// Compress symmetrically on an SMP system.
- ThreadStruct *threadframe;
- int fields = match4(asset->vcodec, QUICKTIME_MJPA) ? 2 : 1;
-
-// Set up threads for symmetric compression.
- if(!threads)
- {
- threads = new FileMOVThread*[file->cpus];
- for(j = 0; j < file->cpus; j++)
- {
- threads[j] = new FileMOVThread(this, fields);
- threads[j]->start_encoding();
- }
- }
-
-// Set up the frame structures for asynchronous compression.
-// The mjpeg object must exist in each threadframe because it is where the output
-// is stored.
- while(threadframes.total < len)
- {
- threadframes.append(threadframe = new ThreadStruct);
- }
-
-// Load thread frame structures with new frames.
- for(j = 0; j < len; j++)
- {
- VFrame *frame = frames[i][j];
- threadframes.values[j]->input = frame;
- threadframes.values[j]->completion_lock->lock("FileMOV::write_frames 1");
- }
- total_threadframes = len;
- current_threadframe = 0;
-
-// Start the threads compressing
- for(j = 0; j < file->cpus; j++)
- {
- threads[j]->encode_buffer();
- }
-
-
-// Write the frames as they're finished
- for(j = 0; j < len; j++)
- {
- threadframes.values[j]->completion_lock->lock("FileMOV::write_frames 1");
- threadframes.values[j]->completion_lock->unlock();
- if(!result)
- {
- result = quicktime_write_frame(fd,
- threadframes.values[j]->output,
- threadframes.values[j]->output_size,
- i);
- }
- }
- }
-
- if(default_compressor)
- {
-//printf("FileMOV::write_frames 3\n");
-// Use the library's built in compressor.
- for(j = 0; j < len && !result; j++)
- {
-//printf("FileMOV::write_frames 4\n");
- VFrame *frame = frames[i][j];
- quicktime_set_cmodel(fd, frame->get_color_model());
-//printf("FileMOV::write_frames 5\n");
- if(cmodel_is_planar(frame->get_color_model()))
- {
- unsigned char *planes[3];
- planes[0] = frame->get_y();
- planes[1] = frame->get_u();
- planes[2] = frame->get_v();
- result = quicktime_encode_video(fd, planes, i);
- }
- else
- {
-if(debug) printf("FileMOV::write_frames 1\n");
- result = quicktime_encode_video(fd, frame->get_rows(), i);
-if(debug) printf("FileMOV::write_frames 10\n");
- }
- }
- }
-//printf("FileMOV::write_frames 4\n");
- }
-
-
- return result;
-}
-
-
-
-int FileMOV::read_frame(VFrame *frame)
-{
- if(!fd) return 1;
- int result = 0;
- const int debug = 0;
-
-if(debug) printf("FileMOV::read_frame %d frame=" _LD " color_model=%d\n",
- __LINE__, file->current_frame, frame->get_color_model());
- switch(frame->get_color_model())
- {
- case BC_COMPRESSED:
- frame->allocate_compressed_data(quicktime_frame_size(fd, file->current_frame, file->current_layer));
- frame->set_compressed_size(quicktime_frame_size(fd, file->current_frame, file->current_layer));
- frame->set_keyframe((quicktime_get_keyframe_before(fd,
- file->current_frame,
- file->current_layer) == file->current_frame));
-// printf("FileMOV::read_frame 1 " _LD " %d %p %d\n",
-// file->current_frame,
-// frame->get_keyframe(),
-// frame->get_data(),
-// frame->get_compressed_size());
- result = quicktime_read_frame(fd,
- frame->get_data(),
- file->current_layer);
- break;
-
-// Progressive
- case BC_YUV420P:
- case BC_YUV422P:
- {
- unsigned char *row_pointers[3];
- row_pointers[0] = frame->get_y();
- row_pointers[1] = frame->get_u();
- row_pointers[2] = frame->get_v();
-
- quicktime_set_cmodel(fd, frame->get_color_model());
- result = quicktime_decode_video(fd,
- row_pointers,
- file->current_layer);
- }
- break;
-
-// Packed
- default:
- quicktime_set_cmodel(fd, frame->get_color_model());
- result = quicktime_decode_video(fd,
- frame->get_rows(),
- file->current_layer);
- break;
- }
-
-
-if(debug) printf("FileMOV::read_frame %d\n", __LINE__);
- if (result)
- printf("quicktime_read_frame/quicktime_decode_video failed, result:\n");
-
- return result;
-}
-
-
-
-int64_t FileMOV::compressed_frame_size()
-{
- if(!fd) return 0;
- return quicktime_frame_size(fd, file->current_frame, file->current_layer);
-}
-
-int FileMOV::read_compressed_frame(VFrame *buffer)
-{
- int64_t result;
- if(!fd) return 0;
-
- result = quicktime_read_frame(fd, buffer->get_data(), file->current_layer);
- buffer->set_compressed_size(result);
- buffer->set_keyframe((quicktime_get_keyframe_before(fd,
- file->current_frame,
- file->current_layer) == file->current_frame));
- result = !result;
- return result;
-}
-
-int FileMOV::write_compressed_frame(VFrame *buffer)
-{
- int result = 0;
- if(!fd) return 0;
-
- result = quicktime_write_frame(fd,
- buffer->get_data(),
- buffer->get_compressed_size(),
- file->current_layer);
- return result;
-}
-
-
-
-int FileMOV::read_raw(VFrame *frame,
- float in_x1, float in_y1, float in_x2, float in_y2,
- float out_x1, float out_y1, float out_x2, float out_y2,
- int use_float, int interpolate)
-{
- int64_t result = 1;
- if(!fd) return 1;
-
- quicktime_set_video_position(fd, file->current_frame, file->current_layer);
-// Develop importing strategy
- switch(frame->get_color_model())
- {
- case BC_RGB888:
- result = quicktime_decode_video(fd, frame->get_rows(), file->current_layer);
- break;
- case BC_RGBA8888:
- case BC_RGB161616:
- case BC_RGBA16161616:
- case BC_YUV888:
- case BC_YUVA8888:
- case BC_YUV161616:
- case BC_YUVA16161616:
- case BC_YUV420P:
- eprintf("FileMOV::read_raw: unknown colormodel\n");
- break;
- }
- return result;
-}
-
-// Overlay samples
-int FileMOV::read_samples(double *buffer, int64_t len)
-{
- if(!fd) return 1;
-
- if(quicktime_track_channels(fd, 0) > file->current_channel &&
- quicktime_supported_audio(fd, 0))
- {
-
-//printf("FileMOV::read_samples 2 " _LD " " _LD "\n", file->current_sample, quicktime_audio_position(fd, 0));
- new_audio_temp(len);
-
-//printf("FileMOV::read_samples 3 " _LD " " _LD "\n", file->current_sample, quicktime_audio_position(fd, 0));
- if(quicktime_decode_audio(fd, 0, temp_float[0], len, file->current_channel))
- {
- printf(_("quicktime_decode_audio failed\n"));
- return 1;
- }
- else
- {
- for(int i = 0; i < len; i++) buffer[i] = temp_float[0][i];
- }
-
-// if(file->current_channel == 0)
-// for(int i = 0; i < len; i++)
-// {
-// int16_t value;
-// value = (int16_t)(temp_float[0][i] * 32767);
-// fwrite(&value, 2, 1, stdout);
-// }
-//printf("FileMOV::read_samples 4 " _LD " " _LD "\n", file->current_sample, quicktime_audio_position(fd, 0));
- }
-
- return 0;
-}
-
-
-const char* FileMOV::strtocompression(const char *string)
-{
- if(!strcasecmp(string, _(DIVX_NAME))) return QUICKTIME_DIVX;
- if(!strcasecmp(string, _(H264_NAME))) return QUICKTIME_H264;
- if(!strcasecmp(string, _(HV64_NAME))) return QUICKTIME_HV64;
- if(!strcasecmp(string, _(MP4V_NAME))) return QUICKTIME_MP4V;
- if(!strcasecmp(string, _(H263_NAME))) return QUICKTIME_H263;
- if(!strcasecmp(string, _(HV60_NAME))) return QUICKTIME_HV60;
- if(!strcasecmp(string, _(DIV3_NAME))) return QUICKTIME_DIV3;
-// Students say QUICKTIME_DV is required for compression even though
-// QUICKTIME_DVSD is produced by other software
-// if(!strcasecmp(string, _(DV_NAME))) return QUICKTIME_DVSD;
- if(!strcasecmp(string, _(DV_NAME))) return QUICKTIME_DV;
- if(!strcasecmp(string, _(PNG_NAME))) return QUICKTIME_PNG;
- if(!strcasecmp(string, _(PNGA_NAME))) return MOV_PNGA;
- if(!strcasecmp(string, _(RGB_NAME))) return QUICKTIME_RAW;
- if(!strcasecmp(string, _(RGBA_NAME))) return MOV_RGBA;
- if(!strcasecmp(string, _(QTJPEG_NAME))) return QUICKTIME_JPEG;
- if(!strcasecmp(string, _(QTMJPEGP_NAME))) return QUICKTIME_MJPG;
- if(!strcasecmp(string, _(MJPA_NAME))) return QUICKTIME_MJPA;
- if(!strcasecmp(string, _(YUV420_NAME))) return QUICKTIME_YUV420;
- if(!strcasecmp(string, _(YUV411_NAME))) return QUICKTIME_YUV411;
- if(!strcasecmp(string, _(YUV422_NAME))) return QUICKTIME_YUV422;
- if(!strcasecmp(string, _(TWOVUY_NAME))) return QUICKTIME_2VUY;
- if(!strcasecmp(string, _(YUV444_NAME))) return QUICKTIME_YUV444;
- if(!strcasecmp(string, _(YUVA4444_NAME))) return QUICKTIME_YUVA4444;
- if(!strcasecmp(string, _(YUV444_10BIT_NAME))) return QUICKTIME_YUV444_10bit;
-
- if(!strcasecmp(string, _(TWOS_NAME))) return QUICKTIME_TWOS;
- if(!strcasecmp(string, _(RAW_NAME))) return QUICKTIME_RAW;
- if(!strcasecmp(string, _(IMA4_NAME))) return QUICKTIME_IMA4;
- if(!strcasecmp(string, _(ULAW_NAME))) return QUICKTIME_ULAW;
- if(!strcasecmp(string, _(MP3_NAME))) return QUICKTIME_MP3;
- if(!strcasecmp(string, _(MP4A_NAME))) return QUICKTIME_MP4A;
- if(!strcasecmp(string, _(VORBIS_NAME))) return QUICKTIME_VORBIS;
-
-
-
- return QUICKTIME_RAW;
-}
-
-const char* FileMOV::compressiontostr(const char *string)
-{
- if(match4(string, QUICKTIME_H263)) return _(H263_NAME);
- if(match4(string, QUICKTIME_H264)) return _(H264_NAME);
- if(match4(string, QUICKTIME_HV64)) return _(HV64_NAME);
- if(match4(string, QUICKTIME_DIVX)) return _(DIVX_NAME);
- if(match4(string, QUICKTIME_MP4V)) return _(MP4V_NAME);
- if(match4(string, QUICKTIME_HV60)) return _(HV60_NAME);
- if(match4(string, QUICKTIME_DIV3)) return _(DIV3_NAME);
- if(match4(string, QUICKTIME_DV)) return _(DV_NAME);
- if(match4(string, QUICKTIME_DVCP)) return _(DV_NAME);
- if(match4(string, QUICKTIME_DVSD)) return _(DV_NAME);
- if(match4(string, MOV_PNGA)) return _(PNGA_NAME);
- if(match4(string, QUICKTIME_RAW)) return _(RGB_NAME);
- if(match4(string, MOV_RGBA)) return _(RGBA_NAME);
- if(match4(string, QUICKTIME_JPEG)) return _(QTJPEG_NAME);
- if(match4(string, QUICKTIME_MJPG)) return _(QTMJPEGP_NAME);
- if(match4(string, QUICKTIME_MJPA)) return _(MJPA_NAME);
- if(match4(string, QUICKTIME_YUV420)) return _(YUV420_NAME);
- if(match4(string, QUICKTIME_YUV411)) return _(YUV411_NAME);
- if(match4(string, QUICKTIME_YUV422)) return _(YUV422_NAME);
- if(match4(string, QUICKTIME_2VUY)) return _(TWOVUY_NAME);
- if(match4(string, QUICKTIME_YUV444)) return _(YUV444_NAME);
- if(match4(string, QUICKTIME_YUVA4444)) return _(YUVA4444_NAME);
- if(match4(string, QUICKTIME_YUV444_10bit)) return _(YUV444_10BIT_NAME);
-
-
-
-
-
- if(match4(string, QUICKTIME_TWOS)) return _(TWOS_NAME);
- if(match4(string, QUICKTIME_RAW)) return _(RAW_NAME);
- if(match4(string, QUICKTIME_IMA4)) return _(IMA4_NAME);
- if(match4(string, QUICKTIME_ULAW)) return _(ULAW_NAME);
- if(match4(string, QUICKTIME_MP3)) return _(MP3_NAME);
- if(match4(string, QUICKTIME_MP4A)) return _(MP4A_NAME);
- if(match4(string, QUICKTIME_VORBIS)) return _(VORBIS_NAME);
-
-
-
- return _("Unknown");
-}
-
-
-
-
-
-ThreadStruct::ThreadStruct()
-{
- input = 0;
- output = 0;
- output_allocated = 0;
- output_size = 0;
- completion_lock = new Condition(1, "ThreadStruct::completion_lock");
-}
-
-ThreadStruct::~ThreadStruct()
-{
- if(output) delete [] output;
- delete completion_lock;
-}
-
-void ThreadStruct::load_output(mjpeg_t *mjpeg)
-{
- if(output_allocated < mjpeg_output_size(mjpeg))
- {
- delete [] output;
- output = 0;
- }
- if(!output)
- {
- output_allocated = mjpeg_output_size(mjpeg);
- output = new unsigned char[output_allocated];
- }
-
- output_size = mjpeg_output_size(mjpeg);
- memcpy(output, mjpeg_output_buffer(mjpeg), output_size);
-}
-
-
-FileMOVThread::FileMOVThread(FileMOV *filemov, int fields)
- : Thread(1, 0, 0)
-{
- this->filemov = filemov;
- this->fields = fields;
- mjpeg = 0;
- input_lock = new Condition(1, "FileMOVThread::input_lock");
-}
-
-FileMOVThread::~FileMOVThread()
-{
- delete input_lock;
-}
-
-int FileMOVThread::start_encoding()
-{
- mjpeg = mjpeg_new(filemov->asset->width,
- filemov->asset->height,
- fields);
- mjpeg_set_quality(mjpeg, filemov->asset->jpeg_quality);
- mjpeg_set_float(mjpeg, 0);
- done = 0;
- set_synchronous(1);
- input_lock->lock("FileMOVThread::start_encoding");
- start();
- return 0;
-}
-
-int FileMOVThread::stop_encoding()
-{
- done = 1;
- input_lock->unlock();
- join();
- if(mjpeg) mjpeg_delete(mjpeg);
- return 0;
-}
-
-int FileMOVThread::encode_buffer()
-{
- input_lock->unlock();
- return 0;
-}
-
-void FileMOVThread::run()
-{
- while(!done)
- {
- input_lock->lock("FileMOVThread::run");
-
- if(!done)
- {
-// Get a frame to compress.
- filemov->threadframe_lock->lock("FileMOVThread::stop_encoding");
- if(filemov->current_threadframe < filemov->total_threadframes)
- {
-// Frame is available to process.
- input_lock->unlock();
- threadframe = filemov->threadframes.values[filemov->current_threadframe];
- VFrame *frame = threadframe->input;
-
- filemov->current_threadframe++;
- filemov->threadframe_lock->unlock();
-
- mjpeg_compress(mjpeg,
- frame->get_rows(),
- frame->get_y(),
- frame->get_u(),
- frame->get_v(),
- frame->get_color_model(),
- 1);
-
- if(fields > 1)
- {
- unsigned char *data = mjpeg_output_buffer(mjpeg);
- long data_size = mjpeg_output_size(mjpeg);
- long data_allocated = mjpeg_output_allocated(mjpeg);
- long field2_offset;
-
- if(filemov->asset->format == FILE_MOV)
- {
- mjpeg_insert_quicktime_markers(&data,
- &data_size,
- &data_allocated,
- 2,
- &field2_offset);
- }
- else
- {
- mjpeg_insert_avi_markers(&data,
- &data_size,
- &data_allocated,
- 2,
- &field2_offset);
- }
- mjpeg_set_output_size(mjpeg, data_size);
- }
- threadframe->load_output(mjpeg);
- threadframe->completion_lock->unlock();
- }
- else
- filemov->threadframe_lock->unlock();
- }
- }
-}
-
-
-
-
-
-
-MOVConfigAudio::MOVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
- : BC_Window(_(PROGRAM_NAME ": Audio Compression"),
- parent_window->get_abs_cursor_x(1),
- parent_window->get_abs_cursor_y(1),
- 350,
- 250)
-{
- this->parent_window = parent_window;
- this->asset = asset;
- compression_popup = 0;
- reset();
-}
-
-MOVConfigAudio::~MOVConfigAudio()
-{
- lock_window("MOVConfigAudio::~MOVConfigAudio");
- if(compression_popup) delete compression_popup;
- if(bits_popup) delete bits_popup;
- compression_items.remove_all_objects();
- unlock_window();
-}
-
-
-void MOVConfigAudio::reset()
-{
- bits_popup = 0;
- bits_title = 0;
- dither = 0;
- vorbis_min_bitrate = 0;
- vorbis_bitrate = 0;
- vorbis_max_bitrate = 0;
- vorbis_vbr = 0;
- mp3_bitrate = 0;
- mp4a_bitrate = 0;
- mp4a_quantqual = 0;
-}
-
-void MOVConfigAudio::create_objects()
-{
- int x = 10, y = 10;
- lock_window("MOVConfigAudio::create_objects");
-
- if(asset->format == FILE_MOV)
- {
- compression_items.append(new BC_ListBoxItem(_(TWOS_NAME)));
- compression_items.append(new BC_ListBoxItem(_(RAW_NAME)));
- compression_items.append(new BC_ListBoxItem(_(IMA4_NAME)));
- compression_items.append(new BC_ListBoxItem(_(MP3_NAME)));
- compression_items.append(new BC_ListBoxItem(_(ULAW_NAME)));
- compression_items.append(new BC_ListBoxItem(_(VORBIS_NAME)));
- compression_items.append(new BC_ListBoxItem(_(MP4A_NAME)));
- }
- else
- {
- compression_items.append(new BC_ListBoxItem(_(TWOS_NAME)));
- compression_items.append(new BC_ListBoxItem(_(MP3_NAME)));
- compression_items.append(new BC_ListBoxItem(_(VORBIS_NAME)));
- compression_items.append(new BC_ListBoxItem(_(MP4A_NAME)));
- }
-
- add_tool(new BC_Title(x, y, _("Compression:")));
- y += 25;
- compression_popup = new MOVConfigAudioPopup(this, x, y);
- compression_popup->create_objects();
-
- update_parameters();
-
- add_subwindow(new BC_OKButton(this));
- show_window(1);
- unlock_window();
-}
-
-void MOVConfigAudio::update_parameters()
-{
- int x = 10, y = 70;
- if(bits_title) delete bits_title;
- if(bits_popup) delete bits_popup;
- if(dither) delete dither;
- if(vorbis_min_bitrate) delete vorbis_min_bitrate;
- if(vorbis_bitrate) delete vorbis_bitrate;
- if(vorbis_max_bitrate) delete vorbis_max_bitrate;
- if(vorbis_vbr) delete vorbis_vbr;
- if(mp3_bitrate) delete mp3_bitrate;
- delete mp4a_bitrate;
- delete mp4a_quantqual;
-
- reset();
-
-
-
- if(!strcasecmp(asset->acodec, QUICKTIME_TWOS) ||
- !strcasecmp(asset->acodec, QUICKTIME_RAW))
- {
- add_subwindow(bits_title = new BC_Title(x, y, _("Bits per channel:")));
- bits_popup = new BitsPopup(this,
- x + 150,
- y,
- &asset->bits,
- 0,
- 0,
- 0,
- 0,
- 0);
- bits_popup->create_objects();
- y += 40;
- add_subwindow(dither = new BC_CheckBox(x, y, &asset->dither, _("Dither")));
- }
- else
- if(!strcasecmp(asset->acodec, QUICKTIME_IMA4))
- {
- }
- else
- if(!strcasecmp(asset->acodec, QUICKTIME_MP3))
- {
- mp3_bitrate = new MOVConfigAudioNum(this,
- _("Bitrate:"),
- x,
- y,
- &asset->mp3_bitrate);
- mp3_bitrate->set_increment(64000);
- mp3_bitrate->create_objects();
- }
- else
- if(!strcasecmp(asset->acodec, QUICKTIME_ULAW))
- {
- }
- else
- if(!strcasecmp(asset->acodec, QUICKTIME_VORBIS))
- {
- add_subwindow(vorbis_vbr = new MOVConfigAudioToggle(this,
- _("Variable bitrate"),
- x,
- y,
- &asset->vorbis_vbr));
- y += 35;
- vorbis_min_bitrate = new MOVConfigAudioNum(this,
- _("Min bitrate:"),
- x,
- y,
- &asset->vorbis_min_bitrate);
- vorbis_min_bitrate->set_increment(1000);
- y += 30;
- vorbis_bitrate = new MOVConfigAudioNum(this,
- _("Avg bitrate:"),
- x,
- y,
- &asset->vorbis_bitrate);
- vorbis_bitrate->set_increment(1000);
- y += 30;
- vorbis_max_bitrate = new MOVConfigAudioNum(this,
- _("Max bitrate:"),
- x,
- y,
- &asset->vorbis_max_bitrate);
- vorbis_max_bitrate->set_increment(1000);
-
-
-
- vorbis_min_bitrate->create_objects();
- vorbis_bitrate->create_objects();
- vorbis_max_bitrate->create_objects();
- }
- else
- if(!strcasecmp(asset->acodec, QUICKTIME_MP4A))
- {
- mp4a_bitrate = new MOVConfigAudioNum(this,
- _("Bitrate:"),
- x,
- y,
- &asset->mp4a_bitrate);
- mp4a_bitrate->set_increment(64000);
- mp4a_bitrate->create_objects();
-
- y += 30;
- mp4a_quantqual = new MOVConfigAudioNum(this,
- _("Quantization Quality (%):"),
- x,
- y,
- &asset->mp4a_quantqual);
- mp4a_quantqual->set_increment(1);
- mp4a_quantqual->create_objects();
- }
- show_window(1);
-}
-
-int MOVConfigAudio::close_event()
-{
- set_done(0);
- return 1;
-}
-
-
-
-
-
-MOVConfigAudioToggle::MOVConfigAudioToggle(MOVConfigAudio *popup,
- char *title_text,
- int x,
- int y,
- int *output)
- : BC_CheckBox(x, y, *output, title_text)
-{
- this->popup = popup;
- this->output = output;
-}
-int MOVConfigAudioToggle::handle_event()
-{
- *output = get_value();
- return 1;
-}
-
-
-
-
-
-MOVConfigAudioNum::MOVConfigAudioNum(MOVConfigAudio *popup, char *title_text, int x, int y, int *output)
- : BC_TumbleTextBox(popup,
- (int64_t)*output,
- (int64_t)-1,
- (int64_t)25000000,
- popup->get_w() - 150,
- y,
- 100)
-{
- this->popup = popup;
- this->title_text = title_text;
- this->output = output;
- this->x = x;
- this->y = y;
-}
-
-MOVConfigAudioNum::~MOVConfigAudioNum()
-{
- if(!popup->get_deleting()) delete title;
-}
-
-void MOVConfigAudioNum::create_objects()
-{
- popup->add_subwindow(title = new BC_Title(x, y, title_text));
- BC_TumbleTextBox::create_objects();
-}
-
-int MOVConfigAudioNum::handle_event()
-{
- *output = atol(get_text());
- return 1;
-}
-
-
-
-
-
-
-
-
-MOVConfigAudioPopup::MOVConfigAudioPopup(MOVConfigAudio *popup, int x, int y)
- : BC_PopupTextBox(popup,
- &popup->compression_items,
- FileMOV::compressiontostr(popup->asset->acodec),
- x,
- y,
- 300,
- 300)
-{
- this->popup = popup;
-}
-
-int MOVConfigAudioPopup::handle_event()
-{
- strcpy(popup->asset->acodec, FileMOV::strtocompression(get_text()));
- popup->update_parameters();
- return 1;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-MOVConfigVideo::MOVConfigVideo(BC_WindowBase *parent_window,
- Asset *asset,
- const char *locked_compressor)
- : BC_Window(_(PROGRAM_NAME ": Video Compression"),
- parent_window->get_abs_cursor_x(1),
- parent_window->get_abs_cursor_y(1),
- 420,
- 420)
-{
- this->parent_window = parent_window;
- this->asset = asset;
- this->locked_compressor = locked_compressor;
- compression_popup = 0;
-
- reset();
-}
-
-MOVConfigVideo::~MOVConfigVideo()
-{
- lock_window("MOVConfigVideo::~MOVConfigVideo");
- if(compression_popup) delete compression_popup;
- compression_items.remove_all_objects();
- unlock_window();
-}
-
-void MOVConfigVideo::create_objects()
-{
- int x = 10, y = 10;
- lock_window("MOVConfigVideo::create_objects");
-
- if(asset->format == FILE_MOV)
- {
- compression_items.append(new BC_ListBoxItem(_(H264_NAME)));
- compression_items.append(new BC_ListBoxItem(_(HV64_NAME)));
-// compression_items.append(new BC_ListBoxItem(_(DIVX_NAME)));
- compression_items.append(new BC_ListBoxItem(_(MP4V_NAME)));
- compression_items.append(new BC_ListBoxItem(_(HV60_NAME)));
- compression_items.append(new BC_ListBoxItem(_(DIV3_NAME)));
- compression_items.append(new BC_ListBoxItem(_(DV_NAME)));
- compression_items.append(new BC_ListBoxItem(_(QTJPEG_NAME)));
- compression_items.append(new BC_ListBoxItem(_(QTMJPEGP_NAME)));
- compression_items.append(new BC_ListBoxItem(_(MJPA_NAME)));
- compression_items.append(new BC_ListBoxItem(_(PNG_NAME)));
- compression_items.append(new BC_ListBoxItem(_(PNGA_NAME)));
- compression_items.append(new BC_ListBoxItem(_(RGB_NAME)));
- compression_items.append(new BC_ListBoxItem(_(RGBA_NAME)));
- compression_items.append(new BC_ListBoxItem(_(YUV420_NAME)));
- compression_items.append(new BC_ListBoxItem(_(YUV422_NAME)));
- compression_items.append(new BC_ListBoxItem(_(TWOVUY_NAME)));
- compression_items.append(new BC_ListBoxItem(_(YUV444_NAME)));
- compression_items.append(new BC_ListBoxItem(_(YUVA4444_NAME)));
- compression_items.append(new BC_ListBoxItem(_(YUV444_10BIT_NAME)));
- }
- else
- {
- compression_items.append(new BC_ListBoxItem(_(H264_NAME)));
- compression_items.append(new BC_ListBoxItem(_(HV64_NAME)));
-// compression_items.append(new BC_ListBoxItem(_(DIVX_NAME)));
- compression_items.append(new BC_ListBoxItem(_(MP4V_NAME)));
- compression_items.append(new BC_ListBoxItem(_(HV60_NAME)));
- compression_items.append(new BC_ListBoxItem(_(DIV3_NAME)));
- compression_items.append(new BC_ListBoxItem(_(DV_NAME)));
- compression_items.append(new BC_ListBoxItem(_(QTJPEG_NAME)));
- compression_items.append(new BC_ListBoxItem(_(MJPA_NAME)));
- compression_items.append(new BC_ListBoxItem(_(PNG_NAME)));
- }
-
- add_subwindow(new BC_Title(x, y, _("Compression:")));
- y += 25;
-
- if(!locked_compressor)
- {
- compression_popup = new MOVConfigVideoPopup(this, x, y);
- compression_popup->create_objects();
- }
- else
- {
- add_subwindow(new BC_Title(x,
- y,
- FileMOV::compressiontostr(locked_compressor),
- MEDIUMFONT,
- RED,
- 0));
- }
- y += 40;
-
- param_x = x;
- param_y = y;
- update_parameters();
-
- add_subwindow(new BC_OKButton(this));
- show_window(1);
- unlock_window();
-}
-
-int MOVConfigVideo::close_event()
-{
- set_done(0);
- return 1;
-}
-
-
-void MOVConfigVideo::reset()
-{
- jpeg_quality = 0;
- jpeg_quality_title = 0;
-
- divx_bitrate = 0;
- divx_rc_period = 0;
- divx_rc_reaction_ratio = 0;
- divx_rc_reaction_period = 0;
- divx_max_key_interval = 0;
- divx_max_quantizer = 0;
- divx_min_quantizer = 0;
- divx_quantizer = 0;
- divx_quality = 0;
- divx_fix_bitrate = 0;
- divx_fix_quant = 0;
-
- h264_bitrate = 0;
- h264_quantizer = 0;
- h264_fix_bitrate = 0;
- h264_fix_quant = 0;
-
- ms_bitrate = 0;
- ms_bitrate_tolerance = 0;
- ms_quantization = 0;
- ms_interlaced = 0;
- ms_gop_size = 0;
- ms_fix_bitrate = 0;
- ms_fix_quant = 0;
-}
-
-void MOVConfigVideo::update_parameters()
-{
- if(jpeg_quality)
- {
- delete jpeg_quality_title;
- delete jpeg_quality;
- }
-
- if(divx_bitrate) delete divx_bitrate;
- if(divx_rc_period) delete divx_rc_period;
- if(divx_rc_reaction_ratio) delete divx_rc_reaction_ratio;
- if(divx_rc_reaction_period) delete divx_rc_reaction_period;
- if(divx_max_key_interval) delete divx_max_key_interval;
- if(divx_max_quantizer) delete divx_max_quantizer;
- if(divx_min_quantizer) delete divx_min_quantizer;
- if(divx_quantizer) delete divx_quantizer;
- if(divx_quality) delete divx_quality;
- if(divx_fix_quant) delete divx_fix_quant;
- if(divx_fix_bitrate) delete divx_fix_bitrate;
-
- if(ms_bitrate) delete ms_bitrate;
- if(ms_bitrate_tolerance) delete ms_bitrate_tolerance;
- if(ms_interlaced) delete ms_interlaced;
- if(ms_quantization) delete ms_quantization;
- if(ms_gop_size) delete ms_gop_size;
- if(ms_fix_bitrate) delete ms_fix_bitrate;
- if(ms_fix_quant) delete ms_fix_quant;
-
- delete h264_bitrate;
- delete h264_quantizer;
- delete h264_fix_bitrate;
- delete h264_fix_quant;
-
- reset();
-
-
- const char *vcodec = asset->vcodec;
- if(locked_compressor) vcodec = locked_compressor;
-
-
-// H264 parameters
- if(!strcmp(vcodec, QUICKTIME_H264) ||
- !strcmp(vcodec, QUICKTIME_HV64))
- {
- int x = param_x, y = param_y;
- h264_bitrate = new MOVConfigVideoNum(this,
- _("Bitrate:"),
- x,
- y,
- &asset->h264_bitrate);
- h264_bitrate->set_increment(1000000);
- h264_bitrate->create_objects();
- add_subwindow(h264_fix_bitrate = new MOVConfigVideoFixBitrate(x + 260,
- y,
- &asset->h264_fix_bitrate,
- 1));
- y += 30;
- h264_quantizer = new MOVConfigVideoNum(this,
- _("Quantization:"),
- x,
- y,
- 0,
- 51,
- &asset->h264_quantizer);
- h264_quantizer->create_objects();
- add_subwindow(h264_fix_quant = new MOVConfigVideoFixQuant(x + 260,
- y,
- &asset->h264_fix_bitrate,
- 0));
- h264_fix_bitrate->opposite = h264_fix_quant;
- h264_fix_quant->opposite = h264_fix_bitrate;
- }
- else
-// ffmpeg parameters
- if(!strcmp(vcodec, QUICKTIME_MP4V) ||
- !strcmp(vcodec, QUICKTIME_DIV3))
- {
- int x = param_x, y = param_y;
- ms_bitrate = new MOVConfigVideoNum(this,
- _("Bitrate:"),
- x,
- y,
- &asset->ms_bitrate);
- ms_bitrate->set_increment(1000000);
- ms_bitrate->create_objects();
- add_subwindow(ms_fix_bitrate = new MOVConfigVideoFixBitrate(x + 260,
- y,
- &asset->ms_fix_bitrate,
- 1));
- y += 30;
-
- ms_bitrate_tolerance = new MOVConfigVideoNum(this,
- _("Bitrate tolerance:"),
- x,
- y,
- &asset->ms_bitrate_tolerance);
- ms_bitrate_tolerance->create_objects();
- y += 30;
-
-
-
- ms_quantization = new MOVConfigVideoNum(this,
- _("Quantization:"),
- x,
- y,
- &asset->ms_quantization);
- ms_quantization->create_objects();
- add_subwindow(ms_fix_quant = new MOVConfigVideoFixQuant(x + 260,
- y,
- &asset->ms_fix_bitrate,
- 0));
- ms_fix_bitrate->opposite = ms_fix_quant;
- ms_fix_quant->opposite = ms_fix_bitrate;
-
-
- y += 30;
- add_subwindow(ms_interlaced = new MOVConfigVideoCheckBox(_("Interlaced"),
- x,
- y,
- &asset->ms_interlaced));
- y += 30;
- ms_gop_size = new MOVConfigVideoNum(this,
- _("Keyframe interval:"),
- x,
- y,
- &asset->ms_gop_size);
- ms_gop_size->create_objects();
- }
- else
-// OpenDivx parameters
- if(!strcmp(vcodec, QUICKTIME_DIVX) ||
- !strcmp(vcodec, QUICKTIME_H263) ||
- !strcmp(vcodec, QUICKTIME_HV60))
- {
- int x = param_x, y = param_y;
- divx_bitrate = new MOVConfigVideoNum(this,
- _("Bitrate:"),
- x,
- y,
- &asset->divx_bitrate);
- divx_bitrate->set_increment(1000000);
- divx_bitrate->create_objects();
- add_subwindow(divx_fix_bitrate =
- new MOVConfigVideoFixBitrate(x + 260,
- y,
- &asset->divx_fix_bitrate,
- 1));
- y += 30;
- divx_quantizer = new MOVConfigVideoNum(this,
- _("Quantizer:"),
- x,
- y,
- &asset->divx_quantizer);
- divx_quantizer->create_objects();
- add_subwindow(divx_fix_quant =
- new MOVConfigVideoFixQuant(x + 260,
- y,
- &asset->divx_fix_bitrate,
- 0));
- divx_fix_quant->opposite = divx_fix_bitrate;
- divx_fix_bitrate->opposite = divx_fix_quant;
- y += 30;
- divx_rc_period = new MOVConfigVideoNum(this,
- _("RC Period:"),
- x,
- y,
- &asset->divx_rc_period);
- divx_rc_period->create_objects();
- y += 30;
- divx_rc_reaction_ratio = new MOVConfigVideoNum(this,
- _("Reaction Ratio:"),
- x,
- y,
- &asset->divx_rc_reaction_ratio);
- divx_rc_reaction_ratio->create_objects();
- y += 30;
- divx_rc_reaction_period = new MOVConfigVideoNum(this,
- _("Reaction Period:"),
- x,
- y,
- &asset->divx_rc_reaction_period);
- divx_rc_reaction_period->create_objects();
- y += 30;
- divx_max_key_interval = new MOVConfigVideoNum(this,
- _("Max Key Interval:"),
- x,
- y,
- &asset->divx_max_key_interval);
- divx_max_key_interval->create_objects();
- y += 30;
- divx_max_quantizer = new MOVConfigVideoNum(this,
- _("Max Quantizer:"),
- x,
- y,
- &asset->divx_max_quantizer);
- divx_max_quantizer->create_objects();
- y += 30;
- divx_min_quantizer = new MOVConfigVideoNum(this,
- _("Min Quantizer:"),
- x,
- y,
- &asset->divx_min_quantizer);
- divx_min_quantizer->create_objects();
- y += 30;
- divx_quality = new MOVConfigVideoNum(this,
- _("Quality:"),
- x,
- y,
- &asset->divx_quality);
- divx_quality->create_objects();
- }
- else
- if(!strcmp(vcodec, QUICKTIME_JPEG) ||
- !strcmp(vcodec, QUICKTIME_MJPA))
- {
- add_subwindow(jpeg_quality_title = new BC_Title(param_x, param_y, _("Quality:")));
- add_subwindow(jpeg_quality = new BC_ISlider(param_x + 80,
- param_y,
- 0,
- 200,
- 200,
- 0,
- 100,
- asset->jpeg_quality,
- 0,
- 0,
- &asset->jpeg_quality));
- }
- show_window(1);
-}
-
-
-
-
-
-MOVConfigVideoNum::MOVConfigVideoNum(MOVConfigVideo *popup, char *title_text, int x, int y, int *output)
- : BC_TumbleTextBox(popup,
- (int64_t)*output,
- (int64_t)1,
- (int64_t)25000000,
- x + 130,
- y,
- 100)
-{
- this->popup = popup;
- this->title_text = title_text;
- this->output = output;
- this->x = x;
- this->y = y;
-}
-
-MOVConfigVideoNum::MOVConfigVideoNum(MOVConfigVideo *popup,
- char *title_text,
- int x,
- int y,
- int min,
- int max,
- int *output)
- : BC_TumbleTextBox(popup,
- (int64_t)*output,
- (int64_t)min,
- (int64_t)max,
- x + 130,
- y,
- 100)
-{
- this->popup = popup;
- this->title_text = title_text;
- this->output = output;
- this->x = x;
- this->y = y;
-}
-
-MOVConfigVideoNum::~MOVConfigVideoNum()
-{
- if(!popup->get_deleting()) delete title;
-}
-
-void MOVConfigVideoNum::create_objects()
-{
- popup->add_subwindow(title = new BC_Title(x, y, title_text));
- BC_TumbleTextBox::create_objects();
-}
-
-int MOVConfigVideoNum::handle_event()
-{
- *output = atol(get_text());
- return 1;
-}
-
-
-
-
-
-
-
-MOVConfigVideoCheckBox::MOVConfigVideoCheckBox(char *title_text, int x, int y, int *output)
- : BC_CheckBox(x, y, *output, title_text)
-{
- this->output = output;
-}
-
-int MOVConfigVideoCheckBox::handle_event()
-{
- *output = get_value();
- return 1;
-}
-
-
-
-
-
-
-MOVConfigVideoFixBitrate::MOVConfigVideoFixBitrate(int x,
- int y,
- int *output,
- int value)
- : BC_Radial(x,
- y,
- *output == value,
- _("Fix bitrate"))
-{
- this->output = output;
- this->value = value;
-}
-
-int MOVConfigVideoFixBitrate::handle_event()
-{
- *output = value;
- opposite->update(0);
- return 1;
-}
-
-
-
-
-
-
-MOVConfigVideoFixQuant::MOVConfigVideoFixQuant(int x,
- int y,
- int *output,
- int value)
- : BC_Radial(x,
- y,
- *output == value,
- _("Fix quantization"))
-{
- this->output = output;
- this->value = value;
-}
-
-int MOVConfigVideoFixQuant::handle_event()
-{
- *output = value;
- opposite->update(0);
- return 1;
-}
-
-
-
-
-
-MOVConfigVideoPopup::MOVConfigVideoPopup(MOVConfigVideo *popup, int x, int y)
- : BC_PopupTextBox(popup,
- &popup->compression_items,
- FileMOV::compressiontostr(popup->asset->vcodec),
- x,
- y,
- 300,
- 300)
-{
- this->popup = popup;
-}
-
-int MOVConfigVideoPopup::handle_event()
-{
- strcpy(popup->asset->vcodec, FileMOV::strtocompression(get_text()));
- popup->update_parameters();
- return 1;
-}
-
-
-
-
-
-
-
-
-