]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
Move DECODE_BYTES_PAD* macros before Doxygen comments.
[ffmpeg] / ffmpeg.c
index 088b28727a1895f5f2ad88b3f7d55086da1a1e62..e4b4b9eb95aad81edd6d3ee57fb33869f22fc3e2 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -36,7 +36,7 @@
 #include "libswscale/swscale.h"
 #include "libavcodec/opt.h"
 #include "libavcodec/audioconvert.h"
-#include "libavcodec/colorspace.h"
+#include "libavutil/colorspace.h"
 #include "libavutil/fifo.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/avstring.h"
@@ -121,6 +121,9 @@ static int nb_stream_maps;
 static AVMetaDataMap meta_data_maps[MAX_FILES];
 static int nb_meta_data_maps;
 
+/* indexed by output file stream index */
+static int streamid_map[MAX_STREAMS];
+
 static int frame_width  = 0;
 static int frame_height = 0;
 static float frame_aspect_ratio = 0;
@@ -139,7 +142,7 @@ static const char *video_rc_override_string=NULL;
 static int video_disable = 0;
 static int video_discard = 0;
 static char *video_codec_name = NULL;
-static int video_codec_tag = 0;
+static unsigned int video_codec_tag = 0;
 static char *video_language = NULL;
 static int same_quality = 0;
 static int do_deinterlace = 0;
@@ -151,7 +154,7 @@ static int loop_output = AVFMT_NOOUTPUTLOOP;
 static int qp_hist = 0;
 #if CONFIG_AVFILTER
 static char *vfilters = NULL;
-AVFilterGraph *filt_graph_all = NULL;
+AVFilterGraph *graph = NULL;
 #endif
 
 static int intra_only = 0;
@@ -162,20 +165,20 @@ static float audio_qscale = QSCALE_NONE;
 static int audio_disable = 0;
 static int audio_channels = 1;
 static char  *audio_codec_name = NULL;
-static int audio_codec_tag = 0;
+static unsigned int audio_codec_tag = 0;
 static char *audio_language = NULL;
 
 static int subtitle_disable = 0;
 static char *subtitle_codec_name = NULL;
 static char *subtitle_language = NULL;
-static int subtitle_codec_tag = 0;
+static unsigned int subtitle_codec_tag = 0;
 
 static float mux_preload= 0.5;
 static float mux_max_delay= 0.7;
 
 static int64_t recording_time = INT64_MAX;
 static int64_t start_time = 0;
-static int64_t rec_timestamp = 0;
+static int64_t recording_timestamp = 0;
 static int64_t input_ts_offset = 0;
 static int file_overwrite = 0;
 static int metadata_count;
