diff --git a/Changelog b/Changelog
index 904c1cd3aa..cd73c6d623 100644
--- a/Changelog
+++ b/Changelog
@@ -49,6 +49,7 @@ version next:
 - SubRip encoder and decoder without embedded timing
 - edge detection filter
 - framestep filter
+- ffmpeg -shortest option is now per-output file
 
 
 version 0.11:
diff --git a/cmdutils.c b/cmdutils.c
index 6859692e8b..7ec5db2203 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -801,90 +801,127 @@ int opt_formats(const char *opt, const char *arg)
 
 static char get_media_type_char(enum AVMediaType type)
 {
-    static const char map[AVMEDIA_TYPE_NB] = {
-        [AVMEDIA_TYPE_VIDEO]      = 'V',
-        [AVMEDIA_TYPE_AUDIO]      = 'A',
-        [AVMEDIA_TYPE_DATA]       = 'D',
-        [AVMEDIA_TYPE_SUBTITLE]   = 'S',
-        [AVMEDIA_TYPE_ATTACHMENT] = 'T',
-    };
-    return type >= 0 && type < AVMEDIA_TYPE_NB && map[type] ? map[type] : '?';
+    switch (type) {
+        case AVMEDIA_TYPE_VIDEO:    return 'V';
+        case AVMEDIA_TYPE_AUDIO:    return 'A';
+        case AVMEDIA_TYPE_DATA:     return 'D';
+        case AVMEDIA_TYPE_SUBTITLE: return 'S';
+        case AVMEDIA_TYPE_ATTACHMENT:return 'T';
+        default:                    return '?';
+    }
 }
 
