| @@ -33,7 +33,7 @@ | |||
| #include "bytestream.h" | |||
| #include "internal.h" | |||
| #include "vorbis.h" | |||
| #include "vorbis_parser_internal.h" | |||
| #include "vorbis_parser.h" | |||
| #undef NDEBUG | |||
| #include <assert.h> | |||
| @@ -58,7 +58,7 @@ typedef struct LibvorbisContext { | |||
| vorbis_comment vc; /**< VorbisComment info */ | |||
| ogg_packet op; /**< ogg packet */ | |||
| 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 */ | |||
| } LibvorbisContext; | |||
| @@ -163,6 +163,8 @@ static av_cold int libvorbis_encode_close(AVCodecContext *avctx) | |||
| ff_af_queue_close(&s->afq); | |||
| av_freep(&avctx->extradata); | |||
| av_vorbis_parse_free(&s->vp); | |||
| return 0; | |||
| } | |||
| @@ -221,7 +223,8 @@ static av_cold int libvorbis_encode_init(AVCodecContext *avctx) | |||
| offset += header_code.bytes; | |||
| assert(offset == avctx->extradata_size); | |||
| if ((ret = avpriv_vorbis_parse_extradata(avctx, &s->vp)) < 0) { | |||
| s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size); | |||
| if (!s->vp) { | |||
| av_log(avctx, AV_LOG_ERROR, "invalid extradata\n"); | |||
| return ret; | |||
| } | |||
| @@ -318,7 +321,7 @@ static int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, | |||
| avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos); | |||
| duration = avpriv_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 */ | |||
| @@ -289,18 +289,25 @@ int avpriv_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf, | |||
| #endif | |||
| #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) | |||
| { | |||
| AVVorbisParseContext *s = s1->priv_data; | |||
| VorbisParseContext *s = s1->priv_data; | |||
| int duration; | |||
| if (!s->extradata_parsed && avctx->extradata && avctx->extradata_size) | |||
| if (avpriv_vorbis_parse_extradata(avctx, s)) | |||
| if (!s->vp && avctx->extradata && avctx->extradata_size) { | |||
| s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size); | |||
| if (!s->vp) | |||
| goto end; | |||
| } | |||
| if ((duration = avpriv_vorbis_parse_frame(s, buf, buf_size)) >= 0) | |||
| if ((duration = av_vorbis_parse_frame(s->vp, buf, buf_size)) >= 0) | |||
| s1->duration = duration; | |||
| end: | |||
| @@ -311,9 +318,16 @@ 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(AVVorbisParseContext), | |||
| .priv_data_size = sizeof(VorbisParseContext), | |||
| .parser_parse = vorbis_parse, | |||
| .parser_close = vorbis_parser_close, | |||
| }; | |||
| #endif /* CONFIG_VORBIS_PARSER */ | |||
| @@ -30,7 +30,7 @@ | |||
| #include "libavutil/dict.h" | |||
| #include "libavcodec/bytestream.h" | |||
| #include "libavcodec/get_bits.h" | |||
| #include "libavcodec/vorbis_parser_internal.h" | |||
| #include "libavcodec/vorbis_parser.h" | |||
| #include "avformat.h" | |||
| #include "flac_picture.h" | |||
| #include "internal.h" | |||
| @@ -208,7 +208,7 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, | |||
| struct oggvorbis_private { | |||
| unsigned int len[3]; | |||
| unsigned char *packet[3]; | |||
| AVVorbisParseContext vp; | |||
| AVVorbisParseContext *vp; | |||
| int64_t final_pts; | |||
| int final_duration; | |||
| }; | |||
| @@ -245,9 +245,11 @@ static void vorbis_cleanup(AVFormatContext *s, int idx) | |||
| struct ogg_stream *os = ogg->streams + idx; | |||
| struct oggvorbis_private *priv = os->private; | |||
| int i; | |||
| if (os->private) | |||
| if (os->private) { | |||
| av_vorbis_parse_free(&priv->vp); | |||
| for (i = 0; i < 3; i++) | |||
| av_freep(&priv->packet[i]); | |||
| } | |||
| } | |||
| static int vorbis_header(AVFormatContext *s, int idx) | |||
| @@ -343,7 +345,9 @@ static int vorbis_header(AVFormatContext *s, int idx) | |||
| return ret; | |||
| } | |||
| st->codec->extradata_size = ret; | |||
| if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) { | |||
| priv->vp = av_vorbis_parse_init(st->codec->extradata, st->codec->extradata_size); | |||
| if (!priv->vp) { | |||
| av_freep(&st->codec->extradata); | |||
| st->codec->extradata_size = 0; | |||
| return ret; | |||
| @@ -370,11 +374,11 @@ static int vorbis_packet(AVFormatContext *s, int idx) | |||
| uint8_t *next_pkt = last_pkt; | |||
| int first_duration = 0; | |||
| avpriv_vorbis_parse_reset(&priv->vp); | |||
| av_vorbis_parse_reset(priv->vp); | |||
| duration = 0; | |||
| for (seg = 0; seg < os->nsegs; seg++) { | |||
| if (os->segments[seg] < 255) { | |||
| int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1); | |||
| int d = av_vorbis_parse_frame(priv->vp, last_pkt, 1); | |||
| if (d < 0) { | |||
| duration = os->granule; | |||
| break; | |||
| @@ -393,12 +397,12 @@ static int vorbis_packet(AVFormatContext *s, int idx) | |||
| s->streams[idx]->duration -= s->streams[idx]->start_time; | |||
| s->streams[idx]->cur_dts = AV_NOPTS_VALUE; | |||
| priv->final_pts = AV_NOPTS_VALUE; | |||
| avpriv_vorbis_parse_reset(&priv->vp); | |||
| av_vorbis_parse_reset(priv->vp); | |||
| } | |||
| /* parse packet duration */ | |||
| if (os->psize > 0) { | |||
| duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1); | |||
| duration = av_vorbis_parse_frame(priv->vp, os->buf + os->pstart, 1); | |||
| if (duration <= 0) { | |||
| os->pflags |= AV_PKT_FLAG_CORRUPT; | |||
| return 0; | |||