@@ -398,75 +401,71 @@ static AVFilter output_filter =
 
 static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
 {
-    AVFilterContext *curr_filter;
+    AVFilterContext *last_filter, *filter;
     /** filter graph containing all filters including input & output */
     AVCodecContext *codec = ost->st->codec;
     AVCodecContext *icodec = ist->st->codec;
     char args[255];
 
-    filt_graph_all = av_mallocz(sizeof(AVFilterGraph));
+    graph = av_mallocz(sizeof(AVFilterGraph));
 
-    if(!(ist->input_video_filter = avfilter_open(avfilter_get_by_name("buffer"), "src")))
+    if (!(ist->input_video_filter = avfilter_open(avfilter_get_by_name("buffer"), "src")))
         return -1;
-    if(!(ist->out_video_filter = avfilter_open(&output_filter, "out")))
+    if (!(ist->out_video_filter = avfilter_open(&output_filter, "out")))
         return -1;
 
     snprintf(args, 255, "%d:%d:%d", ist->st->codec->width,
              ist->st->codec->height, ist->st->codec->pix_fmt);
-    if(avfilter_init_filter(ist->input_video_filter, args, NULL))
+    if (avfilter_init_filter(ist->input_video_filter, args, NULL))
         return -1;
-    if(avfilter_init_filter(ist->out_video_filter, NULL, &codec->pix_fmt))
+    if (avfilter_init_filter(ist->out_video_filter, NULL, &codec->pix_fmt))
         return -1;
 
     /* add input and output filters to the overall graph */
-    avfilter_graph_add_filter(filt_graph_all, ist->input_video_filter);
-    avfilter_graph_add_filter(filt_graph_all, ist->out_video_filter);
+    avfilter_graph_add_filter(graph, ist->input_video_filter);
+    avfilter_graph_add_filter(graph, ist->out_video_filter);
 
-    curr_filter = ist->input_video_filter;
+    last_filter = ist->input_video_filter;
 
-    if(ost->video_crop) {
-        char crop_args[255];
-        AVFilterContext *filt_crop;
-        snprintf(crop_args, 255, "%d:%d:%d:%d", ost->leftBand, ost->topBand,
+    if (ost->video_crop) {
+        snprintf(args, 255, "%d:%d:%d:%d", ost->leftBand, ost->topBand,
                  codec->width,
                  codec->height);
-        filt_crop = avfilter_open(avfilter_get_by_name("crop"), NULL);
-        if (!filt_crop)
+        filter = avfilter_open(avfilter_get_by_name("crop"), NULL);
+        if (!filter)
             return -1;
-        if (avfilter_init_filter(filt_crop, crop_args, NULL))
+        if (avfilter_init_filter(filter, args, NULL))
             return -1;
-        if (avfilter_link(curr_filter, 0, filt_crop, 0))
+        if (avfilter_link(last_filter, 0, filter, 0))
             return -1;
-        curr_filter = filt_crop;
-        avfilter_graph_add_filter(filt_graph_all, curr_filter);
+        last_filter = filter;
+        avfilter_graph_add_filter(graph, last_filter);
     }
 
     if((codec->width !=
         icodec->width - (frame_leftBand + frame_rightBand)) ||
        (codec->height != icodec->height - (frame_topBand  + frame_bottomBand))) {
-        char scale_args[255];
-        AVFilterContext *filt_scale;
-        snprintf(scale_args, 255, "%d:%d:flags=0x%X",
+        snprintf(args, 255, "%d:%d:flags=0x%X",
                  codec->width,
                  codec->height,
                  (int)av_get_int(sws_opts, "sws_flags", NULL));
-        filt_scale = avfilter_open(avfilter_get_by_name("scale"), NULL);
-        if (!filt_scale)
+        filter = avfilter_open(avfilter_get_by_name("scale"), NULL);
+        if (!filter)
             return -1;
-        if (avfilter_init_filter(filt_scale, scale_args, NULL))
+        if (avfilter_init_filter(filter, args, NULL))
             return -1;
-        if (avfilter_link(curr_filter, 0, filt_scale, 0))
+        if (avfilter_link(last_filter, 0, filter, 0))
             return -1;
-        curr_filter = filt_scale;
-        avfilter_graph_add_filter(filt_graph_all, curr_filter);
+        last_filter = filter;
+        avfilter_graph_add_filter(graph, last_filter);
     }
 
-    if(vfilters) {
+    if (vfilters) {
         AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
         AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));
 
         outputs->name    = av_strdup("in");
-        outputs->filter  = curr_filter;
+        outputs->filter  = last_filter;
         outputs->pad_idx = 0;
         outputs->next    = NULL;
 
@@ -475,26 +474,23 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
         inputs->pad_idx = 0;
         inputs->next    = NULL;
 
-        if (avfilter_graph_parse(filt_graph_all, vfilters, inputs, outputs, NULL) < 0)
+        if (avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL) < 0)
             return -1;
         av_freep(&vfilters);
     } else {
-        if(avfilter_link(curr_filter, 0, ist->out_video_filter, 0) < 0)
+        if (avfilter_link(last_filter, 0, ist->out_video_filter, 0) < 0)
             return -1;
     }
 
-    {
-        char scale_sws_opts[128];
-        snprintf(scale_sws_opts, sizeof(scale_sws_opts), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL));
-        filt_graph_all->scale_sws_opts = av_strdup(scale_sws_opts);
-    }
+    snprintf(args, sizeof(args), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL));
+    graph->scale_sws_opts = av_strdup(args);
 
     /* configure all the filter links */
-    if(avfilter_graph_check_validity(filt_graph_all, NULL))
+    if (avfilter_graph_check_validity(graph, NULL))
         return -1;
