diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index f6522d1d1ae9859d939d7d55df47c9d8ec9f9dfa..dc317dcf134fb5d1116ee59e6d0375bd1547e077 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -423,6 +423,7 @@ enum AVCodecID {
     AV_CODEC_ID_RALF,
     AV_CODEC_ID_IAC,
     AV_CODEC_ID_ILBC,
+    AV_CODEC_ID_OPUS_DEPRECATED,
     AV_CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
     AV_CODEC_ID_8SVX_RAW    = MKBETAG('8','S','V','X'),
     AV_CODEC_ID_SONIC       = MKBETAG('S','O','N','C'),
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 607dd96f8126c57b954097533cf758a8c183eeb9..2f9e34885c2b8f0e67d3a3f9271c8797371e78ef 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2242,7 +2242,8 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .id        = AV_CODEC_ID_OPUS,
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "opus",
-        .long_name = NULL_IF_CONFIG_SMALL("Opus"),
+        .long_name = NULL_IF_CONFIG_SMALL("Opus (Opus Interactive Audio Codec)"),
+        .props     = AV_CODEC_PROP_LOSSY,
     },
 
     /* subtitle codecs */
diff --git a/libavcodec/dwt.c b/libavcodec/dwt.c
index ec64857d98cfff37b351ba5c29a9ea0522d8336c..d36d25d1a6057526b438ba719ad07be85b9c1f7c 100644
--- a/libavcodec/dwt.c
+++ b/libavcodec/dwt.c
@@ -468,15 +468,6 @@ static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer,
     cs->y  += 2;
 }
 
-static void av_unused spatial_compose53i(IDWTELEM *buffer, IDWTELEM *temp,
-                                         int width, int height, int stride)
-{
-    DWTCompose cs;
-    spatial_compose53i_init(&cs, buffer, height, stride);
-    while (cs.y <= height)
-        spatial_compose53i_dy(&cs, buffer, temp, width, height, stride);
-}
-
 void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width)
 {
     const int w2 = (width + 1) >> 1;
@@ -651,15 +642,6 @@ static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer,
     cs->y  += 2;
 }
 
-static void av_unused spatial_compose97i(IDWTELEM *buffer, IDWTELEM *temp,
-                                         int width, int height, int stride)
-{
-    DWTCompose cs;
-    spatial_compose97i_init(&cs, buffer, height, stride);
-    while (cs.y <= height)
-        spatial_compose97i_dy(&cs, buffer, temp, width, height, stride);
-}
-
 void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
                                    int height, int stride_line, int type,
                                    int decomposition_count)
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index 27f179a943a3f7e5ad299bb574337444367e02c3..61ca6a929254cdce0a4520cc3df71a9b78306e81 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -33,7 +33,6 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "internal.h"
-#include "imgconvert.h"
 #include "libavutil/colorspace.h"
 #include "libavutil/common.h"
 #include "libavutil/pixdesc.h"
diff --git a/libavcodec/imgconvert.h b/libavcodec/imgconvert.h
deleted file mode 100644
index 64da317d27644cfef4d57f09c3f0a640aa1a0d39..0000000000000000000000000000000000000000
--- a/libavcodec/imgconvert.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Misc image conversion routines
- * most functionality is exported to the public API, see avcodec.h
- *
- * Copyright (c) 2008 Vitor Sessak
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_IMGCONVERT_H
-#define AVCODEC_IMGCONVERT_H
-
-#include <stdint.h>
-#include "avcodec.h"
-
-#if LIBAVCODEC_VERSION_MAJOR < 53
-attribute_deprecated
-int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width);
-
-attribute_deprecated
-int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt, int height);
-
-attribute_deprecated
-int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane);
-
-attribute_deprecated
-int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt);
-#endif
-
-#endif /* AVCODEC_IMGCONVERT_H */
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index 75b578359eaa8b6dba89b38d95b4017f59488090..8eb0fae48d8b89e1fb1eaf13629b02b768aa3c1c 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -25,7 +25,6 @@
  */
 
 #include "avcodec.h"
-#include "imgconvert.h"
 #include "raw.h"
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 00434c9114ce0cd2b53623f37fc2188efef64210..53b8b2bf1f3c8a260f73efa3dfb06c32046640af 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -38,7 +38,6 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "libavutil/opt.h"
-#include "imgconvert.h"
 #include "thread.h"
 #include "frame_thread_encoder.h"
 #include "audioconvert.h"
@@ -1848,6 +1847,7 @@ static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id)
         //This is for future deprecatec codec ids, its empty since
         //last major bump but will fill up again over time, please don't remove it
 //         case AV_CODEC_ID_UTVIDEO_DEPRECATED: return AV_CODEC_ID_UTVIDEO;
+        case AV_CODEC_ID_OPUS_DEPRECATED: return AV_CODEC_ID_OPUS;
         default                         : return id;
     }
 }
diff --git a/libavcodec/version.h b/libavcodec/version.h
index d96086a4a68336a6b95700b85117400b5f769158..4d4bc5fd0f6dd6adb3e224e0344ef1159c812b9e 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -27,7 +27,7 @@
  */
 
 #define LIBAVCODEC_VERSION_MAJOR 54
-#define LIBAVCODEC_VERSION_MINOR 59
+#define LIBAVCODEC_VERSION_MINOR 60
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavformat/avio.h b/libavformat/avio.h
index 08e9dd36591c46fb4431374f9d7b557d8bcb5a4a..b16d26f044ce7a4553919dedf4bc96d9c446f0e9 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -48,7 +48,7 @@
  * new elements have been added after this struct in AVFormatContext
  * or AVIOContext.
  */
