~ubuntu-branches/ubuntu/trusty/sound-juicer/trusty

« back to all changes in this revision

Viewing changes to src/gsttaglib.cc

  • Committer: Bazaar Package Importer
  • Author(s): Pedro Fragoso
  • Date: 2008-12-15 13:16:02 UTC
  • mfrom: (1.1.35 upstream) (2.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20081215131602-0bezbep7s4w4zy0s
Tags: 2.25.1-0ubuntu1
* Sync on Debian
* debian/control.in:
  - Build-depends on libcdio-dev and liblaunchpad-integration-dev
* debian/patches/01_lpi.patch,
  debian/patches/02_autoconf.patch:
  - lpi changes and configure update
* New upstream version (LP: #308165)
  - Chain the metadata lookups (Bastien Nocera)
  - Finish the libmusicbrainz3 metadata fetcher (BN)
  - Add a GVFS metadata fetcher as fallback (BN)
  - Make libcdio option, as it breaks the GPL+Exception license (BN)
  - Export ASIN, Discogs, Wikipedia in the internal metadata (BN)
  - Lots of other cleanups to the metadata code (BN)
  - Remove copy of the id3mux plugin, assume it exists now (BN)
  - Remove Encoding field from desktop file (Pacho Ramos)
  - Add Audio to desktop categories (Patryk Zawadzki)
  - Correctly parse CDDA URLs (Matthew Martin)
  - Don't free the option context
* debian/control.in:
  - Change build-dep on libmusicbrainz3-dev
  - Also build-dep on libneon26-gnutls-dev and libdiscid0-dev for lmb3
* debian/watch:
  - Update for 2.25.x releases

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* GStreamer taglib-based ID3 muxer
2
 
 * (c) 2006 Christophe Fergeau  <teuf@gnome.org>
3
 
 *
4
 
 * This library is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU Library General Public
6
 
 * License as published by the Free Software Foundation; either
7
 
 * version 2 of the License, or (at your option) any later version.
8
 
 *
9
 
 * This library is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 * Library General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU Library General Public
15
 
 * License along with this library; if not, write to the
16
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 
 * Boston, MA 02111-1307, USA.
18
 
 */
19
 
 
20
 
/**
21
 
 * SECTION:element-tagid3v2mux
22
 
 * @see_also: #GstID3Demux, #GstTagSetter
23
 
 *
24
 
 * <refsect2>
25
 
 * <para>
26
 
 * This element adds ID3v2 tags to the beginning of a stream using the taglib
27
 
 * library. More precisely, the tags written are ID3 version 2.4.0 tags (which
28
 
 * means in practice that some hardware players or outdated programs might not
29
 
 * be able to read them properly).
30
 
 * </para>
31
 
 * <para>
32
 
 * Applications can set the tags to write using the #GstTagSetter interface.
33
 
 * Tags sent by upstream elements will be picked up automatically (and merged
34
 
 * according to the merge mode set via the tag setter interface).
35
 
 * </para>
36
 
 * <para>
37
 
 * Here is a simple pipeline that transcodes a file from Ogg/Vorbis to mp3
38
 
 * format with an ID3v2 that contains the same as the the Ogg/Vorbis file:
39
 
 * <programlisting>
40
 
 * gst-launch -v filesrc location=foo.ogg ! decodebin ! audioconvert ! lame ! tagid3v2mux ! filesink location=foo.mp3
41
 
 * </programlisting>
42
 
 * </para>
43
 
 * </refsect2>
44
 
 */
45
 
 
46
 
 
47
 
#ifdef HAVE_CONFIG_H
48
 
#include <config.h>
49
 
#endif
50
 
 
51
 
#include <string.h>
52
 
#include <textidentificationframe.h>
53
 
#include <uniquefileidentifierframe.h>
54
 
#include <id3v2tag.h>
55
 
#include <gst/gsttagsetter.h>
56
 
#include <gst/tag/tag.h>
57
 
#include "gsttaglib.h"
58
 
 
59
 
using namespace TagLib;
60
 
 
61
 
GST_DEBUG_CATEGORY_STATIC (sj_tag_lib_mux_debug);
62
 
#define GST_CAT_DEFAULT sj_tag_lib_mux_debug
63
 
 
64
 
static void
65
 
sj_tag_lib_mux_iface_init (GType taglib_type)
66
 
{
67
 
  static const GInterfaceInfo tag_setter_info = {
68
 
    NULL,
69
 
    NULL,
70
 
    NULL
71
 
  };
72
 
 
73
 
  g_type_add_interface_static (taglib_type, GST_TYPE_TAG_SETTER,
74
 
      &tag_setter_info);
75
 
}
76
 
 
77
 
GST_BOILERPLATE_FULL (SjTagLibMux, sj_tag_lib_mux,
78
 
    GstElement, GST_TYPE_ELEMENT, sj_tag_lib_mux_iface_init);
79
 
 
80
 
 
81
 
static GstStateChangeReturn
82
 
sj_tag_lib_mux_change_state (GstElement * element, GstStateChange transition);
83
 
static GstFlowReturn sj_tag_lib_mux_chain (GstPad * pad, GstBuffer * buffer);
84
 
static gboolean sj_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event);
85
 
 
86
 
 
87
 
static void
88
 
sj_tag_lib_mux_finalize (GObject * obj)
89
 
{
90
 
  SjTagLibMux *taglib = SJ_TAGLIB_MUX (obj);
91
 
 
92
 
  if (taglib->tags) {
93
 
    gst_tag_list_free (taglib->tags);
94
 
    taglib->tags = NULL;
95
 
  }
96
 
  G_OBJECT_CLASS (parent_class)->finalize (obj);
97
 
}
98
 
 
99
 
 
100
 
static GstStaticPadTemplate sj_tag_lib_mux_sink_template =
101
 
GST_STATIC_PAD_TEMPLATE ("sink",
102
 
    GST_PAD_SINK,
103
 
    GST_PAD_ALWAYS,
104
 
    GST_STATIC_CAPS ("audio/mpeg"));
105
 
 
106
 
 
107
 
static GstStaticPadTemplate sj_tag_lib_mux_src_template =
108
 
GST_STATIC_PAD_TEMPLATE ("src",
109
 
    GST_PAD_SRC,
110
 
    GST_PAD_ALWAYS,
111
 
    GST_STATIC_CAPS ("application/x-id3"));
112
 
 
113
 
 
114
 
static void
115
 
sj_tag_lib_mux_base_init (gpointer g_class)
116
 
{
117
 
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
118
 
 
119
 
  static GstElementDetails sj_tag_lib_mux_details = {
120
 
    "TagLib ID3 Muxer",
121
 
    "Formatter/Metadata",
122
 
    "Adds an ID3v2 header to the beginning of MP3 files",
123
 
    "Christophe Fergeau <teuf@gnome.org>"
124
 
  };
125
 
 
126
 
 
127
 
  gst_element_class_add_pad_template (element_class,
128
 
      gst_static_pad_template_get (&sj_tag_lib_mux_src_template));
129
 
  gst_element_class_add_pad_template (element_class,
130
 
      gst_static_pad_template_get (&sj_tag_lib_mux_sink_template));
131
 
  gst_element_class_set_details (element_class, &sj_tag_lib_mux_details);
132
 
}
133
 
 
134
 
static void
135
 
sj_tag_lib_mux_class_init (SjTagLibMuxClass * klass)
136
 
{
137
 
  GObjectClass *gobject_class;
138
 
  GstElementClass *gstelement_class;
139
 
 
140
 
  gobject_class = (GObjectClass *) klass;
141
 
  gstelement_class = (GstElementClass *) klass;
142
 
 
143
 
  gobject_class->finalize = GST_DEBUG_FUNCPTR (sj_tag_lib_mux_finalize);
144
 
  gstelement_class->change_state =
145
 
      GST_DEBUG_FUNCPTR (sj_tag_lib_mux_change_state);
146
 
}
147
 
 
148
 
static void
149
 
sj_tag_lib_mux_init (SjTagLibMux * taglib,
150
 
    SjTagLibMuxClass * taglibmux_class)
151
 
{
152
 
  GstElementClass *klass = GST_ELEMENT_CLASS (taglibmux_class);
153
 
 
154
 
  /* pad through which data comes in to the element */
155
 
  taglib->sinkpad =
156
 
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
157
 
          "sink"), "sink");
