X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fwebpenc.c;h=9599fe7b85071ba320d5b1f08eaf25ad00f7a428;hb=f4df5039a791a56de85c64e6b9e4448a221b5c40;hp=9fb472257d7afc2a09b74c1a0f4b406c078ce1e1;hpb=762c2b5dcd99a08452299cd1f83070f88115f1f3;p=ffmpeg diff --git a/libavformat/webpenc.c b/libavformat/webpenc.c index 9fb472257d7..9599fe7b850 100644 --- a/libavformat/webpenc.c +++ b/libavformat/webpenc.c @@ -33,7 +33,7 @@ typedef struct WebpContext{ int using_webp_anim_encoder; } WebpContext; -static int webp_write_header(AVFormatContext *s) +static int webp_init(AVFormatContext *s) { AVStream *st; @@ -53,24 +53,22 @@ static int webp_write_header(AVFormatContext *s) static int is_animated_webp_packet(AVPacket *pkt) { - if (pkt->size) { - int skip = 0; - unsigned flags = 0; - - if (pkt->size < 4) - return 0; - if (AV_RL32(pkt->data) == AV_RL32("RIFF")) - skip = 12; - - if (pkt->size < skip + 4) - return 0; - if (AV_RL32(pkt->data + skip) == AV_RL32("VP8X")) { - flags |= pkt->data[skip + 4 + 4]; - } - - if (flags & 2) // ANIMATION_FLAG is on - return 1; + int skip = 0; + unsigned flags = 0; + + if (pkt->size < 4) + return AVERROR_INVALIDDATA; + if (AV_RL32(pkt->data) == AV_RL32("RIFF")) + skip = 12; + // Safe to do this as a valid WebP bitstream is >=30 bytes. + if (pkt->size < skip + 4) + return AVERROR_INVALIDDATA; + if (AV_RL32(pkt->data + skip) == AV_RL32("VP8X")) { + flags |= pkt->data[skip + 4 + 4]; } + + if (flags & 2) // ANIMATION_FLAG is on + return 1; return 0; } @@ -84,13 +82,9 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) unsigned flags = 0; int vp8x = 0; - if (w->last_pkt.size < 4) - return 0; if (AV_RL32(w->last_pkt.data) == AV_RL32("RIFF")) skip = 12; - if (w->last_pkt.size < skip + 4) - return 0; // Safe to do this as a valid WebP bitstream is >=30 bytes. if (AV_RL32(w->last_pkt.data + skip) == AV_RL32("VP8X")) { flags |= w->last_pkt.data[skip + 4 + 4]; vp8x = 1; @@ -149,7 +143,14 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) static int webp_write_packet(AVFormatContext *s, AVPacket *pkt) { WebpContext *w = s->priv_data; - w->using_webp_anim_encoder |= is_animated_webp_packet(pkt); + int ret; + + if (!pkt->size) + return 0; + ret = is_animated_webp_packet(pkt); + if (ret < 0) + return ret; + w->using_webp_anim_encoder |= ret; if (w->using_webp_anim_encoder) { avio_write(s->pb, pkt->data, pkt->size); @@ -171,7 +172,7 @@ static int webp_write_trailer(AVFormatContext *s) WebpContext *w = s->priv_data; if (w->using_webp_anim_encoder) { - if ((w->frame_count > 1) && w->loop) { // Write loop count. + if (w->loop) { // Write loop count. avio_seek(s->pb, 42, SEEK_SET); avio_wl16(s->pb, w->loop); } @@ -190,6 +191,13 @@ static int webp_write_trailer(AVFormatContext *s) return 0; } +static void webp_deinit(AVFormatContext *s) +{ + WebpContext *w = s->priv_data; + + av_packet_unref(&w->last_pkt); +} + #define OFFSET(x) offsetof(WebpContext, x) #define ENC AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { @@ -204,15 +212,16 @@ static const AVClass webp_muxer_class = { .version = LIBAVUTIL_VERSION_INT, .option = options, }; -AVOutputFormat ff_webp_muxer = { +const AVOutputFormat ff_webp_muxer = { .name = "webp", .long_name = NULL_IF_CONFIG_SMALL("WebP"), .extensions = "webp", .priv_data_size = sizeof(WebpContext), .video_codec = AV_CODEC_ID_WEBP, - .write_header = webp_write_header, + .init = webp_init, .write_packet = webp_write_packet, .write_trailer = webp_write_trailer, + .deinit = webp_deinit, .priv_class = &webp_muxer_class, .flags = AVFMT_VARIABLE_FPS, };