Skip to content

Commit 2969863

Browse files
committed
chapter support in filters - cf gpac#2209
1 parent d485955 commit 2969863

File tree

17 files changed

+322
-65
lines changed

17 files changed

+322
-65
lines changed

include/gpac/filters.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,8 +793,10 @@ typedef enum
793793
/*! 4CC on unsigned 32 bit integer*/
794794
GF_PROP_4CC = 25,
795795
/*! 4CC list on unsigned 32 bit integer, memory is ALWAYS duplicated when setting the property*/
796-
GF_PROP_4CC_LIST = 26,
797-
796+
GF_PROP_4CC_LIST = 26,
797+
/*! string list, memory is duplicated when setting the property - to use only with property assignment functions*/
798+
GF_PROP_STRING_LIST_COPY = 27,
799+
798800
/*! last non-enum property*/
799801
GF_PROP_LAST_NON_ENUM,
800802

@@ -1216,6 +1218,9 @@ enum
12161218
GF_PROP_PID_ORIG_CRYPT_SCHEME = GF_4CC('P','O','C','S'),
12171219
GF_PROP_PID_TIMESHIFT_SEGS = GF_4CC('P','T','S','N'),
12181220

1221+
GF_PROP_PID_CHAP_TIMES = GF_4CC('C','H','P','T'),
1222+
GF_PROP_PID_CHAP_NAMES = GF_4CC('C','H','P','N'),
1223+
12191224
//internal for HLS playlist reference, gives a unique ID identifying media mux, and indicated in packets carrying child playlists
12201225
GF_PROP_PCK_HLS_REF = GF_4CC('H','P','L','R'),
12211226
//internal for HLS low latency

include/gpac/isomedia.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2239,7 +2239,7 @@ GF_Err gf_isom_add_chapter(GF_ISOFile *isom_file, u32 trackNumber, u64 timestamp
22392239
/*! deletes copyright
22402240
\param isom_file the target ISO file
22412241
\param trackNumber the target track
2242-
\param index the 1-based index of the copyright notice to remove, or 0 to remove all copyrights
2242+
\param index the 1-based index of the copyright notice to remove, or 0 to remove all chapters
22432243
\return error if any
22442244
*/
22452245
GF_Err gf_isom_remove_chapter(GF_ISOFile *isom_file, u32 trackNumber, u32 index);

share/doc/man/gpac-filters.1

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,7 +2161,7 @@ store (enum, default: inter): file storage mode
21612161
.br
21622162
* fstart: write samples as they arrive and moov before mdat
21632163
.br
2164-
* tight: uses per-sample interleaving of all tracks (requires temporary storage of all media)
2164+
* tight: uses per-sample interleaving of all tracks (requires temporary storage of all media)
21652165
.br
21662166
* frag: fragments the file using cdur duration
21672167
.br
@@ -4142,6 +4142,8 @@ Note: When sources are ISOBMFF files or segments on local storage or GF_FileIO o
41424142
.br
41434143
* sprops=STR: assigns properties described in STR to all PIDs of the main content during a splice (cf below). STR is formatted according to gpac -h doc using the default parameter set.
41444144
.br
4145+
* chap=NAME: assigns chapter name at the start of next URL (filter always removes source chapter names).
4146+
.br
41454147

41464148
.br
41474149
The following global options (applying to the filter, not the sources) may also be set in the playlist:
@@ -5145,7 +5147,7 @@ Output multiplexers allowing segmented output must obey the following:
51455147
.br
51465148
* subs_sidx=0: indicates an SIDX shall be generated - only added if not already specified by user
51475149
.br
5148-
* xps_inband=all|no: indicates AVC/HEVC/... parameter sets shall be sent inband or out of band
5150+
* xps_inband=all|no|both: indicates AVC/HEVC/... parameter sets shall be sent inband, out of band, or both
51495151
.br
51505152
* nofragdef: indicates fragment defaults should be set in each segment rather than in init segment
51515153
.br
@@ -5212,6 +5214,8 @@ bs_switch (enum, default: def): bitstream switching mode (single init segment)
52125214
.br
52135215
* inband: moves decoder config inband if possible
52145216
.br
5217+
* both: inband and outband parameter sets
5218+
.br
52155219
* pps: moves PPS and APS inband, keep VPS,SPS and DCI out of band (used for VVC RPR)
52165220
.br
52175221
* force: enables it even if only one representation
@@ -10580,7 +10584,7 @@ Authors: GPAC developers, see git repo history (-log)
1058010584
.br
1058110585
For bug reports, feature requests, more information and source code, visit https://github.com/gpac/gpac
1058210586
.br
10583-
build: 2.1-DEV-rev221-ge0cac167f-master
10587+
build: 2.1-DEV-rev252-gd48595585-master
1058410588
.br
1058510589
Copyright: (c) 2000-2022 Telecom Paris distributed under LGPL v2.1+ - http://gpac.io
1058610590
.br

share/doc/man/gpac.1

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,11 @@ hack for PIFF PSEC files generated by 0.9.0 and 1.0 MP4Box with wrong subsample_
10971097
.br
10981098
hack for old vvdec+libavcodec supporting only annexB format
10991099
.br
1100+
.TP
1101+
.B \-heif-hevc-urn
1102+
.br
1103+
use HEVC URN for alpha and depth in HEIF instead of MPEG-B URN (HEIF first edition)
1104+
.br
11001105
.SH libgpac logs options:
11011106
.LP
11021107
.br
@@ -3592,6 +3597,16 @@ PID is a HAS manifest
35923597
PID has potentially empty times between packets
35933598
.br
35943599
.TP
3600+
.B ChapTimes (CHPT,uintl,D )
3601+
.br
3602+
Chapter start times
3603+
.br
3604+
.TP
3605+
.B ChapNames (CHPN,strl,D )
3606+
.br
3607+
Chapter names
3608+
.br
3609+
.TP
35953610
.B SkipBegin (PCKS,uint, P)
35963611
.br
35973612
Amount of media to skip from beginning of packet in PID timescale
@@ -4711,7 +4726,7 @@ Authors: GPAC developers, see git repo history (-log)
47114726
.br
47124727
For bug reports, feature requests, more information and source code, visit https://github.com/gpac/gpac
47134728
.br
4714-
build: 2.1-DEV-rev221-ge0cac167f-master
4729+
build: 2.1-DEV-rev252-gd48595585-master
47154730
.br
47164731
Copyright: (c) 2000-2022 Telecom Paris distributed under LGPL v2.1+ - http://gpac.io
47174732
.br

share/doc/man/mp4box.1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2855,7 +2855,7 @@ Authors: GPAC developers, see git repo history (-log)
28552855
.br
28562856
For bug reports, feature requests, more information and source code, visit https://github.com/gpac/gpac
28572857
.br
2858-
build: 2.1-DEV-rev221-ge0cac167f-master
2858+
build: 2.1-DEV-rev252-gd48595585-master
28592859
.br
28602860
Copyright: (c) 2000-2022 Telecom Paris distributed under LGPL v2.1+ - http://gpac.io
28612861
.br

share/gui/extensions/player/player.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,10 @@ extension = {
665665
}
666666
}
667667