158
 
  gst_pad_set_setcaps_function (taglib->sinkpad,
159
 
      GST_DEBUG_FUNCPTR (gst_pad_proxy_setcaps));
160
 
  gst_pad_set_chain_function (taglib->sinkpad,
161
 
      GST_DEBUG_FUNCPTR (sj_tag_lib_mux_chain));
162
 
  gst_pad_set_event_function (taglib->sinkpad,
163
 
      GST_DEBUG_FUNCPTR (sj_tag_lib_mux_sink_event));
164
 
  gst_element_add_pad (GST_ELEMENT (taglib), taglib->sinkpad);
165
 
 
166
 
  /* pad through which data goes out of the element */
167
 
  taglib->srcpad =
168
 
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
169
 
          "src"), "src");
170
 
  gst_element_add_pad (GST_ELEMENT (taglib), taglib->srcpad);
171
 
 
172
 
  taglib->render_tag = TRUE;
173
 
}
174
 
 
175
 
static void
176
 
add_one_txxx_musicbrainz_tag (ID3v2::Tag * id3v2tag, const gchar * spec_id,
177
 
    const gchar * realworld_id, const gchar * id_str)
178
 
{
179
 
  ID3v2::UserTextIdentificationFrame * frame;
180
 
 
181
 
  if (id_str == NULL)
182
 
    return;
183
 
 
184
 
  GST_DEBUG ("Setting %s to %s", GST_STR_NULL (spec_id), id_str);
185
 
 
186
 
  if (spec_id) {
187
 
    frame = new ID3v2::UserTextIdentificationFrame (String::Latin1);
188
 
    id3v2tag->addFrame (frame);
189
 
    frame->setDescription (spec_id);
190
 
    frame->setText (id_str);
191
 
  }
192
 
 
193
 
  if (realworld_id) {
194
 
    frame = new ID3v2::UserTextIdentificationFrame (String::Latin1);
195
 
    id3v2tag->addFrame (frame);
196
 
    frame->setDescription (realworld_id);
197
 
    frame->setText (id_str);
198
 
  }
199
 
}
200
 
 
201
 
