Browse code

support for adding new components (syntax: ffmpeg -i input_file [output options] output_file [[component output options] {-newaudio|-newvideo|-newsubtitle}]... - added subtitle support - added '-alang' option

Originally committed as revision 4351 to svn://svn.ffmpeg.org/ffmpeg/trunk

Fabrice Bellard authored on 2005/06/03 23:31:45
Showing 1 changed files
... ...
@@ -98,7 +98,7 @@ static int frame_topBand  = 0;
98 98
 static int frame_bottomBand = 0;
99 99
 static int frame_leftBand  = 0;
100 100
 static int frame_rightBand = 0;
101
-static int max_frames[3] = {INT_MAX, INT_MAX, INT_MAX};
101
+static int max_frames[4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX};
102 102
 static int frame_rate = 25;
103 103
 static int frame_rate_base = 1;
104 104
 static int video_bit_rate = 200*1000;
... ...
@@ -219,6 +219,10 @@ static int audio_disable = 0;
219 219
 static int audio_channels = 1;
220 220
 static int audio_codec_id = CODEC_ID_NONE;
221 221
 static int audio_codec_tag = 0;
222
+static char *audio_language = NULL;
223
+
224
+static int subtitle_codec_id = CODEC_ID_NONE;
225
+static char *subtitle_language = NULL;
222 226
 
223 227
 static int mux_rate= 0;
224 228
 static int mux_packet_size= 0;
... ...
@@ -244,6 +248,7 @@ static int bitexact = 0;
244 244
 static char *pass_logfilename = NULL;
245 245
 static int audio_stream_copy = 0;
246 246
 static int video_stream_copy = 0;
247
+static int subtitle_stream_copy = 0;
247 248
 static int video_sync_method= 1;
248 249
 static int audio_sync_method= 0;
249 250
 static int copy_ts= 0;
... ...
@@ -693,6 +698,58 @@ static void fill_pad_region(AVPicture* img, int height, int width,
693 693
     }
694 694
 }
695 695
 
696
+static void do_subtitle_out(AVFormatContext *s, 
697
+                            AVOutputStream *ost, 
698
+                            AVInputStream *ist,
699
+                            AVSubtitle *sub,
700
+                            int64_t pts)
701
+{
702
+    static uint8_t *subtitle_out = NULL;
703
+    int subtitle_out_max_size = 65536;
704
+    int subtitle_out_size, nb, i;
705
+    AVCodecContext *enc;
706
+    AVPacket pkt;
707
+
708
+    if (pts == AV_NOPTS_VALUE) {
709
+        fprintf(stderr, "Subtitle packets must have a pts\n");
710
+        return;
711
+    }
712
+
713
+    enc = &ost->st->codec;
714
+
715
+    if (!subtitle_out) {
716
+        subtitle_out = av_malloc(subtitle_out_max_size);
717
+    }
718
+
719
+    /* Note: DVB subtitle need one packet to draw them and one other
720
+       packet to clear them */
721
+    /* XXX: signal it in the codec context ? */
722
+    if (enc->codec_id == CODEC_ID_DVB_SUBTITLE)
723
+        nb = 2;
724
+    else
725
+        nb = 1;
726
+
727
+    for(i = 0; i < nb; i++) {
728
+        subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out, 
729
+                                                    subtitle_out_max_size, sub);
730
+        
731
+        av_init_packet(&pkt);
732
+        pkt.stream_index = ost->index;
733
+        pkt.data = subtitle_out;
734
+        pkt.size = subtitle_out_size;
735
+        pkt.pts = av_rescale_q(av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
736
+        if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) {
737
+            /* XXX: the pts correction is handled here. Maybe handling
738
+               it in the codec would be better */
739
+            if (i == 0)
740
+                pkt.pts += 90 * sub->start_display_time;
741
+            else
742
+                pkt.pts += 90 * sub->end_display_time;
743
+        }
744
+        av_interleaved_write_frame(s, &pkt);
745
+    }
746
+}
747
+
696 748
 static int bit_buffer_size= 1024*256;
697 749
 static uint8_t *bit_buffer= NULL;
698 750
 
