int using_webp_anim_encoder;
} WebpContext;
-static int webp_write_header(AVFormatContext *s)
+static int webp_init(AVFormatContext *s)
{
AVStream *st;
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;
}
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;
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);
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);
}
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[] = {
.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,
};