static void
202
 
add_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data)
203
 
{
204
 
  ID3v2::Tag * id3v2tag = (ID3v2::Tag *) user_data;
205
 
  gboolean result;
206
 
 
207
 
  /* FIXME: if there are several values set for the same tag, this won't
208
 
   * work, only the first value will be taken into account
209
 
   */
210
 
  if (strcmp (tag, GST_TAG_TITLE) == 0) {
211
 
    char *title;
212
 
 
213
 
    result = gst_tag_list_get_string_index (list, tag, 0, &title);
214
 
    if (result != FALSE) {
215
 
      GST_DEBUG ("Setting title to %s", title);
216
 
      id3v2tag->setTitle (String::String (title, String::UTF8));
217
 
    }
218
 
    g_free (title);
219
 
  } else if (strcmp (tag, GST_TAG_ALBUM) == 0) {
220
 
    char *album;
221
 
 
222
 
    result = gst_tag_list_get_string_index (list, tag, 0, &album);
223
 
    if (result != FALSE) {
224
 
      GST_DEBUG ("Setting album to %s", album);
225
 
      id3v2tag->setAlbum (String::String (album, String::UTF8));
226
 
    }
227
 
    g_free (album);
228
 
  } else if (strcmp (tag, GST_TAG_ARTIST) == 0) {
229
 
    char *artist;
230
 
 
231
 
    result = gst_tag_list_get_string_index (list, tag, 0, &artist);
232
 
    if (result != FALSE) {
233
 
      GST_DEBUG ("Setting artist to %s", artist);
234
 
      id3v2tag->setArtist (String::String (artist, String::UTF8));
235
 
    }
236
 
    g_free (artist);
237
 
  } else if (strcmp (tag, GST_TAG_GENRE) == 0) {
238
 
    char *genre;
239
 
 
240
 
    result = gst_tag_list_get_string_index (list, tag, 0, &genre);
241
 
    if (result != FALSE) {
242
 
      GST_DEBUG ("Setting genre to %s", genre);
243
 
      id3v2tag->setGenre (String::String (genre, String::UTF8));
244
 
    }
245
 
    g_free (genre);
246
 
  } else if (strcmp (tag, GST_TAG_COMMENT) == 0) {
247
 
    char *comment;
248
 
 
249
 
    result = gst_tag_list_get_string_index (list, tag, 0, &comment);
250
 
    if (result != FALSE) {
251
 
      GST_DEBUG ("Setting comment to %s", comment);
252
 
      id3v2tag->setComment (String::String (comment, String::UTF8));
253
 
    }
254
 
    g_free (comment);
255
 
  } else if (strcmp (tag, GST_TAG_DATE) == 0) {
256
 
    GDate *date;
257
 
 
258
 
    result = gst_tag_list_get_date_index (list, tag, 0, &date);
259
 
    if (result != FALSE) {
260
 
      GDateYear year;
261
 
 
262
 
      year = g_date_get_year (date);
263
 
      GST_DEBUG ("Setting track year to %d", year);
264
 
      id3v2tag->setYear (year);
265
 
      g_date_free (date);
266
 
    }
267
 
  } else if (strcmp (tag, GST_TAG_TRACK_NUMBER) == 0) {
268
 
    guint track_number;
269
 
 
270
 
    result = gst_tag_list_get_uint_index (list, tag, 0, &track_number);
271
 
    if (result != FALSE) {
272
 
      guint total_tracks;
273
 
 
274
 
      result = gst_tag_list_get_uint_index (list, GST_TAG_TRACK_COUNT,
275
 
          0, &total_tracks);
276
 
      if (result) {
277
 
        gchar *tag_str;
278
 
 
279
 
        ID3v2::TextIdentificationFrame * frame;
280
 
 
281
 
        frame = new ID3v2::TextIdentificationFrame ("TRCK", String::UTF8);
282
 
        tag_str = g_strdup_printf ("%d/%d", track_number, total_tracks);
283
 
        GST_DEBUG ("Setting track number to %s", tag_str);
284
 
        id3v2tag->addFrame (frame);
285
 
        frame->setText (tag_str);
286
 
        g_free (tag_str);
287
 
      } else {
288
 
        GST_DEBUG ("Setting track number to %d", track_number);
289
 
        id3v2tag->setTrack (track_number);
290
 
      }
291
 
    }
292
 
  } else if (strcmp (tag, GST_TAG_ALBUM_VOLUME_NUMBER) == 0) {
293
 
    guint volume_number;
294
 
 
295
 
    result = gst_tag_list_get_uint_index (list, tag, 0, &volume_number);
296
 
 
297
 
    if (result != FALSE) {
298
 
      guint volume_count;
299
 
      gchar *tag_str;
300
 
 
301
 
      ID3v2::TextIdentificationFrame * frame;
302
 
 
303
 
      frame = new ID3v2::TextIdentificationFrame ("TPOS", String::UTF8);
304
 
      result = gst_tag_list_get_uint_index (list, GST_TAG_ALBUM_VOLUME_COUNT,
305
 
          0, &volume_count);
306
 
      if (result) {
307
 
        tag_str = g_strdup_printf ("%d/%d", volume_number, volume_count);
308
 
      } else {
309
 
        tag_str = g_strdup_printf ("%d", volume_number);
310
 
      }
311
 
 
312
 
      id3v2tag->addFrame (frame);
313
 
      frame->setText (tag_str);
314
 
      g_free (tag_str);
315
 
      GST_DEBUG ("Setting album number to %s", tag_str);
316
 
    }
317
 
  } else if (strcmp (tag, GST_TAG_COPYRIGHT) == 0) {
318
 
    gchar *copyright;
319
 
 
320
 
    result = gst_tag_list_get_string_index (list, tag, 0, &copyright);
321
 
 
322
 
    if (result != FALSE) {
323
 
      ID3v2::TextIdentificationFrame * frame;
324
 
 
325
 
      frame = new ID3v2::TextIdentificationFrame ("TCOP", String::UTF8);
326
 
 
327
 
      id3v2tag->addFrame (frame);
328
 
      frame->setText (copyright);
329
 
      g_free (copyright);
330
 
      GST_DEBUG ("Setting copyright to %s", copyright);
331
 
    }
332
 
  } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_ARTISTID) == 0) {
333
 
    gchar *id_str;
334
 
 
335
 
    if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) {
336
 
      add_one_txxx_musicbrainz_tag (id3v2tag, "MusicBrainz Artist Id",
337
 
          "musicbrainz_artistid", id_str);
338
 
      g_free (id_str);
339
 
    }