-int opt_codecs(const char *opt, const char *arg)
+static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
+                                        int encoder)
 {
-    AVCodec *p = NULL, *p2;
-    const char *last_name;
-    printf("Codecs:\n"
-           " D....... = Decoding supported\n"
-           " .E...... = Encoding supported\n"
-           " ..V..... = Video codec\n"
-           " ..A..... = Audio codec\n"
-           " ..S..... = Subtitle codec\n"
-           " ...S.... = Supports draw_horiz_band\n"
-           " ....D... = Supports direct rendering method 1\n"
-           " .....T.. = Supports weird frame truncation\n"
-           " ......F. = Supports frame-based multi-threaded decoding\n"
-           " ......S. = Supports slice-based multi-threaded decoding\n"
-           " ......B. = Supports both frame-based and slice-based multi-threaded decoding\n"
-           " .......F = Supports frame-based multi-threaded encoding\n"
-           " .......S = Supports slice-based multi-threaded encoding\n"
-           " .......B = Supports both frame-based and slice-based multi-threaded encoding\n"
-           " --------\n");
-    last_name= "000";
-    for (;;) {
-        int decode = 0;
-        int encode = 0;
-        int cap    = 0;
+    while ((prev = av_codec_next(prev))) {
+        if (prev->id == id &&
+            (encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
+            return prev;
+    }
+    return NULL;
+}
 
-        p2 = NULL;
-        while ((p = av_codec_next(p))) {
-            if ((p2 == NULL || strcmp(p->name, p2->name) < 0) &&
-                strcmp(p->name, last_name) > 0) {
-                p2 = p;
-                decode = encode = cap = 0;
-            }
-            if (p2 && strcmp(p->name, p2->name) == 0) {
-                if (av_codec_is_decoder(p))
-                    decode = 1;
-                if (av_codec_is_encoder(p))
-                    encode = 1;
-                cap |= p->capabilities;
+static void print_codecs_for_id(enum AVCodecID id, int encoder)
+{
+    const AVCodec *codec = NULL;
+
+    printf(" (%s: ", encoder ? "encoders" : "decoders");
+
+    while ((codec = next_codec_for_id(id, codec, encoder)))
+        printf("%s ", codec->name);
+
+    printf(")");
+}
+
+int show_codecs(const char *opt, const char *arg)
+{
+    const AVCodecDescriptor *desc = NULL;
+
+    printf("Codecs:\n"
+           " D... = Decoding supported\n"
+           " .E.. = Encoding supported\n"
+           " ..V. = Video codec\n"
+           " ..A. = Audio codec\n"
+           " ..S. = Subtitle codec\n"
+           " ...I = Intra frame-only codec\n"
+           " -----\n");
+    while ((desc = avcodec_descriptor_next(desc))) {
+        const AVCodec *codec = NULL;
+
+        printf(avcodec_find_decoder(desc->id) ? "D" : ".");
+        printf(avcodec_find_encoder(desc->id) ? "E" : ".");
+
+        printf("%c", get_media_type_char(desc->type));
+        printf((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
+
+        printf(" %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
+
+        /* print decoders/encoders when there's more than one or their
+         * names are different from codec name */
+        while ((codec = next_codec_for_id(desc->id, codec, 0))) {
+            if (strcmp(codec->name, desc->name)) {
+                print_codecs_for_id(desc->id, 0);
+                break;
+            }
+        }
+        codec = NULL;
+        while ((codec = next_codec_for_id(desc->id, codec, 1))) {
+            if (strcmp(codec->name, desc->name)) {
+                print_codecs_for_id(desc->id, 1);
+                break;
             }
         }
-        if (p2 == NULL)
-            break;
-        last_name = p2->name;
 
-        printf(" %s%s%c%s%s%s%s%s %-15s %s",
-               decode ? "D" : (/* p2->decoder ? "d" : */ " "),
-               encode ? "E" : " ",
-               get_media_type_char(p2->type),
-               cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S" : " ",
-               cap & CODEC_CAP_DR1 ? "D" : " ",
-               cap & CODEC_CAP_TRUNCATED ? "T" : " ",
-               decode ?
-               cap & CODEC_CAP_FRAME_THREADS ? cap & CODEC_CAP_SLICE_THREADS ? "B" : "F" :
-                                               cap & CODEC_CAP_SLICE_THREADS ? "S" : " "
-               : " ",
-               encode ?
-               cap & CODEC_CAP_FRAME_THREADS ? cap & CODEC_CAP_SLICE_THREADS ? "B" : "F" :
-                                               cap & CODEC_CAP_SLICE_THREADS ? "S" : " "
-               : " ",
-               p2->name,
-               p2->long_name ? p2->long_name : "");
-#if 0
-            if (p2->decoder && decode == 0)
-                printf(" use %s for decoding", p2->decoder->name);
-#endif
         printf("\n");
     }
-    printf("\n");
-    printf("Note, the names of encoders and decoders do not always match, so there are\n"
-           "several cases where the above table shows encoder only or decoder only entries\n"
-           "even though both encoding and decoding are supported. For example, the h263\n"
-           "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
-           "worse.\n");
+    return 0;
+}
+
+static void print_codecs(int encoder)
+{
+    const AVCodecDescriptor *desc = NULL;
+
+    printf("%s:\n"
+           " V..... = Video\n"
+           " A..... = Audio\n"
+           " S..... = Subtitle\n"
+           " .F.... = Frame-level multithreading\n"
+           " ..S... = Slice-level multithreading\n"
+           " ...X.. = Codec is experimental\n"
+           " ....B. = Supports draw_horiz_band\n"
+           " .....D = Supports direct rendering method 1\n"
+           " ------\n",
+           encoder ? "Encoders" : "Decoders");
+    while ((desc = avcodec_descriptor_next(desc))) {
+        const AVCodec *codec = NULL;
+
+        while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
+            printf("%c", get_media_type_char(desc->type));
+            printf((codec->capabilities & CODEC_CAP_FRAME_THREADS) ? "F" : ".");
+            printf((codec->capabilities & CODEC_CAP_SLICE_THREADS) ? "S" : ".");
+            printf((codec->capabilities & CODEC_CAP_EXPERIMENTAL)  ? "X" : ".");
+            printf((codec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
+            printf((codec->capabilities & CODEC_CAP_DR1)           ? "D" : ".");
+
+            printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
+            if (strcmp(codec->name, desc->name))
+                printf(" (codec %s)", desc->name);
+
+            printf("\n");
+        }
+    }
+}
+
+int show_decoders(const char *opt, const char *arg)
+{
+    print_codecs(0);
+    return 0;
+}
+
+int show_encoders(const char *opt, const char *arg)
+{
+    print_codecs(1);
     return 0;
 }
 
diff --git a/cmdutils.h b/cmdutils.h
index 1d237b56aa..d22dcbf773 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -298,7 +298,19 @@ int opt_formats(const char *opt, const char *arg);
  * program.
  * This option processing function does not utilize the arguments.
  */
-int opt_codecs(const char *opt, const char *arg);
+int show_codecs(const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the decoders supported by the
+ * program.
+ */
+int show_decoders(const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the encoders supported by the
+ * program.
+ */
+int show_encoders(const char *opt, const char *arg);
 
 /**
  * Print a listing containing all the filters supported by the
diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h
index 855cb889be..3fb74d6839 100644
--- a/cmdutils_common_opts.h
+++ b/cmdutils_common_opts.h
@@ -5,7 +5,9 @@
     { "-help", OPT_EXIT, {(void*)opt_help}, "show help" },
     { "version", OPT_EXIT, {(void*)opt_version}, "show version" },
     { "formats"  , OPT_EXIT, {(void*)opt_formats  }, "show available formats" },
-    { "codecs"   , OPT_EXIT, {(void*)opt_codecs   }, "show available codecs" },
+    { "codecs"   , OPT_EXIT, {(void*)show_codecs   }, "show available codecs" },
+    { "decoders" , OPT_EXIT, {(void*)show_decoders }, "show available decoders" },
+    { "encoders" , OPT_EXIT, {(void*)show_encoders }, "show available encoders" },
     { "bsfs"     , OPT_EXIT, {(void*)opt_bsfs     }, "show available bit stream filters" },
     { "protocols", OPT_EXIT, {(void*)opt_protocols}, "show available protocols" },
     { "filters",   OPT_EXIT, {(void*)opt_filters  }, "show available filters" },
diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi
index b05b5fa84e..91460b30b2 100644
--- a/doc/avtools-common-opts.texi
+++ b/doc/avtools-common-opts.texi
@@ -72,23 +72,16 @@ Encoding available
 @end table
 
 @item -codecs
-Show available codecs.
+Show all codecs known to libavcodec.
 
-The fields preceding the codec names have the following meanings:
-@table @samp
-@item D
-Decoding available
-@item E
-Encoding available
-@item V/A/S
-Video/audio/subtitle codec
-@item S
-Codec supports slices
-@item D
-Codec supports direct rendering
-@item T
-Codec can handle input truncated at random locations instead of only at frame boundaries
-@end table
+Note that the term 'codec' is used throughout this documentation as a shortcut
+for what is more correctly called a media bitstream format.
+
+@item -decoders
+Show available decoders.
+
+@item -encoders
+Show all available encoders.
 
 @item -bsfs
 Show available bitstream filters.
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index ab7697abc5..89c1eb84c7 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -928,7 +928,7 @@ Try to make the choice automatically, in order to generate a sane output.
 
 Default value is -1.
 
-@item -shortest
+@item -shortest (@emph{output})
 Finish encoding when the shortest input stream ends.
 @item -dts_delta_threshold
 Timestamp discontinuity delta threshold.
diff --git a/ffmpeg.c b/ffmpeg.c
index b97ad7bdbf..860499a1f3 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2783,10 +2783,20 @@ static int process_input(void)
             poll_filters();
         }
 
-        if (opt_shortest)
-            return AVERROR_EOF;
-        else
-            return AVERROR(EAGAIN);
+        for (i = 0; i < nb_output_streams; i++) {
+            OutputStream *ost    = output_streams[i];
+            OutputFile *of       = output_files[ost->file_index];
+            AVFormatContext *os  = output_files[ost->file_index]->ctx;
+
+            if (of->shortest) {
+                int j;
+                for (j = 0; j < of->ctx->nb_streams; j++)
+                    output_streams[of->ost_index + j]->finished = 1;
+                continue;
+            }
+        }
+
+        return AVERROR(EAGAIN);
     }
 
     reset_eagain();
diff --git a/ffmpeg.h b/ffmpeg.h
index 4539ad9478..a2ba198cd6 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -114,6 +114,7 @@ typedef struct OptionsContext {
     uint64_t limit_filesize;
     float mux_preload;
     float mux_max_delay;
+    int shortest;
 
     int video_disable;
     int audio_disable;
@@ -332,6 +333,8 @@ typedef struct OutputFile {
     int64_t recording_time;  ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
     int64_t start_time;      ///< start time in microseconds == AV_TIME_BASE units
     uint64_t limit_filesize; /* filesize limit expressed in bytes */
+
+    int shortest;
 } OutputFile;
 
 extern InputStream **input_streams;
@@ -365,7 +368,6 @@ extern int do_pkt_dump;
 extern int copy_ts;
 extern int copy_tb;
 extern int debug_ts;
-extern int opt_shortest;
 extern int exit_on_error;
 extern int print_stats;
 extern int qp_hist;
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 22ab5044a8..39a19e8a60 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -1613,6 +1613,7 @@ loop_end:
         oc->duration = o->recording_time;
     output_files[nb_output_files - 1]->start_time     = o->start_time;
     output_files[nb_output_files - 1]->limit_filesize = o->limit_filesize;
+    output_files[nb_output_files - 1]->shortest       = o->shortest;
     av_dict_copy(&output_files[nb_output_files - 1]->opts, format_opts, 0);
 
     /* check filename in case of an image number is expected */
@@ -2210,7 +2211,7 @@ const OptionDef options[] = {
     { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" },
     { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)&copy_ts}, "copy timestamps" },
     { "copytb", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&copy_tb}, "copy input stream time base when stream copying", "mode" },
-    { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, //
+    { "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(shortest)}, "finish encoding within shortest input" },
     { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "threshold" },
     { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&dts_error_threshold}, "timestamp error delta threshold", "threshold" },
     { "xerror", OPT_BOOL, {(void*)&exit_on_error}, "exit on error", "error" },
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index d97cbc5ae2..43f2044b8f 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -133,7 +133,7 @@ static int decode_mime_header(AMRWBContext *ctx, const uint8_t *buf)
 {
     /* Decode frame header (1st octet) */
     ctx->fr_cur_mode  = buf[0] >> 3 & 0x0F;
-    ctx->fr_quality   = (buf[0] & 0x4) != 0x4;
+    ctx->fr_quality   = (buf[0] & 0x4) == 0x4;
 
     return 1;
 }
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 372d0cfe4e..1115caf23d 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1440,7 +1440,7 @@ typedef struct AVCodecContext {
     int log_level_offset;
 
     enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
-    struct AVCodec  *codec;
+    const struct AVCodec  *codec;
     char             codec_name[32];
     enum AVCodecID     codec_id; /* see AV_CODEC_ID_xxx */
 
@@ -3338,7 +3338,7 @@ typedef struct AVSubtitle {
  * if c is non-NULL, returns the next registered codec after c,
  * or NULL if c is the last one.
  */
-AVCodec *av_codec_next(AVCodec *c);
+AVCodec *av_codec_next(const AVCodec *c);
 
 /**
  * Return the LIBAVCODEC_VERSION_INT constant.
@@ -3426,7 +3426,7 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType);
  * @return An AVCodecContext filled with default values or NULL on failure.
  * @see avcodec_get_context_defaults
  */
-AVCodecContext *avcodec_alloc_context3(AVCodec *codec);
+AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
 
 /**
  * Set the fields of the given AVCodecContext to default values corresponding
@@ -3437,7 +3437,7 @@ AVCodecContext *avcodec_alloc_context3(AVCodec *codec);
  * If codec is non-NULL, it is illegal to call avcodec_open2() with a
  * different codec on this AVCodecContext.
  */
-int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec);
+int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec);
 
 /**
  * Get the AVClass for AVCodecContext. It can be used in combination with
@@ -3562,7 +3562,7 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
  * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),
  *      av_dict_set(), av_opt_find().
  */
-int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options);
+int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
 
 /**
  * Close a given AVCodecContext and free all the data associated with it
@@ -4834,12 +4834,12 @@ int avcodec_is_open(AVCodecContext *s);
 /**
  * @return a non-zero number if codec is an encoder, zero otherwise
  */
-int av_codec_is_encoder(AVCodec *codec);
+int av_codec_is_encoder(const AVCodec *codec);
 
 /**
  * @return a non-zero number if codec is a decoder, zero otherwise
  */
-int av_codec_is_decoder(AVCodec *codec);
+int av_codec_is_decoder(const AVCodec *codec);
 
 /**
  * @return descriptor for given codec ID or NULL if no descriptor exists.
@@ -4855,6 +4855,12 @@ const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id);
  */
 const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev);
 
+/**
+ * @return codec descriptor with the given name or NULL if no such descriptor
+ *         exists.
+ */
+const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name);
+
 /**
  * @}
  */
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index d702b7faf3..607eaab84a 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <string.h>
+
 #include "avcodec.h"
 
 #include "libavutil/common.h"
@@ -2122,3 +2124,14 @@ const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev)
         return prev + 1;
     return NULL;
 }
+
+const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name)
+{
+    const AVCodecDescriptor *desc = NULL;
+
+    while ((desc = avcodec_descriptor_next(desc))) {
+        if (!strcmp(desc->name, name))
+            return desc;
+    }
+    return NULL;
+}
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 6798061116..bf144affe9 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1120,6 +1120,22 @@ static int skip_check(MpegEncContext *s, Picture *p, Picture *ref)
     return 0;
 }
 
+static int encode_frame(AVCodecContext *c, AVFrame *frame)
+{
+    AVPacket pkt = { 0 };
+    int ret, got_output;
+
+    av_init_packet(&pkt);
+    av_init_packet(&pkt);
+    ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
+    if (ret < 0)
+        return ret;
+
+    ret = pkt.size;
+    av_free_packet(&pkt);
+    return ret;
+}
+
 static int estimate_best_b_count(MpegEncContext *s)
 {
     AVCodec *codec    = avcodec_find_encoder(s->avctx->codec_id);
@@ -1127,8 +1143,6 @@ static int estimate_best_b_count(MpegEncContext *s)
     AVFrame input[FF_MAX_B_FRAMES + 2];
     const int scale = s->avctx->brd_scale;
     int i, j, out_size, p_lambda, b_lambda, lambda2;
-    int outbuf_size  = s->width * s->height; // FIXME
-    uint8_t *outbuf  = av_malloc(outbuf_size);
     int64_t best_rd  = INT64_MAX;
     int best_b_count = -1;
 
@@ -1205,8 +1219,9 @@ static int estimate_best_b_count(MpegEncContext *s)
 
         input[0].pict_type = AV_PICTURE_TYPE_I;
         input[0].quality   = 1 * FF_QP2LAMBDA;
-        out_size           = avcodec_encode_video(c, outbuf,
-                                                  outbuf_size, &input[0]);
+
+        out_size = encode_frame(c, &input[0]);
+
         //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT;
 
         for (i = 0; i < s->max_b_frames + 1; i++) {
@@ -1215,14 +1230,15 @@ static int estimate_best_b_count(MpegEncContext *s)
             input[i + 1].pict_type = is_p ?
                                      AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B;
             input[i + 1].quality   = is_p ? p_lambda : b_lambda;
-            out_size = avcodec_encode_video(c, outbuf, outbuf_size,
-                                            &input[i + 1]);
+
+            out_size = encode_frame(c, &input[i + 1]);
+
             rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);
         }
 
         /* get the delayed frames */
         while (out_size) {
-            out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
+            out_size = encode_frame(c, NULL);
             rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);
         }
 
@@ -1234,7 +1250,6 @@ static int estimate_best_b_count(MpegEncContext *s)
         }
     }
 
