[FFmpeg-devel] [PATCH 5/7] lavf/flacenc: support writing attached pictures

James Almer jamrial at gmail.com
Wed Aug 2 17:30:21 EEST 2017


On 8/2/2017 3:30 AM, Rodger Combs wrote:
> ---
>  libavformat/flacenc.c | 285 +++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 250 insertions(+), 35 deletions(-)
> 
> diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
> index b894f9e..9768b6a 100644

[...]

> @@ -166,23 +341,63 @@ static int flac_write_trailer(struct AVFormatContext *s)
>  static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
>  {
>      FlacMuxerContext *c = s->priv_data;
> -    uint8_t *streaminfo;
> -    int streaminfo_size;
> +    if (pkt->stream_index == c->audio_stream_idx) {
> +        if (c->waiting_pics) {
> +            /* buffer audio packets until we get all the pictures */
> +            AVPacketList *pktl = av_mallocz(sizeof(*pktl));
> +            int ret;
> +            if (!pktl) {
> +                ret = AVERROR(ENOMEM);
> +oom:
> +                if (s->error_recognition & AV_EF_EXPLODE) {
> +                    av_free(pktl);
> +                    return ret;
> +                }
> +                av_log(s, AV_LOG_ERROR, "Out of memory in packet queue; skipping attached pictures\n");
> +                c->waiting_pics = 0;
> +                if ((ret = flac_queue_flush(s)) < 0)
> +                    return ret;
> +                return flac_write_audio_packet(s, pkt);
> +            }
> +
> +            ret = av_packet_ref(&pktl->pkt, pkt);
> +            if (ret < 0) {
> +                av_freep(&pktl);
> +                goto oom;
> +            }
> +
> +            if (c->queue_end)
> +                c->queue_end->next = pktl;
> +            else
> +                c->queue = pktl;
> +            c->queue_end = pktl;
> +        } else {
> +            return flac_write_audio_packet(s, pkt);
> +        }
> +    } else {
> +        int ret, index = pkt->stream_index;
>  
> -    /* check for updated streaminfo */
> -    streaminfo = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
> -                                         &streaminfo_size);
> -    if (streaminfo && streaminfo_size == FLAC_STREAMINFO_SIZE) {
> -        av_freep(&c->streaminfo);
> +        /* warn only once for each stream */
> +        if (s->streams[pkt->stream_index]->nb_frames == 1) {
> +            av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
> +                   " ignoring.\n", pkt->stream_index);
> +        }
> +        if (!c->waiting_pics || s->streams[pkt->stream_index]->nb_frames >= 1)
> +            return 0;
>  
> -        c->streaminfo = av_malloc(FLAC_STREAMINFO_SIZE);
> -        if (!c->streaminfo)
> -            return AVERROR(ENOMEM);
> -        memcpy(c->streaminfo, streaminfo, FLAC_STREAMINFO_SIZE);
> +        if (index > c->audio_stream_idx)
> +            index--;
> +
> +        if ((ret = av_copy_packet(&c->pics[index], pkt)) < 0)

Shouldn't this be av_packet_ref()?
And they should probably be unreferenced after being consumed in
flac_finish_header(), much like the audio packets are in flac_queue_flush().

Also, you don't seem to be freeing c->pics anywhere.

> +            return ret;
> +        c->waiting_pics--;
> +
> +        /* flush the buffered audio packets */
> +        if (!c->waiting_pics &&
> +            (ret = flac_queue_flush(s)) < 0)
> +            return ret;
>      }
>  
> -    if (pkt->size)
> -        avio_write(s->pb, pkt->data, pkt->size);
>      return 0;
>  }
>  
> @@ -205,7 +420,7 @@ AVOutputFormat ff_flac_muxer = {
>      .mime_type         = "audio/x-flac",
>      .extensions        = "flac",
>      .audio_codec       = AV_CODEC_ID_FLAC,
> -    .video_codec       = AV_CODEC_ID_NONE,
> +    .video_codec       = AV_CODEC_ID_PNG,
>      .write_header      = flac_write_header,
>      .write_packet      = flac_write_packet,
>      .write_trailer     = flac_write_trailer,
> 



More information about the ffmpeg-devel mailing list