... ...
@@ -1130,6 +1187,8 @@ static int output_packet(AVInputStream *ist, int ist_index,
1130 1130
     void *buffer_to_free;
1131 1131
     static int samples_size= 0;
1132 1132
     static short *samples= NULL;
1133
+    AVSubtitle subtitle, *subtitle_to_free;
1134
+    int got_subtitle;
1133 1135
     
1134 1136
     if(!pkt){
1135 1137
         ist->pts= ist->next_pts; // needed for last packet if vsync=0
... ...
@@ -1153,6 +1212,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
1153 1153
         /* decode the packet if needed */
1154 1154
         data_buf = NULL; /* fail safe */
1155 1155
         data_size = 0;
1156
+        subtitle_to_free = NULL;
1156 1157
         if (ist->decoding_needed) {
1157 1158
             switch(ist->st->codec.codec_type) {
1158 1159
             case CODEC_TYPE_AUDIO:{
... ...
@@ -1197,10 +1257,21 @@ static int output_packet(AVInputStream *ist, int ist_index,
1197 1197
                     }
1198 1198
                     len = 0;
1199 1199
                     break;
1200
-                default:
1200
+            case CODEC_TYPE_SUBTITLE:
1201
+                ret = avcodec_decode_subtitle(&ist->st->codec, 
1202
+                                              &subtitle, &got_subtitle, ptr, len);
1203
+                if (ret < 0)
1201 1204
                     goto fail_decode;
1205
+                if (!got_subtitle) {
1206
+                    goto discard_packet;
1202 1207
                 }
1203
-            } else {
1208
+                subtitle_to_free = &subtitle;
1209
+                len = 0;
1210
+                break;
1211
+            default:
1212
+                goto fail_decode;
1213
+            }
1214
+        } else {
1204 1215
                 switch(ist->st->codec.codec_type) {
1205 1216
                 case CODEC_TYPE_AUDIO:
1206 1217
                     ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec.frame_size) / 
... ...
@@ -1293,6 +1364,10 @@ static int output_packet(AVInputStream *ist, int ist_index,
1293 1293
                                     if (do_vstats && frame_size)
1294 1294
                                         do_video_stats(os, ost, frame_size);
1295 1295
                                 break;
1296
+                            case CODEC_TYPE_SUBTITLE:
1297
+                                do_subtitle_out(os, ost, ist, &subtitle,
1298
+                                                pkt->pts);
1299
+                                break;
1296 1300
                             default:
1297 1301
                                 av_abort();
1298 1302
                             }
... ...
@@ -1322,9 +1397,16 @@ static int output_packet(AVInputStream *ist, int ist_index,
1322 1322
                                 opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
1323 1323
                             else
1324 1324
                                 opkt.pts= AV_NOPTS_VALUE;
1325
-                            opkt.dts= av_rescale_q(av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
1325
+
1326
+                            {
1327
+                                int64_t dts;
1328
+                                if (pkt->dts == AV_NOPTS_VALUE)
1329
+                                    dts = ist->next_pts;
1330
+                                else
1331
+                                    dts= av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
1332
+                                opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);
1333
+                            }
1326 1334
                             opkt.flags= pkt->flags;
1327
-                            
1328 1335
                             av_interleaved_write_frame(os, &opkt);
1329 1336
                             ost->st->codec.frame_number++;
1330 1337
                             ost->frame_number++;
... ...
@@ -1332,6 +1414,12 @@ static int output_packet(AVInputStream *ist, int ist_index,
1332 1332
                     }
1333 1333
                 }
1334 1334
             av_free(buffer_to_free);
1335
+            /* XXX: allocate the subtitles in the codec ? */
1336
+            if (subtitle_to_free) {
1337
+                av_free(subtitle_to_free->bitmap);
1338
+                av_free(subtitle_to_free->rgba_palette);
1339
+                subtitle_to_free = NULL;
1340
+            }
1335 1341
         }
1336 1342
  discard_packet:
1337 1343
     if (pkt == NULL) {
... ...
@@ -1579,6 +1667,8 @@ static int av_encode(AVFormatContext **output_files,
1579 1579
                 codec->height = icodec->height;
1580 1580
                 codec->has_b_frames = icodec->has_b_frames;
1581 1581
                 break;
1582
+            case CODEC_TYPE_SUBTITLE:
1583
+                break;
1582 1584
             default:
1583 1585
                 av_abort();
1584 1586
             }
... ...
@@ -1686,8 +1776,13 @@ static int av_encode(AVFormatContext **output_files,
1686 1686
                 ost->encoding_needed = 1;
1687 1687
                 ist->decoding_needed = 1;
1688 1688
                 break;
1689
+            case CODEC_TYPE_SUBTITLE:
1690
+                ost->encoding_needed = 1;
1691
+                ist->decoding_needed = 1;
1692
+                break;
1689 1693
             default:
1690 1694
                 av_abort();
1695
+                break;
1691 1696
             }
1692 1697
             /* two pass mode */
1693 1698
             if (ost->encoding_needed && 
... ...
@@ -1984,7 +2079,7 @@ static int av_encode(AVFormatContext **output_files,
1984 1984
             av_free_packet(&pkt);
1985 1985
             goto redo;
1986 1986
         }
1987
-        
1987
+
1988 1988
     discard_packet:
1989 1989
         av_free_packet(&pkt);
1990 1990
         
... ...
@@ -2722,28 +2817,34 @@ static void opt_audio_device(const char *arg)
2722 2722
     audio_device = av_strdup(arg);
2723 2723
 }
2724 2724
 
2725
-static void opt_audio_codec(const char *arg)
2725
+static void opt_codec(int *pstream_copy, int *pcodec_id,
2726
+                      int codec_type, const char *arg)
2726 2727
 {
2727 2728
     AVCodec *p;
2728 2729
 
2729 2730
     if (!strcmp(arg, "copy")) {
2730
-        audio_stream_copy = 1;
2731
+        *pstream_copy = 1;
2731 2732
     } else {
2732 2733
         p = first_avcodec;
2733 2734
         while (p) {
2734
-            if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_AUDIO)
2735
+            if (!strcmp(p->name, arg) && p->type == codec_type)
2735 2736
                 break;
2736 2737
             p = p->next;
2737 2738
         }
2738 2739
         if (p == NULL) {
2739
-            fprintf(stderr, "Unknown audio codec '%s'\n", arg);
2740
+            fprintf(stderr, "Unknown codec '%s'\n", arg);
2740 2741
             exit(1);
2741 2742
         } else {
2742
-            audio_codec_id = p->id;
2743
+            *pcodec_id = p->id;
2743 2744
         }
2744 2745
     }
2745 2746
 }
2746 2747
 
2748
+static void opt_audio_codec(const char *arg)
2749
+{
2750
+    opt_codec(&audio_stream_copy, &audio_codec_id, CODEC_TYPE_AUDIO, arg);
2751
+}
2752
+
2747 2753
 static void opt_audio_tag(const char *arg)
2748 2754
 {
2749 2755
     char *tail;
... ...
@@ -2811,24 +2912,12 @@ static void opt_motion_estimation(const char *arg)
2811 2811
 
2812 2812
 static void opt_video_codec(const char *arg)
2813 2813
 {
2814
-    AVCodec *p;
2814
+    opt_codec(&video_stream_copy, &video_codec_id, CODEC_TYPE_VIDEO, arg);
2815
+}
2815 2816
 
2816
-    if (!strcmp(arg, "copy")) {
2817
-        video_stream_copy = 1;
2818
-    } else {
2819
-        p = first_avcodec;
2820
-        while (p) {
2821
-            if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_VIDEO)
2822
-                break;
2823
-            p = p->next;
2824
-        }
2825
-        if (p == NULL) {
2826
-            fprintf(stderr, "Unknown video codec '%s'\n", arg);
2827
-            exit(1);
2828
-        } else {
2829
-            video_codec_id = p->id;
2830
-        }
2831
-    }
2817
+static void opt_subtitle_codec(const char *arg)
2818
+{
2819
+    opt_codec(&subtitle_stream_copy, &subtitle_codec_id, CODEC_TYPE_SUBTITLE, arg);
2832 2820
 }
2833 2821
 
2834 2822
 static void opt_map(const char *arg)
... ...
@@ -3011,6 +3100,8 @@ static void opt_input_file(const char *filename)
3011 3011
             break;
3012 3012
         case CODEC_TYPE_DATA:
3013 3013
             break;
3014
+        case CODEC_TYPE_SUBTITLE:
3015
+            break;
3014 3016
         default:
3015 3017
             av_abort();
3016 3018
         }
... ...
@@ -3058,6 +3149,7 @@ static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
3058 3058
                 has_video = 1;
3059 3059
                 break;
3060 3060
             case CODEC_TYPE_DATA:
3061
+            case CODEC_TYPE_SUBTITLE:
3061 3062
                 break;
3062 3063
             default:
3063 3064
                 av_abort();
... ...
@@ -3068,12 +3160,407 @@ static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
3068 3068
     *has_audio_ptr = has_audio;
3069 3069
 }
3070 3070
 
3071
-static void opt_output_file(const char *filename)
3071
+static void new_video_stream(AVFormatContext *oc)
3072 3072
 {
3073 3073
     AVStream *st;
3074
-    AVFormatContext *oc;
3075
-    int use_video, use_audio, nb_streams, input_has_video, input_has_audio;
3074
+    AVCodecContext *video_enc;
3075
+    int codec_id;
3076
+    
3077
+    st = av_new_stream(oc, oc->nb_streams);
3078
+    if (!st) {
3079
+        fprintf(stderr, "Could not alloc stream\n");
3080
+        exit(1);
3081
+    }
3082
+#if defined(HAVE_THREADS)
3083
+    if(thread_count>1)
3084
+        avcodec_thread_init(&st->codec, thread_count);
3085
+#endif
3086
+    
3087
+    video_enc = &st->codec;
3088
+    
3089
+    if(video_codec_tag)
3090
+        video_enc->codec_tag= video_codec_tag;
3091
+    
3092
+    if (oc->oformat->flags & AVFMT_GLOBALHEADER) 
3093
+        video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
3094
+    if (video_stream_copy) {
3095
+        st->stream_copy = 1;
3096
+        video_enc->codec_type = CODEC_TYPE_VIDEO;
3097
+    } else {
3098
+        char *p;
3099
+        int i;
3100
+        AVCodec *codec;
3101
+        
3102
+        codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO);
3103
+        if (video_codec_id != CODEC_ID_NONE)
3104
+            codec_id = video_codec_id;
3105
+                
3106
+        video_enc->codec_id = codec_id;
3107
+        codec = avcodec_find_encoder(codec_id);
3108
+                
3109
+        video_enc->bit_rate = video_bit_rate;
3110
+        video_enc->bit_rate_tolerance = video_bit_rate_tolerance;
3111
+        video_enc->time_base.den = frame_rate; 
3112
+        video_enc->time_base.num = frame_rate_base; 
3113
+        if(codec && codec->supported_framerates){
3114
+            const AVRational *p= codec->supported_framerates;
3115
+            AVRational req= (AVRational){frame_rate, frame_rate_base};
3116
+            const AVRational *best=NULL;
3117
+            AVRational best_error= (AVRational){INT_MAX, 1};
3118
+            for(; p->den!=0; p++){
3119
+                AVRational error= av_sub_q(req, *p);
3120
+                if(error.num <0) error.num *= -1;
3121
+                if(av_cmp_q(error, best_error) < 0){
3122
+                    best_error= error;
3123
+                    best= p;
3124
+                }
3125
+            }
3126
+            video_enc->time_base.den= best->num;
3127
+            video_enc->time_base.num= best->den;
3128
+        }
3129
+                
3130
+        video_enc->width = frame_width + frame_padright + frame_padleft;
3131
+        video_enc->height = frame_height + frame_padtop + frame_padbottom;
3132
+        video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
3133
+        video_enc->pix_fmt = frame_pix_fmt;
3134
+
3135
+        if(codec && codec->pix_fmts){
3136
+            const enum PixelFormat *p= codec->pix_fmts;
3137
+            for(; *p!=-1; p++){
3138
+                if(*p == video_enc->pix_fmt)
3139
+                    break;
3140
+            }
3141
+            if(*p == -1)
3142
+                video_enc->pix_fmt = codec->pix_fmts[0];
3143
+        }
3144
+
3145
+        if (!intra_only)
3146
+            video_enc->gop_size = gop_size;
3147
+        else
3148
+            video_enc->gop_size = 0;
3149
+        if (video_qscale || same_quality) {
3150
+            video_enc->flags |= CODEC_FLAG_QSCALE;
3151
+            video_enc->global_quality= 
3152
+                st->quality = FF_QP2LAMBDA * video_qscale;
3153
+        }
3154
+
3155
+        if(intra_matrix)
3156
+            video_enc->intra_matrix = intra_matrix;
3157
+        if(inter_matrix)
3158
+            video_enc->inter_matrix = inter_matrix;
3159
+
3160
+        if(bitexact)
3161
+            video_enc->flags |= CODEC_FLAG_BITEXACT;
3162
+
3163
+        video_enc->mb_decision = mb_decision;
3164
+        video_enc->mb_cmp = mb_cmp;
3165
+        video_enc->ildct_cmp = ildct_cmp;
3166
+        video_enc->me_sub_cmp = sub_cmp;
3167
+        video_enc->me_cmp = cmp;
3168
+        video_enc->me_pre_cmp = pre_cmp;
3169
+        video_enc->pre_me = pre_me;
3170
+        video_enc->lumi_masking = lumi_mask;
3171
+        video_enc->dark_masking = dark_mask;
3172
+        video_enc->spatial_cplx_masking = scplx_mask;
3173
+        video_enc->temporal_cplx_masking = tcplx_mask;
3174
+        video_enc->p_masking = p_mask;
3175
+        video_enc->quantizer_noise_shaping= qns;
3176
+                
3177
+        if (use_umv) {
3178
+            video_enc->flags |= CODEC_FLAG_H263P_UMV;
3179
+        }
3180
+        if (use_ss) {
3181
+            video_enc->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
3182
+        }
3183
+        if (use_aic) {
3184
+            video_enc->flags |= CODEC_FLAG_H263P_AIC;
3185
+        }
3186
+        if (use_aiv) {
3187
+            video_enc->flags |= CODEC_FLAG_H263P_AIV;
3188
+        }
3189
+        if (use_4mv) {
3190
+            video_enc->flags |= CODEC_FLAG_4MV;
3191
+        }
3192
+        if (use_obmc) {
3193
+            video_enc->flags |= CODEC_FLAG_OBMC;
3194
+        }
3195
+        if (use_loop) {
3196
+            video_enc->flags |= CODEC_FLAG_LOOP_FILTER;
3197
+        }
3198
+            
3199
+        if(use_part) {
3200
+            video_enc->flags |= CODEC_FLAG_PART;
3201
+        }
3202
+        if (use_alt_scan) {
3203
+            video_enc->flags |= CODEC_FLAG_ALT_SCAN;
3204
+        }
3205
+        if (use_trell) {
3206
+            video_enc->flags |= CODEC_FLAG_TRELLIS_QUANT;
3207
+        }
3208
+        if (use_mv0) {
3209
+            video_enc->flags |= CODEC_FLAG_MV0;
3210
+        }
3211
+        if (do_normalize_aqp) {
3212
+            video_enc->flags |= CODEC_FLAG_NORMALIZE_AQP;
3213
+        }
3214
+        if (use_scan_offset) {
3215
+            video_enc->flags |= CODEC_FLAG_SVCD_SCAN_OFFSET;
3216
+        }
3217
+        if (closed_gop) {
3218
+            video_enc->flags |= CODEC_FLAG_CLOSED_GOP;
3219
+        }
3220
+        if (strict_gop) {
3221
+            video_enc->flags2 |= CODEC_FLAG2_STRICT_GOP;
3222
+        }
3223
+        if (use_qpel) {
3224
+            video_enc->flags |= CODEC_FLAG_QPEL;
3225
+        }
3226
+        if (use_qprd) {
3227
+            video_enc->flags |= CODEC_FLAG_QP_RD;
3228
+        }
3229
+        if (use_cbprd) {
3230
+            video_enc->flags |= CODEC_FLAG_CBP_RD;
3231
+        }
3232
+        if (b_frames) {
3233
+            video_enc->max_b_frames = b_frames;
3234
+            video_enc->b_frame_strategy = b_strategy;
3235
+            video_enc->b_quant_factor = 2.0;
3236
+        }
3237
+        if (do_interlace_dct) {
3238
+            video_enc->flags |= CODEC_FLAG_INTERLACED_DCT;
3239
+        }
3240
+        if (do_interlace_me) {
3241
+            video_enc->flags |= CODEC_FLAG_INTERLACED_ME;
3242
+        }
3243
+        if (no_output) {
3244
+            video_enc->flags2 |= CODEC_FLAG2_NO_OUTPUT;
3245
+        }
3246
+        if (gray_only) {
3247
+            video_enc->flags |= CODEC_FLAG_GRAY;
3248
+        }
3249
+        video_enc->qmin = video_qmin;
3250
+        video_enc->qmax = video_qmax;
3251
+        video_enc->lmin = video_lmin;
3252
+        video_enc->lmax = video_lmax;
3253
+        video_enc->rc_qsquish = video_qsquish;
3254
+        video_enc->luma_elim_threshold = video_lelim;
3255
+        video_enc->chroma_elim_threshold = video_celim;
3256
+        video_enc->mb_lmin = video_mb_lmin;
3257
+        video_enc->mb_lmax = video_mb_lmax;
3258
+        video_enc->max_qdiff = video_qdiff;
3259
+        video_enc->qblur = video_qblur;
3260
+        video_enc->qcompress = video_qcomp;
3261
+        video_enc->rc_eq = video_rc_eq;
3262
+        video_enc->debug = debug;
3263
+        video_enc->debug_mv = debug_mv;
3264
+        video_enc->workaround_bugs = workaround_bugs;
3265
+        video_enc->thread_count = thread_count;
3266
+        p= video_rc_override_string;
3267
+        for(i=0; p; i++){
3268
+            int start, end, q;
3269
+            int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
3270
+            if(e!=3){
3271
+                fprintf(stderr, "error parsing rc_override\n");
3272
+                exit(1);
3273
+            }
3274
+            video_enc->rc_override= 
3275
+                av_realloc(video_enc->rc_override, 
3276
+                           sizeof(RcOverride)*(i+1));
3277
+            video_enc->rc_override[i].start_frame= start;
3278
+            video_enc->rc_override[i].end_frame  = end;
3279
+            if(q>0){
3280
+                video_enc->rc_override[i].qscale= q;
3281
+                video_enc->rc_override[i].quality_factor= 1.0;
3282
+            }
3283
+            else{
3284
+                video_enc->rc_override[i].qscale= 0;
3285
+                video_enc->rc_override[i].quality_factor= -q/100.0;
3286
+            }
3287
+            p= strchr(p, '/');
3288
+            if(p) p++;
3289
+        }
3290
+        video_enc->rc_override_count=i;
3291
+
3292
+        video_enc->rc_max_rate = video_rc_max_rate;
3293
+        video_enc->rc_min_rate = video_rc_min_rate;
3294
+        video_enc->rc_buffer_size = video_rc_buffer_size;
3295
+        video_enc->rc_initial_buffer_occupancy = video_rc_buffer_size*3/4;
3296
+        video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity;
3297
+        video_enc->rc_initial_cplx= video_rc_initial_cplx;
3298
+        video_enc->i_quant_factor = video_i_qfactor;
3299
+        video_enc->b_quant_factor = video_b_qfactor;
3300
+        video_enc->i_quant_offset = video_i_qoffset;
3301
+        video_enc->b_quant_offset = video_b_qoffset;
3302
+        video_enc->intra_quant_bias = video_intra_quant_bias;
3303
+        video_enc->inter_quant_bias = video_inter_quant_bias;
3304
+        video_enc->dct_algo = dct_algo;
3305
+        video_enc->idct_algo = idct_algo;
3306
+        video_enc->me_threshold= me_threshold;
3307
+        video_enc->mb_threshold= mb_threshold;
3308
+        video_enc->intra_dc_precision= intra_dc_precision - 8;
3309
+        video_enc->strict_std_compliance = strict;
3310
+        video_enc->error_rate = error_rate;
3311
+        video_enc->noise_reduction= noise_reduction;
3312
+        video_enc->scenechange_threshold= sc_threshold;
3313
+        video_enc->me_range = me_range;
3314
+        video_enc->coder_type= coder;
3315
+        video_enc->context_model= context;
3316
+        video_enc->prediction_method= predictor;
3317
+        video_enc->profile= video_profile;
3318
+        video_enc->level= video_level;
3319
+        video_enc->nsse_weight= nsse_weight;
3320
+        video_enc->me_subpel_quality= subpel_quality;
3321
+        video_enc->me_penalty_compensation= me_penalty_compensation;
3322
+        video_enc->frame_skip_threshold= frame_skip_threshold;
3323
+        video_enc->frame_skip_factor= frame_skip_factor;
3324
+        video_enc->frame_skip_exp= frame_skip_exp;
3325
+        video_enc->frame_skip_cmp= frame_skip_cmp;
3326
+
3327
+        if(packet_size){
3328
+            video_enc->rtp_mode= 1;
3329
+            video_enc->rtp_payload_size= packet_size;
3330
+        }
3331
+            
3332
+        if (do_psnr)
3333
+            video_enc->flags|= CODEC_FLAG_PSNR;
3334
+            
3335
+        video_enc->me_method = me_method;
3336
+
3337
+        /* two pass mode */
3338
+        if (do_pass) {
3339
+            if (do_pass == 1) {
3340
+                video_enc->flags |= CODEC_FLAG_PASS1;
3341
+            } else {
3342
+                video_enc->flags |= CODEC_FLAG_PASS2;
3343
+            }
3344
+        }
3345
+    }
3346
+
3347
+    /* reset some key parameters */
3348
+    video_disable = 0;
3349
+    video_codec_id = CODEC_ID_NONE;
3350
+    video_stream_copy = 0;
3351
+}
3352
+
3353
+static void new_audio_stream(AVFormatContext *oc)
3354
+{
3355
+    AVStream *st;
3356
+    AVCodecContext *audio_enc;
3076 3357
     int codec_id;
3358
+            
3359
+    st = av_new_stream(oc, oc->nb_streams);
3360
+    if (!st) {
3361
+        fprintf(stderr, "Could not alloc stream\n");
3362
+        exit(1);
3363
+    }
3364
+#if defined(HAVE_THREADS)
3365
+    if(thread_count>1)
3366
+        avcodec_thread_init(&st->codec, thread_count);
3367
+#endif
3368
+    
3369
+    audio_enc = &st->codec;
3370
+    audio_enc->codec_type = CODEC_TYPE_AUDIO;
3371
+    
3372
+    if(audio_codec_tag)
3373
+        audio_enc->codec_tag= audio_codec_tag;
3374
+    
3375
+    if (oc->oformat->flags & AVFMT_GLOBALHEADER) 
3376
+        audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
3377
+    if (audio_stream_copy) {
3378
+        st->stream_copy = 1;
3379
+        audio_enc->channels = audio_channels;
3380
+    } else {
3381
+        codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO);
3382
+        if (audio_codec_id != CODEC_ID_NONE)
3383
+            codec_id = audio_codec_id;
3384
+        audio_enc->codec_id = codec_id;
3385
+        
3386
+        audio_enc->bit_rate = audio_bit_rate;
3387
+        audio_enc->strict_std_compliance = strict;
3388
+        audio_enc->thread_count = thread_count;
3389
+        /* For audio codecs other than AC3 or DTS we limit */
3390
+        /* the number of coded channels to stereo   */
3391
+        if (audio_channels > 2 && codec_id != CODEC_ID_AC3
3392
+            && codec_id != CODEC_ID_DTS) {
3393
+            audio_enc->channels = 2;
3394
+        } else
3395
+            audio_enc->channels = audio_channels;
3396
+    }
3397
+    audio_enc->sample_rate = audio_sample_rate;
3398
+    if (audio_language) {
3399
+        pstrcpy(st->language, sizeof(st->language), audio_language);
3400
+        av_free(audio_language);
3401
+        audio_language = NULL;
3402
+    }
3403
+
3404
+    /* reset some key parameters */
3405
+    audio_disable = 0;
3406
+    audio_codec_id = CODEC_ID_NONE;
3407
+    audio_stream_copy = 0;
3408
+}
3409
+
3410
+static void opt_new_subtitle_stream(void)
3411
+{
3412
+    AVFormatContext *oc;
3413
+    AVStream *st;
3414
+    AVCodecContext *subtitle_enc;
3415
+            
3416
+    if (nb_output_files <= 0) {
3417
+        fprintf(stderr, "At least one output file must be specified\n");
3418
+        exit(1);
3419
+    }
3420
+    oc = output_files[nb_output_files - 1];
3421
+
3422
+    st = av_new_stream(oc, oc->nb_streams);
3423
+    if (!st) {
3424
+        fprintf(stderr, "Could not alloc stream\n");
3425
+        exit(1);
3426
+    }
3427
+
3428
+    subtitle_enc = &st->codec;
3429
+    subtitle_enc->codec_type = CODEC_TYPE_SUBTITLE;
3430
+    if (subtitle_stream_copy) {
3431
+        st->stream_copy = 1;
3432
+    } else {
3433
+        subtitle_enc->codec_id = subtitle_codec_id;
3434
+    }
3435
+
3436
+    if (subtitle_language) {
3437
+        pstrcpy(st->language, sizeof(st->language), subtitle_language);
3438
+        av_free(subtitle_language);
3439
+        subtitle_language = NULL;
3440
+    }
3441
+
3442
+    subtitle_codec_id = CODEC_ID_NONE;
3443
+    subtitle_stream_copy = 0;
3444
+}
3445
+
3446
+static void opt_new_audio_stream(void)
3447
+{
3448
+    AVFormatContext *oc;
3449
+    if (nb_output_files <= 0) {
3450
+        fprintf(stderr, "At least one output file must be specified\n");
3451
+        exit(1);
3452
+    }
3453
+    oc = output_files[nb_output_files - 1];
3454
+    new_audio_stream(oc);
3455
+}
3456
+
3457
+static void opt_new_video_stream(void)
3458
+{
3459
+    AVFormatContext *oc;
3460
+    if (nb_output_files <= 0) {
3461
+        fprintf(stderr, "At least one output file must be specified\n");
3462
+        exit(1);
3463
+    }
3464
+    oc = output_files[nb_output_files - 1];
3465
+    new_video_stream(oc);
3466
+}
3467
+
3468
+static void opt_output_file(const char *filename)
3469
+{
3470
+    AVFormatContext *oc;
3471
+    int use_video, use_audio, input_has_video, input_has_audio;
3077 3472
     AVFormatParameters params, *ap = &params;
3078 3473
 
3079 3474
     if (!strcmp(filename, "-"))
... ...
@@ -3091,6 +3578,7 @@ static void opt_output_file(const char *filename)
3091 3091
     }