340
 
  } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_ALBUMID) == 0) {
341
 
    gchar *id_str;
342
 
 
343
 
    if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) {
344
 
      add_one_txxx_musicbrainz_tag (id3v2tag, "MusicBrainz Album Id",
345
 
          "musicbrainz_albumid", id_str);
346
 
      g_free (id_str);
347
 
    }
348
 
  } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_ALBUMARTISTID) == 0) {
349
 
    gchar *id_str;
350
 
 
351
 
    if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) {
352
 
      add_one_txxx_musicbrainz_tag (id3v2tag, "MusicBrainz Album Artist Id",
353
 
          "musicbrainz_albumartistid", id_str);
354
 
      g_free (id_str);
355
 
    }
356
 
  } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_TRMID) == 0) {
357
 
    gchar *id_str;
358
 
 
359
 
    if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) {
360
 
      add_one_txxx_musicbrainz_tag (id3v2tag, "MusicBrainz TRM Id",
361
 
          "musicbrainz_trmid", id_str);
362
 
      g_free (id_str);
363
 
    }
364
 
  } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_TRACKID) == 0) {
365
 
    gchar *id_str;
366
 
 
367
 
    if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) {
368
 
      ID3v2::UniqueFileIdentifierFrame * frame;
369
 
 
370
 
      GST_DEBUG ("Setting Musicbrainz Track Id to %s", id_str);
371
 
 
372
 
      frame = new ID3v2::UniqueFileIdentifierFrame ("http://musicbrainz.org",
373
 
          id_str);
374
 
      id3v2tag->addFrame (frame);
375
 
      g_free (id_str);
376
 
    }
377
 
  } else {
378
 
    GST_WARNING ("Unsupported tag: %s", tag);
379
 
  }
380
 
}
381
 
 
382
 
 
383
 
static GstBuffer *
384
 
sj_tag_lib_mux_render_tag (SjTagLibMux * taglib)
385
 
{
386
 
  ID3v2::Tag id3v2tag;
387
 
  ByteVector rendered_tag;
388
 
  GstBuffer *buffer;
389
 
  GstTagSetter *tagsetter = GST_TAG_SETTER (taglib);
390
 
  GstTagList *taglist;
391
 
  GstEvent *event;
392
 
 
393
 
  if (taglib->tags != NULL) {
394
 
    taglist = gst_tag_list_copy (taglib->tags);
395
 
  } else {
396
 
    taglist = gst_tag_list_new ();
397
 
  }
398
 
 
399
 
  if (gst_tag_setter_get_tag_list (tagsetter)) {
400
 
    gst_tag_list_insert (taglist,
401
 
        gst_tag_setter_get_tag_list (tagsetter),
402
 
        gst_tag_setter_get_tag_merge_mode (tagsetter));
403
 
  }
404
 
 
405
 
 
406
 
  /* Render the tag */
407
 
  gst_tag_list_foreach (taglist, add_one_tag, &id3v2tag);
408
 
  rendered_tag = id3v2tag.render ();
409
 
  taglib->tag_size = rendered_tag.size ();
410
 
  buffer = gst_buffer_new_and_alloc (rendered_tag.size ());
411
 
  memcpy (GST_BUFFER_DATA (buffer), rendered_tag.data (), rendered_tag.size ());
412
 
  gst_buffer_set_caps (buffer, GST_PAD_CAPS (taglib->srcpad));
413
 
  /*  gst_util_dump_mem (GST_BUFFER_DATA (buffer), rendered_tag.size()); */
414
 
 
415
 
  /* Send an event about the new tags to downstream elements */
416
 
  /* gst_event_new_tag takes ownership of the list, so no need to unref it */
417
 
  event = gst_event_new_tag (taglist);
418
 
  gst_pad_push_event (taglib->srcpad, event);
419
 
 
420
 
  return buffer;
421
 
}
422
 
 
423
 
 
424
 
static GstFlowReturn
425
 
sj_tag_lib_mux_chain (GstPad * pad, GstBuffer * buffer)
426
 
{
427
 
  SjTagLibMux *taglib = SJ_TAGLIB_MUX (GST_OBJECT_PARENT (pad));
428
 
 
429
 
  if (taglib->render_tag) {
430
 
    GstFlowReturn ret;
431
 
 
432
 
    GST_INFO ("Adding tags to stream");
433
 
    ret = gst_pad_push (taglib->srcpad, sj_tag_lib_mux_render_tag (taglib));
434
 
    if (ret != GST_FLOW_OK) {
435
 
      gst_buffer_unref (buffer);
436
 
      return ret;
437
 
    }
438
 
    taglib->render_tag = FALSE;
439
 
  }
440
 
 
441
 
  gst_buffer_set_caps (buffer, GST_PAD_CAPS (taglib->srcpad));
442
 
  return gst_pad_push (taglib->srcpad, buffer);
443
 
}
444
 
 
445
 
static gboolean
446
 
sj_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event)
447
 
