X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=f3680dfc670511596a73eca81895d715760f2a66;hb=4fa0e24736bff7d7fbdfb36ed578a1db166817d4;hp=08a50d541bbbf0b46691054d431ed8b8eae7978a;hpb=ee77f986a2f7af4ae1fb0f07d302828e08a1a2f7;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index 08a50d541bb..f3680dfc670 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -36,9 +36,9 @@ #include "libswscale/swscale.h" #include "libavcodec/opt.h" #include "libavcodec/audioconvert.h" -#include "libavcore/audioconvert.h" -#include "libavcore/parseutils.h" -#include "libavcore/samplefmt.h" +#include "libavutil/audioconvert.h" +#include "libavutil/parseutils.h" +#include "libavutil/samplefmt.h" #include "libavutil/colorspace.h" #include "libavutil/fifo.h" #include "libavutil/intreadwrite.h" @@ -69,12 +69,7 @@ #include #endif -#if HAVE_TERMIOS_H -#include -#include -#include -#include -#elif HAVE_CONIO_H +#if HAVE_KBHIT #include #endif #include @@ -172,7 +167,6 @@ static int loop_output = AVFMT_NOOUTPUTLOOP; static int qp_hist = 0; #if CONFIG_AVFILTER static char *vfilters = NULL; -AVFilterGraph *graph = NULL; #endif static int intra_only = 0; @@ -213,6 +207,7 @@ static int video_sync_method= -1; static int audio_sync_method= 0; static float audio_drift_threshold= 0.1; static int copy_ts= 0; +static int copy_tb; static int opt_shortest = 0; static int video_global_header = 0; static char *vstats_filename; @@ -250,7 +245,7 @@ static int64_t timer_start; static uint8_t *audio_buf; static uint8_t *audio_out; -unsigned int allocated_audio_out_size, allocated_audio_buf_size; +static unsigned int allocated_audio_out_size, allocated_audio_buf_size; static short *samples; @@ -302,6 +297,14 @@ typedef struct AVOutputStream { AVAudioConvert *reformat_ctx; AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */ FILE *logfile; + +#if CONFIG_AVFILTER + AVFilterContext *output_video_filter; + AVFilterContext *input_video_filter; + AVFilterBufferRef *picref; + char *avfilter; + AVFilterGraph *graph; +#endif } AVOutputStream; static AVOutputStream **output_streams_for_file[MAX_FILES] = { NULL }; @@ -319,16 +322,12 @@ typedef struct AVInputStream { int64_t next_pts; /* synthetic pts for cases where pkt.pts is not defined */ int64_t pts; /* current pts */ - PtsCorrectionContext pts_ctx; int is_start; /* is 1 at the start and after a discontinuity */ int showed_multi_packet_warning; int is_past_recording_time; #if CONFIG_AVFILTER - AVFilterContext *output_video_filter; - AVFilterContext *input_video_filter; AVFrame *filter_frame; int has_filter_frame; - AVFilterBufferRef *picref; #endif } AVInputStream; @@ -339,12 +338,6 @@ typedef struct AVInputFile { int nb_streams; /* nb streams we are aware of */ } AVInputFile; -#if HAVE_TERMIOS_H - -/* init terminal so that we can grab keys */ -static struct termios oldtty; -#endif - #if CONFIG_AVFILTER static int configure_filters(AVInputStream *ist, AVOutputStream *ost) @@ -354,22 +347,30 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost) AVCodecContext *codec = ost->st->codec; AVCodecContext *icodec = ist->st->codec; FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt }; + AVRational sample_aspect_ratio; char args[255]; int ret; - graph = avfilter_graph_alloc(); + ost->graph = avfilter_graph_alloc(); - snprintf(args, 255, "%d:%d:%d:%d:%d", ist->st->codec->width, - ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE); - ret = avfilter_graph_create_filter(&ist->input_video_filter, avfilter_get_by_name("buffer"), - "src", args, NULL, graph); + if (ist->st->sample_aspect_ratio.num){ + sample_aspect_ratio = ist->st->sample_aspect_ratio; + }else + sample_aspect_ratio = ist->st->codec->sample_aspect_ratio; + + snprintf(args, 255, "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width, + ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE, + sample_aspect_ratio.num, sample_aspect_ratio.den); + + ret = avfilter_graph_create_filter(&ost->input_video_filter, avfilter_get_by_name("buffer"), + "src", args, NULL, ost->graph); if (ret < 0) return ret; - ret = avfilter_graph_create_filter(&ist->output_video_filter, &ffsink, - "out", NULL, &ffsink_ctx, graph); + ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink, + "out", NULL, &ffsink_ctx, ost->graph); if (ret < 0) return ret; - last_filter = ist->input_video_filter; + last_filter = ost->input_video_filter; if (codec->width != icodec->width || codec->height != icodec->height) { snprintf(args, 255, "%d:%d:flags=0x%X", @@ -377,7 +378,7 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost) codec->height, (int)av_get_int(sws_opts, "sws_flags", NULL)); if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"), - NULL, args, NULL, graph)) < 0) + NULL, args, NULL, ost->graph)) < 0) return ret; if ((ret = avfilter_link(last_filter, 0, filter, 0)) < 0) return ret; @@ -385,9 +386,9 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost) } snprintf(args, sizeof(args), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL)); - graph->scale_sws_opts = av_strdup(args); + ost->graph->scale_sws_opts = av_strdup(args); - if (vfilters) { + if (ost->avfilter) { AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut)); AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut)); @@ -397,23 +398,25 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost) outputs->next = NULL; inputs->name = av_strdup("out"); - inputs->filter_ctx = ist->output_video_filter; + inputs->filter_ctx = ost->output_video_filter; inputs->pad_idx = 0; inputs->next = NULL; - if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0) + if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, inputs, outputs, NULL)) < 0) return ret; - av_freep(&vfilters); + av_freep(&ost->avfilter); } else { - if ((ret = avfilter_link(last_filter, 0, ist->output_video_filter, 0)) < 0) + if ((ret = avfilter_link(last_filter, 0, ost->output_video_filter, 0)) < 0) return ret; } - if ((ret = avfilter_graph_config(graph, NULL)) < 0) + if ((ret = avfilter_graph_config(ost->graph, NULL)) < 0) return ret; - codec->width = ist->output_video_filter->inputs[0]->w; - codec->height = ist->output_video_filter->inputs[0]->h; + codec->width = ost->output_video_filter->inputs[0]->w; + codec->height = ost->output_video_filter->inputs[0]->h; + codec->sample_aspect_ratio = ost->st->sample_aspect_ratio = + ost->output_video_filter->inputs[0]->sample_aspect_ratio; return 0; } @@ -422,9 +425,6 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost) static void term_exit(void) { av_log(NULL, AV_LOG_QUIET, ""); -#if HAVE_TERMIOS_H - tcsetattr (0, TCSANOW, &oldtty); -#endif } static volatile int received_sigterm = 0; @@ -438,26 +438,6 @@ sigterm_handler(int sig) static void term_init(void) { -#if HAVE_TERMIOS_H - struct termios tty; - - tcgetattr (0, &tty); - oldtty = tty; - atexit(term_exit); - - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP - |INLCR|IGNCR|ICRNL|IXON); - tty.c_oflag |= OPOST; - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); - tty.c_cflag &= ~(CSIZE|PARENB); - tty.c_cflag |= CS8; - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - - tcsetattr (0, TCSANOW, &tty); - signal(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ -#endif - signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */ #ifdef SIGXCPU @@ -468,25 +448,7 @@ static void term_init(void) /* read a key without blocking */ static int read_key(void) { -#if HAVE_TERMIOS_H - int n = 1; - unsigned char ch; - struct timeval tv; - fd_set rfds; - - FD_ZERO(&rfds); - FD_SET(0, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 0; - n = select(1, &rfds, NULL, NULL, &tv); - if (n > 0) { - n = read(0, &ch, 1); - if (n == 1) - return ch; - - return n; - } -#elif HAVE_CONIO_H +#if HAVE_KBHIT if(kbhit()) return(getch()); #endif @@ -495,7 +457,8 @@ static int read_key(void) static int decode_interrupt_cb(void) { - return q_pressed || (q_pressed = read_key() == 'q'); + q_pressed += read_key() == 'q'; + return q_pressed > 1; } static int ffmpeg_exit(int ret) @@ -504,25 +467,10 @@ static int ffmpeg_exit(int ret) /* close files */ for(i=0;ioformat->flags & AVFMT_NOFILE) && s->pb) - url_fclose(s->pb); - for(j=0;jnb_streams;j++) { - av_metadata_free(&s->streams[j]->metadata); - av_free(s->streams[j]->codec); - av_free(s->streams[j]->info); - av_free(s->streams[j]); - } - for(j=0;jnb_programs;j++) { - av_metadata_free(&s->programs[j]->metadata); - } - for(j=0;jnb_chapters;j++) { - av_metadata_free(&s->chapters[j]->metadata); - } - av_metadata_free(&s->metadata); - av_free(s); + avio_close(s->pb); + avformat_free_context(s); av_free(output_streams_for_file[i]); } for(i=0;icodec->sample_fmt) break; } - if(*p == -1) + if (*p == -1) { + av_log(NULL, AV_LOG_WARNING, + "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n", + av_get_sample_fmt_name(st->codec->sample_fmt), + codec->name, + av_get_sample_fmt_name(codec->sample_fmts[0])); st->codec->sample_fmt = codec->sample_fmts[0]; + } } } @@ -706,11 +659,6 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename) choose_pixel_fmt(st, codec); } - if(!st->codec->thread_count) - st->codec->thread_count = 1; - if(st->codec->thread_count>1) - avcodec_thread_init(st->codec, st->codec->thread_count); - if(st->codec->flags & CODEC_FLAG_BITEXACT) nopts = 1; @@ -824,7 +772,9 @@ need_realloc: if (ost->resample) audio_resample_close(ost->resample); } - if (ost->resample_sample_fmt == enc->sample_fmt && + /* if audio_sync_method is >1 the resampler is needed for audio drift compensation */ + if (audio_sync_method <= 1 && + ost->resample_sample_fmt == enc->sample_fmt && ost->resample_channels == enc->channels && ost->resample_sample_rate == enc->sample_rate) { ost->resample = NULL; @@ -1361,9 +1311,9 @@ static void print_report(AVFormatContext **output_files, oc = output_files[0]; - total_size = url_fsize(oc->pb); - if(total_size<0) // FIXME improve url_fsize() so it works with non seekable output too - total_size= url_ftell(oc->pb); + total_size = avio_size(oc->pb); + if(total_size<0) // FIXME improve avio_size() so it works with non seekable output too + total_size= avio_tell(oc->pb); buf[0] = '\0'; ti1 = 1e10; @@ -1544,7 +1494,8 @@ static int output_packet(AVInputStream *ist, int ist_index, decoded_data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2; /* XXX: allocate picture correctly */ avcodec_get_frame_defaults(&picture); - ist->st->codec->reordered_opaque = pkt_pts; + avpkt.pts = pkt_pts; + avpkt.dts = ist->pts; pkt_pts = AV_NOPTS_VALUE; ret = avcodec_decode_video2(ist->st->codec, @@ -1556,7 +1507,7 @@ static int output_packet(AVInputStream *ist, int ist_index, /* no picture yet */ goto discard_packet; } - ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, picture.reordered_opaque, ist->pts); + ist->next_pts = ist->pts = picture.best_effort_timestamp; if (ist->st->codec->time_base.num != 0) { int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; ist->next_pts += ((int64_t)AV_TIME_BASE * @@ -1605,11 +1556,19 @@ static int output_packet(AVInputStream *ist, int ist_index, } #if CONFIG_AVFILTER - if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->input_video_filter) { - // add it to be filtered - av_vsrc_buffer_add_frame(ist->input_video_filter, &picture, - ist->pts, - ist->st->codec->sample_aspect_ratio); + if(ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ + for(i=0;iinput_video_filter && ost->source_index == ist_index) { + AVRational sar; + if (ist->st->sample_aspect_ratio.num) sar = ist->st->sample_aspect_ratio; + else sar = ist->st->codec->sample_aspect_ratio; + // add it to be filtered + av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, + ist->pts, + sar); + } + } } #endif @@ -1634,26 +1593,24 @@ static int output_packet(AVInputStream *ist, int ist_index, if (pts > now) usleep(pts - now); } -#if CONFIG_AVFILTER - frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || - !ist->output_video_filter || avfilter_poll_frame(ist->output_video_filter->inputs[0]); -#endif /* if output time reached then transcode raw format, encode packets and output them */ if (start_time == 0 || ist->pts >= start_time) -#if CONFIG_AVFILTER - while (frame_available) { - AVRational ist_pts_tb; - if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->output_video_filter) - get_filtered_video_frame(ist->output_video_filter, &picture, &ist->picref, &ist_pts_tb); - if (ist->picref) - ist->pts = av_rescale_q(ist->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); -#endif for(i=0;isource_index == ist_index) { +#if CONFIG_AVFILTER + frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || + !ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]); + while (frame_available) { + AVRational ist_pts_tb; + if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) + get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb); + if (ost->picref) + ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); +#endif os = output_files[ost->file_index]; /* set the input output pts pairs */ @@ -1667,8 +1624,8 @@ static int output_packet(AVInputStream *ist, int ist_index, break; case AVMEDIA_TYPE_VIDEO: #if CONFIG_AVFILTER - if (ist->picref->video) - ost->st->codec->sample_aspect_ratio = ist->picref->video->pixel_aspect; + if (ost->picref->video) + ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect; #endif do_video_out(os, ost, ist, &picture, &frame_size); if (vstats_filename && frame_size) @@ -1689,7 +1646,11 @@ static int output_packet(AVInputStream *ist, int ist_index, av_init_packet(&opkt); if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes) +#if !CONFIG_AVFILTER continue; +#else + goto cont; +#endif /* no reencoding needed : output the packet directly */ /* force the input stream PTS */ @@ -1737,16 +1698,17 @@ static int output_packet(AVInputStream *ist, int ist_index, ost->frame_number++; av_free_packet(&opkt); } +#if CONFIG_AVFILTER + cont: + frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && + ost->output_video_filter && avfilter_poll_frame(ost->output_video_filter->inputs[0]); + if(ost->picref) + avfilter_unref_buffer(ost->picref); + } +#endif } } -#if CONFIG_AVFILTER - frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && - ist->output_video_filter && avfilter_poll_frame(ist->output_video_filter->inputs[0]); - if(ist->picref) - avfilter_unref_buffer(ist->picref); - } -#endif av_free(buffer_to_free); /* XXX: allocate the subtitles in the codec ? */ if (subtitle_to_free) { @@ -1862,7 +1824,6 @@ static int copy_chapters(int infile, int outfile) for (i = 0; i < is->nb_chapters; i++) { AVChapter *in_ch = is->chapters[i], *out_ch; - AVMetadataTag *t = NULL; int64_t ts_off = av_rescale_q(start_time - input_files_ts_offset[infile], AV_TIME_BASE_Q, in_ch->time_base); int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX : @@ -1884,8 +1845,7 @@ static int copy_chapters(int infile, int outfile) out_ch->end = FFMIN(rt, in_ch->end - ts_off); if (metadata_chapters_autocopy) - while ((t = av_metadata_get(in_ch->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) - av_metadata_set2(&out_ch->metadata, t->key, t->value, 0); + av_metadata_copy(&out_ch->metadata, in_ch->metadata, 0); os->nb_chapters++; os->chapters = av_realloc(os->chapters, sizeof(AVChapter)*os->nb_chapters); @@ -1986,7 +1946,7 @@ static int transcode(AVFormatContext **output_files, for(i=0;inb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) { - dump_format(output_files[i], i, output_files[i]->filename, 1); + av_dump_format(output_files[i], i, output_files[i]->filename, 1); fprintf(stderr, "Output file #%d does not contain any stream\n", i); ret = AVERROR(EINVAL); goto fail; @@ -2037,7 +1997,7 @@ static int transcode(AVFormatContext **output_files, /* Sanity check that the stream types match */ if (ist_table[ost->source_index]->st->codec->codec_type != ost->st->codec->codec_type) { int i= ost->file_index; - dump_format(output_files[i], i, output_files[i]->filename, 1); + av_dump_format(output_files[i], i, output_files[i]->filename, 1); fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n", stream_maps[n].file_index, stream_maps[n].stream_index, ost->file_index, ost->index); @@ -2088,7 +2048,7 @@ static int transcode(AVFormatContext **output_files, } if (!found) { int i= ost->file_index; - dump_format(output_files[i], i, output_files[i]->filename, 1); + av_dump_format(output_files[i], i, output_files[i]->filename, 1); fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n", ost->file_index, ost->index); ffmpeg_exit(1); @@ -2105,7 +2065,6 @@ static int transcode(AVFormatContext **output_files, /* for each output stream, we compute the right encoding parameters */ for(i=0;ifile_index]; ist = ist_table[ost->source_index]; @@ -2114,9 +2073,8 @@ static int transcode(AVFormatContext **output_files, icodec = ist->st->codec; if (metadata_streams_autocopy) - while ((t = av_metadata_get(ist->st->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) { - av_metadata_set2(&ost->st->metadata, t->key, t->value, AV_METADATA_DONT_OVERWRITE); - } + av_metadata_copy(&ost->st->metadata, ist->st->metadata, + AV_METADATA_DONT_OVERWRITE); ost->st->disposition = ist->st->disposition; codec->bits_per_raw_sample= icodec->bits_per_raw_sample; @@ -2147,7 +2105,7 @@ static int transcode(AVFormatContext **output_files, goto fail; memcpy(codec->extradata, icodec->extradata, icodec->extradata_size); codec->extradata_size= icodec->extradata_size; - if(av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/1000){ + if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){ codec->time_base = icodec->time_base; codec->time_base.num *= icodec->ticks_per_frame; av_reduce(&codec->time_base.num, &codec->time_base.den, @@ -2207,6 +2165,7 @@ static int transcode(AVFormatContext **output_files, codec->height != icodec->height || (codec->pix_fmt != icodec->pix_fmt)); if (ost->video_resample) { +#if !CONFIG_AVFILTER avcodec_get_frame_defaults(&ost->pict_tmp); if(avpicture_alloc((AVPicture*)&ost->pict_tmp, codec->pix_fmt, codec->width, codec->height)) { @@ -2227,7 +2186,6 @@ static int transcode(AVFormatContext **output_files, ffmpeg_exit(1); } -#if !CONFIG_AVFILTER ost->original_height = icodec->height; ost->original_width = icodec->width; #endif @@ -2360,7 +2318,6 @@ static int transcode(AVFormatContext **output_files, st= ist->st; ist->pts = st->avg_frame_rate.num ? - st->codec->has_b_frames*AV_TIME_BASE / av_q2d(st->avg_frame_rate) : 0; ist->next_pts = AV_NOPTS_VALUE; - init_pts_correction(&ist->pts_ctx); ist->is_start = 1; } @@ -2368,7 +2325,6 @@ static int transcode(AVFormatContext **output_files, for (i=0;ikey, mtag->value, AV_METADATA_DONT_OVERWRITE); + av_metadata_copy(meta[0], *meta[1], AV_METADATA_DONT_OVERWRITE); } /* copy global metadata by default */ if (metadata_global_autocopy) { - AVMetadataTag *t = NULL; - while ((t = av_metadata_get(input_files[0]->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) - for (i = 0; i < nb_output_files; i++) - av_metadata_set2(&output_files[i]->metadata, t->key, t->value, AV_METADATA_DONT_OVERWRITE); + for (i = 0; i < nb_output_files; i++) + av_metadata_copy(&output_files[i]->metadata, input_files[0]->metadata, + AV_METADATA_DONT_OVERWRITE); } /* copy chapters according to chapter maps */ @@ -2474,7 +2427,7 @@ static int transcode(AVFormatContext **output_files, /* dump the file output parameters - cannot be done before in case of stream copy */ for(i=0;ifilename, 1); + av_dump_format(output_files[i], i, output_files[i]->filename, 1); } /* dump the stream mapping */ @@ -2504,8 +2457,13 @@ static int transcode(AVFormatContext **output_files, print_sdp(output_files, nb_output_files); } - if (!using_stdin && verbose >= 0) { - fprintf(stderr, "Press [q] to stop encoding\n"); + if (!using_stdin) { + if(verbose >= 0) +#if HAVE_KBHIT + fprintf(stderr, "Press [q] to stop encoding\n"); +#else + fprintf(stderr, "Press ctrl-c to stop encoding\n"); +#endif url_set_interrupt_cb(decode_interrupt_cb); } term_init(); @@ -2570,7 +2528,7 @@ static int transcode(AVFormatContext **output_files, } /* finish if limit size exhausted */ - if (limit_filesize != 0 && limit_filesize <= url_ftell(output_files[0]->pb)) + if (limit_filesize != 0 && limit_filesize <= avio_tell(output_files[0]->pb)) break; /* read a frame from it and output it in the fifo */ @@ -2593,7 +2551,8 @@ static int transcode(AVFormatContext **output_files, memset(no_packet, 0, sizeof(no_packet)); if (do_pkt_dump) { - av_pkt_dump_log(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump); + av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump, + is->streams[pkt.stream_index]); } /* the following test is needed in case new streams appear dynamically in stream : we ignore them */ @@ -2684,6 +2643,9 @@ static int transcode(AVFormatContext **output_files, av_freep(&ost->st->codec->stats_in); avcodec_close(ost->st->codec); } +#if CONFIG_AVFILTER + avfilter_graph_free(&ost->graph); +#endif } /* close each decoder */ @@ -2693,12 +2655,6 @@ static int transcode(AVFormatContext **output_files, avcodec_close(ist->st->codec); } } -#if CONFIG_AVFILTER - if (graph) { - avfilter_graph_free(graph); - av_freep(&graph); - } -#endif /* finished ! */ ret = 0; @@ -2885,9 +2841,13 @@ static int opt_thread_count(const char *opt, const char *arg) static void opt_audio_sample_fmt(const char *arg) { - if (strcmp(arg, "list")) + if (strcmp(arg, "list")) { audio_sample_fmt = av_get_sample_fmt(arg); - else { + if (audio_sample_fmt == AV_SAMPLE_FMT_NONE) { + av_log(NULL, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg); + ffmpeg_exit(1); + } + } else { list_fmts(av_get_sample_fmt_string, AV_SAMPLE_FMT_NB); ffmpeg_exit(0); } @@ -2984,7 +2944,7 @@ static void opt_map(const char *arg) } } -static void parse_meta_type(const char *arg, char *type, int *index, char **endptr) +static void parse_meta_type(char *arg, char *type, int *index, char **endptr) { *endptr = arg; if (*arg == ',') { @@ -3005,7 +2965,7 @@ static void parse_meta_type(const char *arg, char *type, int *index, char **endp *type = 'g'; } -static void opt_map_meta_data(const char *arg) +static void opt_map_metadata(const char *arg) { AVMetaDataMap *m, *m1; char *p; @@ -3031,6 +2991,13 @@ static void opt_map_meta_data(const char *arg) metadata_chapters_autocopy = 0; } +static void opt_map_meta_data(const char *arg) +{ + fprintf(stderr, "-map_meta_data is deprecated and will be removed soon. " + "Use -map_metadata instead.\n"); + opt_map_metadata(arg); +} + static void opt_map_chapters(const char *arg) { AVChapterMap *c; @@ -3238,7 +3205,7 @@ static void opt_input_file(const char *filename) for(i=0;inb_streams;i++) { AVStream *st = ic->streams[i]; AVCodecContext *dec = st->codec; - avcodec_thread_init(dec, thread_count); + dec->thread_count = thread_count; input_codecs = grow_array(input_codecs, sizeof(*input_codecs), &nb_input_codecs, nb_input_codecs + 1); switch (dec->codec_type) { case AVMEDIA_TYPE_AUDIO: @@ -3316,7 +3283,7 @@ static void opt_input_file(const char *filename) input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp); /* dump the file content */ if (verbose >= 0) - dump_format(ic, nb_input_files, filename, 0); + av_dump_format(ic, nb_input_files, filename, 0); nb_input_files++; @@ -3369,8 +3336,9 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) AVStream *st; AVOutputStream *ost; AVCodecContext *video_enc; - enum CodecID codec_id; + enum CodecID codec_id = CODEC_ID_NONE; AVCodec *codec= NULL; + int i; st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0); if (!st) { @@ -3390,13 +3358,24 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); codec = avcodec_find_encoder(codec_id); } +#if CONFIG_AVFILTER + if(frame_aspect_ratio > 0){ + i = vfilters ? strlen(vfilters) : 0; + vfilters = av_realloc(vfilters, i+100); + snprintf(vfilters+i, i+100, "%csetdar=%f\n", i?',':' ', frame_aspect_ratio); + frame_aspect_ratio=0; + } + + ost->avfilter= vfilters; + vfilters= NULL; +#endif } avcodec_get_context_defaults3(st->codec, codec); ost->bitstream_filters = video_bitstream_filters; video_bitstream_filters= NULL; - avcodec_thread_init(st->codec, thread_count); + st->codec->thread_count= thread_count; video_enc = st->codec; @@ -3516,7 +3495,7 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx) AVOutputStream *ost; AVCodec *codec= NULL; AVCodecContext *audio_enc; - enum CodecID codec_id; + enum CodecID codec_id = CODEC_ID_NONE; st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0); if (!st) { @@ -3543,7 +3522,7 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx) ost->bitstream_filters = audio_bitstream_filters; audio_bitstream_filters= NULL; - avcodec_thread_init(st->codec, thread_count); + st->codec->thread_count= thread_count; audio_enc = st->codec; audio_enc->codec_type = AVMEDIA_TYPE_AUDIO; @@ -3594,7 +3573,7 @@ static void new_subtitle_stream(AVFormatContext *oc, int file_idx) AVOutputStream *ost; AVCodec *codec=NULL; AVCodecContext *subtitle_enc; - enum CodecID codec_id; + enum CodecID codec_id = CODEC_ID_NONE; st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0); if (!st) { @@ -3692,7 +3671,6 @@ static void opt_output_file(const char *filename) int input_has_video, input_has_audio, input_has_subtitle; AVFormatParameters params, *ap = ¶ms; AVOutputFormat *file_oformat; - AVMetadataTag *tag = NULL; if (!strcmp(filename, "-")) filename = "pipe:"; @@ -3760,8 +3738,7 @@ static void opt_output_file(const char *filename) oc->timestamp = recording_timestamp; - while ((tag = av_metadata_get(metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) - av_metadata_set2(&oc->metadata, tag->key, tag->value, 0); + av_metadata_copy(&oc->metadata, metadata, 0); av_metadata_free(&metadata); } @@ -3798,7 +3775,7 @@ static void opt_output_file(const char *filename) } /* open the file */ - if ((err = url_fopen(&oc->pb, filename, URL_WRONLY)) < 0) { + if ((err = avio_open(&oc->pb, filename, URL_WRONLY)) < 0) { print_error(filename, err); ffmpeg_exit(1); } @@ -3814,11 +3791,9 @@ static void opt_output_file(const char *filename) oc->preload= (int)(mux_preload*AV_TIME_BASE); oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE); oc->loop_output = loop_output; - oc->flags |= AVFMT_FLAG_NONBLOCK; set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL); - nb_streamid_map = 0; av_freep(&forced_key_frames); } @@ -4191,8 +4166,11 @@ static const OptionDef options[] = { { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" }, { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, - { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file:stream[:syncfile:syncstream]" }, - { "map_meta_data", HAS_ARG | OPT_EXPERT, {(void*)opt_map_meta_data}, "set meta data information of outfile from infile", "outfile[,metadata]:infile[,metadata]" }, + { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" }, + { "map_meta_data", HAS_ARG | OPT_EXPERT, {(void*)opt_map_meta_data}, "DEPRECATED set meta data information of outfile from infile", + "outfile[,metadata]:infile[,metadata]" }, + { "map_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", + "outfile[,metadata]:infile[,metadata]" }, { "map_chapters", HAS_ARG | OPT_EXPERT, {(void*)opt_map_chapters}, "set chapters mapping", "outfile:infile" }, { "t", OPT_FUNC2 | HAS_ARG, {(void*)opt_recording_time}, "record or transcode \"duration\" seconds of audio/video", "duration" }, { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, // @@ -4220,6 +4198,7 @@ static const OptionDef options[] = { { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, { "vglobal", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_global_header}, "video global header storage type", "" }, { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" }, + { "copytb", OPT_BOOL | OPT_EXPERT, {(void*)©_tb}, "copy input stream time base when stream copying" }, { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, // { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "threshold" }, { "programid", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&opt_programid}, "desired program number", "" },