@@ -15,7 +15,12 @@ from av.container.output cimport OutputContainer
15
15
from av.container.pyio cimport pyio_close_custom_gil, pyio_close_gil
16
16
from av.error cimport err_check, stash_exception
17
17
from av.format cimport build_container_format
18
- from av.utils cimport avdict_to_dict, avrational_to_fraction
18
+ from av.utils cimport (
19
+ avdict_to_dict,
20
+ avrational_to_fraction,
21
+ dict_to_avdict,
22
+ to_avrational,
23
+ )
19
24
20
25
from av.dictionary import Dictionary
21
26
from av.logging import Capture as LogCapture
@@ -123,6 +128,17 @@ cdef int pyav_io_close_gil(lib.AVFormatContext *s, lib.AVIOContext *pb) noexcept
123
128
124
129
return result
125
130
131
+ cdef void _free_chapters(lib.AVFormatContext * ctx) noexcept nogil:
132
+ cdef int i
133
+ if ctx.chapters != NULL :
134
+ for i in range (ctx.nb_chapters):
135
+ if ctx.chapters[i] != NULL :
136
+ if ctx.chapters[i].metadata != NULL :
137
+ lib.av_dict_free(& ctx.chapters[i].metadata)
138
+ lib.av_freep(< void ** > & ctx.chapters[i])
139
+ lib.av_freep(< void ** > & ctx.chapters)
140
+ ctx.nb_chapters = 0
141
+
126
142
127
143
class Flags (Flag ):
128
144
gen_pts: " Generate missing pts even if it requires parsing future frames." = lib.AVFMT_FLAG_GENPTS
@@ -346,6 +362,39 @@ cdef class Container:
346
362
})
347
363
return result
348
364
365
+ def set_chapters (self , chapters ):
366
+ self ._assert_open()
367
+
368
+ cdef int count = len (chapters)
369
+ cdef int i
370
+ cdef lib.AVChapter ** ch_array
371
+ cdef lib.AVChapter * ch
372
+ cdef dict entry
373
+
374
+ with nogil:
375
+ _free_chapters(self .ptr)
376
+
377
+ ch_array = < lib.AVChapter ** > lib.av_malloc(count * sizeof(lib.AVChapter * ))
378
+ if ch_array == NULL :
379
+ raise MemoryError (" av_malloc failed for chapters" )
380
+
381
+ for i in range (count):
382
+ entry = chapters[i]
383
+ ch = < lib.AVChapter * > lib.av_malloc(sizeof(lib.AVChapter))
384
+ if ch == NULL :
385
+ raise MemoryError (" av_malloc failed for chapter" )
386
+ ch.id = entry[" id" ]
387
+ ch.start = < int64_t> entry[" start" ]
388
+ ch.end = < int64_t> entry[" end" ]
389
+ to_avrational(entry[" time_base" ], & ch.time_base)
390
+ ch.metadata = NULL
391
+ if " metadata" in entry:
392
+ dict_to_avdict(& ch.metadata, entry[" metadata" ], self .metadata_encoding, self .metadata_errors)
393
+ ch_array[i] = ch
394
+
395
+ self .ptr.nb_chapters = count
396
+ self .ptr.chapters = ch_array
397
+
349
398
def open (
350
399
file ,
351
400
mode = None ,
0 commit comments