[FFmpeg-devel] [FFmpeg-cvslog] avcodec/gif: enable encoding single gif image per frame
Paul B Mahol
onemda at gmail.com
Sat Dec 15 14:43:38 EET 2018
On 12/15/18, Paul B Mahol <onemda at gmail.com> wrote:
> On 12/15/18, Paul B Mahol <onemda at gmail.com> wrote:
>> On 12/15/18, Carl Eugen Hoyos <ceffmpeg at gmail.com> wrote:
>>> 2018-12-13 19:32 GMT+01:00, Paul B Mahol <git at videolan.org>:
>>>> ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed Dec 12
>>>> 13:19:33 2018 +0100| [bb0984cc29e93e56506722fe0ce5c6d43b6d4326] |
>>>> committer:
>>>> Paul B Mahol
>>>>
>>>> avcodec/gif: enable encoding single gif image per frame
>>>>
>>>> Unbreaks gif image2 muxer.
>>>>
>>>>> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=bb0984cc29e93e56506722fe0ce5c6d43b6d4326
>>>> ---
>>>>
>>>> libavcodec/gif.c | 20 ++++++++++++++------
>>>> 1 file changed, 14 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/libavcodec/gif.c b/libavcodec/gif.c
>>>> index 408b7534da..67fc5a1bda 100644
>>>> --- a/libavcodec/gif.c
>>>> +++ b/libavcodec/gif.c
>>>> @@ -51,6 +51,7 @@ typedef struct GIFContext {
>>>> int is_first_frame;
>>>> AVFrame *last_frame;
>>>> int flags;
>>>> + int image;
>>>> uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette
>>>> for
>>>> !pal8
>>>> int palette_loaded;
>>>> int transparent_index;
>>>> @@ -422,6 +423,9 @@ static int gif_encode_frame(AVCodecContext *avctx,
>>>> AVPacket *pkt,
>>>> outbuf_ptr = pkt->data;
>>>> end = pkt->data + pkt->size;
>>>>
>>>> + if (s->image)
>>>> + s->is_first_frame = 1;
>>>> +
>>>> if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
>>>> palette = (uint32_t*)pict->data[1];
>>>>
>>>> @@ -436,19 +440,22 @@ static int gif_encode_frame(AVCodecContext
>>>> *avctx,
>>>> AVPacket *pkt,
>>>>
>>>> gif_image_write_image(avctx, &outbuf_ptr, end, palette,
>>>> pict->data[0], pict->linesize[0], pkt);
>>>> - if (!s->last_frame) {
>>>> + if (!s->last_frame && !s->image) {
>>>> s->last_frame = av_frame_alloc();
>>>> if (!s->last_frame)
>>>> return AVERROR(ENOMEM);
>>>> }
>>>>
>>>> - av_frame_unref(s->last_frame);
>>>> - ret = av_frame_ref(s->last_frame, (AVFrame*)pict);
>>>> - if (ret < 0)
>>>> - return ret;
>>>> + if (!s->image) {
>>>> + av_frame_unref(s->last_frame);
>>>> + ret = av_frame_ref(s->last_frame, (AVFrame*)pict);
>>>> + if (ret < 0)
>>>> + return ret;
>>>> + }
>>>>
>>>> pkt->size = outbuf_ptr - pkt->data;
>>>> - pkt->flags |= AV_PKT_FLAG_KEY;
>>>> + if (s->is_first_frame)
>>>> + pkt->flags |= AV_PKT_FLAG_KEY;
>>>> *got_packet = 1;
>>>>
>>>> return 0;
>>>> @@ -472,6 +479,7 @@ static const AVOption gif_options[] = {
>>>> { "gifflags", "set GIF flags", OFFSET(flags), AV_OPT_TYPE_FLAGS,
>>>> {.i64
>>>> = GF_OFFSETTING|GF_TRANSDIFF}, 0, INT_MAX, FLAGS, "flags" },
>>>> { "offsetting", "enable picture offsetting", 0,
>>>> AV_OPT_TYPE_CONST,
>>>> {.i64=GF_OFFSETTING}, INT_MIN, INT_MAX, FLAGS, "flags" },
>>>> { "transdiff", "enable transparency detection between frames",
>>>> 0,
>>>> AV_OPT_TYPE_CONST, {.i64=GF_TRANSDIFF}, INT_MIN, INT_MAX, FLAGS,
>>>> "flags"
>>>> },
>>>> + { "gifimage", "enable encoding only images per frame",
>>>> OFFSET(image),
>>>> AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS, "flags" },
>>>
>>> Would it not be possible to detect in the flush function that only one
>>> frame
>>> was encoded and make the flag unnecessary?
>>
>> Unfortunately not, gif encoder is not reset anywhere and so
>> frame_number is never set back to 0.
>>
>
> I could use par->codec_tag for this 'GIFI' for images, image2 muxer
> would set this, and encoder could check it, but this is far from
> perfect solution.
>
Or create fake extradata.
More information about the ffmpeg-devel
mailing list