-    av_freep(&outbuf);
     avcodec_close(c);
     av_freep(&c);
 
diff --git a/libavcodec/options.c b/libavcodec/options.c
index e64bc9edf8..cd30229e19 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -94,7 +94,8 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_typ
 }
 #endif
 
-int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){
+int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
+{
     int flags=0;
     memset(s, 0, sizeof(AVCodecContext));
 
@@ -146,7 +147,8 @@ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){
     return 0;
 }
 
-AVCodecContext *avcodec_alloc_context3(AVCodec *codec){
+AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
+{
     AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
 
     if(avctx==NULL) return NULL;
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 53759f2e6f..a96b52d638 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -115,7 +115,8 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size)
 /* encoder management */
 static AVCodec *first_avcodec = NULL;
 
-AVCodec *av_codec_next(AVCodec *c){
+AVCodec *av_codec_next(const AVCodec *c)
+{
     if(c) return c->next;
     else  return first_avcodec;
 }
@@ -131,12 +132,12 @@ static void avcodec_init(void)
     ff_dsputil_static_init();
 }
 
-int av_codec_is_encoder(AVCodec *codec)
+int av_codec_is_encoder(const AVCodec *codec)
 {
     return codec && (codec->encode || codec->encode2);
 }
 
-int av_codec_is_decoder(AVCodec *codec)
+int av_codec_is_decoder(const AVCodec *codec)
 {
     return codec && codec->decode;
 }
@@ -750,7 +751,7 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec)
 }
 #endif
 
