• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/flacenc.c

Go to the documentation of this file.
00001 /*
00002  * raw FLAC muxer
00003  * Copyright (c) 2006-2009 Justin Ruggles
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include "libavcodec/flac.h"
00023 #include "avformat.h"
00024 #include "flacenc.h"
00025 #include "metadata.h"
00026 #include "vorbiscomment.h"
00027 #include "libavcodec/bytestream.h"
00028 
00029 
00030 static int flac_write_block_padding(ByteIOContext *pb, unsigned int n_padding_bytes,
00031                                     int last_block)
00032 {
00033     put_byte(pb, last_block ? 0x81 : 0x01);
00034     put_be24(pb, n_padding_bytes);
00035     while (n_padding_bytes > 0) {
00036         put_byte(pb, 0);
00037         n_padding_bytes--;
00038     }
00039     return 0;
00040 }
00041 
00042 static int flac_write_block_comment(ByteIOContext *pb, AVMetadata *m,
00043                                     int last_block, int bitexact)
00044 {
00045     const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
00046     unsigned int len, count;
00047     uint8_t *p, *p0;
00048 
00049     len = ff_vorbiscomment_length(m, vendor, &count);
00050     p0 = av_malloc(len+4);
00051     if (!p0)
00052         return AVERROR(ENOMEM);
00053     p = p0;
00054 
00055     bytestream_put_byte(&p, last_block ? 0x84 : 0x04);
00056     bytestream_put_be24(&p, len);
00057     ff_vorbiscomment_write(&p, m, vendor, count);
00058 
00059     put_buffer(pb, p0, len+4);
00060     av_freep(&p0);
00061     p = NULL;
00062 
00063     return 0;
00064 }
00065 
00066 static int flac_write_header(struct AVFormatContext *s)
00067 {
00068     int ret;
00069     AVCodecContext *codec = s->streams[0]->codec;
00070 
00071     ret = ff_flac_write_header(s->pb, codec, 0);
00072     if (ret)
00073         return ret;
00074 
00075     ret = flac_write_block_comment(s->pb, s->metadata, 0,
00076                                    codec->flags & CODEC_FLAG_BITEXACT);
00077     if (ret)
00078         return ret;
00079 
00080     /* The command line flac encoder defaults to placing a seekpoint
00081      * every 10s.  So one might add padding to allow that later
00082      * but there seems to be no simple way to get the duration here.
00083      * So let's try the flac default of 8192 bytes */
00084     flac_write_block_padding(s->pb, 8192, 1);
00085 
00086     return ret;
00087 }
00088 
00089 static int flac_write_trailer(struct AVFormatContext *s)
00090 {
00091     ByteIOContext *pb = s->pb;
00092     uint8_t *streaminfo;
00093     enum FLACExtradataFormat format;
00094     int64_t file_size;
00095 
00096     if (!ff_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
00097         return -1;
00098 
00099     if (!url_is_streamed(pb)) {
00100         /* rewrite the STREAMINFO header block data */
00101         file_size = url_ftell(pb);
00102         url_fseek(pb, 8, SEEK_SET);
00103         put_buffer(pb, streaminfo, FLAC_STREAMINFO_SIZE);
00104         url_fseek(pb, file_size, SEEK_SET);
00105         put_flush_packet(pb);
00106     } else {
00107         av_log(s, AV_LOG_WARNING, "unable to rewrite FLAC header.\n");
00108     }
00109     return 0;
00110 }
00111 
00112 static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
00113 {
00114     put_buffer(s->pb, pkt->data, pkt->size);
00115     put_flush_packet(s->pb);
00116     return 0;
00117 }
00118 
00119 AVOutputFormat flac_muxer = {
00120     "flac",
00121     NULL_IF_CONFIG_SMALL("raw FLAC"),
00122     "audio/x-flac",
00123     "flac",
00124     0,
00125     CODEC_ID_FLAC,
00126     CODEC_ID_NONE,
00127     flac_write_header,
00128     flac_write_packet,
00129     flac_write_trailer,
00130     .flags= AVFMT_NOTIMESTAMPS,
00131     .metadata_conv = ff_vorbiscomment_metadata_conv,
00132 };

Generated on Fri Sep 16 2011 17:17:36 for FFmpeg by  doxygen 1.7.1