]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - ffmpeg.c
frsh: Export information about the last RTP contract and VRES
[frescor/ffmpeg.git] / ffmpeg.c
index a78c8c6a7610c95a51c79960117cb969cf919765..5f407c96cccf52473694360fd0040c8ded61a2c9 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -162,6 +162,7 @@ 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 float mux_preload= 0.5;
 static float mux_max_delay= 0.7;
@@ -221,6 +222,12 @@ static unsigned int sws_flags = SWS_BICUBIC;
 
 static int64_t timer_start;
 
+static uint8_t *audio_buf;
+static uint8_t *audio_out;
+static uint8_t *audio_out2;
+
+static short *samples;
+
 static AVBitStreamFilterContext *video_bitstream_filters=NULL;
 static AVBitStreamFilterContext *audio_bitstream_filters=NULL;
 static AVBitStreamFilterContext *subtitle_bitstream_filters=NULL;
@@ -263,7 +270,7 @@ typedef struct AVOutputStream {
     ReSampleContext *resample; /* for audio resampling */
     int reformat_pair;
     AVAudioConvert *reformat_ctx;
-    AVFifoBuffer fifo;     /* for compression: one audio fifo per codec */
+    AVFifoBuffer *fifo;     /* for compression: one audio fifo per codec */
     FILE *logfile;
 } AVOutputStream;
 
@@ -426,6 +433,15 @@ static int av_exit(int ret)
     powerpc_display_perf_report();
 #endif /* CONFIG_POWERPC_PERF */
 
+    for (i=0;i<CODEC_TYPE_NB;i++)
+        av_free(avcodec_opts[i]);
+    av_free(avformat_opts);
+    av_free(sws_opts);
+    av_free(audio_buf);
+    av_free(audio_out);
+    av_free(audio_out2);
+    av_free(samples);
+
     if (received_sigterm) {
         fprintf(stderr,
             "Received signal %d: terminating.\n",
@@ -526,9 +542,6 @@ static void do_audio_out(AVFormatContext *s,
                          unsigned char *buf, int size)
 {
     uint8_t *buftmp;
-    static uint8_t *audio_buf = NULL;
-    static uint8_t *audio_out = NULL;
-    static uint8_t *audio_out2 = NULL;
     const int audio_out_size= 4*MAX_AUDIO_PACKET_SIZE;
 
     int size_out, frame_bytes, ret;
@@ -585,7 +598,7 @@ static void do_audio_out(AVFormatContext *s,
 
     if(audio_sync_method){
         double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts
-                - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2);
+                - av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2);
         double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate;
         int byte_delta= ((int)idelta)*2*ist->st->codec->channels;
 
@@ -622,13 +635,13 @@ static void do_audio_out(AVFormatContext *s,
                 assert(ost->audio_resample);
                 if(verbose > 2)
                     fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
-//                fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2));
+//                fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));
                 av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
             }
         }
     }else
         ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate)
