/*
- * Copyright (C) 2004-2011 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2004 Andre Noll <maan@tuebingen.mpg.de>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
vorbis_comment vc;
};
+/*
+ * Vorbis uses three header packets, all of which are required: the
+ * identification header, the comments header, and the setup header.
+ *
+ * The identification header identifies the bitstream as Vorbis. It contains
+ * the Vorbis version and simple audio characteristics of the stream such as
+ * sample rate and number of channels.
+ *
+ * The comment header includes user text comments (tags) and a vendor string
+ * for the application/library that produced the bitstream.
+ *
+ * The setup header includes extensive CODEC setup information as well as the
+ * complete VQ and Huffman codebooks needed for decoding.
+ */
static int vorbis_packet_callback(ogg_packet *packet, int packet_num,
__a_unused int serial, struct afh_info *afhi, void *private_data)
{
memcpy(p + og->header_len, og->body, og->body_len);
vghd->buf = buf;
vghd->len = new_len;
- PARA_DEBUG_LOG("header/body/old/new: %lu/%lu/%zu/%zu\n",
+ PARA_DEBUG_LOG("header/body/old/new: %li/%li/%zu/%zu\n",
og->header_len, og->body_len, old_len, new_len);
}
return 0;
if (packet_num == 0) {
ogg_stream_init(&vghd->os, serial);
- ret = -E_OGG_PACKET_IN;
ret = ogg_stream_packetin(&vghd->os, packet);
if (ret < 0)
goto out;
return 1;
}
if (packet_num == 1) {
- PARA_INFO_LOG("replacing metadata packet\n");
ogg_packet replacement = *packet;
+ PARA_INFO_LOG("replacing metadata packet\n");
replacement.packet = dummy_packet;
replacement.bytes = sizeof(dummy_packet);
ret = ogg_stream_packetin(&vghd->os, &replacement);
ret = -E_OGG_PACKET_IN;
if (ogg_stream_packetin(&vghd->os, packet) < 0)
goto out;
- ret = -E_OGG_STREAM_FLUSH;
- if (ogg_stream_flush(&vghd->os, &og) == 0)
- goto out;
- add_ogg_page(&og, vghd);
+ while (ogg_stream_flush(&vghd->os, &og))
+ add_ogg_page(&og, vghd);
ret = 0;
out:
ogg_stream_clear(&vghd->os);
PARA_ERROR_LOG("%s\n", para_strerror(-ret));
}
-static const char* ogg_suffixes[] = {"ogg", NULL};
+static int vorbis_make_meta_packet(struct taginfo *tags, ogg_packet *result)
+{
+ vorbis_comment vc;
+ int ret;
+
+ vorbis_comment_init(&vc);
+ vorbis_comment_add_tag(&vc, "artist", tags->artist);
+ vorbis_comment_add_tag(&vc, "title", tags->title);
+ vorbis_comment_add_tag(&vc, "album", tags->album);
+ vorbis_comment_add_tag(&vc, "year", tags->year);
+ vorbis_comment_add_tag(&vc, "comment", tags->comment);
+ ret = vorbis_commentheader_out(&vc, result);
+ vorbis_comment_clear(&vc);
+ if (ret != 0)
+ return -E_VORBIS_COMMENTHEADER;
+ return 1;
+}
+
+static int vorbis_rewrite_tags(const char *map, size_t mapsize,
+ struct taginfo *tags, int output_fd,
+ __a_unused const char *filename)
+{
+ int ret;
+ ogg_packet packet;
+
+ ret = vorbis_make_meta_packet(tags, &packet);
+ if (ret < 0)
+ return ret;
+ ret = ogg_rewrite_tags(map, mapsize, output_fd, (char *)packet.packet,
+ packet.bytes);
+ free(packet.packet);
+ return ret;
+}
+
+static const char * const ogg_suffixes[] = {"ogg", NULL};
/**
* The init function of the ogg vorbis audio format handler.
afh->get_file_info = ogg_vorbis_get_file_info;
afh->get_header = vorbis_get_header;
afh->suffixes = ogg_suffixes;
+ afh->rewrite_tags = vorbis_rewrite_tags;
}