-int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
+int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
 {
     int ret = 0;
     AVDictionary *tmp = NULL;
@@ -1888,7 +1889,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
     const char *codec_type;
     const char *codec_name;
     const char *profile = NULL;
-    AVCodec *p;
+    const AVCodec *p;
     int bitrate;
     AVRational display_aspect_ratio;
 
diff --git a/libavformat/avio.c b/libavformat/avio.c
index 9dca8679e3..fc902ff8a2 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -382,6 +382,21 @@ int ffurl_get_file_handle(URLContext *h)
     return h->prot->url_get_file_handle(h);
 }
 
+int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles)
+{
+    if (!h->prot->url_get_multi_file_handle) {
+        if (!h->prot->url_get_file_handle)
+            return AVERROR(ENOSYS);
+        *handles = av_malloc(sizeof(*handles));
+        if (!*handles)
+            return AVERROR(ENOMEM);
+        *numhandles = 1;
+        *handles[0] = h->prot->url_get_file_handle(h);
+        return 0;
+    }
+    return h->prot->url_get_multi_file_handle(h, handles, numhandles);
+}
+
 int ffurl_shutdown(URLContext *h, int flags)
 {
     if (!h->prot->url_shutdown)
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index 518ae70ccc..604f4ce833 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -41,6 +41,8 @@
 #include "libavutil/opt.h"
 #include "libavutil/timecode.h"
 
+#define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
+
 struct DVMuxContext {
     AVClass          *av_class;
     const DVprofile*  sys;           /* current DV profile, e.g.: 525/60, 625/50 */
@@ -241,7 +243,7 @@ static int dv_assemble_frame(DVMuxContext *c, AVStream* st,
         for (i = 0; i < c->n_ast && st != c->ast[i]; i++);
 
           /* FIXME: we have to have more sensible approach than this one */
-        if (av_fifo_size(c->audio_data[i]) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE)
+        if (av_fifo_size(c->audio_data[i]) + data_size >= 100*MAX_AUDIO_FRAME_SIZE)
             av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames);
         av_fifo_generic_write(c->audio_data[i], data, data_size, NULL);
 
@@ -329,7 +331,7 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
         c->start_time = ff_iso8601_to_unix_time(t->value);
 
     for (i=0; i < c->n_ast; i++) {
-        if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*AVCODEC_MAX_AUDIO_FRAME_SIZE))) {
+        if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*MAX_AUDIO_FRAME_SIZE))) {
             while (i > 0) {
                 i--;
                 av_fifo_free(c->audio_data[i]);
diff --git a/libavformat/rtmpdh.c b/libavformat/rtmpdh.c
index 03582eafb9..7d6734daac 100644
--- a/libavformat/rtmpdh.c
+++ b/libavformat/rtmpdh.c
@@ -28,6 +28,7 @@
 
 #include "config.h"
 #include "rtmpdh.h"
+#include "libavutil/random_seed.h"
 
 #define P1024                                          \
     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
@@ -78,7 +79,14 @@
             ret = (mpz_set_str(bn, buf, 16) == 0);  \
     } while (0)
 #define bn_modexp(bn, y, q, p)      mpz_powm(bn, y, q, p)
-#define bn_random(bn, num_bytes)    mpz_random(bn, num_bytes);
+#define bn_random(bn, num_bytes)                    \
+    do {                                            \
+        gmp_randstate_t rs;                         \
+        gmp_randinit_mt(rs);                        \
+        gmp_randseed_ui(rs, av_get_random_seed());  \
+        mpz_urandomb(bn, rs, num_bytes);            \
+        gmp_randclear(rs);                          \
+    } while (0)
 #elif CONFIG_GCRYPT
 #define bn_new(bn)                  bn = gcry_mpi_new(1)
 #define bn_free(bn)                 gcry_mpi_release(bn)
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 907403286f..521b2f5be4 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -71,11 +71,6 @@ void ff_rtp_send_punch_packets(URLContext* rtp_handle);
  */
 int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, int count);
 