-typedef struct {
+typedef struct AVIOInterruptCB {
     int (*callback)(void*);
     void *opaque;
 } AVIOInterruptCB;
@@ -65,7 +65,7 @@ typedef struct {
  *       when implementing custom I/O. Normally these are set to the
  *       function pointers specified in avio_alloc_context()
  */
-typedef struct {
+typedef struct AVIOContext {
     /**
      * A class for private options.
      *
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index ae386884c720e2dc99804c62c3abaec5e9bbcbf4..4871a0e34f860615d0e5b789a8ac1cd724f24c2f 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -349,6 +349,35 @@ static int ogg_build_speex_headers(AVCodecContext *avctx,
     return 0;
 }
 
+#define OPUS_HEADER_SIZE 19
+
+static int ogg_build_opus_headers(AVCodecContext *avctx,
+                                  OGGStreamContext *oggstream, int bitexact,
+                                  AVDictionary **m)
+{
+    uint8_t *p;
+
+    if (avctx->extradata_size < OPUS_HEADER_SIZE)
+        return -1;
+
+    /* first packet: Opus header */
+    p = av_mallocz(avctx->extradata_size);
+    if (!p)
+        return AVERROR(ENOMEM);
+    oggstream->header[0] = p;
+    oggstream->header_len[0] = avctx->extradata_size;
+    bytestream_put_buffer(&p, avctx->extradata, avctx->extradata_size);
+
+    /* second packet: VorbisComment */
+    p = ogg_write_vorbiscomment(8, bitexact, &oggstream->header_len[1], m, 0);
+    if (!p)
+        return AVERROR(ENOMEM);
+    oggstream->header[1] = p;
+    bytestream_put_buffer(&p, "OpusTags", 8);
+
+    return 0;
+}
+
 static int ogg_write_header(AVFormatContext *s)
 {
     OGGStreamContext *oggstream;
@@ -359,13 +388,18 @@ static int ogg_write_header(AVFormatContext *s)
         unsigned serial_num = i;
 
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
-            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+            if (st->codec->codec_id == AV_CODEC_ID_OPUS)
+                /* Opus requires a fixed 48kHz clock */
+                avpriv_set_pts_info(st, 64, 1, 48000);
+            else
+                avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
         else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
             avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
         if (st->codec->codec_id != AV_CODEC_ID_VORBIS &&
             st->codec->codec_id != AV_CODEC_ID_THEORA &&
             st->codec->codec_id != AV_CODEC_ID_SPEEX  &&
-            st->codec->codec_id != AV_CODEC_ID_FLAC) {
+            st->codec->codec_id != AV_CODEC_ID_FLAC   &&
+            st->codec->codec_id != AV_CODEC_ID_OPUS) {
             av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i);
             return -1;
         }
@@ -407,6 +441,15 @@ static int ogg_write_header(AVFormatContext *s)
                 av_freep(&st->priv_data);
                 return err;
             }
+        } else if (st->codec->codec_id == AV_CODEC_ID_OPUS) {
+            int err = ogg_build_opus_headers(st->codec, oggstream,
+                                             st->codec->flags & CODEC_FLAG_BITEXACT,
+                                             &s->metadata);
+            if (err) {
+                av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n");
+                av_freep(&st->priv_data);
+                return err;
+            }
         } else {
             uint8_t *p;
             const char *cstr = st->codec->codec_id == AV_CODEC_ID_VORBIS ? "vorbis" : "theora";
@@ -503,7 +546,9 @@ static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
             pframe_count = 0;
         }
         granule = (oggstream->last_kf_pts<<oggstream->kfgshift) | pframe_count;
-    } else
+    } else if (st->codec->codec_id == AV_CODEC_ID_OPUS)
+        granule = pkt->pts + pkt->duration + av_rescale_q(st->codec->delay, (AVRational){ 1, st->codec->sample_rate }, st->time_base);
+    else
         granule = pkt->pts + pkt->duration;
 
     ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule, 0);
@@ -531,7 +576,8 @@ static int ogg_write_trailer(AVFormatContext *s)
         AVStream *st = s->streams[i];
         OGGStreamContext *oggstream = st->priv_data;
         if (st->codec->codec_id == AV_CODEC_ID_FLAC ||
-            st->codec->codec_id == AV_CODEC_ID_SPEEX) {
+            st->codec->codec_id == AV_CODEC_ID_SPEEX ||
+            st->codec->codec_id == AV_CODEC_ID_OPUS) {
             av_freep(&oggstream->header[0]);
         }
         av_freep(&oggstream->header[1]);
@@ -544,7 +590,7 @@ AVOutputFormat ff_ogg_muxer = {
     .name              = "ogg",
     .long_name         = NULL_IF_CONFIG_SMALL("Ogg"),
     .mime_type         = "application/ogg",
-    .extensions        = "ogg,ogv,spx",
+    .extensions        = "ogg,ogv,spx,opus",
     .priv_data_size    = sizeof(OGGContext),
     .audio_codec       = AV_CODEC_ID_FLAC,
     .video_codec       = AV_CODEC_ID_THEORA,
diff --git a/libavformat/version.h b/libavformat/version.h
index 26cbbcfe42275179f0ea11eaaf8872b5aada573e..32a70d2792b5137ffcda1269453c0c850d213c06 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
 
 #define LIBAVFORMAT_VERSION_MAJOR 54
 #define LIBAVFORMAT_VERSION_MINOR 29
-#define LIBAVFORMAT_VERSION_MICRO 104
+#define LIBAVFORMAT_VERSION_MICRO 105
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \