X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fcinelerra%2Fffmpeg.C;h=68ff296d0013581d695f2bb713d75d4554f764eb;hb=91efd376233a15f6572e6f68d28a5bee69797e87;hp=16d6fe056c4e06c952ed062414a8017b68b4b0c0;hpb=fe44dc1d43f34e4440f4c398bbf2475a07f80ffc;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/cinelerra/ffmpeg.C b/cinelerra-5.0/cinelerra/ffmpeg.C index 16d6fe05..68ff296d 100644 --- a/cinelerra-5.0/cinelerra/ffmpeg.C +++ b/cinelerra-5.0/cinelerra/ffmpeg.C @@ -30,10 +30,16 @@ Mutex FFMPEG::fflock("FFMPEG::fflock"); -static void ff_err(int ret, const char *msg) +static void ff_err(int ret, const char *fmt, ...) { - char errmsg[BCSTRLEN]; av_strerror(ret, errmsg, sizeof(errmsg)); - fprintf(stderr,"%s: %s\n",msg, errmsg); + char msg[BCTEXTLEN]; + va_list ap; + va_start(ap, fmt); + vsnprintf(msg, sizeof(msg), fmt, ap); + va_end(ap); + char errmsg[BCSTRLEN]; + av_strerror(ret, errmsg, sizeof(errmsg)); + fprintf(stderr,_("%s err: %s\n"),msg, errmsg); } FFPacket::FFPacket() @@ -321,7 +327,7 @@ int FFStream::read_packet() if( ret >= 0 ) return 1; st_eof(1); if( ret == AVERROR_EOF ) return 0; - fprintf(stderr, "FFStream::read_packet: av_read_frame failed\n"); + ff_err(ret, "FFStream::read_packet: av_read_frame failed\n"); flushed = 1; return -1; } @@ -381,7 +387,7 @@ int FFStream::read_filter(AVFrame *frame) if( ret < 0 ) { if( ret == AVERROR(EAGAIN) ) return 0; if( ret == AVERROR_EOF ) { st_eof(1); return -1; } - fprintf(stderr, "FFStream::read_filter: av_buffersink_get_frame failed\n"); + ff_err(ret, "FFStream::read_filter: av_buffersink_get_frame failed\n"); return ret; } return 1; @@ -447,7 +453,7 @@ int FFAudioStream::load_history(uint8_t **data, int len) int ret = swr_convert(resample_context, (uint8_t**)&aud_bfr, aud_bfr_sz, (const uint8_t**)data, len); if( ret < 0 ) { - fprintf(stderr, "FFAudioStream::load_history: swr_convert failed\n"); + ff_err(ret, "FFAudioStream::load_history: swr_convert failed\n"); return -1; } samples = aud_bfr; @@ -463,7 +469,7 @@ int FFAudioStream::decode_frame(AVFrame *frame, int &got_frame) { int ret = avcodec_decode_audio4(st->codec, frame, &got_frame, ipkt); if( ret < 0 ) { - fprintf(stderr, "FFAudioStream::decode_frame: Could not read audio frame\n"); + ff_err(ret, "FFAudioStream::decode_frame: Could not read audio frame\n"); return -1; } return ret; @@ -512,7 +518,7 @@ int FFAudioStream::init_frame(AVFrame *frame) frame->sample_rate = ctx->sample_rate; int ret = av_frame_get_buffer(frame, 0); if (ret < 0) - fprintf(stderr, "FFAudioStream::init_frame: av_frame_get_buffer failed\n"); + ff_err(ret, "FFAudioStream::init_frame: av_frame_get_buffer failed\n"); return ret; } @@ -533,7 +539,7 @@ int FFAudioStream::load(int64_t pos, int len) curr_pos += frame->nb_samples; } } - if( flushed && end_pos > curr_pos ) { + if( end_pos > curr_pos ) { zero(end_pos - curr_pos); curr_pos = end_pos; } @@ -548,6 +554,7 @@ int FFAudioStream::audio_seek(int64_t pos) return 0; } if( pos == curr_pos ) return 0; + if( !st->codec || !st->codec->codec ) return -1; avcodec_flush_buffers(st->codec); double secs = (double)pos / sample_rate; int64_t tstmp = secs * st->time_base.den / st->time_base.num; @@ -576,7 +583,7 @@ int FFAudioStream::encode(double **samples, int len) (uint8_t **)frame->extended_data, frame_sz, (const uint8_t **)&bfrp, frame_sz); if( ret < 0 ) { - fprintf(stderr, "FFAudioStream::encode: swr_convert failed\n"); + ff_err(ret, "FFAudioStream::encode: swr_convert failed\n"); break; } frm->queue(curr_pos); @@ -609,7 +616,7 @@ int FFVideoStream::decode_frame(AVFrame *frame, int &got_frame) { int ret = avcodec_decode_video2(st->codec, frame, &got_frame, ipkt); if( ret < 0 ) { - fprintf(stderr, "FFVideoStream::decode_frame: Could not read video frame\n"); + ff_err(ret, "FFVideoStream::decode_frame: Could not read video frame\n"); return -1; } if( got_frame ) @@ -619,12 +626,12 @@ int FFVideoStream::decode_frame(AVFrame *frame, int &got_frame) int FFVideoStream::load(VFrame *vframe, int64_t pos) { - if( video_seek(pos) < 0 ) return -1; + int ret = video_seek(pos); + if( ret < 0 ) return -1; if( !frame && !(frame=av_frame_alloc()) ) { fprintf(stderr, "FFVideoStream::load: av_frame_alloc failed\n"); return -1; } - int ret = 0; for( int i=0; ret>=0 && !flushed && curr_pos<=pos && i<1000; ++i ) { ret = read_frame(frame); } @@ -646,6 +653,8 @@ int FFVideoStream::video_seek(int64_t pos) if( gop < 4 ) gop = 4; if( gop > 64 ) gop = 64; if( pos >= curr_pos && pos <= curr_pos + gop ) return 0; + if( pos == curr_pos-1 && curr_pos > seek_pos ) return 1; + if( !st->codec || !st->codec->codec ) return -1; avcodec_flush_buffers(st->codec); // back up a few frames to read up to current to help repair damages if( (pos-=gop) < 0 ) pos = 0; @@ -767,9 +776,10 @@ int FFVideoStream::convert_picture_vframe(VFrame *frame, " sws_getCachedContext() failed\n"); return 1; } - if( sws_scale(convert_ctx, ip->data, ip->linesize, 0, ih, - opic.data, opic.linesize) < 0 ) { - fprintf(stderr, "FFVideoStream::convert_picture_frame: sws_scale() failed\n"); + int ret = sws_scale(convert_ctx, ip->data, ip->linesize, 0, ih, + opic.data, opic.linesize); + if( ret < 0 ) { + ff_err(ret, "FFVideoStream::convert_picture_frame: sws_scale() failed\n"); return 1; } return 0; @@ -830,9 +840,10 @@ int FFVideoStream::convert_vframe_picture(VFrame *frame, " sws_getCachedContext() failed\n"); return 1; } - if( sws_scale(convert_ctx, opic.data, opic.linesize, 0, frame->get_h(), - op->data, op->linesize) < 0 ) { - fprintf(stderr, "FFVideoStream::convert_frame_picture: sws_scale() failed\n"); + int ret = sws_scale(convert_ctx, opic.data, opic.linesize, 0, frame->get_h(), + op->data, op->linesize); + if( ret < 0 ) { + ff_err(ret, "FFVideoStream::convert_frame_picture: sws_scale() failed\n"); return 1; } return 0; @@ -931,10 +942,15 @@ AVRational FFMPEG::check_frame_rate(AVCodec *codec, double frame_rate) AVRational FFMPEG::to_sample_aspect_ratio(double aspect_ratio) { +#if 1 int height = 1000000, width = height * aspect_ratio; float w, h; MWindow::create_aspect_ratio(w, h, width, height); return (AVRational){(int)w, (int)h}; +#else +// square pixels + return (AVRational){1, 1}; +#endif } AVRational FFMPEG::to_time_base(int sample_rate) @@ -942,8 +958,6 @@ AVRational FFMPEG::to_time_base(int sample_rate) return (AVRational){1, sample_rate}; } -extern void get_exe_path(char *result); // from main.C - void FFMPEG::set_option_path(char *path, const char *fmt, ...) { get_exe_path(path); @@ -1028,8 +1042,8 @@ int FFMPEG::get_encoder(const char *options, return 1; } if( get_encoder(fp, format, codec, bsfilter, bsargs) ) - eprintf("FFMPEG::get_encoder:" - " err: format/codec not found %s\n", options); + eprintf(_("FFMPEG::get_encoder:" + " err: format/codec not found %s\n"), options); fclose(fp); return 0; } @@ -1059,12 +1073,14 @@ int FFMPEG::read_options(const char *options, AVDictionary *&opts) return ret; } -int FFMPEG::scan_options(const char *options, AVDictionary *&opts) +int FFMPEG::scan_options(const char *options, AVDictionary *&opts, AVStream *st) { FILE *fp = fmemopen((void *)options,strlen(options),"r"); if( !fp ) return 0; int ret = read_options(fp, options, opts); fclose(fp); + AVDictionaryEntry *tag = av_dict_get(opts, "id", NULL, 0); + if( tag ) st->id = strtol(tag->value,0,0); return ret; } @@ -1079,8 +1095,8 @@ int FFMPEG::read_options(FILE *fp, const char *options, AVDictionary *&opts) if( line[0] == '\n' ) continue; char key[BCSTRLEN], val[BCTEXTLEN]; if( scan_option_line(line, key, val) ) { - eprintf("FFMPEG::read_options:" - " err reading %s: line %d\n", options, no); + eprintf(_("FFMPEG::read_options:" + " err reading %s: line %d\n"), options, no); ret = 1; } if( !ret ) { @@ -1159,7 +1175,7 @@ int FFMPEG::info(char *text, int len) for( int i=0; i<(int)fmt_ctx->nb_streams; ++i ) { AVStream *st = fmt_ctx->streams[i]; AVCodecContext *avctx = st->codec; - report("stream %d, id 0x%06x:\n", i, avctx->codec_id); + report(_("stream %d, id 0x%06x:\n"), i, avctx->codec_id); const AVCodecDescriptor *desc = avcodec_descriptor_get(avctx->codec_id); if( avctx->codec_type == AVMEDIA_TYPE_VIDEO ) { AVRational framerate = av_guess_frame_rate(fmt_ctx, st, 0); @@ -1191,7 +1207,7 @@ int FFMPEG::info(char *text, int len) report(" %d:%02d:%05.2f\n", hrs, mins, secs); } else - report(" codec_type unknown\n"); + report(_(" codec_type unknown\n")); } report("\n"); for( int i=0; i<(int)fmt_ctx->nb_programs; ++i ) { @@ -1421,13 +1437,14 @@ int FFMPEG::open_encoder(const char *type, const char *spec) break; } has_audio = 1; - if( scan_options(asset->ff_audio_options, sopts) ) { + if( scan_options(asset->ff_audio_options, sopts, st) ) { eprintf("FFMPEG::open_encoder: bad audio options %s:%s\n", codec_name, filename); ret = 1; break; } if( asset->ff_audio_bitrate > 0 ) { + ctx->bit_rate = asset->ff_audio_bitrate; char arg[BCSTRLEN]; sprintf(arg, "%d", asset->ff_audio_bitrate); av_dict_set(&sopts, "b", arg, 0); @@ -1466,13 +1483,14 @@ int FFMPEG::open_encoder(const char *type, const char *spec) break; } has_video = 1; - if( scan_options(asset->ff_video_options, sopts) ) { + if( scan_options(asset->ff_video_options, sopts, st) ) { eprintf("FFMPEG::open_encoder: bad video options %s:%s\n", codec_name, filename); ret = 1; break; } if( asset->ff_video_bitrate > 0 ) { + ctx->bit_rate = asset->ff_video_bitrate; char arg[BCSTRLEN]; sprintf(arg, "%d", asset->ff_video_bitrate); av_dict_set(&sopts, "b", arg, 0); @@ -1640,11 +1658,12 @@ int FFMPEG::decode_activate() int FFMPEG::encode_activate() { + int ret = 0; if( encoding < 0 ) { encoding = 0; if( !(fmt_ctx->flags & AVFMT_NOFILE) && - avio_open(&fmt_ctx->pb, fmt_ctx->filename, AVIO_FLAG_WRITE) < 0 ) { - fprintf(stderr, "FFMPEG::encode_activate: err opening : %s\n", + (ret=avio_open(&fmt_ctx->pb, fmt_ctx->filename, AVIO_FLAG_WRITE)) < 0 ) { + ff_err(ret, "FFMPEG::encode_activate: err opening : %s\n", fmt_ctx->filename); return 1; } @@ -1653,10 +1672,10 @@ int FFMPEG::encode_activate() char option_path[BCTEXTLEN]; set_option_path(option_path, "format/%s", file_format); read_options(option_path, fopts); - int ret = avformat_write_header(fmt_ctx, &fopts); + ret = avformat_write_header(fmt_ctx, &fopts); av_dict_free(&fopts); if( ret < 0 ) { - fprintf(stderr, "FFMPEG::encode_activate: write header failed %s\n", + ff_err(ret, "FFMPEG::encode_activate: write header failed %s\n", fmt_ctx->filename); return 1; }