-    if(avfilter_graph_config_formats(filt_graph_all, NULL))
+    if (avfilter_graph_config_formats(graph, NULL))
         return -1;
-    if(avfilter_graph_config_links(filt_graph_all, NULL))
+    if (avfilter_graph_config_links(graph, NULL))
         return -1;
 
     codec->width = ist->out_video_filter->inputs[0]->w;
@@ -547,10 +543,6 @@ static void term_init(void)
 #ifdef SIGXCPU
     signal(SIGXCPU, sigterm_handler);
 #endif
-
-#if CONFIG_BEOS_NETSERVER
-    fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
-#endif
 }
 
 /* read a key without blocking */
@@ -559,7 +551,6 @@ static int read_key(void)
 #if HAVE_TERMIOS_H
     int n = 1;
     unsigned char ch;
-#if !CONFIG_BEOS_NETSERVER
     struct timeval tv;
     fd_set rfds;
 
@@ -568,7 +559,6 @@ static int read_key(void)
     tv.tv_sec = 0;
     tv.tv_usec = 0;
     n = select(1, &rfds, NULL, NULL, &tv);
-#endif
     if (n > 0) {
         n = read(0, &ch, 1);
         if (n == 1)
@@ -631,11 +621,6 @@ static int av_exit(int ret)
 
     av_free(video_standard);
 
-#if CONFIG_POWERPC_PERF
-    void powerpc_display_perf_report(void);
-    powerpc_display_perf_report();
-#endif /* CONFIG_POWERPC_PERF */
-
     for (i=0;i<AVMEDIA_TYPE_NB;i++)
         av_free(avcodec_opts[i]);
     av_free(avformat_opts);
@@ -826,6 +811,7 @@ need_realloc:
     audio_buf_size= (allocated_for_size + isize*dec->channels - 1) / (isize*dec->channels);
     audio_buf_size= (audio_buf_size*enc->sample_rate + dec->sample_rate) / dec->sample_rate;
     audio_buf_size= audio_buf_size*2 + 10000; //safety factors for the deprecated resampling API
+    audio_buf_size= FFMAX(audio_buf_size, enc->frame_size);
     audio_buf_size*= osize*enc->channels;
 
     audio_out_size= FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);
@@ -1526,9 +1512,8 @@ static int output_packet(AVInputStream *ist, int ist_index,
     void *buffer_to_free;
     static unsigned int samples_size= 0;
     AVSubtitle subtitle, *subtitle_to_free;
-    int got_subtitle;
 #if CONFIG_AVFILTER
-    int loop;
+    int frame_available;
 #endif
 
     AVPacket avpkt;
@@ -1621,10 +1606,10 @@ static int output_packet(AVInputStream *ist, int ist_index,
                     break;
             case AVMEDIA_TYPE_SUBTITLE:
                 ret = avcodec_decode_subtitle2(ist->st->codec,
-                                               &subtitle, &got_subtitle, &avpkt);
+                                               &subtitle, &got_picture, &avpkt);
                 if (ret < 0)
                     goto fail_decode;
-                if (!got_subtitle) {
+                if (!got_picture) {
                     goto discard_packet;
                 }
                 subtitle_to_free = &subtitle;
@@ -1689,14 +1674,14 @@ static int output_packet(AVInputStream *ist, int ist_index,
                 usleep(pts - now);
         }
 #if CONFIG_AVFILTER
-        loop = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
+        frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
             !ist->out_video_filter || avfilter_poll_frame(ist->out_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(loop) {
+        while (frame_available) {
             if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->out_video_filter)
                 get_filtered_video_pic(ist->out_video_filter, &ist->picref, &picture, &ist->pts);
 #endif
@@ -1789,7 +1774,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
                     }
                 }
 #if CONFIG_AVFILTER
-                loop =  (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+                frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
                         ist->out_video_filter && avfilter_poll_frame(ist->out_video_filter->inputs[0]);
 #endif
             }
@@ -1845,17 +1830,17 @@ static int output_packet(AVInputStream *ist, int ist_index,
                                 int osize = av_get_bits_per_sample_format(enc->sample_fmt) >> 3;
                                 int fs_tmp = enc->frame_size;
 
-                                av_fifo_generic_read(ost->fifo, samples, fifo_bytes, NULL);
+                                av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
                                 if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
                                     enc->frame_size = fifo_bytes / (osize * enc->channels);
                                 } else { /* pad */
                                     int frame_bytes = enc->frame_size*osize*enc->channels;
-                                    if (samples_size < frame_bytes)
+                                    if (allocated_audio_buf_size < frame_bytes)
                                         av_exit(1);
-                                    memset((uint8_t*)samples+fifo_bytes, 0, frame_bytes - fifo_bytes);
+                                    memset(audio_buf+fifo_bytes, 0, frame_bytes - fifo_bytes);
                                 }
 
-                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
+                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf);
                                 pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
                                                           ost->st->time_base.num, enc->sample_rate);
                                 enc->frame_size = fs_tmp;