{
448
 
  SjTagLibMux *taglib;
449
 
  gboolean result;
450
 
 
451
 
  taglib = SJ_TAGLIB_MUX (gst_pad_get_parent (pad));
452
 
  result = FALSE;
453
 
 
454
 
  switch (GST_EVENT_TYPE (event)) {
455
 
    case GST_EVENT_TAG:
456
 
    {
457
 
      GstTagList *tags;
458
 
 
459
 
      GST_INFO ("Got tag event");
460
 
 
461
 
      gst_event_parse_tag (event, &tags);
462
 
      if (taglib->tags != NULL) {
463
 
        /* FIXME: which policy is the best here? PREPEND or something else? */
464
 
        gst_tag_list_insert (taglib->tags, tags, GST_TAG_MERGE_PREPEND);
465
 
      } else {
466
 
        taglib->tags = gst_tag_list_copy (tags);
467
 
      }
468
 
      /* We'll push a new tag event in render_tag */
469
 
      gst_event_unref (event);
470
 
      result = TRUE;
471
 
      break;
472
 
    }
473
 
    case GST_EVENT_NEWSEGMENT:
474
 
      if (taglib->tag_size == 0) {
475
 
        result = gst_pad_push_event (taglib->srcpad, event);
476
 
      } else {
477
 
        gboolean update;
478
 
        gdouble rate;
479
 
        GstFormat format;
480
 
        gint64 value, end_value, base;
481
 
 
482
 
        gst_event_parse_new_segment (event, &update, &rate, &format,
483
 
            &value, &end_value, &base);
484
 
        gst_event_unref (event);
485
 
        if (format == GST_FORMAT_BYTES && gst_pad_is_linked (taglib->srcpad)) {
486
 
          GstEvent *new_event;
487
 
 
488
 
          GST_INFO ("Adjusting NEW_SEGMENT event by %d", taglib->tag_size);
489
 
          value += taglib->tag_size;
490
 
          if (end_value != -1) {
491
 
            end_value += taglib->tag_size;
492
 
          }
493
 
 
494
 
          new_event = gst_event_new_new_segment (update, rate, format,
495
 
              value, end_value, base);
496
 
          result = gst_pad_push_event (taglib->srcpad, new_event);
497
 
        } else {
498
 
          result = FALSE;
499
 
        }
500
 
      }
501
 
      break;
502
 
 
503
 
    default:
504
 
      result = gst_pad_event_default (pad, event);
505
 
      break;
506
 
  }
507
 
  gst_object_unref (GST_OBJECT (taglib));
508
 
 
509
 
  return result;
510
 
}
511
 
 
512
 
 
513
 
static GstStateChangeReturn
514
 
sj_tag_lib_mux_change_state (GstElement * element, GstStateChange transition)
515
 
{
516
 
  SjTagLibMux *taglib;
517
 
  GstStateChangeReturn result;
518
 
 
519
 
  taglib = SJ_TAGLIB_MUX (element);
520
 
 
521
 
  result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
522
 
  if (result != GST_STATE_CHANGE_SUCCESS) {
523
 
    return result;
524
 
  }
525
 
 
526
 
  switch (transition) {
527
 
    case GST_STATE_CHANGE_PAUSED_TO_READY:
528
 
      if (taglib->tags) {
529
 
        gst_tag_list_free (taglib->tags);
530
 
        taglib->tags = NULL;
531
 
      }
532
 
      taglib->tag_size = 0;
533
 
      taglib->render_tag = TRUE;
534
 
      break;
535
 
    default:
536
 
      break;
537
 
  }
538
 
 
539
 
  return result;
540
 
}
541
 
 
542
 
 
543
 
static gboolean
544
 
plugin_init (GstPlugin * plugin)
545
 
{
546
 
  if (!gst_element_register (plugin, "id3mux", GST_RANK_NONE,
547
 
          SJ_TYPE_TAGLIB_MUX))
548
 
    return FALSE;
549
 
 
550
 
  GST_DEBUG_CATEGORY_INIT (sj_tag_lib_mux_debug, "taglibmux", 0,
551
 
      "ID3 Tag Muxer");
552
 
 
553
 
  gst_tag_register_musicbrainz_tags ();
554
 
 
555
 
  return TRUE;
556
 
}
557
 
 
558
 
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
559
 
    GST_VERSION_MINOR,
560
 
    "taglib",
561
 
    "Tag-writing plug-in based on taglib",
562
 
    plugin_init, VERSION, "LGPL", PACKAGE_NAME, PACKAGE);
563
 
 
564
 
void
565
 
id3mux_register(void)
566
 
{
567
 
  _gst_plugin_register_static (&gst_plugin_desc);
568
 
}