-                        - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2); //FIXME wrong
+                        - av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2); //FIXME wrong
 
     if (ost->audio_resample) {
         buftmp = audio_buf;
@@ -660,19 +673,19 @@ static void do_audio_out(AVFormatContext *s,
     /* now encode as many frames as possible */
     if (enc->frame_size > 1) {
         /* output resampled raw samples */
-        if (av_fifo_realloc2(&ost->fifo, av_fifo_size(&ost->fifo) + size_out) < 0) {
+        if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) {
             fprintf(stderr, "av_fifo_realloc2() failed\n");
             av_exit(1);
         }
-        av_fifo_generic_write(&ost->fifo, buftmp, size_out, NULL);
+        av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL);
 
         frame_bytes = enc->frame_size * osize * enc->channels;
 
-        while (av_fifo_size(&ost->fifo) >= frame_bytes) {
+        while (av_fifo_size(ost->fifo) >= frame_bytes) {
             AVPacket pkt;
             av_init_packet(&pkt);
 
-            av_fifo_read(&ost->fifo, audio_buf, frame_bytes);
+            av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL);
 
             //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
 
@@ -946,7 +959,7 @@ static void do_video_out(AVFormatContext *s,
             /* better than nothing: use input picture interlaced
                settings */
             big_picture.interlaced_frame = in_picture->interlaced_frame;
-            if(avctx_opts[CODEC_TYPE_VIDEO]->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)){
+            if(avcodec_opts[CODEC_TYPE_VIDEO]->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)){
                 if(top_field_first == -1)
                     big_picture.top_field_first = in_picture->top_field_first;
                 else
@@ -1048,7 +1061,7 @@ static void print_report(AVFormatContext **output_files,
 {
     char buf[1024];
     AVOutputStream *ost;
-    AVFormatContext *oc, *os;
+    AVFormatContext *oc;
     int64_t total_size;
     AVCodecContext *enc;
     int frame_number, vid, i;
@@ -1081,7 +1094,6 @@ static void print_report(AVFormatContext **output_files,
     vid = 0;
     for(i=0;i<nb_ostreams;i++) {
         ost = ost_table[i];
-        os = output_files[ost->file_index];
         enc = ost->st->codec;
         if (vid && enc->codec_type == CODEC_TYPE_VIDEO) {
             snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ",
@@ -1173,39 +1185,38 @@ static int output_packet(AVInputStream *ist, int ist_index,
 {
     AVFormatContext *os;
     AVOutputStream *ost;
-    uint8_t *ptr;
-    int len, ret, i;
+    int ret, i;
     uint8_t *data_buf;
     int data_size, got_picture;
     AVFrame picture;
     void *buffer_to_free;
     static unsigned int samples_size= 0;
-    static short *samples= NULL;
     AVSubtitle subtitle, *subtitle_to_free;
     int got_subtitle;
+    AVPacket avpkt;
 
     if(ist->next_pts == AV_NOPTS_VALUE)
         ist->next_pts= ist->pts;
 
     if (pkt == NULL) {
         /* EOF handling */
-        ptr = NULL;
-        len = 0;
+        av_init_packet(&avpkt);
+        avpkt.data = NULL;
+        avpkt.size = 0;
         goto handle_eof;
+    } else {
+        avpkt = *pkt;
     }
 
     if(pkt->dts != AV_NOPTS_VALUE)
         ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
 
-    len = pkt->size;
-    ptr = pkt->data;
-
     //while we have more to decode or while the decoder did output something on EOF
-    while (len > 0 || (!pkt && ist->next_pts != ist->pts)) {
+    while (avpkt.size > 0 || (!pkt && ist->next_pts != ist->pts)) {
     handle_eof:
         ist->pts= ist->next_pts;
 
-        if(len && len != pkt->size && verbose>0)
+        if(avpkt.size && avpkt.size != pkt->size && verbose>0)
             fprintf(stderr, "Multiple frames in a packet from stream %d\n", pkt->stream_index);
 
         /* decode the packet if needed */
@@ -1223,12 +1234,12 @@ static int output_packet(AVInputStream *ist, int ist_index,
                 data_size= samples_size;
                     /* XXX: could avoid copy if PCM 16 bits with same
                        endianness as CPU */
-                ret = avcodec_decode_audio2(ist->st->codec, samples, &data_size,
-                                           ptr, len);
+                ret = avcodec_decode_audio3(ist->st->codec, samples, &data_size,
+                                            &avpkt);
                 if (ret < 0)
                     goto fail_decode;
-                ptr += ret;
-                len -= ret;
+                avpkt.data += ret;
+                avpkt.size -= ret;
                 /* Some bug in mpeg audio decoder gives */
                 /* data_size < 0, it seems they are overflows */
                 if (data_size <= 0) {
@@ -1244,8 +1255,8 @@ static int output_packet(AVInputStream *ist, int ist_index,
                     /* XXX: allocate picture correctly */
                     avcodec_get_frame_defaults(&picture);
 
-                    ret = avcodec_decode_video(ist->st->codec,
-                                               &picture, &got_picture, ptr, len);
+                    ret = avcodec_decode_video2(ist->st->codec,
+                                                &picture, &got_picture, &avpkt);
                     ist->st->quality= picture.quality;
                     if (ret < 0)
                         goto fail_decode;
@@ -1259,18 +1270,18 @@ static int output_packet(AVInputStream *ist, int ist_index,
                                           ist->st->codec->time_base.num * ticks) /
                             ist->st->codec->time_base.den;
                     }
-                    len = 0;
+                    avpkt.size = 0;
                     break;
             case CODEC_TYPE_SUBTITLE:
-                ret = avcodec_decode_subtitle(ist->st->codec,
-                                              &subtitle, &got_subtitle, ptr, len);
+                ret = avcodec_decode_subtitle2(ist->st->codec,
+                                               &subtitle, &got_subtitle, &avpkt);
                 if (ret < 0)
                     goto fail_decode;
                 if (!got_subtitle) {
                     goto discard_packet;
                 }
                 subtitle_to_free = &subtitle;
-                len = 0;
+                avpkt.size = 0;
                 break;
             default:
                 goto fail_decode;
@@ -1290,10 +1301,10 @@ static int output_packet(AVInputStream *ist, int ist_index,
                 }
                 break;
             }
-            data_buf = ptr;
-            data_size = len;
-            ret = len;
-            len = 0;
+            data_buf = avpkt.data;
+            data_size = avpkt.size;
+            ret = avpkt.size;
+            avpkt.size = 0;
         }
 
         buffer_to_free = NULL;
@@ -1363,6 +1374,8 @@ static int output_packet(AVInputStream *ist, int ist_index,
                     } else {
                         AVFrame avframe; //FIXME/XXX remove this
                         AVPacket opkt;
+                        int64_t ost_tb_start_time= av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base);
+
                         av_init_packet(&opkt);
 
                         if ((!ost->frame_number && !(pkt->flags & PKT_FLAG_KEY)) && !copy_initial_nonkeyframes)
@@ -1384,7 +1397,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
 
                         opkt.stream_index= ost->index;
                         if(pkt->pts != AV_NOPTS_VALUE)
-                            opkt.pts= av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base);
+                            opkt.pts= av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time;
                         else
                             opkt.pts= AV_NOPTS_VALUE;
 
@@ -1392,6 +1405,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
                             opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base);
                         else
                             opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
+                        opkt.dts -= ost_tb_start_time;
 
                         opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
                         opkt.flags= pkt->flags;
@@ -1446,14 +1460,17 @@ static int output_packet(AVInputStream *ist, int ist_index,
 
                         switch(ost->st->codec->codec_type) {
                         case CODEC_TYPE_AUDIO:
-                            fifo_bytes = av_fifo_size(&ost->fifo);
+                            fifo_bytes = av_fifo_size(ost->fifo);
                             ret = 0;
                             /* encode any samples remaining in fifo */
                             if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
+                                int osize = av_get_bits_per_sample_format(enc->sample_fmt) >> 3;
                                 int fs_tmp = enc->frame_size;
-                                enc->frame_size = fifo_bytes / (2 * enc->channels);
-                                av_fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes);
-                                    ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
+                                enc->frame_size = fifo_bytes / (osize * enc->channels);
+                                av_fifo_generic_read(ost->fifo, samples, fifo_bytes, NULL);
+                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
+                                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;
                             }
                             if(ret <= 0) {
@@ -1545,12 +1562,13 @@ static int av_encode(AVFormatContext **output_files,
                      int nb_input_files,
                      AVStreamMap *stream_maps, int nb_stream_maps)
 {
-    int ret, i, j, k, n, nb_istreams = 0, nb_ostreams = 0;
+    int ret = 0, i, j, k, n, nb_istreams = 0, nb_ostreams = 0;
     AVFormatContext *is, *os;
     AVCodecContext *codec, *icodec;
     AVOutputStream *ost, **ost_table = NULL;
     AVInputStream *ist, **ist_table = NULL;
     AVInputFile *file_table;
+    char error[1024];
     int key;
     int want_sdp = 1;
     uint8_t no_packet[MAX_FILES]={0};
@@ -1730,6 +1748,8 @@ static int av_encode(AVFormatContext **output_files,
             av_metadata_set(&ost->st->metadata, "language", lang->value);
 
         ost->st->disposition = ist->st->disposition;
+        codec->bits_per_raw_sample= icodec->bits_per_raw_sample;
+        codec->chroma_sample_location = icodec->chroma_sample_location;
 
         if (ost->st->stream_copy) {
             /* if stream_copy is selected, no need to decode or encode */
@@ -1783,7 +1803,8 @@ static int av_encode(AVFormatContext **output_files,
         } else {
             switch(codec->codec_type) {
             case CODEC_TYPE_AUDIO:
-                if (av_fifo_init(&ost->fifo, 1024))
+                ost->fifo= av_fifo_alloc(1024);
+                if(!ost->fifo)
                     goto fail;
                 ost->reformat_pair = MAKE_SFMT_PAIR(SAMPLE_FMT_NONE,SAMPLE_FMT_NONE);
                 ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
@@ -1838,6 +1859,7 @@ static int av_encode(AVFormatContext **output_files,
                         av_exit(1);
                     }
                     ost->resample_height = icodec->height - (frame_topBand + frame_bottomBand);
+                    codec->bits_per_raw_sample= 0;
                 }
                 ost->encoding_needed = 1;
                 ist->decoding_needed = 1;
@@ -1898,31 +1920,9 @@ static int av_encode(AVFormatContext **output_files,
 
     if (!bit_buffer)
         bit_buffer = av_malloc(bit_buffer_size);
-    if (!bit_buffer)
+    if (!bit_buffer) {
+        ret = AVERROR(ENOMEM);
         goto fail;
-
-    /* dump the file output parameters - cannot be done before in case
-       of stream copy */
-    for(i=0;i<nb_output_files;i++) {
-        dump_format(output_files[i], i, output_files[i]->filename, 1);
-    }
-
-    /* dump the stream mapping */
-    if (verbose >= 0) {
-        fprintf(stderr, "Stream mapping:\n");
-        for(i=0;i<nb_ostreams;i++) {
-            ost = ost_table[i];
-            fprintf(stderr, "  Stream #%d.%d -> #%d.%d",
-                    ist_table[ost->source_index]->file_index,
-                    ist_table[ost->source_index]->index,
-                    ost->file_index,
-                    ost->index);
-            if (ost->sync_ist != ist_table[ost->source_index])
-                fprintf(stderr, " [sync #%d.%d]",
-                        ost->sync_ist->file_index,
-                        ost->sync_ist->index);
-            fprintf(stderr, "\n");
-        }
     }
 
     /* open each encoder */
@@ -1933,14 +1933,16 @@ static int av_encode(AVFormatContext **output_files,
             if (!codec)
                 codec = avcodec_find_encoder(ost->st->codec->codec_id);
             if (!codec) {
-                fprintf(stderr, "Unsupported codec for output stream #%d.%d\n",
+                snprintf(error, sizeof(error), "Unsupported codec for output stream #%d.%d",
                         ost->file_index, ost->index);
-                av_exit(1);
+                ret = AVERROR(EINVAL);
+                goto dump_format;
             }
             if (avcodec_open(ost->st->codec, codec) < 0) {
-                fprintf(stderr, "Error while opening codec for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height\n",
+                snprintf(error, sizeof(error), "Error while opening codec for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",
                         ost->file_index, ost->index);
-                av_exit(1);
+                ret = AVERROR(EINVAL);
+                goto dump_format;
             }
             extra_size += ost->st->codec->extradata_size;
         }
@@ -1954,14 +1956,16 @@ static int av_encode(AVFormatContext **output_files,
             if (!codec)
                 codec = avcodec_find_decoder(ist->st->codec->codec_id);
             if (!codec) {
-                fprintf(stderr, "Unsupported codec (id=%d) for input stream #%d.%d\n",
+                snprintf(error, sizeof(error), "Unsupported codec (id=%d) for input stream #%d.%d",
                         ist->st->codec->codec_id, ist->file_index, ist->index);
-                av_exit(1);
+                ret = AVERROR(EINVAL);
+                goto dump_format;
             }
             if (avcodec_open(ist->st->codec, codec) < 0) {
-                fprintf(stderr, "Error while opening codec for input stream #%d.%d\n",
+                snprintf(error, sizeof(error), "Error while opening codec for input stream #%d.%d",
                         ist->file_index, ist->index);
-                av_exit(1);
+                ret = AVERROR(EINVAL);
+                goto dump_format;
             }
             //if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO)
             //    ist->st->codec->flags |= CODEC_FLAG_REPEAT_FIELD;
@@ -1971,7 +1975,6 @@ static int av_encode(AVFormatContext **output_files,
     /* init pts */
     for(i=0;i<nb_istreams;i++) {
         ist = ist_table[i];
-        is = input_files[ist->file_index];
         ist->pts = 0;
         ist->next_pts = AV_NOPTS_VALUE;
         ist->is_start = 1;
@@ -1986,14 +1989,16 @@ static int av_encode(AVFormatContext **output_files,
         int out_file_index = meta_data_maps[i].out_file;
         int in_file_index = meta_data_maps[i].in_file;
         if (out_file_index < 0 || out_file_index >= nb_output_files) {
-            fprintf(stderr, "Invalid output file index %d map_meta_data(%d,%d)\n", out_file_index, out_file_index, in_file_index);
+            snprintf(error, sizeof(error), "Invalid output file index %d map_meta_data(%d,%d)",
+                     out_file_index, out_file_index, in_file_index);
             ret = AVERROR(EINVAL);
-            goto fail;
+            goto dump_format;
         }
         if (in_file_index < 0 || in_file_index >= nb_input_files) {
-            fprintf(stderr, "Invalid input file index %d map_meta_data(%d,%d)\n", in_file_index, out_file_index, in_file_index);
+            snprintf(error, sizeof(error), "Invalid input file index %d map_meta_data(%d,%d)",
+                     in_file_index, out_file_index, in_file_index);
             ret = AVERROR(EINVAL);
-            goto fail;
+            goto dump_format;
         }
 
         out_file = output_files[out_file_index];
@@ -2011,14 +2016,45 @@ static int av_encode(AVFormatContext **output_files,
     for(i=0;i<nb_output_files;i++) {
         os = output_files[i];
         if (av_write_header(os) < 0) {
-            fprintf(stderr, "Could not write header for output file #%d (incorrect codec parameters ?)\n", i);
+            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
             ret = AVERROR(EINVAL);
-            goto fail;
+            goto dump_format;
         }
         if (strcmp(output_files[i]->oformat->name, "rtp")) {
             want_sdp = 0;
         }
     }
+
+ dump_format:
+    /* dump the file output parameters - cannot be done before in case
+       of stream copy */
+    for(i=0;i<nb_output_files;i++) {
+        dump_format(output_files[i], i, output_files[i]->filename, 1);
+    }
+
+    /* dump the stream mapping */
+    if (verbose >= 0) {
+        fprintf(stderr, "Stream mapping:\n");
+        for(i=0;i<nb_ostreams;i++) {
+            ost = ost_table[i];
+            fprintf(stderr, "  Stream #%d.%d -> #%d.%d",
+                    ist_table[ost->source_index]->file_index,
+                    ist_table[ost->source_index]->index,
+                    ost->file_index,
+                    ost->index);
+            if (ost->sync_ist != ist_table[ost->source_index])
+                fprintf(stderr, " [sync #%d.%d]",
+                        ost->sync_ist->file_index,
+                        ost->sync_ist->index);
+            fprintf(stderr, "\n");
+        }
+    }
+
+    if (ret) {
+        fprintf(stderr, "%s\n", error);
+        goto fail;
+    }
+
     if (want_sdp) {
         print_sdp(output_files, nb_output_files);
     }
@@ -2029,7 +2065,6 @@ static int av_encode(AVFormatContext **output_files,
     }
     term_init();
 
-    key = -1;
     timer_start = av_gettime();
 
     for(; received_sigterm == 0;) {
@@ -2086,6 +2121,7 @@ static int av_encode(AVFormatContext **output_files,
             if(no_packet_count){
                 no_packet_count=0;
                 memset(no_packet, 0, sizeof(no_packet));
+                usleep(10000);
                 continue;
             }
             break;
@@ -2102,7 +2138,7 @@ static int av_encode(AVFormatContext **output_files,
         /* read a frame from it and output it in the fifo */
         is = input_files[file_index];
         ret= av_read_frame(is, &pkt);
-        if(ret == AVERROR(EAGAIN) && strcmp(is->iformat->name, "ffm")){
+        if(ret == AVERROR(EAGAIN)){
             no_packet[file_index]=1;
             no_packet_count++;
             continue;
@@ -2213,9 +2249,9 @@ static int av_encode(AVFormatContext **output_files,
     }
 
     /* finished ! */
-
     ret = 0;
- fail1:
+
+ fail:
     av_freep(&bit_buffer);
     av_free(file_table);
 
@@ -2234,7 +2270,7 @@ static int av_encode(AVFormatContext **output_files,
                     fclose(ost->logfile);
                     ost->logfile = NULL;
                 }
-                av_fifo_free(&ost->fifo); /* works even if fifo is not
+                av_fifo_free(ost->fifo); /* works even if fifo is not
                                              initialized but set to zero */
                 av_free(ost->pict_tmp.data[0]);
                 if (ost->video_resample)
@@ -2249,9 +2285,6 @@ static int av_encode(AVFormatContext **output_files,
         av_free(ost_table);
     }
     return ret;
- fail:
-    ret = AVERROR(ENOMEM);
-    goto fail1;
 }
 
 #if 0
@@ -2305,10 +2338,16 @@ static int opt_me_threshold(const char *opt, const char *arg)
     return 0;
 }
 
+static int opt_loglevel(const char *opt, const char *arg)
+{
+    int level = parse_number_or_die(opt, arg, OPT_INT, INT_MIN, INT_MAX);
+    av_log_set_level(level);
+    return 0;
+}
+
 static int opt_verbose(const char *opt, const char *arg)
 {
     verbose = parse_number_or_die(opt, arg, OPT_INT64, -10, 10);
-    av_log_set_level(verbose);
     return 0;
 }
 
@@ -2327,7 +2366,7 @@ static int opt_bitrate(const char *opt, const char *arg)
 
     opt_default(opt, arg);
 
-    if (av_get_int(avctx_opts[codec_type], "b", NULL) < 1000)
+    if (av_get_int(avcodec_opts[codec_type], "b", NULL) < 1000)
         fprintf(stderr, "WARNING: The bitrate parameter is set too low. It takes bits/s as argument, not kbits/s\n");
 
     return 0;
@@ -2515,9 +2554,13 @@ static void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt),
 
 static void opt_frame_pix_fmt(const char *arg)
 {
-    if (strcmp(arg, "list"))
+    if (strcmp(arg, "list")) {
         frame_pix_fmt = avcodec_get_pix_fmt(arg);
-    else {
+        if (frame_pix_fmt == PIX_FMT_NONE) {
+            fprintf(stderr, "Unknown pixel format requested: %s\n", arg);
+            av_exit(1);
+        }
+    } else {
         list_fmts(avcodec_pix_fmt_string, PIX_FMT_NB);
         av_exit(0);
     }
@@ -2666,6 +2709,15 @@ static void opt_subtitle_codec(const char *arg)
     opt_codec(&subtitle_stream_copy, &subtitle_codec_name, CODEC_TYPE_SUBTITLE, arg);
 }
 
+static void opt_subtitle_tag(const char *arg)
+{
+    char *tail;
+    subtitle_codec_tag= strtol(arg, &tail, 0);
+
+    if(!tail || *tail)
+        subtitle_codec_tag= arg[0] + (arg[1]<<8) + (arg[2]<<16) + (arg[3]<<24);
+}
+
 static void opt_map(const char *arg)
 {
     AVStreamMap *m;
@@ -2804,6 +2856,7 @@ static void opt_input_file(const char *filename)
     ic->video_codec_id   = find_codec_or_die(video_codec_name   , CODEC_TYPE_VIDEO   , 0);
     ic->audio_codec_id   = find_codec_or_die(audio_codec_name   , CODEC_TYPE_AUDIO   , 0);
     ic->subtitle_codec_id= find_codec_or_die(subtitle_codec_name, CODEC_TYPE_SUBTITLE, 0);
+    ic->flags |= AVFMT_FLAG_NONBLOCK;
 
     /* open the input file with generic libav function */
     err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
@@ -2852,7 +2905,7 @@ static void opt_input_file(const char *filename)
         enc->thread_count= thread_count;
         switch(enc->codec_type) {
         case CODEC_TYPE_AUDIO:
-            set_context_opts(enc, avctx_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
+            set_context_opts(enc, avcodec_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
             //fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
             channel_layout = enc->channel_layout;
             audio_channels = enc->channels;
@@ -2863,7 +2916,7 @@ static void opt_input_file(const char *filename)
                 ic->streams[i]->discard= AVDISCARD_ALL;
             break;
         case CODEC_TYPE_VIDEO:
-            set_context_opts(enc, avctx_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
+            set_context_opts(enc, avcodec_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
             frame_height = enc->height;
             frame_width = enc->width;
             if(ic->streams[i]->sample_aspect_ratio.num)
@@ -2992,11 +3045,11 @@ static void new_video_stream(AVFormatContext *oc)
     if(   (video_global_header&1)
        || (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))){
         video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
-        avctx_opts[CODEC_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
+        avcodec_opts[CODEC_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
     }
     if(video_global_header&2){
         video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER;
-        avctx_opts[CODEC_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER;
+        avcodec_opts[CODEC_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER;
     }
 
     if (video_stream_copy) {
@@ -3021,7 +3074,7 @@ static void new_video_stream(AVFormatContext *oc)
 
         video_enc->codec_id = codec_id;
 
-        set_context_opts(video_enc, avctx_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
+        set_context_opts(video_enc, avcodec_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
 
         if (codec && codec->supported_framerates && !force_fps)
             fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)];
@@ -3135,7 +3188,7 @@ static void new_audio_stream(AVFormatContext *oc)
 
     if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
         audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
-        avctx_opts[CODEC_TYPE_AUDIO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
+        avcodec_opts[CODEC_TYPE_AUDIO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
     }
     if (audio_stream_copy) {
         st->stream_copy = 1;
@@ -3143,7 +3196,7 @@ static void new_audio_stream(AVFormatContext *oc)
     } else {
         AVCodec *codec;
 
-        set_context_opts(audio_enc, avctx_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
+        set_context_opts(audio_enc, avcodec_opts[CODEC_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, CODEC_TYPE_AUDIO, 1);
@@ -3163,6 +3216,8 @@ static void new_audio_stream(AVFormatContext *oc)
         audio_enc->channels = audio_channels;
         audio_enc->sample_fmt = audio_sample_fmt;
         audio_enc->channel_layout = channel_layout;
+        if (avcodec_channel_layout_num_channels(channel_layout) != audio_channels)
+            audio_enc->channel_layout = 0;
 
         if(codec && codec->sample_fmts){
             const enum SampleFormat *p= codec->sample_fmts;
@@ -3206,10 +3261,14 @@ static void new_subtitle_stream(AVFormatContext *oc)
 
     subtitle_enc = st->codec;
     subtitle_enc->codec_type = CODEC_TYPE_SUBTITLE;
+
+    if(subtitle_codec_tag)
+        subtitle_enc->codec_tag= subtitle_codec_tag;
+
     if (subtitle_stream_copy) {
         st->stream_copy = 1;
     } else {
-        set_context_opts(avctx_opts[CODEC_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
+        set_context_opts(avcodec_opts[CODEC_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, CODEC_TYPE_SUBTITLE, 1);
         output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name);
     }
@@ -3359,13 +3418,10 @@ static void opt_output_file(const char *filename)
              filename[1] == ':' ||
              av_strstart(filename, "file:", NULL))) {
             if (url_exist(filename)) {
-                int c;
-
                 if (!using_stdin) {
                     fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
                     fflush(stderr);
-                    c = getchar();
-                    if (toupper(c) != 'Y') {
+                    if (!read_yesno()) {
                         fprintf(stderr, "Not overwriting - exiting\n");
                         av_exit(1);
                     }
@@ -3394,6 +3450,7 @@ 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);
 
@@ -3500,7 +3557,7 @@ static void show_help(void)
                       OPT_GRAB,
                       OPT_GRAB);
     printf("\n");
-    av_opt_show(avctx_opts[0], NULL);
+    av_opt_show(avcodec_opts[0], NULL);
     printf("\n");
     av_opt_show(avformat_opts, NULL);
     printf("\n");
@@ -3763,8 +3820,8 @@ 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" },
-    { "metadata", OPT_FUNC2 | HAS_ARG, {(void*)&opt_metadata}, "add metadata", "string=string" },
+    { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)opt_rec_timestamp}, "set the 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[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" },
     { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
       "add timings for benchmarking" },
@@ -3775,7 +3832,8 @@ static const OptionDef options[] = {
     { "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" },
     { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
     { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "number of times to loop output in formats that support looping (0 loops forever)", "" },
-    { "v", HAS_ARG | OPT_FUNC2, {(void*)opt_verbose}, "set the logging verbosity level", "number" },
+    { "v", HAS_ARG | OPT_FUNC2, {(void*)opt_verbose}, "set ffmpeg verbosity level", "number" },
+    { "loglevel", HAS_ARG | OPT_FUNC2, {(void*)opt_loglevel}, "set libav* logging level", "number" },
     { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
     { "threads", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
     { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
@@ -3850,6 +3908,7 @@ static const OptionDef options[] = {
     { "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" },
     { "newsubtitle", OPT_SUBTITLE, {(void*)opt_new_subtitle_stream}, "add a new subtitle stream to the current output stream" },
     { "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" },
+    { "stag", HAS_ARG | OPT_EXPERT | OPT_SUBTITLE, {(void*)opt_subtitle_tag}, "force subtitle tag/fourcc", "fourcc/tag" },
 
     /* grab options */
     { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" },
@@ -3885,7 +3944,7 @@ int main(int argc, char **argv)
         url_set_interrupt_cb(decode_interrupt_cb);
 
     for(i=0; i<CODEC_TYPE_NB; i++){
-        avctx_opts[i]= avcodec_alloc_context2(i);
+        avcodec_opts[i]= avcodec_alloc_context2(i);
     }
     avformat_opts = avformat_alloc_context();
     sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);