-/**
- * Get the file handle for the RTCP socket.
- */
-int ff_rtp_get_rtcp_file_handle(URLContext *h);
-
 // these statistics are used for rtcp receiver reports...
 typedef struct {
     uint16_t max_seq;           ///< highest sequence number seen
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index f140580c7e..17b0f64afb 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -316,18 +316,27 @@ static int rtp_get_file_handle(URLContext *h)
     return s->rtp_fd;
 }
 
-int ff_rtp_get_rtcp_file_handle(URLContext *h) {
+static int rtp_get_multi_file_handle(URLContext *h, int **handles,
+                                     int *numhandles)
+{
     RTPContext *s = h->priv_data;
-    return s->rtcp_fd;
+    int *hs       = *handles = av_malloc(sizeof(**handles) * 2);
+    if (!hs)
+        return AVERROR(ENOMEM);
+    hs[0] = s->rtp_fd;
+    hs[1] = s->rtcp_fd;
+    *numhandles = 2;
+    return 0;
 }
 
 URLProtocol ff_rtp_protocol = {
-    .name                = "rtp",
-    .url_open            = rtp_open,
-    .url_read            = rtp_read,
-    .url_write           = rtp_write,
-    .url_close           = rtp_close,
-    .url_get_file_handle = rtp_get_file_handle,
-    .priv_data_size      = sizeof(RTPContext),
-    .flags               = URL_PROTOCOL_FLAG_NETWORK,
+    .name                      = "rtp",
+    .url_open                  = rtp_open,
+    .url_read                  = rtp_read,
+    .url_write                 = rtp_write,
+    .url_close                 = rtp_close,
+    .url_get_file_handle       = rtp_get_file_handle,
+    .url_get_multi_file_handle = rtp_get_multi_file_handle,
+    .priv_data_size            = sizeof(RTPContext),
+    .flags                     = URL_PROTOCOL_FLAG_NETWORK,
 };
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index b5e6858e00..35b2724950 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1690,6 +1690,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
     int n, i, ret, tcp_fd, timeout_cnt = 0;
     int max_p = 0;
     struct pollfd *p = rt->p;
+    int *fds = NULL, fdsnum, fdsidx;
 
     for (;;) {
         if (ff_check_interrupt(&s->interrupt_callback))
@@ -1707,10 +1708,21 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
         for (i = 0; i < rt->nb_rtsp_streams; i++) {
             rtsp_st = rt->rtsp_streams[i];
             if (rtsp_st->rtp_handle) {
-                p[max_p].fd = ffurl_get_file_handle(rtsp_st->rtp_handle);
-                p[max_p++].events = POLLIN;
-                p[max_p].fd = ff_rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
-                p[max_p++].events = POLLIN;
+                if (ret = ffurl_get_multi_file_handle(rtsp_st->rtp_handle,
+                                                      &fds, &fdsnum)) {
+                    av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n");
+                    return ret;
+                }
+                if (fdsnum != 2) {
+                    av_log(s, AV_LOG_ERROR,
+                           "Number of fds %d not supported\n", fdsnum);
+                    return AVERROR_INVALIDDATA;
+                }
+                for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) {
+                    p[max_p].fd       = fds[fdsidx];
+                    p[max_p++].events = POLLIN;
+                }
+                av_free(fds);
             }
         }
         n = poll(p, max_p, POLL_TIMEOUT_MS);
diff --git a/libavformat/swf.c b/libavformat/swf.c
index d0095077e5..1aa434a0ea 100644
--- a/libavformat/swf.c
+++ b/libavformat/swf.c
@@ -23,7 +23,7 @@
 #include "internal.h"
 
 const AVCodecTag ff_swf_codec_tags[] = {
-    { CODEC_ID_FLV1, 0x02 },
-    { CODEC_ID_VP6F, 0x04 },
-    { CODEC_ID_NONE,    0 },
+    { AV_CODEC_ID_FLV1, 0x02 },
+    { AV_CODEC_ID_VP6F, 0x04 },
+    { AV_CODEC_ID_NONE,    0 },
 };
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index 069457f9fd..86ea6dec9e 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -24,12 +24,12 @@
 #include "swf.h"
 
 static const AVCodecTag swf_audio_codec_tags[] = {
-    { CODEC_ID_PCM_S16LE,  0x00 },
-    { CODEC_ID_ADPCM_SWF,  0x01 },
-    { CODEC_ID_MP3,        0x02 },
-    { CODEC_ID_PCM_S16LE,  0x03 },
-//  { CODEC_ID_NELLYMOSER, 0x06 },
-    { CODEC_ID_NONE,          0 },
+    { AV_CODEC_ID_PCM_S16LE,  0x00 },
+    { AV_CODEC_ID_ADPCM_SWF,  0x01 },
+    { AV_CODEC_ID_MP3,        0x02 },
+    { AV_CODEC_ID_PCM_S16LE,  0x03 },
+//  { AV_CODEC_ID_NELLYMOSER, 0x06 },
+    { AV_CODEC_ID_NONE,          0 },
 };
 
 static int get_swf_tag(AVIOContext *pb, int *len_ptr)
diff --git a/libavformat/url.h b/libavformat/url.h
index 82f42e8c59..d88ab52705 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -81,6 +81,8 @@ typedef struct URLProtocol {
     int64_t (*url_read_seek)(URLContext *h, int stream_index,
                              int64_t timestamp, int flags);
     int (*url_get_file_handle)(URLContext *h);
+    int (*url_get_multi_file_handle)(URLContext *h, int **handles,
+                                     int *numhandles);
     int (*url_shutdown)(URLContext *h, int flags);
     int priv_data_size;
     const AVClass *priv_data_class;
@@ -202,6 +204,13 @@ int64_t ffurl_size(URLContext *h);
  */
 int ffurl_get_file_handle(URLContext *h);
 
+/**
+ * Return the file descriptors associated with this URL.
+ *
+ * @return 0 on success or <0 on error.
+ */
+int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles);
+
 /**
  * Signal the URLContext that we are done reading or writing the stream.
  *