#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavcodec/flac.h"
+#include "libavcodec/packet_internal.h"
#include "avformat.h"
#include "avio_internal.h"
#include "flacenc.h"
#include "id3v2.h"
#include "internal.h"
#include "vorbiscomment.h"
-#include "libavcodec/bytestream.h"
typedef struct FlacMuxerContext {
int audio_stream_idx;
int waiting_pics;
/* audio packets are queued here until we get all the attached pictures */
- AVPacketList *queue, *queue_end;
+ PacketList *queue, *queue_end;
/* updated streaminfo sent by the encoder at the end */
- uint8_t *streaminfo;
+ uint8_t streaminfo[FLAC_STREAMINFO_SIZE];
+ int updated_streaminfo;
unsigned attached_types;
} FlacMuxerContext;
{
const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
int64_t len;
- uint8_t *p, *p0;
ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL);
len = ff_vorbiscomment_length(*m, vendor, NULL, 0);
if (len >= ((1<<24) - 4))
return AVERROR(EINVAL);
- p0 = av_malloc(len+4);
- if (!p0)
- return AVERROR(ENOMEM);
- p = p0;
-
- bytestream_put_byte(&p, last_block ? 0x84 : 0x04);
- bytestream_put_be24(&p, len);
- ff_vorbiscomment_write(&p, m, vendor, NULL, 0);
- avio_write(pb, p0, len+4);
- av_freep(&p0);
- p = NULL;
+ avio_w8(pb, last_block ? 0x84 : 0x04);
+ avio_wb24(pb, len);
+ ff_vorbiscomment_write(pb, *m, vendor, NULL, 0);
return 0;
}
AVDictionaryEntry *e;
const char *mimetype = NULL, *desc = "";
const AVStream *st = s->streams[pkt->stream_index];
- int i, mimelen, desclen, type = 0;
+ int i, mimelen, desclen, type = 0, blocklen;
if (!pkt->data)
return 0;
desc = e->value;
desclen = strlen(desc);
+ blocklen = 4 + 4 + mimelen + 4 + desclen + 4 + 4 + 4 + 4 + 4 + pkt->size;
+ if (blocklen >= 1<<24) {
+ av_log(s, AV_LOG_ERROR, "Picture block too big %d >= %d\n", blocklen, 1<<24);
+ return AVERROR(EINVAL);
+ }
+
avio_w8(pb, 0x06);
- avio_wb24(pb, 4 + 4 + mimelen + 4 + desclen + 4 + 4 + 4 + 4 + 4 + pkt->size);
+ avio_wb24(pb, blocklen);
avio_wb32(pb, type);
{
FlacMuxerContext *c = s->priv_data;
uint8_t *streaminfo;
- int streaminfo_size;
+ size_t streaminfo_size;
/* 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);
-
- c->streaminfo = av_malloc(FLAC_STREAMINFO_SIZE);
- if (!c->streaminfo)
- return AVERROR(ENOMEM);
memcpy(c->streaminfo, streaminfo, FLAC_STREAMINFO_SIZE);
+ c->updated_streaminfo = 1;
}
if (pkt->size)
write = 0;
while (c->queue) {
- ff_packet_list_get(&c->queue, &c->queue_end, &pkt);
+ avpriv_packet_list_get(&c->queue, &c->queue_end, &pkt);
if (write && (ret = flac_write_audio_packet(s, &pkt)) < 0)
write = 0;
av_packet_unref(&pkt);
AVIOContext *pb = s->pb;
int64_t file_size;
FlacMuxerContext *c = s->priv_data;
- uint8_t *streaminfo = c->streaminfo ? c->streaminfo :
- s->streams[c->audio_stream_idx]->codecpar->extradata;
if (c->waiting_pics) {
av_log(s, AV_LOG_WARNING, "No packets were sent for some of the "
flac_queue_flush(s);
}
- if (!c->write_header || !streaminfo)
+ if (!c->write_header || !c->updated_streaminfo)
return 0;
if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
/* rewrite the STREAMINFO header block data */
file_size = avio_tell(pb);
avio_seek(pb, 8, SEEK_SET);
- avio_write(pb, streaminfo, FLAC_STREAMINFO_SIZE);
+ avio_write(pb, c->streaminfo, FLAC_STREAMINFO_SIZE);
avio_seek(pb, file_size, SEEK_SET);
- avio_flush(pb);
} else {
av_log(s, AV_LOG_WARNING, "unable to rewrite FLAC header.\n");
}
- av_freep(&c->streaminfo);
-
return 0;
}
+static void flac_deinit(struct AVFormatContext *s)
+{
+ FlacMuxerContext *c = s->priv_data;
+
+ avpriv_packet_list_free(&c->queue, &c->queue_end);
+ for (unsigned i = 0; i < s->nb_streams; i++)
+ av_packet_free((AVPacket **)&s->streams[i]->priv_data);
+}
+
static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
{
FlacMuxerContext *c = s->priv_data;
if (pkt->stream_index == c->audio_stream_idx) {
if (c->waiting_pics) {
/* buffer audio packets until we get all the pictures */
- ret = ff_packet_list_put(&c->queue, &c->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET);
+ ret = avpriv_packet_list_put(&c->queue, &c->queue_end, pkt, av_packet_ref, 0);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Out of memory in packet queue; skipping attached pictures\n");
c->waiting_pics = 0;
.write_header = flac_write_header,
.write_packet = flac_write_packet,
.write_trailer = flac_write_trailer,
+ .deinit = flac_deinit,
.flags = AVFMT_NOTIMESTAMPS,
.priv_class = &flac_muxer_class,
};