668+
wnd.chapters = gw_new_icon(wnd.infobar, 'chapters');
669+
wnd.chapters.extension = this;
670+
wnd.chapters.hide();
671+
668672
wnd.loop = gw_new_icon(wnd.infobar, 'play_once');
669673
wnd.loop.extension = this;
670674
wnd.loop.add_icon(gwskin.images.play_loop);
@@ -897,6 +901,11 @@ extension = {
897901
if (this.extension.root_odm && !this.extension.dynamic_scene && !this.extension.root_odm.is_over)
898902
is_over = false;
899903

904+
905+
if (this.chapters.visible) {
906+
full_w += control_icon_size;
907+
}
908+
900909
} else {
901910
this.stats.hide();
902911
this.stop.hide();
@@ -1679,6 +1688,8 @@ extension = {
16791688
this.services = [];
16801689

16811690
var root_odm = this.root_odm;
1691+
let chaps = null;
1692+
this.controler.chapters.hide();
16821693
if (root_odm) {
16831694
for (var res_i = 0; res_i < root_odm.nb_resources; res_i++) {
16841695
var m = root_odm.get_resource(res_i);
@@ -1694,8 +1705,39 @@ extension = {
16941705
this.services.push(m);
16951706
}
16961707
}
1708+
chaps = root_odm.get_chapters();
16971709
}
16981710

1711+
if (chaps) {
1712+
if (!this.controler.chapters.visible) {
1713+
this.controler.chapters.show();
1714+
this.controler.layout();
1715+
}
1716+
1717+
this.controler.chapters.on_click = function () {
1718+
1719+
if (this.extension.channels_wnd) {
1720+
this.extension.channels_wnd.close();
1721+
return;
1722+
}
1723+
var wnd = gw_new_popup(this.extension.controler.channels, 'up');
1724+
this.extension.channels_wnd = wnd;
1725+
wnd.extension = this.extension;
1726+
1727+
wnd.on_close = function () {
1728+
this.extension.channels_wnd = null;
1729+
}
1730+
1731+
chaps.forEach(chap => {
1732+
wnd.add_menu_item(chap.name, function () {
1733+
this.extension.movie_control.mediaStartTime = chap.start/1000.0;
1734+
});
1735+
});
1736+
wnd.on_display_size(gw_display_width, gw_display_height);
1737+
wnd.show();
1738+
}
1739+
}
1740+
16991741
if (this.services.length <= 1) {
17001742
this.controler.channels.hide();
17011743
this.controler.channels.on_click = function () { }

share/gui/gwlib.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,8 @@ gwskin.images.view360 = 'icons/image.svg';
845845
gwskin.labels.view360 = 'VR';
846846
gwskin.images.sensors = 'icons/compass.svg';
847847
gwskin.labels.sensors = 'Orientation';
848+
gwskin.images.chapters = 'icons/chapter.svg';
849+
gwskin.labels.chapters = 'Chapters';
848850

849851

850852
gwskin.mime_video_default_ext = " mp4 mp4s m4s 3gp 3gpp m2ts ts trp m3u8 mpd avi mov ";
@@ -3649,7 +3651,7 @@ function gw_new_popup(anchor, type)
36493651
var s = children[i].get_label().length;
36503652
if (s>max_s) max_s = s;
36513653
}
3652-
3654+
max_s *= 0.66;
36533655
for (var i=0; i<children.length; i++) {
36543656
children[i].set_size(max_s * gwskin.default_text_font_size, gwskin.default_icon_height);
36553657
}

share/gui/icons/chapter.svg

Lines changed: 7 additions & 0 deletions
Loading

src/filter_core/filter_props.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ GF_List *gf_props_get_list(GF_PropertyMap *map)
945945
}
946946
#endif
947947

948-
static void gf_props_assign_value(GF_PropertyEntry *prop, const GF_PropertyValue *value, Bool is_old_prop)
948+
static GF_Err gf_props_assign_value(GF_PropertyEntry *prop, const GF_PropertyValue *value, Bool is_old_prop)
949949
{
950950
char *src_ptr;
951951
//remember source pointer
@@ -960,6 +960,7 @@ static void gf_props_assign_value(GF_PropertyEntry *prop, const GF_PropertyValue
960960

961961
if (prop->prop.type == GF_PROP_STRING) {
962962
prop->prop.value.string = value->value.string ? gf_strdup(value->value.string) : NULL;
963+
if (value->value.string && !prop->prop.value.string) return GF_OUT_OF_MEM;
963964
} else if (prop->prop.type == GF_PROP_STRING_NO_COPY) {
964965
prop->prop.value.string = value->value.string;
965966
prop->prop.type = GF_PROP_STRING;
@@ -969,6 +970,10 @@ static void gf_props_assign_value(GF_PropertyEntry *prop, const GF_PropertyValue
969970
if (prop->alloc_size < value->value.data.size) {
970971
prop->alloc_size = value->value.data.size;
971972
prop->prop.value.data.ptr = gf_realloc(prop->prop.value.data.ptr, sizeof(char) * value->value.data.size);
973+
if (!prop->prop.value.data.ptr) {
974+
prop->alloc_size = 0;
975+
return GF_OUT_OF_MEM;
976+
}
972977
assert(prop->alloc_size);
973978
}
974979
memcpy(prop->prop.value.data.ptr, value->value.data.ptr, value->value.data.size);
@@ -985,15 +990,31 @@ static void gf_props_assign_value(GF_PropertyEntry *prop, const GF_PropertyValue
985990
else if (prop->prop.type == GF_PROP_SINT_LIST) it_size = sizeof(s32);
986991
else if (prop->prop.type == GF_PROP_VEC2I_LIST) it_size = sizeof(GF_PropVec2i);
987992
prop->prop.value.uint_list.vals = gf_malloc(it_size * value->value.uint_list.nb_items);
988-
if (value->value.uint_list.nb_items)
989-
memcpy(prop->prop.value.uint_list.vals, value->value.uint_list.vals, it_size * value->value.uint_list.nb_items);
993+
if (!value->value.uint_list.nb_items) return GF_OUT_OF_MEM;
994+
memcpy(prop->prop.value.uint_list.vals, value->value.uint_list.vals, it_size * value->value.uint_list.nb_items);
990995
prop->prop.value.uint_list.nb_items = value->value.uint_list.nb_items;
991996
}
997+
else if (prop->prop.type == GF_PROP_STRING_LIST_COPY) {
998+
u32 i;
999+
prop->prop.type = GF_PROP_STRING_LIST;
1000+
prop->prop.value.string_list.nb_items = value->value.string_list.nb_items;
1001+
prop->prop.value.string_list.vals = gf_malloc(sizeof(char*)*value->value.string_list.nb_items);
1002+
if (!prop->prop.value.string_list.vals) return GF_OUT_OF_MEM;
1003+
memset(prop->prop.value.string_list.vals, 0, sizeof(char*)*value->value.string_list.nb_items);
1004+
for (i=0; i<prop->prop.value.string_list.nb_items; i++) {
1005+
if (value->value.string_list.vals[i]) {
1006+
prop->prop.value.string_list.vals[i] = gf_strdup(value->value.string_list.vals[i]);
1007+
if (!prop->prop.value.string_list.vals[i]) return GF_OUT_OF_MEM;
1008+
}
1009+
}
1010+
}
1011+
return GF_OK;
9921012
}
9931013

9941014
GF_Err gf_props_insert_property(GF_PropertyMap *map, u32 hash, u32 p4cc, const char *name, char *dyn_name, const GF_PropertyValue *value)
9951015
{
9961016
GF_PropertyEntry *prop;
1017+
GF_Err e;
9971018
#if GF_PROPS_HASHTABLE_SIZE
9981019
u32 i, count;
9991020
#endif
@@ -1039,7 +1060,11 @@ GF_Err gf_props_insert_property(GF_PropertyMap *map, u32 hash, u32 p4cc, const c
10391060
prop->name_alloc=GF_TRUE;
10401061
}
10411062

1042-
gf_props_assign_value(prop, value, GF_FALSE);
1063+
e = gf_props_assign_value(prop, value, GF_FALSE);
1064+
if (e) {
1065+
gf_props_del_property(prop);
1066+
return e;
1067+
}
10431068

10441069
#if GF_PROPS_HASHTABLE_SIZE
10451070
return gf_list_add(map->hash_table[hash], prop);
@@ -1558,6 +1583,9 @@ GF_BuiltInProperty GF_BuiltInProps [] =
15581583
{ GF_PROP_PID_IS_MANIFEST, "IsManifest", "PID is a HAS manifest", GF_PROP_BOOL, GF_PROP_FLAG_GSF_REM},
15591584
{ GF_PROP_PID_SPARSE, "Sparse", "PID has potentially empty times between packets", GF_PROP_BOOL, GF_PROP_FLAG_GSF_REM},
15601585

1586+
{ GF_PROP_PID_CHAP_TIMES, "ChapTimes", "Chapter start times", GF_PROP_UINT_LIST, GF_PROP_FLAG_GSF_REM},
1587+
{ GF_PROP_PID_CHAP_NAMES, "ChapNames", "Chapter names", GF_PROP_STRING_LIST, GF_PROP_FLAG_GSF_REM},
1588+
15611589
{ GF_PROP_PCK_SKIP_BEGIN, "SkipBegin", "Amount of media to skip from beginning of packet in PID timescale", GF_PROP_UINT, GF_PROP_FLAG_PCK},
15621590
{ GF_PROP_PCK_SKIP_PRES, "SkipPres", "Packet and any following with CTS greater than this packet shall not be presented (used by reframer to create edit lists)", GF_PROP_BOOL, GF_PROP_FLAG_PCK},
15631591

0 commit comments

Comments
 (0)