#define gst_flac_enc_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstFlacEnc, gst_flac_enc, GST_TYPE_AUDIO_ENCODER,
- G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
+ G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL)
+ G_IMPLEMENT_INTERFACE (GST_TYPE_TOC_SETTER, NULL)
+ );
static gboolean gst_flac_enc_start (GstAudioEncoder * enc);
static gboolean gst_flac_enc_stop (GstAudioEncoder * enc);
flacenc->offset = 0;
flacenc->eos = FALSE;
flacenc->tags = gst_tag_list_new_empty ();
+ flacenc->toc = NULL;
return TRUE;
}
GST_DEBUG_OBJECT (enc, "stop");
gst_tag_list_unref (flacenc->tags);
flacenc->tags = NULL;
+ if (flacenc->toc)
+ gst_toc_unref (flacenc->toc);
+ flacenc->toc = NULL;
if (FLAC__stream_encoder_get_state (flacenc->encoder) !=
FLAC__STREAM_ENCODER_UNINITIALIZED) {
flacenc->stopped = TRUE;
if (flacenc->meta[2])
FLAC__metadata_object_delete (flacenc->meta[2]);
+ if (flacenc->meta[3])
+ FLAC__metadata_object_delete (flacenc->meta[3]);
+
g_free (flacenc->meta);
flacenc->meta = NULL;
}
flacenc->headers = NULL;
gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
+ gst_toc_setter_reset (GST_TOC_SETTER (enc));
return TRUE;
}
g_list_free (comments);
}
+static gboolean
+add_cuesheet (const GstToc * toc, guint sample_rate,
+ FLAC__StreamMetadata * cuesheet)
+{
+ gint8 track_num = 0;
+ gint64 start, stop;
+ gchar *isrc = NULL;
+ const gchar *is_legal;
+ GList *list;
+ GstTagList *tags;
+ GstTocEntry *entry;
+ FLAC__StreamMetadata_CueSheet *cs;
+ FLAC__StreamMetadata_CueSheet_Track *track;
+
+ cs = &cuesheet->data.cue_sheet;
+ if (!cs)
+ return FALSE;
+
+ /* check if the TOC entries is valid */
+ list = gst_toc_get_entries (toc);
+ while (list) {
+ entry = list->data;
+ if (!gst_toc_entry_is_sequence (entry))
+ return FALSE;
+ list = g_list_next (list);
+ }
+
+ /* add tracks in cuesheet */
+ list = gst_toc_get_entries (toc);
+ while (list) {
+ entry = list->data;
+ gst_toc_entry_get_start_stop_times (entry, &start, &stop);
+ tags = gst_toc_entry_get_tags (entry);
+ if (tags)
+ gst_tag_list_get_string (tags, GST_TAG_ISRC, &isrc);
+ track = FLAC__metadata_object_cuesheet_track_new ();
+ track->offset =
+ (FLAC__uint64) gst_util_uint64_scale_round (start, sample_rate,
+ GST_SECOND);
+ track->number = (FLAC__byte) track_num + 1;
+ if (isrc)
+ strcpy (track->isrc, isrc);
+ if (track->number <= 0)
+ return FALSE;
+ if (!FLAC__metadata_object_cuesheet_insert_track (cuesheet, track_num,
+ track, FALSE))
+ return FALSE;
+ if (!FLAC__metadata_object_cuesheet_track_insert_blank_index (cuesheet,
+ track_num, 0))
+ return FALSE;
+ track_num++;
+ list = g_list_next (list);
+ }
+
+ if (cs->num_tracks <= 0)
+ return FALSE;
+
+ /* add lead-out track in cuesheet */
+ track = FLAC__metadata_object_cuesheet_track_new ();
+ track->offset =
+ (FLAC__uint64) gst_util_uint64_scale_round (stop, sample_rate,
+ GST_SECOND);
+ track->number = 255;
+ if (!FLAC__metadata_object_cuesheet_insert_track (cuesheet, cs->num_tracks,
+ track, FALSE))
+ return FALSE;
+
+ /* check if the cuesheet is valid */
+ if (!FLAC__metadata_object_cuesheet_is_legal (cuesheet, FALSE, &is_legal)) {
+ g_warning ("%s\n", is_legal);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static void
-gst_flac_enc_set_metadata (GstFlacEnc * flacenc, guint64 total_samples)
+gst_flac_enc_set_metadata (GstFlacEnc * flacenc, GstAudioInfo * info,
+ guint64 total_samples)
{
const GstTagList *user_tags;
GstTagList *copy;
gint entries = 1;
gint n_images, n_preview_images;
- GstAudioInfo *info =
- gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (flacenc));
+ FLAC__StreamMetadata *cuesheet;
g_return_if_fail (flacenc != NULL);
+
user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (flacenc));
if ((flacenc->tags == NULL) && (user_tags == NULL)) {
return;
n_preview_images = gst_tag_list_get_tag_size (copy, GST_TAG_PREVIEW_IMAGE);
flacenc->meta =
- g_new0 (FLAC__StreamMetadata *, 3 + n_images + n_preview_images);
+ g_new0 (FLAC__StreamMetadata *, 4 + n_images + n_preview_images);
flacenc->meta[0] =
FLAC__metadata_object_new (FLAC__METADATA_TYPE_VORBIS_COMMENT);
gst_tag_list_foreach (copy, add_one_tag, flacenc);
+ if (!flacenc->toc)
+ flacenc->toc = gst_toc_setter_get_toc (GST_TOC_SETTER (flacenc));
+
+ if (flacenc->toc) {
+ cuesheet = FLAC__metadata_object_new (FLAC__METADATA_TYPE_CUESHEET);
+ if (add_cuesheet (flacenc->toc, GST_AUDIO_INFO_RATE (info), cuesheet)) {
+ flacenc->meta[entries] = cuesheet;
+ entries++;
+ } else {
+ FLAC__metadata_object_delete (cuesheet);
+ flacenc->meta[entries] = NULL;
+ }
+ }
+
if (n_images + n_preview_images > 0) {
GstSample *sample;
GstBuffer *buffer;
FLAC__stream_encoder_set_total_samples_estimate (flacenc->encoder,
MIN (total_samples, G_GUINT64_CONSTANT (0x0FFFFFFFFF)));
- gst_flac_enc_set_metadata (flacenc, total_samples);
+ gst_flac_enc_set_metadata (flacenc, info, total_samples);
/* callbacks clear to go now;
* write callbacks receives headers during init */
{
GstFlacEnc *flacenc;
GstTagList *taglist;
+ GstToc *toc;
gboolean ret = FALSE;
flacenc = GST_FLAC_ENC (enc);
}
ret = GST_AUDIO_ENCODER_CLASS (parent_class)->sink_event (enc, event);
break;
+ case GST_EVENT_TOC:
+ gst_event_parse_toc (event, &toc, NULL);
+ if (toc) {
+ if (flacenc->toc != toc) {
+ if (flacenc->toc)
+ gst_toc_unref (flacenc->toc);
+ flacenc->toc = toc;
+ }
+ }
+ ret = GST_AUDIO_ENCODER_CLASS (parent_class)->sink_event (enc, event);
+ break;
default:
ret = GST_AUDIO_ENCODER_CLASS (parent_class)->sink_event (enc, event);
break;