X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fcinelerra%2Fffmpeg.C;h=2f1a1987cf6cd7fe6397da5ccb43381d4b82827d;hb=5aad2133f228b736f033d6c48e1629078b858286;hp=decb3d0078260bf419a7469a16e00d62def79f89;hpb=2d8ee7ae9c2f42d8c6f2d5dcc8949ef989ebd7af;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/cinelerra/ffmpeg.C b/cinelerra-5.0/cinelerra/ffmpeg.C index decb3d00..2f1a1987 100644 --- a/cinelerra-5.0/cinelerra/ffmpeg.C +++ b/cinelerra-5.0/cinelerra/ffmpeg.C @@ -18,6 +18,8 @@ #include "fileffmpeg.h" #include "file.h" #include "ffmpeg.h" +#include "libdv.h" +#include "libmjpeg.h" #include "mainerror.h" #include "mwindow.h" #include "vframe.h" @@ -941,8 +943,8 @@ FFMPEG::~FFMPEG() delete flow_lock; delete mux_lock; av_dict_free(&opts); - delete opt_video_filter; - delete opt_audio_filter; + delete [] opt_video_filter; + delete [] opt_audio_filter; } int FFMPEG::check_sample_rate(AVCodec *codec, int sample_rate) @@ -982,13 +984,15 @@ AVRational FFMPEG::check_frame_rate(AVCodec *codec, double frame_rate) return max_err < 0.0001 ? best_rate : (AVRational) { 0, 0 }; } -AVRational FFMPEG::to_sample_aspect_ratio(double aspect_ratio) +AVRational FFMPEG::to_sample_aspect_ratio(Asset *asset) { #if 1 - int height = 1000000, width = height * aspect_ratio; + double display_aspect = asset->width / (double)asset->height; + double sample_aspect = asset->aspect_ratio / display_aspect; + int width = 1000000, height = width * sample_aspect + 0.5; float w, h; MWindow::create_aspect_ratio(w, h, width, height); - return (AVRational){(int)w, (int)h}; + return (AVRational){(int)h, (int)w}; #else // square pixels return (AVRational){1, 1}; @@ -1335,7 +1339,13 @@ int FFMPEG::open_decoder() AVStream *st = fmt_ctx->streams[i]; if( st->duration == AV_NOPTS_VALUE ) bad_time = 1; AVCodecContext *avctx = st->codec; + const AVCodecDescriptor *codec_desc = avcodec_descriptor_get(avctx->codec_id); + if( !codec_desc ) continue; if( avctx->codec_type == AVMEDIA_TYPE_VIDEO ) { + if( avctx->width < 1 ) continue; + if( avctx->height < 1 ) continue; + AVRational framerate = av_guess_frame_rate(fmt_ctx, st, 0); + if( framerate.num < 1 ) continue; has_video = 1; FFVideoStream *vid = new FFVideoStream(this, st, i); int vidx = ffvideo.size(); @@ -1343,7 +1353,6 @@ int FFMPEG::open_decoder() ffvideo.append(vid); vid->width = avctx->width; vid->height = avctx->height; - AVRational framerate = av_guess_frame_rate(fmt_ctx, st, 0); vid->frame_rate = !framerate.den ? 0 : (double)framerate.num / framerate.den; double secs = to_secs(st->duration, st->time_base); vid->length = secs * vid->frame_rate; @@ -1354,6 +1363,8 @@ int FFMPEG::open_decoder() vid->create_filter(opt_video_filter, avctx,avctx); } else if( avctx->codec_type == AVMEDIA_TYPE_AUDIO ) { + if( avctx->channels < 1 ) continue; + if( avctx->sample_rate < 1 ) continue; has_audio = 1; FFAudioStream *aud = new FFAudioStream(this, st, i); int aidx = ffaudio.size(); @@ -1440,6 +1451,10 @@ int FFMPEG::open_encoder(const char *type, const char *spec) return 1; } + if( !strcmp(codec_name, CODEC_TAG_DVSD) ) strcpy(codec_name, "dv"); + else if( !strcmp(codec_name, CODEC_TAG_MJPEG) ) strcpy(codec_name, "mjpeg"); + else if( !strcmp(codec_name, CODEC_TAG_JPEG) ) strcpy(codec_name, "jpeg"); + int ret = 0; ff_lock("FFMPEG::open_encoder"); FFStream *fst = 0; @@ -1560,7 +1575,7 @@ int FFMPEG::open_encoder(const char *type, const char *spec) vid->height = asset->height; ctx->height = (vid->height+3) & ~3; vid->frame_rate = asset->frame_rate; - ctx->sample_aspect_ratio = to_sample_aspect_ratio(asset->aspect_ratio); + ctx->sample_aspect_ratio = to_sample_aspect_ratio(asset); 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 ) { @@ -1580,6 +1595,9 @@ int FFMPEG::open_encoder(const char *type, const char *spec) } } if( !ret ) { + if( fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER ) + st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; + ret = avcodec_open2(st->codec, codec, &sopts); if( ret < 0 ) { ff_err(ret,"FFMPEG::open_encoder"); @@ -1591,8 +1609,6 @@ int FFMPEG::open_encoder(const char *type, const char *spec) ret = 0; } if( !ret ) { - if( fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER ) - st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; if( fst && bsfilter[0] ) fst->add_bsfilter(bsfilter, !bsargs[0] ? 0 : bsargs); } @@ -2070,6 +2086,11 @@ int FFVideoStream::create_filter(const char *filter_spec, AVCodecContext *src_ctx, AVCodecContext *sink_ctx) { avfilter_register_all(); + AVFilter *filter = avfilter_get_by_name(filter_spec); + if( !filter || filter->inputs->type != AVMEDIA_TYPE_VIDEO ) { + ff_err(AVERROR(EINVAL), "FFVideoStream::create_filter: %s\n", filter_spec); + return -1; + } filter_graph = avfilter_graph_alloc(); AVFilter *buffersrc = avfilter_get_by_name("buffer"); AVFilter *buffersink = avfilter_get_by_name("buffersink"); @@ -2101,6 +2122,11 @@ int FFAudioStream::create_filter(const char *filter_spec, AVCodecContext *src_ctx, AVCodecContext *sink_ctx) { avfilter_register_all(); + AVFilter *filter = avfilter_get_by_name(filter_spec); + if( !filter || filter->inputs->type != AVMEDIA_TYPE_AUDIO ) { + ff_err(AVERROR(EINVAL), "FFAudioStream::create_filter: %s\n", filter_spec); + return -1; + } filter_graph = avfilter_graph_alloc(); AVFilter *buffersrc = avfilter_get_by_name("abuffer"); AVFilter *buffersink = avfilter_get_by_name("abuffersink");