// format = FILE_MOV;
// Has to be unknown for file probing to succeed
format = FILE_UNKNOWN;
+ fformat[0] = 0;
bits = 0;
byte_order = 0;
signed_ = 0;
strcpy(vcodec, QUICKTIME_YUV2);
strcpy(acodec, QUICKTIME_TWOS);
+
+ ff_audio_options[0] = 0;
+ ff_video_options[0] = 0;
+ ff_audio_bitrate = 0;
+ ff_video_bitrate = 0;
+ ff_video_quality = 0;
+
jpeg_quality = 100;
aspect_ratio = -1;
id = EDL::next_id();
- pipe[0] = 0;
- use_pipe = 0;
-
- reset_timecode();
-
return 0;
}
index_state->reset();
}
-int Asset::reset_timecode()
-{
- strcpy(reel_name, "cin0000");
- reel_number = 0;
- tcstart = 0;
- tcend = 0;
- tcformat = 0;
-
- return 0;
-}
-
void Asset::copy_from(Asset *asset, int do_index)
{
copy_location(asset);
audio_data = asset->audio_data;
format = asset->format;
+ strcpy(fformat, asset->fformat);
channels = asset->channels;
sample_rate = asset->sample_rate;
bits = asset->bits;
strcpy(vcodec, asset->vcodec);
strcpy(acodec, asset->acodec);
+ strcpy(ff_audio_options, asset->ff_audio_options);
+ strcpy(ff_video_options, asset->ff_video_options);
+ ff_audio_bitrate = asset->ff_audio_bitrate;
+ ff_video_bitrate = asset->ff_video_bitrate;
+ ff_video_quality = asset->ff_video_quality;
+
this->audio_length = asset->audio_length;
this->video_length = asset->video_length;
int result = (!strcmp(asset.path, path) &&
format == asset.format);
+ if(result && format == FILE_FFMPEG)
+ result = !strcmp(fformat, asset.fformat);
+
if(test_audio && result)
{
result = (channels == asset.channels &&
header == asset.header &&
dither == asset.dither &&
!strcmp(acodec, asset.acodec));
+ if(result && format == FILE_FFMPEG)
+ result = !strcmp(ff_audio_options, asset.ff_audio_options) &&
+ ff_audio_bitrate == asset.ff_audio_bitrate;
+
}
width == asset.width &&
height == asset.height &&
!strcmp(vcodec, asset.vcodec));
+ if(result && format == FILE_FFMPEG)
+ result = !strcmp(ff_video_options, asset.ff_video_options) &&
+ ff_video_bitrate == asset.ff_video_bitrate &&
+ ff_video_quality == asset.ff_video_quality;
}
return result;
format = File::strtoformat(string);
use_header =
file->tag.get_property("USE_HEADER", use_header);
+ file->tag.get_property("FFORMAT", fformat);
}
else
if(file->tag.title_is("FOLDER"))
audio_length = file->tag.get_property("AUDIO_LENGTH", (int64_t)0);
acodec[0] = 0;
file->tag.get_property("ACODEC", acodec);
-
-
-
return 0;
}
file->tag.set_property("TYPE",
File::formattostr(format));
file->tag.set_property("USE_HEADER", use_header);
+ file->tag.set_property("FFORMAT", fformat);
file->append_tag();
file->append_newline();
{
format = GET_DEFAULT("FORMAT", format);
use_header = GET_DEFAULT("USE_HEADER", use_header);
+ GET_DEFAULT("FFORMAT", fformat);
}
if(do_data_types)
theora_quality = GET_DEFAULT("THEORA_QUALITY", theora_quality);
theora_sharpness = GET_DEFAULT("THEORA_SHARPNESS", theora_sharpness);
theora_keyframe_frequency = GET_DEFAULT("THEORA_KEYFRAME_FREQUENCY", theora_keyframe_frequency);
- theora_keyframe_force_frequency = GET_DEFAULT("THEORA_FORCE_KEYFRAME_FEQUENCY", theora_keyframe_force_frequency);
-
+ theora_keyframe_force_frequency = GET_DEFAULT("THEORA_FORCE_KEYFRAME_FREQUENCY", theora_keyframe_force_frequency);
+ GET_DEFAULT("FF_AUDIO_OPTIONS", ff_audio_options);
+ ff_audio_bitrate = GET_DEFAULT("FF_AUDIO_BITRATE", ff_audio_bitrate);
+ GET_DEFAULT("FF_VIDEO_OPTIONS", ff_video_options);
+ ff_video_bitrate = GET_DEFAULT("FF_VIDEO_BITRATE", ff_video_bitrate);
+ ff_video_quality = GET_DEFAULT("FF_VIDEO_QUALITY", ff_video_quality);
mp3_bitrate = GET_DEFAULT("MP3_BITRATE", mp3_bitrate);
mp4a_bitrate = GET_DEFAULT("MP4A_BITRATE", mp4a_bitrate);
{
UPDATE_DEFAULT("FORMAT", format);
UPDATE_DEFAULT("USE_HEADER", use_header);
+ UPDATE_DEFAULT("FFORMAT", fformat);
}
if(do_data_types)
UPDATE_DEFAULT("VORBIS_BITRATE", vorbis_bitrate);
UPDATE_DEFAULT("VORBIS_MAX_BITRATE", vorbis_max_bitrate);
+ UPDATE_DEFAULT("FF_AUDIO_OPTIONS", ff_audio_options);
+ UPDATE_DEFAULT("FF_AUDIO_BITRATE", ff_audio_bitrate);
+ UPDATE_DEFAULT("FF_VIDEO_OPTIONS", ff_video_options);
+ UPDATE_DEFAULT("FF_VIDEO_BITRATE", ff_video_bitrate);
+ UPDATE_DEFAULT("FF_VIDEO_QUALITY", ff_video_quality);
UPDATE_DEFAULT("THEORA_FIX_BITRATE", theora_fix_bitrate);
UPDATE_DEFAULT("THEORA_BITRATE", theora_bitrate);
UPDATE_DEFAULT("THEORA_QUALITY", theora_quality);
UPDATE_DEFAULT("THEORA_SHARPNESS", theora_sharpness);
UPDATE_DEFAULT("THEORA_KEYFRAME_FREQUENCY", theora_keyframe_frequency);
- UPDATE_DEFAULT("THEORA_FORCE_KEYFRAME_FEQUENCY", theora_keyframe_force_frequency);
+ UPDATE_DEFAULT("THEORA_FORCE_KEYFRAME_FREQUENCY", theora_keyframe_force_frequency);
fprintf(fp," this=%p path=%s\n", this, path);
fprintf(fp," index_status %d\n", index_state->index_status);
fprintf(fp," format %d\n", format);
+ fprintf(fp," fformat=\"%s\"\n", fformat);
+ fprintf(fp," ff_audio_options=\"%s\"\n", ff_audio_options);
+ fprintf(fp," ff_audio_bitrate=%d\n", ff_audio_bitrate);
+ fprintf(fp," ff_video_options=\"%s\"\n", ff_video_options);
+ fprintf(fp," ff_video_bitrate=%d\n", ff_video_bitrate);
+ fprintf(fp," ff_video_quality=%d\n", ff_video_quality);
fprintf(fp," audio_data %d channels %d samplerate %d bits %d"
" byte_order %d signed %d header %d dither %d acodec %c%c%c%c\n",
audio_data, channels, sample_rate, bits, byte_order, signed_,
int64_t audio_length;
-// Timecode information. User setable, in case of errors in source
- char reel_name[BCTEXTLEN];
- int reel_number;
- int64_t tcstart;
- int64_t tcend;
- int tcformat;
-
// contains video data
int video_data;
int layers, program;
int vmpeg_field_order;
int vmpeg_pframe_distance;
-
-
-
-
-
-
+// ffmpeg muxer file extension
+ char fformat[BCSTRLEN];
+ char ff_audio_options[BCTEXTLEN];
+ char ff_video_options[BCTEXTLEN];
+ int ff_audio_bitrate;
+ int ff_video_bitrate;
+ int ff_video_quality;
// Divx video compression
int divx_bitrate;
int ac3_bitrate;
- char pipe[BCTEXTLEN];
- int use_pipe;
-
// Image file sequences. Background rendering doesn't want to write a
// sequence header but instead wants to start the sequence numbering at a certain
// number. This ensures deletion of all the frames which aren't being used.
char *string;
defaults.save_string(string);
file->append_text(string);
- delete [] string;
+ free(string);
file->tag.set_title("/JOB");
file->append_tag();
file->append_newline();
x = x1;
- y += 30;
+ y += 64;
add_subwindow(update_selected_edl = new BatchRenderUpdateEDL(thread,
x,
y));
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
+#include <fcntl.h>
#include <limits.h>
// work arounds (centos)
#include <lzma.h>
#include "fileffmpeg.h"
#include "file.h"
#include "ffmpeg.h"
+#include "mainerror.h"
#include "mwindow.h"
#include "vframe.h"
fst->dequeue(this);
}
-FFAudioHistory::FFAudioHistory()
+int FFAudioStream::read(float *fp, long len)
{
- this->nch = 1;
- this->sz = 0x1000;
- bsz = sz * nch;
- bfr = new float[bsz];
- inp = outp = bfr;
- lmt = bfr + bsz;
+ long n = len * nch;
+ float *op = outp;
+ while( n > 0 ) {
+ int k = lmt - op;
+ if( k > n ) k = n;
+ n -= k;
+ while( --k >= 0 ) *fp++ = *op++;
+ if( op >= lmt ) op = bfr;
+ }
+ return len;
}
-FFAudioHistory::~FFAudioHistory()
+void FFAudioStream::realloc(long sz, int nch, long len)
{
- delete [] bfr;
+ long bsz = sz * nch;
+ float *np = new float[bsz];
+ inp = np + read(np, len) * nch;
+ outp = np;
+ lmt = np + bsz;
+ this->nch = nch;
+ this->sz = sz;
+ delete [] bfr; bfr = np;
}
-
-void FFAudioHistory::reserve(long sz, int nch)
+void FFAudioStream::realloc(long sz, int nch)
{
- long isz = inp - outp;
- sz += isz / nch;
- if( this->sz < sz || this->nch != nch ) {
- realloc(sz, nch);
- return;
+ if( sz > this->sz || this->nch != nch ) {
+ long len = this->nch != nch ? 0 : curr_pos - seek_pos;
+ if( len > this->sz ) len = this->sz;
+ iseek(len);
+ realloc(sz, nch, len);
}
- if( isz > 0 )
- memmove(bfr, outp, isz*sizeof(*bfr));
- outp = bfr;
- inp = bfr + isz;
}
-void FFAudioHistory::realloc(long sz, int nch)
+void FFAudioStream::reserve(long sz, int nch)
{
- if( this->nch != nch )
- reset();
- else if( this->sz >= sz )
+ long len = (inp - outp) / nch;
+ sz += len;
+ if( sz > this->sz || this->nch != nch ) {
+ if( this->nch != nch ) len = 0;
+ realloc(sz, nch, len);
return;
- this->nch = nch;
- this->sz = sz;
- bsz = sz * nch;
- float *np = new float[bsz];
- inp = np + copy(np, used());
- outp = np;
- lmt = np + bsz;
- delete [] bfr; bfr = np;
+ }
+ if( (len*=nch) > 0 && bfr != outp )
+ memmove(bfr, outp, len*sizeof(*bfr));
+ outp = bfr;
+ inp = bfr + len;
}
-long FFAudioHistory::used()
+long FFAudioStream::used()
{
long len = inp>=outp ? inp-outp : inp-bfr + lmt-outp;
return len / nch;
}
-long FFAudioHistory::avail()
+long FFAudioStream::avail()
{
float *in1 = inp+1;
if( in1 >= lmt ) in1 = bfr;
long len = outp >= in1 ? outp-in1 : outp-bfr + lmt-in1;
return len / nch;
}
-void FFAudioHistory::reset() // clear bfr
+void FFAudioStream::reset() // clear bfr
{
inp = outp = bfr;
}
-void FFAudioHistory::iseek(int64_t ofs)
+void FFAudioStream::iseek(int64_t ofs)
{
outp = inp - ofs*nch;
- if( outp < bfr ) outp += bsz;
+ if( outp < bfr ) outp += sz*nch;
}
-float *FFAudioHistory::get_outp(int ofs)
+float *FFAudioStream::get_outp(int ofs)
{
float *ret = outp;
outp += ofs*nch;
return ret;
}
-int64_t FFAudioHistory::get_inp(int ofs)
+int64_t FFAudioStream::put_inp(int ofs)
{
inp += ofs*nch;
- return (inp-bfr) / nch;
+ return (inp-outp) / nch;
}
-int FFAudioHistory::write(const float *fp, long len)
+int FFAudioStream::write(const float *fp, long len)
{
long n = len * nch;
float *ip = inp;
return len;
}
-int FFAudioHistory::copy(float *fp, long len)
-{
- long n = len * nch;
- float *op = outp;
- while( n > 0 ) {
- int k = lmt - op;
- if( k > n ) k = n;
- n -= k;
- while( --k >= 0 ) *fp++ = *op++;
- if( op >= lmt ) op = bfr;
- }
- outp = op;
- return len;
-}
-
-int FFAudioHistory::zero(long len)
+int FFAudioStream::zero(long len)
{
long n = len * nch;
float *ip = inp;
}
// does not advance outp
-int FFAudioHistory::read(double *dp, long len, int ch)
+int FFAudioStream::read(double *dp, long len, int ch)
{
- long sz = used();
- if( !sz ) return 0;
- if( len > sz ) len = sz;
long n = len;
float *op = outp + ch;
float *lmt1 = lmt + nch-1;
if( k > n ) k = n;
n -= k;
while( --k >= 0 ) { *dp++ = *op; op += nch; }
- if( op >= lmt ) op -= bsz;
+ if( op >= lmt ) op -= sz*nch;
}
return len;
}
// load linear buffer, no wrapping allowed, does not advance inp
-int FFAudioHistory::write(const double *dp, long len, int ch)
+int FFAudioStream::write(const double *dp, long len, int ch)
{
- long osz = avail();
- if( !osz || !len ) return 0;
- if( len > osz ) len = osz;
long n = len;
float *ip = inp + ch;
while( --n >= 0 ) { *ip = *dp++; ip += nch; }
if( ret >= 0 )
reading = 1;
else
- fprintf(stderr, "FFStream::decode_activate: open decoder failed\n");
+ eprintf("FFStream::decode_activate: open decoder failed\n");
}
else
- fprintf(stderr, "FFStream::decode_activate: can't clone input file\n");
+ eprintf("FFStream::decode_activate: can't clone input file\n");
av_dict_free(&copts);
ff_unlock();
}
frame, AV_BUFFERSRC_FLAG_KEEP_REF);
if( ret < 0 ) {
av_frame_unref(frame);
- fprintf(stderr, "FFStream::load_filter: av_buffersrc_add_frame_flags failed\n");
+ eprintf("FFStream::load_filter: av_buffersrc_add_frame_flags failed\n");
}
return ret;
}
aud_bfr_sz = 0;
aud_bfr = 0;
+
+// history buffer
+ nch = 2;
+ sz = 0x10000;
+ long bsz = sz * nch;
+ bfr = new float[bsz];
+ inp = outp = bfr;
+ lmt = bfr + bsz;
}
FFAudioStream::~FFAudioStream()
{
if( resample_context ) swr_free(&resample_context);
delete [] aud_bfr;
+ delete [] bfr;
}
-int FFAudioStream::load_history(float *&bfr, int len)
+int FFAudioStream::load_history(uint8_t **data, int len)
{
+ float *samples = *(float **)data;
if( resample_context ) {
if( len > aud_bfr_sz ) {
delete [] aud_bfr;
aud_bfr = new float[aud_bfr_sz*channels];
}
int ret = swr_convert(resample_context,
- (uint8_t**)&aud_bfr, aud_bfr_sz,
- (const uint8_t**)&bfr, len);
+ (uint8_t**)&aud_bfr, aud_bfr_sz, (const uint8_t**)data, len);
if( ret < 0 ) {
fprintf(stderr, "FFAudioStream::load_history: swr_convert failed\n");
return -1;
}
- bfr = aud_bfr;
+ samples = aud_bfr;
len = ret;
}
- append_history(bfr, len);
+ // biggest user bfr since seek + frame
+ realloc(mbsz + len + 1, channels);
+ write(samples, len);
return len;
}
10000 : ctx->frame_size;
}
-void FFAudioStream::alloc_history(int len)
-{
- history.realloc(len+1, channels);
-}
-
-void FFAudioStream::reserve_history(int len)
-{
- history.reserve(len+1, st->codec->channels);
-}
-
-void FFAudioStream::append_history(const float *fp, int len)
-{
- // biggest user bfr since seek + length this frame
- int hsz = mbsz + len;
- alloc_history(hsz);
- history.write(fp, len);
-}
-
int64_t FFAudioStream::load_buffer(double ** const sp, int len)
{
- reserve_history(len);
- int nch = st->codec->channels;
+ reserve(len+1, st->codec->channels);
for( int ch=0; ch<nch; ++ch )
- history.write(sp[ch], len, ch);
- return history.get_inp(len);
-}
-
-void FFAudioStream::zero_history(int len)
-{
- history.zero(len);
-}
-
-float* FFAudioStream::get_history(int len)
-{
- return history.get_outp(len);
+ write(sp[ch], len, ch);
+ return put_inp(len);
}
int FFAudioStream::in_history(int64_t pos)
{
if( pos > curr_pos ) return 0;
int64_t len = curr_pos - seek_pos;
- if( len > history.sz ) len = history.sz;
+ if( len > sz ) len = sz;
if( pos < curr_pos - len ) return 0;
return 1;
}
for( int i=0; ret>=0 && !flushed && curr_pos<end_pos && i<1000; ++i ) {
ret = read_frame(frame);
if( ret > 0 ) {
- load_history((float *&)frame->extended_data[0], frame->nb_samples);
+ load_history(&frame->extended_data[0], frame->nb_samples);
curr_pos += frame->nb_samples;
}
}
if( flushed && end_pos > curr_pos ) {
- zero_history(end_pos - curr_pos);
+ zero(end_pos - curr_pos);
curr_pos = end_pos;
}
return curr_pos - pos;
{
if( decode_activate() < 0 ) return -1;
if( in_history(pos) ) {
- history.iseek(curr_pos - pos);
+ iseek(curr_pos - pos);
return 0;
}
if( pos == curr_pos ) return 0;
avformat_seek_file(fmt_ctx, st->index, -INT64_MAX, tstmp, INT64_MAX, 0);
seek_pos = curr_pos = pos;
mbsz = 0;
- history.reset();
+ reset();
st_eof(0);
return 1;
}
frm = new FFrame(this);
if( (ret=frm->initted()) < 0 ) break;
AVFrame *frame = *frm;
- float *bfrp = get_history(frame_sz);
+ float *bfrp = get_outp(frame_sz);
ret = swr_convert(resample_context,
(uint8_t **)frame->extended_data, frame_sz,
(const uint8_t **)&bfrp, frame_sz);
set_option_path(path, "%s/%s", type, spec);
}
-int FFMPEG::check_option(const char *path, char *spec)
+int FFMPEG::get_format(char *format, const char *path, char *spec)
{
- char option_path[BCTEXTLEN], line[BCTEXTLEN];
- char format[BCSTRLEN], codec[BCSTRLEN];
+ char option_path[BCTEXTLEN], line[BCTEXTLEN], codec[BCSTRLEN];
get_option_path(option_path, path, spec);
FILE *fp = fopen(option_path,"r");
if( !fp ) return 1;
line[sizeof(line)-1] = 0;
ret = scan_option_line(line, format, codec);
}
- if( !ret ) {
- if( !file_format[0] ) strcpy(file_format, format);
- else if( strcmp(file_format, format) ) ret = 1;
- }
fclose(fp);
return ret;
}
-const char *FFMPEG::get_file_format()
+int FFMPEG::get_file_format()
{
- file_format[0] = 0;
int ret = 0;
+ char audio_format[BCSTRLEN], video_format[BCSTRLEN];
+ file_format[0] = audio_format[0] = video_format[0] = 0;
Asset *asset = file_base->asset;
if( !ret && asset->audio_data )
- ret = check_option("audio", asset->acodec);
+ ret = get_format(audio_format, "audio", asset->acodec);
if( !ret && asset->video_data )
- ret = check_option("video", asset->vcodec);
- if( !ret && !file_format[0] ) ret = 1;
- return !ret ? file_format : 0;
+ ret = get_format(video_format, "video", asset->vcodec);
+ if( !ret && !audio_format[0] && !video_format[0] )
+ ret = 1;
+ if( !ret && audio_format[0] && video_format[0] &&
+ strcmp(audio_format, video_format) ) ret = -1;
+ if( !ret )
+ strcpy(file_format, audio_format[0] ? audio_format : video_format);
+ return ret;
}
int FFMPEG::scan_option_line(char *cp, char *tag, char *val)
return 0;
}
-int FFMPEG::read_options(const char *options, char *format, char *codec,
- char *bsfilter, char *bsargs, AVDictionary *&opts)
+int FFMPEG::get_encoder(const char *options,
+ char *format, char *codec, char *bsfilter, char *bsargs)
{
FILE *fp = fopen(options,"r");
if( !fp ) {
- fprintf(stderr, "FFMPEG::read_options: options open failed %s\n",options);
+ eprintf("FFMPEG::get_encoder: options open failed %s\n",options);
return 1;
}
- int ret = read_options(fp, options, format, codec, opts);
- char *cp = codec;
- while( *cp && *cp != '|' ) ++cp;
- if( *cp == '|' && !scan_option_line(cp+1, bsfilter, bsargs) ) {
- do { *cp-- = 0; } while( cp>=codec && (*cp==' ' || *cp == '\t' ) );
- }
- else
- bsfilter[0] = bsargs[0] = 0;
+ if( get_encoder(fp, format, codec, bsfilter, bsargs) )
+ eprintf("FFMPEG::get_encoder:"
+ " err: format/codec not found %s\n", options);
fclose(fp);
- return ret;
+ return 0;
}
-int FFMPEG::read_options(FILE *fp, const char *options,
- char *format, char *codec, AVDictionary *&opts)
+int FFMPEG::get_encoder(FILE *fp,
+ char *format, char *codec, char *bsfilter, char *bsargs)
{
+ format[0] = codec[0] = bsfilter[0] = bsargs[0] = 0;
char line[BCTEXTLEN];
- if( !fgets(line, sizeof(line), fp) ) {
- fprintf(stderr, "FFMPEG::read_options:"
- " options file empty %s\n",options);
- return 1;
- }
+ if( !fgets(line, sizeof(line), fp) ) return 1;
line[sizeof(line)-1] = 0;
- if( scan_option_line(line, format, codec) ) {
- fprintf(stderr, "FFMPEG::read_options:"
- " err: format/codec not found %s\n", options);
- return 1;
- }
- return read_options(fp, options, opts, 1);
+ if( scan_option_line(line, format, codec) ) return 1;
+ char *cp = codec;
+ while( *cp && *cp != '|' ) ++cp;
+ if( !*cp ) return 0;
+ if( scan_option_line(cp+1, bsfilter, bsargs) ) return 1;
+ do { *cp-- = 0; } while( cp>=codec && (*cp==' ' || *cp == '\t' ) );
+ return 0;
}
int FFMPEG::read_options(const char *options, AVDictionary *&opts)
return ret;
}
-int FFMPEG::read_options(FILE *fp, const char *options, AVDictionary *&opts, int no)
+int FFMPEG::scan_options(const char *options, AVDictionary *&opts)
{
- int ret = 0;
+ FILE *fp = fmemopen((void *)options,strlen(options),"r");
+ if( !fp ) return 0;
+ int ret = read_options(fp, options, opts);
+ fclose(fp);
+ return ret;
+}
+
+int FFMPEG::read_options(FILE *fp, const char *options, AVDictionary *&opts)
+{
+ int ret = 0, no = 0;
char line[BCTEXTLEN];
while( !ret && fgets(line, sizeof(line), fp) ) {
line[sizeof(line)-1] = 0;
++no;
if( line[0] == '#' ) continue;
+ if( line[0] == '\n' ) continue;
char key[BCSTRLEN], val[BCTEXTLEN];
if( scan_option_line(line, key, val) ) {
- fprintf(stderr, "FFMPEG::read_options:"
+ eprintf("FFMPEG::read_options:"
" err reading %s: line %d\n", options, no);
ret = 1;
}
fp = fopen(file_opts, "r");
}
if( fp ) {
- read_options(fp, file_opts, opts, 0);
+ read_options(fp, file_opts, opts);
fclose(fp);
}
else
{
struct stat st;
if( stat(fmt_ctx->filename, &st) < 0 ) {
- fprintf(stderr,"FFMPEG::open_decoder: can't stat file: %s\n",
+ eprintf("FFMPEG::open_decoder: can't stat file: %s\n",
fmt_ctx->filename);
return 1;
}
int FFMPEG::init_encoder(const char *filename)
{
- const char *format = get_file_format();
- if( !format ) {
- fprintf(stderr, "FFMPEG::init_encoder: invalid file format for %s\n", filename);
+ int fd = ::open(filename,O_WRONLY);
+ if( fd < 0 ) fd = open(filename,O_WRONLY+O_CREAT,0666);
+ if( fd < 0 ) {
+ eprintf("FFMPEG::init_encoder: bad file path: %s\n", filename);
+ return 1;
+ }
+ ::close(fd);
+ int ret = get_file_format();
+ if( ret > 0 ) {
+ eprintf("FFMPEG::init_encoder: bad file format: %s\n", filename);
+ return 1;
+ }
+ if( ret < 0 ) {
+ eprintf("FFMPEG::init_encoder: mismatch audio/video file format: %s\n", filename);
return 1;
}
- int ret = 0;
ff_lock("FFMPEG::init_encoder");
av_register_all();
- avformat_alloc_output_context2(&fmt_ctx, 0, format, filename);
+ avformat_alloc_output_context2(&fmt_ctx, 0, file_format, filename);
if( !fmt_ctx ) {
- fprintf(stderr, "FFMPEG::init_encoder: failed: %s\n", filename);
+ eprintf("FFMPEG::init_encoder: failed: %s\n", filename);
ret = 1;
}
if( !ret ) {
return ret;
}
-int FFMPEG::open_encoder(const char *path, const char *spec)
+int FFMPEG::open_encoder(const char *type, const char *spec)
{
Asset *asset = file_base->asset;
AVDictionary *sopts = 0;
av_dict_copy(&sopts, opts, 0);
char option_path[BCTEXTLEN];
- set_option_path(option_path, "%s/%s.opts", path, path);
+ set_option_path(option_path, "%s/%s.opts", type, type);
read_options(option_path, sopts);
- get_option_path(option_path, path, spec);
+ get_option_path(option_path, type, spec);
char format_name[BCSTRLEN], codec_name[BCTEXTLEN];
char bsfilter[BCSTRLEN], bsargs[BCTEXTLEN];
- if( read_options(option_path, format_name, codec_name, bsfilter, bsargs, sopts) ) {
- fprintf(stderr, "FFMPEG::open_encoder: read options failed %s:%s\n",
+ if( get_encoder(option_path, format_name, codec_name, bsfilter, bsargs) ) {
+ eprintf("FFMPEG::open_encoder: get_encoder failed %s:%s\n",
option_path, filename);
return 1;
}
const AVCodecDescriptor *codec_desc = 0;
AVCodec *codec = avcodec_find_encoder_by_name(codec_name);
if( !codec ) {
- fprintf(stderr, "FFMPEG::open_encoder: cant find codec %s:%s\n",
+ eprintf("FFMPEG::open_encoder: cant find codec %s:%s\n",
codec_name, filename);
ret = 1;
}
if( !ret ) {
codec_desc = avcodec_descriptor_get(codec->id);
if( !codec_desc ) {
- fprintf(stderr, "FFMPEG::open_encoder: unknown codec %s:%s\n",
+ eprintf("FFMPEG::open_encoder: unknown codec %s:%s\n",
codec_name, filename);
ret = 1;
}
if( !ret ) {
st = avformat_new_stream(fmt_ctx, 0);
if( !st ) {
- fprintf(stderr, "FFMPEG::open_encoder: cant create stream %s:%s\n",
+ eprintf("FFMPEG::open_encoder: cant create stream %s:%s\n",
codec_name, filename);
ret = 1;
}
switch( codec_desc->type ) {
case AVMEDIA_TYPE_AUDIO: {
if( has_audio ) {
- fprintf(stderr, "FFMPEG::open_encoder: duplicate audio %s:%s\n",
+ eprintf("FFMPEG::open_encoder: duplicate audio %s:%s\n",
codec_name, filename);
ret = 1;
break;
}
has_audio = 1;
+ if( scan_options(asset->ff_audio_options, sopts) ) {
+ eprintf("FFMPEG::open_encoder: bad audio options %s:%s\n",
+ codec_name, filename);
+ ret = 1;
+ break;
+ }
+ if( asset->ff_audio_bitrate > 0 ) {
+ char arg[BCSTRLEN];
+ sprintf(arg, "%d", asset->ff_audio_bitrate);
+ av_dict_set(&sopts, "b", arg, 0);
+ }
int aidx = ffaudio.size();
int idx = aidx + ffvideo.size();
FFAudioStream *aud = new FFAudioStream(this, st, idx);
ctx->channel_layout = av_get_default_channel_layout(ctx->channels);
ctx->sample_rate = check_sample_rate(codec, asset->sample_rate);
if( !ctx->sample_rate ) {
- fprintf(stderr, "FFMPEG::open_audio_encode:"
+ eprintf("FFMPEG::open_audio_encode:"
" check_sample_rate failed %s\n", filename);
ret = 1;
break;
break; }
case AVMEDIA_TYPE_VIDEO: {
if( has_video ) {
- fprintf(stderr, "FFMPEG::open_encoder: duplicate video %s:%s\n",
+ eprintf("FFMPEG::open_encoder: duplicate video %s:%s\n",
codec_name, filename);
ret = 1;
break;
}
has_video = 1;
+ if( scan_options(asset->ff_video_options, sopts) ) {
+ eprintf("FFMPEG::open_encoder: bad video options %s:%s\n",
+ codec_name, filename);
+ ret = 1;
+ break;
+ }
+ if( asset->ff_video_bitrate > 0 ) {
+ char arg[BCSTRLEN];
+ sprintf(arg, "%d", asset->ff_video_bitrate);
+ av_dict_set(&sopts, "b", arg, 0);
+ }
+ else if( asset->ff_video_quality > 0 ) {
+ ctx->global_quality = asset->ff_video_quality * FF_QP2LAMBDA;
+ ctx->qmin = ctx->qmax = asset->ff_video_quality;
+ ctx->mb_lmin = ctx->qmin * FF_QP2LAMBDA;
+ ctx->mb_lmax = ctx->qmax * FF_QP2LAMBDA;
+ ctx->flags |= CODEC_FLAG_QSCALE;
+ char arg[BCSTRLEN];
+ av_dict_set(&sopts, "flags", "+qscale", 0);
+ sprintf(arg, "%d", asset->ff_video_quality);
+ av_dict_set(&sopts, "qscale", arg, 0);
+ sprintf(arg, "%d", ctx->global_quality);
+ av_dict_set(&sopts, "global_quality", arg, 0);
+ }
int vidx = ffvideo.size();
int idx = vidx + ffaudio.size();
FFVideoStream *vid = new FFVideoStream(this, st, idx);
ctx->pix_fmt = codec->pix_fmts ? codec->pix_fmts[0] : AV_PIX_FMT_YUV420P;
AVRational frame_rate = check_frame_rate(codec, vid->frame_rate);
if( !frame_rate.num || !frame_rate.den ) {
- fprintf(stderr, "FFMPEG::open_audio_encode:"
+ eprintf("FFMPEG::open_audio_encode:"
" check_frame_rate failed %s\n", filename);
ret = 1;
break;
vid->writing = -1;
break; }
default:
- fprintf(stderr, "FFMPEG::open_encoder: not audio/video, %s:%s\n",
+ eprintf("FFMPEG::open_encoder: not audio/video, %s:%s\n",
codec_name, filename);
ret = 1;
}
ret = avcodec_open2(st->codec, codec, &sopts);
if( ret < 0 ) {
ff_err(ret,"FFMPEG::open_encoder");
- fprintf(stderr, "FFMPEG::open_encoder: open failed %s:%s\n",
+ eprintf("FFMPEG::open_encoder: open failed %s:%s\n",
codec_name, filename);
ret = 1;
}
FFAudioStream *aud = ffaudio[aidx];
if( aud->load(pos, len) < len ) return -1;
int ch = astrm_index[chn].st_ch;
- return aud->history.read(samples,len,ch);
+ return aud->read(samples,len,ch);
}
int FFMPEG::decode(int layer, int64_t pos, VFrame *vframe)
#include <string.h>
#include "arraylist.h"
-#include "linklist.h"
#include "asset.inc"
#include "bccmodels.h"
+#include "bcwindowbase.inc"
+#include "condition.h"
#include "cstrdup.h"
+#include "linklist.h"
#include "ffmpeg.inc"
#include "filebase.inc"
#include "fileffmpeg.inc"
+#include "mutex.h"
+#include "thread.h"
#include "vframe.inc"
extern "C" {
void dequeue();
};
-class FFAudioHistory {
-public:
- float *inp, *outp, *bfr, *lmt;
- long sz, bsz;
- int nch;
-
- FFAudioHistory();
- ~FFAudioHistory();
- void reserve(long sz, int nch);
- void realloc(long sz, int nch);
- long used();
- long avail();
- void reset();
- void iseek(int64_t ofs);
- float *get_outp(int len);
- int64_t get_inp(int len);
- int write(const float *fp, long len);
- int copy(float *fp, long len);
- int zero(long len);
- int read(double *dp, long len, int ch);
- int write(const double *dp, long len, int ch);
-};
-
class FFStream {
public:
FFStream(FFMPEG *ffmpeg, AVStream *st, int idx);
};
class FFAudioStream : public FFStream {
+ float *inp, *outp, *bfr, *lmt;
+ long sz;
+ int nch;
+
+ int read(float *fp, long len);
+ void realloc(long sz, int nch, long len);
+ void realloc(long sz, int nch);
+ void reserve(long sz, int nch);
+ long used();
+ long avail();
+ void reset();
+ void iseek(int64_t ofs);
+ float *get_outp(int len);
+ int64_t put_inp(int len);
+ int write(const float *fp, long len);
+ int zero(long len);
+ int write(const double *dp, long len, int ch);
public:
FFAudioStream(FFMPEG *ffmpeg, AVStream *strm, int idx);
virtual ~FFAudioStream();
- int load_history(float *&bfr, int len);
+ int load_history(uint8_t **data, int len);
int decode_frame(AVFrame *frame, int &got_frame);
int create_filter(const char *filter_spec,
AVCodecContext *src_ctx, AVCodecContext *sink_ctx);
int encode_activate();
int nb_samples();
- void alloc_history(int len);
- void reserve_history(int len);
- void append_history(const float *fp, int len);
- void zero_history(int len);
int64_t load_buffer(double ** const sp, int len);
- float *get_history(int len);
int in_history(int64_t pos);
+ int read(double *dp, long len, int ch);
int init_frame(AVFrame *frame);
int load(int64_t pos, int len);
int64_t seek_pos, curr_pos;
int64_t length;
- FFAudioHistory history;
SwrContext *resample_context;
int aud_bfr_sz;
float *aud_bfr;
static void set_option_path(char *path, const char *fmt, ...);
static void get_option_path(char *path, const char *type, const char *spec);
- int check_option(const char *path, char *spec);
- const char *get_file_format();
+ int get_format(char *format, const char *path, char *spec);
+ int get_file_format();
int scan_option_line(char *cp,char *tag,char *val);
- int read_options(const char *options, char *format, char *codec,
- char *bsfilter, char *bsargs, AVDictionary *&opts);
- int read_options(FILE *fp, const char *options,
- char *format, char *codec, AVDictionary *&opts);
+ int get_encoder(const char *options,
+ char *format, char *codec, char *bsfilter, char *bsargs);
+ int get_encoder(FILE *fp,
+ char *format, char *codec, char *bsfilter, char *bsargs);
int read_options(const char *options, AVDictionary *&opts);
- int read_options(FILE *fp, const char *options, AVDictionary *&opts, int no=0);
+ int scan_options(const char *options, AVDictionary *&opts);
+ int read_options(FILE *fp, const char *options, AVDictionary *&opts);
int load_options(const char *options, AVDictionary *&opts);
void set_loglevel(const char *ap);
static double to_secs(int64_t time, AVRational time_base);
int init_decoder(const char *filename);
int open_decoder();
int init_encoder(const char *filename);
- int open_encoder(const char *path, const char *spec);
+ int open_encoder(const char *type, const char *spec);
int close_encoder();
int total_audio_channels();
#include "pluginserver.h"
#include "preferences.h"
#include "samples.h"
-#include "stringfile.h"
#include "vframe.h"
//suppress noref warning
buffer,
buffer_size);
delete [] buffer;
- delete [] string;
+ free(string);
//printf("File::open_file %d\n", __LINE__);
// Get the updated asset from the fork
// Reopen file with correct parser and get header.
if(file->open_file(rd, wr)) {
- delete file;
+ delete file; file = 0;
return FILE_NOT_FOUND;
}
case FILE_VMPEG: return "m2v";
case FILE_VORBIS: return "ogg";
case FILE_WAV: return "wav";
- case FILE_FFMPEG: return "media";
+ case FILE_FFMPEG: return "ffmpg";
}
return 0;
}
}
+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)
return BC_YUV420P;
}
+static void load_options(const char *path, char *bfr, int len)
+{
+ *bfr = 0;
+ FILE *fp = fopen(path, "r");
+ if( !fp ) return;
+ fgets(bfr, len, fp); // skip hdr
+ len = fread(bfr, 1, len-1, fp);
+ if( len < 0 ) len = 0;
+ bfr[len] = 0;
+ fclose(fp);
+}
//======
extern void get_exe_path(char *result); // from main.C
this->parent_window = parent_window;
this->asset = asset;
preset_popup = 0;
+
+ bitrate = 0;
+ audio_options = 0;
}
FFMPEGConfigAudio::~FFMPEGConfigAudio()
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 ) ext = name;
+ else if( !strcmp("opts", ++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);
+ 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();
}
}
+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)
{
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);
+ load_options(option_path, asset->ff_audio_options,
+ sizeof(asset->ff_audio_options));
+ popup->audio_options->update(asset->ff_audio_options);
return 1;
}
this->parent_window = parent_window;
this->asset = asset;
preset_popup = 0;
+
+ bitrate = 0;
+ video_options = 0;
}
FFMPEGConfigVideo::~FFMPEGConfigVideo()
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 ) ext = name;
+ else if( !strcmp("opts", ++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);
+ 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();
}
}
+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)
{
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);
+ load_options(option_path, asset->ff_video_options,
+ sizeof(asset->ff_video_options));
+ popup->video_options->update(asset->ff_video_options);
return 1;
}
#include <unistd.h>
#include <string.h>
+class FileFFMPEG;
+class FFMpegConfigNum;
+class FFMpegAudioNum;
+class FFMpegVideoNum;
+class FFOkButton;
+class FFOptions;
+class FFMPEGConfigAudio;
+class FFAudioOptions;
+class FFMPEGConfigAudioPopup;
+class FFMPEGConfigAudioToggle;
+class FFMPEGConfigVideo;
+class FFVideoOptions;
+class FFMPEGConfigVideoPopup;
+class FFMPEGConfigVideoToggle;
class FileFFMPEG : public FileBase
{
int select_audio_stream(Asset *asset, int astream);
};
+class FFMpegConfigNum : public BC_TumbleTextBox
+{
+public:
+ FFMpegConfigNum(BC_Window *window, int x, int y,
+ char *title_text, int *output);
+ ~FFMpegConfigNum();
+
+ void create_objects();
+ int handle_event();
+ int *output;
+ BC_Window *window;
+ BC_Title *title;
+ char *title_text;
+ int x, y;
+};
+
+class FFMpegAudioNum : public FFMpegConfigNum
+{
+public:
+ FFMpegAudioNum(BC_Window *window, int x, int y, char *title_text, int *output);
+ ~FFMpegAudioNum() {}
+
+ FFMPEGConfigAudio *window() { return (FFMPEGConfigAudio *)FFMpegConfigNum::window; }
+};
+
+class FFMpegAudioBitrate : public FFMpegAudioNum
+{
+public:
+ FFMpegAudioBitrate(BC_Window *window, int x, int y, char *title_text, int *output)
+ : FFMpegAudioNum(window, x, y, title_text, output) {}
+ int handle_event();
+};
+
+class FFMpegVideoNum : public FFMpegConfigNum
+{
+public:
+ FFMpegVideoNum(BC_Window *window, int x, int y, char *title_text, int *output);
+ ~FFMpegVideoNum() {}
+
+ FFMPEGConfigVideo *window() { return (FFMPEGConfigVideo *)FFMpegConfigNum::window; }
+};
+
+class FFMpegVideoBitrate : public FFMpegVideoNum
+{
+public:
+ FFMpegVideoBitrate(BC_Window *window, int x, int y, char *title_text, int *output)
+ : FFMpegVideoNum(window, x, y, title_text, output) {}
+ int handle_event();
+};
+
+class FFMpegVideoQuality : public FFMpegVideoNum
+{
+public:
+ FFMpegVideoQuality(BC_Window *window, int x, int y, char *title_text, int *output)
+ : FFMpegVideoNum(window, x, y, title_text, output) {}
+ int handle_event();
+};
class FFMPEGConfigAudio : public BC_Window
{
ArrayList<BC_ListBoxItem*> presets;
FFMPEGConfigAudioPopup *preset_popup;
+ FFMpegAudioBitrate *bitrate;
+ FFAudioOptions *audio_options;
BC_WindowBase *parent_window;
Asset *asset;
};
+class FFAudioOptions : public BC_TextBox
+{
+public:
+ FFAudioOptions(FFMPEGConfigAudio *audio_popup,
+ int x, int y, int w, int rows, int size, char *text);
+ int handle_event();
+
+ FFMPEGConfigAudio *audio_popup;
+};
+
class FFMPEGConfigAudioPopup : public BC_PopupTextBox
{
ArrayList<BC_ListBoxItem*> presets;
FFMPEGConfigVideoPopup *preset_popup;
BC_WindowBase *parent_window;
+ FFMpegVideoBitrate *bitrate;
+ FFMpegVideoQuality *quality;
+ FFVideoOptions *video_options;
Asset *asset;
};
+class FFVideoOptions : public BC_TextBox
+{
+public:
+ FFVideoOptions(FFMPEGConfigVideo *video_popup,
+ int x, int y, int w, int rows, int size, char *text);
+ int handle_event();
+
+ FFMPEGConfigVideo *video_popup;
+};
+
class FFMPEGConfigVideoPopup : public BC_PopupTextBox
{
public:
table.save_string(string);
int buffer_size = strlen(string) + 1;
send_result(result, (unsigned char*)string, buffer_size);
- delete [] string;
+ free(string);
break;
}
// Set decoding parameter
quicktime_set_parameter(fd, "divx_use_deblocking", &asset->divx_use_deblocking);
// Set timecode offset
- quicktime_set_frame_start(fd, asset->tcstart);
+ quicktime_set_frame_start(fd, 0);
return 0;
}
dv_parse_packs(tmp_decoder, frame->get_data());
dv_get_timestamp(tmp_decoder, tc);
// printf("Timestamp %s\n", tc);
-
- float seconds = Units::text_to_seconds(tc,
- 1, // Use 1 as sample rate, doesn't matter
- TIME_HMSF, asset->frame_rate, 0);
- // Set tcstart if it hasn't been set yet, this is a bit problematic
- // FIXME: The problem arises if file has nonzero tcstart and user
- // manualy sets it to zero - every time project will load it will
- // be set to nonzero
- if (asset->tcstart == 0)
- asset->tcstart = int64_t(seconds * asset->frame_rate);
}
delete frame;
dv_decoder_free(tmp_decoder);
#include "bcsignals.h"
#include "file.inc"
+#include "filesystem.h"
+#include "ffmpeg.h"
#include "formatpopup.h"
#include "language.h"
#include "pluginserver.h"
FormatPopup::~FormatPopup()
{
- for(int i = 0; i < format_items.total; i++) delete format_items.values[i];
+ format_items.remove_all_objects();
}
int FormatPopup::handle_event()
{
return 0;
}
+
+
+FFMPEGPopup::FFMPEGPopup(ArrayList<PluginServer*> *plugindb, int x, int y)
+ : BC_ListBox(x, y, 50, 200, LISTBOX_TEXT, 0, 0, 0, 1, 0, 1)
+{
+ this->plugindb = plugindb;
+ set_tooltip(_("Set ffmpeg file type"));
+}
+
+void FFMPEGPopup::create_objects()
+{
+ static const char *dirs[] = { "/audio", "/video", };
+ for( int i=0; i<(int)(sizeof(dirs)/sizeof(dirs[0])); ++i ) {
+ FileSystem fs;
+ char option_path[BCTEXTLEN];
+ FFMPEG::set_option_path(option_path, dirs[i]);
+ fs.update(option_path);
+ int total_files = fs.total_files();
+ for( int j=0; j<total_files; ++j ) {
+ const char *name = fs.get_entry(j)->get_name();
+ const char *ext = strrchr(name,'.');
+ if( !ext ) ext = name;
+ else if( !strcmp("opts", ++ext) ) continue;
+ int k = ffmpeg_types.size();
+ while( --k >= 0 && strcmp(ffmpeg_types[k]->get_text(), ext) );
+ if( k >= 0 ) continue;
+ ffmpeg_types.append(new BC_ListBoxItem(ext));
+ }
+ }
+
+ update(&ffmpeg_types, 0, 0, 1);
+}
+
+FFMPEGPopup::~FFMPEGPopup()
+{
+ ffmpeg_types.remove_all_objects();
+}
+
+int FFMPEGPopup::handle_event()
+{
+ return 0;
+}
+
+
};
+class FFMPEGPopup : public BC_ListBox
+{
+public:
+ FFMPEGPopup(ArrayList<PluginServer*> *plugindb, int x, int y);
+ ~FFMPEGPopup();
+
+ void create_objects();
+ virtual int handle_event();
+ ArrayList<PluginServer*> *plugindb;
+ ArrayList<BC_ListBoxItem*> ffmpeg_types;
+};
+
+
window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:")));
x += 90;
- window->add_subwindow(format_text = new BC_TextBox(x, y, 200, 1,
+ window->add_subwindow(format_text = new BC_TextBox(x, y, 180, 1,
File::formattostr(asset->format)));
x += format_text->get_w();
//printf("FormatTools::create_objects %d %p\n", __LINE__, window);
window->add_subwindow(format_button = new FormatFormat(x, y, this));
format_button->create_objects();
+ x += format_button->get_w() + 5;
+ window->add_subwindow(ffmpeg_type = new FFMpegType(x, y, 50, 1, asset->fformat));
+ x += ffmpeg_type->get_w();
+ window->add_subwindow(format_ffmpeg = new FormatFFMPEG(x, y, this));
+ format_ffmpeg->create_objects();
x = init_x;
y += format_button->get_h() + 10;
else
video_switch->enable();
}
+ if( asset->format == FILE_FFMPEG ) {
+ ffmpeg_type->show();
+ format_ffmpeg->show();
+ }
+ else {
+ ffmpeg_type->hide();
+ format_ffmpeg->hide();
+ }
}
int FormatTools::handle_event()
if(need_extension)
{
char *ptr1 = ptr;
- extension_ptr = extensions.get(0);
+ extension_ptr = asset->format != FILE_FFMPEG ?
+ extensions.get(0) : asset->fformat;
while(*extension_ptr != 0 && *extension_ptr != '/')
*ptr1++ = *extension_ptr++;
*ptr1 = 0;
int FormatFormat::handle_event()
{
- if(get_selection(0, 0) >= 0)
- {
+ BC_ListBoxItem *selection = get_selection(0, 0);
+ if( selection ) {
int new_format = File::strtoformat(format->plugindb, get_selection(0, 0)->get_text());
// if(new_format != format->asset->format)
{
format->asset->format = new_format;
- format->format_text->update(get_selection(0, 0)->get_text());
+ format->format_text->update(selection->get_text());
format->update_extension();
format->close_format_windows();
format->update_format();
}
+FormatFFMPEG::FormatFFMPEG(int x, int y, FormatTools *format)
+ : FFMPEGPopup(format->plugindb, x, y)
+{
+ this->format = format;
+}
+
+FormatFFMPEG::~FormatFFMPEG()
+{
+}
+
+int FormatFFMPEG::handle_event()
+{
+ BC_ListBoxItem *selection = get_selection(0, 0);
+ if( selection ) {
+ char *text = get_selection(0, 0)->get_text();
+ format->ffmpeg_type->update(text);
+ strcpy(format->asset->fformat, text);
+ strcpy(format->asset->ff_audio_options, "");
+ strcpy(format->asset->ff_video_options, "");
+ format->update_extension();
+ format->close_format_windows();
+ format->update_format();
+ }
+ return 1;
+}
+
+
+
FormatChannels::FormatChannels(int x, int y, FormatTools *format)
: BC_TextBox(x, y, 100, 1, format->asset->channels)
class FormatPathButton;
class FormatPathText;
class FormatFormat;
+class FormatFFMPEG;
+class FFMpegType;
class FormatAudio;
class FormatVideo;
class FormatMultiple;
BC_Title *format_title;
FormatFormat *format_button;
BC_TextBox *format_text;
+ FormatFFMPEG *format_ffmpeg;
+ FFMpegType *ffmpeg_type;
BC_ITumbler *channels_tumbler;
BC_Title *audio_title;
FormatTools *format;
};
+class FormatFFMPEG : public FFMPEGPopup
+{
+public:
+ FormatFFMPEG(int x, int y, FormatTools *format);
+ ~FormatFFMPEG();
+
+ int handle_event();
+ FormatTools *format;
+// squash show/hide window
+ int show_window(int flush=1) { return 0; }
+ int hide_window(int flush=1) { return 0; }
+ int show(int flush=1) { return BC_SubWindow::show_window(flush); }
+ int hide(int flush=1) { return BC_SubWindow::hide_window(flush); }
+};
+
+class FFMpegType : public BC_TextBox
+{
+public:
+ FFMpegType(int x, int y, int w, int h, const char *text)
+ : BC_TextBox(x, y, w, h, text) {}
+ ~FFMpegType() {}
+// squash show/hide window
+ int show_window(int flush=1) { return 0; }
+ int hide_window(int flush=1) { return 0; }
+ int show(int flush=1) { return BC_SubWindow::show_window(flush); }
+ int hide(int flush=1) { return BC_SubWindow::hide_window(flush); }
+};
+
class FormatAParams : public BC_Button
{
public:
#include "patchbay.h"
#include "recordlabel.h"
#include "mainsession.h"
-#include "stringfile.h"
#include "theme.h"
#include "timebar.h"
#include <string.h>
virtual int draw_framerate(int flush) { return 0; }
// update rendering rates
virtual void update_rates() {}
- virtual void show_window(int flush) { BC_SubWindow::show_window(flush); }
+ virtual int show_window(int flush) { return BC_SubWindow::show_window(flush); }
PreferencesWindow *pwindow;
MWindow *mwindow;
}
-void RecordPrefs::show_window(int flush)
+int RecordPrefs::show_window(int flush)
{
PreferencesDialog::show_window(flush);
if( pwindow->thread->edl->session->recording_format->format == FILE_MPEG &&
pwindow->thread->edl->session->vconfig_in->driver == CAPTURE_DVB &&
pwindow->thread->edl->session->aconfig_in->driver == AUDIO_DVB )
- realtime_toc->show_window(flush);
- else
- realtime_toc->hide_window(flush);
+ return realtime_toc->show_window(flush);
+ return realtime_toc->hide_window(flush);
}
~RecordPrefs();
void create_objects();
- void show_window(int flush);
+ int show_window(int flush);
FormatTools *recording_format;
RecordRealtimeTOC *realtime_toc;
if(debug) printf("Render::handle_close_event %d\n", __LINE__);
}
-PRINT_TRACE
+//PRINT_TRACE
save_defaults(asset);
-PRINT_TRACE
+//PRINT_TRACE
mwindow->save_defaults();
-PRINT_TRACE
+//PRINT_TRACE
if(!format_error && !result)
{
if(!result) start_render();
if(debug) printf("Render::handle_close_event %d\n", __LINE__);
}
-PRINT_TRACE
+//PRINT_TRACE
}
server->preferences->save_defaults(&defaults);
defaults.save_string(string);
write_string(string);
-
- delete [] string;
+ free(string);
}
void RenderFarmServerThread::send_asset()
1,
1);
defaults.save_string(string1);
-
FileXML file;
server->default_asset->write(&file, 0, 0);
file.terminate_string();
write_string(string1);
write_string(file.string());
- delete [] string1;
+ free(string1);
}
#include "bctimer.h"
#include "clip.h"
#include "format.inc"
-#include "stringfile.h"
#include "undostack.h"
#include <string.h>
dvd ac3
-b 448000
maxrate 9000000
minrate 0
bufsize 1835008
mp4 libfdk_aac | aac_adtstoasc
-b 192000
strict -2
r 30000/1001
pix_fmt yuv420p
g 18
-b 6000000
maxrate 9000000
minrate 0
bufsize 1835008
mpeg mpeg2video
-b=4000000
HAVE_AVIFILE := n
HAVE_FIREWIRE := y
HAVE_OSS := y
-STATIC_LIBRARIES := y
+STATIC_LIBRARIES := n
OBJDIR := $(shell uname --machine)
$(OBJDIR)/mutex.o \
$(OBJDIR)/rotateframe.o \
$(OBJDIR)/sema.o \
- $(OBJDIR)/stringfile.o \
$(OBJDIR)/thread.o \
$(OBJDIR)/testobject.o \
$(OBJDIR)/bctimer.o \
#include "bcsignals.h"
#include "filesystem.h"
#include "format.inc"
-#include "stringfile.h"
BC_Hash::BC_Hash()
{
}
}
-int BC_Hash::load()
-{
- StringFile stringfile(filename);
- load_stringfile(&stringfile);
- return 0;
-}
-
-void BC_Hash::load_stringfile(StringFile *file)
+int BC_Hash::load_file(FILE *fp)
{
- char arg1[1024], arg2[1024];
+ char line[4096];
+ int done = 0, ch = -1;
total = 0;
- while(file->get_pointer() < file->get_length())
- {
- file->readline(arg1, arg2);
+
+ while( !done ) {
+ char *bp = line, *ep = bp + sizeof(line);
+ if( !fgets(bp, ep-bp, fp) ) break;
+ // skip ws (indent)
+ while( bp < ep && *bp == ' ' ) ++bp;
+ if( bp >= ep || !*bp || *bp == '\n' ) continue;
+ char *title = bp;
+ // span to ws
+ while( bp < ep && *bp && *bp != ' ' && *bp != '\n' ) ++bp;
+ if( bp >= ep || title == bp ) continue;
+ int title_len = bp - title;
+ // skip blank seperator
+ if( *bp++ != ' ' ) continue;
reallocate_table(total + 1);
- names[total] = new char[strlen(arg1) + 1];
- values[total] = new char[strlen(arg2) + 1];
- strcpy(names[total], arg1);
- strcpy(values[total], arg2);
+ char *tp = new char[title_len + 1];
+ names[total] = tp;
+ while( --title_len >= 0 ) *tp++ = *title++;
+ *tp = 0;
+ // accumulate value (+ continued lines)
+ char *value = bp;
+ while( bp < ep && !done ) {
+ while( bp < ep && *bp && *bp != '\n' ) ++bp;
+ if( bp >= ep || !*bp ) break;
+ if( (ch=fgetc(fp)) < 0 ) break;
+ if( ch != '+' ) { ungetc(ch, fp); break; }
+ *bp++ = '\n';
+ done = !fgets(bp, ep-bp, fp);
+ }
+ int value_len = bp - value;
+ char *vp = new char[value_len + 1];
+ values[total] = vp;
+ while( --value_len >= 0 ) *vp++ = *value++;
+ *vp = 0;
total++;
}
+ return 0;
}
-void BC_Hash::save_stringfile(StringFile *file)
+int BC_Hash::load()
{
- for(int i = 0; i < total; i++)
- {
- file->writeline(names[i], values[i], 0);
- }
+ FILE *fp = fopen(filename, "r");
+ if( !fp ) return 1;
+ int ret = load_file(fp);
+ fclose(fp);
+ return ret;
}
-int BC_Hash::save()
+int BC_Hash::save_file(FILE *fp)
{
- StringFile stringfile;
- save_stringfile(&stringfile);
- stringfile.write_to_file(filename);
+ for(int i = 0; i < total; i++) {
+ fputs(names[i], fp);
+ char *vp = values[i];
+ char *bp = vp;
+ fputc(' ',fp);
+ while( (vp=strchr(vp, '\n')) ) {
+ while( bp < vp ) fputc(*bp++,fp);
+ fputc('\n',fp); fputc('+',fp);
+ ++bp; ++vp;
+ }
+ while( *bp ) fputc(*bp++,fp);
+ fputc('\n', fp);
+ }
return 0;
}
-int BC_Hash::load_string(const char *string)
+int BC_Hash::save()
+{
+ FILE *fp = fopen(filename,"w");
+ if( !fp ) return 1;
+ int ret = save_file(fp);
+ fclose(fp);
+ return ret;
+}
+
+int BC_Hash::load_string(const char *bfr)
{
- StringFile stringfile;
- stringfile.read_from_string(string);
- load_stringfile(&stringfile);
- return 0;
+ FILE *fp = fmemopen((void*)bfr, strlen(bfr), "r");
+ if( !fp ) return 1;
+ int ret = load_file(fp);
+ fclose(fp);
+ return ret;
}
-int BC_Hash::save_string(char* &string)
+int BC_Hash::save_string(char *&bfr)
{
- StringFile stringfile;
- save_stringfile(&stringfile);
- string = new char[stringfile.get_length() + 1];
- memcpy(string, stringfile.string, stringfile.get_length() + 1);
- return 0;
+ size_t bsz = 0;
+ FILE *fp = open_memstream(&bfr, &bsz);
+ if( !fp ) return 1;
+ int ret = save_file(fp);
+ fclose(fp);
+ return ret;
}
#include "bcwindowbase.inc"
#include "bctextbox.inc"
-#include "stringfile.inc"
#include "units.h"
BC_Hash(const char *filename);
virtual ~BC_Hash();
+ int load_file(FILE *fp);
int load(); // load from disk file
+ int save_file(FILE *fp);
int save(); // save to disk file
int load_string(const char *string); // load from string
int save_string(char* &string); // save to new string
- void save_stringfile(StringFile *file);
- void load_stringfile(StringFile *file);
int update(const char *name, double value); // update a value if it exists
int update(const char *name, float value); // update a value if it exists
int update(const char *name, int32_t value); // update a value if it exists
return textbox->get_h();
}
+void BC_TumbleTextBox::disable()
+{
+ if( !get_enabled() ) return;
+ tumbler->hide_window(0);
+ return textbox->disable();
+}
+
+void BC_TumbleTextBox::enable()
+{
+ if( get_enabled() ) return;
+ tumbler->show_window(0);
+ return textbox->enable();
+}
+
+int BC_TumbleTextBox::get_enabled()
+{
+ return textbox->get_enabled();
+}
+
int BC_TumbleTextBox::handle_event()
{
return 1;
int get_y();
int get_w();
int get_h();
+ void disable();
+ void enable();
+ int get_enabled();
void reposition_window(int x, int y);
void set_boundaries(int64_t min, int64_t max);
void set_boundaries(float min, float max);
int get_color(int64_t color);
// return the currently selected color
int64_t get_color();
- int show_window(int flush = 1);
- int hide_window(int flush = 1);
+ virtual int show_window(int flush = 1);
+ virtual int hide_window(int flush = 1);
int get_hidden();
int get_video_on();
// Shouldn't deference a pointer to delete a window if a parent is
virtual int get_h();
virtual int get_x();
virtual int get_y();
- virtual int reposition_widgets(){ printf("foo1"); return 0; }
int get_root_w(int lock_display);
int get_root_h(int lock_display);
XineramaScreenInfo *get_xinerama_info(int screen);
+++ /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 "stringfile.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-StringFile::StringFile(size_t length)
-{
- pointer = 0;
- if(length == 0)
- {
- this->length = 100000;
- }
- else
- {
- this->length = length;
- }
- string = new char[this->length + 1];
- available = this->length;
-}
-
-StringFile::StringFile(const char *filename)
-{
- FILE *in = fopen(filename, "rb");
- if( in )
- {
- fseek(in, 0, SEEK_END);
- length = ftell(in);
- available = length;
- fseek(in, 0, SEEK_SET);
- string = new char[length + 5];
-
- (void)fread(string, length, 1, in);
- for(int i = 0; i < 5; i++) string[length + i] = 0;
- fclose(in);
- }
- else
- {
- //printf("File not found: %s\n", filename);
- length = 0;
- available = 1;
- string = new char[1];
- string[0] = 0;
- }
-
- pointer = 0;
-}
-
-StringFile::~StringFile()
-{
- delete [] string;
-}
-
-int StringFile::write_to_file(const char *filename)
-{
- FILE *out = fopen(filename, "wb");
- if( out )
- {
- fwrite(string, pointer, 1, out);
- }
- else
- {
-// printf("Couldn't open %s for writing.\n", filename);
- return 1;
- }
- fclose(out);
- return 0;
-}
-
-int StringFile::read_from_string(const char *string)
-{
- int i;
-
- delete [] this->string;
- length = strlen(string);
- available = length;
- this->string = new char[length + 5];
- strcpy(this->string, string);
- for(i = 0; i < 5; i++) this->string[length + i] = 0;
- return 0;
-}
-
-size_t StringFile::get_length()
-{
- return strlen(string);
-}
-
-size_t StringFile::get_pointer()
-{
- return pointer;
-}
-
-int StringFile::readline(char *arg2)
-{
- readline(string1, arg2);
- return 0;
-}
-
-int StringFile::readline()
-{
- readline(string1, string1);
- return 0;
-}
-
-int StringFile::readline(float *arg2)
-{
- readline(string1, arg2);
- return 0;
-}
-
-int StringFile::readline(int *arg2)
-{
- readline(string1, arg2);
- return 0;
-}
-
-int StringFile::readline(long *arg2)
-{
- readline(string1, arg2);
- return 0;
-}
-
-int StringFile::readline(Freq *arg2)
-{
- readline(string1, &(arg2->freq));
- return 0;
-}
-
-int StringFile::readline(char *arg1, char *arg2)
-{
- int i, len, max;
- len = 0; max = 1024;
-
- while(string[pointer] == ' ') pointer++; // skip indent
- arg1[0] = 0; arg2[0] = 0;
-
- for(i = 0; string[pointer] != ' ' && string[pointer] != '\n' && len < max; i++, pointer++)
- { // get title
- arg1[i] = string[pointer];
- len++;
- }
- arg1[i] = 0;
-
- if(string[pointer] != '\n')
- { // get value
- pointer++; // skip space
- for(i = 0; string[pointer] != '\n' && len < max; i++, pointer++)
- {
- arg2[i] = string[pointer];
- len++;
- }
- arg2[i] = 0;
- }
- pointer++; // skip eoln
- return 0;
-}
-
-int StringFile::backupline()
-{
- while(string[pointer] != 10 && pointer > 0)
- {
- pointer--; // first eoln
- }
- if(string[pointer] == 10) pointer--; // skip eoln
-
- while(string[pointer] != 10 && pointer > 0)
- {
- pointer--; // second eoln
- }
-
- if(string[pointer] == 10) pointer++; // skip eoln
- return 0;
-}
-
-int StringFile::readline(char *arg1, long *arg2)
-{
- readline(arg1, string1);
- *arg2 = atol(string1);
- return 0;
-}
-
-int StringFile::readline(char *arg1, int *arg2)
-{
- long arg;
- readline(arg1, &arg);
- *arg2 = (int)arg;
- return 0;
-}
-
-int StringFile::readline(char *arg1, float *arg2)
-{
- readline(arg1, string1);
- *arg2 = atof(string1);
- return 0;
-}
-
-int StringFile::writeline(char *arg1, int indent)
-{
-// reallocate the string
- int len = strlen(arg1);
- if( (len + indent) > (int)(available - pointer) ) {
- char *newstring = new char[available * 2];
- strcpy(newstring, string);
- delete string;
- available *= 2;
- length *= 2;
- string = newstring;
- }
-
- for(int i = 0; i < indent; i++) string[pointer++] = ' ';
- strcpy(&string[pointer], arg1);
- pointer += len;
- return 0;
-}
-
-int StringFile::writeline(char *arg1, char *arg2, int indent)
-{
- sprintf(string1, "%s %s\n", arg1, arg2);
- writeline(string1, indent);
- return 0;
-}
-
-int StringFile::writeline(char *arg1, long arg2, int indent)
-{
- sprintf(string1, "%s %ld\n", arg1, arg2);
- writeline(string1, indent);
- return 0;
-}
-
-int StringFile::writeline(char *arg1, int arg2, int indent)
-{
- sprintf(string1, "%s %d\n", arg1, arg2);
- writeline(string1, indent);
- return 0;
-}
-
-int StringFile::writeline(char *arg1, float arg2, int indent)
-{
- sprintf(string1, "%s %f\n", arg1, arg2);
- writeline(string1, indent);
- return 0;
-}
-
-int StringFile::writeline(char *arg1, Freq arg2, int indent)
-{
- sprintf(string1, "%s %d\n", arg1, arg2.freq);
- writeline(string1, indent);
- return 0;
-}
+++ /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
- *
- */
-
-#ifndef STRINGFILE_H
-#define STRINGFILE_H
-
-
-// Line based reading and writing from text files or arrays.
-// Use for extracting databases.
-#include "units.h"
-
-class StringFile
-{
-public:
- StringFile(size_t length = 0);
- StringFile(const char *filename);
- virtual ~StringFile();
-
- int readline(); // read next line from string
- int readline(char *arg2); // read next line from string
- int readline(long *arg2); // read next line from string
- int readline(int *arg2); // read next line from string
- int readline(float *arg2); // read next line from string
- int readline(Freq *arg2); // read next line from string
-
- int readline(char *arg1, char *arg2); // read next line from string
- int readline(char *arg1, long *arg2); // read next line from string
- int readline(char *arg1, int *arg2); // read next line from string
- int readline(char *arg1, float *arg2); // read next line from string
- int writeline(char *arg1, int indent); // write next line to string
- int writeline(char *arg1, char *arg2, int indent); // write next line to string
- int writeline(char *arg1, long arg2, int indent); // write next line to string
- int writeline(char *arg1, int arg2, int indent); // write next line to string
- int writeline(char *arg1, float arg2, int indent); // write next line to string
- int writeline(char *arg1, Freq arg2, int indent); // write next line to string
- int backupline(); // move back one line
-
- size_t get_length();
- size_t get_pointer();
- int write_to_file(const char *filename);
- int read_from_string(const char *string);
-
- char *string;
- size_t pointer, length, available;
- char string1[1024]; // general purpose strings
-};
-
-#endif
+++ /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
- *
- */
-
-#ifndef STRINGFILE_INC
-#define STRINGFILE_INC
-
-class StringFile;
-
-#endif