[FFmpeg-devel] [PATCH] speex in ogg muxer

Baptiste Coudurier baptiste.coudurier
Sun Jun 21 07:00:01 CEST 2009


Hi Justin,

Justin Ruggles wrote:
> Hi,
> 
> This patch adds speex support to the ogg muxer.  It basically does the
> same thing as Ogg/FLAC, in that the 1st packet is a global header from
> extradata and the 2nd packet is vorbiscomment metadata.
> 
> This seems to work just fine for speex-to-speex stream copy, but
> probably would not work for flv-to-speex because flv doesn't to have any
> speex extradata from what I can tell.  I guess a header could be
> constructed, but that would be a separate patch to the flv demuxer.
> 
> This patch is a precursor to libspeex encoding support, which I'll be
> sending shortly.
> 
> -Justin
> 
> 
> 
> ------------------------------------------------------------------------
> 
> Index: libavformat/oggenc.c
> ===================================================================
> --- libavformat/oggenc.c	(revision 19244)
> +++ libavformat/oggenc.c	(working copy)
> @@ -83,10 +83,31 @@
>      return size;
>  }
>  
> +static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact,
> +                                        int *header_len)
> +{
> +    const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
> +    int size;
> +    uint8_t *p, *p0;
> +    
> +    size = offset + 4 + strlen(vendor) + 4;
> +    p = av_mallocz(size);
> +    if (!p)
> +        return NULL;
> +    p0 = p;
> +
> +    p += offset;
> +    bytestream_put_le32(&p, strlen(vendor));
> +    bytestream_put_buffer(&p, vendor, strlen(vendor));
> +    bytestream_put_le32(&p, 0); // user comment list length
> +
> +    *header_len = size;
> +    return p0;
> +}
> +
>  static int ogg_build_flac_headers(AVCodecContext *avctx,
>                                    OGGStreamContext *oggstream, int bitexact)
>  {
> -    const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
>      enum FLACExtradataFormat format;
>      uint8_t *streaminfo;
>      uint8_t *p;
> @@ -104,17 +125,39 @@
>      bytestream_put_byte(&p, 0x00); // streaminfo
>      bytestream_put_be24(&p, 34);
>      bytestream_put_buffer(&p, streaminfo, FLAC_STREAMINFO_SIZE);
> -    oggstream->header_len[1] = 1+3+4+strlen(vendor)+4;
> -    oggstream->header[1] = av_mallocz(oggstream->header_len[1]);
> -    p = oggstream->header[1];
> +    p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1]);
> +    if (!p)
> +        return -1;

AVERROR(ENOMEM)

> +    oggstream->header[1] = p;
>      bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment
>      bytestream_put_be24(&p, oggstream->header_len[1] - 4);
> -    bytestream_put_le32(&p, strlen(vendor));
> -    bytestream_put_buffer(&p, vendor, strlen(vendor));
> -    bytestream_put_le32(&p, 0); // user comment list length
>      return 0;
>  }
>  
> +#define SPEEX_HEADER_SIZE 80
> +
> +static int ogg_build_speex_headers(AVCodecContext *avctx,
> +                                   OGGStreamContext *oggstream, int bitexact)
> +{
> +    uint8_t *p;
> +
> +    if (avctx->extradata_size != SPEEX_HEADER_SIZE)
> +        return -1;
> +
> +    p = av_mallocz(SPEEX_HEADER_SIZE);
> +    if (!p)
> +        return -1;

ditto

> +    oggstream->header[0] = p;
> +    oggstream->header_len[0] = SPEEX_HEADER_SIZE;
> +    bytestream_put_buffer(&p, avctx->extradata, SPEEX_HEADER_SIZE);
> +
> +    p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1]);
> +    if (!p)
> +        return -1;

ditto

> +    oggstream->header[1] = p;
> +    return 0;
> +}
> +
>  static int ogg_write_header(AVFormatContext *s)
>  {
>      OGGStreamContext *oggstream;
> @@ -127,7 +170,8 @@
>              av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
>          if (st->codec->codec_id != CODEC_ID_VORBIS &&
>              st->codec->codec_id != CODEC_ID_THEORA &&
> -            st->codec->codec_id != CODEC_ID_FLAC) {
> +            st->codec->codec_id != CODEC_ID_FLAC &&
> +            st->codec->codec_id != CODEC_ID_SPEEX) {
>              av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i);
>              return -1;
>          }
> @@ -144,6 +188,12 @@
>                  av_log(s, AV_LOG_ERROR, "Extradata corrupted\n");
>                  av_freep(&st->priv_data);
>              }
> +        } else if (st->codec->codec_id == CODEC_ID_SPEEX) {
> +            if (ogg_build_speex_headers(st->codec, oggstream,
> +                                        st->codec->flags & CODEC_FLAG_BITEXACT) < 0) {
> +                av_log(s, AV_LOG_ERROR, "error writing Speex headers\n");
> +                av_freep(&st->priv_data);
> +            }

return error here with the return code of the func :>
Yes, it seems flac miss it too, this needs a fix.

patch fine otherwise, maybe a micro bump for avformat would be nice.

-- 
Baptiste COUDURIER                              GnuPG Key Id: 0x5C1ABAAA
Key fingerprint                 8D77134D20CC9220201FC5DB0AC9325C5C1ABAAA
FFmpeg maintainer                                  http://www.ffmpeg.org



More information about the ffmpeg-devel mailing list