@@ -2163,6 +2148,11 @@ static int av_transcode(AVFormatContext **output_files,
         codec->chroma_sample_location = icodec->chroma_sample_location;
 
         if (ost->st->stream_copy) {
+            uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
+
+            if (extra_size > INT_MAX)
+                goto fail;
+
             /* if stream_copy is selected, no need to decode or encode */
             codec->codec_id = icodec->codec_id;
             codec->codec_type = icodec->codec_type;
@@ -2175,7 +2165,10 @@ static int av_transcode(AVFormatContext **output_files,
             }
 
             codec->bit_rate = icodec->bit_rate;
-            codec->extradata= icodec->extradata;
+            codec->extradata= av_mallocz(extra_size);
+            if (!codec->extradata)
+                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){
                 codec->time_base = icodec->time_base;
@@ -2298,7 +2291,7 @@ static int av_transcode(AVFormatContext **output_files,
                          pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,
                          i);
                 if (codec->flags & CODEC_FLAG_PASS1) {
-                    f = fopen(logfilename, "w");
+                    f = fopen(logfilename, "wb");
                     if (!f) {
                         fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno));
                         av_exit(1);
@@ -2665,9 +2658,9 @@ static int av_transcode(AVFormatContext **output_files,
         }
     }
 #if CONFIG_AVFILTER
-    if (filt_graph_all) {
-        avfilter_graph_destroy(filt_graph_all);
-        av_freep(&filt_graph_all);
+    if (graph) {
+        avfilter_graph_destroy(graph);
+        av_freep(&graph);
     }
 #endif
 
@@ -2689,6 +2682,8 @@ static int av_transcode(AVFormatContext **output_files,
         for(i=0;i<nb_ostreams;i++) {
             ost = ost_table[i];
             if (ost) {
+                if (ost->st->stream_copy)
+                    av_freep(&ost->st->codec->extradata);
                 if (ost->logfile) {
                     fclose(ost->logfile);
                     ost->logfile = NULL;
@@ -2772,6 +2767,7 @@ static void opt_frame_crop_top(const char *arg)
         fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
         av_exit(1);
     }
+    fprintf(stderr, "-crop* is deprecated in favor of the crop avfilter\n");
     frame_height -= frame_topBand;
 }
 
@@ -2786,6 +2782,7 @@ static void opt_frame_crop_bottom(const char *arg)
         fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
         av_exit(1);
     }
+    fprintf(stderr, "-crop* is deprecated in favor of the crop avfilter\n");
     frame_height -= frame_bottomBand;
 }
 
@@ -2800,6 +2797,7 @@ static void opt_frame_crop_left(const char *arg)
         fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
         av_exit(1);
     }
+    fprintf(stderr, "-crop* is deprecated in favor of the crop avfilter\n");
     frame_width -= frame_leftBand;
 }
 
@@ -2814,6 +2812,7 @@ static void opt_frame_crop_right(const char *arg)
         fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
         av_exit(1);
     }
+    fprintf(stderr, "-crop* is deprecated in favor of the crop avfilter\n");
     frame_width -= frame_rightBand;
 }
 
@@ -2826,7 +2825,7 @@ static void opt_frame_size(const char *arg)
 }
 
 static void opt_pad(const char *arg) {
-    fprintf(stderr, "Please use vfilters=pad\n");
+    fprintf(stderr, "Please use vf=pad\n");
     av_exit(1);
 }
 
