Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Deniz Ugur, Romain Bouqueau, Sohaib Larbi
5 : * Copyright (c) Motion Spell
6 : * All rights reserved
7 : *
8 : * This file is part of the GPAC/GStreamer wrapper
9 : *
10 : * This GPAC/GStreamer wrapper is free software; you can redistribute it
11 : * and/or modify it under the terms of the GNU Affero General Public License
12 : * as published by the Free Software Foundation; either version 3, or (at
13 : * your option) any later version.
14 : *
15 : * This GPAC/GStreamer wrapper is distributed in the hope that it will be
16 : * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Affero General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Affero General Public
21 : * License along with this library; see the file LICENSE. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include "lib/packet.h"
27 :
28 : #include <gpac/id3.h>
29 : #include <gst/gst.h>
30 :
31 : gboolean
32 6524 : id3_handler(GPAC_PCK_PROP_IMPL_ARGS)
33 : {
34 6524 : const GstMetaInfo* info = gst_meta_get_info("Id3Meta");
35 6524 : if (!info)
36 6524 : return FALSE;
37 :
38 0 : GstMeta* meta = gst_buffer_get_meta(buffer, info->api);
39 0 : if (!meta)
40 0 : return FALSE;
41 :
42 0 : GstStructure* s = ((GstCustomMeta*)meta)->structure;
43 0 : const GValue* tags_val = gst_structure_get_value(s, "tags");
44 :
45 0 : if (!tags_val || !GST_VALUE_HOLDS_LIST(tags_val))
46 0 : return FALSE;
47 :
48 0 : guint n = gst_value_list_get_size(tags_val);
49 0 : if (n == 0)
50 0 : return FALSE;
51 :
52 : // Create new list to store the tags
53 0 : GF_List* tag_list = gf_list_new();
54 0 : guint64 pts = gf_filter_pck_get_cts(pck);
55 0 : guint32 timescale = gf_filter_pid_get_timescale(pid);
56 :
57 0 : for (guint i = 0; i < n; ++i) {
58 0 : const GValue* tag_val = gst_value_list_get_value(tags_val, i);
59 0 : const GstStructure* tag_struct = g_value_get_boxed(tag_val);
60 :
61 0 : const GValue* data_val = gst_structure_get_value(tag_struct, "data");
62 0 : if (data_val && G_VALUE_HOLDS(data_val, GST_TYPE_BUFFER)) {
63 0 : GstBuffer* tag_buf = g_value_get_boxed(data_val);
64 0 : g_auto(GstBufferMapInfo) map = GST_MAP_INFO_INIT;
65 0 : if (gst_buffer_map(tag_buf, &map, GST_MAP_READ)) {
66 : // Create a new ID3 tag
67 : GF_ID3_TAG* tag;
68 0 : GF_SAFEALLOC(tag, GF_ID3_TAG);
69 0 : gf_id3_tag_new(tag, timescale, pts, map.data, map.size);
70 :
71 : // Add the tag to the list
72 0 : gf_list_add(tag_list, tag);
73 : }
74 : }
75 : }
76 :
77 : // Write the tags to a bitstream
78 0 : GF_BitStream* bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
79 0 : gf_id3_list_to_bitstream(tag_list, bs);
80 :
81 : // Free the tag list
82 : GF_ID3_TAG* tag;
83 0 : while ((tag = (GF_ID3_TAG*)gf_list_pop_back(tag_list)))
84 0 : gf_id3_tag_free(tag);
85 0 : gf_list_del(tag_list);
86 :
87 : // Export the bitrstream
88 : u8* data;
89 : u32 size;
90 0 : gf_bs_get_content(bs, &data, &size);
91 :
92 : // Set the ID3 tags as a property on the packet
93 0 : gf_filter_pck_set_property_str(pck, "id3", &PROP_DATA(data, size));
94 :
95 : // Free the data
96 0 : gf_free(data);
97 0 : gf_bs_del(bs);
98 :
99 0 : return TRUE;
100 : }
|