3092 3092
     
3093 3093
     oc->oformat = file_oformat;
3094
+    pstrcpy(oc->filename, sizeof(oc->filename), filename);
3094 3095
 
3095 3096
     if (!strcmp(file_oformat->name, "ffm") && 
3096 3097
         strstart(filename, "http:", NULL)) {
... ...
@@ -3122,328 +3610,15 @@ static void opt_output_file(const char *filename)
3122 3122
             use_video = 0;
3123 3123
         }
3124 3124
         
3125
-        nb_streams = 0;
3126 3125
         if (use_video) {
3127
-            AVCodecContext *video_enc;
3128
-            
3129
-            st = av_new_stream(oc, nb_streams++);
3130
-            if (!st) {
3131
-                fprintf(stderr, "Could not alloc stream\n");
3132
-                exit(1);
3133
-            }
3134
-#if defined(HAVE_THREADS)
3135
-            if(thread_count>1)
3136
-                avcodec_thread_init(&st->codec, thread_count);
3137
-#endif
3138
-
3139
-            video_enc = &st->codec;
3140
-            
3141
-            if(video_codec_tag)
3142
-                video_enc->codec_tag= video_codec_tag;
3143
-                
3144
-            if (file_oformat->flags & AVFMT_GLOBALHEADER) 
3145
-                video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
3146
-            if (video_stream_copy) {
3147
-                st->stream_copy = 1;
3148
-                video_enc->codec_type = CODEC_TYPE_VIDEO;
3149
-            } else {
3150
-                char *p;
3151
-                int i;
3152
-                AVCodec *codec;
3153
-            
3154
-                codec_id = av_guess_codec(file_oformat, NULL, filename, NULL, CODEC_TYPE_VIDEO);
3155
-                if (video_codec_id != CODEC_ID_NONE)
3156
-                    codec_id = video_codec_id;
3157
-                
3158
-                video_enc->codec_id = codec_id;
3159
-                codec = avcodec_find_encoder(codec_id);
3160
-                
3161
-                video_enc->bit_rate = video_bit_rate;
3162
-                video_enc->bit_rate_tolerance = video_bit_rate_tolerance;
3163
-                video_enc->time_base.den = frame_rate; 
3164
-                video_enc->time_base.num = frame_rate_base; 
3165
-                if(codec && codec->supported_framerates){
3166
-                    const AVRational *p= codec->supported_framerates;
3167
-                    AVRational req= (AVRational){frame_rate, frame_rate_base};
3168
-                    const AVRational *best=NULL;
3169
-                    AVRational best_error= (AVRational){INT_MAX, 1};
3170
-                    for(; p->den!=0; p++){
3171
-                        AVRational error= av_sub_q(req, *p);
3172
-                        if(error.num <0) error.num *= -1;
3173
-                        if(av_cmp_q(error, best_error) < 0){
3174
-                            best_error= error;
3175
-                            best= p;
3176
-                        }
3177
-                    }
3178
-                    video_enc->time_base.den= best->num;
3179
-                    video_enc->time_base.num= best->den;
3180
-                }
3181
-                
3182
-                video_enc->width = frame_width + frame_padright + frame_padleft;
3183
-                video_enc->height = frame_height + frame_padtop + frame_padbottom;
3184
-		video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
3185
-                video_enc->pix_fmt = frame_pix_fmt;
3186
-
3187
-                if(codec && codec->pix_fmts){
3188
-                    const enum PixelFormat *p= codec->pix_fmts;
3189
-                    for(; *p!=-1; p++){
3190
-                        if(*p == video_enc->pix_fmt)
3191
-                            break;
3192
-                    }
3193
-                    if(*p == -1)
3194
-                        video_enc->pix_fmt = codec->pix_fmts[0];
3195
-                }
3196
-
3197
-                if (!intra_only)
3198
-                    video_enc->gop_size = gop_size;
3199
-                else
3200
-                    video_enc->gop_size = 0;
3201
-                if (video_qscale || same_quality) {
3202
-                    video_enc->flags |= CODEC_FLAG_QSCALE;
3203
-                    video_enc->global_quality= 
3204
-                    st->quality = FF_QP2LAMBDA * video_qscale;
3205
-                }
3206
-
3207
-                if(intra_matrix)
3208
-                    video_enc->intra_matrix = intra_matrix;
3209
-                if(inter_matrix)
3210
-                    video_enc->inter_matrix = inter_matrix;
3211
-
3212
-                if(bitexact)
3213
-                    video_enc->flags |= CODEC_FLAG_BITEXACT;
3214
-
3215
-                video_enc->mb_decision = mb_decision;
3216
-                video_enc->mb_cmp = mb_cmp;
3217
-                video_enc->ildct_cmp = ildct_cmp;
3218
-                video_enc->me_sub_cmp = sub_cmp;
3219
-                video_enc->me_cmp = cmp;
3220
-                video_enc->me_pre_cmp = pre_cmp;
3221
-                video_enc->pre_me = pre_me;
3222
-                video_enc->lumi_masking = lumi_mask;
3223
-                video_enc->dark_masking = dark_mask;
3224
-                video_enc->spatial_cplx_masking = scplx_mask;
3225
-                video_enc->temporal_cplx_masking = tcplx_mask;
3226
-                video_enc->p_masking = p_mask;
3227
-                video_enc->quantizer_noise_shaping= qns;
3228
-                
3229
-                if (use_umv) {
3230
-                    video_enc->flags |= CODEC_FLAG_H263P_UMV;
3231
-                }
3232
-                if (use_ss) {
3233
-                    video_enc->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
3234
-                }
3235
-           	if (use_aic) {
3236
-                    video_enc->flags |= CODEC_FLAG_H263P_AIC;
3237
-                }
3238
-           	if (use_aiv) {
3239
-                    video_enc->flags |= CODEC_FLAG_H263P_AIV;
3240
-                }
3241
-                if (use_4mv) {
3242
-                    video_enc->flags |= CODEC_FLAG_4MV;
3243
-                }
3244
-                if (use_obmc) {
3245
-                    video_enc->flags |= CODEC_FLAG_OBMC;
3246
-                }
3247
-                if (use_loop) {
3248
-                    video_enc->flags |= CODEC_FLAG_LOOP_FILTER;
3249
-                }
3250
-            
3251
-                if(use_part) {
3252
-                    video_enc->flags |= CODEC_FLAG_PART;
3253
-                }
3254
-           	if (use_alt_scan) {
3255
-                    video_enc->flags |= CODEC_FLAG_ALT_SCAN;
3256
-                }
3257
-           	if (use_trell) {
3258
-                    video_enc->flags |= CODEC_FLAG_TRELLIS_QUANT;
3259
-                }
3260
-                   if (use_mv0) {
3261
-                    video_enc->flags |= CODEC_FLAG_MV0;
3262
-                }
3263
-                   if (do_normalize_aqp) {
3264
-                    video_enc->flags |= CODEC_FLAG_NORMALIZE_AQP;
3265
-                }
3266
-           	if (use_scan_offset) {
3267
-                    video_enc->flags |= CODEC_FLAG_SVCD_SCAN_OFFSET;
3268
-                }
3269
-           	if (closed_gop) {
3270
-                    video_enc->flags |= CODEC_FLAG_CLOSED_GOP;
3271
-                }
3272
-                if (strict_gop) {
3273
-                    video_enc->flags2 |= CODEC_FLAG2_STRICT_GOP;
3274
-                }
3275
-           	if (use_qpel) {
3276
-                    video_enc->flags |= CODEC_FLAG_QPEL;
3277
-                }
3278
-           	if (use_qprd) {
3279
-                    video_enc->flags |= CODEC_FLAG_QP_RD;
3280
-                }
3281
-           	if (use_cbprd) {
3282
-                    video_enc->flags |= CODEC_FLAG_CBP_RD;
3283
-                }
3284
-                if (b_frames) {
3285
-                    video_enc->max_b_frames = b_frames;
3286
-                    video_enc->b_frame_strategy = b_strategy;
3287
-                    video_enc->b_quant_factor = 2.0;
3288
-                }
3289
-                if (do_interlace_dct) {
3290
-                    video_enc->flags |= CODEC_FLAG_INTERLACED_DCT;
3291
-                }
3292
-                if (do_interlace_me) {
3293
-                    video_enc->flags |= CODEC_FLAG_INTERLACED_ME;
3294
-                }
3295
-                if (no_output) {
3296
-                    video_enc->flags2 |= CODEC_FLAG2_NO_OUTPUT;
3297
-                }
3298
-                if (gray_only) {
3299
-                    video_enc->flags |= CODEC_FLAG_GRAY;
3300
-                }
3301
-                video_enc->qmin = video_qmin;
3302
-                video_enc->qmax = video_qmax;
3303
-                video_enc->lmin = video_lmin;
3304
-                video_enc->lmax = video_lmax;
3305
-                video_enc->rc_qsquish = video_qsquish;
3306
-                video_enc->luma_elim_threshold = video_lelim;
3307
-                video_enc->chroma_elim_threshold = video_celim;
3308
-                video_enc->mb_lmin = video_mb_lmin;
3309
-                video_enc->mb_lmax = video_mb_lmax;
3310
-                video_enc->max_qdiff = video_qdiff;
3311
-                video_enc->qblur = video_qblur;
3312
-                video_enc->qcompress = video_qcomp;
3313
-                video_enc->rc_eq = video_rc_eq;
3314
-                video_enc->debug = debug;
3315
-                video_enc->debug_mv = debug_mv;
3316
-                video_enc->workaround_bugs = workaround_bugs;
3317
-                video_enc->thread_count = thread_count;
3318
-                p= video_rc_override_string;
3319
-                for(i=0; p; i++){
3320
-                    int start, end, q;
3321
-                    int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
3322
-                    if(e!=3){
3323
-                        fprintf(stderr, "error parsing rc_override\n");
3324
-                        exit(1);
3325
-                    }
3326
-                    video_enc->rc_override= 
3327
-                        av_realloc(video_enc->rc_override, 
3328
-                                   sizeof(RcOverride)*(i+1));
3329
-                    video_enc->rc_override[i].start_frame= start;
3330
-                    video_enc->rc_override[i].end_frame  = end;
3331
-                    if(q>0){
3332
-                        video_enc->rc_override[i].qscale= q;
3333
-                        video_enc->rc_override[i].quality_factor= 1.0;
3334
-                    }
3335
-                    else{
3336
-                        video_enc->rc_override[i].qscale= 0;
3337
-                        video_enc->rc_override[i].quality_factor= -q/100.0;
3338
-                    }
3339
-                    p= strchr(p, '/');
3340
-                    if(p) p++;
3341
-                }
3342
-                video_enc->rc_override_count=i;
3343
-
3344
-                video_enc->rc_max_rate = video_rc_max_rate;
3345
-                video_enc->rc_min_rate = video_rc_min_rate;
3346
-                video_enc->rc_buffer_size = video_rc_buffer_size;
3347
-                video_enc->rc_initial_buffer_occupancy = video_rc_buffer_size*3/4;
3348
-                video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity;
3349
-                video_enc->rc_initial_cplx= video_rc_initial_cplx;
3350
-                video_enc->i_quant_factor = video_i_qfactor;
3351
-                video_enc->b_quant_factor = video_b_qfactor;
3352
-                video_enc->i_quant_offset = video_i_qoffset;
3353
-                video_enc->b_quant_offset = video_b_qoffset;
3354
-                video_enc->intra_quant_bias = video_intra_quant_bias;
3355
-                video_enc->inter_quant_bias = video_inter_quant_bias;
3356
-                video_enc->dct_algo = dct_algo;
3357
-                video_enc->idct_algo = idct_algo;
3358
-                video_enc->me_threshold= me_threshold;
3359
-                video_enc->mb_threshold= mb_threshold;
3360
-                video_enc->intra_dc_precision= intra_dc_precision - 8;
3361
-                video_enc->strict_std_compliance = strict;
3362
-                video_enc->error_rate = error_rate;
3363
-                video_enc->noise_reduction= noise_reduction;
3364
-                video_enc->scenechange_threshold= sc_threshold;
3365
-                video_enc->me_range = me_range;
3366
-                video_enc->coder_type= coder;
3367
-                video_enc->context_model= context;
3368
-                video_enc->prediction_method= predictor;
3369
-                video_enc->profile= video_profile;
3370
-                video_enc->level= video_level;
3371
-                video_enc->nsse_weight= nsse_weight;
3372
-                video_enc->me_subpel_quality= subpel_quality;
3373
-                video_enc->me_penalty_compensation= me_penalty_compensation;
3374
-                video_enc->frame_skip_threshold= frame_skip_threshold;
3375
-                video_enc->frame_skip_factor= frame_skip_factor;
3376
-                video_enc->frame_skip_exp= frame_skip_exp;
3377
-                video_enc->frame_skip_cmp= frame_skip_cmp;
3378
-
3379
-                if(packet_size){
3380
-                    video_enc->rtp_mode= 1;
3381
-                    video_enc->rtp_payload_size= packet_size;
3382
-                }
3383
-            
3384
-                if (do_psnr)
3385
-                    video_enc->flags|= CODEC_FLAG_PSNR;
3386
-            
3387
-                video_enc->me_method = me_method;
3388
-
3389
-                /* two pass mode */
3390
-                if (do_pass) {
3391
-                    if (do_pass == 1) {
3392
-                        video_enc->flags |= CODEC_FLAG_PASS1;
3393
-                    } else {
3394
-                        video_enc->flags |= CODEC_FLAG_PASS2;
3395
-                    }
3396
-                }
3397
-            }
3126
+            new_video_stream(oc);
3398 3127
         }