@@ -3063,9 +3062,9 @@ static int opt_start_time(const char *opt, const char *arg)
     return 0;
 }
 
-static int opt_rec_timestamp(const char *opt, const char *arg)
+static int opt_recording_timestamp(const char *opt, const char *arg)
 {
-    rec_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
+    recording_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
     return 0;
 }
 
@@ -3075,7 +3074,7 @@ static int opt_input_ts_offset(const char *opt, const char *arg)
     return 0;
 }
 
-static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
+static enum CodecID find_codec_or_die(const char *name, int type, int encoder, int strict)
 {
     const char *codec_string = encoder ? "encoder" : "decoder";
     AVCodec *codec;
@@ -3093,6 +3092,19 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
         fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
         av_exit(1);
     }
+    if(codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
+       strict > FF_COMPLIANCE_EXPERIMENTAL) {
+        fprintf(stderr, "%s '%s' is experimental and might produce bad "
+                "results.\nAdd '-strict experimental' if you want to use it.\n",
+                codec_string, codec->name);
+        codec = encoder ?
+            avcodec_find_encoder(codec->id) :
+            avcodec_find_decoder(codec->id);
+        if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
+            fprintf(stderr, "Or use the non experimental %s '%s'.\n",
+                    codec_string, codec->name);
+        av_exit(1);
+    }
     return codec->id;
 }
 
@@ -3140,9 +3152,15 @@ static void opt_input_file(const char *filename)
 
     set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
 
-    ic->video_codec_id   = find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0);
-    ic->audio_codec_id   = find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0);
-    ic->subtitle_codec_id= find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0);
+    ic->video_codec_id   =
+        find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0,
+                          avcodec_opts[AVMEDIA_TYPE_VIDEO   ]->strict_std_compliance);
+    ic->audio_codec_id   =
+        find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0,
+                          avcodec_opts[AVMEDIA_TYPE_AUDIO   ]->strict_std_compliance);
+    ic->subtitle_codec_id=
+        find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0,
+                          avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
     ic->flags |= AVFMT_FLAG_NONBLOCK;
 
     if(pgmyuv_compatibility_hack)
@@ -3333,7 +3351,7 @@ static void new_video_stream(AVFormatContext *oc)
     AVCodecContext *video_enc;
     enum CodecID codec_id;
 
-    st = av_new_stream(oc, oc->nb_streams);
+    st = av_new_stream(oc, streamid_map[oc->nb_streams]);
     if (!st) {
         fprintf(stderr, "Could not alloc stream\n");
         av_exit(1);
@@ -3371,7 +3389,8 @@ static void new_video_stream(AVFormatContext *oc)
         AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1};
 
         if (video_codec_name) {
-            codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1);
+            codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
+                                         video_enc->strict_std_compliance);
             codec = avcodec_find_encoder_by_name(video_codec_name);
             output_codecs[nb_ocodecs] = codec;
         } else {
@@ -3470,7 +3489,7 @@ static void new_audio_stream(AVFormatContext *oc)
     AVCodecContext *audio_enc;
     enum CodecID codec_id;
 
-    st = av_new_stream(oc, oc->nb_streams);
+    st = av_new_stream(oc, streamid_map[oc->nb_streams]);
     if (!st) {
         fprintf(stderr, "Could not alloc stream\n");
         av_exit(1);
@@ -3502,7 +3521,8 @@ static void new_audio_stream(AVFormatContext *oc)
         set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
 
         if (audio_codec_name) {
-            codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1);
+            codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
+                                         audio_enc->strict_std_compliance);
             codec = avcodec_find_encoder_by_name(audio_codec_name);
             output_codecs[nb_ocodecs] = codec;
         } else {
@@ -3542,7 +3562,7 @@ static void new_subtitle_stream(AVFormatContext *oc)
     AVStream *st;
     AVCodecContext *subtitle_enc;
 
-    st = av_new_stream(oc, oc->nb_streams);
+    st = av_new_stream(oc, streamid_map[oc->nb_streams]);
     if (!st) {
         fprintf(stderr, "Could not alloc stream\n");
         av_exit(1);
@@ -3562,7 +3582,8 @@ static void new_subtitle_stream(AVFormatContext *oc)
         st->stream_copy = 1;
     } else {
         set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
-        subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1);
+        subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
+                                                   subtitle_enc->strict_std_compliance);
         output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name);
     }
     nb_ocodecs++;
