diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c
index 061a4e9da7..b111379e10 100644
--- a/libavcodec/libvorbisenc.c
+++ b/libavcodec/libvorbisenc.c
@@ -28,6 +28,7 @@
 #include "internal.h"
 #include "vorbis.h"
 #include "vorbis_parser.h"
+#include "vorbis_parser_internal.h"
 
 
 /* Number of samples the user should send in each call.
@@ -48,7 +49,7 @@ typedef struct LibvorbisEncContext {
     int eof;                            /**< end-of-file flag               */
     int dsp_initialized;                /**< vd has been initialized        */
     double iblock;                      /**< impulse block bias option      */
-    AVVorbisParseContext *vp;           /**< parse context to get durations */
+    AVVorbisParseContext vp;            /**< parse context to get durations */
     AudioFrameQueue afq;                /**< frame queue for timestamps     */
 } LibvorbisEncContext;
 
@@ -196,8 +197,6 @@ static av_cold int libvorbis_encode_close(AVCodecContext *avctx)
     av_fifo_freep(&s->pkt_fifo);
     ff_af_queue_close(&s->afq);
 
-    av_vorbis_parse_free(&s->vp);
-
     return 0;
 }
 
@@ -260,10 +259,9 @@ static av_cold int libvorbis_encode_init(AVCodecContext *avctx)
     offset += header_code.bytes;
     av_assert0(offset == avctx->extradata_size);
 
-    s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size);
-    if (!s->vp) {
+    ret = ff_vorbis_parse_init(&s->vp, avctx->extradata, avctx->extradata_size);
+    if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "invalid extradata\n");
-        ret = AVERROR_UNKNOWN;
         goto error;
     }
 
@@ -355,7 +353,7 @@ static int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
     avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos);
 
-    duration = av_vorbis_parse_frame(s->vp, avpkt->data, avpkt->size);
+    duration = av_vorbis_parse_frame(&s->vp, avpkt->data, avpkt->size);
     if (duration > 0) {
         /* we do not know encoder delay until we get the first packet from
          * libvorbis, so we have to update the AudioFrameQueue counts */
diff --git a/libavcodec/vorbis_parser.c b/libavcodec/vorbis_parser.c
index 0b2c97cde5..0d87102adc 100644
--- a/libavcodec/vorbis_parser.c
+++ b/libavcodec/vorbis_parser.c
@@ -181,8 +181,8 @@ bad_header:
     return ret;
 }
 
-static int vorbis_parse_init(AVVorbisParseContext *s,
-                             const uint8_t *extradata, int extradata_size)
+int ff_vorbis_parse_init(AVVorbisParseContext *s,
+                         const uint8_t *extradata, int extradata_size)
 {
     const uint8_t *header_start[3];
     int header_len[3];
@@ -287,7 +287,7 @@ AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata,
     if (!s)
         return NULL;
 
-    ret = vorbis_parse_init(s, extradata, extradata_size);
+    ret = ff_vorbis_parse_init(s, extradata, extradata_size);
     if (ret < 0) {
         av_vorbis_parse_free(&s);
         return NULL;
@@ -298,24 +298,20 @@ AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata,
 
 #if CONFIG_VORBIS_PARSER
 
-typedef struct VorbisParseContext {
-    AVVorbisParseContext *vp;
-} VorbisParseContext;
-
 static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
                         const uint8_t **poutbuf, int *poutbuf_size,
                         const uint8_t *buf, int buf_size)
 {
-    VorbisParseContext *s = s1->priv_data;
+    AVVorbisParseContext *s = s1->priv_data;
     int duration;
 
-    if (!s->vp && avctx->extradata && avctx->extradata_size) {
-        s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size);
+    if (!s->valid_extradata && avctx->extradata && avctx->extradata_size) {
+        ff_vorbis_parse_init(s, avctx->extradata, avctx->extradata_size);
     }
-    if (!s->vp)
+    if (!s->valid_extradata)
         goto end;
 
-    if ((duration = av_vorbis_parse_frame(s->vp, buf, buf_size)) >= 0)
+    if ((duration = av_vorbis_parse_frame(s, buf, buf_size)) >= 0)
         s1->duration = duration;
 
 end:
@@ -326,16 +322,9 @@ end:
     return buf_size;
 }
 
-static void vorbis_parser_close(AVCodecParserContext *ctx)
-{
-    VorbisParseContext *s = ctx->priv_data;
-    av_vorbis_parse_free(&s->vp);
-}
-
 AVCodecParser ff_vorbis_parser = {
     .codec_ids      = { AV_CODEC_ID_VORBIS },
-    .priv_data_size = sizeof(VorbisParseContext),
+    .priv_data_size = sizeof(AVVorbisParseContext),
     .parser_parse   = vorbis_parse,
-    .parser_close   = vorbis_parser_close,
 };
 #endif /* CONFIG_VORBIS_PARSER */
diff --git a/libavcodec/vorbis_parser_internal.h b/libavcodec/vorbis_parser_internal.h
index 691a842385..c0158a210c 100644
--- a/libavcodec/vorbis_parser_internal.h
+++ b/libavcodec/vorbis_parser_internal.h
@@ -43,4 +43,7 @@ struct AVVorbisParseContext {
     int prev_mask;              ///< bitmask used to get the previous mode flag in each packet
 };
 
+int ff_vorbis_parse_init(AVVorbisParseContext *s,
+                         const uint8_t *extradata, int extradata_size);
+
 #endif /* AVCODEC_VORBIS_PARSER_INTERNAL_H */