3399 3128
     
3400 3129
         if (use_audio) {
3401
-            AVCodecContext *audio_enc;
3402
-
3403
-            st = av_new_stream(oc, nb_streams++);
3404
-            if (!st) {
3405
-                fprintf(stderr, "Could not alloc stream\n");
3406
-                exit(1);
3407
-            }
3408
-#if defined(HAVE_THREADS)
3409
-            if(thread_count>1)
3410
-                avcodec_thread_init(&st->codec, thread_count);
3411
-#endif
3412
-
3413
-            audio_enc = &st->codec;
3414
-            audio_enc->codec_type = CODEC_TYPE_AUDIO;
3415
-
3416
-            if(audio_codec_tag)
3417
-                audio_enc->codec_tag= audio_codec_tag;
3418
-
3419
-            if (file_oformat->flags & AVFMT_GLOBALHEADER) 
3420
-                audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
3421
-            if (audio_stream_copy) {
3422
-                st->stream_copy = 1;
3423
-		audio_enc->channels = audio_channels;
3424
-            } else {
3425
-                codec_id = av_guess_codec(file_oformat, NULL, filename, NULL, CODEC_TYPE_AUDIO);
3426
-                if (audio_codec_id != CODEC_ID_NONE)
3427
-                    codec_id = audio_codec_id;
3428
-                audio_enc->codec_id = codec_id;
3429
-                
3430
-                audio_enc->bit_rate = audio_bit_rate;
3431
-                audio_enc->strict_std_compliance = strict;
3432
-                audio_enc->thread_count = thread_count;
3433
-                /* For audio codecs other than AC3 or DTS we limit */
3434
-                /* the number of coded channels to stereo   */
3435
-                if (audio_channels > 2 && codec_id != CODEC_ID_AC3
3436
-                    && codec_id != CODEC_ID_DTS) {
3437
-                    audio_enc->channels = 2;
3438
-                } else
3439
-                    audio_enc->channels = audio_channels;
3440
-            }
3441
-	    audio_enc->sample_rate = audio_sample_rate;
3130
+            new_audio_stream(oc);
3442 3131
         }
3443 3132
 
3444
-        oc->nb_streams = nb_streams;
3445
-
3446
-        if (!nb_streams) {
3133
+        if (!oc->nb_streams) {
3447 3134
             fprintf(stderr, "No audio or video streams available\n");
3448 3135
             exit(1);
3449 3136
         }
... ...
@@ -3462,8 +3637,6 @@ static void opt_output_file(const char *filename)
3462 3462
 
3463 3463
     output_files[nb_output_files++] = oc;
3464 3464
 
3465
-    pstrcpy(oc->filename, sizeof(oc->filename), filename);
3466
-
3467 3465
     /* check filename in case of an image number is expected */
3468 3466
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
3469 3467
         if (filename_number_test(oc->filename) < 0) {
... ...
@@ -3520,12 +3693,6 @@ static void opt_output_file(const char *filename)
3520 3520
     file_oformat = NULL;
3521 3521
     file_iformat = NULL;
3522 3522
     image_format = NULL;
3523
-    audio_disable = 0;
3524
-    video_disable = 0;
3525
-    audio_codec_id = CODEC_ID_NONE;
3526
-    video_codec_id = CODEC_ID_NONE;
3527
-    audio_stream_copy = 0;
3528
-    video_stream_copy = 0;
3529 3523
 }
3530 3524
 
3531 3525
 /* prepare dummy protocols for grab */
... ...
@@ -3722,6 +3889,7 @@ static void show_formats(void)
3722 3722
         int decode=0;
3723 3723
         int encode=0;
3724 3724
         int cap=0;
3725
+        const char *type_str;
3725 3726
 
3726 3727
         p2=NULL;
3727 3728
         for(p = first_avcodec; p != NULL; p = p->next) {
... ...
@@ -3740,11 +3908,25 @@ static void show_formats(void)
3740 3740
             break;
3741 3741
         last_name= p2->name;
3742 3742
         
3743
+        switch(p2->type) {
3744
+        case CODEC_TYPE_VIDEO:
3745
+            type_str = "V";
3746
+            break;
3747
+        case CODEC_TYPE_AUDIO:
3748
+            type_str = "A";
3749
+            break;
3750
+        case CODEC_TYPE_SUBTITLE:
3751
+            type_str = "S";
3752
+            break;
3753
+        default:
3754
+            type_str = "?";
3755
+            break;
3756
+        }
3743 3757
         printf(
3744 3758
             " %s%s%s%s%s%s %s", 
3745 3759
             decode ? "D": (/*p2->decoder ? "d":*/" "), 
3746 3760
             encode ? "E":" ", 
3747
-            p2->type == CODEC_TYPE_AUDIO ? "A":"V",
3761
+            type_str,
3748 3762
             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
3749 3763
             cap & CODEC_CAP_DR1 ? "D":" ",
3750 3764
             cap & CODEC_CAP_TRUNCATED ? "T":" ",
... ...
@@ -4132,7 +4314,8 @@ const OptionDef options[] = {
4132 4132
     { "skip_factor", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_factor}, "frame skip factor", "factor" },
4133 4133
     { "skip_exp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_exp}, "frame skip exponent", "exponent" },
4134 4134
     { "skip_cmp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_cmp}, "frame skip compare function", "compare function" },
4135
-    { "gray", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { &gray_only }, "encode/decode grayscale" },
4135
+    { "gray", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&gray_only }, "encode/decode grayscale" },
4136
+    { "newvideo", OPT_VIDEO, {(void*)opt_new_video_stream}, "add a new video stream to the current output stream" },
4136 4137
 
4137 4138
     /* audio options */
4138 4139
     { "ab", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", },
... ...
@@ -4142,7 +4325,14 @@ const OptionDef options[] = {
4142 4142
     { "acodec", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" },
4143 4143
     { "atag", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_audio_tag}, "force audio tag/fourcc", "fourcc/tag" },
4144 4144
     { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, //
4145
+    { "newaudio", OPT_AUDIO, {(void*)opt_new_audio_stream}, "add a new audio stream to the current output stream" },
4146
+    { "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" },
4145 4147
 
4148
+    /* subtitle options */
4149
+    { "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" },
4150
+    { "newsubtitle", OPT_SUBTITLE, {(void*)opt_new_subtitle_stream}, "add a new subtitle stream to the current output stream" },
4151
+    { "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" },
4152
+    
4146 4153
     /* grab options */
4147 4154
     { "vd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_device}, "set video grab device", "device" },
4148 4155
     { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" },
... ...
@@ -4233,6 +4423,9 @@ static void show_help(void)
4233 4233
     show_help_options(options, "\nAdvanced Audio options:\n",
4234 4234
                       OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, 
4235 4235
                       OPT_AUDIO | OPT_EXPERT);
4236
+    show_help_options(options, "\nSubtitle options:\n",
4237
+                      OPT_SUBTITLE | OPT_GRAB, 
4238
+                      OPT_SUBTITLE);
4236 4239
     show_help_options(options, "\nAudio/Video grab options:\n",
4237 4240
                       OPT_GRAB, 
4238 4241
                       OPT_GRAB);