@@ -3610,6 +3631,27 @@ static void opt_new_subtitle_stream(void)
     new_subtitle_stream(oc);
 }
 
+/* arg format is "output-stream-index:streamid-value". */
+static void opt_streamid(const char *opt, const char *arg)
+{
+    int idx;
+    char *p;
+    char idx_str[16];
+
+    strncpy(idx_str, arg, sizeof(idx_str));
+    idx_str[sizeof(idx_str)-1] = '\0';
+    p = strchr(idx_str, ':');
+    if (!p) {
+        fprintf(stderr,
+                "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
+                arg, opt);
+        av_exit(1);
+    }
+    *p++ = '\0';
+    idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
+    streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
+}
+
 static void opt_output_file(const char *filename)
 {
     AVFormatContext *oc;
@@ -3696,7 +3738,7 @@ static void opt_output_file(const char *filename)
             new_subtitle_stream(oc);
         }
 
-        oc->timestamp = rec_timestamp;
+        oc->timestamp = recording_timestamp;
 
         for(; metadata_count>0; metadata_count--){
             av_metadata_set2(&oc->metadata, metadata[metadata_count-1].key,
@@ -3757,6 +3799,8 @@ static void opt_output_file(const char *filename)
     oc->flags |= AVFMT_FLAG_NONBLOCK;
 
     set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM);
+
+    memset(streamid_map, 0, sizeof(streamid_map));
 }
 
 /* same option as mencoder */
@@ -4143,7 +4187,7 @@ static const OptionDef options[] = {
     { "ss", OPT_FUNC2 | HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
     { "itsoffset", OPT_FUNC2 | HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
     { "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "stream:scale" },
-    { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)opt_rec_timestamp}, "set the timestamp ('now' to set the current time)", "time" },
+    { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)opt_recording_timestamp}, "set the recording timestamp ('now' to set the current time)", "time" },
     { "metadata", OPT_FUNC2 | HAS_ARG, {(void*)opt_metadata}, "add metadata", "string=string" },
     { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[AVMEDIA_TYPE_DATA]}, "set the number of data frames to record", "number" },
     { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
@@ -4178,10 +4222,10 @@ static const OptionDef options[] = {
     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
     { "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format, 'list' as argument shows all the pixel formats supported", "format" },
-    { "croptop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_top}, "set top crop band size (in pixels)", "size" },
-    { "cropbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" },
-    { "cropleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_left}, "set left crop band size (in pixels)", "size" },
-    { "cropright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_right}, "set right crop band size (in pixels)", "size" },
+    { "croptop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_top}, "Deprecated, please use the crop avfilter", "size" },
+    { "cropbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_bottom}, "Deprecated, please use the crop avfilter", "size" },
+    { "cropleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_left}, "Deprecated, please use the crop avfilter", "size" },
+    { "cropright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_right}, "Deprecated, please use the crop avfilter", "size" },
     { "padtop", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "set top pad band size (in pixels)", "size" },
     { "padbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "set bottom pad band size (in pixels)", "size" },
     { "padleft", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "set left pad band size (in pixels)", "size" },
@@ -4204,7 +4248,7 @@ static const OptionDef options[] = {
     { "vstats", OPT_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" },
     { "vstats_file", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_vstats_file}, "dump video coding statistics to file", "file" },
 #if CONFIG_AVFILTER
-    { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
+    { "vf", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
 #endif
     { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
     { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },
@@ -4215,6 +4259,7 @@ static const OptionDef options[] = {
     { "vlang", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void *)&video_language}, "set the ISO 639 language code (3 letters) of the current video stream" , "code" },
     { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" },
     { "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&force_fps}, "force the selected framerate, disable the best supported framerate selection" },
+    { "streamid", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_streamid}, "set the value of an outfile streamid", "streamIndex:value" },
 
     /* audio options */
     { "ab", OPT_FUNC2 | HAS_ARG | OPT_AUDIO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },