From 90ef59f63ed4c8fbe27a14e3665e243c08224f57 Mon Sep 17 00:00:00 2001 From: Norbert Schlia Date: Sat, 13 Jan 2024 22:55:29 +0100 Subject: [PATCH] Deploy code docs to GitHub Pages --- html/aiff_8h.html | 227 +- html/aiff_8h_source.html | 191 +- html/annotated.html | 27 +- html/blurayio_8cc.html | 33 +- html/blurayio_8cc_source.html | 649 +- html/blurayio_8h.html | 65 +- html/blurayio_8h_source.html | 173 +- html/blurayparser_8cc.html | 53 +- html/blurayparser_8cc_source.html | 1209 +- html/blurayparser_8h.html | 41 +- html/blurayparser_8h_source.html | 95 +- html/buffer_8cc.html | 33 +- html/buffer_8cc__incl.png | Bin 63391 -> 63391 bytes html/buffer_8cc_source.html | 2352 ++- html/buffer_8h.html | 192 +- html/buffer_8h__dep__incl.png | Bin 32956 -> 32961 bytes html/buffer_8h__incl.png | Bin 19519 -> 19523 bytes html/buffer_8h_source.html | 371 +- html/bug.html | 29 +- html/cache_8cc.html | 132 +- html/cache_8cc__incl.png | Bin 92191 -> 92185 bytes html/cache_8cc_source.html | 2902 +-- html/cache_8h.html | 293 +- html/cache_8h__dep__incl.png | Bin 17304 -> 17304 bytes html/cache_8h_source.html | 383 +- html/cache__entry_8cc.html | 33 +- html/cache__entry_8cc__incl.png | Bin 84596 -> 84596 bytes html/cache__entry_8cc_source.html | 993 +- html/cache__entry_8h.html | 35 +- html/cache__entry_8h__incl.png | Bin 29812 -> 29811 bytes html/cache__entry_8h_source.html | 305 +- html/cache__maintenance_8cc.html | 364 +- html/cache__maintenance_8cc_source.html | 645 +- html/cache__maintenance_8h.html | 43 +- html/cache__maintenance_8h_source.html | 91 +- html/classBlurayIO-members.html | 63 +- html/classBlurayIO.html | 725 +- html/classBlurayIO__coll__graph.map | 12 +- html/classBlurayIO__coll__graph.md5 | 2 +- html/classBlurayIO__coll__graph.png | Bin 24423 -> 23888 bytes html/classBuffer-members.html | 93 +- html/classBuffer.html | 619 +- html/classBuffer__coll__graph.map | 14 +- html/classBuffer__coll__graph.md5 | 2 +- html/classBuffer__coll__graph.png | Bin 30150 -> 29059 bytes html/classCache-members.html | 75 +- html/classCache.html | 804 +- html/classCache__Entry-members.html | 77 +- html/classCache__Entry.html | 746 +- html/classCache__Entry__coll__graph.map | 26 +- html/classCache__Entry__coll__graph.md5 | 2 +- html/classCache__Entry__coll__graph.png | Bin 54361 -> 50492 bytes html/classDiskIO-members.html | 51 +- html/classDiskIO.html | 282 +- html/classDiskIO__coll__graph.map | 12 +- html/classDiskIO__coll__graph.md5 | 2 +- html/classDiskIO__coll__graph.png | Bin 24193 -> 21171 bytes html/classDvdIO-members.html | 85 +- html/classDvdIO.html | 1161 +- html/classDvdIO__coll__graph.map | 12 +- html/classDvdIO__coll__graph.md5 | 2 +- html/classDvdIO__coll__graph.png | Bin 24185 -> 21145 bytes html/classFFmpeg__Base-members.html | 53 +- html/classFFmpeg__Base.html | 240 +- html/classFFmpeg__Base__coll__graph.map | 10 +- html/classFFmpeg__Base__coll__graph.md5 | 2 +- html/classFFmpeg__Base__coll__graph.png | Bin 23431 -> 20506 bytes html/classFFmpeg__Frame-members.html | 43 +- html/classFFmpeg__Frame.html | 293 +- html/classFFmpeg__Profiles-members.html | 37 +- html/classFFmpeg__Profiles.html | 229 +- html/classFFmpeg__Subtitle-members.html | 37 +- html/classFFmpeg__Subtitle.html | 200 +- html/classFFmpeg__Transcoder-members.html | 259 +- html/classFFmpeg__Transcoder.html | 3089 ++- ...mpeg__Transcoder_1_1StreamRef-members.html | 35 +- .../classFFmpeg__Transcoder_1_1StreamRef.html | 217 +- html/classFFmpeg__Transcoder__coll__graph.map | 26 +- html/classFFmpeg__Transcoder__coll__graph.md5 | 2 +- html/classFFmpeg__Transcoder__coll__graph.png | Bin 78986 -> 78136 bytes html/classFFmpegfs__Format-members.html | 53 +- html/classFFmpegfs__Format.html | 362 +- html/classFileIO-members.html | 47 +- html/classFileIO.html | 263 +- html/classFileIO__coll__graph.map | 10 +- html/classFileIO__coll__graph.md5 | 2 +- html/classFileIO__coll__graph.png | Bin 22819 -> 19979 bytes html/classLogging-members.html | 51 +- html/classLogging.html | 353 +- html/classLogging_1_1Logger-members.html | 35 +- html/classLogging_1_1Logger.html | 213 +- html/classVcdChapter-members.html | 59 +- html/classVcdChapter.html | 384 +- html/classVcdEntries-members.html | 57 +- html/classVcdEntries.html | 408 +- html/classVcdIO-members.html | 55 +- html/classVcdIO.html | 426 +- html/classVcdIO__coll__graph.map | 12 +- html/classVcdIO__coll__graph.md5 | 2 +- html/classVcdIO__coll__graph.png | Bin 24215 -> 21206 bytes html/classVcdInfo-members.html | 47 +- html/classVcdInfo.html | 625 +- html/classes.html | 57 +- html/classthread__pool-members.html | 45 +- html/classthread__pool.html | 167 +- html/cuesheetparser_8cc.html | 63 +- html/cuesheetparser_8cc_source.html | 719 +- html/cuesheetparser_8h.html | 43 +- html/cuesheetparser_8h_source.html | 97 +- html/dir_000000_000001.html | 24 +- .../dir_68267d1309a1af8e8297ef4c3efbcdba.html | 135 +- ...r_68267d1309a1af8e8297ef4c3efbcdba_dep.md5 | 2 +- ...r_68267d1309a1af8e8297ef4c3efbcdba_dep.png | Bin 2157 -> 2221 bytes .../dir_742531be420f0d5d7b3740956037edbc.html | 45 +- ...r_742531be420f0d5d7b3740956037edbc_dep.md5 | 2 +- ...r_742531be420f0d5d7b3740956037edbc_dep.png | Bin 1564 -> 1634 bytes html/diskio_8cc.html | 33 +- html/diskio_8cc_source.html | 271 +- html/diskio_8h.html | 35 +- html/diskio_8h_source.html | 137 +- html/doxygen.css | 58 +- html/dvdio_8cc.html | 320 +- html/dvdio_8cc__incl.png | Bin 35767 -> 35767 bytes html/dvdio_8cc_source.html | 1749 +- html/dvdio_8h.html | 37 +- html/dvdio_8h_source.html | 223 +- html/dvdparser_8cc.html | 158 +- html/dvdparser_8cc__incl.png | Bin 76171 -> 76171 bytes html/dvdparser_8cc_source.html | 1081 +- html/dvdparser_8h.html | 41 +- html/dvdparser_8h_source.html | 95 +- html/dynsections.js | 2 +- html/ffmpeg__base_8cc.html | 33 +- html/ffmpeg__base_8cc_source.html | 927 +- html/ffmpeg__base_8h.html | 275 +- html/ffmpeg__base_8h__dep__incl.png | Bin 11892 -> 11889 bytes html/ffmpeg__base_8h_source.html | 207 +- html/ffmpeg__compat_8h.html | 127 +- html/ffmpeg__compat_8h__dep__incl.png | Bin 120767 -> 120773 bytes html/ffmpeg__compat_8h_source.html | 117 +- html/ffmpeg__frame_8cc.html | 33 +- html/ffmpeg__frame_8cc_source.html | 361 +- html/ffmpeg__frame_8h.html | 35 +- html/ffmpeg__frame_8h__dep__incl.png | Bin 11699 -> 11695 bytes html/ffmpeg__frame_8h_source.html | 137 +- html/ffmpeg__profiles_8cc.html | 87 +- html/ffmpeg__profiles_8cc_source.html | 543 +- html/ffmpeg__profiles_8h.html | 155 +- html/ffmpeg__profiles_8h__dep__incl.png | Bin 9740 -> 9736 bytes html/ffmpeg__profiles_8h_source.html | 161 +- html/ffmpeg__subtitle_8cc.html | 33 +- html/ffmpeg__subtitle_8cc_source.html | 191 +- html/ffmpeg__subtitle_8h.html | 35 +- html/ffmpeg__subtitle_8h__dep__incl.png | Bin 12317 -> 12315 bytes html/ffmpeg__subtitle_8h_source.html | 137 +- html/ffmpeg__transcoder_8cc.html | 63 +- html/ffmpeg__transcoder_8cc_source.html | 15643 ++++++++-------- html/ffmpeg__transcoder_8h.html | 176 +- html/ffmpeg__transcoder_8h__dep__incl.png | Bin 6616 -> 6614 bytes html/ffmpeg__transcoder_8h_source.html | 1055 +- html/ffmpeg__utils_8cc.html | 731 +- html/ffmpeg__utils_8cc_source.html | 5265 +++--- html/ffmpeg__utils_8h.html | 1045 +- html/ffmpeg__utils_8h__dep__incl.png | Bin 117362 -> 117368 bytes html/ffmpeg__utils_8h_source.html | 1243 +- html/ffmpegfs_8cc.html | 737 +- html/ffmpegfs_8cc__incl.png | Bin 84534 -> 84533 bytes html/ffmpegfs_8cc_source.html | 4661 +++-- html/ffmpegfs_8h.html | 384 +- html/ffmpegfs_8h__dep__incl.png | Bin 72092 -> 72094 bytes html/ffmpegfs_8h_source.html | 457 +- html/ffmpegfs_COPYING.html | 29 +- html/ffmpegfs_COPYING_8CC0.html | 29 +- html/ffmpegfs_COPYING_8DOC.html | 29 +- html/ffmpegfs_NEWS.html | 58 +- html/ffmpegfs_TODO.html | 29 +- html/fileio_8cc.html | 33 +- html/fileio_8cc__incl.png | Bin 53237 -> 53235 bytes html/fileio_8cc_source.html | 277 +- html/fileio_8h.html | 421 +- html/fileio_8h__dep__incl.png | Bin 155459 -> 155467 bytes html/fileio_8h_source.html | 501 +- html/files.html | 27 +- html/functions.html | 104 +- html/functions_b.html | 55 +- html/functions_c.html | 186 +- html/functions_d.html | 131 +- html/functions_e.html | 77 +- html/functions_enum.html | 40 +- html/functions_eval.html | 60 +- html/functions_f.html | 156 +- html/functions_func.html | 104 +- html/functions_func_b.html | 51 +- html/functions_func_c.html | 170 +- html/functions_func_d.html | 111 +- html/functions_func_e.html | 77 +- html/functions_func_f.html | 144 +- html/functions_func_g.html | 242 +- html/functions_func_h.html | 62 +- html/functions_func_i.html | 155 +- html/functions_func_l.html | 67 +- html/functions_func_m.html | 46 +- html/functions_func_n.html | 30 +- html/functions_func_o.html | 154 +- html/functions_func_p.html | 113 +- html/functions_func_r.html | 104 +- html/functions_func_s.html | 146 +- html/functions_func_t.html | 68 +- html/functions_func_u.html | 59 +- html/functions_func_v.html | 80 +- html/functions_func_w.html | 55 +- html/functions_func_~.html | 94 +- html/functions_g.html | 242 +- html/functions_h.html | 78 +- html/functions_i.html | 155 +- html/functions_l.html | 140 +- html/functions_m.html | 1464 +- html/functions_n.html | 35 +- html/functions_o.html | 158 +- html/functions_p.html | 145 +- html/functions_r.html | 108 +- html/functions_rela.html | 28 +- html/functions_s.html | 171 +- html/functions_t.html | 77 +- html/functions_type.html | 202 +- html/functions_u.html | 59 +- html/functions_v.html | 80 +- html/functions_vars.html | 30 +- html/functions_vars_l.html | 30 +- html/functions_vars_m.html | 1433 +- html/functions_vars_n.html | 31 +- html/functions_vars_p.html | 38 +- html/functions_vars_r.html | 30 +- html/functions_vars_s.html | 30 +- html/functions_vars_t.html | 30 +- html/functions_w.html | 55 +- html/functions_~.html | 94 +- html/fuseops_8cc.html | 526 +- html/fuseops_8cc__incl.png | Bin 168324 -> 168321 bytes html/fuseops_8cc_source.html | 4549 ++--- html/globals.html | 30 +- html/globals_a.html | 196 +- html/globals_b.html | 46 +- html/globals_c.html | 194 +- html/globals_d.html | 84 +- html/globals_defs.html | 538 +- html/globals_e.html | 64 +- html/globals_enum.html | 76 +- html/globals_eval.html | 300 +- html/globals_f.html | 260 +- html/globals_func.html | 60 +- html/globals_func_b.html | 34 +- html/globals_func_c.html | 86 +- html/globals_func_d.html | 39 +- html/globals_func_e.html | 36 +- html/globals_func_f.html | 183 +- html/globals_func_g.html | 194 +- html/globals_func_h.html | 31 +- html/globals_func_i.html | 95 +- html/globals_func_k.html | 30 +- html/globals_func_l.html | 52 +- html/globals_func_m.html | 71 +- html/globals_func_n.html | 41 +- html/globals_func_p.html | 79 +- html/globals_func_r.html | 81 +- html/globals_func_s.html | 112 +- html/globals_func_t.html | 137 +- html/globals_func_u.html | 35 +- html/globals_func_v.html | 34 +- html/globals_g.html | 198 +- html/globals_h.html | 79 +- html/globals_i.html | 116 +- html/globals_k.html | 30 +- html/globals_l.html | 189 +- html/globals_m.html | 87 +- html/globals_n.html | 41 +- html/globals_o.html | 50 +- html/globals_p.html | 233 +- html/globals_r.html | 129 +- html/globals_s.html | 217 +- html/globals_t.html | 166 +- html/globals_type.html | 337 +- html/globals_u.html | 35 +- html/globals_v.html | 183 +- html/globals_vars.html | 206 +- html/globals_w.html | 46 +- html/globals_x.html | 30 +- html/graph_legend.html | 35 +- html/hierarchy.html | 27 +- html/id3v1tag_8h.html | 95 +- html/id3v1tag_8h__dep__incl.png | Bin 22214 -> 22214 bytes html/id3v1tag_8h_source.html | 113 +- html/index.html | 35 +- html/inherit_graph_14.md5 | 2 +- html/inherit_graph_18.map | 3 +- html/inherit_graph_18.md5 | 2 +- html/inherit_graph_18.png | Bin 2768 -> 2684 bytes html/inherit_graph_19.map | 3 +- html/inherit_graph_19.md5 | 2 +- html/inherit_graph_19.png | Bin 2684 -> 3201 bytes html/inherit_graph_20.map | 3 +- html/inherit_graph_20.md5 | 2 +- html/inherit_graph_20.png | Bin 3183 -> 3047 bytes html/inherit_graph_21.map | 2 +- html/inherit_graph_21.md5 | 2 +- html/inherit_graph_21.png | Bin 3047 -> 4028 bytes html/inherit_graph_22.map | 2 +- html/inherit_graph_22.md5 | 2 +- html/inherit_graph_22.png | Bin 4028 -> 2476 bytes html/inherit_graph_23.map | 2 +- html/inherit_graph_23.md5 | 2 +- html/inherit_graph_23.png | Bin 2476 -> 1504 bytes html/inherit_graph_24.map | 2 +- html/inherit_graph_24.md5 | 2 +- html/inherit_graph_24.png | Bin 1504 -> 1702 bytes html/inherit_graph_25.map | 7 +- html/inherit_graph_25.md5 | 2 +- html/inherit_graph_25.png | Bin 1702 -> 8559 bytes html/inherit_graph_26.map | 7 +- html/inherit_graph_26.md5 | 2 +- html/inherit_graph_26.png | Bin 8559 -> 1496 bytes html/inherit_graph_27.map | 2 +- html/inherit_graph_27.md5 | 2 +- html/inherit_graph_27.png | Bin 1496 -> 2338 bytes html/inherit_graph_28.map | 2 +- html/inherit_graph_28.md5 | 2 +- html/inherit_graph_28.png | Bin 2338 -> 1124 bytes html/inherit_graph_29.map | 2 +- html/inherit_graph_29.md5 | 2 +- html/inherit_graph_29.png | Bin 1124 -> 762 bytes html/inherit_graph_30.map | 2 +- html/inherit_graph_30.md5 | 2 +- html/inherit_graph_30.png | Bin 762 -> 1203 bytes html/inherit_graph_31.map | 2 +- html/inherit_graph_31.md5 | 2 +- html/inherit_graph_31.png | Bin 1203 -> 766 bytes html/inherit_graph_32.map | 3 +- html/inherit_graph_32.md5 | 2 +- html/inherit_graph_32.png | Bin 766 -> 2287 bytes html/inherit_graph_33.map | 4 +- html/inherit_graph_33.md5 | 2 +- html/inherit_graph_33.png | Bin 2287 -> 2768 bytes html/inherit_graph_37.map | 2 +- html/inherit_graph_37.md5 | 2 +- html/inherit_graph_37.png | Bin 1526 -> 1561 bytes html/inherit_graph_38.map | 2 +- html/inherit_graph_38.md5 | 2 +- html/inherit_graph_38.png | Bin 1561 -> 1526 bytes html/inherits.html | 83 +- html/jquery.js | 4 +- html/logging_8cc.html | 433 +- html/logging_8cc_source.html | 489 +- html/logging_8h.html | 205 +- html/logging_8h_source.html | 475 +- html/md_FEATURES.html | 177 +- html/md_HISTORY.html | 81 +- html/md_INSTALL.html | 189 +- html/md_PROBLEMS.html | 75 +- html/md_README.html | 234 +- html/menu.js | 96 +- html/namespaceVCDUTILS.html | 51 +- html/namespacemembers.html | 48 +- html/namespacemembers_func.html | 48 +- html/namespaces.html | 27 +- html/pages.html | 27 +- html/search/all_0.html | 6 +- html/search/all_1.html | 6 +- html/search/all_1.js | 134 +- html/search/all_10.html | 6 +- html/search/all_10.js | 82 +- html/search/all_11.html | 6 +- html/search/all_11.js | 156 +- html/search/all_12.html | 6 +- html/search/all_12.js | 94 +- html/search/all_13.html | 6 +- html/search/all_13.js | 20 +- html/search/all_14.html | 6 +- html/search/all_14.js | 144 +- html/search/all_15.html | 6 +- html/search/all_15.js | 26 +- html/search/all_16.html | 6 +- html/search/all_16.js | 2 +- html/search/all_17.html | 6 +- html/search/all_17.js | 34 +- html/search/all_2.html | 6 +- html/search/all_2.js | 38 +- html/search/all_3.html | 6 +- html/search/all_3.js | 178 +- html/search/all_4.html | 6 +- html/search/all_4.js | 96 +- html/search/all_5.html | 6 +- html/search/all_5.js | 38 +- html/search/all_6.html | 6 +- html/search/all_6.js | 212 +- html/search/all_7.html | 6 +- html/search/all_7.js | 182 +- html/search/all_8.html | 6 +- html/search/all_8.js | 56 +- html/search/all_9.html | 6 +- html/search/all_9.js | 106 +- html/search/all_a.html | 6 +- html/search/all_a.js | 2 +- html/search/all_b.html | 6 +- html/search/all_b.js | 143 +- html/search/all_c.html | 6 +- html/search/all_c.js | 690 +- html/search/all_d.html | 6 +- html/search/all_d.js | 10 +- html/search/all_e.html | 6 +- html/search/all_e.js | 78 +- html/search/all_f.html | 6 +- html/search/all_f.js | 163 +- html/search/classes_0.html | 6 +- html/search/classes_0.js | 4 +- html/search/classes_1.html | 6 +- html/search/classes_1.js | 14 +- html/search/classes_2.html | 6 +- html/search/classes_2.js | 8 +- html/search/classes_3.html | 6 +- html/search/classes_3.js | 10 +- html/search/classes_4.html | 6 +- html/search/classes_4.js | 6 +- html/search/classes_5.html | 6 +- html/search/classes_5.js | 18 +- html/search/classes_6.html | 6 +- html/search/classes_6.js | 2 +- html/search/classes_7.html | 6 +- html/search/classes_7.js | 6 +- html/search/classes_8.html | 6 +- html/search/classes_8.js | 4 +- html/search/classes_9.html | 6 +- html/search/classes_9.js | 2 +- html/search/classes_a.html | 6 +- html/search/classes_a.js | 8 +- html/search/classes_b.html | 6 +- html/search/classes_b.js | 2 +- html/search/classes_c.html | 6 +- html/search/classes_c.js | 10 +- html/search/classes_d.html | 6 +- html/search/classes_d.js | 22 +- html/search/classes_e.html | 6 +- html/search/classes_e.js | 10 +- html/search/defines_0.html | 6 +- html/search/defines_0.js | 2 +- html/search/defines_1.html | 6 +- html/search/defines_1.js | 44 +- html/search/defines_2.html | 6 +- html/search/defines_2.js | 4 +- html/search/defines_3.html | 6 +- html/search/defines_3.js | 48 +- html/search/defines_4.html | 6 +- html/search/defines_4.js | 12 +- html/search/defines_5.html | 6 +- html/search/defines_5.js | 18 +- html/search/defines_6.html | 6 +- html/search/defines_6.js | 6 +- html/search/defines_7.html | 6 +- html/search/defines_7.js | 8 +- html/search/defines_8.html | 6 +- html/search/defines_8.js | 8 +- html/search/defines_9.html | 6 +- html/search/defines_9.js | 2 +- html/search/defines_a.html | 6 +- html/search/defines_a.js | 10 +- html/search/defines_b.html | 6 +- html/search/defines_b.js | 26 +- html/search/defines_c.html | 6 +- html/search/defines_c.js | 18 +- html/search/defines_d.html | 6 +- html/search/defines_d.js | 4 +- html/search/defines_e.html | 6 +- html/search/defines_e.js | 26 +- html/search/defines_f.html | 6 +- html/search/defines_f.js | 2 +- html/search/enums_0.html | 6 +- html/search/enums_0.js | 2 +- html/search/enums_1.html | 6 +- html/search/enums_1.js | 4 +- html/search/enums_2.html | 6 +- html/search/enums_2.js | 2 +- html/search/enums_3.html | 6 +- html/search/enums_3.js | 2 +- html/search/enums_4.html | 6 +- html/search/enums_4.js | 4 +- html/search/enums_5.html | 6 +- html/search/enums_5.js | 2 +- html/search/enums_6.html | 6 +- html/search/enums_6.js | 4 +- html/search/enums_7.html | 6 +- html/search/enums_7.js | 4 +- html/search/enums_8.html | 6 +- html/search/enums_8.js | 4 +- html/search/enums_9.html | 6 +- html/search/enums_9.js | 6 +- html/search/enumvalues_0.html | 6 +- html/search/enumvalues_0.js | 10 +- html/search/enumvalues_1.html | 6 +- html/search/enumvalues_1.js | 12 +- html/search/enumvalues_2.html | 6 +- html/search/enumvalues_2.js | 12 +- html/search/enumvalues_3.html | 6 +- html/search/enumvalues_3.js | 12 +- html/search/enumvalues_4.html | 6 +- html/search/enumvalues_4.js | 10 +- html/search/enumvalues_5.html | 6 +- html/search/enumvalues_5.js | 38 +- html/search/enumvalues_6.html | 6 +- html/search/enumvalues_6.js | 12 +- html/search/enumvalues_7.html | 6 +- html/search/enumvalues_7.js | 26 +- html/search/enumvalues_8.html | 6 +- html/search/enumvalues_8.js | 26 +- html/search/files_0.html | 6 +- html/search/files_0.js | 2 +- html/search/files_1.html | 6 +- html/search/files_1.js | 12 +- html/search/files_2.html | 6 +- html/search/files_2.js | 16 +- html/search/files_3.html | 6 +- html/search/files_3.js | 12 +- html/search/files_4.html | 6 +- html/search/files_4.js | 36 +- html/search/files_5.html | 6 +- html/search/files_5.js | 2 +- html/search/files_6.html | 6 +- html/search/files_6.js | 4 +- html/search/files_7.html | 6 +- html/search/files_7.js | 8 +- html/search/files_8.html | 6 +- html/search/files_8.js | 24 +- html/search/files_9.html | 6 +- html/search/files_9.js | 2 +- html/search/functions_0.html | 6 +- html/search/functions_0.js | 52 +- html/search/functions_1.html | 6 +- html/search/functions_1.js | 14 +- html/search/functions_10.html | 6 +- html/search/functions_10.js | 90 +- html/search/functions_11.html | 6 +- html/search/functions_11.js | 62 +- html/search/functions_12.html | 6 +- html/search/functions_12.js | 20 +- html/search/functions_13.html | 6 +- html/search/functions_13.js | 28 +- html/search/functions_14.html | 6 +- html/search/functions_14.js | 14 +- html/search/functions_15.html | 6 +- html/search/functions_15.js | 34 +- html/search/functions_2.html | 6 +- html/search/functions_2.js | 94 +- html/search/functions_3.html | 6 +- html/search/functions_3.js | 44 +- html/search/functions_4.html | 6 +- html/search/functions_4.js | 24 +- html/search/functions_5.html | 6 +- html/search/functions_5.js | 124 +- html/search/functions_6.html | 6 +- html/search/functions_6.js | 178 +- html/search/functions_7.html | 6 +- html/search/functions_7.js | 20 +- html/search/functions_8.html | 6 +- html/search/functions_8.js | 88 +- html/search/functions_9.html | 6 +- html/search/functions_9.js | 2 +- html/search/functions_a.html | 6 +- html/search/functions_a.js | 36 +- html/search/functions_b.html | 6 +- html/search/functions_b.js | 30 +- html/search/functions_c.html | 6 +- html/search/functions_c.js | 8 +- html/search/functions_d.html | 6 +- html/search/functions_d.js | 58 +- html/search/functions_e.html | 6 +- html/search/functions_e.js | 68 +- html/search/functions_f.html | 6 +- html/search/functions_f.js | 56 +- html/search/namespaces_0.html | 6 +- html/search/namespaces_0.js | 2 +- html/search/pages_0.html | 6 +- html/search/pages_0.js | 2 +- html/search/pages_1.html | 6 +- html/search/pages_1.js | 4 +- html/search/pages_2.html | 6 +- html/search/pages_2.js | 6 +- html/search/pages_3.html | 6 +- html/search/pages_3.js | 2 +- html/search/pages_4.html | 6 +- html/search/pages_4.js | 4 +- html/search/pages_5.html | 6 +- html/search/pages_5.js | 2 +- html/search/pages_6.html | 6 +- html/search/pages_6.js | 4 +- html/search/pages_7.html | 6 +- html/search/pages_7.js | 2 +- html/search/related_0.html | 6 +- html/search/related_0.js | 2 +- html/search/search.css | 12 +- html/search/search.js | 76 +- html/search/typedefs_0.html | 6 +- html/search/typedefs_0.js | 10 +- html/search/typedefs_1.html | 6 +- html/search/typedefs_1.js | 4 +- html/search/typedefs_10.html | 6 +- html/search/typedefs_10.js | 10 +- html/search/typedefs_2.html | 6 +- html/search/typedefs_2.js | 12 +- html/search/typedefs_3.html | 6 +- html/search/typedefs_3.js | 6 +- html/search/typedefs_4.html | 6 +- html/search/typedefs_4.js | 2 +- html/search/typedefs_5.html | 6 +- html/search/typedefs_5.js | 12 +- html/search/typedefs_6.html | 6 +- html/search/typedefs_6.js | 10 +- html/search/typedefs_7.html | 6 +- html/search/typedefs_7.js | 2 +- html/search/typedefs_8.html | 6 +- html/search/typedefs_8.js | 82 +- html/search/typedefs_9.html | 6 +- html/search/typedefs_9.js | 6 +- html/search/typedefs_a.html | 6 +- html/search/typedefs_a.js | 2 +- html/search/typedefs_b.html | 6 +- html/search/typedefs_b.js | 16 +- html/search/typedefs_c.html | 6 +- html/search/typedefs_c.js | 8 +- html/search/typedefs_d.html | 6 +- html/search/typedefs_d.js | 10 +- html/search/typedefs_e.html | 6 +- html/search/typedefs_e.js | 6 +- html/search/typedefs_f.html | 6 +- html/search/typedefs_f.js | 20 +- html/search/variables_0.html | 6 +- html/search/variables_0.js | 4 +- html/search/variables_1.html | 6 +- html/search/variables_1.js | 2 +- html/search/variables_2.html | 6 +- html/search/variables_2.js | 2 +- html/search/variables_3.html | 6 +- html/search/variables_3.js | 14 +- html/search/variables_4.html | 6 +- html/search/variables_4.js | 2 +- html/search/variables_5.html | 6 +- html/search/variables_5.js | 4 +- html/search/variables_6.html | 6 +- html/search/variables_6.js | 13 +- html/search/variables_7.html | 6 +- html/search/variables_7.js | 656 +- html/search/variables_8.html | 6 +- html/search/variables_8.js | 2 +- html/search/variables_9.html | 6 +- html/search/variables_9.js | 2 +- html/search/variables_a.html | 6 +- html/search/variables_a.js | 13 +- html/search/variables_b.html | 6 +- html/search/variables_b.js | 6 +- html/search/variables_c.html | 6 +- html/search/variables_c.js | 12 +- html/search/variables_d.html | 6 +- html/search/variables_d.js | 10 +- html/search/variables_e.html | 6 +- html/search/variables_e.js | 2 +- html/structAIFF__CHUNK-members.html | 29 +- html/structAIFF__CHUNK.html | 84 +- html/structAIFF__COMMONCHUNK-members.html | 31 +- html/structAIFF__COMMONCHUNK.html | 149 +- html/structAIFF__FORMCHUNK-members.html | 29 +- html/structAIFF__FORMCHUNK.html | 106 +- html/structAIFF__SOUNDDATACHUNK-members.html | 31 +- html/structAIFF__SOUNDDATACHUNK.html | 128 +- html/structAIFF__TEXTCHUNK-members.html | 29 +- html/structAIFF__TEXTCHUNK.html | 80 +- html/structAUDIO__SETTINGS-members.html | 29 +- html/structAUDIO__SETTINGS.html | 109 +- ...tructBuffer_1_1__tagCACHEINFO-members.html | 43 +- html/structBuffer_1_1__tagCACHEINFO.html | 449 +- html/structCACHE__INFO-members.html | 49 +- html/structCACHE__INFO.html | 609 +- ...structCache_1_1TABLE__COLUMNS-members.html | 29 +- html/structCache_1_1TABLE__COLUMNS.html | 80 +- html/structCache_1_1TABLE__DEF-members.html | 29 +- html/structCache_1_1TABLE__DEF.html | 82 +- html/structFFMPEGFS__PARAMS-members.html | 87 +- html/structFFMPEGFS__PARAMS.html | 1422 +- ...eg__Profiles_1_1PROFILE__LIST-members.html | 31 +- ...ructFFmpeg__Profiles_1_1PROFILE__LIST.html | 128 +- ...__Profiles_1_1PROFILE__OPTION-members.html | 31 +- ...ctFFmpeg__Profiles_1_1PROFILE__OPTION.html | 128 +- ...g__Transcoder_1_1BUFFER__DATA-members.html | 29 +- ...uctFFmpeg__Transcoder_1_1BUFFER__DATA.html | 84 +- ...mpeg__Transcoder_1_1INPUTFILE-members.html | 35 +- ...structFFmpeg__Transcoder_1_1INPUTFILE.html | 239 +- ...peg__Transcoder_1_1OUTPUTFILE-members.html | 39 +- ...tructFFmpeg__Transcoder_1_1OUTPUTFILE.html | 201 +- ...Transcoder_1_1PRORES__BITRATE-members.html | 31 +- ...FFmpeg__Transcoder_1_1PRORES__BITRATE.html | 89 +- ..._BITRATE_1_1PRORES__FRAMERATE-members.html | 29 +- ...1PRORES__BITRATE_1_1PRORES__FRAMERATE.html | 82 +- html/structFormat__Options-members.html | 51 +- html/structFormat__Options.html | 354 +- ...ormat__Options_1_1__tagFORMAT-members.html | 31 +- .../structFormat__Options_1_1__tagFORMAT.html | 126 +- html/structHWACCEL-members.html | 29 +- html/structHWACCEL.html | 111 +- html/structID3v1-members.html | 35 +- html/structID3v1.html | 241 +- html/structIMAGE__FRAME-members.html | 31 +- html/structIMAGE__FRAME.html | 161 +- html/structTHREAD__DATA-members.html | 31 +- html/structTHREAD__DATA.html | 159 +- html/structVCDCHAPTER-members.html | 29 +- html/structVCDCHAPTER.html | 82 +- html/structVCDENTRIES-members.html | 33 +- html/structVCDENTRIES.html | 95 +- html/structVCDINFO-members.html | 33 +- html/structVCDINFO.html | 59 +- html/structVCDMSF-members.html | 29 +- html/structVCDMSF.html | 111 +- html/structVIDEO__SETTINGS-members.html | 29 +- html/structVIDEO__SETTINGS.html | 109 +- html/structVIRTUALFILE-members.html | 53 +- html/structVIRTUALFILE.html | 646 +- ...IRTUALFILE_1_1BLURAY__CHAPTER-members.html | 31 +- .../structVIRTUALFILE_1_1BLURAY__CHAPTER.html | 162 +- ...IRTUALFILE_1_1CUESHEET__TRACK-members.html | 37 +- .../structVIRTUALFILE_1_1CUESHEET__TRACK.html | 316 +- ...ALFILE_1_1CUESHEET__TRACK__coll__graph.map | 4 +- ...ALFILE_1_1CUESHEET__TRACK__coll__graph.md5 | 2 +- ...ALFILE_1_1CUESHEET__TRACK__coll__graph.png | Bin 18235 -> 16730 bytes ...ctVIRTUALFILE_1_1DVD__CHAPTER-members.html | 31 +- html/structVIRTUALFILE_1_1DVD__CHAPTER.html | 137 +- ...ctVIRTUALFILE_1_1VCD__CHAPTER-members.html | 31 +- html/structVIRTUALFILE_1_1VCD__CHAPTER.html | 162 +- html/structVIRTUALFILE__coll__graph.map | 8 +- html/structVIRTUALFILE__coll__graph.md5 | 2 +- html/structVIRTUALFILE__coll__graph.png | Bin 17502 -> 15864 bytes html/structWAV__DATA__HEADER-members.html | 29 +- html/structWAV__DATA__HEADER.html | 82 +- html/structWAV__FACT-members.html | 29 +- html/structWAV__FACT.html | 105 +- html/structWAV__HEADER-members.html | 37 +- html/structWAV__HEADER.html | 269 +- html/structWAV__HEADER__EX-members.html | 31 +- html/structWAV__HEADER__EX.html | 126 +- html/structWAV__LIST__HEADER-members.html | 29 +- html/structWAV__LIST__HEADER.html | 105 +- html/structav__context__deleter-members.html | 27 +- html/structav__context__deleter.html | 39 +- html/structcomp-members.html | 27 +- html/structcomp.html | 39 +- ...uctthread__pool_1_1THREADINFO-members.html | 29 +- html/structthread__pool_1_1THREADINFO.html | 39 +- html/tabs.css | 2 +- html/thread__pool_8cc.html | 33 +- html/thread__pool_8cc_source.html | 323 +- html/thread__pool_8h.html | 35 +- html/thread__pool_8h_source.html | 175 +- html/todo.html | 29 +- html/transcode_8cc.html | 313 +- html/transcode_8cc_source.html | 2253 ++- html/transcode_8h.html | 99 +- html/transcode_8h__dep__incl.png | Bin 12273 -> 12273 bytes html/transcode_8h_source.html | 123 +- html/vcdchapter_8cc.html | 33 +- html/vcdchapter_8cc__incl.png | Bin 57251 -> 57251 bytes html/vcdchapter_8cc_source.html | 695 +- html/vcdchapter_8h.html | 90 +- html/vcdchapter_8h__incl.png | Bin 4615 -> 4614 bytes html/vcdchapter_8h_source.html | 205 +- html/vcdentries_8cc.html | 113 +- html/vcdentries_8cc_source.html | 846 +- html/vcdentries_8h.html | 35 +- html/vcdentries_8h_source.html | 197 +- html/vcdinfo_8cc.html | 71 +- html/vcdinfo_8cc_source.html | 387 +- html/vcdinfo_8h.html | 35 +- html/vcdinfo_8h_source.html | 137 +- html/vcdio_8cc.html | 33 +- html/vcdio_8cc_source.html | 435 +- html/vcdio_8h.html | 37 +- html/vcdio_8h_source.html | 153 +- html/vcdparser_8cc.html | 47 +- html/vcdparser_8cc_source.html | 399 +- html/vcdparser_8h.html | 41 +- html/vcdparser_8h__dep__incl.png | Bin 5454 -> 5457 bytes html/vcdparser_8h_source.html | 91 +- html/vcdutils_8cc.html | 39 +- html/vcdutils_8cc_source.html | 357 +- html/vcdutils_8h.html | 152 +- html/vcdutils_8h_source.html | 165 +- html/wave_8h.html | 47 +- html/wave_8h_source.html | 183 +- 792 files changed, 61323 insertions(+), 51951 deletions(-) diff --git a/html/aiff_8h.html b/html/aiff_8h.html index b765e167b..cafbcb69e 100644 --- a/html/aiff_8h.html +++ b/html/aiff_8h.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/aiff.h File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
Classes | Macros | Typedefs
-
-
aiff.h File Reference
+
aiff.h File Reference
@@ -99,7 +98,7 @@

Go to the source code of this file.

- @@ -112,54 +111,192 @@

+

Classes

struct  AIFF_FORMCHUNK
 
struct  AIFF_TEXTCHUNK
 
- - - + + - - + + - - + + - - + + - - + + - - + + - - + +

+

Macros

-#define AIFF_FORMID   "FORM"
 ckID for Form Chunk
#define AIFF_FORMID   "FORM"
 ckID for Form Chunk More...
 
-#define AIFF_COMMONID   "COMM"
 ckID for Common Chunk
#define AIFF_COMMONID   "COMM"
 ckID for Common Chunk More...
 
-#define AIFF_SOUNDATAID   "SSND"
 ckID for Sound Data Chunk
#define AIFF_SOUNDATAID   "SSND"
 ckID for Sound Data Chunk More...
 
-#define AIFF_NAMEID   "NAME"
 ckID for Name Chunk.
#define AIFF_NAMEID   "NAME"
 ckID for Name Chunk. More...
 
-#define AIFF_AUTHORID   "AUTH"
 ckID for Author Chunk.
#define AIFF_AUTHORID   "AUTH"
 ckID for Author Chunk. More...
 
-#define AIFF_COPYRIGHTID   "(c) "
 ckID for Copyright Chunk.
#define AIFF_COPYRIGHTID   "(c) "
 ckID for Copyright Chunk. More...
 
-#define AIFF_ANNOTATIONID   "ANNO"
 ckID for Annotation Chunk.
#define AIFF_ANNOTATIONID   "ANNO"
 ckID for Annotation Chunk. More...
 
- - - + +

+

Typedefs

-typedef uint8_t AIFF_ID[4]
 AIFF fourcc ID.
typedef uint8_t AIFF_ID[4]
 AIFF fourcc ID. More...
 

Detailed Description

-

AIFF file structures http://paulbourke.net/dataformats/audio/.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +
+

Macro Definition Documentation

+ +

◆ AIFF_ANNOTATIONID

+ +
+
+ + + + +
#define AIFF_ANNOTATIONID   "ANNO"
+
+ +

ckID for Annotation Chunk.

+ +

Definition at line 96 of file aiff.h.

+ +
+
+ +

◆ AIFF_AUTHORID

+ +
+
+ + + + +
#define AIFF_AUTHORID   "AUTH"
+
+ +

ckID for Author Chunk.

+ +

Definition at line 94 of file aiff.h.

+ +
+
+ +

◆ AIFF_COMMONID

+ +
+
+ + + + +
#define AIFF_COMMONID   "COMM"
+
+ +

ckID for Common Chunk

+ +

Definition at line 66 of file aiff.h.

+ +
+
+ +

◆ AIFF_COPYRIGHTID

+ +
+
+ + + + +
#define AIFF_COPYRIGHTID   "(c) "
+
+ +

ckID for Copyright Chunk.

+ +

Definition at line 95 of file aiff.h.

+ +
+
+ +

◆ AIFF_FORMID

+ +
+
+ + + + +
#define AIFF_FORMID   "FORM"
+
+ +

ckID for Form Chunk

+ +

Definition at line 44 of file aiff.h.

+ +
+
+ +

◆ AIFF_NAMEID

+ +
+
+ + + + +
#define AIFF_NAMEID   "NAME"
+
+ +

ckID for Name Chunk.

+ +

Definition at line 93 of file aiff.h.

+ +
+
+ +

◆ AIFF_SOUNDATAID

+ +
+
+ + + + +
#define AIFF_SOUNDATAID   "SSND"
+
+ +

ckID for Sound Data Chunk

+ +

Definition at line 80 of file aiff.h.

+ +
+
+

Typedef Documentation

+ +

◆ AIFF_ID

+ +
+
+ + + + +
typedef uint8_t AIFF_ID[4]
+
+ +

AIFF fourcc ID.

+ +

Definition at line 42 of file aiff.h.

+ +
+
+ diff --git a/html/aiff_8h_source.html b/html/aiff_8h_source.html index 59a6da8dd..6643091a8 100644 --- a/html/aiff_8h_source.html +++ b/html/aiff_8h_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/aiff.h Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
aiff.h
+
aiff.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 by Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
33 #ifndef AIFF_H
-
34 #define AIFF_H
-
35 
-
36 #pragma once
-
37 
-
38 #include <stdint.h>
-
39 
-
40 #pragma pack(push, 1)
-
41 
-
42 typedef uint8_t AIFF_ID[4];
-
44 #define AIFF_FORMID "FORM"
-
48 typedef struct
-
49 {
- -
51  uint32_t m_ckSize;
- -
53  //uint8_t chunks[];
- -
55 
-
59 typedef struct
-
60 {
- -
62  uint32_t m_ckSize;
-
63  //uint8_t data[];
-
64 } AIFF_CHUNK;
-
65 
-
66 #define AIFF_COMMONID "COMM"
-
70 typedef struct
-
71 {
- -
73  uint32_t m_ckSize;
-
74  uint8_t m_numChannels;
-
75  uint32_t m_numSampleFrames;
-
76  uint8_t m_sampleSize;
-
77  //extended sampleRate;
- -
79 
-
80 #define AIFF_SOUNDATAID "SSND"
-
84 typedef struct
-
85 {
- -
87  uint32_t m_ckSize;
-
88  uint32_t m_offset;
-
89  uint32_t m_blockSize;
-
90  //uint8_t soundData[];
- -
92 
-
93 #define AIFF_NAMEID "NAME"
-
94 #define AIFF_AUTHORID "AUTH"
-
95 #define AIFF_COPYRIGHTID "(c) "
-
96 #define AIFF_ANNOTATIONID "ANNO"
-
100 typedef struct
-
101 {
- -
103  uint32_t m_ckSize;
-
104  //uint8_t text[];
- -
106 
-
107 #pragma pack(pop)
-
108 
-
109 #endif // AIFF_H
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 by Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
33#ifndef AIFF_H
+
34#define AIFF_H
+
35
+
36#pragma once
+
37
+
38#include <stdint.h>
+
39
+
40#pragma pack(push, 1)
+
41
+
42typedef uint8_t AIFF_ID[4];
+
44#define AIFF_FORMID "FORM"
+
48typedef struct
+
49{
+ +
51 uint32_t m_ckSize;
+ +
53 //uint8_t chunks[];
+ +
55
+
59typedef struct
+
60{
+ +
62 uint32_t m_ckSize;
+
63 //uint8_t data[];
+ +
65
+
66#define AIFF_COMMONID "COMM"
+
70typedef struct
+
71{
+ +
73 uint32_t m_ckSize;
+
74 uint8_t m_numChannels;
+ +
76 uint8_t m_sampleSize;
+
77 //extended sampleRate;
+ +
79
+
80#define AIFF_SOUNDATAID "SSND"
+
84typedef struct
+
85{
+ +
87 uint32_t m_ckSize;
+
88 uint32_t m_offset;
+
89 uint32_t m_blockSize;
+
90 //uint8_t soundData[];
+ +
92
+
93#define AIFF_NAMEID "NAME"
+
94#define AIFF_AUTHORID "AUTH"
+
95#define AIFF_COPYRIGHTID "(c) "
+
96#define AIFF_ANNOTATIONID "ANNO"
+
100typedef struct
+
101{
+ +
103 uint32_t m_ckSize;
+
104 //uint8_t text[];
+ +
106
+
107#pragma pack(pop)
+
108
+
109#endif // AIFF_H
uint8_t AIFF_ID[4]
AIFF fourcc ID.
Definition: aiff.h:42
uint32_t m_ckSize
Size of this chunk - 8.
Definition: aiff.h:62
@@ -177,7 +176,7 @@
diff --git a/html/annotated.html b/html/annotated.html index d46ab1f49..0573f0649 100644 --- a/html/annotated.html +++ b/html/annotated.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Class List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
@@ -62,8 +62,7 @@
-
-
Class List
+
Class List
Here are the classes, structs, unions and interfaces with brief descriptions:
@@ -136,7 +135,7 @@
diff --git a/html/blurayio_8cc.html b/html/blurayio_8cc.html index 889ec6e20..8d9b4c29b 100644 --- a/html/blurayio_8cc.html +++ b/html/blurayio_8cc.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/blurayio.cc File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
blurayio.cc File Reference
+
blurayio.cc File Reference
@@ -109,15 +108,15 @@

Go to the source code of this file.

Detailed Description

-

BlurayIO class implementation.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

BlurayIO class implementation.

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file blurayio.cc.

diff --git a/html/blurayio_8cc_source.html b/html/blurayio_8cc_source.html index a5d9972e7..7c010c8f7 100644 --- a/html/blurayio_8cc_source.html +++ b/html/blurayio_8cc_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/blurayio.cc Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
blurayio.cc
+
blurayio.cc
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
22 #ifdef USE_LIBBLURAY
-
23 
-
34 #include "blurayio.h"
-
35 #include "ffmpeg_utils.h"
-
36 #include "logging.h"
-
37 
-
38 #include <libbluray/bluray.h>
-
39 
- -
41  : m_bd(nullptr)
-
42  , m_is_eof(false)
-
43  , m_errno(0)
-
44  , m_rest_size(0)
-
45  , m_rest_pos(0)
-
46  , m_cur_pos(0)
-
47  , m_start_pos(0)
-
48  , m_end_pos(AV_NOPTS_VALUE)
-
49  , m_full_title(false)
-
50  , m_title_idx(0)
-
51  , m_chapter_idx(0)
-
52  , m_angle_idx(0)
-
53  , m_duration(AV_NOPTS_VALUE)
-
54 {
-
55  std::memset(&m_data, 0, sizeof(m_data));
-
56 }
-
57 
- -
59 {
-
60  pvt_close();
-
61 }
-
62 
- -
64 {
-
65  return VIRTUALTYPE_BLURAY;
-
66 }
-
67 
-
68 size_t BlurayIO::bufsize() const
-
69 {
-
70  return sizeof(m_data);
-
71 }
-
72 
- -
74 {
-
75  const char *bdpath = nullptr;
-
76  uint32_t title_count;
-
77  uint32_t chapter_end;
-
78  char *keyfile = nullptr;
-
79  BLURAY_TITLE_INFO *ti;
-
80 
- -
82 
-
83  bdpath = path().c_str();
-
84 
-
85  if (virtualfile != nullptr)
-
86  {
- - - - - -
92  }
-
93  else
-
94  {
-
95  m_full_title = false;
-
96  m_title_idx = 0;
-
97  m_chapter_idx = 0;
-
98  m_angle_idx = 0;
-
99  m_duration = AV_NOPTS_VALUE;
-
100  }
-
101 
-
102  chapter_end = m_chapter_idx + 1;
-
103 
-
104  Logging::debug(bdpath, "Opening input Blu-ray.");
-
105 
-
106  m_bd = bd_open(bdpath, keyfile);
-
107  if (m_bd == nullptr)
-
108  {
-
109  Logging::error(bdpath, "Failed to open disc.");
-
110  return 1;
-
111  }
-
112 
-
113  title_count = bd_get_titles(m_bd, TITLES_RELEVANT, 0);
-
114  if (title_count == 0)
-
115  {
-
116  Logging::error(bdpath, "There were no titles found.");
-
117  return 1;
-
118  }
-
119 
-
120  if (!bd_select_title(m_bd, m_title_idx))
-
121  {
-
122  Logging::error(bdpath, "The Blu-ray title no. %1 could not be opened.", m_title_idx);
-
123  return 1;
-
124  }
-
125  ti = bd_get_title_info(m_bd, m_title_idx, m_angle_idx);
-
126 
-
127  if (m_angle_idx >= ti->angle_count)
-
128  {
-
129  Logging::warning(bdpath, "The angle %1 is greater than the angle count %2. Using angle 1.", m_angle_idx + 1, ti->angle_count);
-
130  m_angle_idx = 0;
-
131  }
-
132 
-
133  bd_select_angle(m_bd, m_angle_idx);
-
134 
-
135  if (m_chapter_idx >= ti->chapter_count)
-
136  {
-
137  Logging::error(bdpath, "The first chapter %1 is greater than the chapter count %2.", m_chapter_idx + 1, ti->chapter_count);
-
138  return 1;
-
139  }
-
140 
-
141  if (chapter_end >= ti->chapter_count)
-
142  {
-
143  chapter_end = 0;
-
144  }
-
145 
-
146  if (chapter_end > 0 && !m_full_title)
-
147  {
-
148  m_end_pos = bd_chapter_pos(m_bd, chapter_end) - 1;
-
149  }
-
150  else
-
151  {
-
152  m_end_pos = static_cast<int64_t>(bd_get_title_size(m_bd));
-
153  }
-
154 
-
155  if (m_full_title)
-
156  {
-
157  m_duration = static_cast<int64_t>(ti->duration * AV_TIME_BASE / 90000);
-
158  }
-
159  else
-
160  {
-
161  BLURAY_TITLE_CHAPTER *chapter = &ti->chapters[m_chapter_idx];
-
162  m_duration = static_cast<int64_t>(chapter->duration * AV_TIME_BASE / 90000);
-
163  }
-
164 
-
165  bd_free_title_info(ti);
-
166 
-
167  m_start_pos = bd_seek_chapter(m_bd, m_chapter_idx);
-
168 
-
169  m_rest_size = 0;
-
170  m_rest_pos = 0;
-
171 
-
172  return 0;
-
173 }
-
174 
-
175 size_t BlurayIO::readio(void * data, size_t size)
-
176 {
-
177  size_t result_len = 0;
-
178 
-
179  if (m_rest_size)
-
180  {
-
181  result_len = m_rest_size;
-
182 
-
183  if (m_rest_size > size)
-
184  {
-
185  errno = EINVAL;
-
186  return 0;
-
187  }
-
188 
-
189  std::memcpy(data, &m_data[m_rest_pos], m_rest_size);
-
190 
-
191  m_rest_size = m_rest_pos = 0;
-
192 
-
193  return result_len;
-
194  }
-
195 
-
196  m_cur_pos = static_cast<int64_t>(bd_tell(m_bd));
-
197  if (m_end_pos < 0 || m_cur_pos < m_end_pos)
-
198  {
-
199  int maxsize = sizeof(m_data);
-
200 
-
201  if (maxsize > (m_end_pos - m_cur_pos))
-
202  {
-
203  maxsize = static_cast<int>(m_end_pos - m_cur_pos);
-
204  }
-
205 
-
206  int res = bd_read(m_bd, m_data, maxsize);
-
207  if (res < 0)
-
208  {
-
209  Logging::error(path(), "bd_read has failed.");
-
210  return 0;
-
211  }
-
212 
-
213  size_t bytes = static_cast<size_t>(res);
-
214 
-
215  m_cur_pos = static_cast<int64_t>(bd_tell(m_bd));
-
216 
-
217  if (bytes > size)
-
218  {
-
219  result_len = size;
-
220  std::memcpy(data, m_data, result_len);
-
221 
-
222  m_rest_size = bytes - size;
-
223  m_rest_pos = size;
-
224  }
-
225  else
-
226  {
-
227  result_len = bytes;
-
228  std::memcpy(data, m_data, result_len);
-
229  }
-
230  }
-
231 
-
232  return result_len;
-
233 }
-
234 
-
235 int BlurayIO::error() const
-
236 {
-
237  return m_errno;
-
238 }
-
239 
-
240 int64_t BlurayIO::duration() const
-
241 {
-
242  return m_duration;
-
243 }
-
244 
-
245 size_t BlurayIO::size() const
-
246 {
-
247  return static_cast<size_t>(m_end_pos - m_start_pos);
-
248 }
-
249 
-
250 size_t BlurayIO::tell() const
-
251 {
-
252  return static_cast<size_t>(static_cast<int64_t>(bd_tell(m_bd)) - m_start_pos);
-
253 }
-
254 
-
255 int BlurayIO::seek(int64_t offset, int whence)
-
256 {
-
257  int64_t seek_pos;
-
258 
-
259  switch (whence)
-
260  {
-
261  case SEEK_SET:
-
262  {
-
263  seek_pos = m_start_pos + offset;
-
264  break;
-
265  }
-
266  case SEEK_CUR:
-
267  {
-
268  seek_pos = m_start_pos + offset + static_cast<int64_t>(bd_tell(m_bd));
-
269  break;
-
270  }
-
271  case SEEK_END:
-
272  {
-
273  seek_pos = m_end_pos + offset;
-
274  break;
-
275  }
-
276  default:
-
277  {
-
278  errno = EINVAL;
-
279  return (EOF);
-
280  }
-
281  }
-
282 
-
283  if (seek_pos > m_end_pos)
-
284  {
-
285  m_cur_pos = m_end_pos; // Cannot go beyond EOF. Set position to end, leave errno untouched.
-
286  return 0;
-
287  }
-
288 
-
289  if (seek_pos < 0) // Cannot go before head, set errno.
-
290  {
-
291  errno = EINVAL;
-
292  return (EOF);
-
293  }
-
294 
-
295  m_cur_pos = bd_seek(m_bd, static_cast<uint64_t>(seek_pos));
-
296 
-
297  return (m_cur_pos == seek_pos ? 0 : -1);
-
298 }
-
299 
-
300 bool BlurayIO::eof() const
-
301 {
-
302  return (m_cur_pos >= m_end_pos);
-
303 }
-
304 
- -
306 {
-
307  pvt_close();
-
308 }
-
309 
- -
311 {
-
312  BLURAY * bd = m_bd;
-
313  if (bd != nullptr)
-
314  {
-
315  m_bd = nullptr;
-
316  bd_close(bd);
-
317  }
-
318 }
-
319 
-
320 #endif // USE_LIBBLURAY
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
22#ifdef USE_LIBBLURAY
+
23
+
34#include "blurayio.h"
+
35#include "ffmpeg_utils.h"
+
36#include "logging.h"
+
37
+
38#include <libbluray/bluray.h>
+
39
+ +
41 : m_bd(nullptr)
+
42 , m_is_eof(false)
+
43 , m_errno(0)
+
44 , m_rest_size(0)
+
45 , m_rest_pos(0)
+
46 , m_cur_pos(0)
+
47 , m_start_pos(0)
+
48 , m_end_pos(AV_NOPTS_VALUE)
+
49 , m_full_title(false)
+
50 , m_title_idx(0)
+
51 , m_chapter_idx(0)
+
52 , m_angle_idx(0)
+
53 , m_duration(AV_NOPTS_VALUE)
+
54{
+
55 std::memset(&m_data, 0, sizeof(m_data));
+
56}
+
57
+ +
59{
+
60 pvt_close();
+
61}
+
62
+ +
64{
+
65 return VIRTUALTYPE_BLURAY;
+
66}
+
67
+
68size_t BlurayIO::bufsize() const
+
69{
+
70 return sizeof(m_data);
+
71}
+
72
+ +
74{
+
75 const char *bdpath = nullptr;
+
76 uint32_t title_count;
+
77 uint32_t chapter_end;
+
78 char *keyfile = nullptr;
+
79 BLURAY_TITLE_INFO *ti;
+
80
+ +
82
+
83 bdpath = path().c_str();
+
84
+
85 if (virtualfile != nullptr)
+
86 {
+ + + + + +
92 }
+
93 else
+
94 {
+
95 m_full_title = false;
+
96 m_title_idx = 0;
+
97 m_chapter_idx = 0;
+
98 m_angle_idx = 0;
+
99 m_duration = AV_NOPTS_VALUE;
+
100 }
+
101
+
102 chapter_end = m_chapter_idx + 1;
+
103
+
104 Logging::debug(bdpath, "Opening input Blu-ray.");
+
105
+
106 m_bd = bd_open(bdpath, keyfile);
+
107 if (m_bd == nullptr)
+
108 {
+
109 Logging::error(bdpath, "Failed to open disc.");
+
110 return 1;
+
111 }
+
112
+
113 title_count = bd_get_titles(m_bd, TITLES_RELEVANT, 0);
+
114 if (title_count == 0)
+
115 {
+
116 Logging::error(bdpath, "There were no titles found.");
+
117 return 1;
+
118 }
+
119
+
120 if (!bd_select_title(m_bd, m_title_idx))
+
121 {
+
122 Logging::error(bdpath, "The Blu-ray title no. %1 could not be opened.", m_title_idx);
+
123 return 1;
+
124 }
+
125 ti = bd_get_title_info(m_bd, m_title_idx, m_angle_idx);
+
126
+
127 if (m_angle_idx >= ti->angle_count)
+
128 {
+
129 Logging::warning(bdpath, "The angle %1 is greater than the angle count %2. Using angle 1.", m_angle_idx + 1, ti->angle_count);
+
130 m_angle_idx = 0;
+
131 }
+
132
+
133 bd_select_angle(m_bd, m_angle_idx);
+
134
+
135 if (m_chapter_idx >= ti->chapter_count)
+
136 {
+
137 Logging::error(bdpath, "The first chapter %1 is greater than the chapter count %2.", m_chapter_idx + 1, ti->chapter_count);
+
138 return 1;
+
139 }
+
140
+
141 if (chapter_end >= ti->chapter_count)
+
142 {
+
143 chapter_end = 0;
+
144 }
+
145
+
146 if (chapter_end > 0 && !m_full_title)
+
147 {
+
148 m_end_pos = bd_chapter_pos(m_bd, chapter_end) - 1;
+
149 }
+
150 else
+
151 {
+
152 m_end_pos = static_cast<int64_t>(bd_get_title_size(m_bd));
+
153 }
+
154
+
155 if (m_full_title)
+
156 {
+
157 m_duration = static_cast<int64_t>(ti->duration * AV_TIME_BASE / 90000);
+
158 }
+
159 else
+
160 {
+
161 BLURAY_TITLE_CHAPTER *chapter = &ti->chapters[m_chapter_idx];
+
162 m_duration = static_cast<int64_t>(chapter->duration * AV_TIME_BASE / 90000);
+
163 }
+
164
+
165 bd_free_title_info(ti);
+
166
+
167 m_start_pos = bd_seek_chapter(m_bd, m_chapter_idx);
+
168
+
169 m_rest_size = 0;
+
170 m_rest_pos = 0;
+
171
+
172 return 0;
+
173}
+
174
+
175size_t BlurayIO::readio(void * data, size_t size)
+
176{
+
177 size_t result_len = 0;
+
178
+
179 if (m_rest_size)
+
180 {
+
181 result_len = m_rest_size;
+
182
+
183 if (m_rest_size > size)
+
184 {
+
185 errno = EINVAL;
+
186 return 0;
+
187 }
+
188
+
189 std::memcpy(data, &m_data[m_rest_pos], m_rest_size);
+
190
+ +
192
+
193 return result_len;
+
194 }
+
195
+
196 m_cur_pos = static_cast<int64_t>(bd_tell(m_bd));
+
197 if (m_end_pos < 0 || m_cur_pos < m_end_pos)
+
198 {
+
199 int maxsize = sizeof(m_data);
+
200
+
201 if (maxsize > (m_end_pos - m_cur_pos))
+
202 {
+
203 maxsize = static_cast<int>(m_end_pos - m_cur_pos);
+
204 }
+
205
+
206 int res = bd_read(m_bd, m_data, maxsize);
+
207 if (res < 0)
+
208 {
+
209 Logging::error(path(), "bd_read has failed.");
+
210 return 0;
+
211 }
+
212
+
213 size_t bytes = static_cast<size_t>(res);
+
214
+
215 m_cur_pos = static_cast<int64_t>(bd_tell(m_bd));
+
216
+
217 if (bytes > size)
+
218 {
+
219 result_len = size;
+
220 std::memcpy(data, m_data, result_len);
+
221
+
222 m_rest_size = bytes - size;
+ +
224 }
+
225 else
+
226 {
+
227 result_len = bytes;
+
228 std::memcpy(data, m_data, result_len);
+
229 }
+
230 }
+
231
+
232 return result_len;
+
233}
+
234
+ +
236{
+
237 return m_errno;
+
238}
+
239
+
240int64_t BlurayIO::duration() const
+
241{
+
242 return m_duration;
+
243}
+
244
+
245size_t BlurayIO::size() const
+
246{
+
247 return static_cast<size_t>(m_end_pos - m_start_pos);
+
248}
+
249
+
250size_t BlurayIO::tell() const
+
251{
+
252 return static_cast<size_t>(static_cast<int64_t>(bd_tell(m_bd)) - m_start_pos);
+
253}
+
254
+
255int BlurayIO::seek(int64_t offset, int whence)
+
256{
+
257 int64_t seek_pos;
+
258
+
259 switch (whence)
+
260 {
+
261 case SEEK_SET:
+
262 {
+
263 seek_pos = m_start_pos + offset;
+
264 break;
+
265 }
+
266 case SEEK_CUR:
+
267 {
+
268 seek_pos = m_start_pos + offset + static_cast<int64_t>(bd_tell(m_bd));
+
269 break;
+
270 }
+
271 case SEEK_END:
+
272 {
+
273 seek_pos = m_end_pos + offset;
+
274 break;
+
275 }
+
276 default:
+
277 {
+
278 errno = EINVAL;
+
279 return (EOF);
+
280 }
+
281 }
+
282
+
283 if (seek_pos > m_end_pos)
+
284 {
+
285 m_cur_pos = m_end_pos; // Cannot go beyond EOF. Set position to end, leave errno untouched.
+
286 return 0;
+
287 }
+
288
+
289 if (seek_pos < 0) // Cannot go before head, set errno.
+
290 {
+
291 errno = EINVAL;
+
292 return (EOF);
+
293 }
+
294
+
295 m_cur_pos = bd_seek(m_bd, static_cast<uint64_t>(seek_pos));
+
296
+
297 return (m_cur_pos == seek_pos ? 0 : -1);
+
298}
+
299
+
300bool BlurayIO::eof() const
+
301{
+
302 return (m_cur_pos >= m_end_pos);
+
303}
+
304
+ +
306{
+
307 pvt_close();
+
308}
+
309
+ +
311{
+
312 BLURAY * bd = m_bd;
+
313 if (bd != nullptr)
+
314 {
+
315 m_bd = nullptr;
+
316 bd_close(bd);
+
317 }
+
318}
+
319
+
320#endif // USE_LIBBLURAY
Blu-ray I/O.
-
struct bluray BLURAY
Forward declaration of libbluray handle.
Definition: blurayio.h:43
+
struct bluray BLURAY
Forward declaration of libbluray handle.
Definition: blurayio.h:43
virtual size_t readio(void *data, size_t size) override
Read data from file.
Definition: blurayio.cc:175
int64_t m_cur_pos
Current position in virtual file.
Definition: blurayio.h:147
size_t m_rest_pos
Position in buffer.
Definition: blurayio.h:146
@@ -429,7 +428,7 @@
diff --git a/html/blurayio_8h.html b/html/blurayio_8h.html index 2c926505f..1402137d8 100644 --- a/html/blurayio_8h.html +++ b/html/blurayio_8h.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/blurayio.h File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ + -
-
blurayio.h File Reference
+
blurayio.h File Reference
@@ -105,30 +104,48 @@

Go to the source code of this file.

-

+

Classes

class  BlurayIO
 Blu-ray I/O class. More...
 
- - - + +

+

Typedefs

-typedef struct bluray BLURAY
 Forward declaration of libbluray handle.
typedef struct bluray BLURAY
 Forward declaration of libbluray handle. More...
 

Detailed Description

-

Blu-ray I/O.

-

This is only available if built with -DUSE_LIBBLURAY parameter.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

Blu-ray I/O.

+

This is only available if built with -DUSE_LIBBLURAY parameter.

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file blurayio.h.

-
+

Typedef Documentation

+ +

◆ BLURAY

+ +
+
+ + + + +
typedef struct bluray BLURAY
+
+ +

Forward declaration of libbluray handle.

+ +

Definition at line 43 of file blurayio.h.

+ +
+
+ diff --git a/html/blurayio_8h_source.html b/html/blurayio_8h_source.html index ce9643129..9be77ff41 100644 --- a/html/blurayio_8h_source.html +++ b/html/blurayio_8h_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/blurayio.h Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
blurayio.h
+
blurayio.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2018-2023 by Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
34 #ifndef BLURAYIO_H
-
35 #define BLURAYIO_H
-
36 
-
37 #pragma once
-
38 
-
39 #ifdef USE_LIBBLURAY
-
40 
-
41 #include "fileio.h"
-
42 
-
43 typedef struct bluray BLURAY;
-
48 class BlurayIO : public FileIO
-
49 {
-
50 public:
-
54  explicit BlurayIO();
-
58  virtual ~BlurayIO();
-
59 
-
64  virtual VIRTUALTYPE type() const override;
-
69  virtual size_t bufsize() const override;
-
70 
-
77  virtual int openio(LPVIRTUALFILE virtualfile) override;
-
87  virtual size_t readio(void *data, size_t size) override;
-
92  virtual int error() const override;
-
97  virtual int64_t duration() const override;
-
102  virtual size_t size() const override;
-
107  virtual size_t tell() const override;
-
122  virtual int seek(int64_t offset, int whence) override;
-
127  virtual bool eof() const override;
-
131  virtual void closeio() override;
-
132 
-
133 private:
-
138  void pvt_close();
-
139 
-
140 protected:
- -
143  bool m_is_eof;
-
144  int m_errno;
-
145  size_t m_rest_size;
-
146  size_t m_rest_pos;
-
147  int64_t m_cur_pos;
-
148  int64_t m_start_pos;
-
149  int64_t m_end_pos;
- -
152  uint32_t m_title_idx;
-
153  unsigned m_chapter_idx;
-
154  unsigned m_angle_idx;
-
156  uint8_t m_data[192 * 1024];
-
158  int64_t m_duration;
-
159 };
-
160 #endif // USE_LIBBLURAY
-
161 
-
162 #endif // BLURAYIO_H
-
struct bluray BLURAY
Forward declaration of libbluray handle.
Definition: blurayio.h:43
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2018-2023 by Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
34#ifndef BLURAYIO_H
+
35#define BLURAYIO_H
+
36
+
37#pragma once
+
38
+
39#ifdef USE_LIBBLURAY
+
40
+
41#include "fileio.h"
+
42
+
43typedef struct bluray BLURAY;
+
48class BlurayIO : public FileIO
+
49{
+
50public:
+
54 explicit BlurayIO();
+
58 virtual ~BlurayIO();
+
59
+
64 virtual VIRTUALTYPE type() const override;
+
69 virtual size_t bufsize() const override;
+
70
+
77 virtual int openio(LPVIRTUALFILE virtualfile) override;
+
87 virtual size_t readio(void *data, size_t size) override;
+
92 virtual int error() const override;
+
97 virtual int64_t duration() const override;
+
102 virtual size_t size() const override;
+
107 virtual size_t tell() const override;
+
122 virtual int seek(int64_t offset, int whence) override;
+
127 virtual bool eof() const override;
+
131 virtual void closeio() override;
+
132
+
133private:
+
138 void pvt_close();
+
139
+
140protected:
+ +
143 bool m_is_eof;
+ +
145 size_t m_rest_size;
+
146 size_t m_rest_pos;
+
147 int64_t m_cur_pos;
+
148 int64_t m_start_pos;
+
149 int64_t m_end_pos;
+ +
152 uint32_t m_title_idx;
+
153 unsigned m_chapter_idx;
+
154 unsigned m_angle_idx;
+
156 uint8_t m_data[192 * 1024];
+
158 int64_t m_duration;
+
159};
+
160#endif // USE_LIBBLURAY
+
161
+
162#endif // BLURAYIO_H
+
struct bluray BLURAY
Forward declaration of libbluray handle.
Definition: blurayio.h:43
Blu-ray I/O class.
Definition: blurayio.h:49
virtual size_t readio(void *data, size_t size) override
Read data from file.
Definition: blurayio.cc:175
int64_t m_cur_pos
Current position in virtual file.
Definition: blurayio.h:147
@@ -180,7 +179,7 @@
diff --git a/html/blurayparser_8cc.html b/html/blurayparser_8cc.html index 28f5df7b1..36e0c050a 100644 --- a/html/blurayparser_8cc.html +++ b/html/blurayparser_8cc.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/blurayparser.cc File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
blurayparser.cc File Reference
+
blurayparser.cc File Reference
@@ -120,7 +119,7 @@

Go to the source code of this file.

- @@ -145,13 +144,13 @@

+

Functions

static bool audio_stream_info (const std::string &path, BLURAY_STREAM_INFO *ss, int *channels, int *sample_rate)
 Get information about Blu-ray stream. More...
 

Detailed Description

-

Blu-ray disk parser implementation.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

Blu-ray disk parser implementation.

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file blurayparser.cc.

Function Documentation

- +

◆ audio_stream_info()

- +

◆ create_bluray_virtualfile()

@@ -373,13 +372,13 @@

Definition at line 432 of file blurayparser.cc.

-

References add_fuse_entry(), audio_stream_info(), BITRATE, Logging::error(), ffmpeg_format, format_bitrate(), format_duration(), format_samplerate(), format_size(), insert_dir(), insert_file(), VIRTUALFILE::BLURAY_CHAPTER::m_angle_no, VIRTUALFILE::m_bluray, VIRTUALFILE::m_channels, VIRTUALFILE::BLURAY_CHAPTER::m_chapter_no, VIRTUALFILE::m_duration, VIRTUALFILE::m_format_idx, VIRTUALFILE::m_framerate, VIRTUALFILE::m_full_title, VIRTUALFILE::m_height, VIRTUALFILE::BLURAY_CHAPTER::m_playlist_no, VIRTUALFILE::m_predicted_size, VIRTUALFILE::m_sample_rate, VIRTUALFILE::m_st, VIRTUALFILE::BLURAY_CHAPTER::m_title_no, VIRTUALFILE::m_video_frame_count, VIRTUALFILE::m_width, parse_find_best_audio_stream(), parse_find_best_video_stream(), replace_all(), strsprintf(), Logging::trace(), transcoder_cached_filesize(), transcoder_set_filesize(), video_stream_info(), and VIRTUALTYPE_BLURAY.

+

References add_fuse_entry(), audio_stream_info(), BITRATE, Logging::error(), ffmpeg_format, format_bitrate(), format_duration(), format_samplerate(), format_size(), insert_dir(), insert_file(), VIRTUALFILE::BLURAY_CHAPTER::m_angle_no, VIRTUALFILE::m_bluray, VIRTUALFILE::m_channels, VIRTUALFILE::BLURAY_CHAPTER::m_chapter_no, VIRTUALFILE::m_duration, VIRTUALFILE::m_format_idx, VIRTUALFILE::m_framerate, VIRTUALFILE::m_full_title, VIRTUALFILE::m_height, VIRTUALFILE::BLURAY_CHAPTER::m_playlist_no, VIRTUALFILE::m_predicted_size, VIRTUALFILE::m_sample_rate, VIRTUALFILE::m_st, VIRTUALFILE::BLURAY_CHAPTER::m_title_no, VIRTUALFILE::m_video_frame_count, VIRTUALFILE::m_width, parse_find_best_audio_stream(), parse_find_best_video_stream(), replace_all(), strsprintf(), Logging::trace(), transcoder_cached_filesize(), transcoder_set_filesize(), video_stream_info(), and VIRTUALTYPE_BLURAY.

Referenced by parse_bluray().

- +

◆ parse_bluray()

@@ -445,7 +444,7 @@

+

◆ parse_find_best_audio_stream()

@@ -478,7 +477,7 @@

+

◆ parse_find_best_video_stream()

@@ -511,7 +510,7 @@

+

◆ video_stream_info()

@@ -594,7 +593,7 @@

diff --git a/html/blurayparser_8cc_source.html b/html/blurayparser_8cc_source.html index 15900c1c9..9544db22c 100644 --- a/html/blurayparser_8cc_source.html +++ b/html/blurayparser_8cc_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/blurayparser.cc Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
blurayparser.cc
+
blurayparser.cc
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
22 #ifdef USE_LIBBLURAY
-
23 
-
34 #include "ffmpegfs.h"
-
35 #include "blurayparser.h"
-
36 #include "transcode.h"
-
37 #include "logging.h"
-
38 
-
39 #include "libbluray/bluray.h"
-
40 #include "libbluray/bluray-version.h"
-
41 
-
42 extern "C" {
-
43 #include <libavutil/rational.h>
-
44 }
-
45 
-
46 static bool audio_stream_info(const std::string &path, BLURAY_STREAM_INFO *ss, int *channels, int *sample_rate);
-
47 static bool video_stream_info(const std::string &path, BLURAY_STREAM_INFO *ss, int *width, int *height, AVRational *framerate, bool *interleaved);
-
48 static int parse_find_best_audio_stream();
-
49 static int parse_find_best_video_stream();
-
50 static bool create_bluray_virtualfile(BLURAY *bd, const BLURAY_TITLE_INFO* ti, const std::string & path, const struct stat * statbuf, void * buf, fuse_fill_dir_t filler, bool is_main_title, bool full_title, uint32_t title_idx, uint32_t chapter_idx);
-
51 static int parse_bluray(const std::string & path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler);
-
52 
-
61 static bool audio_stream_info(const std::string & path, BLURAY_STREAM_INFO *ss, int *channels, int *sample_rate)
-
62 {
-
63  bool audio = false;
-
64 
-
65  switch (ss->coding_type)
-
66  {
-
67  // Video
-
68  case 0x01:
-
69  case 0x02:
-
70  case 0xea:
-
71  case 0x1b:
-
72  case 0x24:
-
73  {
-
74  break;
-
75  }
-
76  // Audio
-
77  case 0x03:
-
78  case 0x04:
-
79  case 0x80:
-
80  case 0x81:
-
81  case 0x82:
-
82  case 0x83:
-
83  case 0x84:
-
84  case 0x85:
-
85  case 0x86:
-
86  case 0xa1:
-
87  case 0xa2:
-
88  {
-
89  switch (ss->format)
-
90  {
-
91  case BLURAY_AUDIO_FORMAT_MONO:
-
92  {
-
93  *channels = 1; // Mono
-
94  break;
-
95  }
-
96  case BLURAY_AUDIO_FORMAT_STEREO:
-
97  {
-
98  *channels = 2; // Stereo
-
99  break;
-
100  }
-
101  case BLURAY_AUDIO_FORMAT_MULTI_CHAN:
-
102  {
-
103  *channels = 2; // Multi Channel
-
104  break;
-
105  }
-
106  case BLURAY_AUDIO_FORMAT_COMBO:
-
107  {
-
108  *channels = 2; // Stereo ac3/dts
-
109  break;
-
110  }
-
111  default:
-
112  {
-
113  Logging::error(path, "Unknown number of audio channels %1. Assuming 2 channel/stereo - may be totally wrong.", ss->format);
-
114  *channels = 2; // Stereo
-
115  break;
-
116  }
-
117  }
-
118 
-
119  switch (ss->rate)
-
120  {
-
121  case BLURAY_AUDIO_RATE_48:
-
122  {
-
123  *sample_rate = 48000;
-
124  break;
-
125  }
-
126  case BLURAY_AUDIO_RATE_96:
-
127  {
-
128  *sample_rate = 96000;
-
129  break;
-
130  }
-
131  case BLURAY_AUDIO_RATE_192:
-
132  {
-
133  *sample_rate = 192000;
-
134  break;
-
135  }
-
136  // 48 or 96 ac3/dts
-
137  // 192 mpl/dts-hd
-
138  case BLURAY_AUDIO_RATE_192_COMBO:
-
139  {
-
140  // *sample_rate = "48/192 Khz";
-
141  break;
-
142  }
-
143  // 48 ac3/dts
-
144  // 96 mpl/dts-hd
-
145  case BLURAY_AUDIO_RATE_96_COMBO:
-
146  {
-
147  // *sample_rate = "48/96 Khz";
-
148  break;
-
149  }
-
150  default:
-
151  {
-
152  Logging::error(path, "Unknown audio sample rate %1. Assuming 48 kHz - may be totally wrong.", ss->rate);
-
153  *sample_rate = 48000;
-
154  break;
-
155  }
-
156  }
-
157 
-
158  audio = true;
-
159  break;
-
160  }
-
161  case 0x90:
-
162  case 0x91:
-
163  {
-
164  // Language ss->lang
-
165  break;
-
166  }
-
167  case 0x92:
-
168  {
-
169  // Char Code ss->char_code);
-
170  // Language ss->lang);
-
171  break;
-
172  }
-
173  default:
-
174  {
-
175  Logging::error(path, "Unrecognised coding type %<%02x>1.", ss->coding_type);
-
176  break;
-
177  }
-
178  }
-
179 
-
180  return audio;
-
181 }
-
182 
-
193 static bool video_stream_info(const std::string & path, BLURAY_STREAM_INFO *ss, int *width, int *height, AVRational *framerate, bool *interleaved)
-
194 {
-
195  bool video = false;
-
196 
-
197  switch (ss->coding_type)
-
198  {
-
199  // Video
-
200  case 0x01:
-
201  case 0x02:
-
202  case 0xea:
-
203  case 0x1b:
-
204  case 0x24:
-
205  {
-
206  // SD
-
207  // 720×480, 59.94i, 4:3 or 16:9
-
208 
-
209  // 720×576, 50i, 4:3 or 16:9
-
210 
-
211  // HD
-
212  // 1280×720, 59.94p, 16:9
-
213  // 1280×720, 50p, 16:9
-
214  // 1280×720, 24p, 16:9
-
215  // 1280×720, 23.976p, 16:9
-
216 
-
217  // 1440×1080, 59.94i, 16:9
-
218  // 1440×1080, 50i, 16:9
-
219  // 1440×1080, 24p, 16:9
-
220  // 1440×1080, 23.976p, 16:9
-
221 
-
222  // 1920×1080, 59.94i, 16:9
-
223  // 1920×1080, 50i, 16:9
-
224  // 1920×1080, 24p, 16:9
-
225  // 1920×1080, 23.976p, 16:9
-
226 
-
227  // HD
-
228  // 1920×1080, 60p, 16:9
-
229  // 1920×1080, 59.94p, 16:9
-
230  // 1920×1080, 50p, 16:9
-
231  // 1920×1080, 25p, 16:9
-
232 
-
233  // 4K UHD
-
234  // 3840×2160, 60p, 16:9
-
235  // 3840×2160, 59.94p, 16:9
-
236  // 3840×2160, 50p, 16:9
-
237  // 3840×2160, 25p, 16:9
-
238  // 3840×2160, 24p, 16:9
-
239  // 3840×2160, 23.976p, 16:9
-
240 
-
241  switch (ss->format)
-
242  {
-
243  case BLURAY_VIDEO_FORMAT_480I: // ITU-R BT.601-5
-
244  {
-
245  *width = 720;
-
246  *height = 480;
-
247  *interleaved = true;
-
248  break;
-
249  }
-
250  case BLURAY_VIDEO_FORMAT_576I: // ITU-R BT.601-4
-
251  {
-
252  *width = 720;
-
253  *height = 576;
-
254  *interleaved = true;
-
255  break;
-
256  }
-
257  case BLURAY_VIDEO_FORMAT_480P: // SMPTE 293M
-
258  {
-
259  *width = 720;
-
260  *height = 480;
-
261  *interleaved = false;
-
262  break;
-
263  }
-
264  case BLURAY_VIDEO_FORMAT_1080I: // SMPTE 274M
-
265  {
-
266  *width = 1920;
-
267  *height = 1080;
-
268  *interleaved = true;
-
269  break;
-
270  }
-
271  case BLURAY_VIDEO_FORMAT_720P: // SMPTE 296M
-
272  {
-
273  *height = 1280;
-
274  *width = 720;
-
275  *interleaved = false;
-
276  break;
-
277  }
-
278  case BLURAY_VIDEO_FORMAT_1080P: // SMPTE 274M
-
279  {
-
280  *width = 1920;
-
281  *height = 1080;
-
282  *interleaved = false;
-
283  break;
-
284  }
-
285  case BLURAY_VIDEO_FORMAT_576P: // ITU-R BT.1358
-
286  {
-
287  *width = 720;
-
288  *height = 576;
-
289  *interleaved = false;
-
290  break;
-
291  }
-
292  // Added with libluray change 14aa7e9c0 (hpi1 2017-08-28 09:50:43 +0300)
-
293  // Available since version 1.1.0
-
294 #if (BLURAY_VERSION_MAJOR > 1 || (BLURAY_VERSION_MAJOR == 1 && BLURAY_VERSION_MINOR >= 1))
-
295  case BLURAY_VIDEO_FORMAT_2160P: // UHD
-
296  {
-
297  *width = 3840;
-
298  *height = 2160;
-
299  *interleaved = false;
-
300  break;
-
301  }
-
302 #endif
-
303  default:
-
304  {
-
305  Logging::error(path, "Unknown video format %1. Assuming 1920x1080P - may be totally wrong.", ss->format);
-
306  *width = 1920;
-
307  *height = 1080;
-
308  *interleaved = false;
-
309  break;
-
310  }
-
311  }
-
312 
-
313  switch (ss->rate)
-
314  {
-
315  case BLURAY_VIDEO_RATE_24000_1001:
-
316  {
-
317  *framerate = av_make_q(24000, 1001);
-
318  break;
-
319  }
-
320  case BLURAY_VIDEO_RATE_24:
-
321  {
-
322  *framerate = av_make_q(24000, 1000);
-
323  break;
-
324  }
-
325  case BLURAY_VIDEO_RATE_25:
-
326  {
-
327  *framerate = av_make_q(25000, 1000);
-
328  break;
-
329  }
-
330  case BLURAY_VIDEO_RATE_30000_1001:
-
331  {
-
332  *framerate = av_make_q(30000, 1001);
-
333  break;
-
334  }
-
335  case BLURAY_VIDEO_RATE_50:
-
336  {
-
337  *framerate = av_make_q(50000, 1000);
-
338  break;
-
339  }
-
340  case BLURAY_VIDEO_RATE_60000_1001:
-
341  {
-
342  *framerate = av_make_q(60000, 1001);
-
343  break;
-
344  }
-
345  default:
-
346  {
-
347  Logging::error(path, "Unknown video frame rate %1. Assuming 25 fps - may be totally wrong.", ss->rate);
-
348  *framerate = av_make_q(25000, 1000);
-
349  break;
-
350  }
-
351  }
-
352 
-
353  video = true;
-
354  break;
-
355  }
-
356  // Audio
-
357  case 0x03:
-
358  case 0x04:
-
359  case 0x80:
-
360  case 0x81:
-
361  case 0x82:
-
362  case 0x83:
-
363  case 0x84:
-
364  case 0x85:
-
365  case 0x86:
-
366  case 0xa1:
-
367  case 0xa2:
-
368  {
-
369  break;
-
370  }
-
371  case 0x90:
-
372  case 0x91:
-
373  {
-
374  // Language ss->lang
-
375  break;
-
376  }
-
377  case 0x92:
-
378  {
-
379  // Char Code ss->char_code);
-
380  // Language ss->lang);
-
381  break;
-
382  }
-
383  default:
-
384  {
-
385  Logging::error(path, "Unrecognised coding type %<%02x>1.", ss->coding_type);
-
386  break;
-
387  }
-
388  }
-
389 
-
390  return video;
-
391 }
-
392 
- -
402 {
-
403  return 0;
-
404 }
-
405 
- -
413 {
-
414  return 0;
-
415 }
-
416 
-
432 static bool create_bluray_virtualfile(BLURAY *bd, const BLURAY_TITLE_INFO* ti, const std::string & path, const struct stat * statbuf, void * buf, fuse_fill_dir_t filler, bool is_main_title, bool full_title, uint32_t title_idx, uint32_t chapter_idx)
-
433 {
-
434  BLURAY_CLIP_INFO *clip = &ti->clips[0];
-
435  BLURAY_TITLE_CHAPTER *chapter = &ti->chapters[chapter_idx];
-
436  std::string title_buf;
-
437  int64_t duration;
-
438 
-
439  if (full_title)
-
440  {
-
441  duration = static_cast<int64_t>(ti->duration) * AV_TIME_BASE / 90000;
-
442 
-
443  if (duration < AV_TIME_BASE)
-
444  {
-
445  Logging::trace(path, "Title %1: skipping empty title.", title_idx + 1);
-
446  return true;
-
447  }
-
448 
-
449  strsprintf(&title_buf, "%02u. Title [%s]%s.%s",
-
450  title_idx + 1,
-
451  replace_all(format_duration(duration), ":", "-").c_str(),
-
452  is_main_title ? "+" : "",
-
453  ffmpeg_format[0].fileext().c_str()); // can safely assume this is a video format
-
454  }
-
455  else
-
456  {
-
457  duration = static_cast<int64_t>(chapter->duration) * AV_TIME_BASE / 90000;
-
458 
-
459  if (duration < AV_TIME_BASE)
-
460  {
-
461  Logging::trace(path, "Title %1 Chapter %2: skipping empty chapter.", title_idx + 1, chapter_idx + 1);
-
462  return true;
-
463  }
-
464 
-
465  strsprintf(&title_buf, "%02u. Chapter %03u [%s]%s.%s",
-
466  title_idx + 1,
-
467  chapter_idx + 1,
-
468  replace_all(format_duration(duration), ":", "-").c_str(),
-
469  is_main_title ? "+" : "",
-
470  ffmpeg_format[0].fileext().c_str()); // can safely assume this is a video format
-
471 
-
472  }
-
473 
-
474  LPVIRTUALFILE virtualfile = nullptr;
-
475  if (!ffmpeg_format[0].is_multiformat())
-
476  {
-
477  virtualfile = insert_file(VIRTUALTYPE_BLURAY, path + title_buf, statbuf);
-
478  }
-
479  else
-
480  {
-
481  virtualfile = insert_dir(VIRTUALTYPE_BLURAY, path + title_buf, statbuf);
-
482  }
-
483 
-
484  if (virtualfile == nullptr)
-
485  {
-
486  Logging::error(path, "Failed to create virtual path: %1", (path + title_buf).c_str());
-
487  errno = EIO;
-
488  return false;
-
489  }
-
490 
-
491  if (add_fuse_entry(buf, filler, title_buf, &virtualfile->m_st, 0))
-
492  {
-
493  // break;
-
494  }
-
495 
-
496  // Blu-ray is video format anyway
-
497  virtualfile->m_format_idx = 0;
-
498  // Mark title/chapter/angle
-
499  virtualfile->m_full_title = full_title;
-
500  virtualfile->m_bluray.m_title_no = title_idx + 1;
-
501  virtualfile->m_bluray.m_playlist_no = ti->playlist;
-
502  virtualfile->m_bluray.m_chapter_no = chapter_idx + 1;
-
503  virtualfile->m_bluray.m_angle_no = 1;
-
504 
-
505  if (!transcoder_cached_filesize(virtualfile, &virtualfile->m_st))
-
506  {
-
507  BITRATE video_bit_rate = 29*1024*1024; // In case the real bitrate cannot be calculated later, assume 20 Mbit video bitrate
-
508  BITRATE audio_bit_rate = 256*1024; // In case the real bitrate cannot be calculated later, assume 256 kBit audio bitrate
-
509 
-
510  bool audio = false;
-
511 
-
512  bool interleaved = false;
-
513 
-
514  if (!bd_select_title(bd, title_idx))
-
515  {
-
516  Logging::error(path, "The Blu-ray title %1 could not be opened.", title_idx);
-
517  errno = EIO;
-
518  return false;
-
519  }
-
520 
-
521  uint64_t size = bd_get_title_size(bd);
-
522 
-
523  virtualfile->m_duration = duration;
-
524 
-
525  if (duration)
-
526  {
-
532  video_bit_rate = static_cast<BITRATE>(size * 8LL * AV_TIME_BASE / static_cast<uint64_t>(duration)); // calculate bitrate in bps
-
533  }
-
534 
-
535  // Get details
-
536  if (clip->audio_stream_count)
-
537  {
-
538  audio_stream_info(path, &clip->audio_streams[parse_find_best_audio_stream()], &virtualfile->m_channels, &virtualfile->m_sample_rate);
-
539  }
-
540  if (clip->video_stream_count)
-
541  {
-
542  audio = video_stream_info(path, &clip->video_streams[parse_find_best_video_stream()], &virtualfile->m_width, &virtualfile->m_height, &virtualfile->m_framerate, &interleaved);
-
543  }
-
544 
-
545  Logging::trace(path, "Video %1 %2x%3@%<%5.2f>4%5 fps %6 [%7]", format_bitrate(video_bit_rate).c_str(), virtualfile->m_width, virtualfile->m_height, av_q2d(virtualfile->m_framerate), interleaved ? "i" : "p", format_size(size).c_str(), format_duration(duration).c_str());
-
546  if (audio)
-
547  {
-
548  Logging::trace(path, "Audio %1 channels %2", virtualfile->m_channels, format_samplerate(virtualfile->m_sample_rate).c_str());
-
549  }
-
550 
-
551  transcoder_set_filesize(virtualfile, duration, audio_bit_rate, virtualfile->m_channels, virtualfile->m_sample_rate, AV_SAMPLE_FMT_NONE, video_bit_rate, virtualfile->m_width, virtualfile->m_height, interleaved, virtualfile->m_framerate);
-
552 
-
553  virtualfile->m_video_frame_count = static_cast<uint32_t>(av_rescale_q(duration, av_get_time_base_q(), av_inv_q(virtualfile->m_framerate)));
-
554  virtualfile->m_predicted_size = static_cast<size_t>(size);
-
555  }
-
556 
-
557  return true;
-
558 }
-
559 
-
568 static int parse_bluray(const std::string & path, const struct stat * statbuf, void * buf, fuse_fill_dir_t filler)
-
569 {
-
570  BLURAY *bd;
-
571  uint32_t title_count;
-
572  int main_title;
-
573  unsigned int seconds = 0;
-
574  uint8_t flags = TITLES_RELEVANT;
-
575  const char *bd_dir = nullptr;
-
576  bool success = true;
-
577 
-
578  bd_dir = path.c_str();
-
579 
-
580  Logging::debug(path, "Parsing Blu-ray.");
-
581 
-
582  bd = bd_open(bd_dir, nullptr);
-
583 
-
584  title_count = bd_get_titles(bd, flags, seconds);
-
585  main_title = bd_get_main_title(bd);
-
586  if (main_title >= 0)
-
587  {
-
588  Logging::trace(path, "Main title: %1", main_title + 1);
-
589  }
-
590 
-
591  for (uint32_t title_idx = 0; title_idx < title_count && success; title_idx++)
-
592  {
-
593  BLURAY_TITLE_INFO* ti = bd_get_title_info(bd, title_idx, 0);
-
594  bool is_main_title = (main_title >= 0 && title_idx == static_cast<uint32_t>(main_title));
-
595 
-
596  // Add separate chapters
-
597  for (uint32_t chapter_idx = 0; chapter_idx < ti->chapter_count && success; chapter_idx++)
-
598  {
-
599  success = create_bluray_virtualfile(bd, ti, path, statbuf, buf, filler, is_main_title, false, title_idx, chapter_idx);
-
600  }
-
601 
-
602  if (success && ti->chapter_count > 1)
-
603  {
-
604  // If more than 1 chapter, add full title as well
-
605  success = create_bluray_virtualfile(bd, ti, path, statbuf, buf, filler, is_main_title, true, title_idx, 0);
-
606  }
-
607 
-
608  bd_free_title_info(ti);
-
609  }
-
610 
-
611  bd_close(bd);
-
612 
-
613  if (success)
-
614  {
-
615  return static_cast<int>(title_count);
-
616  }
-
617  else
-
618  {
-
619  return -errno;
-
620  }
-
621 }
-
622 
-
623 int check_bluray(const std::string & path, void *buf, fuse_fill_dir_t filler)
-
624 {
-
625  std::string _path(path);
-
626  struct stat stbuf;
-
627  int res = 0;
-
628 
-
629  append_sep(&_path);
-
630 
-
631  if (stat((_path + "BDMV/index.bdmv").c_str(), &stbuf) == 0)
-
632  {
-
633  if (!check_path(_path))
-
634  {
-
635  Logging::trace(_path, "Blu-ray detected.");
-
636  res = parse_bluray(_path, &stbuf, buf, filler);
-
637  Logging::trace(_path, "%1 titles were discovered.", res);
-
638  }
-
639  else
-
640  {
-
641  res = load_path(_path, &stbuf, buf, filler);
-
642  }
-
643 
-
644  add_dotdot(buf, filler, &stbuf, 0);
-
645  }
-
646  return res;
-
647 }
-
648 
-
649 #endif // USE_LIBBLURAY
-
struct bluray BLURAY
Forward declaration of libbluray handle.
Definition: blurayio.h:43
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
22#ifdef USE_LIBBLURAY
+
23
+
34#include "ffmpegfs.h"
+
35#include "blurayparser.h"
+
36#include "transcode.h"
+
37#include "logging.h"
+
38
+
39#include "libbluray/bluray.h"
+
40#include "libbluray/bluray-version.h"
+
41
+
42extern "C" {
+
43#include <libavutil/rational.h>
+
44}
+
45
+
46static bool audio_stream_info(const std::string &path, BLURAY_STREAM_INFO *ss, int *channels, int *sample_rate);
+
47static bool video_stream_info(const std::string &path, BLURAY_STREAM_INFO *ss, int *width, int *height, AVRational *framerate, bool *interleaved);
+ + +
50static bool create_bluray_virtualfile(BLURAY *bd, const BLURAY_TITLE_INFO* ti, const std::string & path, const struct stat * statbuf, void * buf, fuse_fill_dir_t filler, bool is_main_title, bool full_title, uint32_t title_idx, uint32_t chapter_idx);
+
51static int parse_bluray(const std::string & path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler);
+
52
+
61static bool audio_stream_info(const std::string & path, BLURAY_STREAM_INFO *ss, int *channels, int *sample_rate)
+
62{
+
63 bool audio = false;
+
64
+
65 switch (ss->coding_type)
+
66 {
+
67 // Video
+
68 case 0x01:
+
69 case 0x02:
+
70 case 0xea:
+
71 case 0x1b:
+
72 case 0x24:
+
73 {
+
74 break;
+
75 }
+
76 // Audio
+
77 case 0x03:
+
78 case 0x04:
+
79 case 0x80:
+
80 case 0x81:
+
81 case 0x82:
+
82 case 0x83:
+
83 case 0x84:
+
84 case 0x85:
+
85 case 0x86:
+
86 case 0xa1:
+
87 case 0xa2:
+
88 {
+
89 switch (ss->format)
+
90 {
+
91 case BLURAY_AUDIO_FORMAT_MONO:
+
92 {
+
93 *channels = 1; // Mono
+
94 break;
+
95 }
+
96 case BLURAY_AUDIO_FORMAT_STEREO:
+
97 {
+
98 *channels = 2; // Stereo
+
99 break;
+
100 }
+
101 case BLURAY_AUDIO_FORMAT_MULTI_CHAN:
+
102 {
+
103 *channels = 2; // Multi Channel
+
104 break;
+
105 }
+
106 case BLURAY_AUDIO_FORMAT_COMBO:
+
107 {
+
108 *channels = 2; // Stereo ac3/dts
+
109 break;
+
110 }
+
111 default:
+
112 {
+
113 Logging::error(path, "Unknown number of audio channels %1. Assuming 2 channel/stereo - may be totally wrong.", ss->format);
+
114 *channels = 2; // Stereo
+
115 break;
+
116 }
+
117 }
+
118
+
119 switch (ss->rate)
+
120 {
+
121 case BLURAY_AUDIO_RATE_48:
+
122 {
+
123 *sample_rate = 48000;
+
124 break;
+
125 }
+
126 case BLURAY_AUDIO_RATE_96:
+
127 {
+
128 *sample_rate = 96000;
+
129 break;
+
130 }
+
131 case BLURAY_AUDIO_RATE_192:
+
132 {
+
133 *sample_rate = 192000;
+
134 break;
+
135 }
+
136 // 48 or 96 ac3/dts
+
137 // 192 mpl/dts-hd
+
138 case BLURAY_AUDIO_RATE_192_COMBO:
+
139 {
+
140 // *sample_rate = "48/192 Khz";
+
141 break;
+
142 }
+
143 // 48 ac3/dts
+
144 // 96 mpl/dts-hd
+
145 case BLURAY_AUDIO_RATE_96_COMBO:
+
146 {
+
147 // *sample_rate = "48/96 Khz";
+
148 break;
+
149 }
+
150 default:
+
151 {
+
152 Logging::error(path, "Unknown audio sample rate %1. Assuming 48 kHz - may be totally wrong.", ss->rate);
+
153 *sample_rate = 48000;
+
154 break;
+
155 }
+
156 }
+
157
+
158 audio = true;
+
159 break;
+
160 }
+
161 case 0x90:
+
162 case 0x91:
+
163 {
+
164 // Language ss->lang
+
165 break;
+
166 }
+
167 case 0x92:
+
168 {
+
169 // Char Code ss->char_code);
+
170 // Language ss->lang);
+
171 break;
+
172 }
+
173 default:
+
174 {
+
175 Logging::error(path, "Unrecognised coding type %<%02x>1.", ss->coding_type);
+
176 break;
+
177 }
+
178 }
+
179
+
180 return audio;
+
181}
+
182
+
193static bool video_stream_info(const std::string & path, BLURAY_STREAM_INFO *ss, int *width, int *height, AVRational *framerate, bool *interleaved)
+
194{
+
195 bool video = false;
+
196
+
197 switch (ss->coding_type)
+
198 {
+
199 // Video
+
200 case 0x01:
+
201 case 0x02:
+
202 case 0xea:
+
203 case 0x1b:
+
204 case 0x24:
+
205 {
+
206 // SD
+
207 // 720×480, 59.94i, 4:3 or 16:9
+
208
+
209 // 720×576, 50i, 4:3 or 16:9
+
210
+
211 // HD
+
212 // 1280×720, 59.94p, 16:9
+
213 // 1280×720, 50p, 16:9
+
214 // 1280×720, 24p, 16:9
+
215 // 1280×720, 23.976p, 16:9
+
216
+
217 // 1440×1080, 59.94i, 16:9
+
218 // 1440×1080, 50i, 16:9
+
219 // 1440×1080, 24p, 16:9
+
220 // 1440×1080, 23.976p, 16:9
+
221
+
222 // 1920×1080, 59.94i, 16:9
+
223 // 1920×1080, 50i, 16:9
+
224 // 1920×1080, 24p, 16:9
+
225 // 1920×1080, 23.976p, 16:9
+
226
+
227 // HD
+
228 // 1920×1080, 60p, 16:9
+
229 // 1920×1080, 59.94p, 16:9
+
230 // 1920×1080, 50p, 16:9
+
231 // 1920×1080, 25p, 16:9
+
232
+
233 // 4K UHD
+
234 // 3840×2160, 60p, 16:9
+
235 // 3840×2160, 59.94p, 16:9
+
236 // 3840×2160, 50p, 16:9
+
237 // 3840×2160, 25p, 16:9
+
238 // 3840×2160, 24p, 16:9
+
239 // 3840×2160, 23.976p, 16:9
+
240
+
241 switch (ss->format)
+
242 {
+
243 case BLURAY_VIDEO_FORMAT_480I: // ITU-R BT.601-5
+
244 {
+
245 *width = 720;
+
246 *height = 480;
+
247 *interleaved = true;
+
248 break;
+
249 }
+
250 case BLURAY_VIDEO_FORMAT_576I: // ITU-R BT.601-4
+
251 {
+
252 *width = 720;
+
253 *height = 576;
+
254 *interleaved = true;
+
255 break;
+
256 }
+
257 case BLURAY_VIDEO_FORMAT_480P: // SMPTE 293M
+
258 {
+
259 *width = 720;
+
260 *height = 480;
+
261 *interleaved = false;
+
262 break;
+
263 }
+
264 case BLURAY_VIDEO_FORMAT_1080I: // SMPTE 274M
+
265 {
+
266 *width = 1920;
+
267 *height = 1080;
+
268 *interleaved = true;
+
269 break;
+
270 }
+
271 case BLURAY_VIDEO_FORMAT_720P: // SMPTE 296M
+
272 {
+
273 *height = 1280;
+
274 *width = 720;
+
275 *interleaved = false;
+
276 break;
+
277 }
+
278 case BLURAY_VIDEO_FORMAT_1080P: // SMPTE 274M
+
279 {
+
280 *width = 1920;
+
281 *height = 1080;
+
282 *interleaved = false;
+
283 break;
+
284 }
+
285 case BLURAY_VIDEO_FORMAT_576P: // ITU-R BT.1358
+
286 {
+
287 *width = 720;
+
288 *height = 576;
+
289 *interleaved = false;
+
290 break;
+
291 }
+
292 // Added with libluray change 14aa7e9c0 (hpi1 2017-08-28 09:50:43 +0300)
+
293 // Available since version 1.1.0
+
294#if (BLURAY_VERSION_MAJOR > 1 || (BLURAY_VERSION_MAJOR == 1 && BLURAY_VERSION_MINOR >= 1))
+
295 case BLURAY_VIDEO_FORMAT_2160P: // UHD
+
296 {
+
297 *width = 3840;
+
298 *height = 2160;
+
299 *interleaved = false;
+
300 break;
+
301 }
+
302#endif
+
303 default:
+
304 {
+
305 Logging::error(path, "Unknown video format %1. Assuming 1920x1080P - may be totally wrong.", ss->format);
+
306 *width = 1920;
+
307 *height = 1080;
+
308 *interleaved = false;
+
309 break;
+
310 }
+
311 }
+
312
+
313 switch (ss->rate)
+
314 {
+
315 case BLURAY_VIDEO_RATE_24000_1001:
+
316 {
+
317 *framerate = av_make_q(24000, 1001);
+
318 break;
+
319 }
+
320 case BLURAY_VIDEO_RATE_24:
+
321 {
+
322 *framerate = av_make_q(24000, 1000);
+
323 break;
+
324 }
+
325 case BLURAY_VIDEO_RATE_25:
+
326 {
+
327 *framerate = av_make_q(25000, 1000);
+
328 break;
+
329 }
+
330 case BLURAY_VIDEO_RATE_30000_1001:
+
331 {
+
332 *framerate = av_make_q(30000, 1001);
+
333 break;
+
334 }
+
335 case BLURAY_VIDEO_RATE_50:
+
336 {
+
337 *framerate = av_make_q(50000, 1000);
+
338 break;
+
339 }
+
340 case BLURAY_VIDEO_RATE_60000_1001:
+
341 {
+
342 *framerate = av_make_q(60000, 1001);
+
343 break;
+
344 }
+
345 default:
+
346 {
+
347 Logging::error(path, "Unknown video frame rate %1. Assuming 25 fps - may be totally wrong.", ss->rate);
+
348 *framerate = av_make_q(25000, 1000);
+
349 break;
+
350 }
+
351 }
+
352
+
353 video = true;
+
354 break;
+
355 }
+
356 // Audio
+
357 case 0x03:
+
358 case 0x04:
+
359 case 0x80:
+
360 case 0x81:
+
361 case 0x82:
+
362 case 0x83:
+
363 case 0x84:
+
364 case 0x85:
+
365 case 0x86:
+
366 case 0xa1:
+
367 case 0xa2:
+
368 {
+
369 break;
+
370 }
+
371 case 0x90:
+
372 case 0x91:
+
373 {
+
374 // Language ss->lang
+
375 break;
+
376 }
+
377 case 0x92:
+
378 {
+
379 // Char Code ss->char_code);
+
380 // Language ss->lang);
+
381 break;
+
382 }
+
383 default:
+
384 {
+
385 Logging::error(path, "Unrecognised coding type %<%02x>1.", ss->coding_type);
+
386 break;
+
387 }
+
388 }
+
389
+
390 return video;
+
391}
+
392
+ +
402{
+
403 return 0;
+
404}
+
405
+ +
413{
+
414 return 0;
+
415}
+
416
+
432static bool create_bluray_virtualfile(BLURAY *bd, const BLURAY_TITLE_INFO* ti, const std::string & path, const struct stat * statbuf, void * buf, fuse_fill_dir_t filler, bool is_main_title, bool full_title, uint32_t title_idx, uint32_t chapter_idx)
+
433{
+
434 BLURAY_CLIP_INFO *clip = &ti->clips[0];
+
435 BLURAY_TITLE_CHAPTER *chapter = &ti->chapters[chapter_idx];
+
436 std::string title_buf;
+
437 int64_t duration;
+
438
+
439 if (full_title)
+
440 {
+
441 duration = static_cast<int64_t>(ti->duration) * AV_TIME_BASE / 90000;
+
442
+
443 if (duration < AV_TIME_BASE)
+
444 {
+
445 Logging::trace(path, "Title %1: skipping empty title.", title_idx + 1);
+
446 return true;
+
447 }
+
448
+
449 strsprintf(&title_buf, "%02u. Title [%s]%s.%s",
+
450 title_idx + 1,
+
451 replace_all(format_duration(duration), ":", "-").c_str(),
+
452 is_main_title ? "+" : "",
+
453 ffmpeg_format[0].fileext().c_str()); // can safely assume this is a video format
+
454 }
+
455 else
+
456 {
+
457 duration = static_cast<int64_t>(chapter->duration) * AV_TIME_BASE / 90000;
+
458
+
459 if (duration < AV_TIME_BASE)
+
460 {
+
461 Logging::trace(path, "Title %1 Chapter %2: skipping empty chapter.", title_idx + 1, chapter_idx + 1);
+
462 return true;
+
463 }
+
464
+
465 strsprintf(&title_buf, "%02u. Chapter %03u [%s]%s.%s",
+
466 title_idx + 1,
+
467 chapter_idx + 1,
+
468 replace_all(format_duration(duration), ":", "-").c_str(),
+
469 is_main_title ? "+" : "",
+
470 ffmpeg_format[0].fileext().c_str()); // can safely assume this is a video format
+
471
+
472 }
+
473
+
474 LPVIRTUALFILE virtualfile = nullptr;
+
475 if (!ffmpeg_format[0].is_multiformat())
+
476 {
+
477 virtualfile = insert_file(VIRTUALTYPE_BLURAY, path + title_buf, statbuf);
+
478 }
+
479 else
+
480 {
+
481 virtualfile = insert_dir(VIRTUALTYPE_BLURAY, path + title_buf, statbuf);
+
482 }
+
483
+
484 if (virtualfile == nullptr)
+
485 {
+
486 Logging::error(path, "Failed to create virtual path: %1", (path + title_buf).c_str());
+
487 errno = EIO;
+
488 return false;
+
489 }
+
490
+
491 if (add_fuse_entry(buf, filler, title_buf, &virtualfile->m_st, 0))
+
492 {
+
493 // break;
+
494 }
+
495
+
496 // Blu-ray is video format anyway
+
497 virtualfile->m_format_idx = 0;
+
498 // Mark title/chapter/angle
+
499 virtualfile->m_full_title = full_title;
+
500 virtualfile->m_bluray.m_title_no = title_idx + 1;
+
501 virtualfile->m_bluray.m_playlist_no = ti->playlist;
+
502 virtualfile->m_bluray.m_chapter_no = chapter_idx + 1;
+
503 virtualfile->m_bluray.m_angle_no = 1;
+
504
+
505 if (!transcoder_cached_filesize(virtualfile, &virtualfile->m_st))
+
506 {
+
507 BITRATE video_bit_rate = 29*1024*1024; // In case the real bitrate cannot be calculated later, assume 20 Mbit video bitrate
+
508 BITRATE audio_bit_rate = 256*1024; // In case the real bitrate cannot be calculated later, assume 256 kBit audio bitrate
+
509
+
510 bool audio = false;
+
511
+
512 bool interleaved = false;
+
513
+
514 if (!bd_select_title(bd, title_idx))
+
515 {
+
516 Logging::error(path, "The Blu-ray title %1 could not be opened.", title_idx);
+
517 errno = EIO;
+
518 return false;
+
519 }
+
520
+
521 uint64_t size = bd_get_title_size(bd);
+
522
+
523 virtualfile->m_duration = duration;
+
524
+
525 if (duration)
+
526 {
+
532 video_bit_rate = static_cast<BITRATE>(size * 8LL * AV_TIME_BASE / static_cast<uint64_t>(duration)); // calculate bitrate in bps
+
533 }
+
534
+
535 // Get details
+
536 if (clip->audio_stream_count)
+
537 {
+
538 audio_stream_info(path, &clip->audio_streams[parse_find_best_audio_stream()], &virtualfile->m_channels, &virtualfile->m_sample_rate);
+
539 }
+
540 if (clip->video_stream_count)
+
541 {
+
542 audio = video_stream_info(path, &clip->video_streams[parse_find_best_video_stream()], &virtualfile->m_width, &virtualfile->m_height, &virtualfile->m_framerate, &interleaved);
+
543 }
+
544
+
545 Logging::trace(path, "Video %1 %2x%3@%<%5.2f>4%5 fps %6 [%7]", format_bitrate(video_bit_rate).c_str(), virtualfile->m_width, virtualfile->m_height, av_q2d(virtualfile->m_framerate), interleaved ? "i" : "p", format_size(size).c_str(), format_duration(duration).c_str());
+
546 if (audio)
+
547 {
+
548 Logging::trace(path, "Audio %1 channels %2", virtualfile->m_channels, format_samplerate(virtualfile->m_sample_rate).c_str());
+
549 }
+
550
+
551 transcoder_set_filesize(virtualfile, duration, audio_bit_rate, virtualfile->m_channels, virtualfile->m_sample_rate, AV_SAMPLE_FMT_NONE, video_bit_rate, virtualfile->m_width, virtualfile->m_height, interleaved, virtualfile->m_framerate);
+
552
+
553 virtualfile->m_video_frame_count = static_cast<uint32_t>(av_rescale_q(duration, av_get_time_base_q(), av_inv_q(virtualfile->m_framerate)));
+
554 virtualfile->m_predicted_size = static_cast<size_t>(size);
+
555 }
+
556
+
557 return true;
+
558}
+
559
+
568static int parse_bluray(const std::string & path, const struct stat * statbuf, void * buf, fuse_fill_dir_t filler)
+
569{
+
570 BLURAY *bd;
+
571 uint32_t title_count;
+
572 int main_title;
+
573 unsigned int seconds = 0;
+
574 uint8_t flags = TITLES_RELEVANT;
+
575 const char *bd_dir = nullptr;
+
576 bool success = true;
+
577
+
578 bd_dir = path.c_str();
+
579
+
580 Logging::debug(path, "Parsing Blu-ray.");
+
581
+
582 bd = bd_open(bd_dir, nullptr);
+
583
+
584 title_count = bd_get_titles(bd, flags, seconds);
+
585 main_title = bd_get_main_title(bd);
+
586 if (main_title >= 0)
+
587 {
+
588 Logging::trace(path, "Main title: %1", main_title + 1);
+
589 }
+
590
+
591 for (uint32_t title_idx = 0; title_idx < title_count && success; title_idx++)
+
592 {
+
593 BLURAY_TITLE_INFO* ti = bd_get_title_info(bd, title_idx, 0);
+
594 bool is_main_title = (main_title >= 0 && title_idx == static_cast<uint32_t>(main_title));
+
595
+
596 // Add separate chapters
+
597 for (uint32_t chapter_idx = 0; chapter_idx < ti->chapter_count && success; chapter_idx++)
+
598 {
+
599 success = create_bluray_virtualfile(bd, ti, path, statbuf, buf, filler, is_main_title, false, title_idx, chapter_idx);
+
600 }
+
601
+
602 if (success && ti->chapter_count > 1)
+
603 {
+
604 // If more than 1 chapter, add full title as well
+
605 success = create_bluray_virtualfile(bd, ti, path, statbuf, buf, filler, is_main_title, true, title_idx, 0);
+
606 }
+
607
+
608 bd_free_title_info(ti);
+
609 }
+
610
+
611 bd_close(bd);
+
612
+
613 if (success)
+
614 {
+
615 return static_cast<int>(title_count);
+
616 }
+
617 else
+
618 {
+
619 return -errno;
+
620 }
+
621}
+
622
+
623int check_bluray(const std::string & path, void *buf, fuse_fill_dir_t filler)
+
624{
+
625 std::string _path(path);
+
626 struct stat stbuf;
+
627 int res = 0;
+
628
+
629 append_sep(&_path);
+
630
+
631 if (stat((_path + "BDMV/index.bdmv").c_str(), &stbuf) == 0)
+
632 {
+
633 if (!check_path(_path))
+
634 {
+
635 Logging::trace(_path, "Blu-ray detected.");
+
636 res = parse_bluray(_path, &stbuf, buf, filler);
+
637 Logging::trace(_path, "%1 titles were discovered.", res);
+
638 }
+
639 else
+
640 {
+
641 res = load_path(_path, &stbuf, buf, filler);
+
642 }
+
643
+
644 add_dotdot(buf, filler, &stbuf, 0);
+
645 }
+
646 return res;
+
647}
+
648
+
649#endif // USE_LIBBLURAY
+
struct bluray BLURAY
Forward declaration of libbluray handle.
Definition: blurayio.h:43
int check_bluray(const std::string &path, void *buf, fuse_fill_dir_t filler)
Get number of titles on Blu-ray.
static bool create_bluray_virtualfile(BLURAY *bd, const BLURAY_TITLE_INFO *ti, const std::string &path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler, bool is_main_title, bool full_title, uint32_t title_idx, uint32_t chapter_idx)
Create a virtual file entry of a Blu-ray chapter or title.
static int parse_bluray(const std::string &path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler)
Parse Blu-ray directory and get all Blu-ray titles and chapters as virtual files.
@@ -661,19 +660,19 @@
static void debug(const T filename, const std::string &format_string, Args &&...args)
Write debug level log entry.
Definition: logging.h:182
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
Definition: logging.h:163
static void error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
Definition: logging.h:239
-
std::string format_duration(int64_t value, uint32_t fracs)
Format a time in format HH:MM:SS.fract.
-
std::string format_samplerate(int value)
Format a samplerate.
-
std::string format_bitrate(BITRATE value)
Format a bit rate.
-
std::string format_size(uint64_t value)
Format size.
-
std::string replace_all(std::string str, const std::string &from, const std::string &to)
Same as std::string replace(), but replaces all occurrences.
-
const std::string & append_sep(std::string *path)
Add / to the path if required.
-
#define BITRATE
For FFmpeg bit rate is an int.
Definition: ffmpeg_utils.h:149
-
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
Definition: ffmpeg_utils.h:732
+
std::string format_duration(int64_t value, uint32_t fracs)
Format a time in format HH:MM:SS.fract.
+
std::string format_samplerate(int value)
Format a samplerate.
+
std::string format_bitrate(BITRATE value)
Format a bit rate.
+
const std::string & append_sep(std::string *path)
Add / to the path if required.
+
std::string format_size(uint64_t value)
Format size.
+
std::string replace_all(std::string str, const std::string &from, const std::string &to)
Same as std::string replace(), but replaces all occurrences.
+
#define BITRATE
For FFmpeg bit rate is an int.
Definition: ffmpeg_utils.h:145
+
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
Definition: ffmpeg_utils.h:728
FFMPEGFS_FORMAT_ARR ffmpeg_format
Two FFmpegfs_Format infos, 0: video file, 1: audio file.
Definition: ffmpegfs.cc:75
Main include for FFmpegfs project.
-
int add_dotdot(void *buf, fuse_fill_dir_t filler, const struct stat *stbuf, off_t off)
Make dot and double dot entries for a virtual directory.
Definition: fuseops.cc:2414
+
int add_dotdot(void *buf, fuse_fill_dir_t filler, const struct stat *stbuf, off_t off)
Make dot and double dot entries for a virtual directory.
Definition: fuseops.cc:2416
LPVIRTUALFILE insert_dir(VIRTUALTYPE type, const std::string &virtdir, const struct stat *stbuf, int flags=VIRTUALFLAG_NONE)
Add new virtual directory to the internal list. If the file already exists, it will be updated.
Definition: fuseops.cc:1717
-
int add_fuse_entry(void *buf, fuse_fill_dir_t filler, const std::string &name, const struct stat *stbuf, off_t off)
Wrapper to the Fuse filler function.
Definition: fuseops.cc:2404
+
int add_fuse_entry(void *buf, fuse_fill_dir_t filler, const std::string &name, const struct stat *stbuf, off_t off)
Wrapper to the Fuse filler function.
Definition: fuseops.cc:2406
int load_path(const std::string &path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler)
Load a path with virtual files for FUSE.
Definition: fuseops.cc:1759
bool check_path(const std::string &path)
Check if the path has already been parsed. Only useful if for DVD, Blu-ray or VCD where it is guarant...
Definition: fuseops.cc:1752
LPVIRTUALFILE insert_file(VIRTUALTYPE type, const std::string &virtfile, const struct stat *stbuf, int flags=VIRTUALFLAG_NONE)
Add new virtual file to internal list.
Definition: fuseops.cc:1638
@@ -691,7 +690,7 @@
int m_height
Video height - Filled in for the DVD/Blu-ray directory.
Definition: fileio.h:248
int m_channels
Audio channels - Filled in for the DVD/Blu-ray directory.
Definition: fileio.h:244
AVRational m_framerate
Video frame rate - Filled in for the DVD/Blu-ray directory.
Definition: fileio.h:249
-
struct stat m_st
stat structure with size etc.
Definition: fileio.h:151
+
struct stat m_st
stat structure with size etc.
Definition: fileio.h:151
struct VIRTUALFILE::BLURAY_CHAPTER m_bluray
Blu-ray title/chapter info.
size_t m_format_idx
Index into params.format[] array.
Definition: fileio.h:147
uint32_t m_video_frame_count
Number of frames in video or 0 if not a video.
Definition: fileio.h:156
@@ -702,7 +701,7 @@
diff --git a/html/blurayparser_8h.html b/html/blurayparser_8h.html index e4a6fea6f..e1f469ffd 100644 --- a/html/blurayparser_8h.html +++ b/html/blurayparser_8h.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/blurayparser.h File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
blurayparser.h File Reference
+
blurayparser.h File Reference
@@ -98,21 +97,21 @@

Go to the source code of this file.

-

+

Functions

int check_bluray (const std::string &path, void *buf=nullptr, fuse_fill_dir_t filler=nullptr)
 Get number of titles on Blu-ray. More...
 

Detailed Description

-

Blu-ray parser.

-

This is only available if built with -DUSE_LIBBLURAY parameter.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

Blu-ray parser.

+

This is only available if built with -DUSE_LIBBLURAY parameter.

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file blurayparser.h.

Function Documentation

- +

◆ check_bluray()

@@ -158,7 +157,7 @@

Definition at line 623 of file blurayparser.cc.

-

References add_dotdot(), append_sep(), check_path(), load_path(), parse_bluray(), and Logging::trace().

+

References add_dotdot(), append_sep(), check_path(), load_path(), parse_bluray(), and Logging::trace().

Referenced by ffmpegfs_getattr(), and ffmpegfs_readdir().

@@ -167,7 +166,7 @@

diff --git a/html/blurayparser_8h_source.html b/html/blurayparser_8h_source.html index 83619e497..b4bcec3de 100644 --- a/html/blurayparser_8h_source.html +++ b/html/blurayparser_8h_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/blurayparser.h Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
blurayparser.h
+
blurayparser.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2018-2023 by Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
34 #ifndef BLURAYPARSER_H
-
35 #define BLURAYPARSER_H
-
36 
-
37 #pragma once
-
38 
-
39 #ifdef USE_LIBBLURAY
-
40 
-
41 #include <string>
-
42 
-
51 int check_bluray(const std::string & path, void *buf = nullptr, fuse_fill_dir_t filler = nullptr);
-
52 
-
53 #endif // USE_LIBBLURAY
-
54 #endif // BLURAYPARSER_H
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2018-2023 by Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
34#ifndef BLURAYPARSER_H
+
35#define BLURAYPARSER_H
+
36
+
37#pragma once
+
38
+
39#ifdef USE_LIBBLURAY
+
40
+
41#include <string>
+
42
+
51int check_bluray(const std::string & path, void *buf = nullptr, fuse_fill_dir_t filler = nullptr);
+
52
+
53#endif // USE_LIBBLURAY
+
54#endif // BLURAYPARSER_H
int check_bluray(const std::string &path, void *buf=nullptr, fuse_fill_dir_t filler=nullptr)
Get number of titles on Blu-ray.
diff --git a/html/buffer_8cc.html b/html/buffer_8cc.html index a2fda8388..8e4ba9f53 100644 --- a/html/buffer_8cc.html +++ b/html/buffer_8cc.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/buffer.cc File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
buffer.cc File Reference
+
buffer.cc File Reference
@@ -118,15 +117,15 @@

Go to the source code of this file.

Detailed Description

-

Buffer class implementation.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

Buffer class implementation.

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file buffer.cc.

diff --git a/html/buffer_8cc__incl.png b/html/buffer_8cc__incl.png index 95c5e6a5e8b1d5d80dacc29604f89186fd39e7d0..6e0dd98fdb864d907119d35fcfe9e3e3eaa71f91 100644 GIT binary patch literal 63391 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 literal 63391 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Ð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 - - + + FFmpegfs Fuse Multi Media Filesystem: src/buffer.cc Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
buffer.cc
+
buffer.cc
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
32 #include "buffer.h"
-
33 #include "ffmpegfs.h"
-
34 #include "logging.h"
-
35 
-
36 #include <unistd.h>
-
37 #include <sys/mman.h>
-
38 #include <libgen.h>
-
39 #include <cstring>
-
40 
-
41 // Initially Buffer is empty. It will be allocated as needed.
- -
43  : m_cur_ci(nullptr)
-
44  , m_cur_open(0)
-
45 {
-
46 }
-
47 
-
48 // If buffer_data was never allocated, this is a no-op.
- -
50 {
-
51  release();
-
52 }
-
53 
- -
55 {
-
56  return VIRTUALTYPE_BUFFER;
-
57 }
-
58 
-
59 size_t Buffer::bufsize() const
-
60 {
-
61  return 0; // Not applicable
-
62 }
-
63 
-
64 int Buffer::openio(LPVIRTUALFILE virtualfile)
-
65 {
-
66  if (virtualfile == nullptr)
-
67  {
-
68  errno = EINVAL;
-
69  return (EOF);
-
70  }
-
71 
- -
73 
-
74  return 0;
-
75 }
-
76 
-
77 bool Buffer::open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize)
-
78 {
-
79  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
80 
-
81  uint32_t index = segment_no;
-
82  if (index)
-
83  {
-
84  index--;
-
85  }
-
86 
-
87  CACHEINFO & ci = m_ci[index];
-
88 
-
89  ci.m_flags |= flags;
-
90 
-
91  if (ci.m_fd != -1)
-
92  {
-
93  Logging::trace(ci.m_cachefile, "Cache file is already open.");
-
94 
-
95  if (defaultsize)
-
96  {
-
97  // Make sure the requested size is available
-
98  reserve(defaultsize);
-
99  }
-
100  // Already open
-
101  return true;
-
102  }
-
103 
-
104  if (flags & CACHE_FLAG_RW)
-
105  {
-
106  Logging::debug(ci.m_cachefile, "Writing to cache file.");
-
107  }
-
108  else
-
109  {
-
110  Logging::debug(ci.m_cachefile, "Reading from cache file.");
-
111  }
-
112 
-
113  size_t filesize = 0;
-
114  bool isdefaultsize = false;
-
115  uint8_t *p = nullptr;
-
116 
-
117  if (!map_file(ci.m_cachefile, &ci.m_fd, &p, &filesize, &isdefaultsize, defaultsize, (flags & CACHE_FLAG_RW) ? true : false))
-
118  {
-
119  return false;
-
120  }
-
121 
-
122  if (!isdefaultsize)
-
123  {
-
124  ci.m_buffer_pos = ci.m_buffer_watermark = filesize;
-
125  }
-
126 
-
127  ci.m_buffer_size = filesize;
-
128  ci.m_buffer = static_cast<uint8_t*>(p);
-
129  ci.m_buffer_write_size = 0;
-
130  ci.m_buffer_writes = 0;
-
131 
-
132  ++m_cur_open; // track open files
-
133 
-
134  return true;
-
135 }
-
136 
-
137 bool Buffer::close_file(uint32_t segment_no, uint32_t flags)
-
138 {
-
139  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
140 
-
141  uint32_t index = segment_no;
-
142  if (index)
-
143  {
-
144  index--;
-
145  }
-
146 
-
147  CACHEINFO & ci = m_ci[index];
-
148 
-
149  ci.m_flags &= ~flags;
-
150 
-
151  if (ci.m_flags)
-
152  {
-
153  Logging::trace(ci.m_cachefile, "While attempting to close, the cache file is still in use. Currently open: %1", m_cur_open);
-
154  return true;
-
155  }
-
156 
-
157  if (ci.m_fd == -1)
-
158  {
-
159  // Already closed
-
160  Logging::trace(ci.m_cachefile, "No need to close the unopened cache file. Currently open: %1", m_cur_open);
-
161  return true;
-
162  }
-
163 
-
164  Logging::trace(ci.m_cachefile, "Closing cache file.");
-
165 
-
166  bool success = unmap_file(ci.m_cachefile, &ci.m_fd, &ci.m_buffer, ci.m_buffer_size, &ci.m_buffer_watermark);
-
167 
-
168  ci.m_buffer_pos = 0;
-
169  ci.m_buffer_size = 0;
-
170 
-
171  if (success && m_cur_open > 0)
-
172  {
-
173  --m_cur_open; // track open files
-
174  }
-
175 
-
176  return success;
-
177 }
-
178 
-
179 bool Buffer::init(bool erase_cache)
-
180 {
-
181  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
182 
-
183  if (is_open())
-
184  {
-
185  return true;
-
186  }
-
187 
-
188  bool success = true;
-
189 
-
190  try
-
191  {
-
192  if ((virtualfile()->m_flags & VIRTUALFLAG_HLS))
-
193  {
-
194  // HLS format: create several segments
-
195  if (virtualfile()->get_segment_count())
-
196  {
-
197  m_ci.resize(virtualfile()->get_segment_count());
-
198 
-
199  for (uint32_t segment_no = 1; segment_no <= virtualfile()->get_segment_count(); segment_no++)
-
200  {
-
201  make_cachefile_name(m_ci[segment_no - 1].m_cachefile, filename() + "." + make_filename(segment_no, params.current_format(virtualfile())->fileext()), params.current_format(virtualfile())->fileext(), false);
-
202  }
-
203  }
-
204  else
-
205  {
-
206  Logging::error(filename(), "INTERNAL ERROR: Buffer::init()! Segment count is 0.");
-
207  errno = EINVAL;
-
208  throw false;
-
209  }
-
210  }
-
211  else
-
212  {
-
213  // All other formats: create just a single segment.
-
214  m_ci.resize(1);
-
215 
-
216  make_cachefile_name(m_ci[0].m_cachefile, filename(), params.current_format(virtualfile())->fileext(), false);
-
217  if ((virtualfile()->m_flags & VIRTUALFLAG_FRAME))
-
218  {
-
219  // Create extra index cash for frame sets only
-
220  make_cachefile_name(m_ci[0].m_cachefile_idx, filename(), params.current_format(virtualfile())->fileext(), true);
-
221  }
-
222  }
-
223 
-
224  // Set current segment
-
225  m_cur_ci = &m_ci[0];
-
226 
-
227  // Create the path to the cache file. All paths are the same, so this is required only once.
-
228  char *cachefile = new_strdup(m_ci[0].m_cachefile);
-
229 
-
230  if (cachefile == nullptr)
-
231  {
-
232  Logging::error(m_ci[0].m_cachefile, "Error opening the cache file: out of memory.");
-
233  errno = ENOMEM;
-
234  throw false;
-
235  }
-
236 
-
237  if (mktree(dirname(cachefile), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) && errno != EEXIST)
-
238  {
-
239  Logging::error(m_ci[0].m_cachefile, "Error creating cache directory: (%1) %2", errno, strerror(errno));
-
240  delete [] cachefile;
-
241  throw false;
-
242  }
-
243  errno = 0; // reset EEXIST, error can safely be ignored here
-
244 
-
245  delete [] cachefile;
-
246 
-
247 #if __cplusplus >= 202002L
-
248  // C++20 (and later) code
-
249  for (uint32_t index = 0; CACHEINFO & ci : m_ci)
-
250 #else
-
251  uint32_t index = 0;
-
252  for (CACHEINFO & ci : m_ci)
-
253 #endif
-
254  {
-
255  ci.reset();
-
256 
-
257  if (erase_cache)
-
258  {
-
259  remove_cachefile(index + 1);
-
260  errno = 0; // ignore this error
-
261  }
-
262 
-
263  index++;
-
264  }
-
265 
-
266  // Index only required for frame sets and there is only one.
-
267  if (!m_ci[0].m_cachefile_idx.empty())
-
268  {
-
269  if (virtualfile()->m_video_frame_count == 0)
-
270  {
-
271  errno = EINVAL;
-
272  Logging::error(m_ci[0].m_cachefile, "INTERNAL ERROR: Buffer::init()! Frame count is zero (%1) %2", errno, strerror(errno));
-
273  throw false;
-
274  }
-
275  static_assert(sizeof(IMAGE_FRAME) == 32, "sizeof(IMAGE_FRAME) must be 32 bytes");
-
276 
-
277  size_t filesize = 0;
-
278  bool isdefaultsize = false;
-
279  uint8_t *p = nullptr;
-
280 
-
281  if (!map_file(m_ci[0].m_cachefile_idx, &m_ci[0].m_fd_idx, &p, &filesize, &isdefaultsize, sizeof(IMAGE_FRAME) * virtualfile()->m_video_frame_count, false))
-
282  {
-
283  throw false;
-
284  }
-
285 
-
286  m_ci[0].m_buffer_size_idx = filesize;
-
287  m_ci[0].m_buffer_idx = static_cast<uint8_t*>(p);
-
288  }
-
289  }
-
290  catch (bool _success)
-
291  {
-
292  success = _success;
-
293 
-
294  if (!success)
-
295  {
-
296  for (CACHEINFO & ci : m_ci)
-
297  {
-
298  ci.reset();
-
299  }
-
300  }
-
301  }
-
302 
-
303  return success;
-
304 }
-
305 
-
306 bool Buffer::set_segment(uint32_t segment_no, size_t size)
-
307 {
-
308  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
309 
-
310  if (!segment_no || segment_no > segment_count())
-
311  {
-
312  errno = EINVAL;
-
313  return false;
-
314  }
-
315 
- -
317  {
-
318  return false;
-
319  }
-
320 
-
321  if (!open_file(segment_no, CACHE_FLAG_RW, size))
-
322  {
-
323  return false;
-
324  }
-
325 
-
326  m_cur_ci = &m_ci[segment_no - 1];
-
327 
-
328  // Reserve enough buffer space for segment to avoid frequent resizes
-
329  return reserve(size);
-
330 }
-
331 
- -
333 {
-
334  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
335 
-
336  return static_cast<uint32_t>(m_ci.size());
-
337 }
-
338 
- -
340 {
-
341  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
342 
-
343  if (!segment_count() || m_cur_ci == nullptr)
-
344  {
-
345  return 0;
-
346  }
-
347  return static_cast<uint32_t>(m_cur_ci - &m_ci[0]) + 1;
-
348 }
-
349 
-
350 bool Buffer::segment_exists(uint32_t segment_no)
-
351 {
-
352  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
353 
-
354  if (!segment_count() || m_cur_ci == nullptr)
-
355  {
-
356  return false;
-
357  }
-
358  return file_exists(m_ci[segment_no - 1].m_cachefile);
-
359 }
-
360 
-
361 bool Buffer::map_file(const std::string & filename, volatile int *fd, uint8_t **p, size_t *filesize, bool *isdefaultsize, size_t defaultsize, bool truncate) const
-
362 {
-
363  bool success = true;
-
364 
-
365  if (!defaultsize)
-
366  {
-
367  Logging::trace(filename, "Mapping cache file.");
-
368  }
-
369  else
-
370  {
-
371  Logging::trace(filename, "Mapping cache file with %1.", format_size(defaultsize).c_str());
-
372  }
-
373 
-
374  try
-
375  {
-
376  struct stat sb;
-
377 
-
378  *fd = ::open(filename.c_str(), O_CREAT | O_RDWR | (truncate ? O_TRUNC : 0), static_cast<mode_t>(0644));
-
379  if (*fd == -1)
-
380  {
-
381  Logging::error(filename, "The cache file could not be opened due to an error: (%1) %2", errno, strerror(errno));
-
382  throw false;
-
383  }
-
384 
-
385  if (fstat(*fd, &sb) == -1)
-
386  {
-
387  Logging::error(filename, "File stat failed: (%1) %2 (fd = %3)", errno, strerror(errno), *fd);
-
388  throw false;
-
389  }
-
390 
-
391  if (!S_ISREG(sb.st_mode))
-
392  {
-
393  Logging::error(filename, "Not a file.");
-
394  throw false;
-
395  }
-
396 
-
397  if (!sb.st_size || defaultsize)
-
398  {
-
399  // If file is empty or did not exist set file size to default
-
400 
-
401  if (!defaultsize)
-
402  {
-
403  defaultsize = static_cast<size_t>(sysconf(_SC_PAGESIZE));
-
404  }
-
405 
-
406  if (ftruncate(*fd, static_cast<off_t>(defaultsize)) == -1)
-
407  {
-
408  Logging::error(filename, "Error calling ftruncate() to 'stretch' the file: (%1) %2 (fd = %3)", errno, strerror(errno), *fd);
-
409  throw false;
-
410  }
-
411 
-
412  *filesize = defaultsize;
-
413  *isdefaultsize = true;
-
414  }
-
415  else
-
416  {
-
417  // Keep size
-
418  *filesize = static_cast<size_t>(sb.st_size);
-
419  *isdefaultsize = false;
-
420  }
-
421 
-
422  *p = static_cast<uint8_t *>(mmap(nullptr, *filesize, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0));
-
423  if (*p == MAP_FAILED)
-
424  {
-
425  Logging::error(filename, "File mapping failed: (%1) %2 (fd = %3)", errno, strerror(errno), *fd);
-
426  *p = nullptr;
-
427  throw false;
-
428  }
-
429  }
-
430  catch (bool _success)
-
431  {
-
432  success = _success;
-
433 
-
434  if (!success && *fd != -1)
-
435  {
-
436  ::close(*fd);
-
437  *fd = -1;
-
438  }
-
439  }
-
440 
-
441  return success;
-
442 }
-
443 
-
444 bool Buffer::unmap_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t len, size_t * filesize) const
-
445 {
-
446  bool success = true;
-
447 
-
448  Logging::trace(filename, "Unmapping cache file.");
-
449 
-
450  void * _p = *p;
-
451  size_t _filesize = *filesize;
-
452  int _fd = *fd;
-
453 
-
454  // Clear all variables
-
455  *p = nullptr;
-
456  *filesize = 0;
-
457  *fd = -1;
-
458 
-
459  if (_p != nullptr)
-
460  {
-
461  if (munmap(_p, len ? len : static_cast<size_t>(sysconf(_SC_PAGESIZE))) == -1) // Make sure we do not unmap a zero size file (spits EINVAL error)
-
462  {
-
463  Logging::error(filename, "Unmapping cache file failed: (%1) %2 Size: %3", errno, strerror(errno), len);
-
464  success = false;
-
465  }
-
466  }
-
467 
-
468  if (_fd != -1)
-
469  {
-
470  if (_filesize)
-
471  {
-
472  if (ftruncate(_fd, static_cast<off_t>(_filesize)) == -1)
-
473  {
-
474  Logging::error(filename, "Error calling ftruncate() to resize and close the cache file: (%1) %2 (fd = %3) Size: %5", errno, strerror(errno), _fd, _filesize);
-
475  success = false;
-
476  }
-
477  ::close(_fd);
-
478  }
-
479  else
-
480  {
-
481  ::close(_fd);
-
482 
-
483  if (unlink(filename.c_str()) && errno != ENOENT) // Ignore if file does not exist
-
484  {
-
485  Logging::error(filename, "Error removing the cache file: (%1) %2 (fd = %3)", errno, strerror(errno), _fd);
-
486  success = false;
-
487  }
-
488  }
-
489  }
-
490 
-
491  return success;
-
492 }
-
493 
-
494 bool Buffer::release(int flags /*= CACHE_CLOSE_NOOPT*/)
-
495 {
-
496  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
497 
-
498  bool success = true;
-
499 
-
500  if (!is_open())
-
501  {
- -
503  {
-
504  for (uint32_t n = 1; n <= segment_count(); n++)
-
505  {
-
506  remove_cachefile(n);
-
507  }
-
508  errno = 0; // ignore this error
-
509  }
-
510 
-
511  return true;
-
512  }
-
513 
-
514  // Write active cache to disk
-
515  flush();
-
516 
-
517  // Close anything that's still open
-
518  for (uint32_t index = 0; index < segment_count(); index++)
-
519  {
-
520  if (!close_file(index + 1, CACHE_FLAG_RO | CACHE_FLAG_RW))
-
521  {
-
522  success = false;
-
523  }
-
524 
- -
526  {
-
527  remove_cachefile(index + 1);
-
528  errno = 0; // ignore this error
-
529  }
-
530  }
-
531 
-
532  // Remove index for frame sets. There is only one.
-
533  if (!m_ci[0].m_cachefile_idx.empty())
-
534  {
-
535  if (!unmap_file(m_ci[0].m_cachefile_idx, &m_ci[0].m_fd_idx, &m_ci[0].m_buffer_idx, m_ci[0].m_buffer_size_idx, &m_ci[0].m_buffer_size_idx))
-
536  {
-
537  success = false;
-
538  }
-
539  }
-
540 
-
541  return success;
-
542 }
-
543 
-
544 bool Buffer::remove_cachefile(uint32_t segment_no) const
-
545 {
-
546  const CACHEINFO & ci = !segment_no ? *m_cur_ci : m_ci[segment_no - 1];
-
547  bool success = remove_file(ci.m_cachefile);
-
548 
-
549  if (!ci.m_cachefile_idx.empty())
-
550  {
-
551  if (!remove_file(ci.m_cachefile_idx))
-
552  {
-
553  success = false;
-
554  }
-
555  }
-
556  return success;
-
557 }
-
558 
- -
560 {
-
561  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
562 
-
563  if (!segment_count() || m_cur_ci == nullptr || m_cur_ci->m_buffer == nullptr)
-
564  {
-
565  errno = EPERM;
-
566  return false;
-
567  }
-
568 
-
569  if (msync(m_cur_ci->m_buffer, m_cur_ci->m_buffer_size, MS_SYNC) == -1)
-
570  {
-
571  Logging::error(m_cur_ci->m_cachefile, "Could not sync to disk: (%1) %2", errno, strerror(errno));
-
572  return false;
-
573  }
-
574 
-
575  if (m_cur_ci->m_buffer_idx != nullptr)
-
576  {
-
577  if (msync(m_cur_ci->m_buffer_idx, m_cur_ci->m_buffer_size_idx, MS_SYNC) == -1)
-
578  {
-
579  Logging::error(m_cur_ci->m_cachefile_idx, "Could not sync to disk: (%1) %2", errno, strerror(errno));
-
580  return false;
-
581  }
-
582  }
-
583 
-
584  return true;
-
585 }
-
586 
- -
588 {
-
589  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
590 
-
591  bool success = true;
-
592 
-
593  for (CACHEINFO & ci : m_ci)
-
594  {
-
595  ci.m_buffer_pos = 0;
-
596  ci.m_buffer_watermark = 0;
-
597  ci.m_buffer_size = 0;
-
598  ci.m_seg_finished = false;
-
599  ci.m_buffer_write_size = 0;
-
600  ci.m_buffer_writes = 0;
-
601 
-
602  if (ci.m_fd != -1)
-
603  {
-
604  // If empty set file size to 1 page
-
605  long filesize = sysconf(_SC_PAGESIZE);
-
606 
-
607  if (ftruncate(ci.m_fd, filesize) == -1)
-
608  {
-
609  Logging::error(ci.m_cachefile, "Error calling ftruncate() to clear the file: (%1) %2 (fd = %3)", errno, strerror(errno), ci.m_fd);
-
610  success = false;
-
611  }
-
612  }
-
613  else
-
614  {
-
615  remove_file(ci.m_cachefile);
-
616  }
-
617 
-
618  if (ci.m_fd_idx != -1)
-
619  {
-
620  std::memset(ci.m_buffer_idx, 0, ci.m_buffer_size_idx);
-
621  }
-
622  }
-
623 
-
624  return success;
-
625 }
-
626 
-
627 bool Buffer::reserve(size_t size)
-
628 {
-
629  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
630 
-
631  if (m_cur_ci == nullptr || m_cur_ci->m_buffer == nullptr)
-
632  {
-
633  errno = ENOMEM;
-
634  Logging::error(nullptr, "INTERNAL ERROR: Buffer::reserve()!");
-
635  return false;
-
636  }
-
637 
-
638  if (m_cur_ci->m_buffer_size >= size)
-
639  {
-
640  // Do not shrink
-
641  return true;
-
642  }
-
643 
-
644  m_cur_ci->m_buffer = static_cast<uint8_t*>(mremap(m_cur_ci->m_buffer, m_cur_ci->m_buffer_size, size, MREMAP_MAYMOVE));
-
645  if (m_cur_ci->m_buffer == MAP_FAILED)
-
646  {
-
647  Logging::error(m_cur_ci->m_cachefile, "Error calling mremap() to resize the file: (%1) %2 (fd = %3) Old size: %4 New: %5", errno, strerror(errno), m_cur_ci->m_fd, m_cur_ci->m_buffer_size, size);
-
648  m_cur_ci->m_buffer = nullptr;
-
649  return false;
-
650  }
-
651 
-
652  // Save size
- -
654 
-
655  if (ftruncate(m_cur_ci->m_fd, static_cast<off_t>(m_cur_ci->m_buffer_size)) == -1)
-
656  {
-
657  Logging::error(m_cur_ci->m_cachefile, "Error calling ftruncate() to resize the file: (%1) %2 (fd = %3)", errno, strerror(errno), m_cur_ci->m_fd);
-
658  return false;
-
659  }
-
660 
-
661  return true;
-
662 }
-
663 
-
664 size_t Buffer::writeio(const uint8_t* data, size_t length)
-
665 {
-
666  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
667 
-
668  if (m_cur_ci == nullptr || m_cur_ci->m_buffer == nullptr)
-
669  {
-
670  errno = ENOMEM;
-
671  return 0;
-
672  }
-
673 
-
674  uint8_t* write_ptr = write_prepare(length);
-
675  if (write_ptr == nullptr)
-
676  {
-
677  length = 0;
-
678  }
-
679  else
-
680  {
-
681  m_cur_ci->m_buffer_write_size += length;
- -
683 
-
684  std::memcpy(write_ptr, data, length);
-
685  increment_pos(length);
-
686  }
-
687 
-
688  return length;
-
689 }
-
690 
-
691 size_t Buffer::write_frame(const uint8_t *data, size_t length, uint32_t frame_no)
-
692 {
-
693  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
694 
-
695  if (data == nullptr || m_cur_ci == nullptr || m_cur_ci->m_buffer_idx == nullptr || frame_no < 1 || frame_no > virtualfile()->m_video_frame_count)
-
696  {
-
697  // Invalid parameter
-
698  errno = EINVAL;
-
699  return 0;
-
700  }
-
701 
-
702  LPIMAGE_FRAME old_image_frame;
-
703  IMAGE_FRAME new_image_frame;
-
704  size_t bytes_written;
-
705  size_t start = static_cast<size_t>(frame_no - 1) * sizeof(IMAGE_FRAME);
-
706 
-
707  old_image_frame = reinterpret_cast<LPIMAGE_FRAME>(m_cur_ci->m_buffer_idx + start);
-
708 
-
709  if (old_image_frame->m_frame_no && (old_image_frame->m_size <= static_cast<uint32_t>(length)))
-
710  {
-
711  // Frame already exists and has enough space
-
712  old_image_frame->m_size = static_cast<uint32_t>(length);
-
713 
-
714  // Write image
-
715  seek(static_cast<long>(old_image_frame->m_offset), SEEK_SET);
-
716  bytes_written = writeio(data, old_image_frame->m_size);
-
717  if (bytes_written != old_image_frame->m_size)
-
718  {
-
719  return 0;
-
720  }
-
721  }
-
722  else
-
723  {
-
724  // Create new frame if not existing or not enough space
-
725  std::memset(&new_image_frame, 0xFF, sizeof(new_image_frame));
-
726  std::memcpy(new_image_frame.m_tag, IMAGE_FRAME_TAG, sizeof(new_image_frame.m_tag));
-
727  new_image_frame.m_frame_no = frame_no;
-
728  new_image_frame.m_offset = buffer_watermark();
-
729  new_image_frame.m_size = static_cast<uint32_t>(length);
-
730 
-
731  // Write image
-
732  seek(static_cast<long>(new_image_frame.m_offset), SEEK_SET);
-
733  bytes_written = writeio(data, new_image_frame.m_size);
-
734  if (bytes_written != new_image_frame.m_size)
-
735  {
-
736  return 0;
-
737  }
-
738 
-
739  std::memcpy(reinterpret_cast<void *>(m_cur_ci->m_buffer_idx + start), &new_image_frame, sizeof(IMAGE_FRAME));
-
740  }
-
741 
-
742  return bytes_written;
-
743 }
-
744 
-
745 uint8_t* Buffer::write_prepare(size_t length)
-
746 {
-
747  if (reallocate(m_cur_ci->m_buffer_pos + length))
-
748  {
- -
750  {
- -
752  }
- -
754  }
-
755  else
-
756  {
-
757  errno = ESPIPE;
-
758  return nullptr;
-
759  }
-
760 }
-
761 
-
762 void Buffer::increment_pos(size_t increment)
-
763 {
-
764  m_cur_ci->m_buffer_pos += increment;
-
765 }
-
766 
-
767 int Buffer::seek(int64_t offset, int whence)
-
768 {
-
769  return seek(offset, whence, 0);
-
770 }
-
771 
-
772 int Buffer::seek(int64_t offset, int whence, uint32_t segment_no)
-
773 {
-
774  LPCACHEINFO ci = cacheinfo(segment_no);
-
775 
-
776  if (ci == nullptr || ci->m_buffer == nullptr)
-
777  {
-
778  errno = ENOMEM;
-
779  return (EOF);
-
780  }
-
781 
-
782  off_t seek_pos;
-
783 
-
784  switch (whence)
-
785  {
-
786  case SEEK_SET:
-
787  {
-
788  seek_pos = offset;
-
789  break;
-
790  }
-
791  case SEEK_CUR:
-
792  {
-
793  seek_pos = static_cast<off_t>(tell(segment_no)) + offset;
-
794  break;
-
795  }
-
796  case SEEK_END:
-
797  {
-
798  seek_pos = static_cast<off_t>(size(segment_no)) + offset;
-
799  break;
-
800  }
-
801  default:
-
802  {
-
803  errno = EINVAL;
-
804  return (EOF);
-
805  }
-
806  }
-
807 
-
808  if (seek_pos > static_cast<off_t>(size(segment_no)))
-
809  {
-
810  ci->m_buffer_pos = size(segment_no); // Cannot go beyond EOF. Set position to end, leave errno untouched.
-
811  return 0;
-
812  }
-
813 
-
814  if (seek_pos < 0) // Cannot go before head, leave position untouched, set errno.
-
815  {
-
816  errno = EINVAL;
-
817  return (EOF);
-
818  }
-
819 
-
820  ci->m_buffer_pos = static_cast<size_t>(seek_pos);
-
821  return 0;
-
822 }
-
823 
-
824 size_t Buffer::tell() const
-
825 {
-
826  return tell(0);
-
827 }
-
828 
-
829 size_t Buffer::tell(uint32_t segment_no) const
-
830 {
-
831  LPCCACHEINFO ci = const_cacheinfo(segment_no);
-
832 
-
833  if (ci == nullptr)
-
834  {
-
835  errno = EBADF;
-
836  return 0;
-
837  }
-
838 
-
839  return ci->m_buffer_pos;
-
840 }
-
841 
-
842 int64_t Buffer::duration() const
-
843 {
-
844  return AV_NOPTS_VALUE; // not applicable
-
845 }
-
846 
-
847 size_t Buffer::size() const
-
848 {
-
849  return size(0);
-
850 }
-
851 
-
852 size_t Buffer::size(uint32_t segment_no) const
-
853 {
-
854  LPCCACHEINFO ci = const_cacheinfo(segment_no);
-
855 
-
856  if (ci == nullptr)
-
857  {
-
858  errno = EBADF;
-
859  return 0;
-
860  }
-
861 
-
862  return ci->m_buffer_size;
-
863 }
-
864 
-
865 size_t Buffer::buffer_watermark(uint32_t segment_no) const
-
866 {
-
867  LPCCACHEINFO ci = const_cacheinfo(segment_no);
-
868 
-
869  if (ci == nullptr)
-
870  {
-
871  errno = EBADF;
-
872  return 0;
-
873  }
-
874 
-
875  return ci->m_buffer_watermark;
-
876 }
-
877 
-
878 bool Buffer::copy(std::vector<uint8_t> * out_data, size_t offset, uint32_t segment_no)
-
879 {
-
880  return copy(out_data->data(), offset, out_data->size(), segment_no);
-
881 }
-
882 
-
883 bool Buffer::copy(uint8_t* out_data, size_t offset, size_t bufsize, uint32_t segment_no)
-
884 {
-
885  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
886 
-
887  LPCCACHEINFO ci = const_cacheinfo(segment_no);
-
888 
-
889  if (ci == nullptr)
-
890  {
-
891  errno = EBADF;
-
892  return false;
-
893  }
-
894 
-
895  if (ci->m_buffer == nullptr)
-
896  {
-
897  errno = ENOMEM;
-
898  return false;
-
899  }
-
900 
-
901  size_t segment_size = ci->m_buffer_size;
-
902 
-
903  if (!segment_size && errno)
-
904  {
-
905  Logging::error(ci->m_cachefile, "INTERNAL ERROR: Buffer::copy()! size(segment_no) returned error. Segment: %1 (%2) %3", segment_no, errno, strerror(errno));
-
906  return false;
-
907  }
-
908 
-
909  if (ci->m_buffer_size != segment_size)
-
910  {
-
911  Logging::error(ci->m_cachefile, "INTERNAL ERROR: Buffer::copy()! ci->m_buffer_size != segment_size - Segment: %1 ci->m_buffer_size: %2 segment_size: %3", segment_no, ci->m_buffer_size, segment_size);
-
912  errno = ESPIPE; // Comes from size()
-
913  return false;
-
914  }
-
915 
-
916  if (segment_size > offset)
-
917  {
-
918  if (segment_size < offset + bufsize)
-
919  {
-
920  bufsize = segment_size - offset - 1;
-
921  }
-
922 
-
923  std::memcpy(out_data, ci->m_buffer + offset, bufsize);
-
924 
-
925  return true;
-
926  }
-
927  else
-
928  {
-
929  Logging::error(ci->m_cachefile, "INTERNAL ERROR: Buffer::copy()! segment_size <= offset - Segment: %1 Segment Size: %2 Offset: %3", segment_no, segment_size, offset);
-
930  errno = ESPIPE;
-
931 
-
932  return false;
-
933  }
-
934 }
-
935 
-
936 bool Buffer::reallocate(size_t newsize)
-
937 {
-
938  if (newsize > size())
-
939  {
- -
941  {
-
942  size_t alloc_size = newsize - size();
-
943  size_t write_avg = m_cur_ci->m_buffer_write_size / m_cur_ci->m_buffer_writes;
-
944  size_t write_size = PREALLOC_FACTOR * write_avg;
-
945  if (write_size > alloc_size)
-
946  {
-
947  alloc_size = write_size;
-
948 
-
949  newsize = size() + alloc_size;
-
950 
-
951  }
-
952  }
-
953 
-
954  Logging::trace(filename(), "Buffer reallocate: %1 -> %2 (Diff %3).", size(), newsize, newsize - size());
-
955 
-
956  if (!reserve(newsize))
-
957  {
-
958  return false;
-
959  }
-
960  }
-
961  return true;
-
962 }
-
963 
-
964 const std::string & Buffer::cachefile(uint32_t segment_no) const
-
965 {
-
966  LPCCACHEINFO ci = const_cacheinfo(segment_no);
-
967 
-
968  if (ci == nullptr)
-
969  {
-
970  static std::string empty;
-
971  errno = EBADF;
-
972  return empty;
-
973  }
-
974 
-
975  return ci->m_cachefile;
-
976 }
-
977 
-
978 const std::string & Buffer::make_cachefile_name(std::string & cachefile, const std::string & filename, const std::string & fileext, bool is_idx)
-
979 {
- -
981 
- -
983  cachefile += filename;
-
984 
-
985  if (is_idx)
-
986  {
-
987  cachefile += ".idx.";
-
988  }
-
989  else
-
990  {
-
991  cachefile += ".cache.";
-
992  }
-
993  cachefile += fileext;
-
994 
-
995  return cachefile;
-
996 }
-
997 
-
998 bool Buffer::remove_file(const std::string & filename)
-
999 {
-
1000  if (unlink(filename.c_str()) && errno != ENOENT)
-
1001  {
-
1002  Logging::warning(filename, "Cannot unlink the file: (%1) %2", errno, strerror(errno));
-
1003  return false;
-
1004  }
-
1005  else
-
1006  {
-
1007  errno = 0;
-
1008  return true;
-
1009  }
-
1010 }
-
1011 
-
1012 size_t Buffer::readio(void * /*data*/, size_t /*size*/)
-
1013 {
-
1014  // Not implemented
-
1015  errno = EPERM;
-
1016  return 0;
-
1017 }
-
1018 
-
1019 size_t Buffer::read_frame(std::vector<uint8_t> * data, uint32_t frame_no)
-
1020 {
-
1021  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
1022 
-
1023  if (data == nullptr || m_cur_ci->m_buffer_idx == nullptr || frame_no < 1 || frame_no > virtualfile()->m_video_frame_count)
-
1024  {
-
1025  // Invalid parameter
-
1026  errno = EINVAL;
-
1027  return 0;
-
1028  }
-
1029 
-
1030  LPCIMAGE_FRAME image_frame;
-
1031  size_t start = static_cast<size_t>(frame_no - 1) * sizeof(IMAGE_FRAME);
-
1032 
-
1033  image_frame = reinterpret_cast<LPCIMAGE_FRAME>(m_cur_ci->m_buffer_idx + start);
-
1034 
-
1035  if (!image_frame->m_frame_no)
-
1036  {
-
1037  errno = EAGAIN;
-
1038  return 0;
-
1039  }
-
1040 
-
1041  data->resize(image_frame->m_size);
-
1042 
-
1043  return copy(data, static_cast<size_t>(image_frame->m_offset));
-
1044 }
-
1045 
-
1046 int Buffer::error() const
-
1047 {
-
1048  return errno;
-
1049 }
-
1050 
-
1051 bool Buffer::eof() const
-
1052 {
-
1053  return eof(0);
-
1054 }
-
1055 
-
1056 bool Buffer::eof(uint32_t segment_no) const
-
1057 {
-
1058  return (tell(segment_no) == size(segment_no));
-
1059 }
-
1060 
- -
1062 {
-
1063  release();
-
1064 }
-
1065 
-
1066 bool Buffer::have_frame(uint32_t frame_no)
-
1067 {
-
1068  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
1069 
-
1070  if (m_cur_ci->m_buffer_idx == nullptr || frame_no < 1 || frame_no > virtualfile()->m_video_frame_count)
-
1071  {
-
1072  // Invalid parameter
-
1073  errno = EINVAL;
-
1074  return false;
-
1075  }
-
1076 
-
1077  LPCIMAGE_FRAME image_frame;
-
1078  size_t start = static_cast<size_t>(frame_no - 1) * sizeof(IMAGE_FRAME);
-
1079 
-
1080  image_frame = reinterpret_cast<LPCIMAGE_FRAME>(m_cur_ci->m_buffer_idx + start);
-
1081 
-
1082  return (image_frame->m_frame_no ? true : false);
-
1083 }
-
1084 
- -
1086 {
-
1087  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
1088 
-
1089  for (CACHEINFO & ci : m_ci)
-
1090  {
-
1091  if ((ci.m_fd != -1 && (fcntl(ci.m_fd, F_GETFL) != -1 || errno != EBADF)))
-
1092  {
-
1093  return true;
-
1094  }
-
1095  }
-
1096 
-
1097  return false;
-
1098 }
-
1099 
- -
1101 {
-
1102  if (m_cur_ci == nullptr)
-
1103  {
-
1104  return;
-
1105  }
-
1106 
-
1107  m_cur_ci->m_seg_finished = true;
-
1108 
-
1109  flush();
-
1110 }
-
1111 
-
1112 bool Buffer::is_segment_finished(uint32_t segment_no) const
-
1113 {
-
1114  LPCCACHEINFO ci = const_cacheinfo(segment_no);
-
1115 
-
1116  if (ci == nullptr)
-
1117  {
-
1118  errno = EBADF;
-
1119  return false;
-
1120  }
-
1121 
-
1122  return ci->m_seg_finished;
-
1123 }
-
1124 
- -
1126 {
-
1127  if (segment_no)
-
1128  {
-
1129  segment_no--;
-
1130 
-
1131  if (segment_no >= segment_count())
-
1132  {
-
1133  return nullptr;
-
1134  }
-
1135  return (&m_ci[segment_no]);
-
1136  }
-
1137 
-
1138  return m_cur_ci;
-
1139 }
-
1140 
- -
1142 {
-
1143  if (segment_no)
-
1144  {
-
1145  segment_no--;
-
1146 
-
1147  if (segment_no >= m_ci.size())
-
1148  {
-
1149  return nullptr;
-
1150  }
-
1151  return (&m_ci[segment_no]);
-
1152  }
-
1153 
-
1154  return m_cur_ci;
-
1155 }
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
32#include "buffer.h"
+
33#include "ffmpegfs.h"
+
34#include "logging.h"
+
35
+
36#include <unistd.h>
+
37#include <sys/mman.h>
+
38#include <libgen.h>
+
39#include <cstring>
+
40
+
41// Initially Buffer is empty. It will be allocated as needed.
+ +
43 : m_cur_ci(nullptr)
+
44 , m_cur_open(0)
+
45{
+
46}
+
47
+
48// If buffer_data was never allocated, this is a no-op.
+ +
50{
+
51 release();
+
52}
+
53
+ +
55{
+
56 return VIRTUALTYPE_BUFFER;
+
57}
+
58
+
59size_t Buffer::bufsize() const
+
60{
+
61 return 0; // Not applicable
+
62}
+
63
+ +
65{
+
66 if (virtualfile == nullptr)
+
67 {
+
68 errno = EINVAL;
+
69 return (EOF);
+
70 }
+
71
+ +
73
+
74 return 0;
+
75}
+
76
+
77bool Buffer::open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize)
+
78{
+
79 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
80
+
81 uint32_t index = segment_no;
+
82 if (index)
+
83 {
+
84 index--;
+
85 }
+
86
+
87 CACHEINFO & ci = m_ci[index];
+
88
+
89 ci.m_flags |= flags;
+
90
+
91 if (ci.m_fd != -1)
+
92 {
+
93 Logging::trace(ci.m_cachefile, "Cache file is already open.");
+
94
+
95 if (defaultsize)
+
96 {
+
97 // Make sure the requested size is available
+
98 reserve(defaultsize);
+
99 }
+
100 // Already open
+
101 return true;
+
102 }
+
103
+
104 if (flags & CACHE_FLAG_RW)
+
105 {
+
106 Logging::debug(ci.m_cachefile, "Writing to cache file.");
+
107 }
+
108 else
+
109 {
+
110 Logging::debug(ci.m_cachefile, "Reading from cache file.");
+
111 }
+
112
+
113 size_t filesize = 0;
+
114 bool isdefaultsize = false;
+
115 uint8_t *p = nullptr;
+
116
+
117 if (!map_file(ci.m_cachefile, &ci.m_fd, &p, &filesize, &isdefaultsize, defaultsize, (flags & CACHE_FLAG_RW) ? true : false))
+
118 {
+
119 return false;
+
120 }
+
121
+
122 if (!isdefaultsize)
+
123 {
+
124 ci.m_buffer_pos = ci.m_buffer_watermark = filesize;
+
125 }
+
126
+
127 ci.m_buffer_size = filesize;
+
128 ci.m_buffer = static_cast<uint8_t*>(p);
+
129 ci.m_buffer_write_size = 0;
+
130 ci.m_buffer_writes = 0;
+
131
+
132 ++m_cur_open; // track open files
+
133
+
134 return true;
+
135}
+
136
+
137bool Buffer::close_file(uint32_t segment_no, uint32_t flags)
+
138{
+
139 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
140
+
141 uint32_t index = segment_no;
+
142 if (index)
+
143 {
+
144 index--;
+
145 }
+
146
+
147 CACHEINFO & ci = m_ci[index];
+
148
+
149 ci.m_flags &= ~flags;
+
150
+
151 if (ci.m_flags)
+
152 {
+
153 Logging::trace(ci.m_cachefile, "While attempting to close, the cache file is still in use. Currently open: %1", m_cur_open);
+
154 return true;
+
155 }
+
156
+
157 if (ci.m_fd == -1)
+
158 {
+
159 // Already closed
+
160 Logging::trace(ci.m_cachefile, "No need to close the unopened cache file. Currently open: %1", m_cur_open);
+
161 return true;
+
162 }
+
163
+
164 Logging::trace(ci.m_cachefile, "Closing cache file.");
+
165
+
166 bool success = unmap_file(ci.m_cachefile, &ci.m_fd, &ci.m_buffer, ci.m_buffer_size, &ci.m_buffer_watermark);
+
167
+
168 ci.m_buffer_pos = 0;
+
169 ci.m_buffer_size = 0;
+
170
+
171 if (success && m_cur_open > 0)
+
172 {
+
173 --m_cur_open; // track open files
+
174 }
+
175
+
176 return success;
+
177}
+
178
+
179bool Buffer::init(bool erase_cache)
+
180{
+
181 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
182
+
183 if (is_open())
+
184 {
+
185 return true;
+
186 }
+
187
+
188 bool success = true;
+
189
+
190 try
+
191 {
+
192 if ((virtualfile()->m_flags & VIRTUALFLAG_HLS))
+
193 {
+
194 // HLS format: create several segments
+
195 if (virtualfile()->get_segment_count())
+
196 {
+
197 m_ci.resize(virtualfile()->get_segment_count());
+
198
+
199 for (uint32_t segment_no = 1; segment_no <= virtualfile()->get_segment_count(); segment_no++)
+
200 {
+
201 make_cachefile_name(m_ci[segment_no - 1].m_cachefile, filename() + "." + make_filename(segment_no, params.current_format(virtualfile())->fileext()), params.current_format(virtualfile())->fileext(), false);
+
202 }
+
203 }
+
204 else
+
205 {
+
206 Logging::error(filename(), "INTERNAL ERROR: Buffer::init()! Segment count is 0.");
+
207 errno = EINVAL;
+
208 throw false;
+
209 }
+
210 }
+
211 else
+
212 {
+
213 // All other formats: create just a single segment.
+
214 m_ci.resize(1);
+
215
+
216 make_cachefile_name(m_ci[0].m_cachefile, filename(), params.current_format(virtualfile())->fileext(), false);
+
217 if ((virtualfile()->m_flags & VIRTUALFLAG_FRAME))
+
218 {
+
219 // Create extra index cash for frame sets only
+
220 make_cachefile_name(m_ci[0].m_cachefile_idx, filename(), params.current_format(virtualfile())->fileext(), true);
+
221 }
+
222 }
+
223
+
224 // Set current segment
+
225 m_cur_ci = &m_ci[0];
+
226
+
227 // Create the path to the cache file. All paths are the same, so this is required only once.
+
228 char *cachefiletmp = new_strdup(m_ci[0].m_cachefile);
+
229
+
230 if (cachefiletmp == nullptr)
+
231 {
+
232 Logging::error(m_ci[0].m_cachefile, "Error opening the cache file: out of memory.");
+
233 errno = ENOMEM;
+
234 throw false;
+
235 }
+
236
+
237 if (mktree(dirname(cachefiletmp), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) && errno != EEXIST)
+
238 {
+
239 Logging::error(m_ci[0].m_cachefile, "Error creating cache directory: (%1) %2", errno, strerror(errno));
+
240 delete [] cachefiletmp;
+
241 throw false;
+
242 }
+
243 errno = 0; // reset EEXIST, error can safely be ignored here
+
244
+
245 delete [] cachefiletmp;
+
246
+
247#if __cplusplus >= 202002L
+
248 // C++20 (and later) code
+
249 for (uint32_t index = 0; CACHEINFO & ci : m_ci)
+
250#else
+
251 uint32_t index = 0;
+
252 for (CACHEINFO & ci : m_ci)
+
253#endif
+
254 {
+
255 ci.reset();
+
256
+
257 if (erase_cache)
+
258 {
+
259 remove_cachefile(index + 1);
+
260 errno = 0; // ignore this error
+
261 }
+
262
+
263 index++;
+
264 }
+
265
+
266 // Index only required for frame sets and there is only one.
+
267 if (!m_ci[0].m_cachefile_idx.empty())
+
268 {
+
269 if (virtualfile()->m_video_frame_count == 0)
+
270 {
+
271 errno = EINVAL;
+
272 Logging::error(m_ci[0].m_cachefile, "INTERNAL ERROR: Buffer::init()! Frame count is zero (%1) %2", errno, strerror(errno));
+
273 throw false;
+
274 }
+
275 static_assert(sizeof(IMAGE_FRAME) == 32, "sizeof(IMAGE_FRAME) must be 32 bytes");
+
276
+
277 size_t filesize = 0;
+
278 bool isdefaultsize = false;
+
279 uint8_t *p = nullptr;
+
280
+
281 if (!map_file(m_ci[0].m_cachefile_idx, &m_ci[0].m_fd_idx, &p, &filesize, &isdefaultsize, sizeof(IMAGE_FRAME) * virtualfile()->m_video_frame_count, false))
+
282 {
+
283 throw false;
+
284 }
+
285
+
286 m_ci[0].m_buffer_size_idx = filesize;
+
287 m_ci[0].m_buffer_idx = static_cast<uint8_t*>(p);
+
288 }
+
289 }
+
290 catch (bool _success)
+
291 {
+
292 success = _success;
+
293
+
294 if (!success)
+
295 {
+
296 for (CACHEINFO & ci : m_ci)
+
297 {
+
298 ci.reset();
+
299 }
+
300 }
+
301 }
+
302
+
303 return success;
+
304}
+
305
+
306bool Buffer::set_segment(uint32_t segment_no, size_t size)
+
307{
+
308 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
309
+
310 if (!segment_no || segment_no > segment_count())
+
311 {
+
312 errno = EINVAL;
+
313 return false;
+
314 }
+
315
+ +
317 {
+
318 return false;
+
319 }
+
320
+
321 if (!open_file(segment_no, CACHE_FLAG_RW, size))
+
322 {
+
323 return false;
+
324 }
+
325
+
326 m_cur_ci = &m_ci[segment_no - 1];
+
327
+
328 // Reserve enough buffer space for segment to avoid frequent resizes
+
329 return reserve(size);
+
330}
+
331
+ +
333{
+
334 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
335
+
336 return static_cast<uint32_t>(m_ci.size());
+
337}
+
338
+ +
340{
+
341 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
342
+
343 if (!segment_count() || m_cur_ci == nullptr)
+
344 {
+
345 return 0;
+
346 }
+
347 return static_cast<uint32_t>(m_cur_ci - &m_ci[0]) + 1;
+
348}
+
349
+
350bool Buffer::segment_exists(uint32_t segment_no)
+
351{
+
352 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
353
+
354 if (!segment_count() || m_cur_ci == nullptr)
+
355 {
+
356 return false;
+
357 }
+
358 return file_exists(m_ci[segment_no - 1].m_cachefile);
+
359}
+
360
+
361bool Buffer::map_file(const std::string & filename, volatile int *fd, uint8_t **p, size_t *filesize, bool *isdefaultsize, size_t defaultsize, bool truncate) const
+
362{
+
363 bool success = true;
+
364
+
365 if (!defaultsize)
+
366 {
+
367 Logging::trace(filename, "Mapping cache file.");
+
368 }
+
369 else
+
370 {
+
371 Logging::trace(filename, "Mapping cache file with %1.", format_size(defaultsize).c_str());
+
372 }
+
373
+
374 try
+
375 {
+
376 struct stat sb;
+
377
+
378 *fd = ::open(filename.c_str(), O_CREAT | O_RDWR | (truncate ? O_TRUNC : 0), static_cast<mode_t>(0644));
+
379 if (*fd == -1)
+
380 {
+
381 Logging::error(filename, "The cache file could not be opened due to an error: (%1) %2", errno, strerror(errno));
+
382 throw false;
+
383 }
+
384
+
385 if (fstat(*fd, &sb) == -1)
+
386 {
+
387 Logging::error(filename, "File stat failed: (%1) %2 (fd = %3)", errno, strerror(errno), *fd);
+
388 throw false;
+
389 }
+
390
+
391 if (!S_ISREG(sb.st_mode))
+
392 {
+
393 Logging::error(filename, "Not a file.");
+
394 throw false;
+
395 }
+
396
+
397 if (!sb.st_size || defaultsize)
+
398 {
+
399 // If file is empty or did not exist set file size to default
+
400
+
401 if (!defaultsize)
+
402 {
+
403 defaultsize = static_cast<size_t>(sysconf(_SC_PAGESIZE));
+
404 }
+
405
+
406 if (ftruncate(*fd, static_cast<off_t>(defaultsize)) == -1)
+
407 {
+
408 Logging::error(filename, "Error calling ftruncate() to 'stretch' the file: (%1) %2 (fd = %3)", errno, strerror(errno), *fd);
+
409 throw false;
+
410 }
+
411
+
412 *filesize = defaultsize;
+
413 *isdefaultsize = true;
+
414 }
+
415 else
+
416 {
+
417 // Keep size
+
418 *filesize = static_cast<size_t>(sb.st_size);
+
419 *isdefaultsize = false;
+
420 }
+
421
+
422 *p = static_cast<uint8_t *>(mmap(nullptr, *filesize, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0));
+
423 if (*p == MAP_FAILED)
+
424 {
+
425 Logging::error(filename, "File mapping failed: (%1) %2 (fd = %3)", errno, strerror(errno), *fd);
+
426 *p = nullptr;
+
427 throw false;
+
428 }
+
429 }
+
430 catch (bool _success)
+
431 {
+
432 success = _success;
+
433
+
434 if (!success && *fd != -1)
+
435 {
+
436 ::close(*fd);
+
437 *fd = -1;
+
438 }
+
439 }
+
440
+
441 return success;
+
442}
+
443
+
444bool Buffer::unmap_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t len, size_t * filesize) const
+
445{
+
446 bool success = true;
+
447
+
448 Logging::trace(filename, "Unmapping cache file.");
+
449
+
450 void * _p = *p;
+
451 size_t _filesize = *filesize;
+
452 int _fd = *fd;
+
453
+
454 // Clear all variables
+
455 *p = nullptr;
+
456 *filesize = 0;
+
457 *fd = -1;
+
458
+
459 if (_p != nullptr)
+
460 {
+
461 if (munmap(_p, len ? len : static_cast<size_t>(sysconf(_SC_PAGESIZE))) == -1) // Make sure we do not unmap a zero size file (spits EINVAL error)
+
462 {
+
463 Logging::error(filename, "Unmapping cache file failed: (%1) %2 Size: %3", errno, strerror(errno), len);
+
464 success = false;
+
465 }
+
466 }
+
467
+
468 if (_fd != -1)
+
469 {
+
470 if (_filesize)
+
471 {
+
472 if (ftruncate(_fd, static_cast<off_t>(_filesize)) == -1)
+
473 {
+
474 Logging::error(filename, "Error calling ftruncate() to resize and close the cache file: (%1) %2 (fd = %3) Size: %5", errno, strerror(errno), _fd, _filesize);
+
475 success = false;
+
476 }
+
477 ::close(_fd);
+
478 }
+
479 else
+
480 {
+
481 ::close(_fd);
+
482
+
483 if (unlink(filename.c_str()) && errno != ENOENT) // Ignore if file does not exist
+
484 {
+
485 Logging::error(filename, "Error removing the cache file: (%1) %2 (fd = %3)", errno, strerror(errno), _fd);
+
486 success = false;
+
487 }
+
488 }
+
489 }
+
490
+
491 return success;
+
492}
+
493
+
494bool Buffer::release(int flags /*= CACHE_CLOSE_NOOPT*/)
+
495{
+
496 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
497
+
498 bool success = true;
+
499
+
500 if (!is_open())
+
501 {
+ +
503 {
+
504 for (uint32_t n = 1; n <= segment_count(); n++)
+
505 {
+ +
507 }
+
508 errno = 0; // ignore this error
+
509 }
+
510
+
511 return true;
+
512 }
+
513
+
514 // Write active cache to disk
+
515 flush();
+
516
+
517 // Close anything that's still open
+
518 for (uint32_t index = 0; index < segment_count(); index++)
+
519 {
+
520 if (!close_file(index + 1, CACHE_FLAG_RO | CACHE_FLAG_RW))
+
521 {
+
522 success = false;
+
523 }
+
524
+ +
526 {
+
527 remove_cachefile(index + 1);
+
528 errno = 0; // ignore this error
+
529 }
+
530 }
+
531
+
532 // Remove index for frame sets. There is only one.
+
533 if (!m_ci[0].m_cachefile_idx.empty())
+
534 {
+
535 if (!unmap_file(m_ci[0].m_cachefile_idx, &m_ci[0].m_fd_idx, &m_ci[0].m_buffer_idx, m_ci[0].m_buffer_size_idx, &m_ci[0].m_buffer_size_idx))
+
536 {
+
537 success = false;
+
538 }
+
539 }
+
540
+
541 return success;
+
542}
+
543
+
544bool Buffer::remove_cachefile(uint32_t segment_no) const
+
545{
+
546 const CACHEINFO & ci = !segment_no ? *m_cur_ci : m_ci[segment_no - 1];
+
547 bool success = remove_file(ci.m_cachefile);
+
548
+
549 if (!ci.m_cachefile_idx.empty())
+
550 {
+ +
552 {
+
553 success = false;
+
554 }
+
555 }
+
556 return success;
+
557}
+
558
+ +
560{
+
561 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
562
+
563 if (!segment_count() || m_cur_ci == nullptr || m_cur_ci->m_buffer == nullptr)
+
564 {
+
565 errno = EPERM;
+
566 return false;
+
567 }
+
568
+
569 if (msync(m_cur_ci->m_buffer, m_cur_ci->m_buffer_size, MS_SYNC) == -1)
+
570 {
+
571 Logging::error(m_cur_ci->m_cachefile, "Could not sync to disk: (%1) %2", errno, strerror(errno));
+
572 return false;
+
573 }
+
574
+
575 if (m_cur_ci->m_buffer_idx != nullptr)
+
576 {
+
577 if (msync(m_cur_ci->m_buffer_idx, m_cur_ci->m_buffer_size_idx, MS_SYNC) == -1)
+
578 {
+
579 Logging::error(m_cur_ci->m_cachefile_idx, "Could not sync to disk: (%1) %2", errno, strerror(errno));
+
580 return false;
+
581 }
+
582 }
+
583
+
584 return true;
+
585}
+
586
+ +
588{
+
589 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
590
+
591 bool success = true;
+
592
+
593 for (CACHEINFO & ci : m_ci)
+
594 {
+
595 ci.m_buffer_pos = 0;
+
596 ci.m_buffer_watermark = 0;
+
597 ci.m_buffer_size = 0;
+
598 ci.m_seg_finished = false;
+
599 ci.m_buffer_write_size = 0;
+
600 ci.m_buffer_writes = 0;
+
601
+
602 if (ci.m_fd != -1)
+
603 {
+
604 // If empty set file size to 1 page
+
605 long filesize = sysconf(_SC_PAGESIZE);
+
606
+
607 if (ftruncate(ci.m_fd, filesize) == -1)
+
608 {
+
609 Logging::error(ci.m_cachefile, "Error calling ftruncate() to clear the file: (%1) %2 (fd = %3)", errno, strerror(errno), ci.m_fd);
+
610 success = false;
+
611 }
+
612 }
+
613 else
+
614 {
+
615 remove_file(ci.m_cachefile);
+
616 }
+
617
+
618 if (ci.m_fd_idx != -1)
+
619 {
+
620 std::memset(ci.m_buffer_idx, 0, ci.m_buffer_size_idx);
+
621 }
+
622 }
+
623
+
624 return success;
+
625}
+
626
+
627bool Buffer::reserve(size_t size)
+
628{
+
629 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
630
+
631 if (m_cur_ci == nullptr || m_cur_ci->m_buffer == nullptr)
+
632 {
+
633 errno = ENOMEM;
+
634 Logging::error(nullptr, "INTERNAL ERROR: Buffer::reserve()!");
+
635 return false;
+
636 }
+
637
+ +
639 {
+
640 // Do not shrink
+
641 return true;
+
642 }
+
643
+
644 m_cur_ci->m_buffer = static_cast<uint8_t*>(mremap(m_cur_ci->m_buffer, m_cur_ci->m_buffer_size, size, MREMAP_MAYMOVE));
+
645 if (m_cur_ci->m_buffer == MAP_FAILED)
+
646 {
+
647 Logging::error(m_cur_ci->m_cachefile, "Error calling mremap() to resize the file: (%1) %2 (fd = %3) Old size: %4 New: %5", errno, strerror(errno), m_cur_ci->m_fd, m_cur_ci->m_buffer_size, size);
+
648 m_cur_ci->m_buffer = nullptr;
+
649 return false;
+
650 }
+
651
+
652 // Save size
+ +
654
+
655 if (ftruncate(m_cur_ci->m_fd, static_cast<off_t>(m_cur_ci->m_buffer_size)) == -1)
+
656 {
+
657 Logging::error(m_cur_ci->m_cachefile, "Error calling ftruncate() to resize the file: (%1) %2 (fd = %3)", errno, strerror(errno), m_cur_ci->m_fd);
+
658 return false;
+
659 }
+
660
+
661 return true;
+
662}
+
663
+
664size_t Buffer::writeio(const uint8_t* data, size_t length)
+
665{
+
666 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
667
+
668 if (m_cur_ci == nullptr || m_cur_ci->m_buffer == nullptr)
+
669 {
+
670 errno = ENOMEM;
+
671 return 0;
+
672 }
+
673
+
674 uint8_t* write_ptr = write_prepare(length);
+
675 if (write_ptr == nullptr)
+
676 {
+
677 length = 0;
+
678 }
+
679 else
+
680 {
+
681 m_cur_ci->m_buffer_write_size += length;
+ +
683
+
684 std::memcpy(write_ptr, data, length);
+
685 increment_pos(length);
+
686 }
+
687
+
688 return length;
+
689}
+
690
+
691size_t Buffer::write_frame(const uint8_t *data, size_t length, uint32_t frame_no)
+
692{
+
693 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
694
+
695 if (data == nullptr || m_cur_ci == nullptr || m_cur_ci->m_buffer_idx == nullptr || frame_no < 1 || frame_no > virtualfile()->m_video_frame_count)
+
696 {
+
697 // Invalid parameter
+
698 errno = EINVAL;
+
699 return 0;
+
700 }
+
701
+
702 LPIMAGE_FRAME old_image_frame;
+
703 IMAGE_FRAME new_image_frame;
+
704 size_t bytes_written;
+
705 size_t start = static_cast<size_t>(frame_no - 1) * sizeof(IMAGE_FRAME);
+
706
+
707 old_image_frame = reinterpret_cast<LPIMAGE_FRAME>(m_cur_ci->m_buffer_idx + start);
+
708
+
709 if (old_image_frame->m_frame_no && (old_image_frame->m_size <= static_cast<uint32_t>(length)))
+
710 {
+
711 // Frame already exists and has enough space
+
712 old_image_frame->m_size = static_cast<uint32_t>(length);
+
713
+
714 // Write image
+
715 seek(static_cast<long>(old_image_frame->m_offset), SEEK_SET);
+
716 bytes_written = writeio(data, old_image_frame->m_size);
+
717 if (bytes_written != old_image_frame->m_size)
+
718 {
+
719 return 0;
+
720 }
+
721 }
+
722 else
+
723 {
+
724 // Create new frame if not existing or not enough space
+
725 std::memset(&new_image_frame, 0xFF, sizeof(new_image_frame));
+
726 std::memcpy(new_image_frame.m_tag, IMAGE_FRAME_TAG, sizeof(new_image_frame.m_tag));
+
727 new_image_frame.m_frame_no = frame_no;
+
728 new_image_frame.m_offset = buffer_watermark();
+
729 new_image_frame.m_size = static_cast<uint32_t>(length);
+
730
+
731 // Write image
+
732 seek(static_cast<long>(new_image_frame.m_offset), SEEK_SET);
+
733 bytes_written = writeio(data, new_image_frame.m_size);
+
734 if (bytes_written != new_image_frame.m_size)
+
735 {
+
736 return 0;
+
737 }
+
738
+
739 std::memcpy(reinterpret_cast<void *>(m_cur_ci->m_buffer_idx + start), &new_image_frame, sizeof(IMAGE_FRAME));
+
740 }
+
741
+
742 return bytes_written;
+
743}
+
744
+
745uint8_t* Buffer::write_prepare(size_t length)
+
746{
+
747 if (reallocate(m_cur_ci->m_buffer_pos + length))
+
748 {
+ +
750 {
+ +
752 }
+ +
754 }
+
755 else
+
756 {
+
757 errno = ESPIPE;
+
758 return nullptr;
+
759 }
+
760}
+
761
+
762void Buffer::increment_pos(size_t increment)
+
763{
+
764 m_cur_ci->m_buffer_pos += increment;
+
765}
+
766
+
767int Buffer::seek(int64_t offset, int whence)
+
768{
+
769 return seek(offset, whence, 0);
+
770}
+
771
+
772int Buffer::seek(int64_t offset, int whence, uint32_t segment_no)
+
773{
+
774 LPCACHEINFO ci = cacheinfo(segment_no);
+
775
+
776 if (ci == nullptr || ci->m_buffer == nullptr)
+
777 {
+
778 errno = ENOMEM;
+
779 return (EOF);
+
780 }
+
781
+
782 off_t seek_pos;
+
783
+
784 switch (whence)
+
785 {
+
786 case SEEK_SET:
+
787 {
+
788 seek_pos = offset;
+
789 break;
+
790 }
+
791 case SEEK_CUR:
+
792 {
+
793 seek_pos = static_cast<off_t>(tell(segment_no)) + offset;
+
794 break;
+
795 }
+
796 case SEEK_END:
+
797 {
+
798 seek_pos = static_cast<off_t>(size(segment_no)) + offset;
+
799 break;
+
800 }
+
801 default:
+
802 {
+
803 errno = EINVAL;
+
804 return (EOF);
+
805 }
+
806 }
+
807
+
808 if (seek_pos > static_cast<off_t>(size(segment_no)))
+
809 {
+
810 ci->m_buffer_pos = size(segment_no); // Cannot go beyond EOF. Set position to end, leave errno untouched.
+
811 return 0;
+
812 }
+
813
+
814 if (seek_pos < 0) // Cannot go before head, leave position untouched, set errno.
+
815 {
+
816 errno = EINVAL;
+
817 return (EOF);
+
818 }
+
819
+
820 ci->m_buffer_pos = static_cast<size_t>(seek_pos);
+
821 return 0;
+
822}
+
823
+
824size_t Buffer::tell() const
+
825{
+
826 return tell(0);
+
827}
+
828
+
829size_t Buffer::tell(uint32_t segment_no) const
+
830{
+
831 LPCCACHEINFO ci = const_cacheinfo(segment_no);
+
832
+
833 if (ci == nullptr)
+
834 {
+
835 errno = EBADF;
+
836 return 0;
+
837 }
+
838
+
839 return ci->m_buffer_pos;
+
840}
+
841
+
842int64_t Buffer::duration() const
+
843{
+
844 return AV_NOPTS_VALUE; // not applicable
+
845}
+
846
+
847size_t Buffer::size() const
+
848{
+
849 return size(0);
+
850}
+
851
+
852size_t Buffer::size(uint32_t segment_no) const
+
853{
+
854 LPCCACHEINFO ci = const_cacheinfo(segment_no);
+
855
+
856 if (ci == nullptr)
+
857 {
+
858 errno = EBADF;
+
859 return 0;
+
860 }
+
861
+
862 return ci->m_buffer_size;
+
863}
+
864
+
865size_t Buffer::buffer_watermark(uint32_t segment_no) const
+
866{
+
867 LPCCACHEINFO ci = const_cacheinfo(segment_no);
+
868
+
869 if (ci == nullptr)
+
870 {
+
871 errno = EBADF;
+
872 return 0;
+
873 }
+
874
+
875 return ci->m_buffer_watermark;
+
876}
+
877
+
878bool Buffer::copy(std::vector<uint8_t> * out_data, size_t offset, uint32_t segment_no)
+
879{
+
880 return copy(out_data->data(), offset, out_data->size(), segment_no);
+
881}
+
882
+
883bool Buffer::copy(uint8_t* out_data, size_t offset, size_t bufsize, uint32_t segment_no)
+
884{
+
885 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
886
+
887 LPCCACHEINFO ci = const_cacheinfo(segment_no);
+
888
+
889 if (ci == nullptr)
+
890 {
+
891 errno = EBADF;
+
892 return false;
+
893 }
+
894
+
895 if (ci->m_buffer == nullptr)
+
896 {
+
897 errno = ENOMEM;
+
898 return false;
+
899 }
+
900
+
901 size_t segment_size = ci->m_buffer_size;
+
902
+
903 if (!segment_size && errno)
+
904 {
+
905 Logging::error(ci->m_cachefile, "INTERNAL ERROR: Buffer::copy()! size(segment_no) returned error. Segment: %1 (%2) %3", segment_no, errno, strerror(errno));
+
906 return false;
+
907 }
+
908
+
909 if (segment_size > offset)
+
910 {
+
911 if (segment_size < offset + bufsize)
+
912 {
+
913 bufsize = segment_size - offset - 1;
+
914 }
+
915
+
916 std::memcpy(out_data, ci->m_buffer + offset, bufsize);
+
917
+
918 return true;
+
919 }
+
920 else
+
921 {
+
922 Logging::error(ci->m_cachefile, "INTERNAL ERROR: Buffer::copy()! segment_size <= offset - Segment: %1 Segment Size: %2 Offset: %3", segment_no, segment_size, offset);
+
923 errno = ESPIPE;
+
924
+
925 return false;
+
926 }
+
927}
+
928
+
929bool Buffer::reallocate(size_t newsize)
+
930{
+
931 if (newsize > size())
+
932 {
+ +
934 {
+
935 size_t alloc_size = newsize - size();
+ +
937 size_t write_size = PREALLOC_FACTOR * write_avg;
+
938 if (write_size > alloc_size)
+
939 {
+
940 alloc_size = write_size;
+
941
+
942 newsize = size() + alloc_size;
+
943
+
944 }
+
945 }
+
946
+
947 Logging::trace(filename(), "Buffer reallocate: %1 -> %2 (Diff %3).", size(), newsize, newsize - size());
+
948
+
949 if (!reserve(newsize))
+
950 {
+
951 return false;
+
952 }
+
953 }
+
954 return true;
+
955}
+
956
+
957const std::string & Buffer::cachefile(uint32_t segment_no) const
+
958{
+
959 LPCCACHEINFO ci = const_cacheinfo(segment_no);
+
960
+
961 if (ci == nullptr)
+
962 {
+
963 static std::string empty;
+
964 errno = EBADF;
+
965 return empty;
+
966 }
+
967
+
968 return ci->m_cachefile;
+
969}
+
970
+
971const std::string & Buffer::make_cachefile_name(std::string & cachefile, const std::string & filename, const std::string & fileext, bool is_idx)
+
972{
+ +
974
+ + +
977
+
978 if (is_idx)
+
979 {
+
980 cachefile += ".idx.";
+
981 }
+
982 else
+
983 {
+
984 cachefile += ".cache.";
+
985 }
+
986 cachefile += fileext;
+
987
+
988 return cachefile;
+
989}
+
990
+
991bool Buffer::remove_file(const std::string & filename)
+
992{
+
993 if (unlink(filename.c_str()) && errno != ENOENT)
+
994 {
+
995 Logging::warning(filename, "Cannot unlink the file: (%1) %2", errno, strerror(errno));
+
996 return false;
+
997 }
+
998 else
+
999 {
+
1000 errno = 0;
+
1001 return true;
+
1002 }
+
1003}
+
1004
+
1005size_t Buffer::readio(void * /*data*/, size_t /*size*/)
+
1006{
+
1007 // Not implemented
+
1008 errno = EPERM;
+
1009 return 0;
+
1010}
+
1011
+
1012size_t Buffer::read_frame(std::vector<uint8_t> * data, uint32_t frame_no)
+
1013{
+
1014 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
1015
+
1016 if (data == nullptr || m_cur_ci->m_buffer_idx == nullptr || frame_no < 1 || frame_no > virtualfile()->m_video_frame_count)
+
1017 {
+
1018 // Invalid parameter
+
1019 errno = EINVAL;
+
1020 return 0;
+
1021 }
+
1022
+
1023 LPCIMAGE_FRAME image_frame;
+
1024 size_t start = static_cast<size_t>(frame_no - 1) * sizeof(IMAGE_FRAME);
+
1025
+
1026 image_frame = reinterpret_cast<LPCIMAGE_FRAME>(m_cur_ci->m_buffer_idx + start);
+
1027
+
1028 if (!image_frame->m_frame_no)
+
1029 {
+
1030 errno = EAGAIN;
+
1031 return 0;
+
1032 }
+
1033
+
1034 data->resize(image_frame->m_size);
+
1035
+
1036 return copy(data, static_cast<size_t>(image_frame->m_offset));
+
1037}
+
1038
+
1039int Buffer::error() const
+
1040{
+
1041 return errno;
+
1042}
+
1043
+
1044bool Buffer::eof() const
+
1045{
+
1046 return eof(0);
+
1047}
+
1048
+
1049bool Buffer::eof(uint32_t segment_no) const
+
1050{
+
1051 return (tell(segment_no) == size(segment_no));
+
1052}
+
1053
+ +
1055{
+
1056 release();
+
1057}
+
1058
+
1059bool Buffer::have_frame(uint32_t frame_no)
+
1060{
+
1061 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
1062
+
1063 if (m_cur_ci->m_buffer_idx == nullptr || frame_no < 1 || frame_no > virtualfile()->m_video_frame_count)
+
1064 {
+
1065 // Invalid parameter
+
1066 errno = EINVAL;
+
1067 return false;
+
1068 }
+
1069
+
1070 LPCIMAGE_FRAME image_frame;
+
1071 size_t start = static_cast<size_t>(frame_no - 1) * sizeof(IMAGE_FRAME);
+
1072
+
1073 image_frame = reinterpret_cast<LPCIMAGE_FRAME>(m_cur_ci->m_buffer_idx + start);
+
1074
+
1075 return (image_frame->m_frame_no ? true : false);
+
1076}
+
1077
+ +
1079{
+
1080 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
1081
+
1082 for (const CACHEINFO & ci : m_ci)
+
1083 {
+
1084 if ((ci.m_fd != -1 && (fcntl(ci.m_fd, F_GETFL) != -1 || errno != EBADF)))
+
1085 {
+
1086 return true;
+
1087 }
+
1088 }
+
1089
+
1090 return false;
+
1091}
+
1092
+ +
1094{
+
1095 if (m_cur_ci == nullptr)
+
1096 {
+
1097 return;
+
1098 }
+
1099
+
1100 m_cur_ci->m_seg_finished = true;
+
1101
+
1102 flush();
+
1103}
+
1104
+
1105bool Buffer::is_segment_finished(uint32_t segment_no) const
+
1106{
+
1107 LPCCACHEINFO ci = const_cacheinfo(segment_no);
+
1108
+
1109 if (ci == nullptr)
+
1110 {
+
1111 errno = EBADF;
+
1112 return false;
+
1113 }
+
1114
+
1115 return ci->m_seg_finished;
+
1116}
+
1117
+ +
1119{
+
1120 if (segment_no)
+
1121 {
+
1122 segment_no--;
+
1123
+
1124 if (segment_no >= segment_count())
+
1125 {
+
1126 return nullptr;
+
1127 }
+
1128 return (&m_ci[segment_no]);
+
1129 }
+
1130
+
1131 return m_cur_ci;
+
1132}
+
1133
+ +
1135{
+
1136 if (segment_no)
+
1137 {
+
1138 segment_no--;
+
1139
+
1140 if (segment_no >= m_ci.size())
+
1141 {
+
1142 return nullptr;
+
1143 }
+
1144 return (&m_ci[segment_no]);
+
1145 }
+
1146
+
1147 return m_cur_ci;
+
1148}
Buffer class.
#define CACHE_FLAG_RO
Mark cache file read-only.
Definition: buffer.h:49
#define CACHE_FLAG_RW
Mark cache file writeable, implies read permissions.
Definition: buffer.h:50
@@ -1223,53 +1215,53 @@
std::vector< CACHEINFO > m_ci
Cache info.
Definition: buffer.h:477
virtual int64_t duration() const override
Get the duration of the file, in AV_TIME_BASE fractional seconds.
Definition: buffer.cc:842
static constexpr int PREALLOC_FACTOR
PREALLOC_FACTOR - Number of elements allocated on reallocate calls Number of elements allocated on re...
Definition: buffer.h:64
-
virtual bool eof() const override
Check if at end of file.
Definition: buffer.cc:1051
+
virtual bool eof() const override
Check if at end of file.
Definition: buffer.cc:1044
void increment_pos(size_t increment)
Increment buffer position.
Definition: buffer.cc:762
-
LPCACHEINFO cacheinfo(uint32_t segment_no)
Get cache information.
Definition: buffer.cc:1125
+
LPCACHEINFO cacheinfo(uint32_t segment_no)
Get cache information.
Definition: buffer.cc:1118
uint8_t * write_prepare(size_t length)
Prepare for the writing operation.
Definition: buffer.cc:745
bool release(int flags=CACHE_CLOSE_NOOPT)
Release cache buffer.
Definition: buffer.cc:494
uint32_t m_cur_open
Number of open files.
Definition: buffer.h:475
virtual int openio(LPVIRTUALFILE virtualfile) override
Open a virtual file.
Definition: buffer.cc:64
bool segment_exists(uint32_t segment_no)
Check if segment exists.
Definition: buffer.cc:350
-
void finished_segment()
Complete the segment decoding.
Definition: buffer.cc:1100
+
void finished_segment()
Complete the segment decoding.
Definition: buffer.cc:1093
virtual int seek(int64_t offset, int whence) override
Seek to position in file.
Definition: buffer.cc:767
size_t writeio(const uint8_t *data, size_t length)
Write data to the current position in the buffer. The position pointer will be updated.
Definition: buffer.cc:664
bool clear()
Clear (delete) buffer.
Definition: buffer.cc:587
-
static const std::string & make_cachefile_name(std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)
Make up a cache file name, including the full path.
Definition: buffer.cc:978
+
static const std::string & make_cachefile_name(std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)
Make up a cache file name, including the full path.
Definition: buffer.cc:971
bool map_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t *filesize, bool *isdefaultsize, size_t defaultsize, bool truncate) const
Map memory to a file.
Definition: buffer.cc:361
virtual ~Buffer()
Free Buffer object.
Definition: buffer.cc:49
bool unmap_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t len, size_t *filesize) const
Unmap memory from the file.
Definition: buffer.cc:444
-
virtual void closeio() override
Close buffer.
Definition: buffer.cc:1061
+
virtual void closeio() override
Close buffer.
Definition: buffer.cc:1054
virtual VIRTUALTYPE type() const override
Get type of this virtual file.
Definition: buffer.cc:54
bool init(bool erase_cache)
Initialise cache.
Definition: buffer.cc:179
std::recursive_mutex m_mutex
Access mutex.
Definition: buffer.h:473
-
bool is_segment_finished(uint32_t segment_no) const
Return true if transcoding of the segment is finished.
Definition: buffer.cc:1112
-
static bool remove_file(const std::string &filename)
Remove (unlink) the file.
Definition: buffer.cc:998
+
bool is_segment_finished(uint32_t segment_no) const
Return true if transcoding of the segment is finished.
Definition: buffer.cc:1105
+
static bool remove_file(const std::string &filename)
Remove (unlink) the file.
Definition: buffer.cc:991
size_t write_frame(const uint8_t *data, size_t length, uint32_t frame_no)
Write image data for the frame number into the buffer.
Definition: buffer.cc:691
CACHEINFO const * LPCCACHEINFO
Pointer to const version of CACHEINFO.
Definition: buffer.h:121
-
const std::string & cachefile(uint32_t segment_no) const
Get cache filename.
Definition: buffer.cc:964
-
virtual size_t readio(void *data, size_t size) override
Not implemented.
Definition: buffer.cc:1012
-
bool have_frame(uint32_t frame_no)
Check if we have the requested frame number. Works only when processing a frame set.
Definition: buffer.cc:1066
+
const std::string & cachefile(uint32_t segment_no) const
Get cache filename.
Definition: buffer.cc:957
+
virtual size_t readio(void *data, size_t size) override
Not implemented.
Definition: buffer.cc:1005
+
bool have_frame(uint32_t frame_no)
Check if we have the requested frame number. Works only when processing a frame set.
Definition: buffer.cc:1059
bool flush()
Flush buffer to disk.
Definition: buffer.cc:559
bool reserve(size_t size)
Reserve memory without changing size to reduce re-allocations.
Definition: buffer.cc:627
uint32_t current_segment_no()
Get the currently selected segment.
Definition: buffer.cc:339
-
bool reallocate(size_t newsize)
Reallocate the buffer to a new size.
Definition: buffer.cc:936
-
virtual int error() const override
Get last error.
Definition: buffer.cc:1046
+
bool reallocate(size_t newsize)
Reallocate the buffer to a new size.
Definition: buffer.cc:929
+
virtual int error() const override
Get last error.
Definition: buffer.cc:1039
bool copy(std::vector< uint8_t > *out_data, size_t offset, uint32_t segment_no=0)
Copy buffered data into output buffer.
Definition: buffer.cc:878
virtual size_t bufsize() const override
Size of this buffer.
Definition: buffer.cc:59
-
LPCCACHEINFO const_cacheinfo(uint32_t segment_no) const
Get cache information.
Definition: buffer.cc:1141
+
LPCCACHEINFO const_cacheinfo(uint32_t segment_no) const
Get cache information.
Definition: buffer.cc:1134
uint32_t segment_count()
Get segment count.
Definition: buffer.cc:332
virtual size_t tell() const override
Get the value of the internal read position pointer.
Definition: buffer.cc:824
LPCACHEINFO m_cur_ci
Convenience pointer to current write segment.
Definition: buffer.h:474
bool set_segment(uint32_t segment_no, size_t size)
Set the current segment.
Definition: buffer.cc:306
bool remove_cachefile(uint32_t segment_no=0) const
Remove the cachefile.
Definition: buffer.cc:544
Buffer()
Create Buffer object.
Definition: buffer.cc:42
-
bool is_open()
Check if the cache file is open.
Definition: buffer.cc:1085
+
bool is_open()
Check if the cache file is open.
Definition: buffer.cc:1078
virtual size_t size() const override
Get the value of the internal buffer size pointer.
Definition: buffer.cc:847
bool open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize=0)
Open the cache file if not already open.
Definition: buffer.cc:77
bool close_file(uint32_t segment_no, uint32_t flags)
If it hasn't already been done, close the cache file.
Definition: buffer.cc:137
size_t buffer_watermark(uint32_t segment_no=0) const
Return the current watermark of the file while transcoding.
Definition: buffer.cc:865
-
size_t read_frame(std::vector< uint8_t > *data, uint32_t frame_no)
Write image data for the frame number into the buffer.
Definition: buffer.cc:1019
+
size_t read_frame(std::vector< uint8_t > *data, uint32_t frame_no)
Write image data for the frame number into the buffer.
Definition: buffer.cc:1012
LPVIRTUALFILE virtualfile()
Get virtual file object.
Definition: fileio.cc:114
void set_virtualfile(LPVIRTUALFILE virtualfile)
Set the virtual file object.
Definition: fileio.cc:97
const std::string & filename() const
Get source filename.
Definition: fileio.cc:124
@@ -1277,16 +1269,17 @@
static void debug(const T filename, const std::string &format_string, Args &&...args)
Write debug level log entry.
Definition: logging.h:182
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
Definition: logging.h:163
static void error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
Definition: logging.h:239
-
int mktree(const std::string &path, mode_t mode)
Make directory tree.
-
std::string make_filename(uint32_t file_no, const std::string &fileext)
Make a file name from file number and file extension.
-
bool file_exists(const std::string &filename)
Check if file exists.
-
std::string format_size(uint64_t value)
Format size.
-
char * new_strdup(const std::string &str)
strdup() variant taking a std::string as input.
+
int mktree(const std::string &path, mode_t mode)
Make directory tree.
+
char * new_strdup(const std::string &str)
strdup() variant taking a std::string as input.
+
std::string make_filename(uint32_t file_no, const std::string &fileext)
Make a file name from file number and file extension.
+
bool file_exists(const std::string &filename)
Check if file exists.
+
std::string format_size(uint64_t value)
Format size.
FFMPEGFS_PARAMS params
FFmpegfs command line parameters.
Definition: ffmpegfs.cc:76
Main include for FFmpegfs project.
void transcoder_cache_path(std::string &path)
Get transcoder cache path.
Definition: transcode.cc:195
VIRTUALTYPE
Virtual file types enum.
Definition: fileio.h:90
@ VIRTUALTYPE_BUFFER
Buffer file.
Definition: fileio.h:104
+
struct IMAGE_FRAME IMAGE_FRAME
Image frame header.
IMAGE_FRAME const * LPCIMAGE_FRAME
Pointer version of IMAGE_FRAME.
Definition: fileio.h:84
#define VIRTUALFLAG_HLS
File is part of a set of HLS transport stream (ts) files.
Definition: fileio.h:114
#define VIRTUALFLAG_FRAME
File is part of a set of frames.
Definition: fileio.h:113
@@ -1315,10 +1308,11 @@
char m_tag[8]
Start tag, always ascii "IMGFRAME".
Definition: fileio.h:76
Virtual file definition.
Definition: fileio.h:121
uint32_t get_segment_count() const
Number of HLS segments in set.
Definition: fileio.cc:46
+
uint32_t m_video_frame_count
Number of frames in video or 0 if not a video.
Definition: fileio.h:156
diff --git a/html/buffer_8h.html b/html/buffer_8h.html index 3a492fc05..c1721a0bd 100644 --- a/html/buffer_8h.html +++ b/html/buffer_8h.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/buffer.h File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ + -
-
buffer.h File Reference
+
buffer.h File Reference
@@ -117,7 +116,7 @@

Go to the source code of this file.

- @@ -126,43 +125,160 @@

+

Classes

class  Buffer
 The Buffer class. More...
 Structure to hold current cache state. More...
 
- - - + + - - + + - - + + - - + + - - + + - - + +

+

Macros

-#define CACHE_CHECK_BIT(mask, var)   ((mask) == (mask & (var)))
 Check bit in bitmask.
#define CACHE_CHECK_BIT(mask, var)   ((mask) == (mask & (var)))
 Check bit in bitmask. More...
 
-#define CACHE_CLOSE_NOOPT   0x00000000
 Dummy, do nothing special.
#define CACHE_CLOSE_NOOPT   0x00000000
 Dummy, do nothing special. More...
 
-#define CACHE_CLOSE_FREE   0x00000001
 Free memory for cache entry.
#define CACHE_CLOSE_FREE   0x00000001
 Free memory for cache entry. More...
 
-#define CACHE_CLOSE_DELETE   (0x00000002 | CACHE_CLOSE_FREE)
 Delete cache entry, will unlink cached file! Implies CACHE_CLOSE_FREE.
#define CACHE_CLOSE_DELETE   (0x00000002 | CACHE_CLOSE_FREE)
 Delete cache entry, will unlink cached file! Implies CACHE_CLOSE_FREE. More...
 
-#define CACHE_FLAG_RO   0x00000001
 Mark cache file read-only.
#define CACHE_FLAG_RO   0x00000001
 Mark cache file read-only. More...
 
-#define CACHE_FLAG_RW   0x00000002
 Mark cache file writeable, implies read permissions.
#define CACHE_FLAG_RW   0x00000002
 Mark cache file writeable, implies read permissions. More...
 

Detailed Description

- +

Macro Definition Documentation

+ +

◆ CACHE_CHECK_BIT

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define CACHE_CHECK_BIT( mask,
 var 
)   ((mask) == (mask & (var)))
+
+ +

Check bit in bitmask.

+ +

Definition at line 43 of file buffer.h.

+ +
+
+ +

◆ CACHE_CLOSE_DELETE

+ +
+
+ + + + +
#define CACHE_CLOSE_DELETE   (0x00000002 | CACHE_CLOSE_FREE)
+
+ +

Delete cache entry, will unlink cached file! Implies CACHE_CLOSE_FREE.

+ +

Definition at line 47 of file buffer.h.

+ +
+
+ +

◆ CACHE_CLOSE_FREE

+ +
+
+ + + + +
#define CACHE_CLOSE_FREE   0x00000001
+
+ +

Free memory for cache entry.

+ +

Definition at line 46 of file buffer.h.

+ +
+
+ +

◆ CACHE_CLOSE_NOOPT

+ +
+
+ + + + +
#define CACHE_CLOSE_NOOPT   0x00000000
+
+ +

Dummy, do nothing special.

+ +

Definition at line 45 of file buffer.h.

+ +
+
+ +

◆ CACHE_FLAG_RO

+ +
+
+ + + + +
#define CACHE_FLAG_RO   0x00000001
+
+ +

Mark cache file read-only.

+ +

Definition at line 49 of file buffer.h.

+ +
+
+ +

◆ CACHE_FLAG_RW

+ +
+
+ + + + +
#define CACHE_FLAG_RW   0x00000002
+
+ +

Mark cache file writeable, implies read permissions.

+ +

Definition at line 50 of file buffer.h.

+ +
+
+

diff --git a/html/buffer_8h__dep__incl.png b/html/buffer_8h__dep__incl.png index f1e5c5da6418ef2ae15b1adef363d75dc780bc1c..eca98c4f93524423d2f46379dc1b677330a55e97 100644 GIT binary patch literal 32961 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

#uQ15V~68D#Bx~O#Kn!Lp}t=m%llp1 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%0DEe;M=#9s>O%2QBe&tBXm?C zBJ|34Q~bh%2opK570U9Z4GjWMpW04W+orXPv18JWjFfp|=~IL3U3pGU576`H>?jbd zGatRpNgNNdOR`s~LwlY>r_$UuSwU_tKHj2$uIEGeJaX#lTxNv7_V)H*%L0&C3Po$E z=7%Liu^EUDnB&K*gK41B7p$cNs(J6Ih40VTfRj~y7wg^I7ZQ(X6CDBZ=O`S^B zz|h%83%tX{Ia+DE@lry9tgDSeS%4A)8ygs;R|jj6KvsZrm72N`cJuJ?5Qs&fh_}7H zeR;NXtyR|D-HjsWAXxeWpL&mw6lQE>?fEKE#@iHL|wriX@JOGz<4d}!>z-*w~aa&l~R^p2qqDVX1?^73XM z4DKm_7Tcb}PA3Fizl(LHixAQ&cfP~@-zfG+tTul-#|ln9`J>tJCZy~hYY`KpDUU4g z>8XB4^ z(>)ErgHJ$j2o9E!lF}<7Lk{7_QX#>y24?wiUR;+5h5W;!{4HV-F5KO{GX);GjbYc@ zTq8TrysOuh5U1!KD{9N`btO3Ik0OC^f<^uLqB~2 z_B@`-&Fn%e1%=4l5Kasj|18k7v){Sb;P@wYvKZ0$3<8dKluVo9At4K?qNf@`^YblS zGczhNkK=9kQnSKvLN6D96(o$qfrVEBbQ}D~gM))TW3aFCQc~tOH+ura+w%$vl%y~Y zRHGBSzqeu>;(qG{aU!~R%T2`S(<_Tu<)wQ{liegyQB^;zhT*NK8)1fvLt~oP4YXK~7j%@v1BgPV zcAcZ`47ucb@N|c!ZxDzgG*I30IGuGqqT8OSJD3xE*;moWii_qb z)OIv>+vn!d5qmwezSYja_#p_G(b(JGMZWUmOVZDum{1mN_2(<&B-|-2iQ{yymlYSM zyI#<}+d(Dxs;rnV#rWUZK7~Md!FqUpKGglXwcZHR9^L%Ek_Yx9O4-qcgsdlTR zIFYzyTEGfBuTn9KU9sc&#`kwNb< zLBv!q5BcuhJH*85_>!2OuW*o3UOmJ&{a$ki6E8lVnh48*=I`J9NO~{s({}TIG8Cf~ zf&D+Zd3hhIAYBL|g!NDjC2z?8W^%Go7))Y$G?d{-FK0-?TMpjOw?&2>o7nEf3K9<3 zfWXkutcLweIw5g!v_v05W<}fgC4y;ntA*sg^CcxAK|!Ity>(bv_w7KMafi1yCoF7e zdD%ovY`;6&W2eLRXc7S_{kV3rh)nbT&@q!~N>k7mR7pWst~6Tw6%O4iY-I zF*1|+V#C9q1hY7~-}FEr&|({_?H>0}yiw8Cj*1Kh_M`v@$Jz0o(#(uS`X_cVavlnZAljPeUVibyNfCeP?QZw0w6}Wu`t|(LdksaMuYXDmN{K@3 zXl!jQmX{}(3hnrQRrKqQm)OAL`@QWwgkW{sb=4;J$efrctg5ndb$K@7ym_$Zywbno z?OQNEY>s(4+bxOiquH%cU8DY%m73oQ=U!V!mt=Z|1-Sxebc~9Dk-gn;rrF3yFDoV* zS_CDh?C~W9WTMqeJWLH zY2*3kHECo%l2~aIV`CIyCSpC~>|*`Spy8~Yk0Wnxc(A_^qWe;y(Fq1lv(^FGD9%gw zxFh_hz?BQm{c7aEvL)%XO%Hvk%~j11)%q#xbaOdz)aPc=r(P(|tI0IaSqe?phDue< z9SnXO5&4D}G2nlpWeEhsed7j3I1}VlEfC2m8S4FsZ*V{G!`5zBjLKS>IyguK%j4~B zjHyk4E7TvCF*rKf>(V34!SMmdU%$u_x8-n4T}x{wEJ~?w>jgqb1C|`IzP&9c`3P_| zC+WmtV&sGk#5eyxa@)tV zNVWU(=NE7)4-~(^W3?g=X!WI*5>$xfqon+vmi8opY0vLJiaJ@8(bI6jf@&MZqs zIsfk+a!qw!-|syg;?Opm%=Ea-PYw(6fJclE9zS-seP4}3d;%Q4NZKZ097XL}bU_>k zp*B`m*C>N-OfW0$^+s(7#H)|q(umeJe){l-368HtQyK*Y_qePs@$Sx-nMM(#ywPWT z@&d=XU^h8DdQnko4kmk=@Q3OZ%x{%;@#sETPUt_Sd4%ha*|K|aX28kWa2vVp=SbO* zT72!f_wliZhlglK$?uuMCETzq`Zm!O97awSPg z4KXp#PN%lgIi0hd9G11U11zx{2oK$d0|GA^8(GaQT)W!Dj+P`;>?%a*6g)i_UMmD% zo|>g4Cf=xtU-YQ19(DX9t8Z|-H!h=3`gyW|y`f=rTYE!Zwy~l@B(%C~mbT%p;a}}E zxFRF_g%KP3c(X=Cq^cA;^~Yxk%avux&GNeQKL{36c*v174+j_{kfF0vJ=Wjl)3RZ$ zPwNw0f9XG2@Mwa?7Oi=Mf;d(S*?DU~i8=n_LLb*3DBpJPp43_ElJ2K{yfG9>4{Z?( zd3pOuNp9?=owBlR@D(I8{eDw*qSWZ=(e{?1j<$zscXWJ4M)G@`BQ&&+EW3zCvALUg z9N1*F-|{VfH|iJZvq5D-m84*)?T&U+2l%Im&-gwR*;!f1#nXGoGe3UZWa6A^UidX$ zszyf__wCz97Hu+qhkvvlsz6#!DP0LK5V)`^BvBjP!Z4k`$dn zxs`U0>Jqj5>xegX6G6*qy!hz1TXy#rbK5?{$=5eBvfj}O^YzUO!-*632JyLU0o=QH zOUe>Y+Q~O0rQCx9_6LU|1YCKBdo~HdvKMGLP7Lkue7T>KYj%sYw8KG*w z=f_xYUzk@IYHXVGdr5zD;cd=W*7+J4rZ*p;&(f>TnUp9H=j%k(pTq8$GP&e!6zoof zhbtJfSNtx=rWUS`cqZCM?dZ=bGrWn8UcX?y6Z3R6F1GQR-BKKocY zrP0Ty?3sqd`~BPkX3yAheJ(BxLc-x4=AXhe5qf&sz)%YBI{b@1|7 zk2Jn|&(Z1f@4*_cz9z$}`#2B)$fQH&J#>#pa(Q@G&^9)xmwzkGTerr>W?Wp*(6Fml z4Jm3R*%^Y}`fhS2o1oe|*5c;)BTH^eS(#o~XlgVsws#ANi8>$sb#F^b_Xs?CG-RIG zQCt|hy5(Ayy{f070s1WW&h9Uu%>Xnb3n)Ri&1vs!K&n%US6n zg^~1vNN2=j_#N~u_DxT-ad4RZHMMc_O#(4`L|7Oa7FBq{7uD6pmbP(bCufw}+Jfk4 z&L6E7neNq0msFrKJuK{OvXz32`e9gKICfRI_r6y9Ww1mu^ z^TkjUF3WS7ltv;<2s2wZ&!o7W5Ams~|CW@95&3$155R`SL2`7~Cb)YSAbW!N`=tJr zm8cQ1qyqIkjJZtD>z3x4c>Sjj? zDW4Qbl{Jd`=ixoKEd+fzqkM`E#!d#=!KfR ze)%#e$P=fhV*dVUv$bmi?)6wmg1WjJTvqkWG~SoL2?@(NpW`wxJb`TqUrR_CSur4h zurnU1qnEa_Y7E^+t*xT?&}EZ^h6#!d(EFSK3GVdt+la zkgmPsdfN>uem8R|@n3AN)#$u&b9cewA~hp8jM04$4seNlL2ZIrdxlj~#nnz2cVXGk zMN;ysuP+Ib;6wcN-FX7=8n%}%JklFfc z)@=ToI9*Lo{}JAkmm3(CsQFRf5FZ_Ymx#}b@SC47lWu?c?pk93;kJ53(#dg=4g(;D zzKF!r+emEq%yezZq-Hl4_Ug#UVjeu;#ly}hvIwH!=EkQsK`}wm11Kx?r8t^)!qtziHV%;$hB*Z^i^Kx9;9T>ln?8-Ij$MO&KqDDh7At!~Q zeTwJ00_7V(ybTS7) zpwn47kmfgb%`rVGu=Mq)%RF1(93C8y^L!3!(&4nyYW&E$3i>#LDX*0C+3sL!>_dWd za1inJE2LKud3l*2F$rHET|A$B{3vBP?R1YIs=)xG`<^!fMpEFi39_=jsJ2;&N}k1L z+UdLcyU}1a>J4)V=xHqoe%>$>SGfQpLrDp;k`l3uj3XM_d{B_)RLI5ys_@MfLd{pN z9+3B^u>^8il+cAggflMlg<^e;J7#j;ML}h(+_2YNO-*9S!qC}S&d|{0?c1gT&0;@n z`pI$PXWYars;s0z#3XpIAS^7oQZZx}zgUx}tvYY$)Iy>~(KsJaQ;n+16i9ezX>vjs zc!wId6CC2BM{Ifd2^-nZo5-K%B(MthjM}xO2+M-Q0h}*6R;_DmwVpDPVX|VjtG^KV z+3m%$pZX;(F9qPpogLCjihtT|j>t?*^e$j-o}-Kg!b(z-&GY9gR3}_mDx1G;Z5KqI z@Ycjqus?{jn7lVzxz|6ED`&r1^xKXJLGcQl1ju41J=Wv_vAn416WCo-Q_WyP?6=Jg zEPAIzw{nuht89-TJfGqv~kTx|P z!g(O&wZuS6S&LPU$q(aZF)oM)A*96(Gx+k#;|kC>?3hyviyah}l$;tHqvJa-ju~?? zF)6amaRnCZPeS5q|-7WRvuq?MPSKR!lit%|hrt>>NoEI54`T0O9t zBVaQ0BLoZ7@0Yj94T*e@cA)+4QKg*)UIUY#^_&N_zX%p)t&cQ8TdVl`hPsdUfT?Lo z+GlyCi|E*=oOV++D!%%Lz#fu{?g3w*Rr!jX36BHU{p$8u!EaG9{ySLZE7uR{*$c>W z7Z$Z2F-Q~_@w!`VLF*l>qhn`fB?6XOS*iOm?5gziX25qeH4Ut+813z)^e0f`=w#wh zTdbX(vF+J`l=QB+n595t58B5tb4}k*&$lo-IU&2a0z~El1dJc6re^9RBfnRBvVZ>6 z5AT7A6Nh+bNPR|!8eeSH@XE$< z-1YoAI_h5aB`lFAYHv(ij#=wqY1@Vl`Rl7}g)9v;?;8RQt6zw&ptbTnZP4kdGV=23 z*g%*tTWKiyWJxI_XcTZ+)>6^aug&SKuA5rwru3eC^KgtVEbN7SMosk|o5XtQ`YBRe z-)9oP>(Pl#RxYDi^`8d!+0AXT%x?_jc#HkhCKW`!?MIZ|YkW?M0E3zuaj`%9StNQS<}-~s(hwV zWZ~g*ZYQ)`KN(cqw4a2D)0~}()j7yVh849AgbgnW2M4>)lo%8PE|iyp)7b+VfvM>m zP;iZYd@Gjt=h({x-Xrh8z|L^$zH4X>=>{ZC?YqbIo16Q1^r}VGHYRKI*rBM9Ms19_ zo|q-Z4h_lq`}=(RR>;fa)YC%;4Sp^okJ#yI>ff1tHBeN%45$9)hg~>#bZuUBb$g;1 zX8?g4D+sQ%F^W$jTe;@|KD^#-%W$h?!O5x1$>~r~@KD?^I$|G`d$QKoOQd4@?pMUd ze)+OHnja{e(0FmYc#|{#7cycI{rc8Y)2?86jHUdbJe@YnJwo?`-A}CS!`1IwYiUp3RG8^IzFrsl3%esd}z6&<=5Cq z3m`>4L_>gd=H;A5B#>l-K6R`ZBclL|*15CgwpKawA0Mz7R^W9L5)(g0Muun57WT_F zzqz=JmHt$l>>ADIs;N1HaM-}2EKOXF1r4>b*e1*3RoK^F>K7E4d72OQ z))bs2yEv5%deXXknEw6=Eck{t-%}CT1mbg_qA8=iAyFB9-xN3Yz z9diTm6$MP$NR7SrJ!VV^=_wv}{>4be=g!Kdy249Kj1HymzkHoZ9!PiF-Ar}BSJOaw*0xQYEmrXJk3};-J^mvnHhR+>-axloJVi30}Z>)yC-05gssfES(vw5XX^ark~ZV{Vxuk&5!bGgSld$< zB;xQGm5JE-&<4Cvtj^Cd25(yd&#FTO^^7uskEK`p$o~_2`@)OBm7!K&W5!q{5HRYe8k@nhK!eD?vxwwcK2BqXM(YTKTE#Ov2uJHOs_kBu#_Bv%Q<=xLKbq0gdX_y+mABpTXXUfx^f zb|d6?HhBjTNGjdWrZ(lNZwOfjR0SZ-@b$e9wE$UJF-b`mzW6b~@zu+xIy%ut$BbNp zkq|`v;DX%WzkdXo7r(okao%E&)vQ~+k(|(r##Aqqs;YC6it6>y&aNnTP~1=8TkG17 z181t7U;WIrx-0mBTdhDpYP_N{aG*8gxD|qbqg)p_HpX7oyE;Rq7JKwEwSYA|N@-?z zIP^ozhxcsD+s%hTA9a6?9tM>krgw<5T-V)P&}j6}js7eHYIeM|WT7{)vE1u^xFfe< z$?5xHL{7?idSW7&k3jW0M|Qheu|V7kF{X@+=DTL0N4bte|FT3>U{&!?&4+<`S9due?TjG z+UcRm^ivGE+)YG3@B))T`htt&{A5+0P_Dn~V26P8;;6~X-qUN#eyao$e`+9HNk}`q|0K z=hRdu5=(k1(?vd0L%SU zW1+rOy3Rcs!=hPG5JM-6ALu{dP&PUKqemJBl97YN<<1PL^X2)QXw2jMYg|1xbR`Oh zfB--v6Eoh@!cag&eOd^v4%OSh$cY=amCAko2De=8=DM^o_BS*0%|Gjj39iuS{331d znEzBe12j~3mpX&=+BIBU%zxb{BIqqR#UNb&Gp5=c7kAHWLqSbVkV!2DE!Hzo2>e%t zOxzDSmXv1{fETy;iUYnfFz~bo`>d>(`}d|fl{n)odG=C(06yM``1UP2KE4%3c0K9O%2*_@2IQ{3_EH; zr(|-uC$6RKXPj?}t;-*j_& zqw$PIxn2sObjK1Q85xYozjObI7<{}Xg}hhjgOLS>bGG)RIt=GDMw>``;Lo3xK6pCi zoO1SZ`d6_Zb`UeM%$JvC*90@Ef@_DV2pzvfUDM|6q zTtUIkEh1c=$Efe;4pyz_Ka@W^``l)Q@7GcG*OV0M$6J55CRt3)8f4=$zw5T}&Ftg| z(DCpDK=q;LC&UHjQ$*uaL2?pkBpW2Oi@{!Ay2jbG?~w4<+pC?XbG(B8Wuc4q3Z`ug0LRvIcw;@YOg5gwr)-a%HFm|#yqJi?_L0;EWGN3McxKU6pK7iVdv(xEIa%~9! zxV;u5Beg|E%)eJ;ZS>M5W^4Ynv6+3#YOFpPJ2=SiGN$A%4V*H_0sKWuidYTv&T#$p z1sbv|tl}dg%HhfW2-!u#y=OK)JnX*uiVfLoywX@B>L;Rv_&?j)tz!8T!$)S@OJ(BoBxt(e z10kq*zTS!NWjS+DT0Uw}-)g^8PeV&U zM^l?_H?op8&Y%Vo;Iwz|rUV4EJ)wotjltQW`pJn>h2@2@etJ{=F47lBA{<RtVD zaj9~ZV+R}bAX63%JQyb=A`g!|gQWJUt)c$s1?yHVEfsoM{L<3+&f=cUtmNqNNx$VK z#b4vZMKzBRI0#rtY)3~p`#a)0jQ%3~%e`aCe2(@P)hv;ToDg3@stU+)PFmVS2hG20 z^fcZ{oHA>@@nWc{_Bu$IEzXBDh6YjXKaTs89(!D@Kcj<8O~(ToTr4Ol55QV|*#5h> z=-@8InGg^VR9F}cx!_8FVr=Xz8#@ETJM~H8&AuMP-q#fsT&QTB8YTL4Qid0|5lx`2 zd>IxlZ~8X%TLClg`AYz-+^;tJlU3T=QNF~=80K9zY5q0Pr-^3a!n{M!Q*f%sW|L_u z+G@mu(ZULf(4dXbR0bmmdWUt*bQYUF-U^|?5bAGC9(n^2T z4M%_ddbguR91$xa6$n$>yj&HycE%Tr9QM|FdS1VLIf~7C6LABy$@yPU$(NLN-@17Z z>q;Krtcs(ug@w=xD=R~t{D^nIU{@LTymCG+is)-@4_$n#rwzkC>Kyhk%f+6$0S20y zWz;yv_2^O8O3e<{#)dj2>iy)z({>RVnR}f*_wVy;&$6`42VAGnjEq$d#r)mu?9ZPY zynMOHZnVw&jL6eZAHiDvjzgg#KK?<4u+A&FP;rxQsm1RiE1x-bgz~#54Gd5`wK2?1 zUusm%-P*(lBI^xbc{VoJNV>aAOHPBv_s-d1b|#xz3yl605*CgP^>$25OpS_)?CBN2 zz)%olk)TTH?xz2iyGVfV#Etg=Nf4U-lX&gTr)T^Y6VqhyFokz!yU{QdzL)X7WEmf% zyu7Rn@)5+jt z$3;i?-Z6ae!PM9oB&)dpfSCI=;bnAWB#Ku4iI>nvsO6)Jj?sJSI!Tp?!1BAe)YjDS zM*iLH8ze)+6h4pF8{9ehvjP)KbuZ5_fBdKmd4aRNiLan^5pzO>OdbA8NXX^T&sS-T z5HVooQdcqsdP0?rzfeww`*J2!_hTeHitQfVu>M{ZQWm<~R2L$llY`~)=YSft*Fjte-s}RGAotiWN;$9MwfE{u83+eWeaCyP z0e4@D)vd`2kh=l(tD&KxXC%xlEd4-<($LV*)+YCBq2vYGUUQHIG3J=)>VlcH-ObHZ zbaaLtAs|%3`s7LYXBc$&>K8m*Btek20(uw>G<^+xRAps;>$yhpCogbBN~h1y&p{|g z_6uuMV+$iiJUUG9T;15<0$IU52Vj6{Yikqv0$Yp{ z^;$MbU40VRU@$?p4^**X8$J4TxVwRzrpYikRnY(O?kT!NT5_Go7o`*MzBBdhA&0W}FZ zd4I(0L#K7!OZ~xf4=ZT8b;~r47LlEWF|;++)u74)LUb4y7~FQ*x;$>lYc!27;{yyO z;s`1DnrRbYpe`*f%y0rSMpxI+$Vi5AUycntG`J+M{2$yl+O`Gh9N5dOm@!dN{t&}3 zjtvjD%v*EBe|4lXp6P-<>`2XMObTs6LFD~6XrW2N<3jdK;1J0it{~v0qpCKm4 zENK=J_;NIfGLfCXDDX&<5 zu+qwBcm=6#+cbLp|N6vX-hk!Y8DCvlsW9li7iWvr=5=k3uxm@s`>_SituN0{Dl4Dq z>FL2Z#-1K&eO_cQ`PZ*KDYBvVsGwlep#?*J6B84Gtk}YszKtq45J<@4>E#7K0zE}w z&(B{yKF$UStaG67!T8G*;#<9Tpm~kVm6M-;u{NB=qFw)rut+#n>#ylkg--+l9pi#Bq>DCZmgPnF8hCVWb~o{fha9mS*-DFkoyCLrSRs= zg?5`82t^9YGj|sksIE!!yI*e3&(E)|aW7?o0vAm073So3Ixrqg6-`q)11cwVEFp9cg;US3|XT5UnZ3YpR=mMg?{b*Q|tDFz1x-cgkjVm~WpsWq=`WR+U!%&6A zJvhZ3gfd1(D**ukMMXtG$OSnwn7j*CSJ+k)gO2$|3wk&@nL+I7}iwed+*pDeVTg zJ1y2QUlG|WC0Y=fSVCNUb$xxN-t~d+yvcB8Sw)2c1`-NN;HOU-wGQugL-O4mq)1GmD{d3#zCik@>mT#kmTBA|BU7i@}>gt-RaITvebaMaJCufUJcx6h?M&w(l zQ3aBL&vl!NWyFB>8Fb2E-~wzExG+@mlYD0X*Vaz@9^ZMcKViN@N9u zn17+n|1Z#4%vHDor&~$tNujqjFC#9lqifN)+Bmpe?dyxYF7&)yg?yKDVDKj*G7ypNcKh@hh5$J|`T+?<>L@dw74ZvSxuGf1cKS*|Z@ sV#r1RU6q(HFY@1|0hz;pe8+qyU{MxeTS*pwT@FS_h{}o-2R0zeofqxM0j2F}$O%<2eGkHH5Z!C+=ZZENKPnhHG;mi` z7mC-H&9$zpS2_v;P}aKWHQz+$kRtsWU^4P)>a9KYpXZb%A@=b}`giMr63-*oCTr__ zWH(Im70(a6DfsifM+EV|FGj`%g%F;;5@3?(`R_YO2*~*VebM^ozn>}QcD*n)G$bEY z#IRoP3T^j8BjZMa{6Kp8Jq+E*$jDONmg>KMiMcUIn>-&}r;0QpBH%`v{`=n+I5;>B zj)$b&D5RnItbRKf5C|!v-T(hS#3b-fZ%B+sZus9DKlk=Qg^buO);sL)O%`%-aUG_8 zgn_Tj#&czpIMCXembwoYKJoLvr`&~yX#V=|hnu`$o;?vHM04a!Og4}AwI%vN~89Weww9(L*teh$HKdb)dZEg2aZd;1ID zm$)U`4U`lV4yS9P?k?ZIe_w9)@c#8HBs8?<+dPNk!3>Ynk+Yi{>}uY6b8{0ZV`fHO zOH1p>v%I|g*|TRHRtwH+9f2DghRxk5C@5nS6QA5~{)UIYI$qz~+oRX2MkVB+BPTbU zEjMa;xYF|Ux>pZZBrRaFcL>{n_MRip&@`}b)& zO|G*uGaq?)TAWWag_%V}L@tgN-N15zUlI04?+kAv^scOAJH9JaEslzgCj4lVo|?K; zW4+9Mc@GC!d{!y<3?ji{VX@C{F||oL1sHo)Rw~y+=!el%=4Z_UWxVR=JCg)3hy9WmYgu<*rK|we01fgBV z6+HHI5P_QK;9R5^9?oBn49K{h=y?bWvu7OGfYrpJlB1)iZ*th5O67GsT5cJJYB@Mu zg3B8xb#!)uN3-!N%Fj2mwCw0EYxaQV=I2XNM$cMu_s9086d4E34 z?}EFvv0;Da0^$|D)({!8WB%%WSE-JN(ai}jCFT6q0GG$jN%Y^pj5#^%zYY(Vn%w&1 z85tQEjwTD^8ynrh1|=2iSz8b5F@YP=)zwW)NVsW##cyb2#7^tns$V9T#;2{VO+-ZW zur)}?$;k=UgC_RwWVQY7?rvper5cNcii(Om#S>fze5bOq^1avnDR`G(yhIRz;pb$A zkRK(+dg;FtHGW|faT|82#R{8+FhTh$!ayv+AYcFw^WO7@ zgp)JgiHMQ0R543zHJ$|yl8*lw`ceiS@Jgvz3xf+MI67V}E>bZ$QZXu41rsZ})6iB^H${Y!Ohv`F z%A%Xs^FT{eQz)mcB@FVz3LTRL@*`q$f-N`ajmN_sJ$*4XZ_`KC3UaDE>=uFi++01& zB8|_VLot?nG09o*KYZvd(cC=PWS7$XeRr{&cCQK^><9r|L?CZsYHe5TtEQ%+R9{VH zW#+;Hi%&!dYO$BsV6(?$o*dCaX_{YTq~>xnK~NA25{YNqlF#QUH4J4m`gP!NrhQgE{;y^KVUtVEBrJmZ=T6G5oHVYZcd!RG2$ z6a7ph@Ukot%s6S8Ff}nrh@C8A!t=w>ui&~q_NsScL?_8EqO-OvicFeM8Wg*|o#f_j z5_#+(m(|u*($Ue-(QyGUPfzgTN*PMv8h7lCdM)CQ0NMGkAbnf4`5O|l=Hs)FoqeC3 z{R{kEUasjA(cE0%E1LE}sfeD=eqgZb@?H&P71X33TVNHiFwail{?5!41qE@tLk9Y!oHit|u(0R}3E@>#TBEb!;O*y1 zYJ_t>&sYwH;B#$0&og};>)*kKJ76GUQ8EW#-) zJJnK>B##OWg@gO~48n~Dwh~fMROALrecV+V%9H0hJ*`6(L-Q5lU>>cko`T(OOL`;j zCncJ#&;HPxv6KUgXTHa;#F;g%4ejb6(d_G}$yAXW1qDT^PSf7V zsydyrQhR>!=ESstpPw>~%D-$HGVj^ES1PJk{7KuJWy;FbwzkiXSUKZGDai;z$tgsm zqJ-E80>vyW)LdQvR9^V`cCJN5`Nid{v)M-mCuP$Q> z%B}Ao6LNDiV`G;xMZ;88U4{LxRFttBaV%tI4Qy@UJOf!jeBh_p)Dnh|7R$mTv_Quj zG3i9vR?5?1!W(p>P^30wXZJmvryBlk)UAE9*&n~y;8gSJc_N)GC9MK=6E(IAN)B$~ zLa>lx`sdglLl?|IKMbJ&C7s9G3=-K9D#6ccy6P&I^<|Mm4a#D<)}=aR{e4yyv)|a2 z%+W$~Gcs9XW#YCq{Jwvr^ZETTSqwc7xt-u+G6Jf_n$2&fqR7qyQ}erOheC&M#aGQ9 zuhi+#mw(kGk3-y z+=~>MATtF*Jc%>BJ0ACq%H!4i1CJA5RIed=o(l;liZ2}_BR#EjMfq4o4QF`;D*>B? zt`y4SK7s&?fDnR!Q6D)%frLagG1=t{Pmln`scx& zy*<=&vh*_GCD9Wc+~4KjaKg+1&I}foEG;cB7S`a@mL3uJ#mw-rkrGxgkM@BVEU6&l zG)3!!v{ZpV>g?hi#_KQ{F>=h?gIQ55Dox~*2^$$ox0@6Gvvb-n+VqUtXB!VH!tfQk zEom4+ARd?MtH45Q{diDQo)}E?Iy&F}f>Rj!tS&%^q_g8bv-ly+ad$Y4>fzo_;`?`Y z>t{jpHNz>be;!XrpzGqUDk|O~sDohprl$T)O^r-V2`DK^{!oB}Xv2e3Sx<la-sRsHF7$#>POr`w<=e;qK~@nQ2Vh_L{;N(uq%cBx?Egd$}TO%>$E)1 zv6Qwc<{PT1NqfO4+-rCp_BKz~hb757WOogX%<}W0b=URACh_2$uGJWw=tOlP4m*p} z!a>#`PtO;4a4^;alXE%WvM@9hGcrmE3c5d8?P~YGcCu$XTGp+|a$8?A4W#;NW+sZ~ z_kpJG_iu9zjonqrgv7+^e`*~&_J01|ySkpYU(Ytev{mS+|KM?7I5kV6f?69Xu|3TA zj=x!HR$U3Jf9bI%D$4wR{B%5T`8V34Y>F!>M_d?2ra})J0R{2D`QH2%2qGvT{IIvS zhnn^lY3-a=Mdk*>y}ipE*63m3!>vp{7##MdE%Pj5>liDp$&qK8{Ugdn{JDO}?3-Cb@^Pe?ptH0+Uwg0@gZP|)?}`j*)(KS?5r#v1sdx+qrC2yxDI@WZ4b+jZQqK-ty$Kzbu?M5)_qR6G9y4^6Pwy&Oe z+ON(gw7@VqIs4__WoG;|Gr88%(4c>urKS+ouCe-3VO~fj??=RY7vrV|$Hy|As9_-} zII30s-0oul^e4zri;Mo``xUaLK-LCbKkmE2hZQU6!e8&EH%ve~?dg_dF%7D=!~fXbewE z%BiTBU1>%5MlRnNPkdS;4!RR%8VzyrM6I7~bDFRQC-xxkgajG>mUxi1(BA%O05zgF zx>%C@^XJdah5N5j*CU=X23?V5QFZm`kd>3DDDSb5kx^ZCHgBW!+PWQ;%*Q!PEllJ{ ziEM8~-mO79jDsC!=ERpc$=0TNq&~*O)%^B7-q6CRs69eXeFohyYU)2W_6IF`t$&fR zivB2%8V}1*@^IBbTFUXUqGO|#q%tC)m*f9RE$3$OFON$lDce`@A#HG=H(LAC*vLV5 zAPtHaE@Lwr8xuXfgZ3A?T-l1g{{`XJ@}qBl3FQ&yHrvYsF;-1kV@e=l4966%;HDSn@3M zMo47qdZpA`&QiBNlaQrP=7riTDypc@;Jggx8}#g7)qDNg?D5gMt*zPAoMtHP_^)%B zl1V|g1Cmq38%D~7k$)ZXOm5KTn@d?!Oo)I9sB1s)KF}1PqJ?^$5I;UZ={|he>xs<8 zqC~a-jz3bAEKNGU1D z+t)8TgHsK<5|B4*RaDS~{SHd<%}h@T$2R*@2gd}J#=lKY(of%ar}DDK(|yOJ3u$ZX zTklRgT;?wfb=a}*nk-bDE)fN7LCAZ4o7P`n$;1+n96z?MnCMwr;^=6Qu~%V`80w`5 z$@4rF=*o%M4!c*7XHT5VXZie~WHE|}= zN2&LxLgy>ZJ{=3;#tTbIz8IX!R_L*{{cJHErd4n6lbqaxNJdDgaedsK!VlwSW?mlq zYyvU>KC5NJN-g~xT($1*?G|H%%Bt%6-|Ky;lW$6St>!!=2|&BS=jG_Tk^$)f{iU~9vUE) zr9f>cKO6}j;85n3LhA|^%zDXPK1(rIj_6>QE9zgp{>_TU6TY)lm65^m+%q?)SsNcJ zDzZm>#jzukn$uQ>eVzArk+DpHT(X7E-nKBNJsVCqgOAqe*{^aLU z5o$tUAdV+VIrI(jpAsu1^sv)Qw8DI|WS;4-lLgF!+%FtL`5%!$&883{CkPF}FrP}v z-)wyJMtl#wZPH_zRi;T4%1B7EAjHqVyQM!EONSK}6g+l?s(ZmWxwvv19mRBX$Qtz4 zym&Ir13-x^wFGq@WdGh?Ni@84Z{69q90TgIvgQ5`a2PmG_sy-_g0s|k`*?Txr?1Zy zU@`y~xw!H{Vr^`OSmQG(DHZ>OcWAh#+Z`MGEgioE%AQ~Q>Od;5{o&mA=S!Cwy2~PY z@x~^sI~Sk1o5<dGQD6czi8Vdu!Vr|S&##a{ivE5+S8*?&?~$yAGNJs<80!-uQl z8Ea5Rumx*R0%1RYMuJxCPyUD6hIxAJJrRkpdCa6iNqLyl32Muw5BR%2!#nk<&WV&% zR&I^u1gxwiG&ZuhxPVSrN>r4{?<=MXaGfKU+<#Dnx(3+8!nu;>Y{A|SGschYx zu;`tha>=Jrii(@8Ouq*`ou61Ktkk>I#3-j*OESa1XNckQ+RJXUkH_Isr$0VCm48_f zmG--#A$B-k+3{?};Gwlk7zPU3L#3_JzY3Eit++yB1tqNg-Ek4H#bsq0U0nn(ak+<5 zc$60im{#VF{FYLTWuE=R1^5OD&YFtU3ZIE3v164O4ebRL)i{^kf#o+h``~{Y8^1s^ z(QLP!RZ>!(x839W(m(jHGauyW`^u6O25&JS^)U+F~ z{V7BgU$$?*2csy+K$9JaUZCR4Y43h=u-0E2M6EVbN}JgZ+WGRm3|ADG#niL)7PTvGq|j*hi_=b zh7-QhZmAhFesQ*2>p1uES>~x<1r=C2{_*l;^-j?HLiDxzwu%b-N-WFRSWr>X#V1~I znIvPf$Lmkki)f2OLlR%j+UF?f`S9&COX!)=*{>JdLc-JMhYZA4 zC@*PCbwV5MKV)WR4$aOk^jl=t%HG3Dsv9z15zVO;9pS>Iqk)e5#G2Ns5fzWmZe=xQ+;O<5!dDBy}jra;@ zJlN?Q9<%;(rI~k9?3Q)Q?l>$aGDEwiS*TVq5Wr2(vkf~vJwpI3!S(F6(Np-n63FAe z+*)zk<9&i(17~ss3+zXBHug!#&rJ>v4n}xmv;3^0fxP9HOH18gZ^gvQvJ7A^Ui!%< zn^J5=XVya=%ir=pe&R`DHjBEZMlJd)}qO_sKLO+osIgn6hc`AaFfz_vyz=k@*m$~B+-@FPq|Fm{LX*A*@zRh>an;b& zWOdkEK_mPU8d6`mA8E6>89P4@!y(u+0KNW++`{4mpl%i$EPQd*rt?dzYMmI5+I%@d z?$p%SrB`RNoTB5AWaNTd9Qk3^-WPE~`Q}>)ptphj{nyDj0`rZ%?YL19nV9Qy?YL<7>4e zPz3NyJ^T`jUVgr4Z|@5kN-Z6odR>0BBfNy1oRZ`({{25z**8md!=oZI=rz_V?RSxy zrHaXEkcyl1;Ut+DZ}!bDfQi6B3n zxXCm!tLA#g%8|DHy_Zk3%lRcpn<)$O?(Rn&f!)vG<3sTcC}aKwbf(L`E&37 z7X5sS%RY%N8P}TgVrOTdpup9|#SCD?5j3Iz0&+uvXYMtq34o|d7rfisYcrG8{_@2G zq@aKQoVdCBKqtm(Jktj2Mk3)(`Mx*Nzp{cSE8A(*FUF|ORHUW4esNYWkr6SRsy%V5 zO|QA3tE_x^bLw}*mJ0Y`_gh;L1qHU?&Qunok#eIfo(Vmvasf{JkysF@Yk&Uy!A$cQ zo)7$^#)!|#`b}xvtNWi%Du%N1gm&%8*1@bA3JOc1Dp#B=ED(rk17aPR|;1*EX8y;$;-Bxn0+S{4|JYm#jfYT1= z9`4xK)^5lhOxh-nX>xJV9vGlQemOs;eY_$q(eqRWk9CrZiYAIQ9G8~J+~i7`cKpzN zUShHcKtNJ+LOnR&ZuCQ-1aHfSFlEHa&761uDu28G`{^kTdYywx$HQ7Hjt^2ypq24| z#qR;-P${o}=kWRa_sev_mW9STS3t{T9GvV=x0M;ZO66;^>5CB*n$2*gVJJaI4y?2P zur^;4l&X3gV8@9^!C3E zPV0|1WR;njR=t>cfU6VAkZ9Z=Ei)MA^XMz9V4W*BYK)FX9u;&TYW&g(y>3A%E9&iw zg-he#2GXcqjl2RNhe4YT+LBr<*!GaaPU0mQcsC3Ph{GEn9RwL{KChwqy7MdlR~L15 zL>$)dO7rt2^qAIu)WEmSl;IF^)S?rRyMXomKu+%1A4iy&i0JF=%S>BnIPvG9JA62a zxm{HqifxyeNCA?aZWDoq+VsYj@$M%3*w9eGPC8QiJQ^a%;H(!E72VKvN31jC55qq84Im$tM&Es}88PE9QrURD9 z`pwA5&GiruWN&~V{KOb7EIjVBFzYj}4MCC+v|$unGtirz%|Rkrk`n>MF~B@)j-h^? zYtLVZ9xuZp#ImfG`Fa;UBwoR~v5#Fhwy%LyWV|=gO2}D{Pf+lh2s=`>wE45rxbtm! zyp2;*lGfHn<@JhSI5;rA4JLsR5fOxVc=(u@wDhtMtNyJ3DY{yAEu;QVasZmij^9!= z=%boT0jor|zRaQrx}pEKD+l7@N27lt8;A3ifcJ?`)oBEYQl4K{Spg$>l{+&gej231 zmcjI?qVH1^F*haRDV#26-?g;b7aQ`BJ%*Dw5nEi&*-7=qIZN=ys{gOX`^IDq=7X%t zYu@9_{R-`Wy#OZ-0O?s-TW4oaj8oM)T7zZcn^QutToKTgth-ZCP$;w8J_Kw@L!HLs z-TuToKBSIASCI^bI0lEai?_%%EH-F(f9=kVYbd0}kUWNOZ#Toj+`M2Ocj5f#xOYPo zNdDfUBH6dl7UY-E%>4Y1Ud`=mopLE=gmcdB0{XQ!ah3O)Z1i#w@BMEu+``Uk@O z!-sq^`o13yz3P_@A`%t=(X+WBqDjNB|4$?j`Rh&xnJ*Ze!j#(C1lP-TpXTPY+M{M zFsL9PNC02>qcR`FeJgS$kmzyE+}rcp*f@@Xt0-fRxbV`lvz6ksZhrkHw%Igty!u+Gc>wbEF4so|~&Hjd=Lb?$1raTELhOr+PSmmczgx zRHZOEPrk-igQvL8i{I*U@87_HcV^O7mBlnrI{3xJj$&f^AG8qw2tVI)BM4=2*wX{8 zs)A%yij-6VzegWv@2U^{_}pvDvSAjBb^=0EXy5yPoHqCs#PPmQ)c%Ea7|B)5?*?RlZzbID$L5+^&v={ZlWFOI;3TzDP?GWs;GK0opP{SbnKx zcux@|HQ+Bv|Me>uI^OX=7G-C< zg3P%;RR6iR{i^D#= zuh4IfL1UoPZf(tpAWq8K{0H-X5|fa<1ES9`qrB`x9*Tv#yWICve$W}sUf-T@A) zDj?v3-J%4jUAoIJuC6=+(etDM$A$1h6i^)0jHTx%f3;ecs^s4%7?Rb-#8?jvA?h|S zm>W;MSw02l7PxbccXnV7(8LrWHI+#lnCHUndFlB7)eer2KVo6!&&_oKnV6$KqaE!p z=`&<}xRWw{EBwEJrMtVMybtN7RZ!R1MSEwNo{MlzQxnwQ`gqTJaI#7T6ec2Wwg&Mx zAL(feo1B>!midzhjfYdww8MSYcgH(&q+wFh^ULg_f6Xlj{n4NXM_>HE%~LwGuGYUl z>VS2JV<{_dm<*QdHqI!DBj)~jsY|#x@;{tC(zLnH3(WG8ks?&QrNBRg@nA84I$dQ^ z`UGP0(kM%Gc;j|#>g6OQFYD||VRy7&RO6}*1Eb@oB@%qd=}d;3x$U-8zATh5@T>t6 zJN%so!JA9|o9RMeQ=tKrG^2J90F-u)9M@+A$XGDZyyoWJ^X*Ufea6blfEePk7se%( z=f?_5huxV?sBvlYRJuZ}*v(FM75IL!+S??z5h(Q&q1 zQ93TXB1cswugwg zy&jor-_n`WH)PP#^r>qJbK1i_P?0ozU+)604&)HAfx3nUe;=R9FFGod5mBH2u_DCH z&&)KUg60JMf?&TfB4Vak%laet)%B(JNLSvsYo2Jg>vxP4Ioe8CTDoZ=UoGLTM&@Q; z+SqNUj*flicC@rodv|evI}J=B0U-cATZ-v+yL#4KULj5N_Rir{5SPLJligNq>2WasW5Q^sKTe3ZH}KaH z2869a_x3fE3$Q|`)`MOLNf;V#0DslIj=xye%8P`P_bncUH$by&N4)cYHJg!t9kSTnT_X_xC#d_ckmPIqA8%kwPSZKGaa(8TifK(I(X0 zmMJgK0K(wS8wXm|=OW@J$sd`mr|23StzMY0;D&@&p|y<9jwlodhXc3-1fT`RmIaMw z_sY~%Dctwkkox-ilj^<1=A;Prtl~wtvyCM{*pm4q$Xsm?yS(Q&ZgIm6UWvYiRnd~b zf5T%+5BK+9`~k;pY^-TxAvp~UKaZ!~=d!XzZr4-aVGqv)0?y9*0A)8#Wr&mk+CRCp z$NA~&&Y$oV^^ZFcdpKY_F)+|GFi8KS?tDr*IvT)?H+l#mO4;*(F5uGPaXA0wGc?d% ze}ERf_xzY&Km)ru73=Bx5iqig>JyPc0+-Wk#ugMlT$`S5+6YGgN$&>M!GKZ#o!p$0 zt7|yxzZ=BXyE10B!!4?+;$%5lb7dYOfs`~otp;QWd=ha)NB}ZG%n1Oin9r6=kLS&& z^0z$iBKs*}WWpK}f>f&$n5EDIT1Egy($D5J>LZ%heO zbjr9t$S(Eor;MEzglZeTXr{7T3lRQR7AcpLZ6tJ$m@LaV~4s!tzU_n zo&62$A8-!FM4DA)1ShzcIPR(~0%sv;a=9yefv*dg2IJ!6#VMm*-Um|)34BCHgx+o^ zZ4WhZf7f4{t6C30_veQjG9(__u_qPp!4Lvn-#BHB+x1#h^h+dEZ}o+mSapvBaCWnE za$eh-jwsU0lVD**Un#e6a&X}Iliq4O1+gX$45#sfpRqSB?CX=FrKL49+cgdstm!be zwk!0dDG&Gu8TKpb&l}4xw+NWrK$3g;hl+jK4qW>PCY0sWDQpr_fUatDs zQl4v*5EJX2thAn;otc}PFVOrhPO%jadpkNgsiLa7RQ-*xIeW8i@pFIikAHye1Ig59 zLBBUxg!J1S+v94xPjq| z8ym_R8fGRYxOjLo2O5>`NqKpB*Sq5;+e0bb+}xU)n)5Z*)`u?yi`|JEJ)n*=f4_qL ziHnO{$VIw7T4ZHskByJlt+66X8nil;bV#xmSWOjjFBPqJzjRhxhpMemw8dku|C}D~ zoVz$#6}GcGw_a`rE$%;dffF;X^+bE-s-lZ&VDahCLqj24 z>%=7cP?A&E#Km?(!objRvBi*KGu3A)si4eEeM?JAVc~XQY5jmLrL2s-%znC04E(;p zn1%Z4Ro*Mv zxq`W2)oq%$GxE~XWRVim@eIW!C49hk8xu1Dl0A6(>*M8cUF$Zr1YS1|?^Y!6!13__ z_oFRyDmyw>7Zq9R>FF66QSfc<^u^K^^O8|e7!Q*&FqCZ0zxA?qb#sf4kLPze z^O4Hw>h3=G5WMju9@(|m(3n-qlUvQ`>+c8NTn;iaVNK0DfI4DhV}UJO2+7ya&+&m% z&y7!UKFfkHu?&{Var3&43t?F;yn$f3<(aj!kPHom5Ga2zjj>VO{mDW=N};%2A3a>` zVmXmK>aV{3((FFl)|R>HcXf3Ia?eelAq!BqF?E{_doh8x7oEZooGdm@&h3&$=hHPJ z9>2!J?m2;S9v;#D-5*{C69Mf+X!h%La_=EmBrr1r|7pLI>^<3!R=pK| z5SD&EJ}102Ee$I3%z9wCcju~lJRhoUKfcX`Z)HMtd;BD+<@VtJ%03f*HH+6oaeG-+ zeIFTL2poxkhW7Gu7S#4;&j+cj(Z4YH9w}+*Q#6ne)QUAbuhASfdR_zH?@=3&r>gi# z)}f-oErX{>V7>ep!F>a~i?fXDa~y1QbF#YH?r-PyrOF%}f@zQwl9Q89C@eXEznX`Q zt#ZEwu7QOF>*&J-3%JVO_y5iVZxBXwP#m&`Kchw%0sG#~={hipdn2H+Ffln_?7VJH z7RoR+H(#^H^YC~u)&kd6Q&z^q$6w_KflNd5IBqHdJiI(X^K!rj-`m@p4RhKZ%LxfV zUBauqL1=d(Ax4Sr)oH%B1q|rret$#xg~j&p#*|$4&d$zY5+{&DCp$XGd3lN2|8mH2 zsZ4s6#7Ig@SEvJN^su@HbK}+<=D)1}0sUH?#HTB?;%^oEN81hL(Vs{X)Vdho6x7tj zkreZleL(VI5ekr@w6p%F3{JD+Z617VbF=5yuOuKu1qI=(QT_b<4&5Cab(!gxw{C3d z>FMu(#>8Ozx35Bfop`(s3J!MBg(D-&T3A?UYZC$vWOw95nXa0>rR5))e7-=g{iI01)-h8Et_($MVf@1J%9 zi#-AYf+0&{r~db0pi@={sajZA@NjdVZN*NP>TWksF6-SeJof?mDX>UoX0iVIrE2d% z@+go^fWtq4Bug(}cm0_NI+B+6Q2`j4-km5nXs!)F| z1TxR?@G!sKmW-^dtcZwDL4moxzJ3J@9M}Ue1z}`l6#kyS892@}MT6}f9L(6}ZqK(Z z%+1l?^MPDAC58%)y{wcJx5J(?xWJb$$@%%aV6Ne|q?Z$~`6bUC_m3fi3a>9kmF zvv+|x3=#bkDK~~7(&kGcJxdNZ;JF8>1r+;N=;%6s_28B{WBmQa?d|PtY;1rfel$y5 zNl9sbCa<#69!xGMDPbK8HCx*?Cp{&sW+YbQft&kV*5;GmXeu~3xO3oEadMKEkpW5G zT}5T`Cp_ZGLYbQve9#@XIdl?Ko13Fi->ayzt-!;&=6?OMsS@qNk`e|A3U>RQ5wJe` zPvu4?L!owmg_EbJw>L2%;Y))fTKiw%?pU9Op2o7Xv)5QH7Nn=^>Fe7*ISS|fD#9m0!&jl*xNfEFAc8R{O;8I_U!?B+;WbVTjl%BTjOI} zr?H)CQSCzM^3=`_YQ}NnQ#GMw!b4S4Qv*jA9^U&9cn!gP02n)QpWYbK{5Lx{r_P&h>+XM*U6{T-Xs;$%5tW)7f%OF3>%kcoahaL3s(E>~=b)2q;`}ul&|Bf$UPluT>vv$M$yuJ{qo72S&dxyN{mwRO*-OnIGYij4erU6N2Wfcc*X~TwC4U!Ih z5)vaPCWIJEr2#4NaMu3{{OmvelY+k@;-dw{T2$^2nm0G!pN;;6Ktuo)HS(sf&m0K) zdgcWV_cx!IKLnyfgaYIkU$^5wd@(kj18v!RzWe70y^x(NpgoaJ1NRe@Lbvv>vSz)O ztk#CjUm&(zcjr>#qzv60sWNGa%1lggu;8(;B}b6>R9mGaL@K(&Jm3EJe!;^v>qQzB z^?c~3xNqKUu0YO5cu?E_h7x+SumlMUdjNv2{%nMlH=671=kH~2y-7^Iwh~7(`(XG* ze*UZsy~tPnyrx@`^s-$7AHN9=jrPw3L*Ky4!RE{1)Xq;N`}1lZd&)_GDU?b56d*-$ zqr3Cx5B1Hjou5AQ=E!mxQ}^44#d&$#M@MqX)cQlMtzQ8~6%i+KL4W6dzoXcu>qUP! zUFw2}I{JDyaX>%v{LHn;I zkk#hu3|RJwqa}g2T?FxrD2byEXu*rk4?ky^08T?N^BB%9EToN*SMFhU2K>eT?n9n8 zD{@IHWYpz?x^*5pmLdFZF{?*ZQE~J3+?qk#b$+75xNL@o1_dlW4ZW;U1sAQFj?2jk zmJl`X!w+CpadL8aaGl7NZ8c;uYe!If|6Z+4oX?e#zXcb>FyO0%?1`6a%#=>%Yx2Pu zOx`H7qeDTR4`Bv_S8vh5tk^kdlp~{+Xx2<1H|gWjo%gO3(_Nt@K-2}c zauG!EUT;9dD*-Bii|ZphFz;pK)=9_==vGjU^qL*V(!Q3JwZsYb#vqLZR?LC>+jgLD zftyO>lQpd1LL#B3?{qv;m6p!e<#+JG@Nbut8F2SK|p`=NJr`Niqb!zIsS-CyTzrE*r^Y|eD7QM?5SaU*T zC`)yZ#j+HqiW?kZk5r!sg^_l5sB64nB_(k;!R`8G`}>J}d}>WijKBwle68_=!_Y`l z2DH$cfMqNy0^?~CnecFsfag#0+tmSbXmEd>eXq1im9%vsHVWYIJ)rG>6cKY}p{$=i zy&>t)XHUy3%_iruP6aH@^zkCJXZ8ME3&nRKBQ5}V{m#i<@cc4>6|6gi3xg_%J6wzZMuPqp8~W_LBm_UOeC8Q1bk*hv=Z>=lbiaWl5DK611Ss-<0NcH00L=4M8?OU1fgQJI0;NZV75Zsp6=It znZa3s%22Tbwt{kuq%3`-D|^8#QJ*D;IM}!c@r+SwIXOzhGp{9YOAi0`)}iEEx4syx z!+hqK&*NfMeqms4H%rn3wuMe}<7PYUD?9sgz5^m8;v;yn3^PkZdRS(lDxL_CYr4YNx05c*W|Kh|tTruNs*_`H z>Yx4qD6`2)w-40ziXT3H)o7Zl%MWze9n*T+JtTavd#2Uj8WK~qU02&asram8xvJzIpvY0LJPfYA& zV1V!0@Up_rQRumG7?_&Na@vWa5RwoVuiJb}NfVp-hZ;JqD;@qek)Dz9>pCZ)c*5VBj4X*02frwNg)q}K@_?l{W}+olu*dLo8efxc)14WR)Ka`i z)6wj?g@s@)V2>}a-nkqt6b7MCM?Dj`273R_6OUmm3w#%IKs*ZoZwbN^hv6bTsIS)X zn{RP3iLcPrIrOzW+jNP8qKeAN8Nu!2L#f;K5O54dN+1nSVgNTg%0l-cr*Vje5*8te zNX})K9ani}e;vHzc2d^a*@0wphSExVzae z4u!USWitQo7=l68pK>mjG@A#rfI+SYaftzfb#jV>;fpgL#pe9syakwUarP3;QVe^W zI7m3C%?G?k2bWi_3X-ow1RBs3<`iwIh*IZ*JYXCzLJr zrvm-adBcMHUtgBF{!UJ|ii#LDjRB*dIxX))mvbSIh%X@C&>L)4Wo2aI0NM?-ii}Cq z<@2~p!}D8gtSfl1%RFAV1yd3LYI=wGd`S9VFMx!>IygL)-oh=Dg{2cyLab&Pz_MOY z{4J)VS<)R?{`PmM(>}s^gMk+gU|{JsG>Jc2hV^uJ8v(aKrornkz+^R$=y`TFR%2Z{ zI&tui$Xrm6dA<7;b~@BSKr3PA>+KCtrxczsSzCdkCM zB&-x4FD}*+Ss&QgTwfrTDytr;;}?KQ1$H)U@i4a6ik8J7CAxN@&I9-fl<|g}k;TuB zj`)(bn1*GJ-}^)G&Gfb?3arlD~NykiU+ENxGY81?5dzcqJ`jx6-j zUDvw`mYO!XE9w2d)>wOiQB>6*ez7SvCc`q|#GnzD7~oA^iXR(;vs9BP&~@4V%3D^Z zGVHAjKxyD}9e`EDNbI z4LEgrdM>~`gD;+z37yWtN1)>a7+6>c^g7WqATnud#||aG(zlwR9{<{YN5pj&^MtyH z;F0l7gMr4kuu$IaZxStmsam;vd!7x{i+8QgAcB- z-{?sO6KlGjb;9;^QNX}qKfNFO1q_9q9?nlV9ghW~KZlIKfn`zM+>VFdHLC+an-W^n zDQ>z$#aJ5r?wzAQx{H1D<956MDVQh z=jAoW`x_Ime?P^aF#iq&q>e&Q=wWki?izq00qEHVM~lH)O?Q2bF6fBp1AFcqs;a7l zZ(@Ouw@N`DixiBD0dx1mg_4Az;0thFOzx&it*J&+q zx}OkxULTo7O;YS$9lo-ddd>h05X*c{8DET_A}Ll1pJyubyaBTw#87_z2g?P#=bO;^ z{O0ET+S&rBitjhG9*ivD;s>L2NZSaIC~!jlAtnvZHa|=Syru+TEFdfg9(anr)Ew;v zy)giFgtW+m&n=Ek-zQLAyL1D5hQ!&q76yLe(J{<#N1Yr#MJMR1x;!4xn;tI4JA8Z^ zaT%ljTVaMLv(>X_q`-0x=BdG_0T5weoLKEoMW7KbI36U>6?t&5mywc=b%kPeuQDgc z#-@gc_XFcfRCLDIp=+QDN{~l2H$PDpFTlVnZaf^Q3x0xNYVR4jVR~IqP<^|9nyXv* z9+;2XQJ>o%NK^w%O1ZiP@CX;9Q%Cd*izv8>GTff-R)T_^t==|ji%y0nPVLoe-28#i zMj8nbkd8x&C?Fjo-O?p3EunNsH+SLh-aG$$=lgq(f0#d-vB<*R#t|@ zWj>GTd7w?(_s3SiVY!JXYF@&Bl^t7RF_```aNY6_d*64qQL!>_kU-N?tXH#{CQR%}_81!x)e{Svzcpp%ykScLhZd@z08FzTIEdHG+rW2a3w_ZTyz;gG`->Rz5uA82q zY=aQjxq5m_YtxPK-Nu#{Z;=1^XmX5;-Qs=xdovJg4&d7T?P9_KWiU$>W!ylj4zawH z%>KmSy0@GHq$OKuEP^Ei$0e+F-szO)Ew0o8y6_1Stw3ehP|r&H3vs5^=xA~Ne!?ks#2VauA|pI%{Q z!`H8hw8^~T9IW}+7$N^&yF6GrIvwElTT6!y$2$YY-ZFIXwg4w+btK1ei9`wL`PJ6} z>hL*LpZoPg$tf5=Dpe?Zc{wLvi?GAIB_-psqt84irvsc80TnumlXKis5Bcl$pOCQU zgkSRo(iJvsKxEMt7Vb@*661#heqRH7|5*RDKZjHu1!V@1EqamB_K0yJ%yH;^|0Hwk z2DH|FQ59okSWFY#kA}5lrRq;`2e;b;i8DTaRJVpi@yexMz`~(`v(p^74Lu97v5Row z)S&;n^__1p9wEEI0T2zJ4+leMIWPARN&kDfSu=1`X59ggf~nhEf8$eylCAi`odc$M z5?}w^_Yeyl9EB^Nx(!K>IPiwm)Zz?EzlSV~Yqy$~CU7*I9nN;bg7s8`=b^)eg5nK3 zf8^VI%?EAJ>l4vG0_-7hy`&<-SMQ_Fk_u3epqb|?xZRexD~J%k5~}$1Yq=$ONmedo zrSr$|_nm`!BC6C|l(k)>-&mpnZ-xH*dwodlr^wcBXJhd1e;{&?K*E*=VZUL2PnuiV}=!x3FF3aKW z9YI_pLRvZ&XdVULR}KV_1zOzfoSZwrT?2Yz2;dXjH1?gPGO)q!I}8B9$^qD!h5>9? zC~f*2tJtrNt`_FMKiIdTLn^F7cZ~>(iE&sb>m5N}9TYIjN~p(ENE-x692nI#?gN>Po9D=>lqs2KC9>n537N z8b;~>-ceVdIXrvbm;3ls=zpP`?2mmh7U>N91@?lLZmkL$Js&^*wDt1=a#{Q+2a+bf zEd^WK6=<92>8*KL;lFk2_aSOiXljbsZGV#+8^^94>>caew_jHtut(z%Jia!hL~) zp{2BU<~|6`PC!-xsFUW#4Ps~!>ok64JFTr~D6d${R#8}psf=PT;&U<8Dph+SZBtfK z0zo`Te~FTXCBZ4mcDO-jVSzT!!Qkf#$h59(uQ)nEY1+!q5{r3W;rIj%5Pg#Q9BntF zTk!ewV`~Oet}jY7{>l0On+}3cAstLaOni&#n$K0HfzM#t%c?d1Dd*nW+NuAQBLj`G z(d!{|+nTnv$eJ4H1lda!vI0s=2o57hk?x~M%9>tSoY<4K?qyJZtgb#8h71@J6JPTF z{rezZLE0Co$?lxAkXZ6?3X$n#=eS3_W#{M^E167ATs2 zrSEJMP{;$QUBA|4QFamPfJ_d3;2F08sp*Nad2>8w?LG0OA<=;P>b#D>{NdKT-aq@ z6P^bON1(`riG}q58=$}TD#s;GY?k}?UsOr{chm=~xBnOQfrEtw>Ucu-zr>*|*Ak2e z-;x?1-^S-%Z#93qcW}VY!Qr#Bh!OWBJR+iS&h913uXN-q7T3)? zcU2sQ0ypSGayai33-HFVf2*;v5>nU6ou<$GsM1G?gGu#n8n-KzAVYRB#f;L?)7!`M zr0?Xx!#`<%y+scqHWtp^8w_@jk34Jt?7Gw3cqD2FdTLN}_7nFt;%8xz*U(7N7U=z% zDE6l%Rlu=-;$%_t@HQSAnrwW0`@xpdq6>JKMp`-w0|y7@=g(b8h({cSBJFZ>>&Yl+ zUO80zwjVkO#oJxGZo+H*_ER>4NT-CY?PdT5;nOr>EnQuO>9>n4vh&V>%aL=NW6ur@ z4(`BCWD=1n$jC4OO~zb~VdaI5jnu^pL&M0#L^6|J~Z@^ix|N3%O&9#a^&(I-)us)8ZL@THhG>-RsOBW zGJodf#Zqw{#rH36Z7HQeUut)0dFl)6o+`7q(#pyMl`ltHJ7a!BE7hy{#}90ScNMLy zDr$wh|2SUG1=IAUi_w76nYDHP=g**r7h>IR$ob^S6MR&7JFH&fioji_N=;1#D{_a} zmlk-#q(J|GqC1fNMn*`R8=22wktnj zX7NeRy((KvW?+v;ouE7*!zKx>bKf=h@$q^2auup&(h=e2WD2=?RyU|Rq=9H29oVY*0{8K-qE%$VZ2>KHc5jK-j@c+x9p2146`AMr|+)C43nvDL971!^0s~Ic{bP zizN`DD=sbuOZxF6y@*KN_O?Bvyd*vYGxNmYAaF=HO>3ak3%syr&wgxs#$LZTuK+3_ zMGvMBriO;2jSa{JI#hy-46}lp&T(;^eKL}FLM2pr>9+p68*g*d=+B>+BE8*PgoJ-w z_#e&vt>fY%$j|Mao%NZibqD&w;NT!ULJJKCa8E!3P+CR?Ooh$F*OmF!P#|6a$4tA@ ze(v54PfyQ>K!GVQ2Ske&z1g?~R`pPRFbv?bt9mMkxIxC~;^3eS^>(1^Az3jben3r4 zy-=5&oLt~c#%iqaEx{mIE&*G=mMTeAN2v3vuXD*L%T`Gip{ER#x#9(y9p{4eB0 z)b&lBokul+gaib|nyi)n%eP2LNhv6j!D^X`U{g9$7V^{nY7558*5Zi^5&!tiP-l|6 zy86l797QF-U16%fFvcsNX^qDwpR&^$-g0f}==G{`vH3pV%H7<|yKTseCV}tADW1_- zdq5IbbSvbsFg4AsTO}`s7zIQQXo83ZOhK{!eA@)YVmO(2Em{zea`|D0#jY zQ&(|VK0hBJ%*Bn12xAdG`EboJqdUQon252u(%wexdyQ+Tmse)7raX0j8!h_k#$C9f z?0t@pa1cQwBjx^d@lK#2#ra?W8;8o~J{tn@6AEtE3iCqkPY)b@E@>)9ELeE<_rKZj z@!6DKZ18FP`!%=8XeIE!C!bFu(Dn{v>OEJk#Y7Hp-0Qe#dc#+w55^iFLFOth$@uHz z$DIdcvBB+>gqyvB zL@oM;XMGyluMEx<3I>vvf{a#5X34`{OHS^Uk{5*w2zCO(wu-PYZ)|Q^cq=>oguvw}2K! zZj4S0&cp`{rh5(V;vzXCV;@RoN=dW(2hpy&U8`(p_?EYZf=#%BhZZ8Mpdh0%SX?K9 z6GYzA`Bp8hr$*SCAIWT+Xm=#m-F?hRYIQjjt7^2u;gZp*H& z=`bmwIqpS_r-|V9_4zC=0j9d*AVh*7qq*ezyeROI9|$;lp6 zln>X}r&eZN-PGvlKKJ$xg@r99unj#^A+Y!mU1V?yY95nQQ>W9>_lQib^Vfenhx(~Y zYiNuKx^uZ12$++QOkj~Hh`Dp!xnpwMVDADIfdW!jejpT)R$g9MU(d`$0c9v}OUr}5 z3wgD51^naed9*$r9j4U;T%e4(Iv?irL=opp?n~;sb1jBHEFZ2O&X#O$lI&?~WmQu4N*uL&*jL#^BXTMJCxe$uwgwBE&r%%A%}X{SBOs7;f8A%oMe&BVV|@Ivvhq90j7H8Bq?WPCZgRSTlcHjGA~Se_ zdV3=q*|!vEZ>WDu6(=TwLfsG&+l`+KIr!rTZjdHd+mB}^ozdjkO0(DV%C8|Td;=6X z^{S$?vlwgK{$lq%yxFoHb?1xE#WC$eCma&1PNeiWN@x7fff~vZ&#F1u@w7<%*Q2ca zH}MXBh{?Uy*B=@DY*F%ayQ{086Z?*l>OD?*eG)L-*RGM!YY|1s20Gas=#V=y^69u!mv4eogsS1XJT~~AM4{wl+kTAM{F{@HXhiTVP_Lj?L zZJlZ7*8DtuOFz7;MkVq0@B6`9x$=b*wsl67C=^E~-am`cT~g8#m`du33Jtc?y2=BW zBy6-%_c*aZdDYg&t7}%Q`kM>(3uIJO+nbwWTG}u1(kT-avYxB+YHMGtE;`Y1?Z~OB zGRgY~)8^FI6Z_L{2ZR{``J_9ZJWbRq!mB?F)Jv~nAQA7vy`Iu5^Y4CoC+YXbf8K89 zjETP4YJ`~^_iKl`v2im#>i&MXv*7}O;-?PtkE^SW2Y9U5NlASsN?Kg{se_w*W}xQ^ z?Tx6{1Oy)?dkV6rJHKy|CWsaP+f%^@7{m@WIZ&d0nL5&$Z=(l(;qAv zX}o-{56FFNZ1Q4bE5pK2WA?)=nwkzE#2Fk~p$Y@_>y~F9e0+WVjDAj>#D<4&cE%L0 z+lDG+q26eP?#1){F=-*8>n?olD9+9WyMIzUx-gS?vjY;0UQ?jM*KMxa_*q`#lWrxcv_QYpRO^}>_)c6in^OW_uHfk{YI zqhl(#2#@i5d)=@?O&AD}f0PC+i9qFd&V`Kp#Sa4u7nkGF0>0DJP6h%kO|p%7W8f4B zF3McL{)tIxX3oA)uR99=JaH5V?AOdo{djlUhMau zO+tce2ER~z!y9ifT2c$Usp?F2`E?q0ns)W2mhkI#hEvr0M}dE0xPKp0;+c|?m`TmT z-@1^H8=BUYfvqKF7G(+w4^>sK8`KMXZhyGr{1%jkjpY+=)8e&dDQS4`Ei(z0JwW$& zSufVBv=@9GkQc9zWj$M;SkfW$@e@P&>vHm58P|J6m_c(3?Hb|tuipH=zF#wSAP=KO zNB1xaT}S}=%!h%V-qcEHH$rSQF8<;+@$byfcYRKrvXJ8(VA*x6cD{c8J^O&?xyBfp zVB~|X?DTapZ)SRb`i%=~a-QRZ`CO zlpY_=$?0IGa<0O(ldSC#cyhSf39--JF1^WbheJ^0=*&}5kR7 zPZ#CX+>eVgYxAVuv*BuZZs}_o&D913!h(218r z<8%UtRl4Xj9(6Pd;uMV82hXGJk%^P%PG2JmHWUuZB^jd6&og&-XAK%QJcr) zLDJ7Of1ZG0uh&VG^uxlkdQ};{xTvA0hss^nX=_Wu&Ym@^mlG_@(B4)L+%#$viRjK) zU*9z(((KX6$Me7Kg1pWPyL)FK?Bm)|t@7it6w2qqiIgoUE!%k-&Q5)Vqhm5X-FeM( z@3^_;Pfz7!&A&N({!%Nv(F1nt#n3@2e@RkN@cGVLrSyq{{HH+yl>po&PXZ;e@fu+Z zCP?e~Jb(UaTrkQ6HemAfrSd>~WhH`}o9%$-JMlfDCz6tjHASqT{S}?2pAz|OdquUT zuy7}y4NFgtZFy^nfi=vCAFfMIU0rtRPH1&CAT2^XOffOZzZOk<>{Bzbuyr9lySsA< zw<}yaXG3(mIn;QOVB^J{X)(R7@o&|BQjb(cMjyI_%PFDWQk0; z-gUYfoeLSAbo;2C2G4ftC|T0)0ofiT)8mH;4hQS^rKMNR%)&XbF)%XV!qTAwTFXpN z?{s#=%*!K4@aokq25up5PiJ*?t=F$Ro8GwMQa!ntyD1_gbI0RUi;(G^1pad!tUtAe zpHqcw2nn$g-Al0$jmr=M@edBkS68F2dt{5#Vng}rcyl^oaj}3>KPn^!>{E5kDVkl= zf=5|tS4=b}TrPRJkjaTYeowc+IAYS#qn3qJFwF09B^`En&CFH^nbbotlR}`>gTdveXUV! z;mLXs!}s3aqu5w+92^03e+VPzT3EifN&yBlyHVN30J|tHeY^dA!PnxWgXn>#CeDY$ zCQE&jgM$P$F5@NT`vY=vA$O2k8l-eWHPN4E_@}sET#8vSWh z1f(}*2oRds!gPfAe0CR^xy&XencX`{lM~et_!Jh-3=eO_Fkv}FP=3numg~%(nL*Lh z`|ayn;yhwOLm#!iM7n=qqpC7EIyX*+DnZ%NCjIh8X!-ieikQ1w4H1u^^>SGaWpwXO3y<8jf8Oz7m+T2unGQpg4eKfN01bmX28BT64S5ndr0YNi4 zc}*qN7~f<1@qUi#4?TYV>6PIfPv(>u9&%)_XgSU*EVSuO8i$^Sj>(>b zgS4KW!SCPw^=gdqXr6-VqrC$cvbqix@h%8L7ff^hjN(tcxt(OV05t`S9sAcT_44GYN} z78*4?R)L9;F*0l_b3ZfpgpJ$EdcD%M2)ncA)92O%R^;5GDd?VvYBE|fTwGuk>UD>P zdETb9?!Ve3dtb1@vFlJ`d zH#g%uzTSGMnDp>g(A>cR^``m9_J{>z69e6<`8v11Wa=Y}P%78h+rvIOk(QD=E_QBx zJ1{c(EjO=w0IB@tOD8>YJX>i4Vl#f-zir_fre=3ZIYw_H$rZu&iCt9wnr{t;uermf zcLUL==@$^zpnT6>MJ1!A=0;xi?%42GIKunPPg+}T;-lsk4sRLMJAKYh_+{UE<3>4{ z3S3Bi@<03eO}M(IJbXcqDp62y>F|I~$eDSes3A?acDZwUNda3t<5~98DgyND-rfTb z9$Y|K;P(@<{rv*$o`Iqax?odt8nJI?78(q9iD3wb)YGSfO-(;WMy8r2lXq27c3BM! zlHs07KVGEf|J8A|i{h}04I*AApkn=0Lu1rw$>*|ud|E_7RaKO+Exl&Q_5pUp)}#0# z_q`lwEgtT(HMcK5Pc$FVc$SDRflpc!l`4`9Q$kv}Ev8aatELD;A3*+k=8gwO<+t-) zcJ{{a0a)_Z0MPWNbRHQKz{@Rb9we*}J;D5pf5@Xpg#^g`da(Uzp_vx4^`Id0!?UvbzJA^4(NI$!c-tDJl$_oq?9o9St> zq4Uz!GpO19nw^Oztg|%H>|Zwa1d?8S4)$Ux%4_an*R7PQ=wj; zmHlFQ?v{~xmh}VC5jgw6crA^IiAqim%wn|4D%2~P$9wc>f1zC~ za%GT1^up}fv#FUnTt7c~04a3#4{!nL)Kc5ODv~+V>~f671(m#P9 zpY56Bk-dZWg`cuC`*nmk9+l<_5w5ydqbbdeQH;4gc7^*U51A*{D76k(Qq`?xf` z_r8_Y^icNn)jiwhyILHCvC%OGb#AZ7!p)0!L9y4)%d?P8@8$MVdRnc(5CKx*cqx4q zyj)L@3c-qwh8J!=HUvy%nKDDUx!xvLEN>x+w3%`}%^TvYC%)v819rSglLhC#T(}li~%ss1G3Gwez)$jcWU7!)2$}B2sZrl_Q zAO@QV0Vw1H!f`iieP%rmZ3li8o)i|6Xlth|yFJv@(_5=`XS&LvNB3(XrxFpSCt(}J z!_w)`axJQbkvX878VWJ@T}E4@*{>~S7MIoD=e0JIBxPSNO6X(m10p1f=tib7O;@Q_I$D5QsfPfs({%(Yh&CM!)_aA3z)45%ba!Jt{QpRY$;g^vQFy>3$osTZE9 z%E^J4sV~*gG~E(At94yW%!6(g3j!W)c}1`3(b3-4B1%>nMpY6vK@rC+ZOxyrZJ|ws;0F2i7RVmSZ8qehqM+sO2I7bSj;;SsFQ2ydc4y~g+t;z)1~__L}^44Ry5+^7Hdg0Bi!rbGVgo3;jBz-Nu0-AL+%|2;DEe zkr7JI)z$Gi#L`d^X*a-fLiOLy@@RJ;lRYiXab=c8@MP=F%`McMlUoyJ?e#yURrIE# z;}2fjYk19U4S22$w&dh^j`o?2{QOx0^;sAu*4A3``IKnZeLr`m<<3-_^w!Sr@cdQT z!`=S-Qd0Z;Q%~cE+uVnH)@SNU>qSACEj}iuBsBDk|1}P8J969O9Y;(|LLeq{A<)BK zowNn`fb2(*ECamugAJg;o=M0w7(w~Ud``O?WG|Ot6o;Y$D~P+RsYJUtEjnnNKNuKL zhGOjM%8JE^V?KvLwXPnAV#+-d!WJK^in0(SaO25`L@nKT%D$$ zg^rmSK%=2i7jpxe2OLG1!7LXW6=7iHB74Ft((kFlSSqLUla8^XHPF?%DxhtXgDdPm zI+cO^aj)S?jnm3pXAF7!`>La(pT#_!%t?Ctr0l~>MI`||JZz(**`=lanx*W7TsKGq zuQ4&%B|i*F*Oz=H4tQ}8P88rP85vfIGzV5Dj$Hs|N2-7LXl@P=!1e14AjZST7Yat) z?OV)LSDX)Iw^Q}!cc4~|5QUV&dvH>S(`s}Mf`_r9bQz^%Zi~%yp#;$Tdzol7eq}$0E2+UT8MV9)D^r{A9J9D>>^fkuhp^OWd@YzqTPz&W?)hXlt7XJ_Me)n0K9}8$HY#|YX0#|S5KsS zTue+wFOoYBpc{l3N)hXEXQoV?mlp_4Sq!N1GcfEz*b0vdg|%MJ#Tz`Q!5 zyu4)O7e8^bpOp_vtH{%%3HV0^p0rWiyxH>OSwyOkoxHp}r|{mV!a{(*+1Q$n?|zbd z@&tHK&Aq)J^Fo0r^?-rf(Vlbh1OeT-R4J*K9sNFbW<23FQ3wPL(D-J_$Y@18kIZL9 zg9k#JI6ar2JyGZpOW?56tWVh|>~(b^04xULKTNDOBI3`KRN*NpqucWTx&5!VKlsm0 zpPsy>;C(zg{B^3TOc9Y~yo7+tITy0j!!_kCdXS%71RXl?6yjouekY)W^u)x+i*uFr zJ(UF0{Q9-rzo0Axe8T(p(z@%MhDI4SCYi1$dm=y_Mx2XFw(&VQ&K~UTMTpi%1HgT= zor$U8-P@m*c1mN(ih{~Dt4n|CTMd7F`^F6j)KOvHMdI?xeVNCL1RCP@2_uBF@beQ5q zBR3`!OktyR%Gg1yWU6Uy3ZfNK_LRQ4EEHcQu3=ol>J^#c*HE1m*Abeh6syfUac6}Sa|ap z74WHsOg->XN5(2J2IU>mI=Y_FBegs{`oZFZzj57oC*sLZPQG4i*yMy(ugBTeA#3v2 z_#E!o4Xiyk(_US~uUE8m3wQwe3Dp?K*7KNhnYF*4Jlu?%u3fRPDd_eL-J0=|d%~n696+b>h5TKfI#izoE-lElQ}CQq(PHwPOPJG*(d(=38Je^I~C%4POuREIPg}| z-N_vO{#aE{&*dlrfVGQ@v2?Mb_YruU+{rzf=Wl9OyE|lA4Q$D7Gbifpx10V^7uG2Y(f?3U5Swl~*rQpzzn82(}d1MynF$>;pU&egS{5wFBFF?Y41 zC%>d*VWy6YfjcIi#Gup^?KI1FrmWrQ@B9!F`T70(d>TVk#5FVqQ%~Q=AEEK+CMqlC zMJB*mc3W1htu%JCGd+#kcNdD`R`n!i9BdoiO%05oX>V<-uXJdI$qD4v;V;hs1C>(h z_bsw}{yetdbyjM0tU?n1p{US)L`YH+Yc!JQq0>}@K~M{^9i-6e>JER6z2Ys*U%&2x zmM@FGDOY<=RJ=}vq0@q8mN!f{v<+_jkVYLfs3K*u!1(IbP9%-jg>XiO#LGWD>T;ca zCF+yo_fHNAu3=}Inw~H!(sy+3e;i;vGK1>4X=#u}e;NqnaM57w3JOWFurMK$eMm^M z!t|pbOC}^Jsc5vb+}m?t_880>@L|r$hK;M(wpkH&#xvs9+py6G4xg0)vGd(@golNsvQ5hAtgZ2+F6Jqc6 zCGE%gc@VjlES_9LoP=ivU)>eza5L_p@?OICdXkOVeir1RSm7;p7!^ zAU@0%X8m~1@1_RG?d%8F+0jR#ds<8vy+l3$@D;@?O2 zYEt394?A?l{O3;zelQ;A>f_rDZ`o~9c3pnwRU%XgP=NsgCO~A#AY1|;MnCIS^zw&UV@3&@)kgOUu4a!pAEq5KPM zi679s0rDau!onbo_KIIuUq1~fQ6ME&UoVOq{K&=gV0|2<5C<&3#>J@tRWUG7NK?84P>)G$_fq|D6gO{6XfHPv_CY}aVJqs>jyfG z{Sor^7Y0-bxae1Fh>M$su`#7m+qgX6`(=_}y2&Mx{*p~7_V@RP39%}~NCkBj73O>Q zKB)J(F2x=b3cBwsg20xJ&LnVTLAoe3Bt)4-=Jk^>Czee2uAtd2SUOM!BPa#vL9r?$ zOe`OlAoiaqc`!WWuH8OKGIn8)Hi>B?cYG`0hiLp!4bwl zCECMo&d(dKN-r`7>Ndg#q(3le+Xmh;8{~(+XP1#R0=+B-|H!M*$NJ;HP*Z!!EWdgD z=|RF|IOWSKvu+aD-ZG1RZ7nT2oetB|ckeK9gW;kLj*Vr<@9pde!c^8@xt611gTYic zmcf1{!r)NAMOzFRDN8)38=xJU4n^ref4^OKJln%H%CMV7V2)_q%#PDx0PNh^@h*r9 zwY9Z@Y#1n#b+}-oWq$gED)G$Gu`Da=Ph=ek-3bZ_m6w+XYsgOD^8Ww=WvDlA3JD3V zt*)wTXtZ4FY%6PNksm`weG4;Ck{c~)3haYogNdY@@( zX@#7mLxu%R? z;ojc~RBVk{x`xORmpp*>c&M($dS0B3x3shj4LNowjSLUpzI{8$+H-Gt0JNc`iw=Ma z3zBn?YQW|0?&s4wP1q2~`t{u0-0ZpTL%z~Q{xZ~ErciT~B#Umlup8KDkJ#Q|b45o+LZP4zq`I(MK>Q2DnX*aHp}*$Vttybz`$Yx%bI@-4y8e)AKbGn<0&0ZdU|?5 zjn(KW)yu>(ua2WN%b|z0482(R)N=&VXE4dSxw(0`(0X{NE84NEQ`D4IAY)k6loQ*a z%0Ws;$D=s_L#M)4uhbL+H<)5YU3xbbry-8cVhL0^K{XS^%cNd!g+FKFFfc%fixHhQ zEcIN&3zTeaZ-*@g=BHm=WF$N$@-p05O~gN3t)c&y$L-W-J1pnnA90o5O4A`qOh_!U>9>J4!m9UXb=7Lx!xa{f-!hyn)X7mpz4 zj4#uFCfFnXKY>o0M)n0b-B&`W5^WPL$&rzb%@e)@ewn?_@NL6^mdKl%&WJ|WHVsJ^ zco)HmLGa_tuE`odNf&nKm*ws?P!;p79_EF$NXR{wc&@H?<3ImkK;ir(2c< z=iK|A^WOW%{rGw0aqIrZT5HZZ<``qG@aIZ0__)-#2m}IOPF7MCfk0)1|F6Twgx|lp zDn-H%OcMneNyIhsSNf0KcL>BSgq-9Pb&pS*)1G>LrwmxT88cSyNSO4#8%< zRF9IRik*pT$a{4J9=T~v=&6)QGHJ1KNXBIA1(RkZ*wNiTIK3PmD_u*rGHH zTjhB|5D^m^e6C$#MF!vfEarRWK!?hhMPi|dyqkpJ6S%@ciA! z15Hhj@o4z*T0`*BOgB>+ITxnu+#i%Byyb|ACz43e)7GY}b@{8B@9W{=VRUh_x4XZO z8rylkVlRQ6kBxj76Vx||QiC57y-D1h6=_jXcn_?{@T{z?+OM9$n;;*=DTFUXzs}A0 zWOtsD--a@YTQ{VwO%m}~Q4y~riYie2>ICg+2wro4ioo95Fmqor9~v4KL0gvGJBNdn z{s3Q5&wX@wS1BFN7&_sQ`PNX=mLQyJhj~=Q+~LMJC9l!rIKkUWpTcyj?3!n0=o!R( zUVr;`-)(bZuYVRnL`4-|81BY&?tgjqkbq7o2qx9EGltIN?4M=+9<8t&UPwsD z#8fCo4!jCt!5p%x^wH(~tJ8NAx z92VMe>OJNvlkeH z*a$c#mBKz*&Nhge52oVV+uLtW*HO5xk2YVN9t{8Rc1Ix626<%f#mC1RSy*Uq`u+U* z^KEKsjMw2h*_7rFFINjoOR@|7TqU}C&x0J*y^hY#MOX^6eJ+0|t9AtT$Yqq3OXsd( zMG@f!Cq{%4eGx>yKLI|y2xTA^p|pt!Q~i%0s$| zmdjL?otw)nEL@i^wQzZU%=_R0dfH&Vwa1iepqHXavLsWa=bk~G(7w!IvO9| zh?s^(_oXft7MAvl7xSGA{zXk6V9IIe3oUA%N`z@c5WRi-_O(W#rXyX%&%YzNgz#c9 z!D z)u|u#FXlhh8pn&md7DJ8w{qmuKz?#zMT8yS>&x}$@6;Pvg@|w;DsoIb4=O6&3xt?3MB@Cnt0gVJvm-M51;nNOHJrjEwlsD;_32 z372bQ#q6l4INmJ1a-*V3bjDMRoyfEU)Co;Zjl{{>K>pAP@tem%Z_uimy7F#MP1E&UdLT}A88LLL3|fXWGb|>@usJm+ zTKYEYaJM3fzDyt&76vg*N|58?kLuuH5T@OiP$ zY2&{t`^Kox!ljIY9_)Ddg<3)-$2;$gjmznsSF}wBK3yfwq{+6;tse7?6+Mb-?-FbD>2AKdd~&i;$~iQu-Wh;_#^+|^o|pH0kdLt^ z4C?2SqGX$JUz$H&TpUBWQS)QPw3%F0!xmU43oHF>=os9=Ipz<;+drgmN~Vd?4Cg#U z+nf=VGdah2J(zZXZk_tI{}qnpyW17>n*3p;^$+}2=u1p~MEx}6d*}W#zr{pZ zj(Us~b{w4*4r9>M{QMW%;(C1ye&gKk)LOL22V?>NWx=4Iwii2Z$vPfw7NrVcMCWSz|(T~(>Y&2<& zPfzcz$zbYZbc{=m!z@IXf>%)yfBLJzm5EB*qS06^1UvhOlk*+xiMnH<_3`n}c-FwZ zR>CbyR$~cLY~*5lZYEz6$=Mjvd2x!y=WK2mzSGF^YEZ20-``M&^-&v_of$>*&ge*m zj-##jj!Rv(E^9-`;O+T$67)6#iBhP-qMx-av>R0WT|VlF-FY+XN5fGep?CikeMcac zy~E`h$p?3pD4Hs)@bJHa{xfnb6{7T_5$z2ACrm6XxMO3*$T1$ulC%BL@fe$(fjU_} zjFhiqZr<_6<(aL7%fCCHL>}FMAWzakb=om_F!0F}5`2i`J!z9)1sNVko1!taHQWcL zRo3G~1_s|8E>7_3eb1>hHEGH$hH-q(67C*oV>2#fBoRquNvg7rx3^Qa5{lb|R#plr zeM)ApSWGbc#li4N(2=6Kxl!JyD6(3T3DbUuw@BBW;P2nx$zneQ%=_1|@bMoi0lXlM zg)m}KjAtG1U2F@l(=MB%ylZHHxcTl(Rop=C=g2pRb%H?5iuSX^Ou zxuo@psw!rsZ5^Kbv60WQJ{^~#U7+8kVhus$TaN!c$SnxFyLaE00j#NYu?*nW?U<|E zS?}6Bq2WK7pKB(Xs;`OqcK2-yr77hjr#tAV!~>t=3@XOvX2q3 zI~S2z*<*JOzy8OLBc0NlmHrK*!Bn~3!_R>{hE9A&P2_za7Q zdZB9Qrg*CZmyxa;1B_x~_-Z-YMvzU1ekGO);;5KIfT*JUK7gp6QXxV z;dJK5c~msbVC&>Ly^yO_R3fMCaJGUP@(S!K-pq_<$jGX8^yc+FW5lDMBG4+myC8xh zr##pJbI0pw!c(IJ^DwwNA1fZh%)&wf1Jvs(Xl6C^n8E+*5xt+^L3&P3K*rPSmhYC^ zkR0PShOkwHMoA=OaVSl9|J6tTDjZCAv(>Mzo@njc6fS8+MHIboCQnVRay(cm9U6Zh zOT}mQLHHP3LW0Q=5|xFe#-b2yIR?g$rk+GGkJEefrX4P=3+;g_g-HbC#>8JpVO?iY ze!UA5VL!vt(qo0DS@OMosheCcl({k}=z+F&QELKwlJ@sC?~+#b_fvX|F$|4?{V6=R z?#P7w{&wEd+>E=vzVG;q=t~~*QbZ;4CGR_zy3cplHBd|RUa+~VIrV-8v@=$E+*)BB zIaKrkWqdwC*N^ICYw}VhGlZO+`;0zQ+BGi4#3qQ18XCe=LM@0@W1C7On9`_7}C-Y=eM_;Tm{LF=AYtL+WiR1lz9r(mRPf>EHR}-NP-lHl`*Sl zv39ApI!J;T6VKsITwH^M|C`l2s-XmrddzI!?R)GkppBJ?V)$P}`mprdnX zMmUl^dBRiXRl$=g?oa4_zU|<4Men-4=0r!%=mb%(%G#~a?dq7FmqwucRfS|AK}m4;^>BU z5Yz88Tik7Pw{x;8EpqA(X~f(PL$k_Dvd+~5BhwL-H*X^6mmVM>Z#4aM5)~1#d%{NQ zNJr1;6b{dA#=??iJV2|g`0+c1e(i%NfVBq3eAwk299SUKu4a2m*b)0A?*g#`%PoeF zhek%01SPsZJo?514Q&j(1NoHO@wTN_jvx-!SYpk zI!1H%k>%<7;^5|8LxRw%W6|By*U!7=c6Or1ifJ6^OtOD?CBB9@U7V`%H@2HWh4T01 z8BM#tL69seE2Ct7d&h0#Jrf?i#w*&z&f_NgM*PGLv9l+El?%g}69J7H8mDsyrw%UP zTS^-VRBF9QQQu&TUzE`erZqyTzeTiE;g^@Uiv-dg(HqTugHJ@4hTR;N5GiGy;P)f*`A^l z6KkAndXw*Qal#ES!f5M{v+T2ejy*oenG+K>G9D+wRMPTco6i*>kL>F?{diDncqd(} z)RlFn^h-;qY#Xn+q5zk^5IQDi#3PIcP%t>P&YA{y4B`D0XutoibwxWl7w#1l`rX9? zjoyeSb}-)kS4VF$Gk*z;|DE|Eusdm=3(184;^Na#o(gvi(``v1!0>GNfQTX0esSN4 zmX$k26&Jt5rF#@8!Ey^hM1NH>x=o((9G#x0^o5}cmMv;i@Qql9s|)5`4>s4aE~uxZ zXP!yY&z@o2yq(O*X2A}l{Dxci?ib~>`sTvZ#v5vCjYbD6k#l>mmzH?SzBx-l(d~@8 z$@BusN;VPk9>LQPn?MKzEVZ|gMVa5 zY|!A-jcMxH{pb9cy{u|BIx5Phr1iF>3FJUr?*BJroisa? z6g}X&iWCQ3Ld2UKOQsV|%I=P29Q(|jhm6-a_`Vp{8{C3Eg6N!D1i@9uHoK%Gc*wEl?Y&vq4GOm1!h>45qV@i`CDNGVTmWV!b4n;Q7 zmd;hNN}C$C#V+hPk#@>*nJ)i}OXjkd-Et5OHk16C+Z?Hyql=yPkr%}UJ)t4e4{3## zUek*vc!ztqx@v4rJwhqg9S5Gv525`eatIdC+jq>*lbhS)VR?!@SDAlui!DDp5GyXs z_}tBZv>-c>U5)D{H3MV3BsZfZBb!9`VNY0C80VUmipFy5P?^wOJqOh@bQXr#&eozA zmu1%Dl6eIMuLlRuEl6;s;y!fMhxLOsJX)<)ZfS8iZl7nRN$T*pu6o%zX zv_gX0h3b7iAao~VP7VegH44r%1np=2I!^ZLh^eSz8T>cHqiMFP3FLBsbO?*O2&3Q; zTloF$7>UJGMZ%xz>D{9=ojdS^K1@m}1`&lKB(yH*Zg*FwvZ&W}Ehymzcg+RYXYHy-?3|8=8DFMP*;veK4h_LXB)R8)Fy?ww)Z?a6UW?<4d~vtCW7 z@&E@bD~_24U)`gS#Fti9It#vZLO$NQ=H>(jjY>hXZAMl)h7oa&ncv%@*!bmv<|V?G zocMMJks@Fy8A%?pd*B>z)vm_O%p658s$+G|L)ek5uGN`nenZyS%gamkG`rU77h8TB zv!`0z!9-TLi3avvLV1Y``(a_z$ww>%~nVx=PO!D^T z9i=8<12Hi%0Vqi|QwHzuI#^gFh_c?};3$w-q~Jbtz)~RR# z-nz%v&^UOOhDl{uzSQM1{wu^nmJ*eGNvUoXfx`Q{?UPmZ!(YvMol1@V)O$MX9IE3A zxvmFwb;*{rzSaFIC=TB}T|UAgrf}^f$`|rJVobU#ieqc*O8e*@{txe}1)(flIXSr} zb#7bfB_*H8bjf~o#xm3pJSpj3xES&dRL9INmgF!oeaCAzMX#9VhaHGj)%vS2l9V6C z@@E##m&{CKTifX0-(J1{({=$Ir?!rcgt9W>)?`&@w!(Xa&m#kDY;I%Y zM*7Ki$%P%Nv$JznR#v+8c**YWF5>zA>1?CFxYc+`G*Z22%6XPD^wmt^rMY>}?gs^W zQ@nwJfjqTb0z5oCUYE7!ZSCzSkIPqAfj;Kt=MSl@FeL9 z92pxkZ*Fd$r4_h#e0Teq3Cunh8(Ua@etvmb8E?MW>^?3wwh@E4AF1^u+@xc1Zz6$R z4aS&y5(JAv&0=b2Cnw~$Y(Oe1@;q3HD*v)7kXByKC+vO11y2T`@f&Ct_d4XoucP?* zUv?3#tgUq!K&5qYb$uZ#D_fJc3iJKq@#Due40nnz&reVJZr;3kbam;S^zmblbS!;8 zEiEnXHjj@V@=K$?e*KPPmeH1%$JGUy3$1A&RaAG~*X;9n%T9Eu+`^ezkAuoO1+=@-@E0khBr?|=$OjEDt%yfim)jlX zR7p@~_)I&Z0=8~H`}nWlEx4w-`Y|jh5KCanIyS~5epqps;%$tVhQ`DYgy2yHeELLN zq+N~*nSoNwM{uUzQ*GNf$@OY_Y6_Sec2I+`?wj{L9!wQwy(oIAtgA~?US2NfFo!Vs z;T62t8Qa?5Up!&!>*F(2VXYNKCrl0((k?f_fRWQ$@m(+&&sM42crQx;4bV@hGH%=T z5dhJcSeI`AJS(&LO{ihVIssCEi0>Jx2z}|?Y;z#i-u`kg(`0*RXQt&yj+CACpYQA@ zrV0jM8#Ie`Fs`+dTX;w%gf7)K;#vy=-)XzJ3}DE(ysftZa5~mUTyp;#M0H( zZEFLTG|fM0=-XUUVj@|k{cH>QuIuU- z=R1vIk&&$+!SNZl1esJ>52Zhe+lb-Q& zXQ{rK9~P=wH~84D4P^jMcwJb?`Ez6hDU(pr(3p;w=u1`7@R^{~i~B`^;>9c~N=LzC z&<5`giAXSp>Aj(}v^3P#z?2jk_+GhLFF6Ye z-SMn~zGn}%r|Yy#s)Ct*S6EYkei|?_p}n@TkqN^f75}?s^%aCQHX&gsToHn{9D4nL zv8tcjH;-#?XE7CQ3t;A#L1`$foC#{DTBKcZGa*5NI8oojDILcwT%(7ZMWEuC$>-=DW|r?k3Fv7-ZDmOv-*& zr?38P{=NyHNduGQ2w9DZn>2V(8SVtRGm=i&t!Ze8D3)GSqRMU>kv@u?nS66tRSLbtm}!Y@zoWv_SYpAbX3MlTbe=#GG(BZyBJ{7^GQg4?shUX2zuVb1D?Fh z?~?6*AT}tK2?&TM$sSdw&qSm4jxPVp3m_5Z^MxhIhnb%rCz8T@{_Jp-QoI4n@7$Kn z#l=D&8;Wo|=sN68|5eLaSn7VEQLvDIPeHjfBsp2~ft7mUW;9TX(opIV`|>5i!VI0z zHu2i(FhKK?*P|h#VLm+kYdEu$`hl(0Yfzsv-0e*P+Mw#_{Hi91CQ=O^u2LksLlg#* z5`y2pA&i_GZ+>-E-HbDp%FFV0E|tJZuZV2z;BI9FroDNksY&6&R{{i0TTfzeuLL ztjq$(+FFg0T9Zes$bPm#N$h)aPM^ZUus_g-5|yZwf8}8NZ*(b}Z~I6> zg5oD3S3;SXASR{-I;-)4pmImm--KK&k6xe+rj1LEZC6 z`}Y?Su`$AQQ8`cLX+2M)Of25pxQv)T755jZ1-+`EF~CuApG5{emjfdOQcBnSHNXV@u(i>&BSsZ+lRe^KVdTn&H#%2c@Rc zj~f%=WU^#MAp5abtBX*(g1;RcC*NyF^=a7WZx;6=y+IhOyL;4t6(<{ng7(L#1^s?< zN)=Jv#v49N5cVd@=0$95g`vsiBcoQ}v;8QHKoYekwmiV!Z2HjVDowYhioWBucs_ZL z;av)6Q0$=Z=9DKss6@k!jqE@s#SVN<38Q;kzB{{a9VnCaZIXcN^4IK zWl~ay#f)CfJ57l&o985|Qfx?)%I6|E;@zE{mXQPgFPY*Q`gI}6yv<Z=?pI+9eil4Oiy-#}h+o$ScprZm zuCP|?OPwaXJWomTp6W~y2*<|tdXt_`QSG>hp{jaMB{$}7t@|~><@sv#oqUz2g?i_p zQoN3T%aP&GeF&0F!q=tR=WH$gDJr|W)xkF?=)saeS6NBN3&Q7jyXka^^C+OlNAu4? z*TE2|l3V+kZJBLSBuj$2#7bJI`5CFPLC4a$HoWY8xjp3>3?Vk(lX&NU2v|GO^R2>9 zH7YI^{eduKVwxdiVF6Jv=sBB23coaRtt#{;0clXDT4#sN$il$NC||^ppyz+cfg%$d zvd|VTEUTy}Q)-W#u6^rpUAcX>Msi*HlILSW2~Fo0?qR}I zvJxF$%Q4}gAYk=te_P=~(!vKT_<6g2V!raBb>6&FQ+AJ8NR0cEw?R#{ugP6W%Bn7* zi3`hc-M~cN7zJ+p^8{Gm$jBe633|%UE>R61;zctb)|GqtD8!a@Yu3A(xwtS6(Fd&HuH3H4|62G6Y3Q(2a`}2CQ{; zkgBX=>$T?rX8Mc!f%2U%w56r_ft?FLs@sPCF%uIk>$Qwops`8fu<3TY#)UC*Z9Y^= z#R~+6lDEUicDi;-&ANRVgtFcw&rJ6nO%Q(fNd6|V#jw01LIA%X+#dM@*$0Abr1tl6 zc?sKLr4Ma$Vm=n=!nN^1(t}k($@8P1a(EGL(;`o;tjMVaN-$vLF}PWO6{?NnGxkKq z6JZ>=b{~QSO$LRsGnO4nnj#b2HZCzS5_FBZEnmWel^3numg(x&IkG}HDEpX010ehC zE%uk$P0NO}STGSo*Q8wLy1{yJZg124&%oOHFXf3Q)kS8KxSg78<2u`kG5V}SQloh<#v=+ z+C`(F>5N1)1+k&XOOQr=g)jtBqcdhY?qpQQ@#I`)?!BSNaJ3`%=Cm*sP_PN>d;4;n zu)2Y-X&T-`U=rGe(g}AcyiB(<4z`Y_q#19IqVna?v(93|b)QDZ6nmhih%(=EGn+{_DrRYyj+|$i*{QpvxBFSp5fTz# zc1M)GhfC9NuFk9j)NAjiiuuOs*OfE_zXf0kMMj1*ieVP*YA3`0^j}(gZg-I4W z4&Qb=-gxImf{K7-)z%hn$9vy8#{cRRXMO!ARXQzrGyJb=Vwh#@o+=bl`<>-eed4)6-9ZOuf#p zI69gJj&~_%EMjqQvC6?k1pCcnY=NrowTbdL#n?1ua)=xeAId;5gQS~wN>5bTN2u$1 zliVC}+%@7o+PWcOS3(5W;Iq~=94+Sjpu+uLFWXAJ{>*!vI%MY6ZO>kd~B;BaukPQ(=<XzqVoxkoc8fz1w_%A+g`)^Twk**8`0lpu%9_ouW4ZU0cRk48O^SfXQPq*V)w-+1w&1_~fsvJMzDU85+6 zsczmmN=SKu6~zZa32+Ik#@3T4DFU%?l9D!aq9XzeArwKU#S<3R$}8A+Txe5N!i)(C zZEO|4MqdD<5x7cjgC(V@EnIYY+iURnubPnEbk9a@jnguYn2+p}{*QmwesPv=NpEPKrW3GaH&jTDzcAt&rW#B+Y07DU@yWHaVOugJi zDZd;#5}$0^Jc%nw5%X1Csyt61@`OGDYpG_*OJ4r=KQr5 zhUK7~V40Or4*TtUix`G$!kLC=EqjaijcxSak9fq#-$R-yj&=y8-Q4bW#B9Bxx_`!| zt|cQOL2Wnd7Y-P3_t-xG90$)qkoG#VA%J2Ag-$X97mtLA6V_yyNRr-QnvVC$E_Yj7 zS0^NS(1HIC1fz!+!5vx8!uZ&LYzF7%)e{#N)EI`e=F_O#h_1fA<~Zi6a;146$tI?BG@ldiJse_8ty!MG1; zf&E=o{6=u@7>GmI6;_t59XZUPN}=3*=k=+bwM04XC!cAEFuhn5aJ7^Zf83UYSjxNA zpw#*Pz5X{MCgOKNE)%2pE=7m_v_cvjmmCHSQ8LJMaKDop^4N;dcihu`RxD%VVX0cX z(O()!$gHhXnN>ognyo^@B(<;ZB+9`--x)jGTyC0ia`EB{k}>7pu;)Ge2|a>`Nc&|=47h|q zCPnrK=vXpH$r%iH7h25^OS6M|za9s5k+3qV-r`{$9~t@PIN!nyUZxP3vpkTcLI`)F zuJaW)YPu*qXCAt#n3-mtIKS1nGaxv4w%E-I{_v-?xv&l_3Jv&{S<%hgY?RU(2$`9E z6+c^rg9gH0@hiZrxcY^FkKb^Go!7q;C1V{P9Ci>lNLm0fUF27Q$z>7H_;;HZ6mD+% zylysxHHIf8EFhUSHP0i&{1k%=H)6}aCk*mPJ9axm&X>r*28@ri%WeL?j}wU5EmL#8 zQ1AIJ45Ztp*2UZZ{ypGxG*Jd)82if`FD!9OU2hWY;_b}%0-q}c1`<5zERdikiM!_W zw4|&Vv|)03|5@-G01`o^0lPPK2*FmEN@i`kZk74H@FzN;jP3UFqyno(ezg6WOCa$D z=hK;YM7MUl3>q#-p=24a4lp1cV>JZ%>fk{`LSS$KHBo}4W}4UAO}r+pL|-L%ytc;g zk_r+=gv&IPRmo^-9lcPwun9Jtd~`5zH2SASspW3Z4`rl)r-dU~M;MZKO{vfe5N?CE zCV5OJD|;#VzT5|OviN}-6&WK;I7ysF;egTg)h)26nEtca##E2wl+B(@2CACYEmHY3QXikVFTs47(WfuH4Wu~Fx{Py(G<)&nd z6&vb?|;Fi^G|f8p9b79%Po|x ziJZ!yw`qYhQpeINI^jJuw33p;B`M(I;ck)s6ZXiknOZ z|3(rQRS~HxgZ!5~Kz2y))$e=ueaXWVVEjZnZ&a(tWD7N2`Jhw5W0;`=ldpGwBFp{z zSjXEcWLhnv@)GilV9Dz4{vhbSZAdFf6qKtxOQBdyCr}b9QFL2}jcyi6785h`6Y!s1 z9ggZed-f1Ab{pgxXsI*WVp_@K!kTCND3Da%pYN8t{g;f4D#?7UbeNc40B!H(_I4{M zKmikS)5D3&`&UJgHrN`7)!5qfSW7xiBL=7#aM8Ueb1?F|F}*R4Q&usJ5*IeVJ)MZl zr@(ppHZcSvD5*C$n=DwmwQ2u)azxF%=Rn2_xs0ngG8TePAS_c$w5%^qv!U1vo?@vbL?2j8qARF}R zIxN$jnOoSw63{x+0SBJ_B;`5-9`j>?I?4W;3YU$I8|_c)PaG(wrvVu@Q2mcw>bP;v(3u#0n=80qLbCu_-(}#ECIXv*N<KR z*xME-=iprcl61ls#9-gLJp0fBxlzc4&GXO6$)2~vwI3ds0x-a-dM_%;TfIF|T{=-# zLXs(DZ}IpR3roRVYy9A<@z$R>z|Ze>oJ8T}#4o>7xNp~Yv;@z#cIPj#M_5|E5OiKa zfy}Y6Jw0ymXA}WVYrqfRV-CK&4M?bcpEtrwOWEiNdHG91Gi7o)Z69sLD}MOOpj9GC z`kiD+O=Z3nnBt?Iv=)_@iSH5;-Wa!DNxHb0#G$jKm6TwDexL17%orRliKkU6)?8`( zes9-U5lIuVI z`G?H>Q>%YL#KIy^LL-q7fN|ev>&t!`W~4L+2=?w>4AeJ7t{a*%+7mtYm=!C~ow%;k z|HtC@d^^9QT~5B|ajAhdP=LXuJnUj=SlryMdNm7C($Q9qq>KWvVTxiThmPwu-{O3l z|83(gqEmyEY(empQ$E_a7xBN!m_SGGQus>FLm&0~TVm!Ux4%~@5IaDU2LuMP0*QtS zrX8yL1R#>gboG--NCjiL9$E=HnqWd9?{l5_^iG;={I0&AjFZ#tu_7uI@BykurFI4U zyu;Ys%wuHVSU2J439AD9*`#-r`p#AwfEooQN*wqx_Ma6Fn-ea`I_%>^?c>WZ2Z`9@ zNYOKAOmj4fDirn~R_TF{ z2>tHytT+fiN*GnAXJTzUjUJELNXbsqHB{y^0kD9(sR_6wV4dF(GYgqcRc~8N*IMy6 zq9Q-tU5vFev&#h^8npH{(^fozc}tyBHL1v;n3}4;O9i8aM>B>a>=v~s_;ueK2v_8e z1t^E$k_q@k`y_m_pkN=iMcjg=!rh8(wg{dU2iG4V&{5wK6~(Hlks1t)zy+zo$HPnM z-S2`w5jjO1C179&G78W2@Ve@G9n`kdeKm~x1L_(Y;IiT1x1$XPXO_dEx-2W3ElK=4 z<|ab%&8CCZ9R*rS?4=4j5WH@&ENOv>2)P4CyJ~(!PDCX5Sv@+_Lre&@HwI)%yqFfry1af{H33gH8A{nW1h!hUAy z*94HJG)=>YD8qXV4GPxdY z`3tqab>e^yBNV+?_dJa7DDP#_@!NhajOQMXP_%saRw`0yZlZjMM4YzK+mdco`;Ev5CJ`2NXjIBR_?1e!US|JH&)U)t5v!|mn`%YE%{J|IoUSv>mN`wHyu zz?!n%(*4(hU7uG39E!Jy!qPJ`LSpD>nD~$G&onAu@wDFcd`lXOh4kJ}RhO&F4|B!< zxFc2X?gPW?)wx;xdk^H20zOBgSf{6k?Q?Y!_d!T#CpUsEkH0_>{87k!31+mgD*Ja$ zs|Ppyimfd37iWIVCKQlZf}8?XKe(@N^Ip~RfhU9y5)k-4(tHbhgtq8HYMf&eYU!YS zfw23Ppct|R!UCF3U5HBO(abQks`_uT;3(g}X-`Ne}9;0Al` zzN5N3|8(6yuveZTyPuMXj4T#7@~lHrQsB^b8~;{sHfF^TLLw^BPcfOUjq~`oM)*ls zfDlvz4KWmy*T$_vi~?F=Q+md6don#=bRKF<{C1U+?YdW8tHi~onf;|j#@w9$Xd8b4 zoVrkI(7`T3^hyiyGn-V%@JWdz$zQ)fD_N`neR{PAI-1}_~K z7Z;}UYO18P^zTM<@V?FMd4SstAh}6P5dFk=OPBmuxo6L$G&PeXQ&Z}Hf4c+t7UNAP z+Mi0>*Uf>tnf}+BdHT9vFUzT^sfR}18Q8{wY@WYW$J;@PNicdUbk&sUS- zI44_mW_s{|8enAGbRFN&PgO`5-_i>?8T1_!f0T%b+Rwvop)go=p@iKY=loRN-BePw ztOx!VVUl02Yi%gu`Cumw3m12yb6LTI*;0P~NhrlO;oMV(z232WipfLxjTb*@eig9W z$H_{mOdak$BO!t9yURB$Zy!|xg3Z-lyf;zJKH-@Ld7pj8aWTdjOPDM`s& zjEqmHmEWuF%w!v1U-`q<1JQqL!-%u9pXVlgyu6P$#(rA2fPpCCPeUW@U%m+-C5p6_`%e|&b_gR7E?iW~!}(UL#BgedtW#4s1-7i&$T7#SJq7{qg$X2mJf#9uK!dUPW^ z{Kd(|>5YZO`*BH0|JfY!N=eIQOGo)j=X~^%JfV%{D;=->E_Sq zMoWq#bt=ARl$K)n`r3lLkMDbV;je>HrIjPZ8TTo^gfQFF)x~AB_aS!p-M$F5l?wZ; z{DNZk{fC~ikC)zj{21|*_0~^wu#>;P`wZh&mp-L$u^kf}IfuY?@z| z5T{N=`ukwV>OA`Y{24TLn~{o&3RhS|n|^De91T1{JkE9dpN@Z4Mn^;x+~dSv%{+MW zGPJ@CoQ&(EVEun7o4K762Zad8>Sc}DX|#FON)!H5o6dU)M7wbkJ$03(KoFh0yz zuU>)66AN63l#r+v78Vc)Fo|}+XE!RzaD!nVHpI8Pf-fy%s@4^`(;N%7iMviN44i}U zW~kg$1|BohZR?MNlM{#I-{s+Wz~U!yfBM_EZ|52O5CV%ADD{{LUNK}(;GchdU>N|r%%6f{ z3l4zb_wOmLV6z`sbXwsi4Gj$#lkZ)orKF^q;g6hJB}h{MHNQ=msP|EVi*~Te&sU84 z&haXG?k!*ggl+9$+t2|YKN?2WdzY=mBYiDBEl3>24%<^T_6E5>Yx!~gHJ#}c9JBU4 z2O9SG7G=nZh;|SAS!>}K1MAT|;+x@;QG6XDA|l%F@9I;UMzON8mj9`+{sw!;ze1W> zSzYY}zg081HebN5=#h~TsH(Q6V8+`7)0v`zLZt7>?i;=iZE)oLhM}Y~jgpd)x&Q3h zvz7IAoiYa4wN6e;+Xr%14+3<-v2t)QCVlw8?zRat$|WMAx4G3@Sbu(ea9|3Qv-fMXtGf+`=1Efp2XNIc)rVrgp8{=OE8m3?{=3-?Hww)+@^U!|g6QAap>-)wu zumG09PX2P3W?mR5x5WmA*OIrv3_7*!8_4PmV9bK;uPFxR;fL*i; z&NG-uYc==`OlSuws$<1^WsInD_5}G!9o2` zxv)B08$}R}S2{a&l++SyR8qSs2Q1>A1pr~eto__GC`|1xURd>kAclmd3N$OAxN>7t{fH^E6C2%?)e1L4sF zIv2?!h(9fO-&p}5xdqmLZgcp2F^NWjtFzfG6s|VA>nIAo>nY&1=v~`qt`gDGC zGYT@)7qi}^u!snb@y9tjU{Ad;)Yqp&eUm=5DrJyxJeBCGKUS<;HFpimE>M<5LQii> zU?&oCkh+kYC!EWHKs?vz=M>8>EhR(%3MC4^YCO@k9M=aU_VaJ%{Q!BIa}Q zdU@Gws?MD-IyyS;Sn>8vSmV2Aht_&EP8iF}%Q#ieLZ62=4&@k3d2&a>K{CupPe*{8 zum$E_6Yofg>35~@-E7rx9>WGn?nyeESAj1}#P9UfK}Ce)T$uO&>>NMMSC1gE=U^!a z?t3&}TwFZAI+zwWE|x~fk;q}Z-7Yl#8P3~i^uLZd!?JaCJ(T6!D*dI}5icKrCjp0` zM6|R>xVXD7g10tq88Z-tJ{F6|p#HHSZ3i5);&{4mrp-k@IySZd5MXU*M+QFc>%)6_ zj|!?JVl(Qirl#iZ#yAhSm*+=vmE&CL2(VyT;=BXW^2D;$r2KK_u#ux9F+7qC90fA^ zSfTKjM7CFkBYaC z?!;_u*(Ud!qoblIDk-(tRV~6L<{&*wIOe=E}|#tv|B?ZmxtcoUi9?zKrWZV@ApT2s*y}T?XT5R#sZ|Sp8xZA-v$2NDZrDRqC1oA zPAx3ftc+sp|IM2>u-R-FA0HQNpXo~M{s91&%N29V^>m?9sW3D&gqoU~q_+|K?^voj zv9Pd!ii(O8Jz$A>mDq7|E)(l1rB1B=OWTK)QMB#tZG=K03=9mQxw%>Da7ZLhrxS&R zh46Sh*xcMiUtb?Wp%AoMt<<4WmSWD4lsG?fhH$&xsHv$zeSJL)27}b$kVy1;J=)sZ zaP#I(1Ofr5)oQ$Z_YS$axl)HlS&BJFQsN*aLtMXpJ?f4C%3fVvU0MCznv+O}xh}F1 zbB?6K%P~YmL?j6gLWqcnND>@`5D^iPBsd5mA|fJ5a1cU7L`0H^d3TJ<8jf z5F#QXk^~1KL_|a+2@XPth=@oM{{r|=>L7@Si0JhBA5N!25bsXX+yDRo07*qoM6N<$ Ef;Nfiq5uE@ literal 19519 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 z zXlP5b^YfoB*8e5lZES#e($a2gAJy1vqZBGNwf-5@=zz(1>n@h&y{|?t|G*vN)@Z7Y>yAs(W1ploFxZ@~bG&Cz z`yg?;^-zfe3;7jD21`>W>Snz$68g2<;mSLlz}@%7V;~~t?CK#Z1RcNQv%m-THX0kk zID`HDy@;R$q5_tcfH+CkSSUot8Jas}OU?!!BL0w&=8i&bMg%|EOJQec@YdI+v>qr{ z)1UWvL4zj>{3jsA^qZ(B;W-fs67<#`e|j?BNwf$7eOP*Q4V}8M?+GDLw{k%4BGi}j zLyRnA(G3=Kxh97UW&r`5SgMJjT+8U7l*G-6LI_Vwd8G)HOQ?{bK$A8u`xqHvt9`^y z=pQ$5er~y9K0u`I@DczLd7ugo;^_w_6Tw{s6HJbSgYU?3XvsxkPxwWaqMLG z+vnEJHMKTh%T%wt$gRd#j!h1`vyo^PS!LAH$uz8t*hR2AZ{eWdwHr7t&!4ohwFQ}z zHsE3a#megVv&XEEBhkWw6OyxYp_BVRLJ(55M4w1lvoJoIV_5$AMV!yaP0wytSou@r zc#Cg2BFQ5o^K$Cier}cs9DZbKiiU#ntaJY6;atlluD!iGSd1_cHLER<(}3_D0qY~B zh#*bKSmn=pmd*}*i82j1@xf(q^>>i)fsGE1@2Q$R5U{yE&3@mNrI8kX)i?=@(6wht z*#m$?i^Lu0E^#V_MzQf7e~xFUZLE&$Vi|Sd&6?t4&R^~p_V!FQ4iBUwjx>lqJtApY z_EFNd4ZIpNVr#Prl_sopY>NVk&-`p(ZMxdJdYm|;^K)7V(jyHGmVgUu-is4~9+N=T zWaX(IP(H!6h6j5)Bta8TSi}JMnBCEFu0YDmC?ZT*%-ew`6--Vq*G2ce#5NllWsxDd zAi?=ArnGG_@a=*Vm_>8c>9y0`8U3%*U#H!_y|nvVPru0ntv7y;Cuxa{ZHEO7X?M;) zR4HlJ)L{ZmwL372@YYQ=SN19cinpe6;CN!h7@iGcMY#75Cp~ z=i+^rrX(}2 z;rI`gTTG2XsEwn=2`k>h176ai{|)}T`+Z@D6CSrv2V5=5~G??*>9S!=Ex$D)0bS2IIjbMNTDHa_e?{W_B^>Ka(4f%V6!hGXtM>Az1gBDO^x5*Gi5z zY$GE#>itEDAmp9@UEKFOdxPumZ?CWaAROc!Cr4rIUZH>%p{4t8gb|2sfSOU4l$FtCVJmUVur@{t+UR=x zV*PV%TlI8Ic`Yq;pA);dNa7)WCsXQ%cd-N{B$1H3!M+pjf60b0ml%cXyo!cXK6X%u z_Xurlq*602GL$jW7Hvd;OlfXL&gdy*F8cl8R2{yP6%R#8Kb3kz%Q11roDcpMPY zZ=OnJH{vk6J|m|a+9JEN16z#^fCxZQ%(7CoKiW>4a{mE*{N{vq`cs>ber9E9;ZK;X zQ<-9sh^RmmYtTPY(W_I=A+>(awd@$!pny`{^QR}6&-RH)nG6S6suCtrcVE8Q_Ox;T zw{IN-N%w_|g{ic8_NVNOe}U)2?{^(IPEJ-y7d_?0r^A)?^5Q}mjn>DEh0_c;+%!JnsG@ zTZS3Tu-GXn+yzif_%(=_Wd0hs{M#z5LCDg4SpxamwmpkG{|JVM??Cs!@3B{#dafV- zH!&Qs`Va1?oMG(Eu`YH;rt$F?4qA&TDN!QMba{%wBq~b2)a%|CL)k)FRLsoCi08T2 zDh-_hcyE|_cy86$Y-B0KTUAusy>9haB`s=aV62i>iiqjA7&yKvtO>t8FXdM4r&3B9 z{(m8u{+_Jqs{Y4BD9gHwAB7L-W#w2Gx+5vmM_!`*$IJl^7-%0D;gm9AZtc8nM>2=2 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 diff --git a/html/buffer_8h_source.html b/html/buffer_8h_source.html index e31597b6f..7fa8c18d5 100644 --- a/html/buffer_8h_source.html +++ b/html/buffer_8h_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/buffer.h Source File @@ -19,10 +19,9 @@

- + +/* @license-end */ +
-
-
buffer.h
+
buffer.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
32 #ifndef BUFFER_H
-
33 #define BUFFER_H
-
34 
-
35 #pragma once
-
36 
-
37 #include "fileio.h"
-
38 
-
39 #include <mutex>
-
40 #include <vector>
-
41 #include <stddef.h>
-
42 
-
43 #define CACHE_CHECK_BIT(mask, var) ((mask) == (mask & (var)))
-
45 #define CACHE_CLOSE_NOOPT 0x00000000
-
46 #define CACHE_CLOSE_FREE 0x00000001
-
47 #define CACHE_CLOSE_DELETE (0x00000002 | CACHE_CLOSE_FREE)
-
49 #define CACHE_FLAG_RO 0x00000001
-
50 #define CACHE_FLAG_RW 0x00000002
-
55 class Buffer : public FileIO
-
56 {
-
64  static constexpr int PREALLOC_FACTOR = 5;
-
65 public:
-
69  typedef struct _tagCACHEINFO
-
70  {
-
71  public:
- -
73  : m_fd(-1)
-
74  , m_buffer(nullptr)
-
75  , m_buffer_pos(0)
- -
77  , m_buffer_size(0)
-
78  , m_seg_finished(false)
-
79  , m_fd_idx(-1)
-
80  , m_buffer_idx(nullptr)
- -
82  , m_flags(0)
- -
84  , m_buffer_writes(0)
-
85  {
-
86  }
-
87 
-
91  void reset()
-
92  {
-
93  m_fd = -1;
-
94  m_buffer = nullptr;
-
95  m_buffer_pos = 0;
- -
97  m_buffer_size = 0;
- -
99  m_buffer_writes = 0;
-
100  }
-
101 
-
102  // Main cache
-
103  std::string m_cachefile;
-
104  volatile int m_fd;
-
105  uint8_t * m_buffer;
-
106  size_t m_buffer_pos;
- -
108  size_t m_buffer_size;
- -
110  // Index for frame sets
-
111  std::string m_cachefile_idx;
-
112  volatile int m_fd_idx;
-
113  uint8_t * m_buffer_idx;
- -
115  // Flags
-
116  uint32_t m_flags;
-
117  // Statistics
- -
119  unsigned int m_buffer_writes;
- -
121  typedef CACHEINFO const * LPCCACHEINFO;
-
123 public:
-
127  explicit Buffer();
-
133  virtual ~Buffer();
-
138  virtual VIRTUALTYPE type() const override;
-
144  bool init(bool erase_cache);
-
151  bool set_segment(uint32_t segment_no, size_t size);
-
156  uint32_t segment_count();
-
161  uint32_t current_segment_no();
-
167  bool segment_exists(uint32_t segment_no);
-
173  bool release(int flags = CACHE_CLOSE_NOOPT);
-
178  virtual size_t bufsize() const override;
-
179 
-
185  virtual int openio(LPVIRTUALFILE virtualfile) override;
-
192  virtual size_t readio(void *data, size_t size) override;
-
203  size_t read_frame(std::vector<uint8_t> * data, uint32_t frame_no);
-
208  virtual int error() const override;
-
212  virtual int64_t duration() const override;
-
217  virtual size_t size() const override;
-
223  virtual size_t size(uint32_t segment_no) const;
-
228  virtual size_t tell() const override;
-
234  virtual size_t tell(uint32_t segment_no) const;
-
248  virtual int seek(int64_t offset, int whence) override;
-
263  virtual int seek(int64_t offset, int whence, uint32_t segment_no);
-
268  virtual bool eof() const override;
-
274  virtual bool eof(uint32_t segment_no) const;
-
278  virtual void closeio() override;
-
285  size_t writeio(const uint8_t* data, size_t length);
-
293  size_t write_frame(const uint8_t* data, size_t length, uint32_t frame_no);
-
298  bool flush();
-
303  bool clear();
-
309  bool reserve(size_t size);
-
319  size_t buffer_watermark(uint32_t segment_no = 0) const;
-
327  bool copy(std::vector<uint8_t> * out_data, size_t offset, uint32_t segment_no = 0);
-
336  bool copy(uint8_t* out_data, size_t offset, size_t bufsize, uint32_t segment_no = 0);
-
342  const std::string & cachefile(uint32_t segment_no) const;
-
351  static const std::string & make_cachefile_name(std::string &cachefile, const std::string & filename, const std::string &fileext, bool is_idx);
-
357  static bool remove_file(const std::string & filename);
-
363  bool have_frame(uint32_t frame_no);
-
367  void finished_segment();
-
373  bool is_segment_finished(uint32_t segment_no) const;
-
381  bool open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize = 0);
-
388  bool close_file(uint32_t segment_no, uint32_t flags);
-
389 
-
390 protected:
-
396  bool remove_cachefile(uint32_t segment_no = 0) const;
-
401  bool is_open();
-
402 
-
403 private:
-
413  uint8_t* write_prepare(size_t length);
-
422  void increment_pos(size_t increment);
-
432  bool reallocate(size_t newsize);
-
447  bool map_file(const std::string & filename, volatile int *fd, uint8_t **p, size_t *filesize, bool *isdefaultsize, size_t defaultsize, bool truncate) const;
-
457  bool unmap_file(const std::string & filename, volatile int *fd, uint8_t **p, size_t len, size_t *filesize) const;
-
458 
-
464  LPCACHEINFO cacheinfo(uint32_t segment_no);
-
470  LPCCACHEINFO const_cacheinfo(uint32_t segment_no) const;
-
471 
-
472 private:
-
473  std::recursive_mutex m_mutex;
- -
475  uint32_t m_cur_open;
-
477  std::vector<CACHEINFO> m_ci;
-
478 };
-
479 
-
480 #endif
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
32#ifndef BUFFER_H
+
33#define BUFFER_H
+
34
+
35#pragma once
+
36
+
37#include "fileio.h"
+
38
+
39#include <mutex>
+
40#include <vector>
+
41#include <stddef.h>
+
42
+
43#define CACHE_CHECK_BIT(mask, var) ((mask) == (mask & (var)))
+
45#define CACHE_CLOSE_NOOPT 0x00000000
+
46#define CACHE_CLOSE_FREE 0x00000001
+
47#define CACHE_CLOSE_DELETE (0x00000002 | CACHE_CLOSE_FREE)
+
49#define CACHE_FLAG_RO 0x00000001
+
50#define CACHE_FLAG_RW 0x00000002
+
55class Buffer : public FileIO
+
56{
+
64 static constexpr int PREALLOC_FACTOR = 5;
+
65public:
+
69 typedef struct _tagCACHEINFO
+
70 {
+
71 public:
+ +
73 : m_fd(-1)
+
74 , m_buffer(nullptr)
+
75 , m_buffer_pos(0)
+ +
77 , m_buffer_size(0)
+
78 , m_seg_finished(false)
+
79 , m_fd_idx(-1)
+
80 , m_buffer_idx(nullptr)
+ +
82 , m_flags(0)
+ + +
85 {
+
86 }
+
87
+
91 void reset()
+
92 {
+
93 m_fd = -1;
+
94 m_buffer = nullptr;
+
95 m_buffer_pos = 0;
+ +
97 m_buffer_size = 0;
+ + +
100 }
+
101
+
102 // Main cache
+
103 std::string m_cachefile;
+
104 volatile int m_fd;
+
105 uint8_t * m_buffer;
+ + + + +
110 // Index for frame sets
+
111 std::string m_cachefile_idx;
+
112 volatile int m_fd_idx;
+
113 uint8_t * m_buffer_idx;
+ +
115 // Flags
+
116 uint32_t m_flags;
+
117 // Statistics
+ +
119 unsigned int m_buffer_writes;
+ +
121 typedef CACHEINFO const * LPCCACHEINFO;
+
123public:
+
127 explicit Buffer();
+
133 virtual ~Buffer();
+
138 virtual VIRTUALTYPE type() const override;
+
144 bool init(bool erase_cache);
+
151 bool set_segment(uint32_t segment_no, size_t size);
+
156 uint32_t segment_count();
+
161 uint32_t current_segment_no();
+
167 bool segment_exists(uint32_t segment_no);
+
173 bool release(int flags = CACHE_CLOSE_NOOPT);
+
178 virtual size_t bufsize() const override;
+
179
+
185 virtual int openio(LPVIRTUALFILE virtualfile) override;
+
192 virtual size_t readio(void *data, size_t size) override;
+
203 size_t read_frame(std::vector<uint8_t> * data, uint32_t frame_no);
+
208 virtual int error() const override;
+
212 virtual int64_t duration() const override;
+
217 virtual size_t size() const override;
+
223 virtual size_t size(uint32_t segment_no) const;
+
228 virtual size_t tell() const override;
+
234 virtual size_t tell(uint32_t segment_no) const;
+
248 virtual int seek(int64_t offset, int whence) override;
+
263 virtual int seek(int64_t offset, int whence, uint32_t segment_no);
+
268 virtual bool eof() const override;
+
274 virtual bool eof(uint32_t segment_no) const;
+
278 virtual void closeio() override;
+
285 size_t writeio(const uint8_t* data, size_t length);
+
293 size_t write_frame(const uint8_t* data, size_t length, uint32_t frame_no);
+
298 bool flush();
+
303 bool clear();
+
309 bool reserve(size_t size);
+
319 size_t buffer_watermark(uint32_t segment_no = 0) const;
+
327 bool copy(std::vector<uint8_t> * out_data, size_t offset, uint32_t segment_no = 0);
+
336 bool copy(uint8_t* out_data, size_t offset, size_t bufsize, uint32_t segment_no = 0);
+
342 const std::string & cachefile(uint32_t segment_no) const;
+
351 static const std::string & make_cachefile_name(std::string &cachefile, const std::string & filename, const std::string &fileext, bool is_idx);
+
357 static bool remove_file(const std::string & filename);
+
363 bool have_frame(uint32_t frame_no);
+
367 void finished_segment();
+
373 bool is_segment_finished(uint32_t segment_no) const;
+
381 bool open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize = 0);
+
388 bool close_file(uint32_t segment_no, uint32_t flags);
+
389
+
390protected:
+
396 bool remove_cachefile(uint32_t segment_no = 0) const;
+
401 bool is_open();
+
402
+
403private:
+
413 uint8_t* write_prepare(size_t length);
+
422 void increment_pos(size_t increment);
+
432 bool reallocate(size_t newsize);
+
447 bool map_file(const std::string & filename, volatile int *fd, uint8_t **p, size_t *filesize, bool *isdefaultsize, size_t defaultsize, bool truncate) const;
+
457 bool unmap_file(const std::string & filename, volatile int *fd, uint8_t **p, size_t len, size_t *filesize) const;
+
458
+
464 LPCACHEINFO cacheinfo(uint32_t segment_no);
+
470 LPCCACHEINFO const_cacheinfo(uint32_t segment_no) const;
+
471
+
472private:
+
473 std::recursive_mutex m_mutex;
+ +
475 uint32_t m_cur_open;
+
477 std::vector<CACHEINFO> m_ci;
+
478};
+
479
+
480#endif
#define CACHE_CLOSE_NOOPT
Dummy, do nothing special.
Definition: buffer.h:45
The Buffer class.
Definition: buffer.h:56
std::vector< CACHEINFO > m_ci
Cache info.
Definition: buffer.h:477
virtual int64_t duration() const override
Get the duration of the file, in AV_TIME_BASE fractional seconds.
Definition: buffer.cc:842
static constexpr int PREALLOC_FACTOR
PREALLOC_FACTOR - Number of elements allocated on reallocate calls Number of elements allocated on re...
Definition: buffer.h:64
-
virtual bool eof() const override
Check if at end of file.
Definition: buffer.cc:1051
+
virtual bool eof() const override
Check if at end of file.
Definition: buffer.cc:1044
void increment_pos(size_t increment)
Increment buffer position.
Definition: buffer.cc:762
-
LPCACHEINFO cacheinfo(uint32_t segment_no)
Get cache information.
Definition: buffer.cc:1125
+
LPCACHEINFO cacheinfo(uint32_t segment_no)
Get cache information.
Definition: buffer.cc:1118
uint8_t * write_prepare(size_t length)
Prepare for the writing operation.
Definition: buffer.cc:745
bool release(int flags=CACHE_CLOSE_NOOPT)
Release cache buffer.
Definition: buffer.cc:494
uint32_t m_cur_open
Number of open files.
Definition: buffer.h:475
virtual int openio(LPVIRTUALFILE virtualfile) override
Open a virtual file.
Definition: buffer.cc:64
bool segment_exists(uint32_t segment_no)
Check if segment exists.
Definition: buffer.cc:350
-
void finished_segment()
Complete the segment decoding.
Definition: buffer.cc:1100
+
void finished_segment()
Complete the segment decoding.
Definition: buffer.cc:1093
virtual int seek(int64_t offset, int whence) override
Seek to position in file.
Definition: buffer.cc:767
size_t writeio(const uint8_t *data, size_t length)
Write data to the current position in the buffer. The position pointer will be updated.
Definition: buffer.cc:664
bool clear()
Clear (delete) buffer.
Definition: buffer.cc:587
-
static const std::string & make_cachefile_name(std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)
Make up a cache file name, including the full path.
Definition: buffer.cc:978
+
static const std::string & make_cachefile_name(std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)
Make up a cache file name, including the full path.
Definition: buffer.cc:971
bool map_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t *filesize, bool *isdefaultsize, size_t defaultsize, bool truncate) const
Map memory to a file.
Definition: buffer.cc:361
virtual ~Buffer()
Free Buffer object.
Definition: buffer.cc:49
bool unmap_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t len, size_t *filesize) const
Unmap memory from the file.
Definition: buffer.cc:444
-
virtual void closeio() override
Close buffer.
Definition: buffer.cc:1061
+
virtual void closeio() override
Close buffer.
Definition: buffer.cc:1054
virtual VIRTUALTYPE type() const override
Get type of this virtual file.
Definition: buffer.cc:54
bool init(bool erase_cache)
Initialise cache.
Definition: buffer.cc:179
std::recursive_mutex m_mutex
Access mutex.
Definition: buffer.h:473
-
bool is_segment_finished(uint32_t segment_no) const
Return true if transcoding of the segment is finished.
Definition: buffer.cc:1112
-
static bool remove_file(const std::string &filename)
Remove (unlink) the file.
Definition: buffer.cc:998
+
bool is_segment_finished(uint32_t segment_no) const
Return true if transcoding of the segment is finished.
Definition: buffer.cc:1105
+
static bool remove_file(const std::string &filename)
Remove (unlink) the file.
Definition: buffer.cc:991
size_t write_frame(const uint8_t *data, size_t length, uint32_t frame_no)
Write image data for the frame number into the buffer.
Definition: buffer.cc:691
CACHEINFO const * LPCCACHEINFO
Pointer to const version of CACHEINFO.
Definition: buffer.h:121
-
const std::string & cachefile(uint32_t segment_no) const
Get cache filename.
Definition: buffer.cc:964
-
virtual size_t readio(void *data, size_t size) override
Not implemented.
Definition: buffer.cc:1012
-
bool have_frame(uint32_t frame_no)
Check if we have the requested frame number. Works only when processing a frame set.
Definition: buffer.cc:1066
+
const std::string & cachefile(uint32_t segment_no) const
Get cache filename.
Definition: buffer.cc:957
+
virtual size_t readio(void *data, size_t size) override
Not implemented.
Definition: buffer.cc:1005
+
bool have_frame(uint32_t frame_no)
Check if we have the requested frame number. Works only when processing a frame set.
Definition: buffer.cc:1059
bool flush()
Flush buffer to disk.
Definition: buffer.cc:559
bool reserve(size_t size)
Reserve memory without changing size to reduce re-allocations.
Definition: buffer.cc:627
uint32_t current_segment_no()
Get the currently selected segment.
Definition: buffer.cc:339
struct Buffer::_tagCACHEINFO CACHEINFO
Structure to hold current cache state.
-
bool reallocate(size_t newsize)
Reallocate the buffer to a new size.
Definition: buffer.cc:936
-
virtual int error() const override
Get last error.
Definition: buffer.cc:1046
+
bool reallocate(size_t newsize)
Reallocate the buffer to a new size.
Definition: buffer.cc:929
+
virtual int error() const override
Get last error.
Definition: buffer.cc:1039
bool copy(std::vector< uint8_t > *out_data, size_t offset, uint32_t segment_no=0)
Copy buffered data into output buffer.
Definition: buffer.cc:878
virtual size_t bufsize() const override
Size of this buffer.
Definition: buffer.cc:59
-
LPCCACHEINFO const_cacheinfo(uint32_t segment_no) const
Get cache information.
Definition: buffer.cc:1141
+
LPCCACHEINFO const_cacheinfo(uint32_t segment_no) const
Get cache information.
Definition: buffer.cc:1134
uint32_t segment_count()
Get segment count.
Definition: buffer.cc:332
struct Buffer::_tagCACHEINFO * LPCACHEINFO
Pointer version of CACHEINFO.
virtual size_t tell() const override
Get the value of the internal read position pointer.
Definition: buffer.cc:824
@@ -275,12 +274,12 @@
bool set_segment(uint32_t segment_no, size_t size)
Set the current segment.
Definition: buffer.cc:306
bool remove_cachefile(uint32_t segment_no=0) const
Remove the cachefile.
Definition: buffer.cc:544
Buffer()
Create Buffer object.
Definition: buffer.cc:42
-
bool is_open()
Check if the cache file is open.
Definition: buffer.cc:1085
+
bool is_open()
Check if the cache file is open.
Definition: buffer.cc:1078
virtual size_t size() const override
Get the value of the internal buffer size pointer.
Definition: buffer.cc:847
bool open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize=0)
Open the cache file if not already open.
Definition: buffer.cc:77
bool close_file(uint32_t segment_no, uint32_t flags)
If it hasn't already been done, close the cache file.
Definition: buffer.cc:137
size_t buffer_watermark(uint32_t segment_no=0) const
Return the current watermark of the file while transcoding.
Definition: buffer.cc:865
-
size_t read_frame(std::vector< uint8_t > *data, uint32_t frame_no)
Write image data for the frame number into the buffer.
Definition: buffer.cc:1019
+
size_t read_frame(std::vector< uint8_t > *data, uint32_t frame_no)
Write image data for the frame number into the buffer.
Definition: buffer.cc:1012
Base class for I/O.
Definition: fileio.h:258
LPVIRTUALFILE virtualfile()
Get virtual file object.
Definition: fileio.cc:114
const std::string & filename() const
Get source filename.
Definition: fileio.cc:124
@@ -306,7 +305,7 @@
diff --git a/html/bug.html b/html/bug.html index 15935b64e..f85a9aca8 100644 --- a/html/bug.html +++ b/html/bug.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Bug List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
-
Bug List
+
+
Bug List
@@ -93,7 +92,7 @@
diff --git a/html/cache_8cc.html b/html/cache_8cc.html index 63d6b26d2..186f011bc 100644 --- a/html/cache_8cc.html +++ b/html/cache_8cc.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache.cc File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache.cc File Reference
+
cache.cc File Reference
@@ -122,19 +121,16 @@

Go to the source code of this file.

- - - + + - - + + - - + + @@ -144,13 +140,13 @@

+

Macros

-#define sqlite3_errstr(rc)   ""
 If our version of SQLite hasn't go this function.
#define sqlite3_errstr(rc)   ""
 If our version of SQLite hasn't go this function. More...
 
-#define STRINGIFY(x)   #x
 Stringification helper for STRINGIFY. Not to be used separately.
#define STRINGIFY(x)   #x
 Stringification helper for STRINGIFY. Not to be used separately. More...
 
-#define TOSTRING(x)   STRINGIFY(x)
 Convert a macro argument into a string constant.
#define TOSTRING(x)   STRINGIFY(x)
 Convert a macro argument into a string constant. More...
 
#define SQLBINDTXT(idx, var)
 Bind text column to SQLite statement. More...
 

Detailed Description

-

Cache class implementation.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

Cache class implementation.

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file cache.cc.

Macro Definition Documentation

- +

◆ SQLBINDNUM

@@ -182,8 +178,8 @@

Value:
if (SQLITE_OK != (ret = func(m_cacheidx_insert_stmt, idx, var))) \
-
-
Logging::error(m_cacheidx_file, "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
+
{ \
+
Logging::error(m_cacheidx_file, "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
throw false; \
}
#define sqlite3_errstr(rc)
If our version of SQLite hasn't go this function.
Definition: cache.cc:41
@@ -191,11 +187,11 @@

Definition at line 864 of file cache.cc.

+

Definition at line 877 of file cache.cc.

- +

◆ SQLBINDTXT

@@ -221,21 +217,87 @@

Value:
if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_insert_stmt, idx, var, -1, nullptr))) \
-
-
Logging::error(m_cacheidx_file, "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
+
{ \
+
Logging::error(m_cacheidx_file, "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
throw false; \
}

Bind text column to SQLite statement.

-

Definition at line 852 of file cache.cc.

+

Definition at line 865 of file cache.cc.

+ +

+
+ +

◆ sqlite3_errstr

+ +
+
+ + + + + + + + +
#define sqlite3_errstr( rc)   ""
+
+ +

If our version of SQLite hasn't go this function.

+ +

Definition at line 41 of file cache.cc.

+ +
+
+ +

◆ STRINGIFY

+ +
+
+ + + + + + + + +
#define STRINGIFY( x)   #x
+
+ +

Stringification helper for STRINGIFY. Not to be used separately.

+ +

Definition at line 44 of file cache.cc.

+ +
+
+ +

◆ TOSTRING

+ +
+
+ + + + + + + + +
#define TOSTRING( x)   STRINGIFY(x)
+
+ +

Convert a macro argument into a string constant.

+ +

Definition at line 45 of file cache.cc.

diff --git a/html/cache_8cc__incl.png b/html/cache_8cc__incl.png index ac89b57661f64d844c3268dd7743a8ab833870f2..92032669a8deb47ffe2b565c1cb6978133d2cba5 100644 GIT binary patch delta 58863 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

Oy3_2xD3G7o@sRGzcHM00I4BaR2wv6X~LB1y&L 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 diff --git a/html/cache_8cc_source.html b/html/cache_8cc_source.html index a1ed9fdaa..03cd3e732 100644 --- a/html/cache_8cc_source.html +++ b/html/cache_8cc_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache.cc Source File @@ -19,10 +19,9 @@

- + +/* @license-end */ +
-
-
cache.cc
+
cache.cc
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
32 #include "cache.h"
-
33 #include "cache_entry.h"
-
34 #include "ffmpegfs.h"
-
35 #include "logging.h"
-
36 
-
37 #include <vector>
-
38 #include <cassert>
-
39 
-
40 #ifndef HAVE_SQLITE_ERRSTR
-
41 #define sqlite3_errstr(rc) ""
-
42 #endif // HAVE_SQLITE_ERRSTR
-
43 
-
44 #define STRINGIFY(x) #x
-
45 #define TOSTRING(x) STRINGIFY(x)
- -
48 {
-
49  //
-
50  // Table name
-
51  //
-
52  "cache_entry",
-
53  //
-
54  // Primary key
-
55  //
-
56  "PRIMARY KEY(`filename`,`desttype`)"
-
57 };
-
58 
- -
60 {
-
61  //
-
62  // Primary key: filename + desttype
-
63  //
-
64  { "filename", "TEXT NOT NULL" },
-
65  { "desttype", "CHAR ( 10 ) NOT NULL" },
-
66  //
-
67  // Encoding parameters
-
68  //
-
69  { "enable_ismv", "BOOLEAN NOT NULL" },
-
70  { "audiobitrate", "UNSIGNED INT NOT NULL" },
-
71  { "audiosamplerate", "UNSIGNED INT NOT NULL" },
-
72  { "videobitrate", "UNSIGNED INT NOT NULL" },
-
73  { "videowidth", "UNSIGNED INT NOT NULL" },
-
74  { "videoheight", "UNSIGNED INT NOT NULL" },
-
75  { "deinterlace", "BOOLEAN NOT NULL" },
-
76  //
-
77  // Encoding results
-
78  //
-
79  { "duration", "UNSIGNED BIG INT NOT NULL" },
-
80  { "predicted_filesize", "UNSIGNED BIG INT NOT NULL" },
-
81  { "encoded_filesize", "UNSIGNED BIG INT NOT NULL" },
-
82  { "video_frame_count", "UNSIGNED BIG INT NOT NULL" },
-
83  { "segment_count", "UNSIGNED BIG INT NOT NULL" },
-
84  { "finished", "INT NOT NULL" },
-
85  { "error", "BOOLEAN NOT NULL" },
-
86  { "errno", "INT NOT NULL" },
-
87  { "averror", "INT NOT NULL" },
-
88  { "creation_time", "DATETIME NOT NULL" },
-
89  { "access_time", "DATETIME NOT NULL" },
-
90  { "file_time", "DATETIME NOT NULL" },
-
91  { "file_size", "UNSIGNED BIG INT NOT NULL" }
-
92 };
-
93 
- -
95 {
-
96  //
-
97  // Table name
-
98  //
-
99  "version",
-
100  //
-
101  nullptr
-
102 };
-
103 
- -
105 {
-
106  { "db_version_major", "INTEGER NOT NULL" },
-
107  { "db_version_minor", "INTEGER NOT NULL" }
-
108 };
-
109 
- -
111  : m_cacheidx_db(nullptr)
-
112  , m_cacheidx_select_stmt(nullptr)
-
113  , m_cacheidx_insert_stmt(nullptr)
-
114  , m_cacheidx_delete_stmt(nullptr)
-
115 {
-
116 }
-
117 
- -
119 {
-
120  // Clean up memory
-
121  for (auto& [key, value] : m_cache)
-
122  {
-
123  value->destroy();
-
124  }
-
125 
-
126  m_cache.clear();
-
127 
-
128  close_index();
-
129 }
-
130 
- -
132 {
-
133  int ret;
-
134  const char * sql;
-
135 
-
136  sql = "INSERT OR REPLACE INTO cache_entry\n"
-
137  "(filename, desttype, enable_ismv, audiobitrate, audiosamplerate, videobitrate, videowidth, videoheight, deinterlace, duration, predicted_filesize, encoded_filesize, video_frame_count, segment_count, finished, error, errno, averror, creation_time, access_time, file_time, file_size) VALUES\n"
-
138  "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?);\n";
-
139 
-
140  if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql, -1, &m_cacheidx_insert_stmt, nullptr)))
-
141  {
-
142  Logging::error(m_cacheidx_file, "Failed to prepare insert: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql);
-
143  return false;
-
144  }
-
145 
-
146  sql = "SELECT desttype, enable_ismv, audiobitrate, audiosamplerate, videobitrate, videowidth, videoheight, deinterlace, duration, predicted_filesize, encoded_filesize, video_frame_count, segment_count, finished, error, errno, averror, strftime('%s', creation_time), strftime('%s', access_time), strftime('%s', file_time), file_size FROM cache_entry WHERE filename = ? AND desttype = ?;\n";
-
147 
-
148  if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql, -1, &m_cacheidx_select_stmt, nullptr)))
-
149  {
-
150  Logging::error(m_cacheidx_file, "Failed to prepare select: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql);
-
151  return false;
-
152  }
-
153 
-
154  sql = "DELETE FROM cache_entry WHERE filename = ? AND desttype = ?;\n";
-
155 
-
156  if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql, -1, &m_cacheidx_delete_stmt, nullptr)))
-
157  {
-
158  Logging::error(m_cacheidx_file, "Failed to prepare delete: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql);
-
159  return false;
-
160  }
-
161 
-
162  return true;
-
163 }
-
164 
-
165 bool Cache::table_exists(const char *table)
-
166 {
-
167  std::string sql;
-
168  sqlite3_stmt * stmt = nullptr;
-
169  int results = 0;
-
170  int ret;
-
171 
-
172  sql = "SELECT Count(*) FROM sqlite_master WHERE type='table' AND name='";
-
173  sql += table;
-
174  sql += "'";
-
175 
-
176  if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql.c_str(), -1, &stmt, nullptr)))
-
177  {
-
178  Logging::error(m_cacheidx_file, "Failed to prepare statement for table_exists: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql.c_str());
-
179  return false;
-
180  }
-
181 
-
182  ret = sqlite3_step(stmt);
-
183 
-
184  if (ret == SQLITE_ROW)
-
185  {
-
186  results = sqlite3_column_int(stmt, 0);
-
187  }
-
188 
-
189  sqlite3_finalize(stmt);
-
190 
-
191  return (results == 1);
-
192 }
-
193 
-
194 bool Cache::column_exists(const char *table, const char *column)
-
195 {
-
196  std::string sql;
-
197  sqlite3_stmt * stmt = nullptr;
-
198  int results = 0;
-
199  int ret;
-
200 
-
201  sql = "SELECT COUNT(*) AS CNTREC FROM pragma_table_info('";
-
202  sql += table;
-
203  sql += "') WHERE name='";
-
204  sql += column;
-
205  sql += "';";
-
206 
-
207  if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql.c_str(), -1, &stmt, nullptr)))
-
208  {
-
209  Logging::error(m_cacheidx_file, "Failed to prepare statement for table_exists: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql.c_str());
-
210  return false;
-
211  }
-
212 
-
213  ret = sqlite3_step(stmt);
-
214 
-
215  if (ret == SQLITE_ROW)
-
216  {
-
217  results = sqlite3_column_int(stmt, 0);
-
218  }
-
219 
-
220  sqlite3_finalize(stmt);
-
221 
-
222  return (results == 1);
-
223 }
-
224 
-
225 bool Cache::check_min_version(int *db_version_major, int *db_version_minor)
-
226 {
-
227  std::string sql;
-
228  sqlite3_stmt * stmt = nullptr;
-
229  int ret;
-
230 
-
231  sql = "SELECT db_version_major, db_version_minor FROM version;";
-
232 
-
233  if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql.c_str(), -1, &stmt, nullptr)))
-
234  {
-
235  Logging::error(m_cacheidx_file, "Failed to prepare statement for check_min_version: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql.c_str());
-
236  return false;
-
237  }
-
238 
-
239  ret = sqlite3_step(stmt);
-
240 
-
241  if (ret == SQLITE_ROW)
-
242  {
-
243  *db_version_major = sqlite3_column_int(stmt, 0);
-
244  *db_version_minor = sqlite3_column_int(stmt, 1);
-
245  }
-
246 
-
247  sqlite3_finalize(stmt);
-
248 
-
249  return (cmp_version(*db_version_major, *db_version_minor, DB_MIN_VERSION_MAJOR, DB_MIN_VERSION_MINOR) >= 0);
-
250 }
-
251 
-
252 int Cache::cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r)
-
253 {
-
254  if (version_major_l > version_major_r || (version_major_l == version_major_r && version_minor_l > version_minor_r))
-
255  {
-
256  return 1;
-
257  }
-
258 
-
259  if (version_major_l < version_major_r || (version_major_l == version_major_r && version_minor_l < version_minor_r))
-
260  {
-
261  return -1;
-
262  }
-
263  return 0;
-
264 }
-
265 
- -
267 {
-
268  char *errmsg = nullptr;
-
269  const char * sql;
-
270  int ret;
-
271 
-
272  sql = "BEGIN TRANSACTION;";
-
273  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
-
274  {
-
275  Logging::error(m_cacheidx_file, "SQLite3 begin transaction failed: (%1) %2\n%3", ret, errmsg, sql);
-
276  sqlite3_free(errmsg);
-
277  return false;
-
278  }
-
279  return true;
-
280 }
-
281 
- -
283 {
-
284  char *errmsg = nullptr;
-
285  const char * sql;
-
286  int ret;
-
287 
-
288  sql = "END TRANSACTION;";
-
289  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
-
290  {
-
291  Logging::error(m_cacheidx_file, "SQLite3 end transaction failed: (%1) %2\n%3", ret, errmsg, sql);
-
292  sqlite3_free(errmsg);
-
293  return false;
-
294  }
-
295  return true;
-
296 }
-
297 
- -
299 {
-
300  char *errmsg = nullptr;
-
301  const char * sql;
-
302  int ret;
-
303 
-
304  sql = "ROLLBACK;";
-
305  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
-
306  {
-
307  Logging::error(m_cacheidx_file, "SQLite3 rollback transaction failed: (%1) %2\n%3", ret, errmsg, sql);
-
308  sqlite3_free(errmsg);
-
309  return false;
-
310  }
-
311  return true;
-
312 }
-
313 
- -
315 {
-
316  char *errmsg = nullptr;
-
317  std::string sql;
-
318  int ret;
-
319 
-
320  sql = "CREATE TABLE `";
-
321  sql += table->name;
-
322  sql += "` (\n";
-
323 
-
324  int i = 0;
-
325  for (const TABLE_COLUMNS & col : columns)
-
326  {
-
327  if (i++)
-
328  {
-
329  sql += ",\n";
-
330  }
-
331  sql += "`";
-
332  sql += col.name;
-
333  sql += "` ";
-
334  sql += col.type;
-
335  }
-
336 
-
337  if (table->primary_key != nullptr)
-
338  {
-
339  sql += ",\n";
-
340  sql += table->primary_key;
-
341  }
-
342  sql += "\n";
-
343  sql += ");\n";
-
344 
-
345  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
346  {
-
347  Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
348  sqlite3_free(errmsg);
-
349  return false;
-
350  }
-
351  return true;
-
352 }
-
353 
-
354 bool Cache::upgrade_db(int *db_version_major, int *db_version_minor)
-
355 {
-
356  if (!column_exists("cache_entry", "video_frame_count"))
-
357  {
-
358  // If video_frame_count is missing, this db is definetly old
-
359 
-
360  {
-
361  char *errmsg = nullptr;
-
362  std::string sql;
-
363  int ret;
-
364 
-
365  Logging::debug(m_cacheidx_file, "Adding `video_frame_count` column.");
-
366 
-
367  // Add `video_frame_count` UNSIGNED BIG INT NOT NULL DEFAULT 0
-
368  sql = "ALTER TABLE `";
-
369  sql += m_table_cache_entry.name;
-
370  sql += "` ADD COLUMN `video_frame_count` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
-
371  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
372  {
-
373  Logging::error(m_cacheidx_file, "SQLite3 exec error adding column `video_frame_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
374  sqlite3_free(errmsg);
-
375  return false;
-
376  }
-
377 
-
378  Logging::debug(m_cacheidx_file, "Altering `finished` from BOOLEAN to INT.");
-
379  }
-
380 
-
381  {
-
382  char *errmsg = nullptr;
-
383  std::string sql;
-
384  int ret;
-
385 
-
386  //ALTER `finished` from BOOLEAN to INT NOT NULL
-
387  // sqlite can't do that for us, we must...
-
388  //
-
389  // 1. Rename `cache_entry` to `cache_entry_old`
-
390  // 2. Create new table `cache_entry` with new structure
-
391  // 3. Copy all data from `cache_entry_old` to `cache_entry`, converting old to new column
-
392  // 4. Delete `cache_entry_old`
-
393 
-
394  sql = "PRAGMA foreign_keys=off;\n";
-
395  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
396  {
-
397  Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
398  sqlite3_free(errmsg);
-
399  return false;
-
400  }
-
401  }
-
402 
-
403  // Step 1
-
404  {
-
405  char *errmsg = nullptr;
-
406  std::string sql;
-
407  int ret;
-
408 
-
409  sql = "ALTER TABLE `";
-
410  sql += m_table_cache_entry.name;
-
411  sql += "` RENAME TO `";
-
412  sql += m_table_cache_entry.name;
-
413  sql += "_old`;\n";
-
414  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
415  {
-
416  Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
417  sqlite3_free(errmsg);
-
418  return false;
-
419  }
-
420  }
-
421 
-
422  // Step 2
- -
424  {
-
425  Logging::error(m_cacheidx_file, "SQLite3 exec error creating 'cache_entry' table.");
-
426  return false;
-
427  }
-
428 
-
429  // Step 3
-
430  {
-
431  char *errmsg = nullptr;
-
432  std::string sql;
-
433  std::string columns;
-
434  int ret;
-
435 
-
436  for (const TABLE_COLUMNS & col : m_columns_cache_entry)
-
437  {
-
438  if (!columns.empty())
-
439  {
-
440  columns += ",";
-
441  }
-
442  columns += "`";
-
443  columns += col.name;
-
444  columns += "`";
-
445  }
-
446 
-
447  sql = "INSERT INTO `";
-
448  sql += m_table_cache_entry.name;
-
449  sql += "` (";
-
450  sql += columns;
-
451  sql += ")\nSELECT ";
-
452  sql += columns;
-
453  sql += " FROM `";
-
454  sql += m_table_cache_entry.name;
-
455  sql += "_old`;";
-
456 
-
457  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
458  {
-
459  Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
460  sqlite3_free(errmsg);
-
461  return false;
-
462  }
-
463  }
-
464 
-
465  {
-
466  char *errmsg = nullptr;
-
467  std::string sql;
-
468  int ret;
-
469 
-
470  // Old 0 is RESULTCODE_NONE (0)
-
471  // Old 1 is RESULTCODE_FINISHED (2)
-
472  sql = "UPDATE `";
-
473  sql += m_table_cache_entry.name;
-
474  sql += "`\n";
-
475  sql += "SET `finished` = 3\n";
-
476  sql += "WHERE `finished` = 1\n";
-
477  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
478  {
-
479  Logging::error(m_cacheidx_file, "SQLite3 exec error updating column `finished`: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
480  sqlite3_free(errmsg);
-
481  return false;
-
482  }
-
483  }
-
484 
-
485  // Step 4
-
486  {
-
487  char *errmsg = nullptr;
-
488  std::string sql;
-
489  int ret;
-
490 
-
491  sql = "DROP TABLE `cache_entry_old`";
-
492  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
493  {
-
494  Logging::error(m_cacheidx_file, "SQLite3 exec error adding column `video_frame_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
495  sqlite3_free(errmsg);
-
496  return false;
-
497  }
-
498 
-
499  sql = "PRAGMA foreign_keys=on;\n";
-
500  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
501  {
-
502  Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
503  sqlite3_free(errmsg);
-
504  return false;
-
505  }
-
506  }
-
507  }
-
508 
-
509  if (!column_exists("cache_entry", "duration"))
-
510  {
-
511  char *errmsg = nullptr;
-
512  std::string sql;
-
513  int ret;
-
514 
-
515  Logging::debug(m_cacheidx_file, "Adding `duration` column.");
-
516 
-
517  // Add `duration` UNSIGNED BIG INT NOT NULL DEFAULT 0
-
518  sql = "ALTER TABLE `";
-
519  sql += m_table_cache_entry.name;
-
520  sql += "` ADD COLUMN `duration` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
-
521  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
522  {
-
523  Logging::error(m_cacheidx_file, "SQLite3 exec error adding column `duration`: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
524  sqlite3_free(errmsg);
-
525  return false;
-
526  }
-
527  }
-
528 
-
529  if (!column_exists("cache_entry", "segment_count"))
-
530  {
-
531  char *errmsg = nullptr;
-
532  std::string sql;
-
533  int ret;
-
534 
-
535  Logging::debug(m_cacheidx_file, "Adding `segment_count` column.");
-
536 
-
537  // Add `segment_count` UNSIGNED BIG INT NOT NULL DEFAULT 0
-
538  sql = "ALTER TABLE `";
-
539  sql += m_table_cache_entry.name;
-
540  sql += "` ADD COLUMN `segment_count` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
-
541  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
-
542  {
-
543  Logging::error(m_cacheidx_file, "SQLite3 exec error adding column `segment_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
-
544  sqlite3_free(errmsg);
-
545  return false;
-
546  }
-
547  }
-
548 
-
549  // Update DB version
-
550  Logging::debug(m_cacheidx_file, "Updating version table to V%1.%2.", DB_VERSION_MAJOR, DB_VERSION_MINOR);
-
551 
-
552  {
-
553  char *errmsg = nullptr;
-
554  const char * sql;
-
555  int ret;
-
556 
-
557  sql = "UPDATE `version` SET db_version_major = " TOSTRING(DB_VERSION_MAJOR) ", db_version_minor = " TOSTRING(DB_VERSION_MINOR) ";\n";
-
558  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
-
559  {
-
560  Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql);
-
561  sqlite3_free(errmsg);
-
562  return false;
-
563  }
-
564 
-
565  *db_version_major = DB_VERSION_MAJOR;
-
566  *db_version_minor = DB_VERSION_MINOR;
-
567  }
-
568 
-
569  Logging::info(m_cacheidx_file, "Database successfully upgraded to V%1.%2.", *db_version_major, *db_version_minor);
-
570 
-
571  return true;
-
572 }
-
573 
- -
575 {
-
576  bool success = true;
-
577 
-
578  try
-
579  {
-
580  char *errmsg = nullptr;
-
581  int ret;
-
582  bool new_database = false;
-
583  bool need_upate = false;
-
584 
- -
586 
-
587  if (mktree(m_cacheidx_file, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) && errno != EEXIST)
-
588  {
-
589  Logging::error(m_cacheidx_file, "Error creating cache directory: (%1) %2\n%3", errno, strerror(errno), m_cacheidx_file.c_str());
-
590  throw false;
-
591  }
-
592 
-
593  append_filename(&m_cacheidx_file, "cacheidx.sqlite");
-
594 
-
595  // initialise engine
-
596  if (SQLITE_OK != (ret = sqlite3_initialize()))
-
597  {
-
598  Logging::error(m_cacheidx_file, "Failed to initialise SQLite3 library: (%1) %2", ret, sqlite3_errstr(ret));
-
599  throw false;
-
600  }
-
601 
-
602  // open connection to a DB
-
603  if (SQLITE_OK != (ret = sqlite3_open_v2(m_cacheidx_file.c_str(), &m_cacheidx_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_SHAREDCACHE, nullptr)))
-
604  {
-
605  Logging::error(m_cacheidx_file, "Failed to initialise SQLite3 connection: (%1) %2", ret, sqlite3_errmsg(m_cacheidx_db));
-
606  throw false;
-
607  }
-
608 
-
609  if (SQLITE_OK != (ret = sqlite3_busy_timeout(m_cacheidx_db, 1000)))
-
610  {
-
611  Logging::error(m_cacheidx_file, "Failed to set SQLite3 busy timeout: (%1) %2", ret, sqlite3_errmsg(m_cacheidx_db));
-
612  throw false;
-
613  }
-
614 
-
615  // Beginning with version 3.7.0 (2010-07-21), a new "Write-Ahead Log" option
-
616  // We support Sqlite from 3.7.13 anyway
-
617  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, "pragma journal_mode = WAL", nullptr, nullptr, nullptr)))
-
618  {
-
619  Logging::error(m_cacheidx_file, "Failed to set SQLite3 WAL mode: (%1) %2", ret, sqlite3_errmsg(m_cacheidx_db));
-
620  throw false;
-
621  }
-
622 
-
623  // Very strange: Compare operations with =, > etc. are case sensitive, while LIKE by default ignores upper/lowercase.
-
624  // Produces strange results when reading from a Samba drive and different cases are used...
-
625  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, "PRAGMA case_sensitive_like = 1;", nullptr, nullptr, nullptr)))
-
626  {
-
627  Logging::error(m_cacheidx_file, "Failed to set SQLite3 case_sensitive_like = 1: (%1) %2", ret, sqlite3_errmsg(m_cacheidx_db));
-
628  throw false;
-
629  }
-
630 
-
631  // Make sure the next changes are either all successfull or rolled back
-
632  if (!begin_transaction())
-
633  {
-
634  throw false;
-
635  }
-
636 
-
637  // Check if we got a new, empty database and create necessary tables
-
638 
-
639  // Create cache_entry table if not already existing
-
640  if (!table_exists("cache_entry"))
-
641  {
-
642  Logging::debug(m_cacheidx_file, "Creating 'cache_entry' table in database.");
-
643 
- -
645  {
-
646  Logging::error(m_cacheidx_file, "SQLite3 exec error creating 'cache_entry' table: (%1) %2", ret, errmsg);
-
647  throw false;
-
648  }
-
649 
-
650  new_database = true; // Created a new database
-
651  }
-
652 
-
653  // If version table does not exist add it
-
654  if (!table_exists("version"))
-
655  {
-
656  const char * sql;
-
657 
-
658  Logging::debug(m_cacheidx_file, "Creating 'version' table in database.");
-
659 
- -
661  {
-
662  Logging::error(m_cacheidx_file, "SQLite3 exec error creating 'cache_entry' table: (%1) %2", ret, errmsg);
-
663  throw false;
-
664  }
-
665 
-
666  sql = "INSERT INTO `version` (db_version_major, db_version_minor) VALUES (" TOSTRING(DB_VERSION_MAJOR) ", " TOSTRING(DB_VERSION_MINOR) ");\n";
-
667  if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
-
668  {
-
669  Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql);
-
670  sqlite3_free(errmsg);
-
671  throw false;
-
672  }
-
673 
-
674  if (!new_database)
-
675  {
-
676  // Added version only, old database, need upgrade
-
677  need_upate = true;
-
678  }
-
679  }
-
680 
-
681  // Check if database needs a structure upgrade
-
682  int db_version_major = DB_BASE_VERSION_MAJOR; // Old database contains no version table. This is the version of this database.
-
683  int db_version_minor = DB_BASE_VERSION_MINOR;
-
684  if (need_upate || !check_min_version(&db_version_major, &db_version_minor))
-
685  {
-
686  // No version table found, or minimum version too low, do an upgrade.
-
687  Logging::warning(m_cacheidx_file, "Database version is %1.%2, but a least %3.%4 required. Upgrading database now.", db_version_major, db_version_minor, DB_MIN_VERSION_MAJOR, DB_MIN_VERSION_MINOR);
-
688 
-
689  if (!upgrade_db(&db_version_major, &db_version_minor))
-
690  {
-
691  throw false;
-
692  }
-
693  }
-
694 
-
695  if (!end_transaction())
-
696  {
-
697  throw false;
-
698  }
-
699 
-
700 #ifdef HAVE_SQLITE_CACHEFLUSH
-
701  if (!flush_index())
-
702  {
-
703  throw false;
-
704  }
-
705 #endif // HAVE_SQLITE_CACHEFLUSH
-
706 
-
707  // prepare the statements
-
708  if (!prepare_stmts())
-
709  {
-
710  throw false;
-
711  }
-
712  }
-
713  catch (bool _success)
-
714  {
-
715  success = _success;
-
716  }
-
717 
-
718  return success;
-
719 }
-
720 
-
721 #ifdef HAVE_SQLITE_CACHEFLUSH
-
722 bool Cache::flush_index()
-
723 {
-
724  if (m_cacheidx_db != nullptr)
-
725  {
-
726  int ret;
-
727 
-
728  // Flush cache to disk
-
729  if (SQLITE_OK != (ret = sqlite3_db_cacheflush(m_cacheidx_db)))
-
730  {
-
731  Logging::error(m_cacheidx_file, "SQLite3 cache flush error: (%1) %2", ret, sqlite3_errstr(ret));
-
732  return false;
-
733  }
-
734  }
-
735  return true;
-
736 }
-
737 #endif // HAVE_SQLITE_CACHEFLUSH
-
738 
- -
740 {
-
741  bool success = true;
-
742 
-
743  //cache_info->m_enable_ismv = 0;
-
744  cache_info->m_audiobitrate = 0;
-
745  cache_info->m_audiosamplerate = 0;
-
746  cache_info->m_videobitrate = 0;
-
747  cache_info->m_videowidth = 0;
-
748  cache_info->m_videoheight = 0;
-
749  cache_info->m_deinterlace = false;
-
750  cache_info->m_duration = 0;
-
751  cache_info->m_predicted_filesize = 0;
-
752  cache_info->m_encoded_filesize = 0;
-
753  cache_info->m_video_frame_count = 0;
-
754  cache_info->m_segment_count = 0;
-
755  cache_info->m_result = RESULTCODE_NONE;
-
756  cache_info->m_error = false;
-
757  cache_info->m_errno = 0;
-
758  cache_info->m_averror = 0;
-
759  cache_info->m_creation_time = 0;
-
760  cache_info->m_access_time = 0;
-
761  cache_info->m_file_time = 0;
-
762  cache_info->m_file_size = 0;
-
763 
-
764  if (m_cacheidx_select_stmt == nullptr)
-
765  {
-
766  Logging::error(m_cacheidx_file, "SQLite3 select statement not open.");
-
767  return false;
-
768  }
-
769 
-
770  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
771 
-
772  try
-
773  {
-
774  int ret;
-
775 
-
776  assert(sqlite3_bind_parameter_count(m_cacheidx_select_stmt) == 2);
-
777 
-
778  if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_select_stmt, 1, cache_info->m_destfile.c_str(), -1, nullptr)))
-
779  {
-
780  Logging::error(m_cacheidx_file, "SQLite3 select error binding 'filename': (%1) %2", ret, sqlite3_errstr(ret));
-
781  throw false;
-
782  }
-
783 
-
784  if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_select_stmt, 2, cache_info->m_desttype, -1, nullptr)))
-
785  {
-
786  Logging::error(m_cacheidx_file, "SQLite3 select error binding 'desttype': (%1) %2", ret, sqlite3_errstr(ret));
-
787  throw false;
-
788  }
-
789 
-
790  ret = sqlite3_step(m_cacheidx_select_stmt);
-
791 
-
792  if (ret == SQLITE_ROW)
-
793  {
-
794  const char *text = reinterpret_cast<const char *>(sqlite3_column_text(m_cacheidx_select_stmt, 0));
-
795  if (text != nullptr)
-
796  {
-
797  cache_info->m_desttype[0] = '\0';
-
798  strncat(cache_info->m_desttype, text, sizeof(cache_info->m_desttype) - 1);
-
799  }
-
800  //cache_info->m_enable_ismv = sqlite3_column_int(m_cacheidx_select_stmt, 1);
-
801  cache_info->m_audiobitrate = sqlite3_column_int(m_cacheidx_select_stmt, 2);
-
802  cache_info->m_audiosamplerate = sqlite3_column_int(m_cacheidx_select_stmt, 3);
-
803  cache_info->m_videobitrate = sqlite3_column_int(m_cacheidx_select_stmt, 4);
-
804  cache_info->m_videowidth = sqlite3_column_int(m_cacheidx_select_stmt, 5);
-
805  cache_info->m_videoheight = sqlite3_column_int(m_cacheidx_select_stmt, 6);
-
806  cache_info->m_deinterlace = sqlite3_column_int(m_cacheidx_select_stmt, 7);
-
807  cache_info->m_duration = sqlite3_column_int64(m_cacheidx_select_stmt, 8);
-
808  cache_info->m_predicted_filesize = static_cast<size_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 9));
-
809  cache_info->m_encoded_filesize = static_cast<size_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 10));
-
810  cache_info->m_video_frame_count = static_cast<uint32_t>(sqlite3_column_int(m_cacheidx_select_stmt, 11));
-
811  cache_info->m_segment_count = static_cast<uint32_t>(sqlite3_column_int(m_cacheidx_select_stmt, 12));
-
812  cache_info->m_result = static_cast<RESULTCODE>(sqlite3_column_int(m_cacheidx_select_stmt, 13));
-
813  cache_info->m_error = sqlite3_column_int(m_cacheidx_select_stmt, 14);
-
814  cache_info->m_errno = sqlite3_column_int(m_cacheidx_select_stmt, 15);
-
815  cache_info->m_averror = sqlite3_column_int(m_cacheidx_select_stmt, 16);
-
816  cache_info->m_creation_time = static_cast<time_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 17));
-
817  cache_info->m_access_time = static_cast<time_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 18));
-
818  cache_info->m_file_time = static_cast<time_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 19));
-
819  cache_info->m_file_size = static_cast<size_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 20));
-
820  }
-
821  else if (ret != SQLITE_DONE)
-
822  {
-
823  Logging::error(m_cacheidx_file, "Sqlite 3 could not step (execute) select statement: (%1) %2", ret, sqlite3_errstr(ret));
-
824  throw false;
-
825  }
-
826  }
-
827  catch (bool _success)
-
828  {
-
829  success = _success;
-
830  }
-
831 
-
832  sqlite3_reset(m_cacheidx_select_stmt);
-
833 
-
834  if (success)
-
835  {
-
836  errno = 0; // sqlite3 sometimes sets errno without any reason, better reset any error
-
837  }
-
838 
-
839  return success;
-
840 }
-
841 
-
842 #define SQLBINDTXT(idx, var) \
-
843  if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_insert_stmt, idx, var, -1, nullptr))) \
-
844 { \
-
845  Logging::error(m_cacheidx_file, "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
-
846  throw false; \
-
847  }
-
849 #define SQLBINDNUM(func, idx, var) \
-
850  if (SQLITE_OK != (ret = func(m_cacheidx_insert_stmt, idx, var))) \
-
851 { \
-
852  Logging::error(m_cacheidx_file, "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
-
853  throw false; \
-
854  }
-
856 bool Cache::write_info(LPCCACHE_INFO cache_info)
-
857 {
-
858  bool success = true;
-
859 
-
860  if (m_cacheidx_insert_stmt == nullptr)
-
861  {
-
862  Logging::error(m_cacheidx_file, "SQLite3 select statement not open.");
-
863  return false;
-
864  }
-
865 
-
866  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
867 
-
868  try
-
869  {
-
870  int ret;
-
871  bool enable_ismv_dummy = false;
-
872 
-
873  assert(sqlite3_bind_parameter_count(m_cacheidx_insert_stmt) == 22);
-
874 
-
875  SQLBINDTXT(1, cache_info->m_destfile.c_str());
-
876  SQLBINDTXT(2, cache_info->m_desttype);
-
877  //SQLBINDNUM(sqlite3_bind_int, 3, cache_info->m_enable_ismv);
-
878  SQLBINDNUM(sqlite3_bind_int, 3, enable_ismv_dummy);
-
879  SQLBINDNUM(sqlite3_bind_int64, 4, cache_info->m_audiobitrate);
-
880  SQLBINDNUM(sqlite3_bind_int, 5, cache_info->m_audiosamplerate);
-
881  SQLBINDNUM(sqlite3_bind_int64, 6, cache_info->m_videobitrate);
-
882  SQLBINDNUM(sqlite3_bind_int, 7, static_cast<int>(cache_info->m_videowidth));
-
883  SQLBINDNUM(sqlite3_bind_int, 8, static_cast<int>(cache_info->m_videoheight));
-
884  SQLBINDNUM(sqlite3_bind_int, 9, cache_info->m_deinterlace);
-
885  SQLBINDNUM(sqlite3_bind_int64, 10, static_cast<sqlite3_int64>(cache_info->m_duration));
-
886  SQLBINDNUM(sqlite3_bind_int64, 11, static_cast<sqlite3_int64>(cache_info->m_predicted_filesize));
-
887  SQLBINDNUM(sqlite3_bind_int64, 12, static_cast<sqlite3_int64>(cache_info->m_encoded_filesize));
-
888  SQLBINDNUM(sqlite3_bind_int, 13, static_cast<int32_t>(cache_info->m_video_frame_count));
-
889  SQLBINDNUM(sqlite3_bind_int, 14, static_cast<int32_t>(cache_info->m_segment_count));
-
890  SQLBINDNUM(sqlite3_bind_int, 15, cache_info->m_result);
-
891  SQLBINDNUM(sqlite3_bind_int, 16, cache_info->m_error);
-
892  SQLBINDNUM(sqlite3_bind_int, 17, cache_info->m_errno);
-
893  SQLBINDNUM(sqlite3_bind_int, 18, cache_info->m_averror);
-
894  SQLBINDNUM(sqlite3_bind_int64, 19, cache_info->m_creation_time);
-
895  SQLBINDNUM(sqlite3_bind_int64, 20, cache_info->m_access_time);
-
896  SQLBINDNUM(sqlite3_bind_int64, 21, cache_info->m_file_time);
-
897  SQLBINDNUM(sqlite3_bind_int64, 22, static_cast<sqlite3_int64>(cache_info->m_file_size));
-
898 
-
899  ret = sqlite3_step(m_cacheidx_insert_stmt);
-
900 
-
901  if (ret != SQLITE_DONE)
-
902  {
-
903  Logging::error(m_cacheidx_file, "Sqlite 3 could not step (execute) insert statement: (%1) %2", ret, sqlite3_errstr(ret));
-
904  throw false;
-
905  }
-
906  }
-
907  catch (bool _success)
-
908  {
-
909  success = _success;
-
910  }
-
911 
-
912  sqlite3_reset(m_cacheidx_insert_stmt);
-
913 
-
914  if (success)
-
915  {
-
916  errno = 0; // sqlite3 sometimes sets errno without any reason, better reset any error
-
917  }
-
918 
-
919  return success;
-
920 }
-
921 
-
922 bool Cache::delete_info(const std::string & filename, const std::string & desttype)
-
923 {
-
924  bool success = true;
-
925 
-
926  if (m_cacheidx_delete_stmt == nullptr)
-
927  {
-
928  Logging::error(m_cacheidx_file, "SQLite3 delete statement not open.");
-
929  return false;
-
930  }
-
931 
-
932  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
933 
-
934  try
-
935  {
-
936  int ret;
-
937 
-
938  assert(sqlite3_bind_parameter_count(m_cacheidx_delete_stmt) == 2);
-
939 
-
940  if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_delete_stmt, 1, filename.c_str(), -1, nullptr)))
-
941  {
-
942  Logging::error(m_cacheidx_file, "SQLite3 select error binding 'filename': (%1) %2", ret, sqlite3_errstr(ret));
-
943  throw false;
-
944  }
-
945 
-
946  if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_delete_stmt, 2, desttype.c_str(), -1, nullptr)))
-
947  {
-
948  Logging::error(m_cacheidx_file, "SQLite3 select error binding 'desttype': (%1) %2", ret, sqlite3_errstr(ret));
-
949  throw false;
-
950  }
-
951 
-
952  ret = sqlite3_step(m_cacheidx_delete_stmt);
-
953 
-
954  if (ret != SQLITE_DONE)
-
955  {
-
956  Logging::error(m_cacheidx_file, "Sqlite 3 could not step (execute) delete statement: (%1) %2", ret, sqlite3_errstr(ret));
-
957  throw false;
-
958  }
-
959  }
-
960  catch (bool _success)
-
961  {
-
962  success = _success;
-
963  }
-
964 
-
965  sqlite3_reset(m_cacheidx_delete_stmt);
-
966 
-
967  if (success)
-
968  {
-
969  errno = 0; // sqlite3 sometimes sets errno without any reason, better reset any error
-
970  }
-
971 
-
972  return success;
-
973 }
-
974 
-
975 void Cache::close_index()
-
976 {
-
977  if (m_cacheidx_db != nullptr)
-
978  {
-
979 #ifdef HAVE_SQLITE_CACHEFLUSH
-
980  flush_index();
-
981 #endif // HAVE_SQLITE_CACHEFLUSH
-
982 
-
983  sqlite3_finalize(m_cacheidx_select_stmt);
-
984  sqlite3_finalize(m_cacheidx_insert_stmt);
-
985  sqlite3_finalize(m_cacheidx_delete_stmt);
-
986 
-
987  sqlite3_close(m_cacheidx_db);
-
988  }
-
989  sqlite3_shutdown();
-
990 }
-
991 
-
992 Cache_Entry* Cache::create_entry(LPVIRTUALFILE virtualfile, const std::string & desttype)
-
993 {
-
994  //Cache_Entry* cache_entry = new(std::nothrow) Cache_Entry(this, filename);
-
995  Cache_Entry* cache_entry = Cache_Entry::create(this, virtualfile);
-
996  if (cache_entry == nullptr)
-
997  {
-
998  Logging::error(m_cacheidx_file, "Out of memory creating cache entry.");
-
999  return nullptr;
-
1000  }
-
1001 
-
1002  m_cache.insert(make_pair(make_pair(virtualfile->m_destfile, desttype), cache_entry));
-
1003 
-
1004  return cache_entry;
-
1005 }
-
1006 
-
1007 bool Cache::delete_entry(Cache_Entry ** cache_entry, int flags)
-
1008 {
-
1009  if (*cache_entry == nullptr)
-
1010  {
-
1011  return true;
-
1012  }
-
1013 
-
1014  bool deleted = false;
-
1015 
-
1016  if ((*cache_entry)->closeio(flags))
-
1017  {
-
1018  // If CACHE_CLOSE_FREE is set, also free memory
-
1019  if (CACHE_CHECK_BIT(CACHE_CLOSE_FREE, flags))
-
1020  {
-
1021  m_cache.erase(make_pair((*cache_entry)->m_cache_info.m_destfile, (*cache_entry)->m_cache_info.m_desttype));
-
1022 
-
1023  deleted = (*cache_entry)->destroy();
-
1024  *cache_entry = nullptr;
-
1025  }
-
1026  }
-
1027 
-
1028  return deleted;
-
1029 }
-
1030 
- -
1032 {
-
1033  Cache_Entry* cache_entry = nullptr;
-
1034  cache_t::const_iterator p = m_cache.find(make_pair(virtualfile->m_destfile, params.current_format(virtualfile)->desttype()));
-
1035  if (p == m_cache.cend())
-
1036  {
-
1037  Logging::trace(virtualfile->m_destfile, "Created new transcoder.");
-
1038  cache_entry = create_entry(virtualfile, params.current_format(virtualfile)->desttype());
-
1039  }
-
1040  else
-
1041  {
-
1042  Logging::trace(virtualfile->m_destfile, "Reusing cached transcoder.");
-
1043  cache_entry = p->second;
-
1044  }
-
1045 
-
1046  return cache_entry;
-
1047 }
-
1048 
-
1049 bool Cache::closeio(Cache_Entry **cache_entry, int flags /*= CACHE_CLOSE_NOOPT*/)
-
1050 {
-
1051  if (*cache_entry == nullptr)
-
1052  {
-
1053  return true;
-
1054  }
-
1055 
-
1056  bool deleted;
-
1057 
-
1058  std::string filename((*cache_entry)->filename());
-
1059  if (delete_entry(cache_entry, flags))
-
1060  {
-
1061  Logging::trace(filename, "Freed cache entry.");
-
1062  deleted = true;
-
1063  }
-
1064  else
-
1065  {
-
1066  Logging::trace(filename, "Keeping cache entry.");
-
1067  deleted = false;
-
1068  }
-
1069 
-
1070  return deleted;
-
1071 }
-
1072 
-
1073 bool Cache::prune_expired()
-
1074 {
-
1075  if (params.m_expiry_time <= 0)
-
1076  {
-
1077  // There's no limit.
-
1078  return true;
-
1079  }
-
1080 
-
1081  std::vector<cache_key_t> keys;
-
1082  sqlite3_stmt * stmt;
-
1083  time_t now = time(nullptr);
-
1084  std::string sql;
-
1085 
-
1086  Logging::trace(m_cacheidx_file, "Pruning expired cache entries older than %1...", format_time(params.m_expiry_time).c_str());
-
1087 
-
1088  strsprintf(&sql, "SELECT filename, desttype, strftime('%%s', access_time) FROM cache_entry WHERE strftime('%%s', access_time) + %" FFMPEGFS_FORMAT_TIME_T " < %" FFMPEGFS_FORMAT_TIME_T ";\n", params.m_expiry_time, now);
-
1089 
-
1090  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
1091 
-
1092  sqlite3_prepare(m_cacheidx_db, sql.c_str(), -1, &stmt, nullptr);
-
1093 
-
1094  int ret = 0;
-
1095  while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
-
1096  {
-
1097  const char *filename = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
-
1098  const char *desttype = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
-
1099 
-
1100  keys.emplace_back(filename, desttype);
-
1101 
-
1102  Logging::trace(filename, "Found %1 old entries.", format_time(now - static_cast<time_t>(sqlite3_column_int64(stmt, 2))).c_str());
-
1103  }
-
1104 
-
1105  Logging::trace(m_cacheidx_file, "%1 expired cache entries found.", keys.size());
-
1106 
-
1107  if (ret == SQLITE_DONE)
-
1108  {
-
1109  for (const auto& [key, value] : keys)
-
1110  {
-
1111  Logging::trace(m_cacheidx_file, "Pruning '%1' - Type: %2", key.c_str(), value.c_str());
-
1112 
-
1113  cache_t::iterator p = m_cache.find(make_pair(key, value));
-
1114  if (p != m_cache.end())
-
1115  {
-
1116  delete_entry(&p->second, CACHE_CLOSE_DELETE);
-
1117  }
-
1118 
-
1119  if (delete_info(key, value))
-
1120  {
-
1121  remove_cachefile(key, value);
-
1122  }
-
1123  }
-
1124  }
-
1125  else
-
1126  {
-
1127  Logging::error(m_cacheidx_file, "Failed to execute select. Return code: %1 Error: %2 SQL: %3", ret, sqlite3_errmsg(m_cacheidx_db), expanded_sql(stmt).c_str());
-
1128  }
-
1129 
-
1130  sqlite3_finalize(stmt);
-
1131 
-
1132  return true;
-
1133 }
-
1134 
- -
1136 {
-
1137  if (!params.m_max_cache_size)
-
1138  {
-
1139  // There's no limit.
-
1140  return true;
-
1141  }
-
1142 
-
1143  std::vector<cache_key_t> keys;
-
1144  std::vector<size_t> filesizes;
-
1145  sqlite3_stmt * stmt;
-
1146  const char * sql;
-
1147 
-
1148  Logging::trace(m_cacheidx_file, "Pruning oldest cache entries exceeding %1 cache size...", format_size(params.m_max_cache_size).c_str());
-
1149 
-
1150  sql = "SELECT filename, desttype, encoded_filesize FROM cache_entry ORDER BY access_time ASC;\n";
-
1151 
-
1152  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
1153 
-
1154  sqlite3_prepare(m_cacheidx_db, sql, -1, &stmt, nullptr);
-
1155 
-
1156  int ret = 0;
-
1157  size_t total_size = 0;
-
1158  while((ret = sqlite3_step(stmt)) == SQLITE_ROW)
-
1159  {
-
1160  const char *filename = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
-
1161  const char *desttype = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
-
1162  size_t size = static_cast<size_t>(sqlite3_column_int64(stmt, 2));
-
1163 
-
1164  keys.emplace_back(filename, desttype);
-
1165  filesizes.push_back(size);
-
1166  total_size += size;
-
1167  }
-
1168 
-
1169  Logging::trace(m_cacheidx_file, "%1 in cache.", format_size(total_size).c_str());
-
1170 
-
1171  if (total_size > params.m_max_cache_size)
-
1172  {
-
1173  Logging::trace(m_cacheidx_file, "Pruning %1 of oldest cache entries to limit cache size.", format_size(total_size - params.m_max_cache_size).c_str());
-
1174  if (ret == SQLITE_DONE)
-
1175  {
-
1176  size_t n = 0;
-
1177  for (const auto& [key, value] : keys)
-
1178  {
-
1179  Logging::trace(m_cacheidx_file, "Pruning: %1 Type: %2", key.c_str(), value.c_str());
-
1180 
-
1181  cache_t::iterator p = m_cache.find(make_pair(key, value));
-
1182  if (p != m_cache.end())
-
1183  {
-
1184  delete_entry(&p->second, CACHE_CLOSE_DELETE);
-
1185  }
-
1186 
-
1187  if (delete_info(key, value))
-
1188  {
-
1189  remove_cachefile(key, value);
-
1190  }
-
1191 
-
1192  total_size -= filesizes[n++];
-
1193 
-
1194  if (total_size <= params.m_max_cache_size)
-
1195  {
-
1196  break;
-
1197  }
-
1198  }
-
1199 
-
1200  Logging::trace(m_cacheidx_file, "%1 left in cache.", format_size(total_size).c_str());
-
1201  }
-
1202  else
-
1203  {
-
1204  Logging::error(m_cacheidx_file, "Failed to execute select. Return code: %1 Error: %2 SQL: %3", ret, sqlite3_errmsg(m_cacheidx_db), expanded_sql(stmt).c_str());
-
1205  }
-
1206  }
-
1207 
-
1208  sqlite3_finalize(stmt);
-
1209 
-
1210  return true;
-
1211 }
-
1212 
-
1213 bool Cache::prune_disk_space(size_t predicted_filesize)
-
1214 {
-
1215  std::string cachepath;
-
1216 
-
1217  transcoder_cache_path(cachepath);
-
1218 
-
1219  size_t free_bytes = get_disk_free(cachepath);
-
1220 
-
1221  if (!free_bytes && errno)
-
1222  {
-
1223  if (errno == ENOENT)
-
1224  {
-
1225  // Cache path does not exist. Strange problem, but not error. Ignore silently.
-
1226  return true;
-
1227  }
-
1228 
-
1229  Logging::error(cachepath, "prune_disk_space() cannot determine free disk space: (%1) %2", errno, strerror(errno));
-
1230  return false;
-
1231  }
-
1232 
-
1233  if (free_bytes < predicted_filesize)
-
1234  {
-
1235  Logging::error(cachepath, "prune_disk_space() : Insufficient disk space %1 on cache drive, at least %2 required.", format_size(free_bytes).c_str(), format_size(predicted_filesize).c_str());
-
1236  errno = ENOSPC;
-
1237  return false;
-
1238  }
-
1239 
-
1240  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
1241 
-
1242  Logging::trace(cachepath, "%1 disk space before prune.", format_size(free_bytes).c_str());
-
1243  if (free_bytes < params.m_min_diskspace + predicted_filesize)
-
1244  {
-
1245  std::vector<cache_key_t> keys;
-
1246  std::vector<size_t> filesizes;
-
1247  sqlite3_stmt * stmt;
-
1248  const char * sql;
-
1249 
-
1250  sql = "SELECT filename, desttype, encoded_filesize FROM cache_entry ORDER BY access_time ASC;\n";
-
1251 
-
1252  sqlite3_prepare(m_cacheidx_db, sql, -1, &stmt, nullptr);
-
1253 
-
1254  int ret = 0;
-
1255  while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
-
1256  {
-
1257  const char *filename = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
-
1258  const char *desttype = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
-
1259  size_t size = static_cast<size_t>(sqlite3_column_int64(stmt, 2));
-
1260 
-
1261  keys.emplace_back(filename, desttype);
-
1262  filesizes.push_back(size);
-
1263  }
-
1264 
-
1265  Logging::trace(cachepath, "Pruning %1 of oldest cache entries to keep disk space above %2 limit...", format_size(params.m_min_diskspace + predicted_filesize - free_bytes).c_str(), format_size(params.m_min_diskspace).c_str());
-
1266 
-
1267  if (ret == SQLITE_DONE)
-
1268  {
-
1269  size_t n = 0;
-
1270  for (const auto& [key, value] : keys)
-
1271  {
-
1272  Logging::trace(cachepath, "Pruning: %1 Type: %2", key.c_str(), value.c_str());
-
1273 
-
1274  cache_t::iterator p = m_cache.find(make_pair(key, value));
-
1275  if (p != m_cache.end())
-
1276  {
-
1277  delete_entry(&p->second, CACHE_CLOSE_DELETE);
-
1278  }
-
1279 
-
1280  if (delete_info(key, value))
-
1281  {
-
1282  remove_cachefile(key, value);
-
1283  }
-
1284 
-
1285  free_bytes += filesizes[n++];
-
1286 
-
1287  if (free_bytes >= params.m_min_diskspace + predicted_filesize)
-
1288  {
-
1289  break;
-
1290  }
-
1291  }
-
1292  Logging::trace(cachepath, "Disk space after prune: %1", format_size(free_bytes).c_str());
-
1293  }
-
1294  else
-
1295  {
-
1296  Logging::error(cachepath, "Failed to execute select. Return code: %1 Error: %2 SQL: %3", ret, sqlite3_errmsg(m_cacheidx_db), expanded_sql(stmt).c_str());
-
1297  }
-
1298 
-
1299  sqlite3_finalize(stmt);
-
1300  }
-
1301 
-
1302  return true;
-
1303 }
-
1304 
-
1305 bool Cache::maintenance(size_t predicted_filesize)
-
1306 {
-
1307  bool success = true;
-
1308 
-
1309  // Find and remove expired cache entries
-
1310  success &= prune_expired();
-
1311 
-
1312  // Check max. cache size
-
1313  success &= prune_cache_size();
-
1314 
-
1315  // Check min. diskspace required for cache
-
1316  success &= prune_disk_space(predicted_filesize);
-
1317 
-
1318  return success;
-
1319 }
-
1320 
-
1321 bool Cache::clear()
-
1322 {
-
1323  bool success = true;
-
1324 
-
1325  std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
-
1326 
-
1327  std::vector<cache_key_t> keys;
-
1328  sqlite3_stmt * stmt;
-
1329  const char * sql;
-
1330 
-
1331  sql = "SELECT filename, desttype FROM cache_entry;\n";
-
1332 
-
1333  sqlite3_prepare(m_cacheidx_db, sql, -1, &stmt, nullptr);
-
1334 
-
1335  int ret = 0;
-
1336  while((ret = sqlite3_step(stmt)) == SQLITE_ROW)
-
1337  {
-
1338  const char *filename = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
-
1339  const char *desttype = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
-
1340 
-
1341  keys.emplace_back(filename, desttype);
-
1342  }
-
1343 
-
1344  Logging::trace(m_cacheidx_file, "Clearing all %1 entries from cache...", keys.size());
-
1345 
-
1346  if (ret == SQLITE_DONE)
-
1347  {
-
1348  for (const auto& [key, value] : keys)
-
1349  {
-
1350  Logging::trace(m_cacheidx_file, "Pruning: %1 Type: %2", key.c_str(), value.c_str());
-
1351 
-
1352  cache_t::iterator p = m_cache.find(make_pair(key, value));
-
1353  if (p != m_cache.end())
-
1354  {
-
1355  delete_entry(&p->second, CACHE_CLOSE_DELETE);
-
1356  }
-
1357 
-
1358  if (delete_info(key, value))
-
1359  {
-
1360  remove_cachefile(key, value);
-
1361  }
-
1362  }
-
1363  }
-
1364  else
-
1365  {
-
1366  Logging::error(m_cacheidx_file, "Failed to execute select. Return code: %1 Error: %2 SQL: %3", ret, sqlite3_errmsg(m_cacheidx_db), expanded_sql(stmt).c_str());
-
1367  }
-
1368 
-
1369  sqlite3_finalize(stmt);
-
1370 
-
1371  return success;
-
1372 }
-
1373 
-
1374 bool Cache::remove_cachefile(const std::string & filename, const std::string & fileext)
-
1375 {
-
1376  std::string cachefile;
-
1377  bool success;
-
1378 
-
1379  Buffer::make_cachefile_name(cachefile, filename, fileext, false);
-
1380 
-
1381  success = Buffer::remove_file(cachefile);
-
1382 
-
1383  Buffer::make_cachefile_name(cachefile, filename, fileext, true);
- -
1385  if (!Buffer::remove_file(cachefile) && errno != ENOENT)
-
1386  {
-
1387  success = false;
-
1388  }
-
1389 
-
1390  return success;
-
1391 }
-
1392 
-
1393 std::string Cache::expanded_sql(sqlite3_stmt *pStmt)
-
1394 {
-
1395  std::string sql;
-
1396 #ifdef HAVE_SQLITE_EXPANDED_SQL
-
1397  char * p = sqlite3_expanded_sql(pStmt);
-
1398  sql = p;
-
1399  sqlite3_free(p);
-
1400 #else
-
1401  const char *p = sqlite3_sql(pStmt);
-
1402  if (p != nullptr)
-
1403  {
-
1404  sql=p;
-
1405  }
-
1406  else
-
1407  {
-
1408  sql="(nullptr)";
-
1409  }
-
1410 #endif
-
1411  return sql;
-
1412 }
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
32#include "cache.h"
+
33#include "cache_entry.h"
+
34#include "ffmpegfs.h"
+
35#include "logging.h"
+
36
+
37#include <vector>
+
38#include <cassert>
+
39
+
40#ifndef HAVE_SQLITE_ERRSTR
+
41#define sqlite3_errstr(rc) ""
+
42#endif // HAVE_SQLITE_ERRSTR
+
43
+
44#define STRINGIFY(x) #x
+
45#define TOSTRING(x) STRINGIFY(x)
+ +
48{
+
49 //
+
50 // Table name
+
51 //
+
52 "cache_entry",
+
53 //
+
54 // Primary key
+
55 //
+
56 "PRIMARY KEY(`filename`,`desttype`)"
+
57};
+
58
+ +
60{
+
61 //
+
62 // Primary key: filename + desttype
+
63 //
+
64 { "filename", "TEXT NOT NULL" },
+
65 { "desttype", "CHAR ( 10 ) NOT NULL" },
+
66 //
+
67 // Encoding parameters
+
68 //
+
69 { "enable_ismv", "BOOLEAN NOT NULL" },
+
70 { "audiobitrate", "UNSIGNED INT NOT NULL" },
+
71 { "audiosamplerate", "UNSIGNED INT NOT NULL" },
+
72 { "videobitrate", "UNSIGNED INT NOT NULL" },
+
73 { "videowidth", "UNSIGNED INT NOT NULL" },
+
74 { "videoheight", "UNSIGNED INT NOT NULL" },
+
75 { "deinterlace", "BOOLEAN NOT NULL" },
+
76 //
+
77 // Encoding results
+
78 //
+
79 { "duration", "UNSIGNED BIG INT NOT NULL" },
+
80 { "predicted_filesize", "UNSIGNED BIG INT NOT NULL" },
+
81 { "encoded_filesize", "UNSIGNED BIG INT NOT NULL" },
+
82 { "video_frame_count", "UNSIGNED BIG INT NOT NULL" },
+
83 { "segment_count", "UNSIGNED BIG INT NOT NULL" },
+
84 { "finished", "INT NOT NULL" },
+
85 { "error", "BOOLEAN NOT NULL" },
+
86 { "errno", "INT NOT NULL" },
+
87 { "averror", "INT NOT NULL" },
+
88 { "creation_time", "DATETIME NOT NULL" },
+
89 { "access_time", "DATETIME NOT NULL" },
+
90 { "file_time", "DATETIME NOT NULL" },
+
91 { "file_size", "UNSIGNED BIG INT NOT NULL" }
+
92};
+
93
+ +
95{
+
96 //
+
97 // Table name
+
98 //
+
99 "version",
+
100 //
+
101 nullptr
+
102};
+
103
+ +
105{
+
106 { "db_version_major", "INTEGER NOT NULL" },
+
107 { "db_version_minor", "INTEGER NOT NULL" }
+
108};
+
109
+ +
111 : m_cacheidx_db(nullptr)
+
112 , m_cacheidx_select_stmt(nullptr)
+
113 , m_cacheidx_insert_stmt(nullptr)
+
114 , m_cacheidx_delete_stmt(nullptr)
+
115{
+
116}
+
117
+ +
119{
+
120 // Clean up memory
+
121 for (auto& [key, value] : m_cache)
+
122 {
+
123 value->destroy();
+
124 }
+
125
+
126 m_cache.clear();
+
127
+
128 close_index();
+
129}
+
130
+ +
132{
+
133 int ret;
+
134 const char * sql;
+
135
+
136 sql = "INSERT OR REPLACE INTO cache_entry\n"
+
137 "(filename, desttype, enable_ismv, audiobitrate, audiosamplerate, videobitrate, videowidth, videoheight, deinterlace, duration, predicted_filesize, encoded_filesize, video_frame_count, segment_count, finished, error, errno, averror, creation_time, access_time, file_time, file_size) VALUES\n"
+
138 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?);\n";
+
139
+
140 if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql, -1, &m_cacheidx_insert_stmt, nullptr)))
+
141 {
+
142 Logging::error(m_cacheidx_file, "Failed to prepare insert: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql);
+
143 return false;
+
144 }
+
145
+
146 sql = "SELECT desttype, enable_ismv, audiobitrate, audiosamplerate, videobitrate, videowidth, videoheight, deinterlace, duration, predicted_filesize, encoded_filesize, video_frame_count, segment_count, finished, error, errno, averror, strftime('%s', creation_time), strftime('%s', access_time), strftime('%s', file_time), file_size FROM cache_entry WHERE filename = ? AND desttype = ?;\n";
+
147
+
148 if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql, -1, &m_cacheidx_select_stmt, nullptr)))
+
149 {
+
150 Logging::error(m_cacheidx_file, "Failed to prepare select: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql);
+
151 return false;
+
152 }
+
153
+
154 sql = "DELETE FROM cache_entry WHERE filename = ? AND desttype = ?;\n";
+
155
+
156 if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql, -1, &m_cacheidx_delete_stmt, nullptr)))
+
157 {
+
158 Logging::error(m_cacheidx_file, "Failed to prepare delete: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql);
+
159 return false;
+
160 }
+
161
+
162 return true;
+
163}
+
164
+
165bool Cache::table_exists(const char *table)
+
166{
+
167 std::string sql;
+
168 sqlite3_stmt * stmt = nullptr;
+
169 int results = 0;
+
170 int ret;
+
171
+
172 sql = "SELECT Count(*) FROM sqlite_master WHERE type='table' AND name='";
+
173 sql += table;
+
174 sql += "'";
+
175
+
176 if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql.c_str(), -1, &stmt, nullptr)))
+
177 {
+
178 Logging::error(m_cacheidx_file, "Failed to prepare statement for table_exists: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql.c_str());
+
179 return false;
+
180 }
+
181
+
182 ret = sqlite3_step(stmt);
+
183
+
184 if (ret == SQLITE_ROW)
+
185 {
+
186 results = sqlite3_column_int(stmt, 0);
+
187 }
+
188
+
189 sqlite3_finalize(stmt);
+
190
+
191 return (results == 1);
+
192}
+
193
+
194bool Cache::column_exists(const char *table, const char *column)
+
195{
+
196 std::string sql;
+
197 sqlite3_stmt * stmt = nullptr;
+
198 int results = 0;
+
199 int ret;
+
200
+
201 sql = "SELECT COUNT(*) AS CNTREC FROM pragma_table_info('";
+
202 sql += table;
+
203 sql += "') WHERE name='";
+
204 sql += column;
+
205 sql += "';";
+
206
+
207 if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql.c_str(), -1, &stmt, nullptr)))
+
208 {
+
209 Logging::error(m_cacheidx_file, "Failed to prepare statement for table_exists: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql.c_str());
+
210 return false;
+
211 }
+
212
+
213 ret = sqlite3_step(stmt);
+
214
+
215 if (ret == SQLITE_ROW)
+
216 {
+
217 results = sqlite3_column_int(stmt, 0);
+
218 }
+
219
+
220 sqlite3_finalize(stmt);
+
221
+
222 return (results == 1);
+
223}
+
224
+
225bool Cache::check_min_version(int *db_version_major, int *db_version_minor)
+
226{
+
227 std::string sql;
+
228 sqlite3_stmt * stmt = nullptr;
+
229 int ret;
+
230
+
231 sql = "SELECT db_version_major, db_version_minor FROM version;";
+
232
+
233 if (SQLITE_OK != (ret = sqlite3_prepare_v2(m_cacheidx_db, sql.c_str(), -1, &stmt, nullptr)))
+
234 {
+
235 Logging::error(m_cacheidx_file, "Failed to prepare statement for check_min_version: (%1) %2\n%3", ret, sqlite3_errmsg(m_cacheidx_db), sql.c_str());
+
236 return false;
+
237 }
+
238
+
239 ret = sqlite3_step(stmt);
+
240
+
241 if (ret == SQLITE_ROW)
+
242 {
+
243 *db_version_major = sqlite3_column_int(stmt, 0);
+
244 *db_version_minor = sqlite3_column_int(stmt, 1);
+
245 }
+
246
+
247 sqlite3_finalize(stmt);
+
248
+
249 return (cmp_version(*db_version_major, *db_version_minor, DB_MIN_VERSION_MAJOR, DB_MIN_VERSION_MINOR) >= 0);
+
250}
+
251
+
252int Cache::cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r)
+
253{
+
254 if (version_major_l > version_major_r)
+
255 {
+
256 return 1;
+
257 }
+
258 if (version_major_l < version_major_r)
+
259 {
+
260 return -1;
+
261 }
+
262
+
263 // version_major_l == version_major_r
+
264
+
265 if (version_minor_l > version_minor_r)
+
266 {
+
267 return 1;
+
268 }
+
269 if (version_minor_l < version_minor_r)
+
270 {
+
271 return -1;
+
272 }
+
273
+
274 // version_minor_l == version_minor_r
+
275
+
276 return 0;
+
277}
+
278
+ +
280{
+
281 char *errmsg = nullptr;
+
282 const char * sql;
+
283 int ret;
+
284
+
285 sql = "BEGIN TRANSACTION;";
+
286 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
+
287 {
+
288 Logging::error(m_cacheidx_file, "SQLite3 begin transaction failed: (%1) %2\n%3", ret, errmsg, sql);
+
289 sqlite3_free(errmsg);
+
290 return false;
+
291 }
+
292 return true;
+
293}
+
294
+ +
296{
+
297 char *errmsg = nullptr;
+
298 const char * sql;
+
299 int ret;
+
300
+
301 sql = "END TRANSACTION;";
+
302 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
+
303 {
+
304 Logging::error(m_cacheidx_file, "SQLite3 end transaction failed: (%1) %2\n%3", ret, errmsg, sql);
+
305 sqlite3_free(errmsg);
+
306 return false;
+
307 }
+
308 return true;
+
309}
+
310
+ +
312{
+
313 char *errmsg = nullptr;
+
314 const char * sql;
+
315 int ret;
+
316
+
317 sql = "ROLLBACK;";
+
318 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
+
319 {
+
320 Logging::error(m_cacheidx_file, "SQLite3 rollback transaction failed: (%1) %2\n%3", ret, errmsg, sql);
+
321 sqlite3_free(errmsg);
+
322 return false;
+
323 }
+
324 return true;
+
325}
+
326
+ +
328{
+
329 char *errmsg = nullptr;
+
330 std::string sql;
+
331 int ret;
+
332
+
333 sql = "CREATE TABLE `";
+
334 sql += table->name;
+
335 sql += "` (\n";
+
336
+
337 int i = 0;
+
338 for (const TABLE_COLUMNS & col : columns)
+
339 {
+
340 if (i++)
+
341 {
+
342 sql += ",\n";
+
343 }
+
344 sql += "`";
+
345 sql += col.name;
+
346 sql += "` ";
+
347 sql += col.type;
+
348 }
+
349
+
350 if (table->primary_key != nullptr)
+
351 {
+
352 sql += ",\n";
+
353 sql += table->primary_key;
+
354 }
+
355 sql += "\n";
+
356 sql += ");\n";
+
357
+
358 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
359 {
+
360 Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
361 sqlite3_free(errmsg);
+
362 return false;
+
363 }
+
364 return true;
+
365}
+
366
+
367bool Cache::upgrade_db(int *db_version_major, int *db_version_minor)
+
368{
+
369 if (!column_exists("cache_entry", "video_frame_count"))
+
370 {
+
371 // If video_frame_count is missing, this db is definetly old
+
372
+
373 {
+
374 char *errmsg = nullptr;
+
375 std::string sql;
+
376 int ret;
+
377
+
378 Logging::debug(m_cacheidx_file, "Adding `video_frame_count` column.");
+
379
+
380 // Add `video_frame_count` UNSIGNED BIG INT NOT NULL DEFAULT 0
+
381 sql = "ALTER TABLE `";
+ +
383 sql += "` ADD COLUMN `video_frame_count` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
+
384 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
385 {
+
386 Logging::error(m_cacheidx_file, "SQLite3 exec error adding column `video_frame_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
387 sqlite3_free(errmsg);
+
388 return false;
+
389 }
+
390
+
391 Logging::debug(m_cacheidx_file, "Altering `finished` from BOOLEAN to INT.");
+
392 }
+
393
+
394 {
+
395 char *errmsg = nullptr;
+
396 std::string sql;
+
397 int ret;
+
398
+
399 //ALTER `finished` from BOOLEAN to INT NOT NULL
+
400 // sqlite can't do that for us, we must...
+
401 //
+
402 // 1. Rename `cache_entry` to `cache_entry_old`
+
403 // 2. Create new table `cache_entry` with new structure
+
404 // 3. Copy all data from `cache_entry_old` to `cache_entry`, converting old to new column
+
405 // 4. Delete `cache_entry_old`
+
406
+
407 sql = "PRAGMA foreign_keys=off;\n";
+
408 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
409 {
+
410 Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
411 sqlite3_free(errmsg);
+
412 return false;
+
413 }
+
414 }
+
415
+
416 // Step 1
+
417 {
+
418 char *errmsg = nullptr;
+
419 std::string sql;
+
420 int ret;
+
421
+
422 sql = "ALTER TABLE `";
+ +
424 sql += "` RENAME TO `";
+ +
426 sql += "_old`;\n";
+
427 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
428 {
+
429 Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
430 sqlite3_free(errmsg);
+
431 return false;
+
432 }
+
433 }
+
434
+
435 // Step 2
+ +
437 {
+
438 Logging::error(m_cacheidx_file, "SQLite3 exec error creating 'cache_entry' table.");
+
439 return false;
+
440 }
+
441
+
442 // Step 3
+
443 {
+
444 char *errmsg = nullptr;
+
445 std::string sql;
+
446 std::string columns;
+
447 int ret;
+
448
+
449 for (const TABLE_COLUMNS & col : m_columns_cache_entry)
+
450 {
+
451 if (!columns.empty())
+
452 {
+
453 columns += ",";
+
454 }
+
455 columns += "`";
+
456 columns += col.name;
+
457 columns += "`";
+
458 }
+
459
+
460 sql = "INSERT INTO `";
+ +
462 sql += "` (";
+
463 sql += columns;
+
464 sql += ")\nSELECT ";
+
465 sql += columns;
+
466 sql += " FROM `";
+ +
468 sql += "_old`;";
+
469
+
470 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
471 {
+
472 Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
473 sqlite3_free(errmsg);
+
474 return false;
+
475 }
+
476 }
+
477
+
478 {
+
479 char *errmsg = nullptr;
+
480 std::string sql;
+
481 int ret;
+
482
+
483 // Old 0 is RESULTCODE_NONE (0)
+
484 // Old 1 is RESULTCODE_FINISHED (2)
+
485 sql = "UPDATE `";
+ +
487 sql += "`\n";
+
488 sql += "SET `finished` = 3\n";
+
489 sql += "WHERE `finished` = 1\n";
+
490 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
491 {
+
492 Logging::error(m_cacheidx_file, "SQLite3 exec error updating column `finished`: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
493 sqlite3_free(errmsg);
+
494 return false;
+
495 }
+
496 }
+
497
+
498 // Step 4
+
499 {
+
500 char *errmsg = nullptr;
+
501 std::string sql;
+
502 int ret;
+
503
+
504 sql = "DROP TABLE `cache_entry_old`";
+
505 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
506 {
+
507 Logging::error(m_cacheidx_file, "SQLite3 exec error adding column `video_frame_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
508 sqlite3_free(errmsg);
+
509 return false;
+
510 }
+
511
+
512 sql = "PRAGMA foreign_keys=on;\n";
+
513 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
514 {
+
515 Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
516 sqlite3_free(errmsg);
+
517 return false;
+
518 }
+
519 }
+
520 }
+
521
+
522 if (!column_exists("cache_entry", "duration"))
+
523 {
+
524 char *errmsg = nullptr;
+
525 std::string sql;
+
526 int ret;
+
527
+
528 Logging::debug(m_cacheidx_file, "Adding `duration` column.");
+
529
+
530 // Add `duration` UNSIGNED BIG INT NOT NULL DEFAULT 0
+
531 sql = "ALTER TABLE `";
+ +
533 sql += "` ADD COLUMN `duration` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
+
534 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
535 {
+
536 Logging::error(m_cacheidx_file, "SQLite3 exec error adding column `duration`: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
537 sqlite3_free(errmsg);
+
538 return false;
+
539 }
+
540 }
+
541
+
542 if (!column_exists("cache_entry", "segment_count"))
+
543 {
+
544 char *errmsg = nullptr;
+
545 std::string sql;
+
546 int ret;
+
547
+
548 Logging::debug(m_cacheidx_file, "Adding `segment_count` column.");
+
549
+
550 // Add `segment_count` UNSIGNED BIG INT NOT NULL DEFAULT 0
+
551 sql = "ALTER TABLE `";
+ +
553 sql += "` ADD COLUMN `segment_count` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
+
554 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql.c_str(), nullptr, nullptr, &errmsg)))
+
555 {
+
556 Logging::error(m_cacheidx_file, "SQLite3 exec error adding column `segment_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
+
557 sqlite3_free(errmsg);
+
558 return false;
+
559 }
+
560 }
+
561
+
562 // Update DB version
+
563 Logging::debug(m_cacheidx_file, "Updating version table to V%1.%2.", DB_VERSION_MAJOR, DB_VERSION_MINOR);
+
564
+
565 {
+
566 char *errmsg = nullptr;
+
567 const char * sql;
+
568 int ret;
+
569
+
570 sql = "UPDATE `version` SET db_version_major = " TOSTRING(DB_VERSION_MAJOR) ", db_version_minor = " TOSTRING(DB_VERSION_MINOR) ";\n";
+
571 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
+
572 {
+
573 Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql);
+
574 sqlite3_free(errmsg);
+
575 return false;
+
576 }
+
577
+
578 *db_version_major = DB_VERSION_MAJOR;
+
579 *db_version_minor = DB_VERSION_MINOR;
+
580 }
+
581
+
582 Logging::info(m_cacheidx_file, "Database successfully upgraded to V%1.%2.", *db_version_major, *db_version_minor);
+
583
+
584 return true;
+
585}
+
586
+ +
588{
+
589 bool success = true;
+
590
+
591 try
+
592 {
+
593 char *errmsg = nullptr;
+
594 int ret;
+
595 bool new_database = false;
+
596 bool need_upate = false;
+
597
+ +
599
+
600 if (mktree(m_cacheidx_file, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) && errno != EEXIST)
+
601 {
+
602 Logging::error(m_cacheidx_file, "Error creating cache directory: (%1) %2\n%3", errno, strerror(errno), m_cacheidx_file.c_str());
+
603 throw false;
+
604 }
+
605
+
606 append_filename(&m_cacheidx_file, "cacheidx.sqlite");
+
607
+
608 // initialise engine
+
609 if (SQLITE_OK != (ret = sqlite3_initialize()))
+
610 {
+
611 Logging::error(m_cacheidx_file, "Failed to initialise SQLite3 library: (%1) %2", ret, sqlite3_errstr(ret));
+
612 throw false;
+
613 }
+
614
+
615 // open connection to a DB
+
616 if (SQLITE_OK != (ret = sqlite3_open_v2(m_cacheidx_file.c_str(), &m_cacheidx_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_SHAREDCACHE, nullptr)))
+
617 {
+
618 Logging::error(m_cacheidx_file, "Failed to initialise SQLite3 connection: (%1) %2", ret, sqlite3_errmsg(m_cacheidx_db));
+
619 throw false;
+
620 }
+
621
+
622 if (SQLITE_OK != (ret = sqlite3_busy_timeout(m_cacheidx_db, 1000)))
+
623 {
+
624 Logging::error(m_cacheidx_file, "Failed to set SQLite3 busy timeout: (%1) %2", ret, sqlite3_errmsg(m_cacheidx_db));
+
625 throw false;
+
626 }
+
627
+
628 // Beginning with version 3.7.0 (2010-07-21), a new "Write-Ahead Log" option
+
629 // We support Sqlite from 3.7.13 anyway
+
630 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, "pragma journal_mode = WAL", nullptr, nullptr, nullptr)))
+
631 {
+
632 Logging::error(m_cacheidx_file, "Failed to set SQLite3 WAL mode: (%1) %2", ret, sqlite3_errmsg(m_cacheidx_db));
+
633 throw false;
+
634 }
+
635
+
636 // Very strange: Compare operations with =, > etc. are case sensitive, while LIKE by default ignores upper/lowercase.
+
637 // Produces strange results when reading from a Samba drive and different cases are used...
+
638 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, "PRAGMA case_sensitive_like = 1;", nullptr, nullptr, nullptr)))
+
639 {
+
640 Logging::error(m_cacheidx_file, "Failed to set SQLite3 case_sensitive_like = 1: (%1) %2", ret, sqlite3_errmsg(m_cacheidx_db));
+
641 throw false;
+
642 }
+
643
+
644 // Make sure the next changes are either all successfull or rolled back
+
645 if (!begin_transaction())
+
646 {
+
647 throw false;
+
648 }
+
649
+
650 // Check if we got a new, empty database and create necessary tables
+
651
+
652 // Create cache_entry table if not already existing
+
653 if (!table_exists("cache_entry"))
+
654 {
+
655 Logging::debug(m_cacheidx_file, "Creating 'cache_entry' table in database.");
+
656
+ +
658 {
+
659 Logging::error(m_cacheidx_file, "SQLite3 exec error creating 'cache_entry' table: (%1) %2", ret, errmsg);
+
660 throw false;
+
661 }
+
662
+
663 new_database = true; // Created a new database
+
664 }
+
665
+
666 // If version table does not exist add it
+
667 if (!table_exists("version"))
+
668 {
+
669 const char * sql;
+
670
+
671 Logging::debug(m_cacheidx_file, "Creating 'version' table in database.");
+
672
+ +
674 {
+
675 Logging::error(m_cacheidx_file, "SQLite3 exec error creating 'cache_entry' table: (%1) %2", ret, errmsg);
+
676 throw false;
+
677 }
+
678
+
679 sql = "INSERT INTO `version` (db_version_major, db_version_minor) VALUES (" TOSTRING(DB_VERSION_MAJOR) ", " TOSTRING(DB_VERSION_MINOR) ");\n";
+
680 if (SQLITE_OK != (ret = sqlite3_exec(m_cacheidx_db, sql, nullptr, nullptr, &errmsg)))
+
681 {
+
682 Logging::error(m_cacheidx_file, "SQLite3 exec error: (%1) %2\n%3", ret, errmsg, sql);
+
683 sqlite3_free(errmsg);
+
684 throw false;
+
685 }
+
686
+
687 if (!new_database)
+
688 {
+
689 // Added version only, old database, need upgrade
+
690 need_upate = true;
+
691 }
+
692 }
+
693
+
694 // Check if database needs a structure upgrade
+
695 int db_version_major = DB_BASE_VERSION_MAJOR; // Old database contains no version table. This is the version of this database.
+
696 int db_version_minor = DB_BASE_VERSION_MINOR;
+
697 if (need_upate || !check_min_version(&db_version_major, &db_version_minor))
+
698 {
+
699 // No version table found, or minimum version too low, do an upgrade.
+
700 Logging::warning(m_cacheidx_file, "Database version is %1.%2, but a least %3.%4 required. Upgrading database now.", db_version_major, db_version_minor, DB_MIN_VERSION_MAJOR, DB_MIN_VERSION_MINOR);
+
701
+
702 if (!upgrade_db(&db_version_major, &db_version_minor))
+
703 {
+
704 throw false;
+
705 }
+
706 }
+
707
+
708 if (!end_transaction())
+
709 {
+
710 throw false;
+
711 }
+
712
+
713#ifdef HAVE_SQLITE_CACHEFLUSH
+
714 if (!flush_index())
+
715 {
+
716 throw false;
+
717 }
+
718#endif // HAVE_SQLITE_CACHEFLUSH
+
719
+
720 // prepare the statements
+
721 if (!prepare_stmts())
+
722 {
+
723 throw false;
+
724 }
+
725 }
+
726 catch (bool _success)
+
727 {
+
728 success = _success;
+
729 }
+
730
+
731 return success;
+
732}
+
733
+
734#ifdef HAVE_SQLITE_CACHEFLUSH
+
735bool Cache::flush_index()
+
736{
+
737 if (m_cacheidx_db != nullptr)
+
738 {
+
739 int ret;
+
740
+
741 // Flush cache to disk
+
742 if (SQLITE_OK != (ret = sqlite3_db_cacheflush(m_cacheidx_db)))
+
743 {
+
744 Logging::error(m_cacheidx_file, "SQLite3 cache flush error: (%1) %2", ret, sqlite3_errstr(ret));
+
745 return false;
+
746 }
+
747 }
+
748 return true;
+
749}
+
750#endif // HAVE_SQLITE_CACHEFLUSH
+
751
+ +
753{
+
754 bool success = true;
+
755
+
756 //cache_info->m_enable_ismv = 0;
+
757 cache_info->m_audiobitrate = 0;
+
758 cache_info->m_audiosamplerate = 0;
+
759 cache_info->m_videobitrate = 0;
+
760 cache_info->m_videowidth = 0;
+
761 cache_info->m_videoheight = 0;
+
762 cache_info->m_deinterlace = false;
+
763 cache_info->m_duration = 0;
+
764 cache_info->m_predicted_filesize = 0;
+
765 cache_info->m_encoded_filesize = 0;
+
766 cache_info->m_video_frame_count = 0;
+
767 cache_info->m_segment_count = 0;
+
768 cache_info->m_result = RESULTCODE_NONE;
+
769 cache_info->m_error = false;
+
770 cache_info->m_errno = 0;
+
771 cache_info->m_averror = 0;
+
772 cache_info->m_creation_time = 0;
+
773 cache_info->m_access_time = 0;
+
774 cache_info->m_file_time = 0;
+
775 cache_info->m_file_size = 0;
+
776
+
777 if (m_cacheidx_select_stmt == nullptr)
+
778 {
+
779 Logging::error(m_cacheidx_file, "SQLite3 select statement not open.");
+
780 return false;
+
781 }
+
782
+
783 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
784
+
785 try
+
786 {
+
787 int ret;
+
788
+
789 assert(sqlite3_bind_parameter_count(m_cacheidx_select_stmt) == 2);
+
790
+
791 if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_select_stmt, 1, cache_info->m_destfile.c_str(), -1, nullptr)))
+
792 {
+
793 Logging::error(m_cacheidx_file, "SQLite3 select error binding 'filename': (%1) %2", ret, sqlite3_errstr(ret));
+
794 throw false;
+
795 }
+
796
+
797 if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_select_stmt, 2, cache_info->m_desttype, -1, nullptr)))
+
798 {
+
799 Logging::error(m_cacheidx_file, "SQLite3 select error binding 'desttype': (%1) %2", ret, sqlite3_errstr(ret));
+
800 throw false;
+
801 }
+
802
+
803 ret = sqlite3_step(m_cacheidx_select_stmt);
+
804
+
805 if (ret == SQLITE_ROW)
+
806 {
+
807 const char *text = reinterpret_cast<const char *>(sqlite3_column_text(m_cacheidx_select_stmt, 0));
+
808 if (text != nullptr)
+
809 {
+
810 cache_info->m_desttype[0] = '\0';
+
811 strncat(cache_info->m_desttype, text, sizeof(cache_info->m_desttype) - 1);
+
812 }
+
813 //cache_info->m_enable_ismv = sqlite3_column_int(m_cacheidx_select_stmt, 1);
+
814 cache_info->m_audiobitrate = sqlite3_column_int(m_cacheidx_select_stmt, 2);
+
815 cache_info->m_audiosamplerate = sqlite3_column_int(m_cacheidx_select_stmt, 3);
+
816 cache_info->m_videobitrate = sqlite3_column_int(m_cacheidx_select_stmt, 4);
+
817 cache_info->m_videowidth = sqlite3_column_int(m_cacheidx_select_stmt, 5);
+
818 cache_info->m_videoheight = sqlite3_column_int(m_cacheidx_select_stmt, 6);
+
819 cache_info->m_deinterlace = sqlite3_column_int(m_cacheidx_select_stmt, 7);
+
820 cache_info->m_duration = sqlite3_column_int64(m_cacheidx_select_stmt, 8);
+
821 cache_info->m_predicted_filesize = static_cast<size_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 9));
+
822 cache_info->m_encoded_filesize = static_cast<size_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 10));
+
823 cache_info->m_video_frame_count = static_cast<uint32_t>(sqlite3_column_int(m_cacheidx_select_stmt, 11));
+
824 cache_info->m_segment_count = static_cast<uint32_t>(sqlite3_column_int(m_cacheidx_select_stmt, 12));
+
825 cache_info->m_result = static_cast<RESULTCODE>(sqlite3_column_int(m_cacheidx_select_stmt, 13));
+
826 cache_info->m_error = sqlite3_column_int(m_cacheidx_select_stmt, 14);
+
827 cache_info->m_errno = sqlite3_column_int(m_cacheidx_select_stmt, 15);
+
828 cache_info->m_averror = sqlite3_column_int(m_cacheidx_select_stmt, 16);
+
829 cache_info->m_creation_time = static_cast<time_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 17));
+
830 cache_info->m_access_time = static_cast<time_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 18));
+
831 cache_info->m_file_time = static_cast<time_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 19));
+
832 cache_info->m_file_size = static_cast<size_t>(sqlite3_column_int64(m_cacheidx_select_stmt, 20));
+
833 }
+
834 else if (ret != SQLITE_DONE)
+
835 {
+
836 Logging::error(m_cacheidx_file, "Sqlite 3 could not step (execute) select statement: (%1) %2", ret, sqlite3_errstr(ret));
+
837 throw false;
+
838 }
+
839 }
+
840 catch (bool _success)
+
841 {
+
842 success = _success;
+
843 }
+
844
+
845 sqlite3_reset(m_cacheidx_select_stmt);
+
846
+
847 if (success)
+
848 {
+
849 errno = 0; // sqlite3 sometimes sets errno without any reason, better reset any error
+
850 }
+
851
+
852 return success;
+
853}
+
854
+
855#define SQLBINDTXT(idx, var) \
+
856 if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_insert_stmt, idx, var, -1, nullptr))) \
+
857{ \
+
858 Logging::error(m_cacheidx_file, "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
+
859 throw false; \
+
860 }
+
862#define SQLBINDNUM(func, idx, var) \
+
863 if (SQLITE_OK != (ret = func(m_cacheidx_insert_stmt, idx, var))) \
+
864{ \
+
865 Logging::error(m_cacheidx_file, "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
+
866 throw false; \
+
867 }
+
869bool Cache::write_info(LPCCACHE_INFO cache_info)
+
870{
+
871 bool success = true;
+
872
+
873 if (m_cacheidx_insert_stmt == nullptr)
+
874 {
+
875 Logging::error(m_cacheidx_file, "SQLite3 select statement not open.");
+
876 return false;
+ +
878
+
879 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
880
+
881 try
+
882 {
+
883 int ret;
+
884 bool enable_ismv_dummy = false;
+
885
+
886 assert(sqlite3_bind_parameter_count(m_cacheidx_insert_stmt) == 22);
+
887
+
888 SQLBINDTXT(1, cache_info->m_destfile.c_str());
+
889 SQLBINDTXT(2, cache_info->m_desttype);
+
890 //SQLBINDNUM(sqlite3_bind_int, 3, cache_info->m_enable_ismv);
+
891 SQLBINDNUM(sqlite3_bind_int, 3, enable_ismv_dummy);
+
892 SQLBINDNUM(sqlite3_bind_int64, 4, cache_info->m_audiobitrate);
+
893 SQLBINDNUM(sqlite3_bind_int, 5, cache_info->m_audiosamplerate);
+
894 SQLBINDNUM(sqlite3_bind_int64, 6, cache_info->m_videobitrate);
+
895 SQLBINDNUM(sqlite3_bind_int, 7, static_cast<int>(cache_info->m_videowidth));
+
896 SQLBINDNUM(sqlite3_bind_int, 8, static_cast<int>(cache_info->m_videoheight));
+
897 SQLBINDNUM(sqlite3_bind_int, 9, cache_info->m_deinterlace);
+
898 SQLBINDNUM(sqlite3_bind_int64, 10, static_cast<sqlite3_int64>(cache_info->m_duration));
+
899 SQLBINDNUM(sqlite3_bind_int64, 11, static_cast<sqlite3_int64>(cache_info->m_predicted_filesize));
+
900 SQLBINDNUM(sqlite3_bind_int64, 12, static_cast<sqlite3_int64>(cache_info->m_encoded_filesize));
+
901 SQLBINDNUM(sqlite3_bind_int, 13, static_cast<int32_t>(cache_info->m_video_frame_count));
+
902 SQLBINDNUM(sqlite3_bind_int, 14, static_cast<int32_t>(cache_info->m_segment_count));
+
903 SQLBINDNUM(sqlite3_bind_int, 15, cache_info->m_result);
+
904 SQLBINDNUM(sqlite3_bind_int, 16, cache_info->m_error);
+
905 SQLBINDNUM(sqlite3_bind_int, 17, cache_info->m_errno);
+
906 SQLBINDNUM(sqlite3_bind_int, 18, cache_info->m_averror);
+
907 SQLBINDNUM(sqlite3_bind_int64, 19, cache_info->m_creation_time);
+
908 SQLBINDNUM(sqlite3_bind_int64, 20, cache_info->m_access_time);
+
909 SQLBINDNUM(sqlite3_bind_int64, 21, cache_info->m_file_time);
+
910 SQLBINDNUM(sqlite3_bind_int64, 22, static_cast<sqlite3_int64>(cache_info->m_file_size));
+
911
+
912 ret = sqlite3_step(m_cacheidx_insert_stmt);
+
913
+
914 if (ret != SQLITE_DONE)
+
915 {
+
916 Logging::error(m_cacheidx_file, "Sqlite 3 could not step (execute) insert statement: (%1) %2", ret, sqlite3_errstr(ret));
+
917 throw false;
+
918 }
+
919 }
+
920 catch (bool _success)
+
921 {
+
922 success = _success;
+
923 }
+
924
+
925 sqlite3_reset(m_cacheidx_insert_stmt);
+
926
+
927 if (success)
+
928 {
+
929 errno = 0; // sqlite3 sometimes sets errno without any reason, better reset any error
+
930 }
+
931
+
932 return success;
+
933}
+
934
+
935bool Cache::delete_info(const std::string & filename, const std::string & desttype)
+
936{
+
937 bool success = true;
+
938
+
939 if (m_cacheidx_delete_stmt == nullptr)
+
940 {
+
941 Logging::error(m_cacheidx_file, "SQLite3 delete statement not open.");
+
942 return false;
+
943 }
+
944
+
945 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
946
+
947 try
+
948 {
+
949 int ret;
+
950
+
951 assert(sqlite3_bind_parameter_count(m_cacheidx_delete_stmt) == 2);
+
952
+
953 if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_delete_stmt, 1, filename.c_str(), -1, nullptr)))
+
954 {
+
955 Logging::error(m_cacheidx_file, "SQLite3 select error binding 'filename': (%1) %2", ret, sqlite3_errstr(ret));
+
956 throw false;
+
957 }
+
958
+
959 if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_delete_stmt, 2, desttype.c_str(), -1, nullptr)))
+
960 {
+
961 Logging::error(m_cacheidx_file, "SQLite3 select error binding 'desttype': (%1) %2", ret, sqlite3_errstr(ret));
+
962 throw false;
+
963 }
+
964
+
965 ret = sqlite3_step(m_cacheidx_delete_stmt);
+
966
+
967 if (ret != SQLITE_DONE)
+
968 {
+
969 Logging::error(m_cacheidx_file, "Sqlite 3 could not step (execute) delete statement: (%1) %2", ret, sqlite3_errstr(ret));
+
970 throw false;
+
971 }
+
972 }
+
973 catch (bool _success)
+
974 {
+
975 success = _success;
+
976 }
+
977
+
978 sqlite3_reset(m_cacheidx_delete_stmt);
+
979
+
980 if (success)
+
981 {
+
982 errno = 0; // sqlite3 sometimes sets errno without any reason, better reset any error
+
983 }
+
984
+
985 return success;
+
986}
+
987
+ +
989{
+
990 if (m_cacheidx_db != nullptr)
+
991 {
+
992#ifdef HAVE_SQLITE_CACHEFLUSH
+
993 flush_index();
+
994#endif // HAVE_SQLITE_CACHEFLUSH
+
995
+
996 sqlite3_finalize(m_cacheidx_select_stmt);
+
997 sqlite3_finalize(m_cacheidx_insert_stmt);
+
998 sqlite3_finalize(m_cacheidx_delete_stmt);
+
999
+
1000 sqlite3_close(m_cacheidx_db);
+
1001 }
+
1002 sqlite3_shutdown();
+
1003}
+
1004
+
1005Cache_Entry* Cache::create_entry(LPVIRTUALFILE virtualfile, const std::string & desttype)
+
1006{
+
1007 //Cache_Entry* cache_entry = new(std::nothrow) Cache_Entry(this, filename);
+
1008 Cache_Entry* cache_entry = Cache_Entry::create(this, virtualfile);
+
1009 if (cache_entry == nullptr)
+
1010 {
+
1011 Logging::error(m_cacheidx_file, "Out of memory creating cache entry.");
+
1012 return nullptr;
+
1013 }
+
1014
+
1015 m_cache.insert(make_pair(make_pair(virtualfile->m_destfile, desttype), cache_entry));
+
1016
+
1017 return cache_entry;
+
1018}
+
1019
+
1020bool Cache::delete_entry(Cache_Entry ** cache_entry, int flags)
+
1021{
+
1022 if (*cache_entry == nullptr)
+
1023 {
+
1024 return true;
+
1025 }
+
1026
+
1027 bool deleted = false;
+
1028
+
1029 if ((*cache_entry)->closeio(flags))
+ +
1031 // If CACHE_CLOSE_FREE is set, also free memory
+ +
1033 {
+
1034 m_cache.erase(make_pair((*cache_entry)->m_cache_info.m_destfile, (*cache_entry)->m_cache_info.m_desttype));
+
1035
+
1036 deleted = (*cache_entry)->destroy();
+
1037 *cache_entry = nullptr;
+
1038 }
+
1039 }
+
1040
+
1041 return deleted;
+
1042}
+
1043
+ +
1045{
+
1046 Cache_Entry* cache_entry = nullptr;
+
1047 cache_t::const_iterator p = m_cache.find(make_pair(virtualfile->m_destfile, params.current_format(virtualfile)->desttype()));
+
1048 if (p == m_cache.cend())
+
1049 {
+
1050 Logging::trace(virtualfile->m_destfile, "Created new transcoder.");
+
1051 cache_entry = create_entry(virtualfile, params.current_format(virtualfile)->desttype());
+
1052 }
+
1053 else
+ +
1055 Logging::trace(virtualfile->m_destfile, "Reusing cached transcoder.");
+
1056 cache_entry = p->second;
+
1057 }
+
1058
+
1059 return cache_entry;
+
1060}
+
1061
+
1062bool Cache::closeio(Cache_Entry **cache_entry, int flags /*= CACHE_CLOSE_NOOPT*/)
+
1063{
+
1064 if (*cache_entry == nullptr)
+
1065 {
+
1066 return true;
+
1067 }
+
1068
+
1069 bool deleted;
+
1070
+
1071 std::string filename((*cache_entry)->filename());
+
1072 if (delete_entry(cache_entry, flags))
+
1073 {
+
1074 Logging::trace(filename, "Freed cache entry.");
+
1075 deleted = true;
+
1076 }
+
1077 else
+
1078 {
+
1079 Logging::trace(filename, "Keeping cache entry.");
+
1080 deleted = false;
+
1081 }
+
1082
+
1083 return deleted;
+
1084}
+
1085
+ +
1087{
+
1088 if (params.m_expiry_time <= 0)
+
1089 {
+
1090 // There's no limit.
+
1091 return true;
+
1092 }
+
1093
+
1094 std::vector<cache_key_t> keys;
+
1095 sqlite3_stmt * stmt;
+
1096 time_t now = time(nullptr);
+
1097 std::string sql;
+
1098
+
1099 Logging::trace(m_cacheidx_file, "Pruning expired cache entries older than %1...", format_time(params.m_expiry_time).c_str());
+
1100
+
1101 strsprintf(&sql, "SELECT filename, desttype, strftime('%%s', access_time) FROM cache_entry WHERE strftime('%%s', access_time) + %" FFMPEGFS_FORMAT_TIME_T " < %" FFMPEGFS_FORMAT_TIME_T ";\n", params.m_expiry_time, now);
+
1102
+
1103 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
1104
+
1105 sqlite3_prepare(m_cacheidx_db, sql.c_str(), -1, &stmt, nullptr);
+
1106
+
1107 int ret = 0;
+
1108 while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
+
1109 {
+
1110 const char *filename = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
+
1111 const char *desttype = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
+
1112
+
1113 keys.emplace_back(filename, desttype);
+
1114
+
1115 Logging::trace(filename, "Found %1 old entries.", format_time(now - static_cast<time_t>(sqlite3_column_int64(stmt, 2))).c_str());
+
1116 }
+
1117
+
1118 Logging::trace(m_cacheidx_file, "%1 expired cache entries found.", keys.size());
+
1119
+
1120 if (ret == SQLITE_DONE)
+
1121 {
+
1122 for (const auto& [key, value] : keys)
+
1123 {
+
1124 Logging::trace(m_cacheidx_file, "Pruning '%1' - Type: %2", key.c_str(), value.c_str());
+
1125
+
1126 cache_t::iterator p = m_cache.find(make_pair(key, value));
+
1127 if (p != m_cache.end())
+
1128 {
+
1129 delete_entry(&p->second, CACHE_CLOSE_DELETE);
+
1130 }
+
1131
+
1132 if (delete_info(key, value))
+
1133 {
+
1134 remove_cachefile(key, value);
+
1135 }
+
1136 }
+
1137 }
+
1138 else
+
1139 {
+
1140 Logging::error(m_cacheidx_file, "Failed to execute select. Return code: %1 Error: %2 SQL: %3", ret, sqlite3_errmsg(m_cacheidx_db), expanded_sql(stmt).c_str());
+
1141 }
+
1142
+
1143 sqlite3_finalize(stmt);
+
1144
+
1145 return true;
+
1146}
+
1147
+ +
1149{
+ +
1151 {
+
1152 // There's no limit.
+
1153 return true;
+
1154 }
+
1155
+
1156 std::vector<cache_key_t> keys;
+
1157 std::vector<size_t> filesizes;
+
1158 sqlite3_stmt * stmt;
+
1159 const char * sql;
+
1160
+
1161 Logging::trace(m_cacheidx_file, "Pruning oldest cache entries exceeding %1 cache size...", format_size(params.m_max_cache_size).c_str());
+
1162
+
1163 sql = "SELECT filename, desttype, encoded_filesize FROM cache_entry ORDER BY access_time ASC;\n";
+
1164
+
1165 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
1166
+
1167 sqlite3_prepare(m_cacheidx_db, sql, -1, &stmt, nullptr);
+
1168
+
1169 int ret = 0;
+
1170 size_t total_size = 0;
+
1171 while((ret = sqlite3_step(stmt)) == SQLITE_ROW)
+
1172 {
+
1173 const char *filename = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
+
1174 const char *desttype = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
+
1175 size_t size = static_cast<size_t>(sqlite3_column_int64(stmt, 2));
+
1176
+
1177 keys.emplace_back(filename, desttype);
+
1178 filesizes.push_back(size);
+
1179 total_size += size;
+
1180 }
+
1181
+
1182 Logging::trace(m_cacheidx_file, "%1 in cache.", format_size(total_size).c_str());
+
1183
+
1184 if (total_size > params.m_max_cache_size)
+
1185 {
+
1186 Logging::trace(m_cacheidx_file, "Pruning %1 of oldest cache entries to limit cache size.", format_size(total_size - params.m_max_cache_size).c_str());
+
1187 if (ret == SQLITE_DONE)
+
1188 {
+
1189 size_t n = 0;
+
1190 for (const auto& [key, value] : keys)
+
1191 {
+
1192 Logging::trace(m_cacheidx_file, "Pruning: %1 Type: %2", key.c_str(), value.c_str());
+
1193
+
1194 cache_t::iterator p = m_cache.find(make_pair(key, value));
+
1195 if (p != m_cache.end())
+
1196 {
+
1197 delete_entry(&p->second, CACHE_CLOSE_DELETE);
+
1198 }
+
1199
+
1200 if (delete_info(key, value))
+
1201 {
+
1202 remove_cachefile(key, value);
+
1203 }
+
1204
+
1205 total_size -= filesizes[n++];
+
1206
+
1207 if (total_size <= params.m_max_cache_size)
+
1208 {
+
1209 break;
+
1210 }
+
1211 }
+
1212
+
1213 Logging::trace(m_cacheidx_file, "%1 left in cache.", format_size(total_size).c_str());
+
1214 }
+
1215 else
+
1216 {
+
1217 Logging::error(m_cacheidx_file, "Failed to execute select. Return code: %1 Error: %2 SQL: %3", ret, sqlite3_errmsg(m_cacheidx_db), expanded_sql(stmt).c_str());
+
1218 }
+
1219 }
+
1220
+
1221 sqlite3_finalize(stmt);
+
1222
+
1223 return true;
+
1224}
+
1225
+
1226bool Cache::prune_disk_space(size_t predicted_filesize)
+
1227{
+
1228 std::string cachepath;
+
1229
+
1230 transcoder_cache_path(cachepath);
+
1231
+
1232 size_t free_bytes = get_disk_free(cachepath);
+
1233
+
1234 if (!free_bytes && errno)
+
1235 {
+
1236 if (errno == ENOENT)
+
1237 {
+
1238 // Cache path does not exist. Strange problem, but not error. Ignore silently.
+
1239 return true;
+
1240 }
+
1241
+
1242 Logging::error(cachepath, "prune_disk_space() cannot determine free disk space: (%1) %2", errno, strerror(errno));
+
1243 return false;
+
1244 }
+
1245
+
1246 if (free_bytes < predicted_filesize)
+
1247 {
+
1248 Logging::error(cachepath, "prune_disk_space() : Insufficient disk space %1 on cache drive, at least %2 required.", format_size(free_bytes).c_str(), format_size(predicted_filesize).c_str());
+
1249 errno = ENOSPC;
+
1250 return false;
+
1251 }
+
1252
+
1253 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
1254
+
1255 Logging::trace(cachepath, "%1 disk space before prune.", format_size(free_bytes).c_str());
+
1256 if (free_bytes < params.m_min_diskspace + predicted_filesize)
+
1257 {
+
1258 std::vector<cache_key_t> keys;
+
1259 std::vector<size_t> filesizes;
+
1260 sqlite3_stmt * stmt;
+
1261 const char * sql;
+
1262
+
1263 sql = "SELECT filename, desttype, encoded_filesize FROM cache_entry ORDER BY access_time ASC;\n";
+
1264
+
1265 sqlite3_prepare(m_cacheidx_db, sql, -1, &stmt, nullptr);
+
1266
+
1267 int ret = 0;
+
1268 while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
+
1269 {
+
1270 const char *filename = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
+
1271 const char *desttype = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
+
1272 size_t size = static_cast<size_t>(sqlite3_column_int64(stmt, 2));
+
1273
+
1274 keys.emplace_back(filename, desttype);
+
1275 filesizes.push_back(size);
+
1276 }
+
1277
+
1278 Logging::trace(cachepath, "Pruning %1 of oldest cache entries to keep disk space above %2 limit...", format_size(params.m_min_diskspace + predicted_filesize - free_bytes).c_str(), format_size(params.m_min_diskspace).c_str());
+
1279
+
1280 if (ret == SQLITE_DONE)
+
1281 {
+
1282 size_t n = 0;
+
1283 for (const auto& [key, value] : keys)
+
1284 {
+
1285 Logging::trace(cachepath, "Pruning: %1 Type: %2", key.c_str(), value.c_str());
+
1286
+
1287 cache_t::iterator p = m_cache.find(make_pair(key, value));
+
1288 if (p != m_cache.end())
+
1289 {
+
1290 delete_entry(&p->second, CACHE_CLOSE_DELETE);
+
1291 }
+
1292
+
1293 if (delete_info(key, value))
+
1294 {
+
1295 remove_cachefile(key, value);
+
1296 }
+
1297
+
1298 free_bytes += filesizes[n++];
+
1299
+
1300 if (free_bytes >= params.m_min_diskspace + predicted_filesize)
+
1301 {
+
1302 break;
+
1303 }
+
1304 }
+
1305 Logging::trace(cachepath, "Disk space after prune: %1", format_size(free_bytes).c_str());
+
1306 }
+
1307 else
+
1308 {
+
1309 Logging::error(cachepath, "Failed to execute select. Return code: %1 Error: %2 SQL: %3", ret, sqlite3_errmsg(m_cacheidx_db), expanded_sql(stmt).c_str());
+
1310 }
+
1311
+
1312 sqlite3_finalize(stmt);
+
1313 }
+
1314
+
1315 return true;
+
1316}
+
1317
+
1318bool Cache::maintenance(size_t predicted_filesize)
+
1319{
+
1320 bool success = true;
+
1321
+
1322 // Find and remove expired cache entries
+
1323 success &= prune_expired();
+
1324
+
1325 // Check max. cache size
+
1326 success &= prune_cache_size();
+
1327
+
1328 // Check min. diskspace required for cache
+
1329 success &= prune_disk_space(predicted_filesize);
+
1330
+
1331 return success;
+
1332}
+
1333
+
1334bool Cache::clear()
+
1335{
+
1336 bool success = true;
+
1337
+
1338 std::lock_guard<std::recursive_mutex> lock_mutex(m_mutex);
+
1339
+
1340 std::vector<cache_key_t> keys;
+
1341 sqlite3_stmt * stmt;
+
1342 const char * sql;
+
1343
+
1344 sql = "SELECT filename, desttype FROM cache_entry;\n";
+
1345
+
1346 sqlite3_prepare(m_cacheidx_db, sql, -1, &stmt, nullptr);
+
1347
+
1348 int ret = 0;
+
1349 while((ret = sqlite3_step(stmt)) == SQLITE_ROW)
+
1350 {
+
1351 const char *filename = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
+
1352 const char *desttype = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
+
1353
+
1354 keys.emplace_back(filename, desttype);
+
1355 }
+
1356
+
1357 Logging::trace(m_cacheidx_file, "Clearing all %1 entries from cache...", keys.size());
+
1358
+
1359 if (ret == SQLITE_DONE)
+
1360 {
+
1361 for (const auto& [key, value] : keys)
+
1362 {
+
1363 Logging::trace(m_cacheidx_file, "Pruning: %1 Type: %2", key.c_str(), value.c_str());
+
1364
+
1365 cache_t::iterator p = m_cache.find(make_pair(key, value));
+
1366 if (p != m_cache.end())
+
1367 {
+
1368 delete_entry(&p->second, CACHE_CLOSE_DELETE);
+
1369 }
+
1370
+
1371 if (delete_info(key, value))
+
1372 {
+
1373 remove_cachefile(key, value);
+
1374 }
+
1375 }
+
1376 }
+
1377 else
+
1378 {
+
1379 Logging::error(m_cacheidx_file, "Failed to execute select. Return code: %1 Error: %2 SQL: %3", ret, sqlite3_errmsg(m_cacheidx_db), expanded_sql(stmt).c_str());
+
1380 }
+
1381
+
1382 sqlite3_finalize(stmt);
+
1383
+
1384 return success;
+
1385}
+
1386
+
1387bool Cache::remove_cachefile(const std::string & filename, const std::string & fileext)
+
1388{
+
1389 std::string cachefile;
+
1390 bool success;
+
1391
+
1392 Buffer::make_cachefile_name(cachefile, filename, fileext, false);
+
1393
+
1394 success = Buffer::remove_file(cachefile);
+
1395
+
1396 Buffer::make_cachefile_name(cachefile, filename, fileext, true);
+ +
1398 if (!Buffer::remove_file(cachefile) && errno != ENOENT)
+
1399 {
+
1400 success = false;
+
1401 }
+
1402
+
1403 return success;
+
1404}
+
1405
+
1406std::string Cache::expanded_sql(sqlite3_stmt *pStmt)
+
1407{
+
1408 std::string sql;
+
1409#ifdef HAVE_SQLITE_EXPANDED_SQL
+
1410 char * p = sqlite3_expanded_sql(pStmt);
+
1411 sql = p;
+
1412 sqlite3_free(p);
+
1413#else
+
1414 const char *p = sqlite3_sql(pStmt);
+
1415 if (p != nullptr)
+ +
1417 sql=p;
+
1418 }
+
1419 else
+
1420 {
+
1421 sql="(nullptr)";
+
1422 }
+
1423#endif
+
1424 return sql;
+
1425}
#define CACHE_CLOSE_FREE
Free memory for cache entry.
Definition: buffer.h:46
#define CACHE_CHECK_BIT(mask, var)
Check bit in bitmask.
Definition: buffer.h:43
#define CACHE_CLOSE_DELETE
Delete cache entry, will unlink cached file! Implies CACHE_CLOSE_FREE.
Definition: buffer.h:47
-
#define SQLBINDTXT(idx, var)
Bind text column to SQLite statement.
Definition: cache.cc:842
+
#define SQLBINDTXT(idx, var)
Bind text column to SQLite statement.
Definition: cache.cc:855
#define sqlite3_errstr(rc)
If our version of SQLite hasn't go this function.
Definition: cache.cc:41
-
#define SQLBINDNUM(func, idx, var)
Bind numeric column to SQLite statement.
Definition: cache.cc:854
+
#define SQLBINDNUM(func, idx, var)
Bind numeric column to SQLite statement.
Definition: cache.cc:867
#define TOSTRING(x)
Convert a macro argument into a string constant.
Definition: cache.cc:45
Data cache management.
#define DB_VERSION_MINOR
Current database version minor.
Definition: cache.h:46
@@ -1487,48 +1499,48 @@
#define DB_BASE_VERSION_MAJOR
The oldest database version major (Release < 1.95)
Definition: cache.h:42
CACHE_INFO const * LPCCACHE_INFO
Pointer version of CACHE_INFO.
Definition: cache.h:93
Cache entry
-
static const std::string & make_cachefile_name(std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)
Make up a cache file name, including the full path.
Definition: buffer.cc:978
-
static bool remove_file(const std::string &filename)
Remove (unlink) the file.
Definition: buffer.cc:998
+
static const std::string & make_cachefile_name(std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)
Make up a cache file name, including the full path.
Definition: buffer.cc:971
+
static bool remove_file(const std::string &filename)
Remove (unlink) the file.
Definition: buffer.cc:991
The Cache_Entry class.
Definition: cache_entry.h:49
-
static Cache_Entry * create(Cache *owner, LPVIRTUALFILE virtualfile)
Create a new Cache_Entry object.
Definition: cache_entry.cc:74
-
Cache_Entry * openio(LPVIRTUALFILE virtualfile)
Open cache entry.
Definition: cache.cc:1041
+
static Cache_Entry * create(Cache *owner, LPVIRTUALFILE virtualfile)
Create a new Cache_Entry object.
Definition: cache_entry.cc:76
+
Cache_Entry * openio(LPVIRTUALFILE virtualfile)
Open cache entry.
Definition: cache.cc:1054
static const TABLECOLUMNS_VEC m_columns_cache_entry
Columns of table "cache_entry".
Definition: cache.h:324
-
bool prune_disk_space(size_t predicted_filesize)
Prune cache entries to ensure disk space.
Definition: cache.cc:1223
-
bool delete_info(const std::string &filename, const std::string &desttype)
Delete cache file info.
Definition: cache.cc:932
-
bool delete_entry(Cache_Entry **cache_entry, int flags)
Delete cache entry object.
Definition: cache.cc:1017
+
bool prune_disk_space(size_t predicted_filesize)
Prune cache entries to ensure disk space.
Definition: cache.cc:1236
+
bool delete_info(const std::string &filename, const std::string &desttype)
Delete cache file info.
Definition: cache.cc:945
+
bool delete_entry(Cache_Entry **cache_entry, int flags)
Delete cache entry object.
Definition: cache.cc:1030
sqlite3 * m_cacheidx_db
SQLite handle of cache index database.
Definition: cache.h:332
sqlite3_stmt * m_cacheidx_insert_stmt
Prepared insert statement.
Definition: cache.h:334
int cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r)
Compare two versions.
Definition: cache.cc:252
-
bool create_table_cache_entry(LPCTABLE_DEF table, const TABLECOLUMNS_VEC &columns)
Create cache_entry table.
Definition: cache.cc:314
-
bool clear()
Clear cache: deletes all entries.
Definition: cache.cc:1331
+
bool create_table_cache_entry(LPCTABLE_DEF table, const TABLECOLUMNS_VEC &columns)
Create cache_entry table.
Definition: cache.cc:327
+
bool clear()
Clear cache: deletes all entries.
Definition: cache.cc:1344
cache_t m_cache
Cache file (memory mapped file)
Definition: cache.h:336
bool prepare_stmts()
Prepare all SQL statements.
Definition: cache.cc:131
-
bool remove_cachefile(const std::string &filename, const std::string &fileext)
Remove a cache file from disk.
Definition: cache.cc:1384
-
bool maintenance(size_t predicted_filesize=0)
Run disk maintenance.
Definition: cache.cc:1315
+
bool remove_cachefile(const std::string &filename, const std::string &fileext)
Remove a cache file from disk.
Definition: cache.cc:1397
+
bool maintenance(size_t predicted_filesize=0)
Run disk maintenance.
Definition: cache.cc:1328
Cache()
Construct Cache object.
Definition: cache.cc:110
std::vector< TABLE_COLUMNS > TABLECOLUMNS_VEC
Table columns array.
Definition: cache.h:128
sqlite3_stmt * m_cacheidx_delete_stmt
Prepared delete statement.
Definition: cache.h:335
-
std::string expanded_sql(sqlite3_stmt *pStmt)
Get expanded SQL string for a statement.
Definition: cache.cc:1403
+
std::string expanded_sql(sqlite3_stmt *pStmt)
Get expanded SQL string for a statement.
Definition: cache.cc:1416
TABLE_DEF const * LPCTABLE_DEF
Pointer version of TABLE_DEF.
Definition: cache.h:114
-
bool load_index()
Load cache index from disk.
Definition: cache.cc:574
-
bool write_info(LPCCACHE_INFO cache_info)
Write cache file info.
Definition: cache.cc:866
+
bool load_index()
Load cache index from disk.
Definition: cache.cc:587
+
bool write_info(LPCCACHE_INFO cache_info)
Write cache file info.
Definition: cache.cc:879
static const TABLECOLUMNS_VEC m_columns_version
Columns of table "version".
Definition: cache.h:328
static const TABLE_DEF m_table_version
Definition and indexes of table "version".
Definition: cache.h:326
std::string m_cacheidx_file
Name of SQLite cache index database.
Definition: cache.h:331
-
bool rollback_transaction()
Rollback a database transaction.
Definition: cache.cc:298
-
void close_index()
Close cache index.
Definition: cache.cc:985
-
bool begin_transaction()
Begin a database transactio.n.
Definition: cache.cc:266
+
bool rollback_transaction()
Rollback a database transaction.
Definition: cache.cc:311
+
void close_index()
Close cache index.
Definition: cache.cc:998
+
bool begin_transaction()
Begin a database transactio.n.
Definition: cache.cc:279
sqlite3_stmt * m_cacheidx_select_stmt
Prepared select statement.
Definition: cache.h:333
-
bool read_info(LPCACHE_INFO cache_info)
Read cache file info.
Definition: cache.cc:739
+
bool read_info(LPCACHE_INFO cache_info)
Read cache file info.
Definition: cache.cc:752
bool table_exists(const char *table)
Check if SQL table exists in database.
Definition: cache.cc:165
-
bool end_transaction()
End a database transaction.
Definition: cache.cc:282
-
bool upgrade_db(int *db_version_major, int *db_version_minor)
Upgrade database from version below 1.95.
Definition: cache.cc:354
-
bool prune_cache_size()
Prune cache entries to keep cache size within limit.
Definition: cache.cc:1145
+
bool end_transaction()
End a database transaction.
Definition: cache.cc:295
+
bool upgrade_db(int *db_version_major, int *db_version_minor)
Upgrade database from version below 1.95.
Definition: cache.cc:367
+
bool prune_cache_size()
Prune cache entries to keep cache size within limit.
Definition: cache.cc:1158
std::recursive_mutex m_mutex
Access mutex.
Definition: cache.h:330
-
bool closeio(Cache_Entry **cache_entry, int flags=CACHE_CLOSE_NOOPT)
Close a cache entry.
Definition: cache.cc:1059
-
Cache_Entry * create_entry(LPVIRTUALFILE virtualfile, const std::string &desttype)
Create cache entry object for a VIRTUALFILE.
Definition: cache.cc:1002
+
bool closeio(Cache_Entry **cache_entry, int flags=CACHE_CLOSE_NOOPT)
Close a cache entry.
Definition: cache.cc:1072
+
Cache_Entry * create_entry(LPVIRTUALFILE virtualfile, const std::string &desttype)
Create cache entry object for a VIRTUALFILE.
Definition: cache.cc:1015
bool column_exists(const char *table, const char *column)
Check if column exists in SQL table.
Definition: cache.cc:194
-
bool prune_expired()
Prune expired cache entries.
Definition: cache.cc:1083
+
bool prune_expired()
Prune expired cache entries.
Definition: cache.cc:1096
bool check_min_version(int *db_version_major, int *db_version_minor)
Check the db version if upgrade needed.
Definition: cache.cc:225
virtual ~Cache()
Destruct Cache object.
Definition: cache.cc:118
static const TABLE_DEF m_table_cache_entry
Definition and indexes of table "cache_entry".
Definition: cache.h:322
@@ -1538,12 +1550,12 @@
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
Definition: logging.h:163
static void info(const T filename, const std::string &format_string, Args &&...args)
Write info level log entry.
Definition: logging.h:201
static void error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
Definition: logging.h:239
-
int mktree(const std::string &path, mode_t mode)
Make directory tree.
-
size_t get_disk_free(std::string &path)
Get free disk space.
-
std::string format_time(time_t value)
Format a time in format "w d m s".
-
const std::string & append_filename(std::string *path, const std::string &filename)
Add filename to path, including / after the path if required.
-
std::string format_size(uint64_t value)
Format size.
-
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
Definition: ffmpeg_utils.h:732
+
int mktree(const std::string &path, mode_t mode)
Make directory tree.
+
const std::string & append_filename(std::string *path, const std::string &filename)
Add filename to path, including / after the path if required.
+
size_t get_disk_free(std::string &path)
Get free disk space.
+
std::string format_time(time_t value)
Format a time in format "w d m s".
+
std::string format_size(uint64_t value)
Format size.
+
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
Definition: ffmpeg_utils.h:728
FFMPEGFS_PARAMS params
FFmpegfs command line parameters.
Definition: ffmpegfs.cc:76
Main include for FFmpegfs project.
void transcoder_cache_path(std::string &path)
Get transcoder cache path.
Definition: transcode.cc:195
@@ -1582,7 +1594,7 @@
diff --git a/html/cache_8h.html b/html/cache_8h.html index d3b3f3bc1..5b7eb6d16 100644 --- a/html/cache_8h.html +++ b/html/cache_8h.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache.h File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ + -
-
cache.h File Reference
+
cache.h File Reference
@@ -116,7 +115,7 @@

Go to the source code of this file.

- @@ -131,61 +130,51 @@

+

Classes

struct  CACHE_INFO
 Cache information block. More...
 Column definition of sql table. More...
 
- - - + + - - + + - - + + - - + + - - + + - - + +

+

Macros

-#define DB_BASE_VERSION_MAJOR   1
 The oldest database version major (Release < 1.95)
#define DB_BASE_VERSION_MAJOR   1
 The oldest database version major (Release < 1.95) More...
 
-#define DB_BASE_VERSION_MINOR   0
 The oldest database version minor (Release < 1.95)
#define DB_BASE_VERSION_MINOR   0
 The oldest database version minor (Release < 1.95) More...
 
-#define DB_VERSION_MAJOR   1
 Current database version major.
#define DB_VERSION_MAJOR   1
 Current database version major. More...
 
-#define DB_VERSION_MINOR   97
 Current database version minor.
#define DB_VERSION_MINOR   97
 Current database version minor. More...
 
-#define DB_MIN_VERSION_MAJOR   1
 Required database version major (required 1.95)
#define DB_MIN_VERSION_MAJOR   1
 Required database version major (required 1.95) More...
 
-#define DB_MIN_VERSION_MINOR   97
 Required database version minor (required 1.95)
#define DB_MIN_VERSION_MINOR   97
 Required database version minor (required 1.95) More...
 
- - + - - + + - - + + - + - - + + - - + +

+

Typedefs

-typedef enum RESULTCODE RESULTCODE
+typedef enum RESULTCODE RESULTCODE
 RESULTCODE of transcoding operation.
 
-typedef RESULTCODE const * LPCRESULTCODE
 Pointer version of RESULTCODE.
typedef RESULTCODE const * LPCRESULTCODE
 Pointer version of RESULTCODE. More...
 
-typedef RESULTCODELPRESULTCODE
 Pointer to const version of RESULTCODE.
typedef RESULTCODELPRESULTCODE
 Pointer to const version of RESULTCODE. More...
 
-typedef struct CACHE_INFO CACHE_INFO
+typedef struct CACHE_INFO CACHE_INFO
 Cache information block.
 
-typedef CACHE_INFO const * LPCCACHE_INFO
 Pointer version of CACHE_INFO.
typedef CACHE_INFO const * LPCCACHE_INFO
 Pointer version of CACHE_INFO. More...
 
-typedef CACHE_INFOLPCACHE_INFO
 Pointer to const version of CACHE_INFO.
typedef CACHE_INFOLPCACHE_INFO
 Pointer to const version of CACHE_INFO. More...
 
-

+

Enumerations

enum  RESULTCODE { RESULTCODE_NONE , RESULTCODE_FINISHED_INCOMPLETE @@ -196,13 +185,195 @@
 

Detailed Description

-

Data cache management.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

Data cache management.

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file cache.h.

-

Enumeration Type Documentation

- +

Macro Definition Documentation

+ +

◆ DB_BASE_VERSION_MAJOR

+ +
+
+ + + + +
#define DB_BASE_VERSION_MAJOR   1
+
+ +

The oldest database version major (Release < 1.95)

+ +

Definition at line 42 of file cache.h.

+ +
+
+ +

◆ DB_BASE_VERSION_MINOR

+ +
+
+ + + + +
#define DB_BASE_VERSION_MINOR   0
+
+ +

The oldest database version minor (Release < 1.95)

+ +

Definition at line 43 of file cache.h.

+ +
+
+ +

◆ DB_MIN_VERSION_MAJOR

+ +
+
+ + + + +
#define DB_MIN_VERSION_MAJOR   1
+
+ +

Required database version major (required 1.95)

+ +

Definition at line 48 of file cache.h.

+ +
+
+ +

◆ DB_MIN_VERSION_MINOR

+ +
+
+ + + + +
#define DB_MIN_VERSION_MINOR   97
+
+ +

Required database version minor (required 1.95)

+ +

Definition at line 49 of file cache.h.

+ +
+
+ +

◆ DB_VERSION_MAJOR

+ +
+
+ + + + +
#define DB_VERSION_MAJOR   1
+
+ +

Current database version major.

+ +

Definition at line 45 of file cache.h.

+ +
+
+ +

◆ DB_VERSION_MINOR

+ +
+
+ + + + +
#define DB_VERSION_MINOR   97
+
+ +

Current database version minor.

+ +

Definition at line 46 of file cache.h.

+ +
+
+

Typedef Documentation

+ +

◆ LPCACHE_INFO

+ +
+
+ + + + +
typedef CACHE_INFO* LPCACHE_INFO
+
+ +

Pointer to const version of CACHE_INFO.

+ +

Definition at line 94 of file cache.h.

+ +
+
+ +

◆ LPCCACHE_INFO

+ +
+
+ + + + +
typedef CACHE_INFO const* LPCCACHE_INFO
+
+ +

Pointer version of CACHE_INFO.

+ +

Definition at line 93 of file cache.h.

+ +
+
+ +

◆ LPCRESULTCODE

+ +
+
+ + + + +
typedef RESULTCODE const* LPCRESULTCODE
+
+ +

Pointer version of RESULTCODE.

+ +

Definition at line 61 of file cache.h.

+ +
+
+ +

◆ LPRESULTCODE

+ +
+
+ + + + +
typedef RESULTCODE* LPRESULTCODE
+
+ +

Pointer to const version of RESULTCODE.

+ +

Definition at line 62 of file cache.h.

+ +
+
+

Enumeration Type Documentation

+

◆ RESULTCODE

@@ -216,13 +387,13 @@

-EnumeratorRESULTCODE_NONE 

No result code available.

+EnumeratorRESULTCODE_NONE 

No result code available.

-RESULTCODE_FINISHED_INCOMPLETE 

Transcode finished, but incomplete.

+RESULTCODE_FINISHED_INCOMPLETE 

Transcode finished, but incomplete.

-RESULTCODE_FINISHED_SUCCESS 

Transcode finished successfully.

+RESULTCODE_FINISHED_SUCCESS 

Transcode finished successfully.

-RESULTCODE_FINISHED_ERROR 

Transcode finished with error.

+RESULTCODE_FINISHED_ERROR 

Transcode finished with error.

@@ -233,7 +404,7 @@

diff --git a/html/cache_8h__dep__incl.png b/html/cache_8h__dep__incl.png index 9a6959e9de6312035c315e2a7f6ae71c2151431d..e225ad5b80b1633c614aaed408acd7e06778f82f 100644 GIT binary patch literal 17304 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 NhYudf7D}7E`5%t!QBVK? literal 17304 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 JP{Ppf{{TK - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache.h Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache.h
+
cache.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
32 #ifndef CACHE_H
-
33 #define CACHE_H
-
34 
-
35 #pragma once
-
36 
-
37 #include "buffer.h"
-
38 
-
39 #include <map>
-
40 #include <sqlite3.h>
-
41 
-
42 #define DB_BASE_VERSION_MAJOR 1
-
43 #define DB_BASE_VERSION_MINOR 0
-
45 #define DB_VERSION_MAJOR 1
-
46 #define DB_VERSION_MINOR 97
-
48 #define DB_MIN_VERSION_MAJOR 1
-
49 #define DB_MIN_VERSION_MINOR 97
-
54 typedef enum RESULTCODE
-
55 {
- - - - - -
61 typedef RESULTCODE const *LPCRESULTCODE;
- -
67 typedef struct CACHE_INFO
-
68 {
-
69  std::string m_origfile;
-
70  std::string m_destfile;
-
71  char m_desttype[11];
-
72  int64_t m_audiobitrate;
- -
74  int64_t m_videobitrate;
- - - -
78  int64_t m_duration;
- - - -
82  uint32_t m_segment_count;
- -
84  bool m_error;
-
85  int m_errno;
-
86  int m_averror;
-
87  time_t m_creation_time;
-
88  time_t m_access_time;
-
89  time_t m_file_time;
-
90  size_t m_file_size;
-
91  unsigned int m_access_count;
- -
93 typedef CACHE_INFO const *LPCCACHE_INFO;
- -
96 class Cache_Entry;
-
97 
-
101 class Cache
-
102 {
-
103  typedef std::pair<std::string, std::string> cache_key_t;
-
104  typedef std::map<cache_key_t, Cache_Entry *> cache_t;
-
105 public:
-
109  typedef struct
-
110  {
-
111  const char * name;
-
112  const char * primary_key;
-
113  } TABLE_DEF;
-
114  typedef TABLE_DEF const *LPCTABLE_DEF;
- -
120  typedef struct
-
121  {
-
122  const char * name;
-
123  const char * type;
-
124  } TABLE_COLUMNS;
- - -
128  typedef std::vector<TABLE_COLUMNS> TABLECOLUMNS_VEC;
- - -
132  friend class Cache_Entry;
-
133 
-
134 public:
-
138  explicit Cache();
-
142  virtual ~Cache();
- -
161  bool closeio(Cache_Entry **cache_entry, int flags = CACHE_CLOSE_NOOPT);
-
166  bool load_index();
-
167 #ifdef HAVE_SQLITE_CACHEFLUSH
-
172  bool flush_index();
-
173 #endif // HAVE_SQLITE_CACHEFLUSH
-
183  bool maintenance(size_t predicted_filesize = 0);
-
188  bool clear();
-
193  bool prune_expired();
-
198  bool prune_cache_size();
-
203  bool prune_disk_space(size_t predicted_filesize);
-
210  bool remove_cachefile(const std::string & filename, const std::string &fileext);
-
211 
-
212 protected:
-
218  bool read_info(LPCACHE_INFO cache_info);
-
224  bool write_info(LPCCACHE_INFO cache_info);
-
231  bool delete_info(const std::string & filename, const std::string & desttype);
-
238  Cache_Entry* create_entry(LPVIRTUALFILE virtualfile, const std::string & desttype);
-
245  bool delete_entry(Cache_Entry **cache_entry, int flags);
-
249  void close_index();
-
255  std::string expanded_sql(sqlite3_stmt *pStmt);
-
260  bool prepare_stmts();
-
266  bool table_exists(const char *table);
-
273  bool column_exists(const char *table, const char *column);
-
280  bool check_min_version(int *db_version_major, int *db_version_minor);
-
289  int cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r);
-
294  bool begin_transaction();
-
299  bool end_transaction();
-
304  bool rollback_transaction();
-
309  bool create_table_cache_entry(LPCTABLE_DEF table, const TABLECOLUMNS_VEC & columns);
-
310  /*
-
311  */
-
318  bool upgrade_db(int *db_version_major, int *db_version_minor);
-
319 
-
320 private:
-
321  static const
- -
323  static const
- -
325  static const
- -
327  static const
- -
330  std::recursive_mutex m_mutex;
-
331  std::string m_cacheidx_file;
-
332  sqlite3* m_cacheidx_db;
-
333  sqlite3_stmt * m_cacheidx_select_stmt;
-
334  sqlite3_stmt * m_cacheidx_insert_stmt;
-
335  sqlite3_stmt * m_cacheidx_delete_stmt;
- -
337 };
-
338 
-
339 #endif
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
32#ifndef CACHE_H
+
33#define CACHE_H
+
34
+
35#pragma once
+
36
+
37#include "buffer.h"
+
38
+
39#include <map>
+
40#include <sqlite3.h>
+
41
+
42#define DB_BASE_VERSION_MAJOR 1
+
43#define DB_BASE_VERSION_MINOR 0
+
45#define DB_VERSION_MAJOR 1
+
46#define DB_VERSION_MINOR 97
+
48#define DB_MIN_VERSION_MAJOR 1
+
49#define DB_MIN_VERSION_MINOR 97
+
54typedef enum RESULTCODE
+
55{
+ + + + + +
61typedef RESULTCODE const *LPCRESULTCODE;
+ +
67typedef struct CACHE_INFO
+
68{
+
69 std::string m_origfile;
+
70 std::string m_destfile;
+
71 char m_desttype[11];
+ + + + + + +
78 int64_t m_duration;
+ + + +
82 uint32_t m_segment_count;
+ +
84 bool m_error;
+
85 int m_errno;
+ + + +
89 time_t m_file_time;
+
90 size_t m_file_size;
+
91 unsigned int m_access_count;
+ +
93typedef CACHE_INFO const *LPCCACHE_INFO;
+ +
96class Cache_Entry;
+
97
+
101class Cache
+
102{
+
103 typedef std::pair<std::string, std::string> cache_key_t;
+
104 typedef std::map<cache_key_t, Cache_Entry *> cache_t;
+
105public:
+
109 typedef struct
+
110 {
+
111 const char * name;
+
112 const char * primary_key;
+
113 } TABLE_DEF;
+
114 typedef TABLE_DEF const *LPCTABLE_DEF;
+ +
120 typedef struct
+
121 {
+
122 const char * name;
+
123 const char * type;
+ + + +
128 typedef std::vector<TABLE_COLUMNS> TABLECOLUMNS_VEC;
+ + +
132 friend class Cache_Entry;
+
133
+
134public:
+
138 explicit Cache();
+
142 virtual ~Cache();
+ +
161 bool closeio(Cache_Entry **cache_entry, int flags = CACHE_CLOSE_NOOPT);
+
166 bool load_index();
+
167#ifdef HAVE_SQLITE_CACHEFLUSH
+
172 bool flush_index();
+
173#endif // HAVE_SQLITE_CACHEFLUSH
+
183 bool maintenance(size_t predicted_filesize = 0);
+
188 bool clear();
+
193 bool prune_expired();
+
198 bool prune_cache_size();
+
203 bool prune_disk_space(size_t predicted_filesize);
+
210 bool remove_cachefile(const std::string & filename, const std::string &fileext);
+
211
+
212protected:
+
218 bool read_info(LPCACHE_INFO cache_info);
+
224 bool write_info(LPCCACHE_INFO cache_info);
+
231 bool delete_info(const std::string & filename, const std::string & desttype);
+
238 Cache_Entry* create_entry(LPVIRTUALFILE virtualfile, const std::string & desttype);
+
245 bool delete_entry(Cache_Entry **cache_entry, int flags);
+
249 void close_index();
+
255 std::string expanded_sql(sqlite3_stmt *pStmt);
+
260 bool prepare_stmts();
+
266 bool table_exists(const char *table);
+
273 bool column_exists(const char *table, const char *column);
+
280 bool check_min_version(int *db_version_major, int *db_version_minor);
+
289 int cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r);
+
294 bool begin_transaction();
+
299 bool end_transaction();
+ +
309 bool create_table_cache_entry(LPCTABLE_DEF table, const TABLECOLUMNS_VEC & columns);
+
310 /*
+
311 */
+
318 bool upgrade_db(int *db_version_major, int *db_version_minor);
+
319
+
320private:
+
321 static const
+ +
323 static const
+ +
325 static const
+ +
327 static const
+ +
330 std::recursive_mutex m_mutex;
+
331 std::string m_cacheidx_file;
+
332 sqlite3* m_cacheidx_db;
+
333 sqlite3_stmt * m_cacheidx_select_stmt;
+
334 sqlite3_stmt * m_cacheidx_insert_stmt;
+
335 sqlite3_stmt * m_cacheidx_delete_stmt;
+ +
337};
+
338
+
339#endif
Buffer class.
#define CACHE_CLOSE_NOOPT
Dummy, do nothing special.
Definition: buffer.h:45
RESULTCODE * LPRESULTCODE
Pointer to const version of RESULTCODE.
Definition: cache.h:62
@@ -239,53 +238,53 @@
CACHE_INFO const * LPCCACHE_INFO
Pointer version of CACHE_INFO.
Definition: cache.h:93
struct CACHE_INFO CACHE_INFO
Cache information block.
The Cache_Entry class.
Definition: cache_entry.h:49
-
LPVIRTUALFILE virtualfile()
Get the underlying VIRTUALFILE object.
Definition: cache_entry.cc:420
-
const char * filename() const
Return source filename.
Definition: cache_entry.cc:311
+
LPVIRTUALFILE virtualfile()
Get the underlying VIRTUALFILE object.
Definition: cache_entry.cc:422
+
const char * filename() const
Return source filename.
Definition: cache_entry.cc:313
The Cache class.
Definition: cache.h:102
-
Cache_Entry * openio(LPVIRTUALFILE virtualfile)
Open cache entry.
Definition: cache.cc:1041
+
Cache_Entry * openio(LPVIRTUALFILE virtualfile)
Open cache entry.
Definition: cache.cc:1054
static const TABLECOLUMNS_VEC m_columns_cache_entry
Columns of table "cache_entry".
Definition: cache.h:324
-
bool prune_disk_space(size_t predicted_filesize)
Prune cache entries to ensure disk space.
Definition: cache.cc:1223
-
bool delete_info(const std::string &filename, const std::string &desttype)
Delete cache file info.
Definition: cache.cc:932
-
bool delete_entry(Cache_Entry **cache_entry, int flags)
Delete cache entry object.
Definition: cache.cc:1017
+
bool prune_disk_space(size_t predicted_filesize)
Prune cache entries to ensure disk space.
Definition: cache.cc:1236
+
bool delete_info(const std::string &filename, const std::string &desttype)
Delete cache file info.
Definition: cache.cc:945
+
bool delete_entry(Cache_Entry **cache_entry, int flags)
Delete cache entry object.
Definition: cache.cc:1030
sqlite3 * m_cacheidx_db
SQLite handle of cache index database.
Definition: cache.h:332
TABLECOLUMNS_VEC * LPTABLECOLUMNS_VEC
Pointer to const version of TABLECOLUMNS_VEC.
Definition: cache.h:130
sqlite3_stmt * m_cacheidx_insert_stmt
Prepared insert statement.
Definition: cache.h:334
int cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r)
Compare two versions.
Definition: cache.cc:252
-
bool create_table_cache_entry(LPCTABLE_DEF table, const TABLECOLUMNS_VEC &columns)
Create cache_entry table.
Definition: cache.cc:314
-
bool clear()
Clear cache: deletes all entries.
Definition: cache.cc:1331
+
bool create_table_cache_entry(LPCTABLE_DEF table, const TABLECOLUMNS_VEC &columns)
Create cache_entry table.
Definition: cache.cc:327
+
bool clear()
Clear cache: deletes all entries.
Definition: cache.cc:1344
cache_t m_cache
Cache file (memory mapped file)
Definition: cache.h:336
bool prepare_stmts()
Prepare all SQL statements.
Definition: cache.cc:131
-
bool remove_cachefile(const std::string &filename, const std::string &fileext)
Remove a cache file from disk.
Definition: cache.cc:1384
+
bool remove_cachefile(const std::string &filename, const std::string &fileext)
Remove a cache file from disk.
Definition: cache.cc:1397
Cache()
Construct Cache object.
Definition: cache.cc:110
TABLE_COLUMNS * LPTABLE_COLUMNS
Pointer to const version of TABLE_COLUMNS.
Definition: cache.h:126
std::map< cache_key_t, Cache_Entry * > cache_t
Map of cache entries.
Definition: cache.h:104
std::vector< TABLE_COLUMNS > TABLECOLUMNS_VEC
Table columns array.
Definition: cache.h:128
sqlite3_stmt * m_cacheidx_delete_stmt
Prepared delete statement.
Definition: cache.h:335
-
std::string expanded_sql(sqlite3_stmt *pStmt)
Get expanded SQL string for a statement.
Definition: cache.cc:1403
+
std::string expanded_sql(sqlite3_stmt *pStmt)
Get expanded SQL string for a statement.
Definition: cache.cc:1416
TABLE_DEF const * LPCTABLE_DEF
Pointer version of TABLE_DEF.
Definition: cache.h:114
-
bool load_index()
Load cache index from disk.
Definition: cache.cc:574
-
bool write_info(LPCCACHE_INFO cache_info)
Write cache file info.
Definition: cache.cc:866
+
bool load_index()
Load cache index from disk.
Definition: cache.cc:587
+
bool write_info(LPCCACHE_INFO cache_info)
Write cache file info.
Definition: cache.cc:879
std::pair< std::string, std::string > cache_key_t
Filenames and destination types.
Definition: cache.h:103
static const TABLECOLUMNS_VEC m_columns_version
Columns of table "version".
Definition: cache.h:328
static const TABLE_DEF m_table_version
Definition and indexes of table "version".
Definition: cache.h:326
std::string m_cacheidx_file
Name of SQLite cache index database.
Definition: cache.h:331
-
bool rollback_transaction()
Rollback a database transaction.
Definition: cache.cc:298
-
void close_index()
Close cache index.
Definition: cache.cc:985
-
bool begin_transaction()
Begin a database transactio.n.
Definition: cache.cc:266
+
bool rollback_transaction()
Rollback a database transaction.
Definition: cache.cc:311
+
void close_index()
Close cache index.
Definition: cache.cc:998
+
bool begin_transaction()
Begin a database transactio.n.
Definition: cache.cc:279
sqlite3_stmt * m_cacheidx_select_stmt
Prepared select statement.
Definition: cache.h:333
-
bool read_info(LPCACHE_INFO cache_info)
Read cache file info.
Definition: cache.cc:739
+
bool read_info(LPCACHE_INFO cache_info)
Read cache file info.
Definition: cache.cc:752
bool table_exists(const char *table)
Check if SQL table exists in database.
Definition: cache.cc:165
-
bool end_transaction()
End a database transaction.
Definition: cache.cc:282
-
bool upgrade_db(int *db_version_major, int *db_version_minor)
Upgrade database from version below 1.95.
Definition: cache.cc:354
-
bool prune_cache_size()
Prune cache entries to keep cache size within limit.
Definition: cache.cc:1145
+
bool end_transaction()
End a database transaction.
Definition: cache.cc:295
+
bool upgrade_db(int *db_version_major, int *db_version_minor)
Upgrade database from version below 1.95.
Definition: cache.cc:367
+
bool prune_cache_size()
Prune cache entries to keep cache size within limit.
Definition: cache.cc:1158
std::recursive_mutex m_mutex
Access mutex.
Definition: cache.h:330
-
bool closeio(Cache_Entry **cache_entry, int flags=CACHE_CLOSE_NOOPT)
Close a cache entry.
Definition: cache.cc:1059
+
bool closeio(Cache_Entry **cache_entry, int flags=CACHE_CLOSE_NOOPT)
Close a cache entry.
Definition: cache.cc:1072
TABLE_DEF * LPTABLE_DEF
Pointer to const version of TABLE_DEF.
Definition: cache.h:115
TABLECOLUMNS_VEC const * LPCTABLECOLUMNS_VEC
Pointer version of TABLECOLUMNS_VEC.
Definition: cache.h:129
TABLE_COLUMNS const * LPCTABLE_COLUMNS
Pointer version of TABLE_COLUMNS.
Definition: cache.h:125
-
Cache_Entry * create_entry(LPVIRTUALFILE virtualfile, const std::string &desttype)
Create cache entry object for a VIRTUALFILE.
Definition: cache.cc:1002
+
Cache_Entry * create_entry(LPVIRTUALFILE virtualfile, const std::string &desttype)
Create cache entry object for a VIRTUALFILE.
Definition: cache.cc:1015
bool column_exists(const char *table, const char *column)
Check if column exists in SQL table.
Definition: cache.cc:194
-
bool prune_expired()
Prune expired cache entries.
Definition: cache.cc:1083
+
bool prune_expired()
Prune expired cache entries.
Definition: cache.cc:1096
bool check_min_version(int *db_version_major, int *db_version_minor)
Check the db version if upgrade needed.
Definition: cache.cc:225
virtual ~Cache()
Destruct Cache object.
Definition: cache.cc:118
static const TABLE_DEF m_table_cache_entry
Definition and indexes of table "cache_entry".
Definition: cache.h:322
@@ -323,7 +322,7 @@
diff --git a/html/cache__entry_8cc.html b/html/cache__entry_8cc.html index acee1c82b..e9768fc09 100644 --- a/html/cache__entry_8cc.html +++ b/html/cache__entry_8cc.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache_entry.cc File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache_entry.cc File Reference
+
cache_entry.cc File Reference
@@ -118,15 +117,15 @@

Go to the source code of this file.

Detailed Description

- diff --git a/html/cache__entry_8cc__incl.png b/html/cache__entry_8cc__incl.png index e42b6eeb89014cb91471b0c557823ed92be20028..823c9d524f781559e0f4b9e55f164cbb6d9f1aa0 100644 GIT binary patch delta 54207 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
9s|E}I9A3XZ08f7broH{r(JKpL8PVS6u% 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 J&#eZ@-#DYZ@oKHyCO9n$G$Z*>yl%X9S2S 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

GZ_JAkU*|bP5Uz9vRicuiE8n8yl}Z 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 diff --git a/html/cache__entry_8cc_source.html b/html/cache__entry_8cc_source.html index 930ed9432..f51f71ce0 100644 --- a/html/cache__entry_8cc_source.html +++ b/html/cache__entry_8cc_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache_entry.cc Source File @@ -19,10 +19,9 @@

- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache_entry.cc
+
cache_entry.cc
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
32 #include "cache_entry.h"
-
33 #include "ffmpegfs.h"
-
34 #include "buffer.h"
-
35 #include "logging.h"
-
36 
-
37 #include <cstring>
-
38 
- -
40  : m_owner(owner)
-
41  , m_ref_count(0)
-
42  , m_virtualfile(virtualfile)
-
43  , m_seek_to_no(0)
-
44 {
- - -
47 
-
48  m_cache_info.m_desttype[0] = '\0';
- -
50 
-
51  m_buffer = new(std::nothrow) Buffer;
-
52 
-
53  if (m_buffer != nullptr)
-
54  {
- -
56  }
-
57 
-
58  clear();
-
59 
-
60  Logging::trace(filename(), "Created a new cache entry.");
-
61 }
-
62 
- -
64 {
-
65  std::unique_lock<std::recursive_mutex> lock_active_mutex(m_active_mutex);
-
66 
-
67  delete m_buffer;
-
68 
-
69  unlock();
-
70 
-
71  Logging::trace(filename(), "Deleted buffer.");
-
72 }
-
73 
- -
75 {
-
76  return new(std::nothrow) Cache_Entry(owner, virtualfile);
-
77 }
-
78 
- -
80 {
-
81  delete this;
-
82  return true;
-
83 }
-
84 
-
85 void Cache_Entry::clear(bool fetch_file_time /*= true*/)
-
86 {
-
87  m_is_decoding = false;
-
88 
-
89  // Initialise ID3v1.1 tag structure
- -
91 
-
92  //m_cache_info.m_enable_ismv = params.m_enable_ismv;
- - - - - - - - - - -
103  m_cache_info.m_error = false;
-
104  m_cache_info.m_errno = 0;
- - - -
108 
-
109  if (fetch_file_time)
-
110  {
-
111  struct stat sb;
-
112 
-
113  if (stat(filename(), &sb) == -1)
-
114  {
- - -
117  }
-
118  else
-
119  {
-
120  m_cache_info.m_file_time = sb.st_mtime;
-
121  m_cache_info.m_file_size = static_cast<size_t>(sb.st_size);
-
122  }
-
123  }
-
124 
-
125  if (m_buffer != nullptr)
-
126  {
-
127  m_buffer->clear();
-
128  }
-
129 }
-
130 
- -
132 {
-
133  return m_owner->read_info(&m_cache_info);
-
134 }
-
135 
- -
137 {
-
138  return m_owner->write_info(&m_cache_info);
-
139 }
-
140 
- -
142 {
- -
144 }
-
145 
-
146 bool Cache_Entry::update_access(bool update_database /*= false*/)
-
147 {
-
148  m_cache_info.m_access_time = time(nullptr);
-
149 
-
150  if (update_database)
-
151  {
-
152  return m_owner->write_info(&m_cache_info);
-
153  }
-
154  else
-
155  {
-
156  return true;
-
157  }
-
158 }
-
159 
-
160 bool Cache_Entry::openio(bool create_cache /*= true*/)
-
161 {
-
162  if (m_buffer == nullptr)
-
163  {
-
164  errno = EINVAL;
-
165  return false;
-
166  }
-
167 
-
168  if (m_ref_count++ > 0) // fetch_and_add
-
169  {
-
170  // Already open
-
171  return true;
-
172  }
-
173 
-
174  bool erase_cache = !read_info(); // If read_info fails, rebuild cache entry
-
175 
-
176  if (!create_cache)
-
177  {
-
178  return true;
-
179  }
-
180 
-
181  if (!is_finished())
-
182  {
-
183  // If no database entry found (database is not consistent),
-
184  // or file was not completely transcoded last time,
-
185  // simply create a new file.
-
186  erase_cache = true;
-
187  }
-
188 
-
189  Logging::trace(filename(), "The last transcode was completed. Result %1 Erasing cache: %2.", m_cache_info.m_result, erase_cache);
-
190 
-
191  // Store access time
-
192  update_access(true);
-
193 
-
194  // Open the cache
-
195  if (m_buffer->init(erase_cache))
-
196  {
-
197  return true;
-
198  }
-
199  else
-
200  {
-
201  clear(false);
-
202  return false;
-
203  }
-
204 }
-
205 
- -
207 {
-
208  if (m_buffer->release(flags))
-
209  {
-
210  if (flags)
-
211  {
-
212  delete_info();
-
213  }
-
214  }
-
215 }
-
216 
-
217 bool Cache_Entry::closeio(int flags)
-
218 {
-
219  write_info();
-
220 
-
221  if (m_buffer == nullptr)
-
222  {
-
223  errno = EINVAL;
-
224  return false;
-
225  }
-
226 
-
227  if (!m_ref_count)
-
228  {
-
229  close_buffer(flags);
-
230 
-
231  return true;
-
232  }
-
233 
-
234  if (--m_ref_count > 0) // sub_and_fetch
-
235  {
-
236  // Just flush to disk
-
237  flush();
-
238  return false;
-
239  }
-
240 
-
241  close_buffer(flags);
-
242 
-
243  return true;
-
244 }
-
245 
- -
247 {
-
248  if (m_buffer == nullptr)
-
249  {
-
250  errno = EINVAL;
-
251  return false;
-
252  }
-
253 
-
254  m_buffer->flush();
-
255  //write_info();
-
256 
-
257  return true;
-
258 }
-
259 
-
260 size_t Cache_Entry::size() const
-
261 {
- -
263  {
- -
265  }
-
266  else
-
267  {
-
268  if (m_buffer == nullptr)
-
269  {
- -
271  }
-
272  else
-
273  {
-
274  size_t current_size = m_buffer->buffer_watermark();
-
275 
-
276  return std::max(current_size, m_cache_info.m_predicted_filesize);
-
277  }
-
278  }
-
279 }
-
280 
- -
282 {
- -
284 }
-
285 
-
286 time_t Cache_Entry::age() const
-
287 {
-
288  return (time(nullptr) - m_cache_info.m_creation_time);
-
289 }
-
290 
- -
292 {
- -
294 }
-
295 
- -
297 {
-
298  return (age() > params.m_expiry_time);
-
299 }
-
300 
- -
302 {
-
303  return (((time(nullptr) - m_cache_info.m_access_time) >= params.m_max_inactive_suspend) && m_ref_count <= 1);
-
304 }
-
305 
- -
307 {
-
308  return (((time(nullptr) - m_cache_info.m_access_time) >= params.m_max_inactive_abort) && m_ref_count <= 1);
-
309 }
-
310 
-
311 const char * Cache_Entry::filename() const
-
312 {
-
313  return (m_virtualfile != nullptr ? m_virtualfile->m_origfile.c_str() : "");
-
314 }
-
315 
-
316 const char *Cache_Entry::destname() const
-
317 {
-
318  return (m_virtualfile != nullptr ? m_virtualfile->m_destfile.c_str() : "");
-
319 }
-
320 
-
321 const char * Cache_Entry::virtname() const
-
322 {
-
323  return (m_virtualfile != nullptr ? m_virtualfile->m_virtfile.c_str() : "");
-
324 }
-
325 
- -
327 {
-
328  m_mutex.lock();
-
329 }
-
330 
- -
332 {
-
333  m_mutex.unlock();
-
334 }
-
335 
- -
337 {
-
338  return m_ref_count;
-
339 }
-
340 
- -
342 {
-
343  return m_ref_count++; // fetch_and_add
-
344 }
-
345 
- -
347 {
-
348  return --m_ref_count; // sub_and_fetch
-
349 }
-
350 
- -
352 {
-
353  struct stat sb;
-
354 
- -
356  {
- -
358  {
-
359  // Report if old rate is known
-
360  Logging::debug(filename(), "Triggering re-transcode: Selected audio bitrate changed from %1 to %2.", m_cache_info.m_audiobitrate, params.m_audiobitrate);
-
361  }
-
362  return true;
-
363  }
-
364 
- -
366  {
- -
368  {
-
369  // Report if old rate is known
-
370  Logging::debug(filename(), "Triggering re-transcode: Selected audio samplerate changed from %1 to %2.", m_cache_info.m_audiosamplerate, params.m_audiosamplerate);
-
371  }
-
372  return true;
-
373  }
-
374 
- -
376  {
- -
378  {
-
379  // Report if old rate is known
-
380  Logging::debug(filename(), "Triggering re-transcode: Selected video bitrate changed from %1 to %2.", m_cache_info.m_audiobitrate, params.m_audiobitrate);
-
381  }
-
382  return true;
-
383  }
-
384 
- -
386  {
- -
388  {
-
389  // Report if old dimensions is known
-
390  Logging::debug(filename(), "Triggering re-transcode: Selected video witdh/height changed from %1/%2 to %3/%4.", m_cache_info.m_videowidth, m_cache_info.m_videoheight, params.m_videowidth, params.m_videoheight);
-
391  }
-
392  return true;
-
393  }
-
394 
-
395  if (m_cache_info.m_deinterlace != (params.m_deinterlace ? true : false))
-
396  {
-
397  Logging::debug(filename(), "Triggering re-transcode: Selected video deinterlace changed from %1 to %2.", m_cache_info.m_deinterlace, params.m_deinterlace);
-
398  return true;
-
399  }
-
400 
-
401  if (stat(filename(), &sb) != -1)
-
402  {
-
403  // If source file exists, check file date/size
-
404  if (m_cache_info.m_file_time < sb.st_mtime)
-
405  {
-
406  Logging::debug(filename(), "Triggering re-transcode: File time has gone forward.");
-
407  return true;
-
408  }
-
409 
-
410  if (m_cache_info.m_file_size != static_cast<size_t>(sb.st_size))
-
411  {
-
412  Logging::debug(filename(), "Triggering re-transcode: File size has changed.");
-
413  return true;
-
414  }
-
415  }
-
416 
-
417  return false;
-
418 }
-
419 
- -
421 {
-
422  return m_virtualfile;
-
423 }
-
424 
- -
426 {
- -
428 }
-
429 
-
430 unsigned int Cache_Entry::read_count() const
-
431 {
- -
433 }
-
434 
- -
436 {
- -
438 }
-
439 
- -
441 {
- -
443 }
-
444 
- -
446 {
- -
448 }
-
449 
- -
451 {
- -
453 }
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
32#include "cache_entry.h"
+
33#include "ffmpegfs.h"
+
34#include "buffer.h"
+
35#include "logging.h"
+
36
+
37#include <cstring>
+
38
+ +
40 : m_owner(owner)
+
41 , m_ref_count(0)
+
42 , m_virtualfile(virtualfile)
+
43 , m_is_decoding(false)
+
44 , m_suspend_timeout(false)
+
45 , m_seek_to_no(0)
+
46{
+ + +
49
+
50 m_cache_info.m_desttype[0] = '\0';
+ +
52
+
53 m_buffer = new(std::nothrow) Buffer;
+
54
+
55 if (m_buffer != nullptr)
+
56 {
+ +
58 }
+
59
+
60 clear();
+
61
+
62 Logging::trace(filename(), "Created a new cache entry.");
+
63}
+
64
+ +
66{
+
67 std::unique_lock<std::recursive_mutex> lock_active_mutex(m_active_mutex);
+
68
+
69 delete m_buffer;
+
70
+
71 unlock();
+
72
+
73 Logging::trace(filename(), "Deleted buffer.");
+
74}
+
75
+ +
77{
+
78 return new(std::nothrow) Cache_Entry(owner, virtualfile);
+
79}
+
80
+ +
82{
+
83 delete this;
+
84 return true;
+
85}
+
86
+
87void Cache_Entry::clear(bool fetch_file_time /*= true*/)
+
88{
+
89 m_is_decoding = false;
+
90
+
91 // Initialise ID3v1.1 tag structure
+ +
93
+
94 //m_cache_info.m_enable_ismv = params.m_enable_ismv;
+ + + + + + + + + + +
105 m_cache_info.m_error = false;
+ + + + +
110
+
111 if (fetch_file_time)
+
112 {
+
113 struct stat sb;
+
114
+
115 if (stat(filename(), &sb) == -1)
+
116 {
+ + +
119 }
+
120 else
+
121 {
+
122 m_cache_info.m_file_time = sb.st_mtime;
+
123 m_cache_info.m_file_size = static_cast<size_t>(sb.st_size);
+
124 }
+
125 }
+
126
+
127 if (m_buffer != nullptr)
+
128 {
+
129 m_buffer->clear();
+
130 }
+
131}
+
132
+ +
134{
+ +
136}
+
137
+ +
139{
+ +
141}
+
142
+ +
144{
+ +
146}
+
147
+
148bool Cache_Entry::update_access(bool update_database /*= false*/)
+
149{
+
150 m_cache_info.m_access_time = time(nullptr);
+
151
+
152 if (update_database)
+
153 {
+ +
155 }
+
156 else
+
157 {
+
158 return true;
+
159 }
+
160}
+
161
+
162bool Cache_Entry::openio(bool create_cache /*= true*/)
+
163{
+
164 if (m_buffer == nullptr)
+
165 {
+
166 errno = EINVAL;
+
167 return false;
+
168 }
+
169
+
170 if (m_ref_count++ > 0) // fetch_and_add
+
171 {
+
172 // Already open
+
173 return true;
+
174 }
+
175
+
176 bool erase_cache = !read_info(); // If read_info fails, rebuild cache entry
+
177
+
178 if (!create_cache)
+
179 {
+
180 return true;
+
181 }
+
182
+
183 if (!is_finished())
+
184 {
+
185 // If no database entry found (database is not consistent),
+
186 // or file was not completely transcoded last time,
+
187 // simply create a new file.
+
188 erase_cache = true;
+
189 }
+
190
+
191 Logging::trace(filename(), "The last transcode was completed. Result %1 Erasing cache: %2.", m_cache_info.m_result, erase_cache);
+
192
+
193 // Store access time
+
194 update_access(true);
+
195
+
196 // Open the cache
+
197 if (m_buffer->init(erase_cache))
+
198 {
+
199 return true;
+
200 }
+
201 else
+
202 {
+
203 clear(false);
+
204 return false;
+
205 }
+
206}
+
207
+ +
209{
+
210 if (m_buffer->release(flags))
+
211 {
+
212 if (flags)
+
213 {
+
214 delete_info();
+
215 }
+
216 }
+
217}
+
218
+
219bool Cache_Entry::closeio(int flags)
+
220{
+
221 write_info();
+
222
+
223 if (m_buffer == nullptr)
+
224 {
+
225 errno = EINVAL;
+
226 return false;
+
227 }
+
228
+
229 if (!m_ref_count)
+
230 {
+
231 close_buffer(flags);
+
232
+
233 return true;
+
234 }
+
235
+
236 if (--m_ref_count > 0) // sub_and_fetch
+
237 {
+
238 // Just flush to disk
+
239 flush();
+
240 return false;
+
241 }
+
242
+
243 close_buffer(flags);
+
244
+
245 return true;
+
246}
+
247
+ +
249{
+
250 if (m_buffer == nullptr)
+
251 {
+
252 errno = EINVAL;
+
253 return false;
+
254 }
+
255
+
256 m_buffer->flush();
+
257 //write_info();
+
258
+
259 return true;
+
260}
+
261
+
262size_t Cache_Entry::size() const
+
263{
+ +
265 {
+ +
267 }
+
268 else
+
269 {
+
270 if (m_buffer == nullptr)
+
271 {
+ +
273 }
+
274 else
+
275 {
+
276 size_t current_size = m_buffer->buffer_watermark();
+
277
+
278 return std::max(current_size, m_cache_info.m_predicted_filesize);
+
279 }
+
280 }
+
281}
+
282
+ +
284{
+ +
286}
+
287
+
288time_t Cache_Entry::age() const
+
289{
+
290 return (time(nullptr) - m_cache_info.m_creation_time);
+
291}
+
292
+ +
294{
+ +
296}
+
297
+ +
299{
+
300 return (age() > params.m_expiry_time);
+
301}
+
302
+ +
304{
+
305 return (((time(nullptr) - m_cache_info.m_access_time) >= params.m_max_inactive_suspend) && m_ref_count <= 1);
+
306}
+
307
+ +
309{
+
310 return (((time(nullptr) - m_cache_info.m_access_time) >= params.m_max_inactive_abort) && m_ref_count <= 1);
+
311}
+
312
+
313const char * Cache_Entry::filename() const
+
314{
+
315 return (m_virtualfile != nullptr ? m_virtualfile->m_origfile.c_str() : "");
+
316}
+
317
+
318const char *Cache_Entry::destname() const
+
319{
+
320 return (m_virtualfile != nullptr ? m_virtualfile->m_destfile.c_str() : "");
+
321}
+
322
+
323const char * Cache_Entry::virtname() const
+
324{
+
325 return (m_virtualfile != nullptr ? m_virtualfile->m_virtfile.c_str() : "");
+
326}
+
327
+ +
329{
+
330 m_mutex.lock();
+
331}
+
332
+ +
334{
+
335 m_mutex.unlock();
+
336}
+
337
+ +
339{
+
340 return m_ref_count;
+
341}
+
342
+ +
344{
+
345 return m_ref_count++; // fetch_and_add
+
346}
+
347
+ +
349{
+
350 return --m_ref_count; // sub_and_fetch
+
351}
+
352
+ +
354{
+
355 struct stat sb;
+
356
+ +
358 {
+ +
360 {
+
361 // Report if old rate is known
+
362 Logging::debug(filename(), "Triggering re-transcode: Selected audio bitrate changed from %1 to %2.", m_cache_info.m_audiobitrate, params.m_audiobitrate);
+
363 }
+
364 return true;
+
365 }
+
366
+ +
368 {
+ +
370 {
+
371 // Report if old rate is known
+
372 Logging::debug(filename(), "Triggering re-transcode: Selected audio samplerate changed from %1 to %2.", m_cache_info.m_audiosamplerate, params.m_audiosamplerate);
+
373 }
+
374 return true;
+
375 }
+
376
+ +
378 {
+ +
380 {
+
381 // Report if old rate is known
+
382 Logging::debug(filename(), "Triggering re-transcode: Selected video bitrate changed from %1 to %2.", m_cache_info.m_audiobitrate, params.m_audiobitrate);
+
383 }
+
384 return true;
+
385 }
+
386
+ +
388 {
+ +
390 {
+
391 // Report if old dimensions is known
+
392 Logging::debug(filename(), "Triggering re-transcode: Selected video witdh/height changed from %1/%2 to %3/%4.", m_cache_info.m_videowidth, m_cache_info.m_videoheight, params.m_videowidth, params.m_videoheight);
+
393 }
+
394 return true;
+
395 }
+
396
+
397 if (m_cache_info.m_deinterlace != (params.m_deinterlace ? true : false))
+
398 {
+
399 Logging::debug(filename(), "Triggering re-transcode: Selected video deinterlace changed from %1 to %2.", m_cache_info.m_deinterlace, params.m_deinterlace);
+
400 return true;
+
401 }
+
402
+
403 if (stat(filename(), &sb) != -1)
+
404 {
+
405 // If source file exists, check file date/size
+
406 if (m_cache_info.m_file_time < sb.st_mtime)
+
407 {
+
408 Logging::debug(filename(), "Triggering re-transcode: File time has gone forward.");
+
409 return true;
+
410 }
+
411
+
412 if (m_cache_info.m_file_size != static_cast<size_t>(sb.st_size))
+
413 {
+
414 Logging::debug(filename(), "Triggering re-transcode: File size has changed.");
+
415 return true;
+
416 }
+
417 }
+
418
+
419 return false;
+
420}
+
421
+ +
423{
+
424 return m_virtualfile;
+
425}
+
426
+ +
428{
+ +
430}
+
431
+
432unsigned int Cache_Entry::read_count() const
+
433{
+ +
435}
+
436
+ +
438{
+ +
440}
+
441
+ +
443{
+ +
445}
+
446
+ +
448{
+ +
450}
+
451
+ +
453{
+ +
455}
Buffer class.
@ RESULTCODE_FINISHED_SUCCESS
Transcode finished successfully.
Definition: cache.h:58
@ RESULTCODE_NONE
No result code available.
Definition: cache.h:56
@@ -527,59 +528,59 @@
bool flush()
Flush buffer to disk.
Definition: buffer.cc:559
size_t buffer_watermark(uint32_t segment_no=0) const
Return the current watermark of the file while transcoding.
Definition: buffer.cc:865
The Cache_Entry class.
Definition: cache_entry.h:49
-
size_t size() const
Return size of output file, as computed by encoder.
Definition: cache_entry.cc:260
+
size_t size() const
Return size of output file, as computed by encoder.
Definition: cache_entry.cc:262
CACHE_INFO m_cache_info
Info about cached object.
Definition: cache_entry.h:277
-
bool update_access(bool update_database=false)
Update last access time.
Definition: cache_entry.cc:146
-
bool is_finished_error() const
Get if cache has been finished and with an error.
Definition: cache_entry.cc:450
+
bool update_access(bool update_database=false)
Update last access time.
Definition: cache_entry.cc:148
+
bool is_finished_error() const
Get if cache has been finished and with an error.
Definition: cache_entry.cc:452
Buffer * m_buffer
Buffer object.
Definition: cache_entry.h:271
-
static Cache_Entry * create(Cache *owner, LPVIRTUALFILE virtualfile)
Create a new Cache_Entry object.
Definition: cache_entry.cc:74
-
time_t age() const
Get the age of the cache entry.
Definition: cache_entry.cc:286
-
bool is_finished() const
Get if cache has been finished.
Definition: cache_entry.cc:435
+
static Cache_Entry * create(Cache *owner, LPVIRTUALFILE virtualfile)
Create a new Cache_Entry object.
Definition: cache_entry.cc:76
+
time_t age() const
Get the age of the cache entry.
Definition: cache_entry.cc:288
+
bool is_finished() const
Get if cache has been finished.
Definition: cache_entry.cc:437
std::recursive_mutex m_mutex
Access mutex.
Definition: cache_entry.h:264
-
bool suspend_timeout() const
Check for decode suspend timeout.
Definition: cache_entry.cc:301
+
bool suspend_timeout() const
Check for decode suspend timeout.
Definition: cache_entry.cc:303
Cache * m_owner
Owner cache object.
Definition: cache_entry.h:263
-
int ref_count() const
Get the current reference counter.
Definition: cache_entry.cc:336
-
void lock()
Lock the access mutex.
Definition: cache_entry.cc:326
+
int ref_count() const
Get the current reference counter.
Definition: cache_entry.cc:338
+
void lock()
Lock the access mutex.
Definition: cache_entry.cc:328
std::atomic_bool m_is_decoding
true while file is decoding
Definition: cache_entry.h:272
-
void close_buffer(int flags)
Close buffer object.
Definition: cache_entry.cc:206
-
const char * virtname() const
Return virtual filename. Same as destination filename, but with virtual (mount) path....
Definition: cache_entry.cc:321
+
void close_buffer(int flags)
Close buffer object.
Definition: cache_entry.cc:208
+
const char * virtname() const
Return virtual filename. Same as destination filename, but with virtual (mount) path....
Definition: cache_entry.cc:323
LPVIRTUALFILE m_virtualfile
Underlying virtual file object.
Definition: cache_entry.h:268
-
void clear(bool fetch_file_time=true)
Clear the cache entry.
Definition: cache_entry.cc:85
-
const char * destname() const
Return destination filename.
Definition: cache_entry.cc:316
-
LPVIRTUALFILE virtualfile()
Get the underlying VIRTUALFILE object.
Definition: cache_entry.cc:420
-
bool write_info()
Write cache info.
Definition: cache_entry.cc:136
-
bool destroy()
Destroy this Cache_Entry object.
Definition: cache_entry.cc:79
-
bool openio(bool create_cache=true)
Open the cache file.
Definition: cache_entry.cc:160
+
void clear(bool fetch_file_time=true)
Clear the cache entry.
Definition: cache_entry.cc:87
+
const char * destname() const
Return destination filename.
Definition: cache_entry.cc:318
+
LPVIRTUALFILE virtualfile()
Get the underlying VIRTUALFILE object.
Definition: cache_entry.cc:422
+
bool write_info()
Write cache info.
Definition: cache_entry.cc:138
+
bool destroy()
Destroy this Cache_Entry object.
Definition: cache_entry.cc:81
+
bool openio(bool create_cache=true)
Open the cache file.
Definition: cache_entry.cc:162
Cache_Entry(Cache *owner, LPVIRTUALFILE virtualfile)
Create Cache_Entry object.
Definition: cache_entry.cc:39
-
void update_read_count()
Update read counter.
Definition: cache_entry.cc:425
+
void update_read_count()
Update read counter.
Definition: cache_entry.cc:427
std::atomic_int m_ref_count
Reference counter.
Definition: cache_entry.h:266
-
const char * filename() const
Return source filename.
Definition: cache_entry.cc:311
-
int decr_refcount()
Decrement the current reference counter.
Definition: cache_entry.cc:346
-
time_t last_access() const
Get last access time.
Definition: cache_entry.cc:291
+
const char * filename() const
Return source filename.
Definition: cache_entry.cc:313
+
int decr_refcount()
Decrement the current reference counter.
Definition: cache_entry.cc:348
+
time_t last_access() const
Get last access time.
Definition: cache_entry.cc:293
std::recursive_mutex m_active_mutex
Mutex while thread is active.
Definition: cache_entry.h:273
ID3v1 m_id3v1
ID3v1 structure which is used to send to clients.
Definition: cache_entry.h:279
-
uint32_t video_frame_count() const
Get the video frame count.
Definition: cache_entry.cc:281
-
bool closeio(int flags)
Close the cache entry.
Definition: cache_entry.cc:217
-
unsigned int read_count() const
Get read counter.
Definition: cache_entry.cc:430
-
int inc_refcount()
Increment the current reference counter.
Definition: cache_entry.cc:341
-
bool flush()
Flush current memory cache to disk.
Definition: cache_entry.cc:246
-
bool decode_timeout() const
Check for decode timeout.
Definition: cache_entry.cc:306
-
void unlock()
Unlock the access mutex.
Definition: cache_entry.cc:331
-
bool is_finished_incomplete() const
Get if cache has been finished, but not completely filled.
Definition: cache_entry.cc:440
-
bool is_finished_success() const
Get if cache has been finished and filled successfully.
Definition: cache_entry.cc:445
-
bool outdated() const
Check if cache entry needs to be recoded.
Definition: cache_entry.cc:351
-
bool delete_info()
Delete cache info.
Definition: cache_entry.cc:141
-
virtual ~Cache_Entry()
Destroy Cache_Entry object.
Definition: cache_entry.cc:63
-
bool read_info()
Read cache info.
Definition: cache_entry.cc:131
-
bool expired() const
Check if cache entry expired.
Definition: cache_entry.cc:296
+
uint32_t video_frame_count() const
Get the video frame count.
Definition: cache_entry.cc:283
+
bool closeio(int flags)
Close the cache entry.
Definition: cache_entry.cc:219
+
unsigned int read_count() const
Get read counter.
Definition: cache_entry.cc:432
+
int inc_refcount()
Increment the current reference counter.
Definition: cache_entry.cc:343
+
bool flush()
Flush current memory cache to disk.
Definition: cache_entry.cc:248
+
bool decode_timeout() const
Check for decode timeout.
Definition: cache_entry.cc:308
+
void unlock()
Unlock the access mutex.
Definition: cache_entry.cc:333
+
bool is_finished_incomplete() const
Get if cache has been finished, but not completely filled.
Definition: cache_entry.cc:442
+
bool is_finished_success() const
Get if cache has been finished and filled successfully.
Definition: cache_entry.cc:447
+
bool outdated() const
Check if cache entry needs to be recoded.
Definition: cache_entry.cc:353
+
bool delete_info()
Delete cache info.
Definition: cache_entry.cc:143
+
virtual ~Cache_Entry()
Destroy Cache_Entry object.
Definition: cache_entry.cc:65
+
bool read_info()
Read cache info.
Definition: cache_entry.cc:133
+
bool expired() const
Check if cache entry expired.
Definition: cache_entry.cc:298
The Cache class.
Definition: cache.h:102
-
bool delete_info(const std::string &filename, const std::string &desttype)
Delete cache file info.
Definition: cache.cc:932
-
bool write_info(LPCCACHE_INFO cache_info)
Write cache file info.
Definition: cache.cc:866
-
bool read_info(LPCACHE_INFO cache_info)
Read cache file info.
Definition: cache.cc:739
+
bool delete_info(const std::string &filename, const std::string &desttype)
Delete cache file info.
Definition: cache.cc:945
+
bool write_info(LPCCACHE_INFO cache_info)
Write cache file info.
Definition: cache.cc:879
+
bool read_info(LPCACHE_INFO cache_info)
Read cache file info.
Definition: cache.cc:752
const std::string & desttype() const
Get destination type.
static void debug(const T filename, const std::string &format_string, Args &&...args)
Write debug level log entry.
Definition: logging.h:182
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
Definition: logging.h:163
-
void init_id3v1(ID3v1 *id3v1)
Initialise ID3v1 tag.
+
void init_id3v1(ID3v1 *id3v1)
Initialise ID3v1 tag.
FFMPEGFS_PARAMS params
FFmpegfs command line parameters.
Definition: ffmpegfs.cc:76
Main include for FFmpegfs project.
Provide various log facilities to stderr, disk or syslog.
@@ -621,7 +622,7 @@
diff --git a/html/cache__entry_8h.html b/html/cache__entry_8h.html index 267ca06ba..15ceceb31 100644 --- a/html/cache__entry_8h.html +++ b/html/cache__entry_8h.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache_entry.h File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache_entry.h File Reference
+
cache_entry.h File Reference
@@ -115,22 +114,22 @@

Go to the source code of this file.

-

+

Classes

class  Cache_Entry
 The Cache_Entry class. More...
 

Detailed Description

- diff --git a/html/cache__entry_8h__incl.png b/html/cache__entry_8h__incl.png index 04d1f175c709d573f56e90d663cbf177b73f3fa0..1219ca7d8b10a235a62f9b3ea337e27065a25cbd 100644 GIT binary patch delta 28505 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 a93#00wI9ex!eOvbD5ZO9^2Ksy0sjX}K}=Er delta 28518 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�+Heh&jy@lm4BzwIY=nBR0f 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 diff --git a/html/cache__entry_8h_source.html b/html/cache__entry_8h_source.html index 81fbb905f..07e829de9 100644 --- a/html/cache__entry_8h_source.html +++ b/html/cache__entry_8h_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache_entry.h Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache_entry.h
+
cache_entry.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 by Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
32 #ifndef CACHE_ENTRY_H
-
33 #define CACHE_ENTRY_H
-
34 
-
35 #pragma once
-
36 
-
37 #include "cache.h"
-
38 
-
39 #include "id3v1tag.h"
-
40 
-
41 #include <atomic>
-
42 
-
43 class Buffer;
-
44 
- -
49 {
-
50 private:
-
56  explicit Cache_Entry(Cache *owner, LPVIRTUALFILE virtualfile);
-
60  Cache_Entry(Cache_Entry &) = delete;
-
64  virtual ~Cache_Entry();
-
65 
-
66 public:
-
72  Cache_Entry & operator= (Cache_Entry const & other) = delete;
-
73 
- -
85  bool destroy();
-
86 
-
92  bool openio(bool create_cache = true);
-
97  bool flush();
-
102  void clear(bool fetch_file_time = true);
-
110  size_t size() const;
-
115  uint32_t video_frame_count() const;
-
120  time_t age() const;
-
125  time_t last_access() const;
-
133  bool expired() const;
-
138  bool suspend_timeout() const;
-
143  bool decode_timeout() const;
-
148  const char * filename() const;
-
153  const char * destname() const;
-
158  const char * virtname() const;
-
164  bool update_access(bool update_database = false);
-
168  void lock();
-
172  void unlock();
-
177  int ref_count() const;
-
182  int inc_refcount();
-
187  int decr_refcount();
-
188 
-
192  bool outdated() const;
-
193 
- -
199 
-
205  bool closeio(int flags);
-
209  void update_read_count();
-
217  unsigned int read_count() const;
-
218 
-
223  bool is_finished() const;
-
228  bool is_finished_incomplete() const;
-
233  bool is_finished_success() const;
-
238  bool is_finished_error() const;
-
239 
-
240 protected:
-
245  void close_buffer(int flags);
-
250  bool read_info();
-
255  bool write_info();
-
260  bool delete_info();
-
261 
-
262 protected:
- -
264  std::recursive_mutex m_mutex;
-
266  std::atomic_int m_ref_count;
- -
270 public:
- -
272  std::atomic_bool m_is_decoding;
-
273  std::recursive_mutex m_active_mutex;
-
274  std::recursive_mutex m_restart_mutex;
-
275  std::atomic_bool m_suspend_timeout;
- - -
281  std::atomic_uint32_t m_seek_to_no;
-
282 };
-
283 
-
284 #endif // CACHE_ENTRY_H
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 by Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
32#ifndef CACHE_ENTRY_H
+
33#define CACHE_ENTRY_H
+
34
+
35#pragma once
+
36
+
37#include "cache.h"
+
38
+
39#include "id3v1tag.h"
+
40
+
41#include <atomic>
+
42
+
43class Buffer;
+
44
+ +
49{
+
50private:
+ + +
64 virtual ~Cache_Entry();
+
65
+
66public:
+
72 Cache_Entry & operator= (Cache_Entry const & other) = delete;
+
73
+ +
85 bool destroy();
+
86
+
92 bool openio(bool create_cache = true);
+
97 bool flush();
+
102 void clear(bool fetch_file_time = true);
+
110 size_t size() const;
+
115 uint32_t video_frame_count() const;
+
120 time_t age() const;
+
125 time_t last_access() const;
+
133 bool expired() const;
+
138 bool suspend_timeout() const;
+
143 bool decode_timeout() const;
+
148 const char * filename() const;
+
153 const char * destname() const;
+
158 const char * virtname() const;
+
164 bool update_access(bool update_database = false);
+
168 void lock();
+
172 void unlock();
+
177 int ref_count() const;
+
182 int inc_refcount();
+
187 int decr_refcount();
+
188
+
192 bool outdated() const;
+
193
+ +
199
+
205 bool closeio(int flags);
+
209 void update_read_count();
+
217 unsigned int read_count() const;
+
218
+
223 bool is_finished() const;
+
228 bool is_finished_incomplete() const;
+
233 bool is_finished_success() const;
+
238 bool is_finished_error() const;
+
239
+
240protected:
+
245 void close_buffer(int flags);
+
250 bool read_info();
+
255 bool write_info();
+
260 bool delete_info();
+
261
+
262protected:
+ +
264 std::recursive_mutex m_mutex;
+
266 std::atomic_int m_ref_count;
+ +
270public:
+ +
272 std::atomic_bool m_is_decoding;
+
273 std::recursive_mutex m_active_mutex;
+
274 std::recursive_mutex m_restart_mutex;
+
275 std::atomic_bool m_suspend_timeout;
+ + +
281 std::atomic_uint32_t m_seek_to_no;
+
282};
+
283
+
284#endif // CACHE_ENTRY_H
Data cache management.
The Buffer class.
Definition: buffer.h:56
The Cache_Entry class.
Definition: cache_entry.h:49
std::recursive_mutex m_restart_mutex
Mutex while thread is restarted.
Definition: cache_entry.h:274
-
size_t size() const
Return size of output file, as computed by encoder.
Definition: cache_entry.cc:260
+
size_t size() const
Return size of output file, as computed by encoder.
Definition: cache_entry.cc:262
CACHE_INFO m_cache_info
Info about cached object.
Definition: cache_entry.h:277
-
bool update_access(bool update_database=false)
Update last access time.
Definition: cache_entry.cc:146
-
bool is_finished_error() const
Get if cache has been finished and with an error.
Definition: cache_entry.cc:450
+
bool update_access(bool update_database=false)
Update last access time.
Definition: cache_entry.cc:148
+
bool is_finished_error() const
Get if cache has been finished and with an error.
Definition: cache_entry.cc:452
Buffer * m_buffer
Buffer object.
Definition: cache_entry.h:271
-
static Cache_Entry * create(Cache *owner, LPVIRTUALFILE virtualfile)
Create a new Cache_Entry object.
Definition: cache_entry.cc:74
+
static Cache_Entry * create(Cache *owner, LPVIRTUALFILE virtualfile)
Create a new Cache_Entry object.
Definition: cache_entry.cc:76
std::atomic_bool m_suspend_timeout
true to temporarly disable read_frame timeout
Definition: cache_entry.h:275
-
time_t age() const
Get the age of the cache entry.
Definition: cache_entry.cc:286
-
bool is_finished() const
Get if cache has been finished.
Definition: cache_entry.cc:435
+
time_t age() const
Get the age of the cache entry.
Definition: cache_entry.cc:288
+
bool is_finished() const
Get if cache has been finished.
Definition: cache_entry.cc:437
std::recursive_mutex m_mutex
Access mutex.
Definition: cache_entry.h:264
-
bool suspend_timeout() const
Check for decode suspend timeout.
Definition: cache_entry.cc:301
+
bool suspend_timeout() const
Check for decode suspend timeout.
Definition: cache_entry.cc:303
Cache * m_owner
Owner cache object.
Definition: cache_entry.h:263
-
int ref_count() const
Get the current reference counter.
Definition: cache_entry.cc:336
-
void lock()
Lock the access mutex.
Definition: cache_entry.cc:326
+
int ref_count() const
Get the current reference counter.
Definition: cache_entry.cc:338
+
void lock()
Lock the access mutex.
Definition: cache_entry.cc:328
std::atomic_bool m_is_decoding
true while file is decoding
Definition: cache_entry.h:272
-
void close_buffer(int flags)
Close buffer object.
Definition: cache_entry.cc:206
-
const char * virtname() const
Return virtual filename. Same as destination filename, but with virtual (mount) path....
Definition: cache_entry.cc:321
+
void close_buffer(int flags)
Close buffer object.
Definition: cache_entry.cc:208
+
const char * virtname() const
Return virtual filename. Same as destination filename, but with virtual (mount) path....
Definition: cache_entry.cc:323
LPVIRTUALFILE m_virtualfile
Underlying virtual file object.
Definition: cache_entry.h:268
-
void clear(bool fetch_file_time=true)
Clear the cache entry.
Definition: cache_entry.cc:85
-
const char * destname() const
Return destination filename.
Definition: cache_entry.cc:316
-
LPVIRTUALFILE virtualfile()
Get the underlying VIRTUALFILE object.
Definition: cache_entry.cc:420
-
bool write_info()
Write cache info.
Definition: cache_entry.cc:136
-
bool destroy()
Destroy this Cache_Entry object.
Definition: cache_entry.cc:79
-
bool openio(bool create_cache=true)
Open the cache file.
Definition: cache_entry.cc:160
+
void clear(bool fetch_file_time=true)
Clear the cache entry.
Definition: cache_entry.cc:87
+
const char * destname() const
Return destination filename.
Definition: cache_entry.cc:318
+
LPVIRTUALFILE virtualfile()
Get the underlying VIRTUALFILE object.
Definition: cache_entry.cc:422
+
bool write_info()
Write cache info.
Definition: cache_entry.cc:138
+
bool destroy()
Destroy this Cache_Entry object.
Definition: cache_entry.cc:81
+
bool openio(bool create_cache=true)
Open the cache file.
Definition: cache_entry.cc:162
Cache_Entry(Cache *owner, LPVIRTUALFILE virtualfile)
Create Cache_Entry object.
Definition: cache_entry.cc:39
-
void update_read_count()
Update read counter.
Definition: cache_entry.cc:425
+
void update_read_count()
Update read counter.
Definition: cache_entry.cc:427
std::atomic_int m_ref_count
Reference counter.
Definition: cache_entry.h:266
-
const char * filename() const
Return source filename.
Definition: cache_entry.cc:311
-
int decr_refcount()
Decrement the current reference counter.
Definition: cache_entry.cc:346
-
time_t last_access() const
Get last access time.
Definition: cache_entry.cc:291
+
const char * filename() const
Return source filename.
Definition: cache_entry.cc:313
+
int decr_refcount()
Decrement the current reference counter.
Definition: cache_entry.cc:348
+
time_t last_access() const
Get last access time.
Definition: cache_entry.cc:293
std::recursive_mutex m_active_mutex
Mutex while thread is active.
Definition: cache_entry.h:273
ID3v1 m_id3v1
ID3v1 structure which is used to send to clients.
Definition: cache_entry.h:279
-
uint32_t video_frame_count() const
Get the video frame count.
Definition: cache_entry.cc:281
-
bool closeio(int flags)
Close the cache entry.
Definition: cache_entry.cc:217
-
unsigned int read_count() const
Get read counter.
Definition: cache_entry.cc:430
-
int inc_refcount()
Increment the current reference counter.
Definition: cache_entry.cc:341
-
bool flush()
Flush current memory cache to disk.
Definition: cache_entry.cc:246
-
bool decode_timeout() const
Check for decode timeout.
Definition: cache_entry.cc:306
-
void unlock()
Unlock the access mutex.
Definition: cache_entry.cc:331
-
bool is_finished_incomplete() const
Get if cache has been finished, but not completely filled.
Definition: cache_entry.cc:440
-
bool is_finished_success() const
Get if cache has been finished and filled successfully.
Definition: cache_entry.cc:445
-
bool outdated() const
Check if cache entry needs to be recoded.
Definition: cache_entry.cc:351
+
uint32_t video_frame_count() const
Get the video frame count.
Definition: cache_entry.cc:283
+
bool closeio(int flags)
Close the cache entry.
Definition: cache_entry.cc:219
+
unsigned int read_count() const
Get read counter.
Definition: cache_entry.cc:432
+
int inc_refcount()
Increment the current reference counter.
Definition: cache_entry.cc:343
+
bool flush()
Flush current memory cache to disk.
Definition: cache_entry.cc:248
+
bool decode_timeout() const
Check for decode timeout.
Definition: cache_entry.cc:308
+
void unlock()
Unlock the access mutex.
Definition: cache_entry.cc:333
+
bool is_finished_incomplete() const
Get if cache has been finished, but not completely filled.
Definition: cache_entry.cc:442
+
bool is_finished_success() const
Get if cache has been finished and filled successfully.
Definition: cache_entry.cc:447
+
bool outdated() const
Check if cache entry needs to be recoded.
Definition: cache_entry.cc:353
std::atomic_uint32_t m_seek_to_no
If not 0, seeks to specified frame.
Definition: cache_entry.h:281
-
bool delete_info()
Delete cache info.
Definition: cache_entry.cc:141
-
virtual ~Cache_Entry()
Destroy Cache_Entry object.
Definition: cache_entry.cc:63
-
Cache_Entry & operator=(Cache_Entry const &other)=delete
operator = declared deleted, should use create to get this object to maintain reference count.
-
bool read_info()
Read cache info.
Definition: cache_entry.cc:131
-
bool expired() const
Check if cache entry expired.
Definition: cache_entry.cc:296
+
Cache_Entry & operator=(Cache_Entry const &other)=delete
operator = declared deleted, should use create to get this object to maintain reference count.
+
bool delete_info()
Delete cache info.
Definition: cache_entry.cc:143
+
virtual ~Cache_Entry()
Destroy Cache_Entry object.
Definition: cache_entry.cc:65
+
bool read_info()
Read cache info.
Definition: cache_entry.cc:133
+
bool expired() const
Check if cache entry expired.
Definition: cache_entry.cc:298
Cache_Entry(Cache_Entry &)=delete
Copy constructor declared deleted, should use create to get this object to maintain reference count.
The Cache class.
Definition: cache.h:102
ID3v1 tag structure
@@ -234,7 +233,7 @@
diff --git a/html/cache__maintenance_8cc.html b/html/cache__maintenance_8cc.html index ca446ece7..1ad12cb99 100644 --- a/html/cache__maintenance_8cc.html +++ b/html/cache__maintenance_8cc.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache_maintenance.cc File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
Macros | Functions | Variables
-
-
cache_maintenance.cc File Reference
+
cache_maintenance.cc File Reference
@@ -123,22 +122,19 @@

Go to the source code of this file.

- - - + + - - + + - - + +

+

Macros

-#define CLOCKID   CLOCK_REALTIME
 Use real time clock here.
#define CLOCKID   CLOCK_REALTIME
 Use real time clock here. More...
 
-#define SIGMAINT   SIGRTMIN
 Map maintenance signal.
#define SIGMAINT   SIGRTMIN
 Map maintenance signal. More...
 
-#define SEM_OPEN_FILE   "/" PACKAGE_NAME "_04806785-b5fb-4615-ba56-b30a2946e80b"
 Shared semaphore name, should be unique system wide.
#define SEM_OPEN_FILE   "/" PACKAGE_NAME "_04806785-b5fb-4615-ba56-b30a2946e80b"
 Shared semaphore name, should be unique system wide. More...
 
- @@ -152,9 +148,8 @@ - - + + @@ -166,41 +161,90 @@

+

Functions

static void maintenance_handler (int sig, __attribute__((unused)) siginfo_t *si, __attribute__((unused)) void *uc)
 Run maintenance handler. More...
static bool link_up ()
 Set system wide inter process link up. More...
 
-static void master_check ()
 Check if a master is already running. We become master if not.
static void master_check ()
 Check if a master is already running. We become master if not. More...
 
static bool link_down ()
 Set system wide inter process link down. More...
 Stop cache maintenance timer. More...
 
- - - + + - - + + - - + + - - + + - - + + - - + +

+

Variables

-static sigset_t mask
 Process mask for timer.
static sigset_t mask
 Process mask for timer. More...
 
-static timer_t timerid
 Timer id.
static timer_t timerid
 Timer id. More...
 
-static sem_t * sem
 Semaphore used to synchronise between master and slave processes.
static sem_t * sem
 Semaphore used to synchronise between master and slave processes. More...
 
-static int shmid
 Shared memory segment ID.
static int shmid
 Shared memory segment ID. More...
 
-static pid_t * pid_master
 PID of master process.
static pid_t * pid_master
 PID of master process. More...
 
-static bool master
 If true, we are master.
static bool master
 If true, we are master. More...
 

Detailed Description

-

Cache maintenance implementation

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

Cache maintenance implementation

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file cache_maintenance.cc.

-

Function Documentation

- +

Macro Definition Documentation

+ +

◆ CLOCKID

+ +
+
+ + + + +
#define CLOCKID   CLOCK_REALTIME
+
+ +

Use real time clock here.

+ +

Definition at line 41 of file cache_maintenance.cc.

+ +
+
+ +

◆ SEM_OPEN_FILE

+ +
+
+ + + + +
#define SEM_OPEN_FILE   "/" PACKAGE_NAME "_04806785-b5fb-4615-ba56-b30a2946e80b"
+
+ +

Shared semaphore name, should be unique system wide.

+ +

Definition at line 44 of file cache_maintenance.cc.

+ +
+
+ +

◆ SIGMAINT

+ +
+
+ + + + +
#define SIGMAINT   SIGRTMIN
+
+ +

Map maintenance signal.

+ +

Definition at line 42 of file cache_maintenance.cc.

+ +
+
+

Function Documentation

+

◆ link_down()

@@ -234,7 +278,7 @@

+

◆ link_up()

@@ -268,7 +312,7 @@

+

◆ maintenance_handler()

@@ -326,7 +370,40 @@

+ +

◆ master_check()

+ +
+
+ + + + + +
+ + + + + + + +
static void master_check ()
+
+static
+
+ +

Check if a master is already running. We become master if not.

+ +

Definition at line 238 of file cache_maintenance.cc.

+ +

References Logging::info(), master, pid_master, sem, and Logging::trace().

+ +

Referenced by maintenance_handler().

+ +
+
+

◆ start_cache_maintenance()

- +

◆ stop_cache_maintenance()

@@ -426,7 +503,7 @@

+

◆ stop_timer()

@@ -458,12 +535,181 @@

Referenced by stop_cache_maintenance().

+

+

+

Variable Documentation

+ +

◆ mask

+ +
+
+ + + + + +
+ + + + +
sigset_t mask
+
+static
+
+ +

Process mask for timer.

+ +

Definition at line 46 of file cache_maintenance.cc.

+ +

Referenced by start_timer().

+ +
+
+ +

◆ master

+ +
+
+ + + + + +
+ + + + +
bool master
+
+static
+
+ +

If true, we are master.

+ +

Definition at line 52 of file cache_maintenance.cc.

+ +

Referenced by link_up(), maintenance_handler(), and master_check().

+ +
+
+ +

◆ pid_master

+ +
+
+ + + + + +
+ + + + +
pid_t* pid_master
+
+static
+
+ +

PID of master process.

+ +

Definition at line 51 of file cache_maintenance.cc.

+ +

Referenced by link_down(), link_up(), and master_check().

+ +
+
+ +

◆ sem

+ +
+
+ + + + + +
+ + + + +
sem_t* sem
+
+static
+
+ +

Semaphore used to synchronise between master and slave processes.

+ +

Definition at line 49 of file cache_maintenance.cc.

+ +

Referenced by link_down(), link_up(), and master_check().

+ +
+
+ +

◆ shmid

+ +
+
+ + + + + +
+ + + + +
int shmid
+
+static
+
+ +

Shared memory segment ID.

+ +

Definition at line 50 of file cache_maintenance.cc.

+ +

Referenced by link_down(), and link_up().

+ +
+
+ +

◆ timerid

+ +
+
+ + + + + +
+ + + + +
timer_t timerid
+
+static
+
+ +

Timer id.

+ +

Definition at line 47 of file cache_maintenance.cc.

+ +

Referenced by start_timer(), and stop_timer().

+

diff --git a/html/cache__maintenance_8cc_source.html b/html/cache__maintenance_8cc_source.html index 7a4797dca..5aea68096 100644 --- a/html/cache__maintenance_8cc_source.html +++ b/html/cache__maintenance_8cc_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache_maintenance.cc Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache_maintenance.cc
+
cache_maintenance.cc
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
32 #include "cache_maintenance.h"
-
33 #include "ffmpegfs.h"
-
34 #include "logging.h"
-
35 
-
36 #include <csignal>
-
37 #include <unistd.h>
-
38 #include <sys/shm.h> /* shmat(), IPC_RMID */
-
39 #include <semaphore.h> /* sem_open(), sem_destroy(), sem_wait().. */
-
40 
-
41 #define CLOCKID CLOCK_REALTIME
-
42 #define SIGMAINT SIGRTMIN
-
44 #define SEM_OPEN_FILE "/" PACKAGE_NAME "_04806785-b5fb-4615-ba56-b30a2946e80b"
-
46 static sigset_t mask;
-
47 static timer_t timerid;
-
49 static sem_t * sem;
-
50 static int shmid;
-
51 static pid_t * pid_master;
-
52 static bool master;
-
54 static void maintenance_handler(int sig, __attribute__((unused)) siginfo_t *si, __attribute__((unused)) void *uc);
-
55 static bool start_timer(time_t interval);
-
56 static bool stop_timer();
-
57 static bool link_up();
-
58 static void master_check();
-
59 static bool link_down();
-
60 
-
67 static void maintenance_handler(int sig, __attribute__((unused)) siginfo_t *si, __attribute__((unused)) void *uc)
-
68 {
-
69  if (sig != SIGMAINT)
-
70  {
-
71  // Wrong signal. Should never happen.
-
72  return;
-
73  }
-
74 
-
75  master_check();
-
76 
-
77  if (master)
-
78  {
-
79  Logging::info(nullptr, "Running periodic cache maintenance.");
- -
81  }
-
82 }
-
83 
-
89 static bool start_timer(time_t interval)
-
90 {
-
91  struct sigevent sev;
-
92  struct itimerspec its;
-
93  long long freq_nanosecs;
-
94  struct sigaction sa;
-
95 
-
96  freq_nanosecs = interval * 1000000000LL;
-
97 
-
98  Logging::trace(nullptr, "Starting maintenance timer with %1period.", format_time(interval).c_str());
-
99 
-
100  // Establish maintenance_handler for timer signal
-
101  sa.sa_flags = SA_SIGINFO;
-
102  sa.sa_sigaction = maintenance_handler;
-
103  sigemptyset(&sa.sa_mask);
-
104  if (sigaction(SIGMAINT, &sa, nullptr) == -1)
-
105  {
-
106  Logging::error(nullptr, "start_timer(): sigaction failed: (%1) %2", errno, strerror(errno));
-
107  return false;
-
108  }
-
109 
-
110  // Block timer signal temporarily
-
111  sigemptyset(&mask);
-
112  sigaddset(&mask, SIGMAINT);
-
113  if (sigprocmask(SIG_SETMASK, &mask, nullptr) == -1)
-
114  {
-
115  Logging::error(nullptr, "start_timer(): sigprocmask(SIG_SETMASK) failed: (%1) %2", errno, strerror(errno));
-
116  return false;
-
117  }
-
118 
-
119  // Create the timer
-
120  sev.sigev_notify = SIGEV_SIGNAL;
-
121  sev.sigev_signo = SIGMAINT;
-
122  sev.sigev_value.sival_ptr = &timerid;
-
123  if (timer_create(CLOCKID, &sev, &timerid) == -1)
-
124  {
-
125  Logging::error(nullptr, "start_timer(): timer_create failed: (%1) %2", errno, strerror(errno));
-
126  return false;
-
127  }
-
128 
-
129  // Start the timer
-
130  its.it_value.tv_sec = static_cast<time_t>(freq_nanosecs / 1000000000);
-
131  its.it_value.tv_nsec = static_cast<long>(freq_nanosecs % 1000000000);
-
132  its.it_interval.tv_sec = its.it_value.tv_sec;
-
133  its.it_interval.tv_nsec = its.it_value.tv_nsec;
-
134 
-
135  if (timer_settime(timerid, 0, &its, nullptr) == -1)
-
136  {
-
137  Logging::error(nullptr, "start_timer(): timer_settime failed: (%1) %2", errno, strerror(errno));
-
138  return false;
-
139  }
-
140 
-
141  if (sigprocmask(SIG_UNBLOCK, &mask, nullptr) == -1)
-
142  {
-
143  Logging::error(nullptr, "start_timer(): sigprocmask(SIG_UNBLOCK) failed: (%1) %2", errno, strerror(errno));
-
144  }
-
145 
-
146  Logging::trace(nullptr, "The maintenance timer started successfully.");
-
147 
-
148  return true;
-
149 }
-
150 
-
155 static bool stop_timer()
-
156 {
-
157  Logging::info(nullptr, "Stopping the maintenance timer.");
-
158 
-
159  if (timer_delete(timerid) == -1 && errno)
-
160  {
-
161  Logging::error(nullptr, "stop_timer(): timer_delete failed: (%1) %2", errno, strerror(errno));
-
162  return false;
-
163  }
-
164 
-
165  return true;
-
166 }
-
167 
-
172 static bool link_up()
-
173 {
-
174  key_t shmkey;
-
175 
-
176  Logging::debug(nullptr, "Activating " PACKAGE " inter-process link.");
-
177 
-
178  // initialise a shared variable in shared memory
-
179  shmkey = ftok ("/dev/null", 5); // valid directory name and a number
-
180 
-
181  if (shmkey == -1)
-
182  {
-
183  Logging::error(nullptr, "link_up(): ftok error (%1) %2", errno, strerror(errno));
-
184  return false;
-
185  }
-
186 
-
187  // First try to open existing memory.
-
188  shmid = shmget (shmkey, sizeof (pid_t), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-
189  if (shmid != -1)
-
190  {
-
191  // Shared memory already exists, seems we are client.
-
192  master = false;
-
193  }
-
194  else
-
195  {
-
196  // Ignore error at first, try to create memory.
-
197  shmid = shmget (shmkey, sizeof (pid_t), IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-
198  if (shmid != -1)
-
199  {
-
200  // Shared memory freshly created, seems we are master.
-
201  master = true;
-
202  }
-
203  else
-
204  {
-
205  Logging::error(nullptr, "link_up(): shmget error (%1) %2", errno, strerror(errno));
-
206  return false;
-
207  }
-
208  }
-
209 
-
210  pid_master = static_cast<pid_t *>(shmat (shmid, nullptr, 0)); // attach pid_master to shared memory
-
211 
-
212  if (master)
-
213  {
-
214  *pid_master = getpid();
-
215  Logging::info(nullptr, "The process with PID %1 is now master.", *pid_master);
-
216  }
-
217  else
-
218  {
-
219  Logging::info(nullptr, "The process with PID %1 is now a client, and PID %2 is the master.", getpid(), *pid_master);
-
220  }
-
221 
-
222  // Also create inter-process semaphore.
-
223  sem = sem_open(const_cast<const char *>(SEM_OPEN_FILE), O_CREAT, 0777, 1);
-
224 
-
225  if (sem == SEM_FAILED)
-
226  {
-
227  Logging::error(nullptr, "link_up(): sem_open error (%1) %2", errno, strerror(errno));
-
228  link_down();
-
229  return false;
-
230  }
-
231 
-
232  return true;
-
233 }
-
234 
-
238 static void master_check()
-
239 {
-
240  pid_t pid_self = getpid();
-
241 
-
242  if (*pid_master == pid_self)
-
243  {
-
244  Logging::trace(nullptr, "The process with PID %1 is already master.", pid_self);
-
245  return;
-
246  }
-
247 
-
248  sem_wait(sem);
-
249 
-
250  // Check if master process still exists
-
251  int master_running = (getpgid(*pid_master) >= 0);
-
252 
-
253  Logging::trace(nullptr, "Master with PID %1 is %2 running.", *pid_master, master_running ? "still" : "NOT");
-
254 
-
255  if (!master_running)
-
256  {
-
257  Logging::info(nullptr, "Master with PID %1 is gone. PID %2 taking over as new master.", *pid_master, pid_self);
-
258 
-
259  // Register us as master
-
260  *pid_master = pid_self;
-
261  master = true;
-
262  }
-
263 
-
264  sem_post(sem);
-
265 }
-
266 
-
271 static bool link_down()
-
272 {
-
273  struct shmid_ds buf;
-
274  bool success = true;
-
275 
-
276  Logging::info(nullptr, "Shutting " PACKAGE " inter-process link down.");
-
277 
-
278  if (sem != nullptr && sem_close(sem))
-
279  {
-
280  Logging::error(nullptr, "link_down(): sem_close error (%1) %2", errno, strerror(errno));
-
281  success = false;
-
282  }
-
283 
-
284  // shared memory detach
-
285  if (shmdt (pid_master))
-
286  {
-
287  Logging::error(nullptr, "link_down(): shmdt error (%1) %2", errno, strerror(errno));
-
288  success = false;
-
289  }
-
290 
-
291  if (shmctl(shmid, IPC_STAT, &buf))
-
292  {
-
293  Logging::error(nullptr, "link_down(): shmctl error (%1) %2", errno, strerror(errno));
-
294  success = false;
-
295  }
-
296  else
-
297  {
-
298  if (!buf.shm_nattch)
-
299  {
-
300  if (shmctl (shmid, IPC_RMID, nullptr))
-
301  {
-
302  Logging::error(nullptr, "link_down(): shmctl error (%1) %2", errno, strerror(errno));
-
303  success = false;
-
304  }
-
305 
-
306  // unlink prevents the semaphore existing forever
-
307  // if a crash occurs during the execution
-
308  if (sem_unlink(SEM_OPEN_FILE))
-
309  {
-
310  Logging::error(nullptr, "link_down(): sem_unlink error (%1) %2", errno, strerror(errno));
-
311  success = false;
-
312  }
-
313  }
-
314  }
-
315 
-
316  return success;
-
317 }
-
318 
-
319 bool start_cache_maintenance(time_t interval)
-
320 {
-
321  // Start link
-
322  if (!link_up())
-
323  {
-
324  return false;
-
325  }
-
326 
-
327  // Now start timer
-
328  return start_timer(interval);
-
329 }
-
330 
- -
332 {
-
333  bool success = true;
-
334 
-
335  // Stop timer first
-
336  if (!stop_timer())
-
337  {
-
338  success = false;
-
339  }
-
340 
-
341  // Now shut down link
-
342  if (!link_down())
-
343  {
-
344  success = false;
-
345  }
-
346 
-
347  return success;
-
348 }
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
32#include "cache_maintenance.h"
+
33#include "ffmpegfs.h"
+
34#include "logging.h"
+
35
+
36#include <csignal>
+
37#include <unistd.h>
+
38#include <sys/shm.h> /* shmat(), IPC_RMID */
+
39#include <semaphore.h> /* sem_open(), sem_destroy(), sem_wait().. */
+
40
+
41#define CLOCKID CLOCK_REALTIME
+
42#define SIGMAINT SIGRTMIN
+
44#define SEM_OPEN_FILE "/" PACKAGE_NAME "_04806785-b5fb-4615-ba56-b30a2946e80b"
+
46static sigset_t mask;
+
47static timer_t timerid;
+
49static sem_t * sem;
+
50static int shmid;
+
51static pid_t * pid_master;
+
52static bool master;
+
54static void maintenance_handler(int sig, __attribute__((unused)) siginfo_t *si, __attribute__((unused)) void *uc);
+
55static bool start_timer(time_t interval);
+
56static bool stop_timer();
+
57static bool link_up();
+
58static void master_check();
+
59static bool link_down();
+
60
+
67static void maintenance_handler(int sig, __attribute__((unused)) siginfo_t *si, __attribute__((unused)) void *uc)
+
68{
+
69 if (sig != SIGMAINT)
+
70 {
+
71 // Wrong signal. Should never happen.
+
72 return;
+
73 }
+
74
+ +
76
+
77 if (master)
+
78 {
+
79 Logging::info(nullptr, "Running periodic cache maintenance.");
+ +
81 }
+
82}
+
83
+
89static bool start_timer(time_t interval)
+
90{
+
91 struct sigevent sev;
+
92 struct itimerspec its;
+
93 long long freq_nanosecs;
+
94 struct sigaction sa;
+
95
+
96 freq_nanosecs = interval * 1000000000LL;
+
97
+
98 Logging::trace(nullptr, "Starting maintenance timer with %1period.", format_time(interval).c_str());
+
99
+
100 // Establish maintenance_handler for timer signal
+
101 sa.sa_flags = SA_SIGINFO;
+
102 sa.sa_sigaction = maintenance_handler;
+
103 sigemptyset(&sa.sa_mask);
+
104 if (sigaction(SIGMAINT, &sa, nullptr) == -1)
+
105 {
+
106 Logging::error(nullptr, "start_timer(): sigaction failed: (%1) %2", errno, strerror(errno));
+
107 return false;
+
108 }
+
109
+
110 // Block timer signal temporarily
+
111 sigemptyset(&mask);
+
112 sigaddset(&mask, SIGMAINT);
+
113 if (sigprocmask(SIG_SETMASK, &mask, nullptr) == -1)
+
114 {
+
115 Logging::error(nullptr, "start_timer(): sigprocmask(SIG_SETMASK) failed: (%1) %2", errno, strerror(errno));
+
116 return false;
+
117 }
+
118
+
119 // Create the timer
+
120 sev.sigev_notify = SIGEV_SIGNAL;
+
121 sev.sigev_signo = SIGMAINT;
+
122 sev.sigev_value.sival_ptr = &timerid;
+
123 if (timer_create(CLOCKID, &sev, &timerid) == -1)
+
124 {
+
125 Logging::error(nullptr, "start_timer(): timer_create failed: (%1) %2", errno, strerror(errno));
+
126 return false;
+
127 }
+
128
+
129 // Start the timer
+
130 its.it_value.tv_sec = static_cast<time_t>(freq_nanosecs / 1000000000);
+
131 its.it_value.tv_nsec = static_cast<long>(freq_nanosecs % 1000000000);
+
132 its.it_interval.tv_sec = its.it_value.tv_sec;
+
133 its.it_interval.tv_nsec = its.it_value.tv_nsec;
+
134
+
135 if (timer_settime(timerid, 0, &its, nullptr) == -1)
+
136 {
+
137 Logging::error(nullptr, "start_timer(): timer_settime failed: (%1) %2", errno, strerror(errno));
+
138 return false;
+
139 }
+
140
+
141 if (sigprocmask(SIG_UNBLOCK, &mask, nullptr) == -1)
+
142 {
+
143 Logging::error(nullptr, "start_timer(): sigprocmask(SIG_UNBLOCK) failed: (%1) %2", errno, strerror(errno));
+
144 }
+
145
+
146 Logging::trace(nullptr, "The maintenance timer started successfully.");
+
147
+
148 return true;
+
149}
+
150
+
155static bool stop_timer()
+
156{
+
157 Logging::info(nullptr, "Stopping the maintenance timer.");
+
158
+
159 if (timer_delete(timerid) == -1 && errno)
+
160 {
+
161 Logging::error(nullptr, "stop_timer(): timer_delete failed: (%1) %2", errno, strerror(errno));
+
162 return false;
+
163 }
+
164
+
165 return true;
+
166}
+
167
+
172static bool link_up()
+
173{
+
174 key_t shmkey;
+
175
+
176 Logging::debug(nullptr, "Activating " PACKAGE " inter-process link.");
+
177
+
178 // initialise a shared variable in shared memory
+
179 shmkey = ftok ("/dev/null", 5); // valid directory name and a number
+
180
+
181 if (shmkey == -1)
+
182 {
+
183 Logging::error(nullptr, "link_up(): ftok error (%1) %2", errno, strerror(errno));
+
184 return false;
+
185 }
+
186
+
187 // First try to open existing memory.
+
188 shmid = shmget (shmkey, sizeof (pid_t), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
189 if (shmid != -1)
+
190 {
+
191 // Shared memory already exists, seems we are client.
+
192 master = false;
+
193 }
+
194 else
+
195 {
+
196 // Ignore error at first, try to create memory.
+
197 shmid = shmget (shmkey, sizeof (pid_t), IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
198 if (shmid != -1)
+
199 {
+
200 // Shared memory freshly created, seems we are master.
+
201 master = true;
+
202 }
+
203 else
+
204 {
+
205 Logging::error(nullptr, "link_up(): shmget error (%1) %2", errno, strerror(errno));
+
206 return false;
+
207 }
+
208 }
+
209
+
210 pid_master = static_cast<pid_t *>(shmat (shmid, nullptr, 0)); // attach pid_master to shared memory
+
211
+
212 if (master)
+
213 {
+
214 *pid_master = getpid();
+
215 Logging::info(nullptr, "The process with PID %1 is now master.", *pid_master);
+
216 }
+
217 else
+
218 {
+
219 Logging::info(nullptr, "The process with PID %1 is now a client, and PID %2 is the master.", getpid(), *pid_master);
+
220 }
+
221
+
222 // Also create inter-process semaphore.
+
223 sem = sem_open(const_cast<const char *>(SEM_OPEN_FILE), O_CREAT, 0777, 1);
+
224
+
225 if (sem == SEM_FAILED)
+
226 {
+
227 Logging::error(nullptr, "link_up(): sem_open error (%1) %2", errno, strerror(errno));
+
228 link_down();
+
229 return false;
+
230 }
+
231
+
232 return true;
+
233}
+
234
+
238static void master_check()
+
239{
+
240 pid_t pid_self = getpid();
+
241
+
242 if (*pid_master == pid_self)
+
243 {
+
244 Logging::trace(nullptr, "The process with PID %1 is already master.", pid_self);
+
245 return;
+
246 }
+
247
+
248 sem_wait(sem);
+
249
+
250 // Check if master process still exists
+
251 int master_running = (getpgid(*pid_master) >= 0);
+
252
+
253 Logging::trace(nullptr, "Master with PID %1 is %2 running.", *pid_master, master_running ? "still" : "NOT");
+
254
+
255 if (!master_running)
+
256 {
+
257 Logging::info(nullptr, "Master with PID %1 is gone. PID %2 taking over as new master.", *pid_master, pid_self);
+
258
+
259 // Register us as master
+
260 *pid_master = pid_self;
+
261 master = true;
+
262 }
+
263
+
264 sem_post(sem);
+
265}
+
266
+
271static bool link_down()
+
272{
+
273 struct shmid_ds buf;
+
274 bool success = true;
+
275
+
276 Logging::info(nullptr, "Shutting " PACKAGE " inter-process link down.");
+
277
+
278 if (sem != nullptr && sem_close(sem))
+
279 {
+
280 Logging::error(nullptr, "link_down(): sem_close error (%1) %2", errno, strerror(errno));
+
281 success = false;
+
282 }
+
283
+
284 // shared memory detach
+
285 if (shmdt (pid_master))
+
286 {
+
287 Logging::error(nullptr, "link_down(): shmdt error (%1) %2", errno, strerror(errno));
+
288 success = false;
+
289 }
+
290
+
291 if (shmctl(shmid, IPC_STAT, &buf))
+
292 {
+
293 Logging::error(nullptr, "link_down(): shmctl error (%1) %2", errno, strerror(errno));
+
294 success = false;
+
295 }
+
296 else
+
297 {
+
298 if (!buf.shm_nattch)
+
299 {
+
300 if (shmctl (shmid, IPC_RMID, nullptr))
+
301 {
+
302 Logging::error(nullptr, "link_down(): shmctl error (%1) %2", errno, strerror(errno));
+
303 success = false;
+
304 }
+
305
+
306 // unlink prevents the semaphore existing forever
+
307 // if a crash occurs during the execution
+
308 if (sem_unlink(SEM_OPEN_FILE))
+
309 {
+
310 Logging::error(nullptr, "link_down(): sem_unlink error (%1) %2", errno, strerror(errno));
+
311 success = false;
+
312 }
+
313 }
+
314 }
+
315
+
316 return success;
+
317}
+
318
+
319bool start_cache_maintenance(time_t interval)
+
320{
+
321 // Start link
+
322 if (!link_up())
+
323 {
+
324 return false;
+
325 }
+
326
+
327 // Now start timer
+
328 return start_timer(interval);
+
329}
+
330
+ +
332{
+
333 bool success = true;
+
334
+
335 // Stop timer first
+
336 if (!stop_timer())
+
337 {
+
338 success = false;
+
339 }
+
340
+
341 // Now shut down link
+
342 if (!link_down())
+
343 {
+
344 success = false;
+
345 }
+
346
+
347 return success;
+
348}
static bool master
If true, we are master.
bool stop_cache_maintenance()
Stop cache maintenance timer.
#define CLOCKID
Use real time clock here.
@@ -400,14 +399,14 @@
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
Definition: logging.h:163
static void info(const T filename, const std::string &format_string, Args &&...args)
Write info level log entry.
Definition: logging.h:201
static void error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
Definition: logging.h:239
-
std::string format_time(time_t value)
Format a time in format "w d m s".
+
std::string format_time(time_t value)
Format a time in format "w d m s".
Main include for FFmpegfs project.
bool transcoder_cache_maintenance()
Run cache maintenance.
Definition: transcode.cc:745
Provide various log facilities to stderr, disk or syslog.
diff --git a/html/cache__maintenance_8h.html b/html/cache__maintenance_8h.html index 609d5c9c4..42b5b85fd 100644 --- a/html/cache__maintenance_8h.html +++ b/html/cache__maintenance_8h.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache_maintenance.h File Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache_maintenance.h File Reference
+
cache_maintenance.h File Reference
@@ -98,7 +97,7 @@

Go to the source code of this file.

- @@ -108,15 +107,15 @@

+

Functions

bool start_cache_maintenance (time_t interval)
 Start cache maintenance timer. More...
 

Detailed Description

-

Cache maintenance

-

Creates a POSIX timer that starts the cache maintenance in preset intervals. To ensure that only one instance of FFmpegfs cleans up the cache a shared memory area and a named semaphore is also created.

-

The first FFmpegfs process acts as master, all subsequently started instances will be clients. If the master process goes away one of the clients will automatically take over as master.

-
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
- +

Cache maintenance

+

Creates a POSIX timer that starts the cache maintenance in preset intervals. To ensure that only one instance of FFmpegfs cleans up the cache a shared memory area and a named semaphore is also created.

+

The first FFmpegfs process acts as master, all subsequently started instances will be clients. If the master process goes away one of the clients will automatically take over as master.

+
Author
Norbert Schlia (nschl.nosp@m.ia@o.nosp@m.blivi.nosp@m.on-s.nosp@m.oftwa.nosp@m.re.d.nosp@m.e)
+

Definition in file cache_maintenance.h.

Function Documentation

- +

◆ start_cache_maintenance()

@@ -149,7 +148,7 @@

+

◆ stop_cache_maintenance()

@@ -178,7 +177,7 @@

diff --git a/html/cache__maintenance_8h_source.html b/html/cache__maintenance_8h_source.html index 9d2eea321..2f6d1e1b4 100644 --- a/html/cache__maintenance_8h_source.html +++ b/html/cache__maintenance_8h_source.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: src/cache_maintenance.h Source File @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
cache_maintenance.h
+
cache_maintenance.h
-Go to the documentation of this file.
1 /*
-
2  * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
-
3  *
-
4  * This program is free software; you can redistribute it and/or modify
-
5  * it under the terms of the GNU General Public License as published by
-
6  * the Free Software Foundation; either version 3 of the License, or
-
7  * (at your option) any later version.
-
8  *
-
9  * This program 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
-
12  * GNU General Public License for more details.
-
13  *
-
14  * You should have received a copy of the GNU General Public License
-
15  * along with this program; if not, write to the Free Software
-
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
17  *
-
18  * On Debian systems, the complete text of the GNU General Public License
-
19  * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-
20  */
-
21 
-
40 #ifndef CACHE_MAINTENANCE_H
-
41 #define CACHE_MAINTENANCE_H
-
42 
-
43 #pragma once
-
44 
-
45 #include <time.h>
-
46 
-
52 bool start_cache_maintenance(time_t interval);
- -
58 
-
59 #endif // CACHE_MAINTENANCE_H
+Go to the documentation of this file.
1/*
+
2 * Copyright (C) 2017-2023 Norbert Schlia (nschlia@oblivion-software.de)
+
3 *
+
4 * This program is free software; you can redistribute it and/or modify
+
5 * it under the terms of the GNU General Public License as published by
+
6 * the Free Software Foundation; either version 3 of the License, or
+
7 * (at your option) any later version.
+
8 *
+
9 * This program 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
+
12 * GNU General Public License for more details.
+
13 *
+
14 * You should have received a copy of the GNU General Public License
+
15 * along with this program; if not, write to the Free Software
+
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
17 *
+
18 * On Debian systems, the complete text of the GNU General Public License
+
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
20 */
+
21
+
40#ifndef CACHE_MAINTENANCE_H
+
41#define CACHE_MAINTENANCE_H
+
42
+
43#pragma once
+
44
+
45#include <time.h>
+
46
+
52bool start_cache_maintenance(time_t interval);
+ +
58
+
59#endif // CACHE_MAINTENANCE_H
bool stop_cache_maintenance()
Stop cache maintenance timer.
bool start_cache_maintenance(time_t interval)
Start cache maintenance timer.
diff --git a/html/classBlurayIO-members.html b/html/classBlurayIO-members.html index 78ea51644..22639c2a6 100644 --- a/html/classBlurayIO-members.html +++ b/html/classBlurayIO-members.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
BlurayIO Member List
+
BlurayIO Member List

This is the complete list of members for BlurayIO, including all inherited members.

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
alloc(VIRTUALTYPE type)FileIOstatic
BlurayIO()BlurayIOexplicit
BlurayIO()BlurayIOexplicit
bufsize() const overrideBlurayIOvirtual
closeio() overrideBlurayIOvirtual
closeio() overrideBlurayIOvirtual
duration() const overrideBlurayIOvirtual
eof() const overrideBlurayIOvirtual
eof() const overrideBlurayIOvirtual
error() const overrideBlurayIOvirtual
FileIO()FileIOexplicit
FileIO()FileIOexplicit
filename() constFileIO
m_angle_idxBlurayIOprotected
m_angle_idxBlurayIOprotected
m_bdBlurayIOprotected
m_chapter_idxBlurayIOprotected
m_chapter_idxBlurayIOprotected
m_cur_posBlurayIOprotected
m_dataBlurayIOprotected
m_dataBlurayIOprotected
m_durationBlurayIOprotected
m_end_posBlurayIOprotected
m_end_posBlurayIOprotected
m_errnoBlurayIOprotected
m_full_titleBlurayIOprotected
m_full_titleBlurayIOprotected
m_is_eofBlurayIOprotected
m_pathFileIOprivate
m_pathFileIOprivate
m_rest_posBlurayIOprotected
m_rest_sizeBlurayIOprotected
m_rest_sizeBlurayIOprotected
m_start_posBlurayIOprotected
m_title_idxBlurayIOprotected
m_title_idxBlurayIOprotected
m_virtualfileFileIOprivate
openio(LPVIRTUALFILE virtualfile) overrideBlurayIOvirtual
openio(LPVIRTUALFILE virtualfile) overrideBlurayIOvirtual
path() constFileIO
pvt_close()BlurayIOprivate
pvt_close()BlurayIOprivate
readio(void *data, size_t size) overrideBlurayIOvirtual
seek(int64_t offset, int whence) overrideBlurayIOvirtual
seek(int64_t offset, int whence) overrideBlurayIOvirtual
set_virtualfile(LPVIRTUALFILE virtualfile)FileIOprotected
size() const overrideBlurayIOvirtual
size() const overrideBlurayIOvirtual
tell() const overrideBlurayIOvirtual
type() const overrideBlurayIOvirtual
type() const overrideBlurayIOvirtual
virtualfile()FileIO
~BlurayIO()BlurayIOvirtual
~BlurayIO()BlurayIOvirtual
~FileIO()=defaultFileIOvirtual
diff --git a/html/classBlurayIO.html b/html/classBlurayIO.html index 284a2cbb3..3861194f2 100644 --- a/html/classBlurayIO.html +++ b/html/classBlurayIO.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: BlurayIO Class Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ + -
-
BlurayIO Class Reference
+
BlurayIO Class Reference
@@ -90,25 +89,23 @@
Collaboration graph
- - - - + + + + - - + +
[legend]
- - - + + - - + + @@ -140,19 +137,50 @@ - - + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -163,73 +191,58 @@

+

Public Member Functions

BlurayIO ()
 Create BlurayIO object.
 BlurayIO ()
 Create BlurayIO object. More...
 
-virtual ~BlurayIO ()
 Free BlurayIO object.
virtual ~BlurayIO ()
 Free BlurayIO object. More...
 
virtual VIRTUALTYPE type () const override
 Get type of the virtual file. More...
virtual bool eof () const override
 Check if at end of file. More...
 
-virtual void closeio () override
 Close virtual file.
virtual void closeio () override
 Close virtual file. More...
 
- Public Member Functions inherited from FileIO
FileIO ()
 Create FileIO object.
 FileIO ()
 Create FileIO object. More...
 
-virtual ~FileIO ()=default
+virtual ~FileIO ()=default
 Free FileIO object.
 
virtual VIRTUALTYPE type () const =0
 Get type of the virtual file. More...
 
virtual size_t bufsize () const =0
 Get the ideal buffer size. More...
 
virtual int openio (LPVIRTUALFILE virtualfile)=0
 Open a virtual file. More...
 
virtual size_t readio (void *data, size_t size)=0
 Read data from a file. More...
 
virtual int error () const =0
 Get last error. More...
 
virtual int64_t duration () const =0
 Get the duration of the file, in AV_TIME_BASE fractional seconds. More...
 
virtual size_t size () const =0
 Get the file size. More...
 
virtual size_t tell () const =0
 Get current read position. More...
 
virtual int seek (int64_t offset, int whence)=0
 Seek to position in file. More...
 
virtual bool eof () const =0
 Check if at end of file. More...
 
virtual void closeio ()=0
 Close virtual file. More...
 
LPVIRTUALFILE virtualfile ()
 Get virtual file object. More...
 
 Path to source file (without file name) More...
 
- - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

+

Protected Attributes

-BLURAYm_bd
 Blu-ray disk handle.
BLURAYm_bd
 Blu-ray disk handle. More...
 
-bool m_is_eof
 true if at end of virtual file
bool m_is_eof
 true if at end of virtual file More...
 
-int m_errno
 Last errno.
int m_errno
 Last errno. More...
 
-size_t m_rest_size
 Rest bytes in buffer.
size_t m_rest_size
 Rest bytes in buffer. More...
 
-size_t m_rest_pos
 Position in buffer.
size_t m_rest_pos
 Position in buffer. More...
 
-int64_t m_cur_pos
 Current position in virtual file.
int64_t m_cur_pos
 Current position in virtual file. More...
 
-int64_t m_start_pos
 Start offset in bytes.
int64_t m_start_pos
 Start offset in bytes. More...
 
-int64_t m_end_pos
 End offset in bytes (not including this byte)
int64_t m_end_pos
 End offset in bytes (not including this byte) More...
 
-bool m_full_title
 If true, ignore m_chapter_no and provide full track.
bool m_full_title
 If true, ignore m_chapter_no and provide full track. More...
 
-uint32_t m_title_idx
 Track index (track number - 1)
uint32_t m_title_idx
 Track index (track number - 1) More...
 
-unsigned m_chapter_idx
 Chapter index (chapter number - 1)
unsigned m_chapter_idx
 Chapter index (chapter number - 1) More...
 
-unsigned m_angle_idx
 Selected angle index (angle number -1)
unsigned m_angle_idx
 Selected angle index (angle number -1) More...
 
-uint8_t m_data [192 *1024]
 Buffer for readio() data.
uint8_t m_data [192 *1024]
 Buffer for readio() data. More...
 
-int64_t m_duration
 Track/chapter duration, in AV_TIME_BASE fractional seconds.
int64_t m_duration
 Track/chapter duration, in AV_TIME_BASE fractional seconds. More...
 
- - - + +

+

Private Member Functions

-void pvt_close ()
 Close virtual file. Non-virtual version to be safely called from constructor/destructor.
void pvt_close ()
 Close virtual file. Non-virtual version to be safely called from constructor/destructor. More...
 
- @@ -241,11 +254,74 @@

+

Additional Inherited Members

- Static Public Member Functions inherited from FileIO
static FileIOalloc (VIRTUALTYPE type)
 

Detailed Description

-

Blu-ray I/O class.

+

Blu-ray I/O class.

Definition at line 48 of file blurayio.h.

-

Member Function Documentation

- +

Constructor & Destructor Documentation

+ +

◆ BlurayIO()

+ +
+
+ + + + + +
+ + + + + + + +
BlurayIO::BlurayIO ()
+
+explicit
+
+ +

Create BlurayIO object.

+ +

Definition at line 40 of file blurayio.cc.

+ +

References m_data.

+ +
+
+ +

◆ ~BlurayIO()

+ +
+
+ + + + + +
+ + + + + + + +
BlurayIO::~BlurayIO ()
+
+virtual
+
+ +

Free BlurayIO object.

+ +

Definition at line 58 of file blurayio.cc.

+ +

References pvt_close().

+ +
+
+

Member Function Documentation

+

◆ bufsize()

@@ -279,7 +355,40 @@

+ +

◆ closeio()

+ +
+
+ + + + + +
+ + + + + + + +
void BlurayIO::closeio ()
+
+overridevirtual
+
+ +

Close virtual file.

+ +

Implements FileIO.

+ +

Definition at line 305 of file blurayio.cc.

+ +

References pvt_close().

+ +
+
+

◆ duration()

@@ -313,7 +422,7 @@

+

◆ eof()

@@ -347,7 +456,7 @@

+

◆ error()

@@ -381,7 +490,7 @@

+

◆ openio()

@@ -423,7 +532,40 @@

+ +

◆ pvt_close()

+ +
+
+ + + + + +
+ + + + + + + +
void BlurayIO::pvt_close ()
+
+private
+
+ +

Close virtual file. Non-virtual version to be safely called from constructor/destructor.

+ +

Definition at line 310 of file blurayio.cc.

+ +

References m_bd.

+ +

Referenced by closeio(), and ~BlurayIO().

+ +
+
+

◆ readio()

+ +

◆ m_bd

+ +
+
+ + + + + +
+ + + + +
BLURAY* BlurayIO::m_bd
+
+protected
+
+ +

Blu-ray disk handle.

+ +

Definition at line 141 of file blurayio.h.

+ +

Referenced by openio(), pvt_close(), readio(), seek(), and tell().

+ +
+
+ +

◆ m_chapter_idx

+ +
+
+ + + + + +
+ + + + +
unsigned BlurayIO::m_chapter_idx
+
+protected
+
+ +

Chapter index (chapter number - 1)

+ +

Definition at line 153 of file blurayio.h.

+ +

Referenced by openio().

+ +
+
+ +

◆ m_cur_pos

+ +
+
+ + + + + +
+ + + + +
int64_t BlurayIO::m_cur_pos
+
+protected
+
+ +

Current position in virtual file.

+ +

Definition at line 147 of file blurayio.h.

+ +

Referenced by eof(), readio(), and seek().

+ +
+
+ +

◆ m_data

+ +
+
+ + + + + +
+ + + + +
uint8_t BlurayIO::m_data[192 *1024]
+
+protected
+
+ +

Buffer for readio() data.

+ +

Definition at line 156 of file blurayio.h.

+ +

Referenced by BlurayIO(), bufsize(), and readio().

+ +
+
+ +

◆ m_duration

+ +
+
+ + + + + +
+ + + + +
int64_t BlurayIO::m_duration
+
+protected
+
+ +

Track/chapter duration, in AV_TIME_BASE fractional seconds.

+ +

Definition at line 158 of file blurayio.h.

+ +

Referenced by duration(), and openio().

+ +
+
+ +

◆ m_end_pos

+ +
+
+ + + + + +
+ + + + +
int64_t BlurayIO::m_end_pos
+
+protected
+
+ +

End offset in bytes (not including this byte)

+ +

Definition at line 149 of file blurayio.h.

+ +

Referenced by eof(), openio(), readio(), seek(), and size().

+ +
+
+ +

◆ m_errno

+ +
+
+ + + + + +
+ + + + +
int BlurayIO::m_errno
+
+protected
+
+ +

Last errno.

+ +

Definition at line 144 of file blurayio.h.

+ +

Referenced by error().

+ +
+
+ +

◆ m_full_title

+ +
+
+ + + + + +
+ + + + +
bool BlurayIO::m_full_title
+
+protected
+
+ +

If true, ignore m_chapter_no and provide full track.

+ +

Definition at line 151 of file blurayio.h.

+ +

Referenced by openio().

+ +
+
+ +

◆ m_is_eof

+ +
+
+ + + + + +
+ + + + +
bool BlurayIO::m_is_eof
+
+protected
+
+ +

true if at end of virtual file

+ +

Definition at line 143 of file blurayio.h.

+ +
+
+ +

◆ m_rest_pos

+ +
+
+ + + + + +
+ + + + +
size_t BlurayIO::m_rest_pos
+
+protected
+
+ +

Position in buffer.

+ +

Definition at line 146 of file blurayio.h.

+ +

Referenced by openio(), and readio().

+ +
+
+ +

◆ m_rest_size

+ +
+
+ + + + + +
+ + + + +
size_t BlurayIO::m_rest_size
+
+protected
+
+ +

Rest bytes in buffer.

+ +

Definition at line 145 of file blurayio.h.

+ +

Referenced by openio(), and readio().

+ +
+
+ +

◆ m_start_pos

+ +
+
+ + + + + +
+ + + + +
int64_t BlurayIO::m_start_pos
+
+protected
+
+ +

Start offset in bytes.

+ +

Definition at line 148 of file blurayio.h.

+ +

Referenced by openio(), seek(), size(), and tell().

+ +
+
+ +

◆ m_title_idx

+ +
+
+ + + + + +
+ + + + +
uint32_t BlurayIO::m_title_idx
+
+protected
+
+ +

Track index (track number - 1)

+ +

Definition at line 152 of file blurayio.h.

+ +

Referenced by openio().

+

The documentation for this class was generated from the following files:
    @@ -646,7 +1179,7 @@

    diff --git a/html/classBlurayIO__coll__graph.map b/html/classBlurayIO__coll__graph.map index 1746ecd41..1ed3afae2 100644 --- a/html/classBlurayIO__coll__graph.map +++ b/html/classBlurayIO__coll__graph.map @@ -1,9 +1,9 @@ - - - - + + + + - - + + diff --git a/html/classBlurayIO__coll__graph.md5 b/html/classBlurayIO__coll__graph.md5 index f00eb68e5..ebd8a9d6b 100644 --- a/html/classBlurayIO__coll__graph.md5 +++ b/html/classBlurayIO__coll__graph.md5 @@ -1 +1 @@ -bdbab23e003c8c2c925678bd61ff479f \ No newline at end of file +808f1e10c9e2b32fb00192ed00ed0c26 \ No newline at end of file diff --git a/html/classBlurayIO__coll__graph.png b/html/classBlurayIO__coll__graph.png index 05f39a59ee9b2cad34232999ccd185e9095994aa..0b9601c81249e695562870527ac2af171c98aa89 100644 GIT binary patch literal 23888 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 literal 24423 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 diff --git a/html/classBuffer-members.html b/html/classBuffer-members.html index ea80ebb96..024fa3fb4 100644 --- a/html/classBuffer-members.html +++ b/html/classBuffer-members.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
    - - + @@ -30,21 +29,22 @@
    -
    FFmpegfs Fuse Multi Media Filesystem -  2.14 +
    +
    FFmpegfs Fuse Multi Media Filesystem 2.14
    - + +/* @license-end */ +
    -
    -
    Buffer Member List
    +
    Buffer Member List

    This is the complete list of members for Buffer, including all inherited members.

    - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
    alloc(VIRTUALTYPE type)FileIOstatic
    Buffer()Bufferexplicit
    Buffer()Bufferexplicit
    buffer_watermark(uint32_t segment_no=0) constBuffer
    bufsize() const overrideBuffervirtual
    bufsize() const overrideBuffervirtual
    cachefile(uint32_t segment_no) constBuffer
    CACHEINFO typedefBuffer
    CACHEINFO typedefBuffer
    cacheinfo(uint32_t segment_no)Bufferprivate
    clear()Buffer
    clear()Buffer
    close_file(uint32_t segment_no, uint32_t flags)Buffer
    closeio() overrideBuffervirtual
    closeio() overrideBuffervirtual
    const_cacheinfo(uint32_t segment_no) constBufferprivate
    copy(std::vector< uint8_t > *out_data, size_t offset, uint32_t segment_no=0)Buffer
    copy(std::vector< uint8_t > *out_data, size_t offset, uint32_t segment_no=0)Buffer
    copy(uint8_t *out_data, size_t offset, size_t bufsize, uint32_t segment_no=0)Buffer
    current_segment_no()Buffer
    current_segment_no()Buffer
    duration() const overrideBuffervirtual
    eof() const overrideBuffervirtual
    eof() const overrideBuffervirtual
    eof(uint32_t segment_no) constBuffervirtual
    error() const overrideBuffervirtual
    error() const overrideBuffervirtual
    FileIO()FileIOexplicit
    filename() constFileIO
    filename() constFileIO
    finished_segment()Buffer
    flush()Buffer
    flush()Buffer
    have_frame(uint32_t frame_no)Buffer
    increment_pos(size_t increment)Bufferprivate
    increment_pos(size_t increment)Bufferprivate
    init(bool erase_cache)Buffer
    is_open()Bufferprotected
    is_open()Bufferprotected
    is_segment_finished(uint32_t segment_no) constBuffer
    LPCACHEINFO typedefBuffer
    LPCACHEINFO typedefBuffer
    LPCCACHEINFO typedefBuffer
    m_ciBufferprivate
    m_ciBufferprivate
    m_cur_ciBufferprivate
    m_cur_openBufferprivate
    m_cur_openBufferprivate
    m_mutexBufferprivate
    m_pathFileIOprivate
    m_pathFileIOprivate
    m_virtualfileFileIOprivate
    make_cachefile_name(std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)Bufferstatic
    make_cachefile_name(std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)Bufferstatic
    map_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t *filesize, bool *isdefaultsize, size_t defaultsize, bool truncate) constBufferprivate
    open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize=0)Buffer
    open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize=0)Buffer
    openio(LPVIRTUALFILE virtualfile) overrideBuffervirtual
    path() constFileIO
    path() constFileIO
    PREALLOC_FACTORBufferprivatestatic
    read_frame(std::vector< uint8_t > *data, uint32_t frame_no)Buffer
    read_frame(std::vector< uint8_t > *data, uint32_t frame_no)Buffer
    readio(void *data, size_t size) overrideBuffervirtual
    reallocate(size_t newsize)Bufferprivate
    reallocate(size_t newsize)Bufferprivate
    release(int flags=CACHE_CLOSE_NOOPT)Buffer
    remove_cachefile(uint32_t segment_no=0) constBufferprotected
    remove_cachefile(uint32_t segment_no=0) constBufferprotected
    remove_file(const std::string &filename)Bufferstatic
    reserve(size_t size)Buffer
    reserve(size_t size)Buffer
    seek(int64_t offset, int whence) overrideBuffervirtual
    seek(int64_t offset, int whence, uint32_t segment_no)Buffervirtual
    seek(int64_t offset, int whence, uint32_t segment_no)Buffervirtual
    segment_count()Buffer
    segment_exists(uint32_t segment_no)Buffer
    segment_exists(uint32_t segment_no)Buffer
    set_segment(uint32_t segment_no, size_t size)Buffer
    set_virtualfile(LPVIRTUALFILE virtualfile)FileIOprotected
    set_virtualfile(LPVIRTUALFILE virtualfile)FileIOprotected
    size() const overrideBuffervirtual
    size(uint32_t segment_no) constBuffervirtual
    size(uint32_t segment_no) constBuffervirtual
    tell() const overrideBuffervirtual
    tell(uint32_t segment_no) constBuffervirtual
    tell(uint32_t segment_no) constBuffervirtual
    type() const overrideBuffervirtual
    unmap_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t len, size_t *filesize) constBufferprivate
    unmap_file(const std::string &filename, volatile int *fd, uint8_t **p, size_t len, size_t *filesize) constBufferprivate
    virtualfile()FileIO
    write_frame(const uint8_t *data, size_t length, uint32_t frame_no)Buffer
    write_frame(const uint8_t *data, size_t length, uint32_t frame_no)Buffer
    write_prepare(size_t length)Bufferprivate
    writeio(const uint8_t *data, size_t length)Buffer
    writeio(const uint8_t *data, size_t length)Buffer
    ~Buffer()Buffervirtual
    ~FileIO()=defaultFileIOvirtual
    ~FileIO()=defaultFileIOvirtual
    diff --git a/html/classBuffer.html b/html/classBuffer.html index 48dc78fe2..d1f6c3361 100644 --- a/html/classBuffer.html +++ b/html/classBuffer.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Buffer Class Reference @@ -19,10 +19,9 @@
    - - + @@ -30,21 +29,22 @@
    -
    FFmpegfs Fuse Multi Media Filesystem -  2.14 +
    +
    FFmpegfs Fuse Multi Media Filesystem 2.14
    - + +/* @license-end */ + -
    -
    Buffer Class Reference
    +
    Buffer Class Reference
    @@ -95,43 +94,41 @@
    Collaboration graph
    - - - - + + + + - - - + + +
    [legend]
    -

    +

    Classes

    struct  _tagCACHEINFO
     Structure to hold current cache state. More...
     
    - - + - + - - + +

    +

    Public Types

    -typedef struct Buffer::_tagCACHEINFO CACHEINFO
    +typedef struct Buffer::_tagCACHEINFO CACHEINFO
     Structure to hold current cache state.
     
    -typedef struct Buffer::_tagCACHEINFOLPCACHEINFO
    +typedef struct Buffer::_tagCACHEINFOLPCACHEINFO
     Pointer version of CACHEINFO.
     
    -typedef CACHEINFO const * LPCCACHEINFO
     Pointer to const version of CACHEINFO.
    typedef CACHEINFO const * LPCCACHEINFO
     Pointer to const version of CACHEINFO. More...
     
    - - - + + @@ -199,9 +196,8 @@ - - + + @@ -233,9 +229,8 @@ - - + + @@ -247,14 +242,46 @@ - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -265,7 +292,7 @@

    +

    Public Member Functions

    Buffer ()
     Create Buffer object.
     Buffer ()
     Create Buffer object. More...
     
    virtual ~Buffer ()
     Free Buffer object. More...
    virtual bool eof (uint32_t segment_no) const
     Check if at end of file. More...
     
    -virtual void closeio () override
     Close buffer.
    virtual void closeio () override
     Close buffer. More...
     
    size_t writeio (const uint8_t *data, size_t length)
     Write data to the current position in the buffer. The position pointer will be updated. More...
    bool have_frame (uint32_t frame_no)
     Check if we have the requested frame number. Works only when processing a frame set. More...
     
    -void finished_segment ()
     Complete the segment decoding.
    void finished_segment ()
     Complete the segment decoding. More...
     
    bool is_segment_finished (uint32_t segment_no) const
     Return true if transcoding of the segment is finished. More...
     If it hasn't already been done, close the cache file. More...
     
    - Public Member Functions inherited from FileIO
    FileIO ()
     Create FileIO object.
     FileIO ()
     Create FileIO object. More...
     
    -virtual ~FileIO ()=default
    +virtual ~FileIO ()=default
     Free FileIO object.
     
    virtual VIRTUALTYPE type () const =0
     Get type of the virtual file. More...
     
    virtual size_t bufsize () const =0
     Get the ideal buffer size. More...
     
    virtual int openio (LPVIRTUALFILE virtualfile)=0
     Open a virtual file. More...
     
    virtual size_t readio (void *data, size_t size)=0
     Read data from a file. More...
     
    virtual int error () const =0
     Get last error. More...
     
    virtual int64_t duration () const =0
     Get the duration of the file, in AV_TIME_BASE fractional seconds. More...
     
    virtual size_t size () const =0
     Get the file size. More...
     
    virtual size_t tell () const =0
     Get current read position. More...
     
    virtual int seek (int64_t offset, int whence)=0
     Seek to position in file. More...
     
    virtual bool eof () const =0
     Check if at end of file. More...
     
    virtual void closeio ()=0
     Close virtual file. More...
     
    LPVIRTUALFILE virtualfile ()
     Get virtual file object. More...
     
     Path to source file (without file name) More...
     
    - @@ -278,7 +305,7 @@

    +

    Static Public Member Functions

    static const std::string & make_cachefile_name (std::string &cachefile, const std::string &filename, const std::string &fileext, bool is_idx)
     Make up a cache file name, including the full path. More...
     Allocate the correct object for type(). More...
     
    - @@ -291,7 +318,7 @@

    +

    Protected Member Functions

    bool remove_cachefile (uint32_t segment_no=0) const
     Remove the cachefile. More...
     Set the virtual file object. More...
     
    - @@ -315,38 +342,81 @@

    +

    Private Member Functions

    uint8_t * write_prepare (size_t length)
     Prepare for the writing operation. More...
     Get cache information. More...
     
    - - - + + - - + + - - + + - - + +

    +

    Private Attributes

    -std::recursive_mutex m_mutex
     Access mutex.
    std::recursive_mutex m_mutex
     Access mutex. More...
     
    -LPCACHEINFO m_cur_ci
     Convenience pointer to current write segment.
    LPCACHEINFO m_cur_ci
     Convenience pointer to current write segment. More...
     
    -uint32_t m_cur_open
     Number of open files.
    uint32_t m_cur_open
     Number of open files. More...
     
    -std::vector< CACHEINFOm_ci
     Cache info.
    std::vector< CACHEINFOm_ci
     Cache info. More...
     
    - - - + +

    +

    Static Private Attributes

    -static constexpr int PREALLOC_FACTOR = 5
     PREALLOC_FACTOR - Number of elements allocated on reallocate calls Number of elements allocated on reallocate calls. The buffer keeps track of the typical buffer write size. To prevent repeated reallocations, reallocate() attempts to set aside enough memory for PREALLOC FACTOR average elements whenever it is invoked.
    static constexpr int PREALLOC_FACTOR = 5
     PREALLOC_FACTOR - Number of elements allocated on reallocate calls Number of elements allocated on reallocate calls. The buffer keeps track of the typical buffer write size. To prevent repeated reallocations, reallocate() attempts to set aside enough memory for PREALLOC FACTOR average elements whenever it is invoked. More...
     

    Detailed Description

    -

    The Buffer class.

    +

    The Buffer class.

    Definition at line 55 of file buffer.h.

    -

    Constructor & Destructor Documentation

    - +

    Member Typedef Documentation

    + +

    ◆ LPCCACHEINFO

    + +
    +
    + + + + +
    typedef CACHEINFO const* Buffer::LPCCACHEINFO
    +
    + +

    Pointer to const version of CACHEINFO.

    + +

    Definition at line 121 of file buffer.h.

    + +
    +
    +

    Constructor & Destructor Documentation

    + +

    ◆ Buffer()

    + +
    +
    + + + + + +
    + + + + + + + +
    Buffer::Buffer ()
    +
    +explicit
    +
    + +

    Create Buffer object.

    + +

    Definition at line 42 of file buffer.cc.

    + +
    +
    +

    ◆ ~Buffer()

    @@ -370,7 +440,7 @@

    Free Buffer object.

    -

    Release memory and close files

    +

    Release memory and close files

    Definition at line 49 of file buffer.cc.

    @@ -379,7 +449,7 @@

    Member Function Documentation

    - +

    ◆ buffer_watermark()

    @@ -396,7 +466,7 @@

    Return the current watermark of the file while transcoding.

    -

    While transcoding, this value reflects the current size of the transcoded file. This is the maximum byte offset until the file can be read so far.

    +

    While transcoding, this value reflects the current size of the transcoded file. This is the maximum byte offset until the file can be read so far.

    Parameters
    @@ -407,13 +477,13 @@

    Definition at line 865 of file buffer.cc.

    -

    References const_cacheinfo().

    +

    References const_cacheinfo().

    -

    Referenced by FFmpeg_Transcoder::encode_finish(), Cache_Entry::size(), transcode(), transcode_finish(), transcoder_buffer_watermark(), and write_frame().

    +

    Referenced by FFmpeg_Transcoder::encode_finish(), Cache_Entry::size(), transcode(), transcode_finish(), transcoder_buffer_watermark(), and write_frame().

    - +

    ◆ bufsize()

    @@ -447,7 +517,7 @@

    +

    ◆ cachefile()

    @@ -472,15 +542,15 @@

    Returns
    Returns cache filename.
    -

    Definition at line 964 of file buffer.cc.

    +

    Definition at line 957 of file buffer.cc.

    -

    References const_cacheinfo().

    +

    References const_cacheinfo().

    -

    Referenced by init(), and make_cachefile_name().

    +

    Referenced by make_cachefile_name().

    - +

    ◆ cacheinfo()

    @@ -513,7 +583,7 @@

    Returns
    Pointer to CACHEINFO object, or nullptr on error.
    -

    Definition at line 1125 of file buffer.cc.

    +

    Definition at line 1118 of file buffer.cc.

    References m_ci, m_cur_ci, and segment_count().

    @@ -521,7 +591,7 @@

    +

    ◆ clear()

    @@ -541,13 +611,13 @@

    Definition at line 587 of file buffer.cc.

    -

    References Logging::error(), m_ci, m_mutex, and remove_file().

    +

    References Logging::error(), m_ci, m_mutex, and remove_file().

    -

    Referenced by Cache_Entry::clear().

    +

    Referenced by Cache_Entry::clear().

    - +

    ◆ close_file()

    @@ -591,7 +661,40 @@

    + +

    ◆ closeio()

    + +
    +
    +

    [in]segment_no- If > 0 returns watermark for specific segment. If 0, returns watermark for current write segment.
    + + + + +
    + + + + + + + +
    void Buffer::closeio ()
    +
    +overridevirtual
    +

    + +

    Close buffer.

    + +

    Implements FileIO.

    + +

    Definition at line 1054 of file buffer.cc.

    + +

    References release().

    + +
    +

    +

    ◆ const_cacheinfo()

    - +

    ◆ copy() [1/2]

- +

◆ copy() [2/2]

- +

◆ current_segment_no()

@@ -763,7 +868,7 @@

+

◆ duration()

@@ -795,7 +900,7 @@

+

◆ eof() [1/2]

@@ -823,13 +928,15 @@

FileIO.

-

Definition at line 1051 of file buffer.cc.

+

Definition at line 1044 of file buffer.cc.

-

Referenced by FFmpeg_Transcoder::read_aiff_chunk().

+

References eof().

+ +

Referenced by eof(), and FFmpeg_Transcoder::read_aiff_chunk().

- +

◆ eof() [2/2]

@@ -862,13 +969,13 @@

Returns
Returns true if at end of buffer.
-

Definition at line 1056 of file buffer.cc.

+

Definition at line 1049 of file buffer.cc.

References size(), and tell().

- +

◆ error()

@@ -896,11 +1003,36 @@

FileIO.

-

Definition at line 1046 of file buffer.cc.

+

Definition at line 1039 of file buffer.cc.

+ +

+

+ +

◆ finished_segment()

+ +
+
+ + + + + + + +
void Buffer::finished_segment ()
+
+ +

Complete the segment decoding.

+ +

Definition at line 1093 of file buffer.cc.

+ +

References flush(), m_cur_ci, and Buffer::_tagCACHEINFO::m_seg_finished.

+ +

Referenced by FFmpeg_Transcoder::encode_finish().

- +

◆ flush()

- +

◆ have_frame()

- +

◆ increment_pos()

- +

◆ is_open()

@@ -1058,7 +1190,7 @@

Returns
Returns true if the cache file is open; false if not.
-

Definition at line 1085 of file buffer.cc.

+

Definition at line 1078 of file buffer.cc.

References m_ci, and m_mutex.

@@ -1066,7 +1198,7 @@

+

◆ is_segment_finished()

@@ -1091,15 +1223,15 @@

Returns
Returns true if finished, false if not.
-

Definition at line 1112 of file buffer.cc.

+

Definition at line 1105 of file buffer.cc.

-

References const_cacheinfo().

+

References const_cacheinfo().

Referenced by transcode_until().

- +

◆ make_cachefile_name()

- +

◆ map_file()

- +

◆ open_file()

- +

◆ openio()

@@ -1348,7 +1480,7 @@

+

◆ read_frame()

@@ -1388,7 +1520,7 @@

error() will return 0 if at EOF.
If the image frame is not yet read, the function also returns 0 and errno is EAGAIN.

-

Definition at line 1019 of file buffer.cc.

+

Definition at line 1012 of file buffer.cc.

References copy(), Buffer::_tagCACHEINFO::m_buffer_idx, m_cur_ci, m_mutex, and FileIO::virtualfile().

@@ -1396,7 +1528,7 @@

+

◆ readio()

@@ -1442,11 +1574,11 @@

FileIO.

-

Definition at line 1012 of file buffer.cc.

+

Definition at line 1005 of file buffer.cc.

- +

◆ reallocate()

- +

◆ remove_cachefile()

- +

◆ remove_file()

- +

◆ seek() [1/2]

@@ -1670,7 +1802,7 @@

Seek to position in file.

-

Repositions the offset of the open file to the argument offset according to the directive whence. May block for a long time if the buffer has not been filled to the requested offset.

+

Repositions the offset of the open file to the argument offset according to the directive whence. May block for a long time if the buffer has not been filled to the requested offset.

Parameters
@@ -1687,11 +1819,13 @@

Definition at line 767 of file buffer.cc.

-

Referenced by FFmpeg_Transcoder::create_fake_aiff_header(), FFmpeg_Transcoder::create_fake_wav_header(), and write_frame().

+

References seek().

+ +

Referenced by FFmpeg_Transcoder::create_fake_aiff_header(), FFmpeg_Transcoder::create_fake_wav_header(), seek(), and write_frame().

- +

◆ seek() [2/2]

[in]offset- offset in bytes
@@ -1748,11 +1882,11 @@

Definition at line 772 of file buffer.cc.

-

References cacheinfo(), Buffer::_tagCACHEINFO::m_buffer, Buffer::_tagCACHEINFO::m_buffer_pos, size(), and tell().

+

References cacheinfo(), Buffer::_tagCACHEINFO::m_buffer, Buffer::_tagCACHEINFO::m_buffer_pos, size(), and tell().

- +

◆ segment_count()

- +

◆ segment_exists()

- +

◆ set_segment()

- +

◆ size() [1/2]

@@ -1885,11 +2019,13 @@

Definition at line 847 of file buffer.cc.

-

Referenced by eof(), reallocate(), reserve(), seek(), and set_segment().

+

References size().

+ +

Referenced by eof(), reallocate(), reserve(), seek(), set_segment(), and size().

- +

◆ size() [2/2]

@@ -1924,11 +2060,11 @@

Definition at line 852 of file buffer.cc.

-

References const_cacheinfo().

+

References const_cacheinfo().

- +

◆ tell() [1/2]

- +

◆ tell() [2/2]

@@ -1997,11 +2135,11 @@

Definition at line 829 of file buffer.cc.

-

References const_cacheinfo().

+

References const_cacheinfo().

- +

◆ type()

@@ -2035,7 +2173,7 @@

+

◆ unmap_file()

- +

◆ write_prepare()

@@ -2184,7 +2322,7 @@

Prepare for the writing operation.

-

Ensure the buffer has sufficient space for the quantity of data and return a pointer to where the data may be written. The position pointer should be updated afterward with increment_pos().

Parameters
+

Ensure the buffer has sufficient space for the quantity of data and return a pointer to where the data may be written. The position pointer should be updated afterward with increment_pos().

Parameters

[in]offset- offset in bytes
[in]length- Buffer length to prepare.
@@ -2194,13 +2332,13 @@

Definition at line 745 of file buffer.cc.

-

References Buffer::_tagCACHEINFO::m_buffer, Buffer::_tagCACHEINFO::m_buffer_pos, Buffer::_tagCACHEINFO::m_buffer_watermark, m_cur_ci, and reallocate().

+

References Buffer::_tagCACHEINFO::m_buffer, Buffer::_tagCACHEINFO::m_buffer_pos, Buffer::_tagCACHEINFO::m_buffer_watermark, m_cur_ci, and reallocate().

Referenced by writeio().

- +

◆ writeio()

+
+

Member Data Documentation

+ +

◆ m_ci

+ +
+
+ + + + + +
+ + + + +
std::vector<CACHEINFO> Buffer::m_ci
+
+private
+
+
+ +

◆ m_cur_ci

+ +
+
+ + + + + +
+ + + + +
LPCACHEINFO Buffer::m_cur_ci
+
+private
+
+
+ +

◆ m_cur_open

+ +
+
+ + + + + +
+ + + + +
uint32_t Buffer::m_cur_open
+
+private
+
+ +

Number of open files.

+ +

Definition at line 475 of file buffer.h.

+ +

Referenced by close_file(), and open_file().

+ +
+
+ +

◆ m_mutex

+ +
+
+ + + + + +
+ + + + +
std::recursive_mutex Buffer::m_mutex
+
+private
+
+
+ +

◆ PREALLOC_FACTOR

+ +
+
+ + + + + +
+ + + + +
constexpr int Buffer::PREALLOC_FACTOR = 5
+
+staticconstexprprivate
+
+ +

PREALLOC_FACTOR - Number of elements allocated on reallocate calls Number of elements allocated on reallocate calls. The buffer keeps track of the typical buffer write size. To prevent repeated reallocations, reallocate() attempts to set aside enough memory for PREALLOC FACTOR average elements whenever it is invoked.

+ +

Definition at line 64 of file buffer.h.

+ +

Referenced by reallocate().

@@ -2251,7 +2530,7 @@

diff --git a/html/classBuffer__coll__graph.map b/html/classBuffer__coll__graph.map index e3d39962f..a2ce2581f 100644 --- a/html/classBuffer__coll__graph.map +++ b/html/classBuffer__coll__graph.map @@ -1,10 +1,10 @@ - - - - + + + + - - - + + + diff --git a/html/classBuffer__coll__graph.md5 b/html/classBuffer__coll__graph.md5 index 3be93faf4..92eb7e4a8 100644 --- a/html/classBuffer__coll__graph.md5 +++ b/html/classBuffer__coll__graph.md5 @@ -1 +1 @@ -a4705d0306651604cf86a90af7b8a1c5 \ No newline at end of file +80b8972b3bfec1533c4430517194ca32 \ No newline at end of file diff --git a/html/classBuffer__coll__graph.png b/html/classBuffer__coll__graph.png index 7c02181e10e39bc23703f213ad1b67329bab1487..5b067ee4f940a37aef5c3efc3bac82b8775d60b9 100644 GIT binary patch literal 29059 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 literal 30150 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 - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
Cache Member List
+
Cache Member List

This is the complete list of members for Cache, including all inherited members.

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
begin_transaction()Cacheprotected
Cache()Cacheexplicit
Cache()Cacheexplicit
Cache_Entry (defined in Cache)Cachefriend
cache_key_t typedefCacheprivate
cache_key_t typedefCacheprivate
cache_t typedefCacheprivate
check_min_version(int *db_version_major, int *db_version_minor)Cacheprotected
check_min_version(int *db_version_major, int *db_version_minor)Cacheprotected
clear()Cache
close_index()Cacheprotected
close_index()Cacheprotected
closeio(Cache_Entry **cache_entry, int flags=CACHE_CLOSE_NOOPT)Cache
cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r)Cacheprotected
cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r)Cacheprotected
column_exists(const char *table, const char *column)Cacheprotected
create_entry(LPVIRTUALFILE virtualfile, const std::string &desttype)Cacheprotected
create_entry(LPVIRTUALFILE virtualfile, const std::string &desttype)Cacheprotected
create_table_cache_entry(LPCTABLE_DEF table, const TABLECOLUMNS_VEC &columns)Cacheprotected
delete_entry(Cache_Entry **cache_entry, int flags)Cacheprotected
delete_entry(Cache_Entry **cache_entry, int flags)Cacheprotected
delete_info(const std::string &filename, const std::string &desttype)Cacheprotected
end_transaction()Cacheprotected
end_transaction()Cacheprotected
expanded_sql(sqlite3_stmt *pStmt)Cacheprotected
load_index()Cache
load_index()Cache
LPCTABLE_COLUMNS typedefCache
LPCTABLE_DEF typedefCache
LPCTABLE_DEF typedefCache
LPCTABLECOLUMNS_VEC typedefCache
LPTABLE_COLUMNS typedefCache
LPTABLE_COLUMNS typedefCache
LPTABLE_DEF typedefCache
LPTABLECOLUMNS_VEC typedefCache
LPTABLECOLUMNS_VEC typedefCache
m_cacheCacheprivate
m_cacheidx_dbCacheprivate
m_cacheidx_dbCacheprivate
m_cacheidx_delete_stmtCacheprivate
m_cacheidx_fileCacheprivate
m_cacheidx_fileCacheprivate
m_cacheidx_insert_stmtCacheprivate
m_cacheidx_select_stmtCacheprivate
m_cacheidx_select_stmtCacheprivate
m_columns_cache_entryCacheprivatestatic
m_columns_versionCacheprivatestatic
m_columns_versionCacheprivatestatic
m_mutexCacheprivate
m_table_cache_entryCacheprivatestatic
m_table_cache_entryCacheprivatestatic
m_table_versionCacheprivatestatic
maintenance(size_t predicted_filesize=0)Cache
maintenance(size_t predicted_filesize=0)Cache
openio(LPVIRTUALFILE virtualfile)Cache
prepare_stmts()Cacheprotected
prepare_stmts()Cacheprotected
prune_cache_size()Cache
prune_disk_space(size_t predicted_filesize)Cache
prune_disk_space(size_t predicted_filesize)Cache
prune_expired()Cache
read_info(LPCACHE_INFO cache_info)Cacheprotected
read_info(LPCACHE_INFO cache_info)Cacheprotected
remove_cachefile(const std::string &filename, const std::string &fileext)Cache
rollback_transaction()Cacheprotected
rollback_transaction()Cacheprotected
table_exists(const char *table)Cacheprotected
TABLECOLUMNS_VEC typedefCache
TABLECOLUMNS_VEC typedefCache
upgrade_db(int *db_version_major, int *db_version_minor)Cacheprotected
write_info(LPCCACHE_INFO cache_info)Cacheprotected
write_info(LPCCACHE_INFO cache_info)Cacheprotected
~Cache()Cachevirtual
diff --git a/html/classCache.html b/html/classCache.html index fc418fbfa..0b1b2f3fc 100644 --- a/html/classCache.html +++ b/html/classCache.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Cache Class Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
Static Private Attributes | Friends | List of all members
-
-
Cache Class Reference
+
Cache Class Reference
@@ -91,7 +90,7 @@
[legend]
- @@ -100,46 +99,37 @@

+

Classes

struct  TABLE_COLUMNS
 Column definition of sql table. More...
 Definition of sql table. More...
 
- - - + + - - + + - - + + - - + + - - + + - - + + - - + +

+

Public Types

-typedef TABLE_DEF const * LPCTABLE_DEF
 Pointer version of TABLE_DEF.
typedef TABLE_DEF const * LPCTABLE_DEF
 Pointer version of TABLE_DEF. More...
 
-typedef TABLE_DEFLPTABLE_DEF
 Pointer to const version of TABLE_DEF.
typedef TABLE_DEFLPTABLE_DEF
 Pointer to const version of TABLE_DEF. More...
 
-typedef TABLE_COLUMNS const * LPCTABLE_COLUMNS
 Pointer version of TABLE_COLUMNS.
typedef TABLE_COLUMNS const * LPCTABLE_COLUMNS
 Pointer version of TABLE_COLUMNS. More...
 
-typedef TABLE_COLUMNSLPTABLE_COLUMNS
 Pointer to const version of TABLE_COLUMNS.
typedef TABLE_COLUMNSLPTABLE_COLUMNS
 Pointer to const version of TABLE_COLUMNS. More...
 
-typedef std::vector< TABLE_COLUMNSTABLECOLUMNS_VEC
 Table columns array.
typedef std::vector< TABLE_COLUMNSTABLECOLUMNS_VEC
 Table columns array. More...
 
-typedef TABLECOLUMNS_VEC const * LPCTABLECOLUMNS_VEC
 Pointer version of TABLECOLUMNS_VEC.
typedef TABLECOLUMNS_VEC const * LPCTABLECOLUMNS_VEC
 Pointer version of TABLECOLUMNS_VEC. More...
 
-typedef TABLECOLUMNS_VECLPTABLECOLUMNS_VEC
 Pointer to const version of TABLECOLUMNS_VEC.
typedef TABLECOLUMNS_VECLPTABLECOLUMNS_VEC
 Pointer to const version of TABLECOLUMNS_VEC. More...
 
- - - + + - - + + @@ -169,7 +159,7 @@

+

Public Member Functions

Cache ()
 Construct Cache object.
 Cache ()
 Construct Cache object. More...
 
-virtual ~Cache ()
 Destruct Cache object.
virtual ~Cache ()
 Destruct Cache object. More...
 
Cache_Entryopenio (LPVIRTUALFILE virtualfile)
 Open cache entry. More...
 Remove a cache file from disk. More...
 
- @@ -186,9 +176,8 @@ - - + + @@ -224,56 +213,46 @@

+

Protected Member Functions

bool read_info (LPCACHE_INFO cache_info)
 Read cache file info. More...
bool delete_entry (Cache_Entry **cache_entry, int flags)
 Delete cache entry object. More...
 
-void close_index ()
 Close cache index.
void close_index ()
 Close cache index. More...
 
std::string expanded_sql (sqlite3_stmt *pStmt)
 Get expanded SQL string for a statement. More...
 Upgrade database from version below 1.95. More...
 
- - - + + - - + +

+

Private Types

-typedef std::pair< std::string, std::string > cache_key_t
 Filenames and destination types.
typedef std::pair< std::string, std::string > cache_key_t
 Filenames and destination types. More...
 
-typedef std::map< cache_key_t, Cache_Entry * > cache_t
 Map of cache entries.
typedef std::map< cache_key_t, Cache_Entry * > cache_t
 Map of cache entries. More...
 
- - - + + - - + + - - + + - - + + - - + + - - + + - - + +

+

Private Attributes

-std::recursive_mutex m_mutex
 Access mutex.
std::recursive_mutex m_mutex
 Access mutex. More...
 
-std::string m_cacheidx_file
 Name of SQLite cache index database.
std::string m_cacheidx_file
 Name of SQLite cache index database. More...
 
-sqlite3 * m_cacheidx_db
 SQLite handle of cache index database.
sqlite3 * m_cacheidx_db
 SQLite handle of cache index database. More...
 
-sqlite3_stmt * m_cacheidx_select_stmt
 Prepared select statement.
sqlite3_stmt * m_cacheidx_select_stmt
 Prepared select statement. More...
 
-sqlite3_stmt * m_cacheidx_insert_stmt
 Prepared insert statement.
sqlite3_stmt * m_cacheidx_insert_stmt
 Prepared insert statement. More...
 
-sqlite3_stmt * m_cacheidx_delete_stmt
 Prepared delete statement.
sqlite3_stmt * m_cacheidx_delete_stmt
 Prepared delete statement. More...
 
-cache_t m_cache
 Cache file (memory mapped file)
cache_t m_cache
 Cache file (memory mapped file) More...
 
- - - + + @@ -282,18 +261,257 @@

+

Static Private Attributes

static const TABLE_DEF m_table_cache_entry
 Definition and indexes of table "cache_entry". More...
 
-static const TABLECOLUMNS_VEC m_columns_cache_entry
 Columns of table "cache_entry".
static const TABLECOLUMNS_VEC m_columns_cache_entry
 Columns of table "cache_entry". More...
 
static const TABLE_DEF m_table_version
 Definition and indexes of table "version". More...
 Columns of table "version". More...
 
- - +

+

Friends

-class Cache_Entry
class Cache_Entry
 

Detailed Description

-

The Cache class.

+

The Cache class.

Definition at line 101 of file cache.h.

-

Member Function Documentation

- +

Member Typedef Documentation

+ +

◆ cache_key_t

+ +
+
+ + + + + +
+ + + + +
typedef std::pair<std::string, std::string> Cache::cache_key_t
+
+private
+
+ +

Filenames and destination types.

+ +

Definition at line 103 of file cache.h.

+ +
+
+ +

◆ cache_t

+ +
+
+ + + + + +
+ + + + +
typedef std::map<cache_key_t, Cache_Entry *> Cache::cache_t
+
+private
+
+ +

Map of cache entries.

+ +

Definition at line 104 of file cache.h.

+ +
+
+ +

◆ LPCTABLE_COLUMNS

+ +
+
+ + + + +
typedef TABLE_COLUMNS const* Cache::LPCTABLE_COLUMNS
+
+ +

Pointer version of TABLE_COLUMNS.

+ +

Definition at line 125 of file cache.h.

+ +
+
+ +

◆ LPCTABLE_DEF

+ +
+
+ + + + +
typedef TABLE_DEF const* Cache::LPCTABLE_DEF
+
+ +

Pointer version of TABLE_DEF.

+ +

Definition at line 114 of file cache.h.

+ +
+
+ +

◆ LPCTABLECOLUMNS_VEC

+ +
+
+ + + + +
typedef TABLECOLUMNS_VEC const* Cache::LPCTABLECOLUMNS_VEC
+
+ +

Pointer version of TABLECOLUMNS_VEC.

+ +

Definition at line 129 of file cache.h.

+ +
+
+ +

◆ LPTABLE_COLUMNS

+ +
+
+ +

Pointer to const version of TABLE_COLUMNS.

+ +

Definition at line 126 of file cache.h.

+ +
+
+ +

◆ LPTABLE_DEF

+ +
+
+ + + + +
typedef TABLE_DEF* Cache::LPTABLE_DEF
+
+ +

Pointer to const version of TABLE_DEF.

+ +

Definition at line 115 of file cache.h.

+ +
+
+ +

◆ LPTABLECOLUMNS_VEC

+ +
+
+ +

Pointer to const version of TABLECOLUMNS_VEC.

+ +

Definition at line 130 of file cache.h.

+ +
+
+ +

◆ TABLECOLUMNS_VEC

+ +
+
+ + + + +
typedef std::vector<TABLE_COLUMNS> Cache::TABLECOLUMNS_VEC
+
+ +

Table columns array.

+ +

Definition at line 128 of file cache.h.

+ +
+
+

Constructor & Destructor Documentation

+ +

◆ Cache()

+ +
+
+ + + + + +
+ + + + + + + +
Cache::Cache ()
+
+explicit
+
+ +

Construct Cache object.

+ +

Definition at line 110 of file cache.cc.

+ +
+
+ +

◆ ~Cache()

+ +
+
+ + + + + +
+ + + + + + + +
Cache::~Cache ()
+
+virtual
+
+ +

Destruct Cache object.

+ +

Definition at line 118 of file cache.cc.

+ +

References close_index(), and m_cache.

+ +
+
+

Member Function Documentation

+

◆ begin_transaction()

@@ -319,15 +537,15 @@

Returns
Returns true on success; false on error.
-

Definition at line 266 of file cache.cc.

+

Definition at line 279 of file cache.cc.

References Logging::error(), m_cacheidx_db, and m_cacheidx_file.

-

Referenced by load_index().

+

Referenced by load_index().

- +

◆ check_min_version()

- +

◆ clear()

@@ -397,13 +615,44 @@

Returns
Returns true on success; false on error.
-

Definition at line 1331 of file cache.cc.

+

Definition at line 1344 of file cache.cc.

Referenced by transcoder_cache_clear().

- + +

◆ close_index()

+ +
+
+ + + + + +
+ + + + + + + +
void Cache::close_index ()
+
+protected
+
+ +

Close cache index.

+ +

Definition at line 998 of file cache.cc.

+ +

Referenced by ~Cache().

+ +
+
+

◆ closeio()

@@ -430,7 +679,7 @@

Close a cache entry.

-

If the cache entry is in use will not be deleted.

+

If the cache entry is in use will not be deleted.

Parameters
@@ -440,7 +689,7 @@

Returns
Returns true if the object was deleted; false if not.
-

Definition at line 1059 of file cache.cc.

+

Definition at line 1072 of file cache.cc.

References Logging::trace().

@@ -448,7 +697,7 @@

+

◆ cmp_version()

@@ -512,7 +761,7 @@

+

◆ column_exists()

@@ -560,11 +809,11 @@

References Logging::error(), m_cacheidx_db, and m_cacheidx_file.

-

Referenced by upgrade_db().

+

Referenced by upgrade_db().

- +

◆ create_entry()

@@ -608,11 +857,11 @@

Returns
On success, returns pointer to a Cache_Entry. On error, returns nullptr.
-

Definition at line 1002 of file cache.cc.

+

Definition at line 1015 of file cache.cc.

- +

◆ create_table_cache_entry()

@@ -649,15 +898,15 @@

Returns
Returns true on success; false on error.
-

Definition at line 314 of file cache.cc.

+

Definition at line 327 of file cache.cc.

References Logging::error(), m_cacheidx_db, and m_cacheidx_file.

-

Referenced by load_index(), and upgrade_db().

+

Referenced by load_index(), and upgrade_db().

- +

◆ delete_entry()

- +

◆ delete_info()

@@ -751,13 +1000,13 @@

Returns
Returns true on success; false on error.
-

Definition at line 932 of file cache.cc.

+

Definition at line 945 of file cache.cc.

-

Referenced by Cache_Entry::delete_info().

+

Referenced by Cache_Entry::delete_info().

- +

◆ end_transaction()

@@ -783,15 +1032,15 @@

Returns
Returns true on success; false on error.
-

Definition at line 282 of file cache.cc.

+

Definition at line 295 of file cache.cc.

References Logging::error(), m_cacheidx_db, and m_cacheidx_file.

-

Referenced by load_index().

+

Referenced by load_index().

- +

◆ expanded_sql()

- +

◆ load_index()

- +

◆ maintenance()

[in,out]cache_entry- Cache entry object to be closed.
@@ -880,13 +1129,13 @@

Returns
Returns true on success; false on error.
-

Definition at line 1315 of file cache.cc.

+

Definition at line 1328 of file cache.cc.

Referenced by transcode(), and transcoder_cache_maintenance().

- +

◆ openio()

[in]predicted_filesize- Size of new file
@@ -912,7 +1161,7 @@

Returns
On success, returns pointer to a Cache_Entry. On error, returns nullptr.
-

Definition at line 1041 of file cache.cc.

+

Definition at line 1054 of file cache.cc.

References VIRTUALFILE::m_destfile, and Logging::trace().

@@ -920,7 +1169,7 @@

+

◆ prepare_stmts()

- +

◆ prune_cache_size()

@@ -972,11 +1221,11 @@

Returns
Returns true on success; false on error.
-

Definition at line 1145 of file cache.cc.

+

Definition at line 1158 of file cache.cc.

- +

◆ prune_disk_space()

@@ -995,11 +1244,11 @@

Returns
Returns true on success; false on error.
-

Definition at line 1223 of file cache.cc.

+

Definition at line 1236 of file cache.cc.

- +

◆ prune_expired()

@@ -1017,11 +1266,11 @@

Returns
Returns true on success; false on error.
-

Definition at line 1083 of file cache.cc.

+

Definition at line 1096 of file cache.cc.

- +

◆ read_info()

- +

◆ remove_cachefile()

@@ -1098,11 +1347,11 @@

Returns
Returns true on success; false on error.
-

Definition at line 1384 of file cache.cc.

+

Definition at line 1397 of file cache.cc.

- +

◆ rollback_transaction()

- +

◆ table_exists()

@@ -1171,11 +1420,11 @@

References Logging::error(), m_cacheidx_db, and m_cacheidx_file.

-

Referenced by load_index().

+

Referenced by load_index().

- +

◆ upgrade_db()

- +

◆ write_info()

+ +

Friends And Related Function Documentation

+ +

◆ Cache_Entry

+ +
+
+

[in]virtualfile- VIRTUALFILE struct of a file.
+ + + + +
+ + + + +
friend class Cache_Entry
+
+friend
+

+ +

Definition at line 132 of file cache.h.

Member Data Documentation

- + +

◆ m_cache

+ +
+
+ + + + + +
+ + + + +
cache_t Cache::m_cache
+
+private
+
+ +

Cache file (memory mapped file)

+ +

Definition at line 336 of file cache.h.

+ +

Referenced by delete_entry(), and ~Cache().

+ +
+
+ +

◆ m_cacheidx_db

+ +
+
+ + + + + +
+ + + + +
sqlite3* Cache::m_cacheidx_db
+
+private
+
+
+ +

◆ m_cacheidx_delete_stmt

+ +
+
+ + + + + +
+ + + + +
sqlite3_stmt* Cache::m_cacheidx_delete_stmt
+
+private
+
+ +

Prepared delete statement.

+ +

Definition at line 335 of file cache.h.

+ +

Referenced by prepare_stmts().

+ +
+
+ +

◆ m_cacheidx_file

+ +
+
+ + + + + +
+ + + + +
std::string Cache::m_cacheidx_file
+
+private
+
+
+ +

◆ m_cacheidx_insert_stmt

+ +
+
+ + + + + +
+ + + + +
sqlite3_stmt* Cache::m_cacheidx_insert_stmt
+
+private
+
+ +

Prepared insert statement.

+ +

Definition at line 334 of file cache.h.

+ +

Referenced by prepare_stmts().

+ +
+
+ +

◆ m_cacheidx_select_stmt

+ +
+
+ + + + + +
+ + + + +
sqlite3_stmt* Cache::m_cacheidx_select_stmt
+
+private
+
+ +

Prepared select statement.

+ +

Definition at line 333 of file cache.h.

+ +

Referenced by prepare_stmts(), and read_info().

+ +
+
+ +

◆ m_columns_cache_entry

+ +
+
+ + + + + +
+ + + + +
const Cache::TABLECOLUMNS_VEC Cache::m_columns_cache_entry
+
+staticprivate
+
+ +

Columns of table "cache_entry".

+ +

Definition at line 324 of file cache.h.

+ +

Referenced by load_index(), and upgrade_db().

+ +
+
+

◆ m_columns_version

@@ -1296,11 +1766,39 @@

Definition at line 328 of file cache.h.

-

Referenced by load_index().

+

Referenced by load_index().

+ +

+

+ +

◆ m_mutex

+ +
+
+ + + + + +
+ + + + +
std::recursive_mutex Cache::m_mutex
+
+private
+
+ +

Access mutex.

+ +

Definition at line 330 of file cache.h.

+ +

Referenced by read_info().

- +

◆ m_table_cache_entry

@@ -1335,11 +1833,11 @@

Definition at line 322 of file cache.h.

-

Referenced by load_index(), and upgrade_db().

+

Referenced by load_index(), and upgrade_db().

- +

◆ m_table_version

@@ -1372,7 +1870,7 @@

Definition at line 326 of file cache.h.

-

Referenced by load_index().

+

Referenced by load_index().

@@ -1383,7 +1881,7 @@

diff --git a/html/classCache__Entry-members.html b/html/classCache__Entry-members.html index 8f6ef3efe..923ef6da8 100644 --- a/html/classCache__Entry-members.html +++ b/html/classCache__Entry-members.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
Cache_Entry Member List
+
Cache_Entry Member List

This is the complete list of members for Cache_Entry, including all inherited members.

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
age() constCache_Entry
Cache_Entry(Cache *owner, LPVIRTUALFILE virtualfile)Cache_Entryexplicitprivate
Cache_Entry(Cache *owner, LPVIRTUALFILE virtualfile)Cache_Entryexplicitprivate
Cache_Entry(Cache_Entry &)=deleteCache_Entryprivate
clear(bool fetch_file_time=true)Cache_Entry
clear(bool fetch_file_time=true)Cache_Entry
close_buffer(int flags)Cache_Entryprotected
closeio(int flags)Cache_Entry
closeio(int flags)Cache_Entry
create(Cache *owner, LPVIRTUALFILE virtualfile)Cache_Entrystatic
decode_timeout() constCache_Entry
decode_timeout() constCache_Entry
decr_refcount()Cache_Entry
delete_info()Cache_Entryprotected
delete_info()Cache_Entryprotected
destname() constCache_Entry
destroy()Cache_Entry
destroy()Cache_Entry
expired() constCache_Entry
filename() constCache_Entry
filename() constCache_Entry
flush()Cache_Entry
inc_refcount()Cache_Entry
inc_refcount()Cache_Entry
is_finished() constCache_Entry
is_finished_error() constCache_Entry
is_finished_error() constCache_Entry
is_finished_incomplete() constCache_Entry
is_finished_success() constCache_Entry
is_finished_success() constCache_Entry
last_access() constCache_Entry
lock()Cache_Entry
lock()Cache_Entry
m_active_mutexCache_Entry
m_bufferCache_Entry
m_bufferCache_Entry
m_cache_infoCache_Entry
m_id3v1Cache_Entry
m_id3v1Cache_Entry
m_is_decodingCache_Entry
m_mutexCache_Entryprotected
m_mutexCache_Entryprotected
m_ownerCache_Entryprotected
m_ref_countCache_Entryprotected
m_ref_countCache_Entryprotected
m_restart_mutexCache_Entry
m_seek_to_noCache_Entry
m_seek_to_noCache_Entry
m_suspend_timeoutCache_Entry
m_virtualfileCache_Entryprotected
m_virtualfileCache_Entryprotected
openio(bool create_cache=true)Cache_Entry
operator=(Cache_Entry const &other)=deleteCache_Entry
operator=(Cache_Entry const &other)=deleteCache_Entry
outdated() constCache_Entry
read_count() constCache_Entry
read_count() constCache_Entry
read_info()Cache_Entryprotected
ref_count() constCache_Entry
ref_count() constCache_Entry
size() constCache_Entry
suspend_timeout() constCache_Entry
suspend_timeout() constCache_Entry
unlock()Cache_Entry
update_access(bool update_database=false)Cache_Entry
update_access(bool update_database=false)Cache_Entry
update_read_count()Cache_Entry
video_frame_count() constCache_Entry
video_frame_count() constCache_Entry
virtname() constCache_Entry
virtualfile()Cache_Entry
virtualfile()Cache_Entry
write_info()Cache_Entryprotected
~Cache_Entry()Cache_Entryprivatevirtual
~Cache_Entry()Cache_Entryprivatevirtual
diff --git a/html/classCache__Entry.html b/html/classCache__Entry.html index afc8319cc..243752135 100644 --- a/html/classCache__Entry.html +++ b/html/classCache__Entry.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Cache_Entry Class Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ + -
-
Cache_Entry Class Reference
+
Cache_Entry Class Reference
@@ -84,27 +83,27 @@
Collaboration graph
- - - - - - - - - - - - - + + + + + + + + + + + + +
[legend]
- - - - + + + @@ -150,13 +149,11 @@ - - + + - - + + @@ -167,9 +164,8 @@ - - + + @@ -177,9 +173,8 @@ - - + + @@ -197,48 +192,40 @@

+

Public Member Functions

Cache_Entryoperator= (Cache_Entry const &other)=delete
 operator = declared deleted, should use create to get this object to maintain reference count. More...
 
Cache_Entryoperator= (Cache_Entry const &other)=delete
 operator = declared deleted, should use create to get this object to maintain reference count. More...
 
bool destroy ()
 Destroy this Cache_Entry object. More...
 
bool update_access (bool update_database=false)
 Update last access time. More...
 
-void lock ()
 Lock the access mutex.
void lock ()
 Lock the access mutex. More...
 
-void unlock ()
 Unlock the access mutex.
void unlock ()
 Unlock the access mutex. More...
 
int ref_count () const
 Get the current reference counter. More...
int decr_refcount ()
 Decrement the current reference counter. More...
 
-bool outdated () const
 Check if cache entry needs to be recoded.
bool outdated () const
 Check if cache entry needs to be recoded. More...
 
LPVIRTUALFILE virtualfile ()
 Get the underlying VIRTUALFILE object. More...
bool closeio (int flags)
 Close the cache entry. More...
 
-void update_read_count ()
 Update read counter.
void update_read_count ()
 Update read counter. More...
 
unsigned int read_count () const
 Get read counter. More...
 Get if cache has been finished and with an error. More...
 
-

+

Static Public Member Functions

static Cache_Entrycreate (Cache *owner, LPVIRTUALFILE virtualfile)
 Create a new Cache_Entry object. More...
 
- - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

+

Public Attributes

-Bufferm_buffer
 Buffer object.
Bufferm_buffer
 Buffer object. More...
 
-std::atomic_bool m_is_decoding
 true while file is decoding
std::atomic_bool m_is_decoding
 true while file is decoding More...
 
-std::recursive_mutex m_active_mutex
 Mutex while thread is active.
std::recursive_mutex m_active_mutex
 Mutex while thread is active. More...
 
-std::recursive_mutex m_restart_mutex
 Mutex while thread is restarted.
std::recursive_mutex m_restart_mutex
 Mutex while thread is restarted. More...
 
-std::atomic_bool m_suspend_timeout
 true to temporarly disable read_frame timeout
std::atomic_bool m_suspend_timeout
 true to temporarly disable read_frame timeout More...
 
-CACHE_INFO m_cache_info
 Info about cached object.
CACHE_INFO m_cache_info
 Info about cached object. More...
 
-ID3v1 m_id3v1
 ID3v1 structure which is used to send to clients.
ID3v1 m_id3v1
 ID3v1 structure which is used to send to clients. More...
 
-std::atomic_uint32_t m_seek_to_no
 If not 0, seeks to specified frame.
std::atomic_uint32_t m_seek_to_no
 If not 0, seeks to specified frame. More...
 
- @@ -253,45 +240,40 @@

+

Protected Member Functions

void close_buffer (int flags)
 Close buffer object. More...
 Delete cache info. More...
 
- - - + + - - + + - - + + - - + +

+

Protected Attributes

-Cachem_owner
 Owner cache object.
Cachem_owner
 Owner cache object. More...
 
-std::recursive_mutex m_mutex
 Access mutex.
std::recursive_mutex m_mutex
 Access mutex. More...
 
-std::atomic_int m_ref_count
 Reference counter.
std::atomic_int m_ref_count
 Reference counter. More...
 
-LPVIRTUALFILE m_virtualfile
 Underlying virtual file object.
LPVIRTUALFILE m_virtualfile
 Underlying virtual file object. More...
 
- - + - - + +

+

Private Member Functions

 Cache_Entry (Cache *owner, LPVIRTUALFILE virtualfile)
 Create Cache_Entry object. More...
 
Cache_Entry (Cache_Entry &)=delete
Cache_Entry (Cache_Entry &)=delete
 Copy constructor declared deleted, should use create to get this object to maintain reference count.
 
-virtual ~Cache_Entry ()
 Destroy Cache_Entry object.
virtual ~Cache_Entry ()
 Destroy Cache_Entry object. More...
 

Detailed Description

- + +

◆ ~Cache_Entry()

+ +
+
+ + + + + +
+ + + + + + + +
Cache_Entry::~Cache_Entry ()
+
+privatevirtual
+
+ +

Destroy Cache_Entry object.

+ +

Definition at line 65 of file cache_entry.cc.

-

Referenced by create().

+

References filename(), m_active_mutex, m_buffer, Logging::trace(), and unlock().

Member Function Documentation

- +

◆ age()

@@ -361,15 +374,15 @@

Returns
Returns the age of the cache entry in seconds since epoch.
-

Definition at line 286 of file cache_entry.cc.

+

Definition at line 288 of file cache_entry.cc.

References m_cache_info, and CACHE_INFO::m_creation_time.

-

Referenced by expired().

+

Referenced by expired().

- +

◆ clear()

@@ -393,15 +406,15 @@

Definition at line 85 of file cache_entry.cc.

+

Definition at line 87 of file cache_entry.cc.

-

References Buffer::clear(), filename(), init_id3v1(), CACHE_INFO::m_access_count, CACHE_INFO::m_access_time, CACHE_INFO::m_audiobitrate, FFMPEGFS_PARAMS::m_audiobitrate, CACHE_INFO::m_audiosamplerate, FFMPEGFS_PARAMS::m_audiosamplerate, CACHE_INFO::m_averror, m_buffer, m_cache_info, CACHE_INFO::m_creation_time, CACHE_INFO::m_deinterlace, FFMPEGFS_PARAMS::m_deinterlace, CACHE_INFO::m_encoded_filesize, CACHE_INFO::m_errno, CACHE_INFO::m_error, CACHE_INFO::m_file_size, CACHE_INFO::m_file_time, m_id3v1, m_is_decoding, CACHE_INFO::m_predicted_filesize, CACHE_INFO::m_result, CACHE_INFO::m_video_frame_count, CACHE_INFO::m_videobitrate, FFMPEGFS_PARAMS::m_videobitrate, CACHE_INFO::m_videoheight, FFMPEGFS_PARAMS::m_videoheight, CACHE_INFO::m_videowidth, FFMPEGFS_PARAMS::m_videowidth, params, and RESULTCODE_NONE.

+

References Buffer::clear(), filename(), init_id3v1(), CACHE_INFO::m_access_count, CACHE_INFO::m_access_time, CACHE_INFO::m_audiobitrate, FFMPEGFS_PARAMS::m_audiobitrate, CACHE_INFO::m_audiosamplerate, FFMPEGFS_PARAMS::m_audiosamplerate, CACHE_INFO::m_averror, m_buffer, m_cache_info, CACHE_INFO::m_creation_time, CACHE_INFO::m_deinterlace, FFMPEGFS_PARAMS::m_deinterlace, CACHE_INFO::m_encoded_filesize, CACHE_INFO::m_errno, CACHE_INFO::m_error, CACHE_INFO::m_file_size, CACHE_INFO::m_file_time, m_id3v1, m_is_decoding, CACHE_INFO::m_predicted_filesize, CACHE_INFO::m_result, CACHE_INFO::m_video_frame_count, CACHE_INFO::m_videobitrate, FFMPEGFS_PARAMS::m_videobitrate, CACHE_INFO::m_videoheight, FFMPEGFS_PARAMS::m_videoheight, CACHE_INFO::m_videowidth, FFMPEGFS_PARAMS::m_videowidth, params, and RESULTCODE_NONE.

-

Referenced by Cache_Entry(), openio(), transcode(), and transcoder_new().

+

Referenced by Cache_Entry(), openio(), transcode(), and transcoder_new().

- +

◆ close_buffer()

@@ -433,15 +446,15 @@

Definition at line 206 of file cache_entry.cc.

+

Definition at line 208 of file cache_entry.cc.

-

References delete_info(), m_buffer, and Buffer::release().

+

References delete_info(), m_buffer, and Buffer::release().

-

Referenced by closeio().

+

Referenced by closeio().

- +

◆ closeio()

- +

◆ create()

@@ -516,13 +529,13 @@

Returns
On success, returns a Cache_Entry object; on error (out of memory) returns a nullptr
-

Definition at line 74 of file cache_entry.cc.

+

Definition at line 76 of file cache_entry.cc.

-

References Cache_Entry(), and virtualfile().

+

References Cache_Entry(), and virtualfile().

- +

◆ decode_timeout()

@@ -540,7 +553,7 @@

Returns
Returns true if decoding timed out.
-

Definition at line 306 of file cache_entry.cc.

+

Definition at line 308 of file cache_entry.cc.

References CACHE_INFO::m_access_time, m_cache_info, FFMPEGFS_PARAMS::m_max_inactive_abort, m_ref_count, and params.

@@ -548,7 +561,7 @@

+

◆ decr_refcount()

@@ -566,13 +579,13 @@

Returns
Returns the current reference counter.
-

Definition at line 346 of file cache_entry.cc.

+

Definition at line 348 of file cache_entry.cc.

References m_ref_count.

- +

◆ delete_info()

- +

◆ destname()

- +

◆ destroy()

@@ -650,11 +663,11 @@

Todo:
Implement delete later mechanism
Todo:
Return true when deleted, false if kept for delete later
-

Definition at line 79 of file cache_entry.cc.

+

Definition at line 81 of file cache_entry.cc.

- +

◆ expired()

- +

◆ filename()

- +

◆ flush()

- +

◆ inc_refcount()

@@ -749,13 +762,13 @@

Returns
Returns the current reference counter.
-

Definition at line 341 of file cache_entry.cc.

+

Definition at line 343 of file cache_entry.cc.

References m_ref_count.

- +

◆ is_finished()

- +

◆ is_finished_error()

- +

◆ is_finished_incomplete()

- +

◆ is_finished_success()

- + +

◆ lock()

+ +
+
+ + + + + + + +
void Cache_Entry::lock ()
+
+ +

Lock the access mutex.

+ +

Definition at line 328 of file cache_entry.cc.

+ +

References m_mutex.

+ +

Referenced by transcoder_new().

+ +
+
+

◆ openio()

- -

◆ operator=()

+ +

◆ operator=()

+

◆ read_count()

- +

◆ read_info()

@@ -998,15 +1061,15 @@

Returns
On success, returns true; returns false on error.
-

Definition at line 131 of file cache_entry.cc.

+

Definition at line 133 of file cache_entry.cc.

-

References m_cache_info, m_owner, and Cache::read_info().

+

References m_cache_info, m_owner, and Cache::read_info().

-

Referenced by openio().

+

Referenced by openio().

- +

◆ ref_count()

@@ -1024,7 +1087,7 @@

Returns
Returns the current reference counter.
-

Definition at line 336 of file cache_entry.cc.

+

Definition at line 338 of file cache_entry.cc.

References m_ref_count.

@@ -1032,7 +1095,7 @@

+

◆ size()

@@ -1048,10 +1111,10 @@

Return size of output file, as computed by encoder.

-

Returns the file size, either the predicted size (which may be inaccurate) or the real size (which is only available once the file was completely recoded).

+

Returns the file size, either the predicted size (which may be inaccurate) or the real size (which is only available once the file was completely recoded).

Returns
The size of the file. Function never fails.
-

Definition at line 260 of file cache_entry.cc.

+

Definition at line 262 of file cache_entry.cc.

References Buffer::buffer_watermark(), m_buffer, m_cache_info, CACHE_INFO::m_encoded_filesize, and CACHE_INFO::m_predicted_filesize.

@@ -1059,7 +1122,7 @@

+

◆ suspend_timeout()

@@ -1077,7 +1140,7 @@

Returns
Returns true if decoding was suspended.
-

Definition at line 301 of file cache_entry.cc.

+

Definition at line 303 of file cache_entry.cc.

References CACHE_INFO::m_access_time, m_cache_info, FFMPEGFS_PARAMS::m_max_inactive_suspend, m_ref_count, and params.

@@ -1085,7 +1148,32 @@

+ +

◆ unlock()

+ +
+
+ + + + + + + +
void Cache_Entry::unlock ()
+
+ +

Unlock the access mutex.

+ +

Definition at line 333 of file cache_entry.cc.

+ +

References m_mutex.

+ +

Referenced by transcoder_new(), and ~Cache_Entry().

+ +
+
+

◆ update_access()

+

+ +

◆ update_read_count()

+ +
+
+ + + + + + + +
void Cache_Entry::update_read_count ()
+
+ +

Update read counter.

-

References CACHE_INFO::m_access_time, m_cache_info, m_owner, and Cache::write_info().

+

Definition at line 427 of file cache_entry.cc.

+ +

References CACHE_INFO::m_access_count, and m_cache_info.

-

Referenced by openio(), transcode(), transcoder_read(), and transcoder_read_frame().

+

Referenced by transcoder_read(), and transcoder_read_frame().

- +

◆ video_frame_count()

- +

◆ virtname()

@@ -1160,7 +1273,7 @@

Returns
Returns the name of the transcoded file.
-

Definition at line 321 of file cache_entry.cc.

+

Definition at line 323 of file cache_entry.cc.

References VIRTUALFILE::m_virtfile, and m_virtualfile.

@@ -1168,7 +1281,7 @@

+

◆ virtualfile()

@@ -1186,15 +1299,15 @@

VIRTUALFILE object.

Returns
Return the underlying VIRTUALFILE object.
-

Definition at line 420 of file cache_entry.cc.

+

Definition at line 422 of file cache_entry.cc.

References m_virtualfile.

-

Referenced by Cache_Entry(), create(), ffmpegfs_release(), transcode(), and transcoder_read().

+

Referenced by Cache_Entry(), create(), ffmpegfs_release(), transcode(), and transcoder_read().

- +

◆ write_info()

@@ -1220,11 +1333,284 @@

Returns
On success, returns true; returns false on error.
-

Definition at line 136 of file cache_entry.cc.

+

Definition at line 138 of file cache_entry.cc.

+ +

References m_cache_info, m_owner, and Cache::write_info().

+ +

Referenced by closeio().

+ +

+

+

Member Data Documentation

+ +

◆ m_active_mutex

+ +
+
+ + + + +
std::recursive_mutex Cache_Entry::m_active_mutex
+
+ +

Mutex while thread is active.

+ +

Definition at line 273 of file cache_entry.h.

+ +

Referenced by transcoder_thread(), and ~Cache_Entry().

+ +
+
+ +

◆ m_buffer

+ + + +

◆ m_cache_info

+ + + +

◆ m_id3v1

+ +
+
+ + + + +
ID3v1 Cache_Entry::m_id3v1
+
+ +

ID3v1 structure which is used to send to clients.

+ +

Definition at line 279 of file cache_entry.h.

+ +

Referenced by clear(), and transcode().

+ +
+
+ +

◆ m_is_decoding

+ +
+
+ + + + +
std::atomic_bool Cache_Entry::m_is_decoding
+
+ +

true while file is decoding

+ +

Definition at line 272 of file cache_entry.h.

+ +

Referenced by clear(), transcode(), transcode_finish(), transcode_until(), transcoder_new(), transcoder_read_frame(), and transcoder_thread().

+ +
+
+ +

◆ m_mutex

+ +
+
+ + + + + +
+ + + + +
std::recursive_mutex Cache_Entry::m_mutex
+
+protected
+
+ +

Access mutex.

+ +

Definition at line 264 of file cache_entry.h.

+ +

Referenced by lock(), and unlock().

+ +
+
+ +

◆ m_owner

+ +
+
+ + + + + +
+ + + + +
Cache* Cache_Entry::m_owner
+
+protected
+
+ +

Owner cache object.

+ +

Definition at line 263 of file cache_entry.h.

+ +

Referenced by delete_info(), read_info(), update_access(), and write_info().

+ +
+
+ +

◆ m_ref_count

+ +
+
+ + + + + +
+ + + + +
std::atomic_int Cache_Entry::m_ref_count
+
+protected
+
+ +

Reference counter.

+ +

Definition at line 266 of file cache_entry.h.

+ +

Referenced by closeio(), decode_timeout(), decr_refcount(), inc_refcount(), openio(), ref_count(), and suspend_timeout().

+ +
+
+ +

◆ m_restart_mutex

+ +
+
+ + + + +
std::recursive_mutex Cache_Entry::m_restart_mutex
+
+ +

Mutex while thread is restarted.

+ +

Definition at line 274 of file cache_entry.h.

+ +

Referenced by transcoder_thread().

+ +
+
+ +

◆ m_seek_to_no

+ +
+
+ + + + +
std::atomic_uint32_t Cache_Entry::m_seek_to_no
+
+ +

If not 0, seeks to specified frame.

+ +

Definition at line 281 of file cache_entry.h.

+ +

Referenced by transcode(), transcoder_read(), transcoder_read_frame(), and transcoder_thread().

+ +
+
+ +

◆ m_suspend_timeout

+ +
+
+ + + + +
std::atomic_bool Cache_Entry::m_suspend_timeout
+
+ +

true to temporarly disable read_frame timeout

+ +

Definition at line 275 of file cache_entry.h.

+ +

Referenced by transcode(), and transcoder_read_frame().

+ +
+
+ +

◆ m_virtualfile

+ +
+
+ + + + + +
+ + + + +
LPVIRTUALFILE Cache_Entry::m_virtualfile
+
+protected
+
+ +

Underlying virtual file object.

-

References m_cache_info, m_owner, and Cache::write_info().

+

Definition at line 268 of file cache_entry.h.

-

Referenced by closeio().

+

Referenced by destname(), filename(), virtname(), and virtualfile().

@@ -1235,7 +1621,7 @@

diff --git a/html/classCache__Entry__coll__graph.map b/html/classCache__Entry__coll__graph.map index 965b8efee..fa5718abc 100644 --- a/html/classCache__Entry__coll__graph.map +++ b/html/classCache__Entry__coll__graph.map @@ -1,15 +1,15 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/html/classCache__Entry__coll__graph.md5 b/html/classCache__Entry__coll__graph.md5 index feb63de23..5ad63bba7 100644 --- a/html/classCache__Entry__coll__graph.md5 +++ b/html/classCache__Entry__coll__graph.md5 @@ -1 +1 @@ -41f2041a89ba582072d92f3487379e56 \ No newline at end of file +53362b7b31e28192454fce7073f035bd \ No newline at end of file diff --git a/html/classCache__Entry__coll__graph.png b/html/classCache__Entry__coll__graph.png index 118151e303e79c1e37f4f20b087f37df4471cfae..86b74d98dcf099d42a1aeb9ec4ff6ecee3fcd740 100644 GIT binary patch literal 50492 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

vv7Yv${{W4 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 UnmOjIqu{kge+TWJu1(1Q0nYDnaR2}S diff --git a/html/classDiskIO-members.html b/html/classDiskIO-members.html index 0a3d5f078..b16b65f6f 100644 --- a/html/classDiskIO-members.html +++ b/html/classDiskIO-members.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@

- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
DiskIO Member List
+
DiskIO Member List

This is the complete list of members for DiskIO, including all inherited members.

- + - + - + - + - + - + - + - + - + - + - + - +
alloc(VIRTUALTYPE type)FileIOstatic
bufsize() const overrideDiskIOvirtual
bufsize() const overrideDiskIOvirtual
closeio() overrideDiskIOvirtual
DiskIO() (defined in DiskIO)DiskIOexplicit
DiskIO() (defined in DiskIO)DiskIOexplicit
duration() const overrideDiskIOvirtual
eof() const overrideDiskIOvirtual
eof() const overrideDiskIOvirtual
error() const overrideDiskIOvirtual
FileIO()FileIOexplicit
FileIO()FileIOexplicit
filename() constFileIO
m_fpiDiskIOprotected
m_fpiDiskIOprotected
m_pathFileIOprivate
m_virtualfileFileIOprivate
m_virtualfileFileIOprivate
openio(LPVIRTUALFILE virtualfile) overrideDiskIOvirtual
path() constFileIO
path() constFileIO
pvt_close()DiskIOprivate
readio(void *data, size_t size) overrideDiskIOvirtual
readio(void *data, size_t size) overrideDiskIOvirtual
seek(int64_t offset, int whence) overrideDiskIOvirtual
set_virtualfile(LPVIRTUALFILE virtualfile)FileIOprotected
set_virtualfile(LPVIRTUALFILE virtualfile)FileIOprotected
size() const overrideDiskIOvirtual
tell() const overrideDiskIOvirtual
tell() const overrideDiskIOvirtual
type() const overrideDiskIOvirtual
virtualfile()FileIO
virtualfile()FileIO
~DiskIO() (defined in DiskIO)DiskIOvirtual
~FileIO()=defaultFileIOvirtual
~FileIO()=defaultFileIOvirtual
diff --git a/html/classDiskIO.html b/html/classDiskIO.html index cdf2c8a55..f2b266c2a 100644 --- a/html/classDiskIO.html +++ b/html/classDiskIO.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: DiskIO Class Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ + -
-
DiskIO Class Reference
+
DiskIO Class Reference
@@ -90,17 +89,17 @@
Collaboration graph
- - - - + + + + - - + +
[legend]
- @@ -132,19 +131,50 @@ - - + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -155,21 +185,19 @@

+

Public Member Functions

virtual VIRTUALTYPE type () const override
 Get type of the virtual file. More...
virtual bool eof () const override
 Check if at end of file. More...
 
-virtual void closeio () override
 Close virtual file.
virtual void closeio () override
 Close virtual file. More...
 
- Public Member Functions inherited from FileIO
FileIO ()
 Create FileIO object.
 FileIO ()
 Create FileIO object. More...
 
-virtual ~FileIO ()=default
+virtual ~FileIO ()=default
 Free FileIO object.
 
virtual VIRTUALTYPE type () const =0
 Get type of the virtual file. More...
 
virtual size_t bufsize () const =0
 Get the ideal buffer size. More...
 
virtual int openio (LPVIRTUALFILE virtualfile)=0
 Open a virtual file. More...
 
virtual size_t readio (void *data, size_t size)=0
 Read data from a file. More...
 
virtual int error () const =0
 Get last error. More...
 
virtual int64_t duration () const =0
 Get the duration of the file, in AV_TIME_BASE fractional seconds. More...
 
virtual size_t size () const =0
 Get the file size. More...
 
virtual size_t tell () const =0
 Get current read position. More...
 
virtual int seek (int64_t offset, int whence)=0
 Seek to position in file. More...
 
virtual bool eof () const =0
 Check if at end of file. More...
 
virtual void closeio ()=0
 Close virtual file. More...
 
LPVIRTUALFILE virtualfile ()
 Get virtual file object. More...
 
 Path to source file (without file name) More...
 
- - - + +

+

Protected Attributes

-FILE * m_fpi
 File pointer to source media.
FILE * m_fpi
 File pointer to source media. More...
 
- - - + +

+

Private Member Functions

-void pvt_close ()
 Close virtual file. Non-virtual version to be safely called from constructor/destructor.
void pvt_close ()
 Close virtual file. Non-virtual version to be safely called from constructor/destructor. More...
 
- @@ -181,11 +209,66 @@

+

Additional Inherited Members

- Static Public Member Functions inherited from FileIO
static FileIOalloc (VIRTUALTYPE type)
 

Detailed Description

-

Disk file I/O class.

+

Disk file I/O class.

Definition at line 41 of file diskio.h.

-

Member Function Documentation

- +

Constructor & Destructor Documentation

+ +

◆ DiskIO()

+ +
+
+ + + + + +
+ + + + + + + +
DiskIO::DiskIO ()
+
+explicit
+
+ +

Definition at line 37 of file diskio.cc.

+ +
+
+ +

◆ ~DiskIO()

+ +
+
+ + + + + +
+ + + + + + + +
DiskIO::~DiskIO ()
+
+virtual
+
+ +

Definition at line 43 of file diskio.cc.

+ +
+
+

Member Function Documentation

+

◆ bufsize()

@@ -217,7 +300,40 @@

+ +

◆ closeio()

+ +
+
+ + + + + +
+ + + + + + + +
void DiskIO::closeio ()
+
+overridevirtual
+
+ +

Close virtual file.

+ +

Implements FileIO.

+ +

Definition at line 119 of file diskio.cc.

+ +

References pvt_close().

+ +
+
+

◆ duration()

@@ -241,7 +357,7 @@

Get the duration of the file, in AV_TIME_BASE fractional seconds.

-

Not applicable to generic disk files, always returns AV_NOPTS_VALUE.

+

Not applicable to generic disk files, always returns AV_NOPTS_VALUE.

Implements FileIO.

@@ -249,7 +365,7 @@

+

◆ eof()

@@ -283,7 +399,7 @@

+

◆ error()

@@ -317,7 +433,7 @@

+

◆ openio()

@@ -359,7 +475,40 @@

+ +

◆ pvt_close()

+ +
+
+ + + + + +
+ + + + + + + +
void DiskIO::pvt_close ()
+
+private
+
+ +

Close virtual file. Non-virtual version to be safely called from constructor/destructor.

+ +

Definition at line 124 of file diskio.cc.

+ +

References m_fpi.

+ +

Referenced by closeio().

+ +
+
+

◆ readio()


The documentation for this class was generated from the following files:
    @@ -582,7 +760,7 @@

    diff --git a/html/classDiskIO__coll__graph.map b/html/classDiskIO__coll__graph.map index 2dd014893..c272a84bb 100644 --- a/html/classDiskIO__coll__graph.map +++ b/html/classDiskIO__coll__graph.map @@ -1,9 +1,9 @@ - - - - + + + + - - + + diff --git a/html/classDiskIO__coll__graph.md5 b/html/classDiskIO__coll__graph.md5 index 04fbc6aef..0cbb77b41 100644 --- a/html/classDiskIO__coll__graph.md5 +++ b/html/classDiskIO__coll__graph.md5 @@ -1 +1 @@ -93354797af3293f57af18fe67073cf93 \ No newline at end of file +0bb4f149180ada5b73887e36efa40cc0 \ No newline at end of file diff --git a/html/classDiskIO__coll__graph.png b/html/classDiskIO__coll__graph.png index 637f93e40a7bbfbfd414e1c0687489e0dd85b44a..e2d76a82fcea1c29143c444cc113b47a647a9210 100644 GIT binary patch literal 21171 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 z
    YJAi`G-+aue`DN8)%H$*}Rc~ZT^eE~|<84+zdD6lwa$N&!_)YSm83e!(#_Co# zc9aGVBWDE3sB{;y;6@2r@@)!`Nx(y$lMFj!<~Zx60iJH6>xJqDMhidqn>{%u+V z$W{kQ(x#aoF-w8Ltw@M|j?T^w;M(#8JQu;Pj1`42fGVo0cAgbVA%B1}4;(d9s=Sb^HrB7q z|Muxd^SJm+;AZe_(Egp2lF|k{z?AO)(yg6Vx(0qtAM3n?5KR_fpU@$Lh`}V!bqWT6 z$DT>u06Md>y84oS9~;n@Sg}xI6HIqnHzdb(Uw0EsO#Zcbn#buy{r5_)NL2XZ zO9u{%Wz&7R9;YQsRR530FTG - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
    - - + @@ -30,21 +29,22 @@
    -
    FFmpegfs Fuse Multi Media Filesystem -  2.14 +
    +
    FFmpegfs Fuse Multi Media Filesystem 2.14
    - + +/* @license-end */ +
    -
    -
    DvdIO Member List
    +
    DvdIO Member List

    This is the complete list of members for DvdIO, including all inherited members.

    - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
    alloc(VIRTUALTYPE type)FileIOstatic
    bufsize() const overrideDvdIOvirtual
    bufsize() const overrideDvdIOvirtual
    closeio() overrideDvdIOvirtual
    demux_pes(uint8_t *out, const uint8_t *in, size_t len) constDvdIOprivate
    demux_pes(uint8_t *out, const uint8_t *in, size_t len) constDvdIOprivate
    DSITYPE enum nameDvdIOprivate
    DSITYPE typedefDvdIOprivate
    DSITYPE typedefDvdIOprivate
    DSITYPE_CONTINUE enum valueDvdIOprivate
    DSITYPE_EOF_CHAPTER enum valueDvdIOprivate
    DSITYPE_EOF_CHAPTER enum valueDvdIOprivate
    DSITYPE_EOF_TITLE enum valueDvdIOprivate
    duration() const overrideDvdIOvirtual
    duration() const overrideDvdIOvirtual
    DvdIO()DvdIOexplicit
    eof() const overrideDvdIOvirtual
    eof() const overrideDvdIOvirtual
    error() const overrideDvdIOvirtual
    FileIO()FileIOexplicit
    FileIO()FileIOexplicit
    filename() constFileIO
    get_packet_size(const uint8_t *p, size_t peek, size_t *size) constDvdIOprivate
    get_packet_size(const uint8_t *p, size_t peek, size_t *size) constDvdIOprivate
    get_pes_id(const uint8_t *buffer, size_t size) constDvdIOprivate
    handle_DSI(void *_dsi_pack, size_t *cur_output_size, unsigned int *next_block, uint8_t *data)DvdIOprivate
    handle_DSI(void *_dsi_pack, size_t *cur_output_size, unsigned int *next_block, uint8_t *data)DvdIOprivate
    is_nav_pack(const unsigned char *buffer) constDvdIOprivate
    m_angle_idxDvdIOprotected
    m_angle_idxDvdIOprotected
    m_bufferDvdIOprotected
    m_chapter_idxDvdIOprotected
    m_chapter_idxDvdIOprotected
    m_cur_blockDvdIOprotected
    m_cur_cellDvdIOprotected
    m_cur_cellDvdIOprotected
    m_cur_pgcDvdIOprotected
    m_cur_posDvdIOprotected
    m_cur_posDvdIOprotected
    m_dataDvdIOprotected
    m_durationDvdIOprotected
    m_durationDvdIOprotected
    m_dvdDvdIOprotected
    m_dvd_titleDvdIOprotected
    m_dvd_titleDvdIOprotected
    m_end_cellDvdIOprotected
    m_errnoDvdIOprotected
    m_errnoDvdIOprotected
    m_full_titleDvdIOprotected
    m_goto_next_cellDvdIOprotected
    m_goto_next_cellDvdIOprotected
    m_is_eofDvdIOprotected
    m_next_cellDvdIOprotected
    m_next_cellDvdIOprotected
    m_pathFileIOprivate
    m_rest_posDvdIOprotected
    m_rest_posDvdIOprotected
    m_rest_sizeDvdIOprotected
    m_sizeDvdIOprotected
    m_sizeDvdIOprotected
    m_start_cellDvdIOprotected
    m_title_idxDvdIOprotected
    m_title_idxDvdIOprotected
    m_virtualfileFileIOprivate
    m_vmg_fileDvdIOprotected
    m_vmg_fileDvdIOprotected
    m_vts_fileDvdIOprotected
    next_cell()DvdIOprivate
    next_cell()DvdIOprivate
    openio(LPVIRTUALFILE virtualfile) overrideDvdIOvirtual
    path() constFileIO
    path() constFileIO
    pvt_close()DvdIOprivate
    readio(void *data, size_t size) overrideDvdIOvirtual
    readio(void *data, size_t size) overrideDvdIOvirtual
    rewind()DvdIOprivate
    seek(int64_t offset, int whence) overrideDvdIOvirtual
    seek(int64_t offset, int whence) overrideDvdIOvirtual
    set_virtualfile(LPVIRTUALFILE virtualfile)FileIOprotected
    size() const overrideDvdIOvirtual
    size() const overrideDvdIOvirtual
    tell() const overrideDvdIOvirtual
    type() const overrideDvdIOvirtual
    type() const overrideDvdIOvirtual
    virtualfile()FileIO
    ~DvdIO()DvdIOvirtual
    ~DvdIO()DvdIOvirtual
    ~FileIO()=defaultFileIOvirtual
    diff --git a/html/classDvdIO.html b/html/classDvdIO.html index 019926c79..2f304056a 100644 --- a/html/classDvdIO.html +++ b/html/classDvdIO.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: DvdIO Class Reference @@ -19,10 +19,9 @@
    - - + @@ -30,21 +29,22 @@
    -
    FFmpegfs Fuse Multi Media Filesystem -  2.14 +
    +
    FFmpegfs Fuse Multi Media Filesystem 2.14
    - + +/* @license-end */ + -
    -
    DvdIO Class Reference
    +
    DvdIO Class Reference
    @@ -91,25 +90,23 @@
    Collaboration graph
    - - - - + + + + - - + +
    [legend]
    - - - + + - - + + @@ -141,19 +138,50 @@ - - + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -164,106 +192,82 @@

    +

    Public Member Functions

    DvdIO ()
     Create DvdIO object.
     DvdIO ()
     Create DvdIO object. More...
     
    -virtual ~DvdIO ()
     Free DvdIO object.
    virtual ~DvdIO ()
     Free DvdIO object. More...
     
    virtual VIRTUALTYPE type () const override
     Get type of the virtual file. More...
    virtual bool eof () const override
     Check if at end of file. More...
     
    -virtual void closeio () override
     Close virtual file.
    virtual void closeio () override
     Close virtual file. More...
     
    - Public Member Functions inherited from FileIO
    FileIO ()
     Create FileIO object.
     FileIO ()
     Create FileIO object. More...
     
    -virtual ~FileIO ()=default
    +virtual ~FileIO ()=default
     Free FileIO object.
     
    virtual VIRTUALTYPE type () const =0
     Get type of the virtual file. More...
     
    virtual size_t bufsize () const =0
     Get the ideal buffer size. More...
     
    virtual int openio (LPVIRTUALFILE virtualfile)=0
     Open a virtual file. More...
     
    virtual size_t readio (void *data, size_t size)=0
     Read data from a file. More...
     
    virtual int error () const =0
     Get last error. More...
     
    virtual int64_t duration () const =0
     Get the duration of the file, in AV_TIME_BASE fractional seconds. More...
     
    virtual size_t size () const =0
     Get the file size. More...
     
    virtual size_t tell () const =0
     Get current read position. More...
     
    virtual int seek (int64_t offset, int whence)=0
     Seek to position in file. More...
     
    virtual bool eof () const =0
     Check if at end of file. More...
     
    virtual void closeio ()=0
     Close virtual file. More...
     
    LPVIRTUALFILE virtualfile ()
     Get virtual file object. More...
     
     Path to source file (without file name) More...
     
    - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

    +

    Protected Attributes

    -dvd_reader_t * m_dvd
     DVD reader handle.
    dvd_reader_t * m_dvd
     DVD reader handle. More...
     
    -dvd_file_t * m_dvd_title
     DVD title handle.
    dvd_file_t * m_dvd_title
     DVD title handle. More...
     
    -ifo_handle_t * m_vmg_file
     DVD video manager handle.
    ifo_handle_t * m_vmg_file
     DVD video manager handle. More...
     
    -ifo_handle_t * m_vts_file
     DVD video title stream handle.
    ifo_handle_t * m_vts_file
     DVD video title stream handle. More...
     
    -pgc_t * m_cur_pgc
     Current program chain.
    pgc_t * m_cur_pgc
     Current program chain. More...
     
    -int m_start_cell
     Start cell.
    int m_start_cell
     Start cell. More...
     
    -int m_end_cell
     End cell (of title)
    int m_end_cell
     End cell (of title) More...
     
    -int m_cur_cell
     Current cell.
    int m_cur_cell
     Current cell. More...
     
    -int m_next_cell
     Next cell to be processed.
    int m_next_cell
     Next cell to be processed. More...
     
    -bool m_goto_next_cell
     If logc needs to go to next cell before next read.
    bool m_goto_next_cell
     If logc needs to go to next cell before next read. More...
     
    -unsigned int m_cur_block
     Current processing block.
    unsigned int m_cur_block
     Current processing block. More...
     
    -bool m_is_eof
     true if at "end of file", i.e, end of chapter or title
    bool m_is_eof
     true if at "end of file", i.e, end of chapter or title More...
     
    -int m_errno
     errno of last operation
    int m_errno
     errno of last operation More...
     
    -size_t m_rest_size
     Rest bytes in buffer.
    size_t m_rest_size
     Rest bytes in buffer. More...
     
    -size_t m_rest_pos
     Position in buffer.
    size_t m_rest_pos
     Position in buffer. More...
     
    -size_t m_cur_pos
     Current position in virtual file.
    size_t m_cur_pos
     Current position in virtual file. More...
     
    -bool m_full_title
     If true, ignore m_chapter_no and provide full track.
    bool m_full_title
     If true, ignore m_chapter_no and provide full track. More...
     
    -int m_title_idx
     Track index (track number - 1)
    int m_title_idx
     Track index (track number - 1) More...
     
    -int m_chapter_idx
     Chapter index (chapter number - 1)
    int m_chapter_idx
     Chapter index (chapter number - 1) More...
     
    -int m_angle_idx
     Selected angle index (angle number -1)
    int m_angle_idx
     Selected angle index (angle number -1) More...
     
    -unsigned char m_data [1024 *DVD_VIDEO_LB_LEN]
     Buffer for readio() data.
    unsigned char m_data [1024 *DVD_VIDEO_LB_LEN]
     Buffer for readio() data. More...
     
    -unsigned char m_buffer [1024 *DVD_VIDEO_LB_LEN]
     Buffer for data extracted from VOB file.
    unsigned char m_buffer [1024 *DVD_VIDEO_LB_LEN]
     Buffer for data extracted from VOB file. More...
     
    -int64_t m_duration
     Track/chapter duration, in AV_TIME_BASE fractional seconds.
    int64_t m_duration
     Track/chapter duration, in AV_TIME_BASE fractional seconds. More...
     
    -size_t m_size
     Size of virtual file.
    size_t m_size
     Size of virtual file. More...
     
    -

    +

    Private Types

    enum  DSITYPE { DSITYPE_CONTINUE , DSITYPE_EOF_CHAPTER @@ -275,11 +279,10 @@
     Type of a DSI block. More...
     
    - - - + + @@ -296,16 +299,14 @@ - - + + - - + +

    +

    Private Member Functions

    -void pvt_close ()
     Close virtual file. Non-virtual version to be safely called from constructor/destructor.
    void pvt_close ()
     Close virtual file. Non-virtual version to be safely called from constructor/destructor. More...
     
    bool is_nav_pack (const unsigned char *buffer) const
     Do a rough check if this is really a navigation packet. More...
    DSITYPE handle_DSI (void *_dsi_pack, size_t *cur_output_size, unsigned int *next_block, uint8_t *data)
     Handle DSI (Data Search Information) packet. More...
     
    -void next_cell ()
     Goto next DVD cell.
    void next_cell ()
     Goto next DVD cell. More...
     
    -void rewind ()
     Rewind to start of stream.
    void rewind ()
     Rewind to start of stream. More...
     
    - @@ -317,11 +318,11 @@

    +

    Additional Inherited Members

    - Static Public Member Functions inherited from FileIO
    static FileIOalloc (VIRTUALTYPE type)
     

    Detailed Description

    -

    Member Enumeration Documentation

    -
    +

    ◆ DSITYPE

    +
    +

    Constructor & Destructor Documentation

    + +

    ◆ DvdIO()

    + +
    +
    + + + + + +
    + + + + + + + +
    DvdIO::DvdIO ()
    +
    +explicit
    +
    + +

    Create DvdIO object.

    + +

    Definition at line 42 of file dvdio.cc.

    + +

    References m_buffer, and m_data.

    + +
    +
    + +

    ◆ ~DvdIO()

    + +
    +
    + + + + + +
    + + + + + + + +
    DvdIO::~DvdIO ()
    +
    +virtual
    +
    + +

    Free DvdIO object.

    + +

    Definition at line 70 of file dvdio.cc.

    + +

    References pvt_close().

    +

    Member Function Documentation

    - +

    ◆ bufsize()

    @@ -417,7 +481,40 @@

    + +

    ◆ closeio()

    + +
    +
    + + + + + +
    + + + + + + + +
    void DvdIO::closeio ()
    +
    +overridevirtual
    +
    + +

    Close virtual file.

    + +

    Implements FileIO.

    + +

    Definition at line 797 of file dvdio.cc.

    + +

    References pvt_close().

    + +
    +
    +

    ◆ demux_pes()

    - +

    ◆ duration()

    @@ -510,7 +607,7 @@

    +

    ◆ eof()

    @@ -546,7 +643,7 @@

    +

    ◆ error()

    @@ -580,7 +677,7 @@

    +

    ◆ get_packet_size()

    @@ -639,7 +736,7 @@

    +

    ◆ get_pes_id()

    @@ -691,7 +788,7 @@

    +

    ◆ handle_DSI()

    @@ -757,7 +854,7 @@

    +

    ◆ is_nav_pack()

    @@ -796,7 +893,40 @@

    + +

    ◆ next_cell()

    + +
    +
    + + + + + +
    + + + + + + + +
    void DvdIO::next_cell ()
    +
    +private
    +
    + +

    Goto next DVD cell.

    + +

    Definition at line 530 of file dvdio.cc.

    + +

    References m_angle_idx, m_cur_cell, m_cur_pgc, and m_next_cell.

    + +

    Referenced by handle_DSI(), and readio().

    + +
    +
    +

    ◆ openio()

    @@ -838,7 +968,40 @@

    + +

    ◆ pvt_close()

    + +
    +
    + + + + + +
    + + + + + + + +
    void DvdIO::pvt_close ()
    +
    +private
    +
    + +

    Close virtual file. Non-virtual version to be safely called from constructor/destructor.

    + +

    Definition at line 802 of file dvdio.cc.

    + +

    References m_dvd, m_dvd_title, m_vmg_file, and m_vts_file.

    + +

    Referenced by closeio(), and ~DvdIO().

    + +
    +
    +

    ◆ readio()

    + +

    ◆ m_buffer

    + +
    +
    + + + + + +
    + + + + +
    unsigned char DvdIO::m_buffer[1024 *DVD_VIDEO_LB_LEN]
    +
    +protected
    +
    + +

    Buffer for data extracted from VOB file.

    + +

    Definition at line 226 of file dvdio.h.

    + +

    Referenced by DvdIO(), and readio().

    + +
    +
    + +

    ◆ m_chapter_idx

    + +
    +
    + + + + + +
    + + + + +
    int DvdIO::m_chapter_idx
    +
    +protected
    +
    + +

    Chapter index (chapter number - 1)

    + +

    Definition at line 222 of file dvdio.h.

    + +

    Referenced by openio().

    + +
    +
    + +

    ◆ m_cur_block

    + +
    +
    + + + + + +
    + + + + +
    unsigned int DvdIO::m_cur_block
    +
    +protected
    +
    + +

    Current processing block.

    + +

    Definition at line 213 of file dvdio.h.

    + +

    Referenced by handle_DSI(), and readio().

    + +
    +
    + +

    ◆ m_cur_cell

    + +
    +
    + + + + + +
    + + + + +
    int DvdIO::m_cur_cell
    +
    +protected
    +
    + +

    Current cell.

    + +

    Definition at line 210 of file dvdio.h.

    + +

    Referenced by handle_DSI(), next_cell(), readio(), and rewind().

    + +
    +
    + +

    ◆ m_cur_pgc

    + +
    +
    + + + + + +
    + + + + +
    pgc_t* DvdIO::m_cur_pgc
    +
    +protected
    +
    + +

    Current program chain.

    + +

    Definition at line 207 of file dvdio.h.

    + +

    Referenced by handle_DSI(), next_cell(), openio(), and readio().

    + +
    +
    + +

    ◆ m_cur_pos

    + +
    +
    + + + + + +
    + + + + +
    size_t DvdIO::m_cur_pos
    +
    +protected
    +
    + +

    Current position in virtual file.

    + +

    Definition at line 218 of file dvdio.h.

    + +

    Referenced by readio(), rewind(), and tell().

    + +
    +
    + +

    ◆ m_data

    + +
    +
    + + + + + +
    + + + + +
    unsigned char DvdIO::m_data[1024 *DVD_VIDEO_LB_LEN]
    +
    +protected
    +
    + +

    Buffer for readio() data.

    + +

    Definition at line 225 of file dvdio.h.

    + +

    Referenced by bufsize(), DvdIO(), and readio().

    + +
    +
    + +

    ◆ m_duration

    + +
    +
    + + + + + +
    + + + + +
    int64_t DvdIO::m_duration
    +
    +protected
    +
    + +

    Track/chapter duration, in AV_TIME_BASE fractional seconds.

    + +

    Definition at line 228 of file dvdio.h.

    + +

    Referenced by duration(), and openio().

    + +
    +
    + +

    ◆ m_dvd

    + +
    +
    + + + + + +
    + + + + +
    dvd_reader_t* DvdIO::m_dvd
    +
    +protected
    +
    + +

    DVD reader handle.

    + +

    Definition at line 203 of file dvdio.h.

    + +

    Referenced by openio(), and pvt_close().

    + +
    +
    + +

    ◆ m_dvd_title

    + +
    +
    + + + + + +
    + + + + +
    dvd_file_t* DvdIO::m_dvd_title
    +
    +protected
    +
    + +

    DVD title handle.

    + +

    Definition at line 204 of file dvdio.h.

    + +

    Referenced by openio(), pvt_close(), and readio().

    + +
    +
    + +

    ◆ m_end_cell

    + +
    +
    + + + + + +
    + + + + +
    int DvdIO::m_end_cell
    +
    +protected
    +
    + +

    End cell (of title)

    + +

    Definition at line 209 of file dvdio.h.

    + +

    Referenced by handle_DSI(), and openio().

    + +
    +
    + +

    ◆ m_errno

    + +
    +
    + + + + + +
    + + + + +
    int DvdIO::m_errno
    +
    +protected
    +
    + +

    errno of last operation

    + +

    Definition at line 215 of file dvdio.h.

    + +

    Referenced by error(), readio(), and rewind().

    + +
    +
    + +

    ◆ m_full_title

    + +
    +
    + + + + + +
    + + + + +
    bool DvdIO::m_full_title
    +
    +protected
    +
    + +

    If true, ignore m_chapter_no and provide full track.

    + +

    Definition at line 220 of file dvdio.h.

    + +

    Referenced by openio(), and readio().

    + +
    +
    + +

    ◆ m_goto_next_cell

    + +
    +
    + + + + + +
    + + + + +
    bool DvdIO::m_goto_next_cell
    +
    +protected
    +
    + +

    If logc needs to go to next cell before next read.

    + +

    Definition at line 212 of file dvdio.h.

    + +

    Referenced by readio(), and rewind().

    + +
    +
    + +

    ◆ m_is_eof

    + +
    +
    + + + + + +
    + + + + +
    bool DvdIO::m_is_eof
    +
    +protected
    +
    + +

    true if at "end of file", i.e, end of chapter or title

    + +

    Definition at line 214 of file dvdio.h.

    + +

    Referenced by eof(), readio(), and rewind().

    + +
    +
    + +

    ◆ m_next_cell

    + +
    +
    + + + + + +
    + + + + +
    int DvdIO::m_next_cell
    +
    +protected
    +
    + +

    Next cell to be processed.

    + +

    Definition at line 211 of file dvdio.h.

    + +

    Referenced by handle_DSI(), next_cell(), readio(), and rewind().

    + +
    +
    + +

    ◆ m_rest_pos

    + +
    +
    + + + + + +
    + + + + +
    size_t DvdIO::m_rest_pos
    +
    +protected
    +
    + +

    Position in buffer.

    + +

    Definition at line 217 of file dvdio.h.

    + +

    Referenced by readio(), and rewind().

    + +
    +
    + +

    ◆ m_rest_size

    + +
    +
    + + + + + +
    + + + + +
    size_t DvdIO::m_rest_size
    +
    +protected
    +
    + +

    Rest bytes in buffer.

    + +

    Definition at line 216 of file dvdio.h.

    + +

    Referenced by readio(), and rewind().

    + +
    +
    + +

    ◆ m_size

    + +
    +
    + + + + + +
    + + + + +
    size_t DvdIO::m_size
    +
    +protected
    +
    + +

    Size of virtual file.

    + +

    Definition at line 229 of file dvdio.h.

    + +

    Referenced by openio(), and size().

    + +
    +
    + +

    ◆ m_start_cell

    + +
    +
    + + + + + +
    + + + + +
    int DvdIO::m_start_cell
    +
    +protected
    +
    + +

    Start cell.

    + +

    Definition at line 208 of file dvdio.h.

    + +

    Referenced by openio(), and rewind().

    + +
    +
    + +

    ◆ m_title_idx

    + +
    +
    + + + + + +
    + + + + +
    int DvdIO::m_title_idx
    +
    +protected
    +
    + +

    Track index (track number - 1)

    + +

    Definition at line 221 of file dvdio.h.

    + +

    Referenced by openio().

    + +
    +
    + +

    ◆ m_vmg_file

    + +
    +
    + + + + + +
    + + + + +
    ifo_handle_t* DvdIO::m_vmg_file
    +
    +protected
    +
    + +

    DVD video manager handle.

    + +

    Definition at line 205 of file dvdio.h.

    + +

    Referenced by openio(), and pvt_close().

    + +
    +
    + +

    ◆ m_vts_file

    + +
    +
    + + + + + +
    + + + + +
    ifo_handle_t* DvdIO::m_vts_file
    +
    +protected
    +
    + +

    DVD video title stream handle.

    + +

    Definition at line 206 of file dvdio.h.

    + +

    Referenced by openio(), and pvt_close().

    +

    The documentation for this class was generated from the following files:
      @@ -1065,7 +1934,7 @@

      diff --git a/html/classDvdIO__coll__graph.map b/html/classDvdIO__coll__graph.map index 0747713e2..0a5a5a4df 100644 --- a/html/classDvdIO__coll__graph.map +++ b/html/classDvdIO__coll__graph.map @@ -1,9 +1,9 @@ - - - - + + + + - - + + diff --git a/html/classDvdIO__coll__graph.md5 b/html/classDvdIO__coll__graph.md5 index 5143c57b9..d001d6b8c 100644 --- a/html/classDvdIO__coll__graph.md5 +++ b/html/classDvdIO__coll__graph.md5 @@ -1 +1 @@ -9c2c05b34bc2c0d5b606581be52a4fbd \ No newline at end of file +e79d7cc0ce2159728bbb7877ead8bf26 \ No newline at end of file diff --git a/html/classDvdIO__coll__graph.png b/html/classDvdIO__coll__graph.png index bf1501fdc2c90f9dfb67cb9bedf7866290922e5a..f17ba94027acae2f90d39ccf8895d414a231e55c 100644 GIT binary patch literal 21145 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 X)P=61rnNaw;wJ*#+KyUbbt3jZuEmAt literal 24185 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⁣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 - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
      - - + @@ -30,21 +29,22 @@
      -
      FFmpegfs Fuse Multi Media Filesystem -  2.14 +
      +
      FFmpegfs Fuse Multi Media Filesystem 2.14
      - + +/* @license-end */ +
      -
      -
      FFmpeg_Base Member List
      +
      FFmpeg_Base Member List

      This is the complete list of members for FFmpeg_Base, including all inherited members.

      - + - + - + - + - + - + - + - + - + - + - - - + + +
      audio_info(bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) constFFmpeg_Baseprotected
      destname() const =0FFmpeg_Baseprotectedpure virtual
      destname() const =0FFmpeg_Baseprotectedpure virtual
      dict_set_with_check(AVDictionary **pm, const char *key, const char *value, int flags, const char *filename=nullptr, bool nodelete=false) constFFmpeg_Baseprotected
      dict_set_with_check(AVDictionary **pm, const char *key, int64_t value, int flags, const char *filename=nullptr, bool nodelete=false) constFFmpeg_Baseprotected
      dict_set_with_check(AVDictionary **pm, const char *key, int64_t value, int flags, const char *filename=nullptr, bool nodelete=false) constFFmpeg_Baseprotected
      FFmpeg_Base()FFmpeg_Baseexplicit
      filename() const =0FFmpeg_Baseprotectedpure virtual
      filename() const =0FFmpeg_Baseprotectedpure virtual
      frame_to_pts(AVStream *stream, uint32_t frame_no) constFFmpeg_Baseprotected
      get_channel_layout_name(const AVChannelLayout *ch_layout)FFmpeg_Baseprotectedstatic
      get_channel_layout_name(const AVChannelLayout *ch_layout)FFmpeg_Baseprotectedstatic
      get_channels(const AVCodecParameters *codecpar) constFFmpeg_Baseprotected
      get_channels(const AVCodecContext *codec_ctx) constFFmpeg_Baseprotected
      get_channels(const AVCodecContext *codec_ctx) constFFmpeg_Baseprotected
      get_pix_fmt_name(AVPixelFormat pix_fmt)FFmpeg_Baseprotectedstatic
      get_sample_fmt_name(AVSampleFormat sample_fmt)FFmpeg_Baseprotectedstatic
      get_sample_fmt_name(AVSampleFormat sample_fmt)FFmpeg_Baseprotectedstatic
      get_script_info(AVCodecContext *codec_ctx, int play_res_x, int play_res_y, const char *font, int font_size, int primary_color, int secondary_color, int outline_color, int back_color, int bold, int italic, int underline, int border_style, int alignment) constFFmpeg_Baseprotected
      m_virtualfileFFmpeg_Baseprotected
      m_virtualfileFFmpeg_Baseprotected
      opt_set_with_check(void *obj, const char *key, const char *value, int flags, const char *filename=nullptr) constFFmpeg_Baseprotected
      pts_to_frame(AVStream *stream, int64_t pts) constFFmpeg_Baseprotected
      pts_to_frame(AVStream *stream, int64_t pts) constFFmpeg_Baseprotected
      set_channels(AVCodecParameters *codecpar_out, const AVCodecParameters *codecpar_in) constFFmpeg_Baseprotected
      set_channels(AVCodecContext *codec_ctx_out, const AVCodecContext *codec_ctx_in) constFFmpeg_Baseprotected
      set_channels(AVCodecContext *codec_ctx_out, const AVCodecContext *codec_ctx_in) constFFmpeg_Baseprotected
      set_channels(AVCodecContext *codec_ctx_out, int channels) constFFmpeg_Baseprotected
      subtitle_info(bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) constFFmpeg_Baseprotected
      subtitle_info(bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) constFFmpeg_Baseprotected
      video_info(bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) constFFmpeg_Baseprotected
      video_stream_setup(AVCodecContext *output_codec_ctx, AVStream *output_stream, AVCodecContext *input_codec_ctx, AVRational framerate, AVPixelFormat enc_hw_pix_fmt) constFFmpeg_Baseprotected
      virtname() const =0FFmpeg_Baseprotectedpure virtual
      ~FFmpeg_Base()=defaultFFmpeg_Basevirtual
      video_stream_setup(AVCodecContext *output_codec_ctx, AVStream *output_stream, AVCodecContext *input_codec_ctx, AVRational framerate, AVPixelFormat enc_hw_pix_fmt) constFFmpeg_Baseprotected
      virtname() const =0FFmpeg_Baseprotectedpure virtual
      ~FFmpeg_Base()=defaultFFmpeg_Basevirtual
      diff --git a/html/classFFmpeg__Base.html b/html/classFFmpeg__Base.html index 786460e23..5b4508a64 100644 --- a/html/classFFmpeg__Base.html +++ b/html/classFFmpeg__Base.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: FFmpeg_Base Class Reference @@ -19,10 +19,9 @@
      - - + @@ -30,21 +29,22 @@
      -
      FFmpegfs Fuse Multi Media Filesystem -  2.14 +
      +
      FFmpegfs Fuse Multi Media Filesystem 2.14
      - + +/* @license-end */ +
      Static Protected Member Functions | Protected Attributes | List of all members
      -
      -
      FFmpeg_Base Class Referenceabstract
      +
      FFmpeg_Base Class Referenceabstract
      @@ -91,38 +90,37 @@
      Collaboration graph
      - - - + + + - - + +
      [legend]
      - - - + + - +

      +

      Public Member Functions

      FFmpeg_Base ()
       Construct FFmpeg_Base object.
       FFmpeg_Base ()
       Construct FFmpeg_Base object. More...
       
      -virtual ~FFmpeg_Base ()=default
      +virtual ~FFmpeg_Base ()=default
       Destruct FFmpeg_Base object.
       
      - - + - + - + @@ -134,15 +132,15 @@ - - - - - - - - - + + + + + + + + + @@ -168,7 +166,7 @@

      +

      Protected Member Functions

      void video_stream_setup (AVCodecContext *output_codec_ctx, AVStream *output_stream, AVCodecContext *input_codec_ctx, AVRational framerate, AVPixelFormat enc_hw_pix_fmt) const
       Set up a video stream. More...
       
      int dict_set_with_check (AVDictionary **pm, const char *key, const char *value, int flags, const char *filename=nullptr, bool nodelete=false) const
      int dict_set_with_check (AVDictionary **pm, const char *key, const char *value, int flags, const char *filename=nullptr, bool nodelete=false) const
       Call av_dict_set and check the result code. It displays an error message if appropriate. More...
       
      int dict_set_with_check (AVDictionary **pm, const char *key, int64_t value, int flags, const char *filename=nullptr, bool nodelete=false) const
      int dict_set_with_check (AVDictionary **pm, const char *key, int64_t value, int flags, const char *filename=nullptr, bool nodelete=false) const
       Call av_dict_set and check the result code. It displays an error message if appropriate. More...
       
      int opt_set_with_check (void *obj, const char *key, const char *value, int flags, const char *filename=nullptr) const
      int opt_set_with_check (void *obj, const char *key, const char *value, int flags, const char *filename=nullptr) const
       Call av_opt_set and check result code. Displays an error message if appropriate. More...
       
      void video_info (bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) const
      void subtitle_info (bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) const
       Print data from the subtitle stream to log. More...
       
      virtual const char * filename () const =0
       Return source filename. Must be implemented in child class. More...
       
      virtual const char * destname () const =0
       Return destination filename. Must be implemented in child class. More...
       
      virtual const char * virtname () const =0
       Return virtual filename. Must be implemented in child class. More...
       
      virtual const char * filename () const =0
       Return source filename. Must be implemented in child class. More...
       
      virtual const char * destname () const =0
       Return destination filename. Must be implemented in child class. More...
       
      virtual const char * virtname () const =0
       Return virtual filename. Must be implemented in child class. More...
       
      uint32_t pts_to_frame (AVStream *stream, int64_t pts) const
       Convert PTS value to frame number. More...
       
       Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS. Nicked from the FFmpeg API function ff_ass_subtitle_header_full(). :) More...
       
      - @@ -180,19 +178,48 @@

      +

      Static Protected Member Functions

      static std::string get_pix_fmt_name (AVPixelFormat pix_fmt)
       Calls av_get_pix_fmt_name and returns a std::string with the pix format name. More...
       Calls av_channel_layout_describe and returns a std::string with the channel layout. More...
       
      - - - + +

      +

      Protected Attributes

      -VIRTUALFILEm_virtualfile
       Underlying virtual file object.
      VIRTUALFILEm_virtualfile
       Underlying virtual file object. More...
       

      Detailed Description

      -

      The FFmpeg_Base class.

      +

      The FFmpeg_Base class.

      Definition at line 45 of file ffmpeg_base.h.

      -

      Member Function Documentation

      - +

      Constructor & Destructor Documentation

      + +

      ◆ FFmpeg_Base()

      + +
      +
      + + + + + +
      + + + + + + + +
      FFmpeg_Base::FFmpeg_Base ()
      +
      +explicit
      +
      + +

      Construct FFmpeg_Base object.

      + +

      Definition at line 53 of file ffmpeg_base.cc.

      + +
      +
      +

      Member Function Documentation

      +

      ◆ audio_info()

      - -

      ◆ destname()

      + +

      ◆ destname()

      @@ -260,7 +287,7 @@

      - + @@ -280,7 +307,7 @@

      +

      ◆ dict_set_with_check() [1/2]

      - +

      ◆ dict_set_with_check() [2/2]

      - -

      ◆ filename()

      + +

      ◆ filename()

      @@ -448,7 +475,7 @@

      virtual const char* FFmpeg_Base::destname virtual const char * FFmpeg_Base::destname ( ) const
      - + @@ -470,7 +497,7 @@

      +

      ◆ frame_to_pts()

      - +

      ◆ get_channel_layout_name()

      - +

      ◆ get_channels() [1/2]

      - +

      ◆ get_pix_fmt_name()

      - +

      ◆ get_sample_fmt_name()

      - +

      ◆ get_script_info()

      - +

      ◆ opt_set_with_check()

      - +

      ◆ pts_to_frame()

      - +

      ◆ set_channels() [1/3]

      @@ -1019,7 +1046,7 @@

      +

      ◆ set_channels() [2/3]

      @@ -1066,7 +1093,7 @@

      +

      ◆ set_channels() [3/3]

      @@ -1111,11 +1138,11 @@

      Definition at line 340 of file ffmpeg_base.cc.

      -

      Referenced by FFmpeg_Transcoder::add_stream().

      +

      Referenced by FFmpeg_Transcoder::add_stream().

      - +

      ◆ subtitle_info()

      - +

      ◆ video_info()

      - +

      ◆ video_stream_setup()

      @@ -1299,12 +1326,12 @@

      References Logging::warning().

      -

      Referenced by FFmpeg_Transcoder::add_stream().

      +

      Referenced by FFmpeg_Transcoder::add_stream().

      - -

      ◆ virtname()

      + +

      ◆ virtname()

      @@ -1313,7 +1340,7 @@

      virtual const char* FFmpeg_Base::filename virtual const char * FFmpeg_Base::filename ( ) const
      - + @@ -1333,6 +1360,35 @@

      Referenced by audio_info(), subtitle_info(), and video_info().

      + + +

      Member Data Documentation

      + +

      ◆ m_virtualfile

      + +
      +
      +
      virtual const char* FFmpeg_Base::virtname virtual const char * FFmpeg_Base::virtname ( ) const
      + + + + +
      + + + + +
      VIRTUALFILE* FFmpeg_Base::m_virtualfile
      +
      +protected
      +


      The documentation for this class was generated from the following files:

    -

    Definition at line 2541 of file ffmpeg_transcoder.cc.

    +

    Definition at line 2567 of file ffmpeg_transcoder.cc.

    -

    References Logging::error(), ffmpeg_geterror(), store_packet(), Logging::trace(), and virtname().

    +

    References Logging::error(), ffmpeg_geterror(), store_packet(), Logging::trace(), and virtname().

    -

    Referenced by decode_frame(), and process_albumarts().

    +

    Referenced by decode_frame(), and process_albumarts().

- +

◆ add_albumart_stream()

- +

◆ add_external_subtitle_stream()

- +

◆ add_external_subtitle_streams()

- +

◆ add_samples_to_fifo()

- +

◆ add_stream()

@@ -1331,15 +1429,15 @@

Returns
On success, returns index of new stream [0...n]; On error, negative AVERROR value.
Todo:
FFmpeg actually can transcode while presevering the SAR. FFmpegfs rescales to fix that problem. Need to find out what I am doing wrong here...
-

Definition at line 1607 of file ffmpeg_transcoder.cc.

+

Definition at line 1633 of file ffmpeg_transcoder.cc.

-

References add_stream_map(), BITRATE, Logging::debug(), FFmpeg_Base::dict_set_with_check(), Logging::error(), ffmpeg_rescale_q(), format_bitrate(), format_samplerate(), FFmpeg_Base::get_channels(), get_hw_encoder_name(), get_hw_pix_fmt(), get_hwaccel_API_text(), get_output_bit_rate(), get_output_sample_rate(), get_video_size(), HWACCELMODE_ENABLED, HWACCELMODE_FALLBACK, hwframe_ctx_set(), FFmpeg_Transcoder::INPUTFILE::m_audio, FFMPEGFS_PARAMS::m_audiobitrate, FFMPEGFS_PARAMS::m_audiochannels, FFMPEGFS_PARAMS::m_audiosamplerate, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_current_format, m_enc_hw_pix_fmt, FFmpeg_Transcoder::INPUTFILE::m_filetype, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_hwaccel_enable_enc_buffering, FFMPEGFS_PARAMS::m_hwaccel_enc_API, m_hwaccel_enc_device_ctx, FFMPEGFS_PARAMS::m_hwaccel_enc_device_type, m_hwaccel_enc_mode, m_in, m_out, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, FFMPEGFS_PARAMS::m_videobitrate, params, FFmpegfs_Format::sample_format(), FFmpeg_Base::set_channels(), FFmpeg_Transcoder::StreamRef::set_codec_ctx(), Logging::trace(), FFmpeg_Base::video_stream_setup(), and virtname().

+

References add_stream_map(), BITRATE, Logging::debug(), FFmpeg_Base::dict_set_with_check(), Logging::error(), ffmpeg_rescale_q(), format_bitrate(), format_samplerate(), FFmpeg_Base::get_channels(), get_hw_encoder_name(), get_hw_pix_fmt(), get_hwaccel_API_text(), get_output_bit_rate(), get_output_sample_rate(), get_video_size(), HWACCELMODE_ENABLED, HWACCELMODE_FALLBACK, hwframe_ctx_set(), FFmpeg_Transcoder::INPUTFILE::m_audio, FFMPEGFS_PARAMS::m_audiobitrate, FFMPEGFS_PARAMS::m_audiochannels, FFMPEGFS_PARAMS::m_audiosamplerate, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_current_format, m_enc_hw_pix_fmt, FFmpeg_Transcoder::INPUTFILE::m_filetype, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_hwaccel_enable_enc_buffering, FFMPEGFS_PARAMS::m_hwaccel_enc_API, m_hwaccel_enc_device_ctx, FFMPEGFS_PARAMS::m_hwaccel_enc_device_type, m_hwaccel_enc_mode, m_in, m_out, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, FFMPEGFS_PARAMS::m_videobitrate, params, FFmpegfs_Format::sample_format(), FFmpeg_Base::set_channels(), FFmpeg_Transcoder::StreamRef::set_codec_ctx(), Logging::trace(), FFmpeg_Base::video_stream_setup(), and virtname().

-

Referenced by open_output_filestreams().

+

Referenced by open_output_filestreams().

- +

◆ add_stream_copy()

- +

◆ add_stream_map()

@@ -1434,15 +1532,15 @@

Definition at line 7481 of file ffmpeg_transcoder.cc.

+

Definition at line 7529 of file ffmpeg_transcoder.cc.

References INVALID_STREAM, and m_stream_map.

-

Referenced by add_stream(), add_stream_copy(), and add_subtitle_stream().

+

Referenced by add_stream(), add_stream_copy(), and add_subtitle_stream().

- +

◆ add_subtitle_stream()

@@ -1493,15 +1591,15 @@

Returns
On success, returns index of new stream [0...n]; On error, negative AVERROR value.
-

Definition at line 2214 of file ffmpeg_transcoder.cc.

+

Definition at line 2240 of file ffmpeg_transcoder.cc.

-

References add_stream_map(), ASS_DEFAULT_ALIGNMENT, ASS_DEFAULT_BACK_COLOUR, ASS_DEFAULT_BOLD, ASS_DEFAULT_BORDERSTYLE, ASS_DEFAULT_COLOUR, ASS_DEFAULT_FONT, ASS_DEFAULT_FONT_SIZE, ASS_DEFAULT_ITALIC, ASS_DEFAULT_PLAYRESX, ASS_DEFAULT_PLAYRESY, ASS_DEFAULT_UNDERLINE, Logging::debug(), FFmpeg_Base::dict_set_with_check(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), get_codec_name(), get_media_type_string(), FFmpeg_Base::get_script_info(), FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::StreamRef::m_codec_ctx, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_in, m_out, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_subtitle, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Transcoder::StreamRef::set_codec_ctx(), and virtname().

+

References add_stream_map(), ASS_DEFAULT_ALIGNMENT, ASS_DEFAULT_BACK_COLOUR, ASS_DEFAULT_BOLD, ASS_DEFAULT_BORDERSTYLE, ASS_DEFAULT_COLOUR, ASS_DEFAULT_FONT, ASS_DEFAULT_FONT_SIZE, ASS_DEFAULT_ITALIC, ASS_DEFAULT_PLAYRESX, ASS_DEFAULT_PLAYRESY, ASS_DEFAULT_UNDERLINE, Logging::debug(), FFmpeg_Base::dict_set_with_check(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), get_codec_name(), get_media_type_string(), FFmpeg_Base::get_script_info(), FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::StreamRef::m_codec_ctx, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_in, m_out, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_subtitle, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Transcoder::StreamRef::set_codec_ctx(), and virtname().

-

Referenced by add_external_subtitle_stream(), and add_subtitle_streams().

+

Referenced by add_external_subtitle_stream(), and add_subtitle_streams().

- +

◆ add_subtitle_streams()

- +

◆ alloc_picture()

- +

◆ audio_size()

- + +

◆ calculate_predicted_filesize()

+ + +

◆ can_copy_stream()

- +

◆ close_input_file()

- +

◆ close_output_file()

- +

◆ close_resample()

+ + +

◆ closeio()

+ +
+
+ + + + + + + +
void FFmpeg_Transcoder::closeio ()
+
- +

◆ convert_samples()

- +

◆ copy_audio_to_frame_buffer()

- +

◆ copy_metadata()

- +

◆ create_audio_frame()

- +

◆ create_fake_aiff_header()

- +

◆ create_fake_wav_header()

- +

◆ decode()

@@ -2124,7 +2280,7 @@

-

This does not quite work like avcodec_decode_audio4/avcodec_decode_video2. There is the following difference: if you got a frame, you must call it again with pkt=nullptr. pkt==nullptr is treated differently from pkt->size==0 (pkt==nullptr means get more output, pkt->size==0 is a flush/drain packet)

Parameters
+

This does not quite work like avcodec_decode_audio4/avcodec_decode_video2. There is the following difference: if you got a frame, you must call it again with pkt=nullptr. pkt==nullptr is treated differently from pkt->size==0 (pkt==nullptr means get more output, pkt->size==0 is a flush/drain packet)

Parameters
@@ -2142,15 +2298,15 @@

Definition at line 3173 of file ffmpeg_transcoder.cc.

+

Definition at line 3199 of file ffmpeg_transcoder.cc.

-

References Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), filename(), is_audio_stream(), is_video_stream(), FFmpeg_Transcoder::INPUTFILE::m_audio, m_in, m_out, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, and stream_exists().

+

References Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), filename(), is_audio_stream(), is_video_stream(), FFmpeg_Transcoder::INPUTFILE::m_audio, m_in, m_out, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, and stream_exists().

-

Referenced by decode_audio_frame(), and decode_video_frame().

+

Referenced by decode_audio_frame(), and decode_video_frame().

- +

◆ decode_audio_frame()

- +

◆ decode_frame()

@@ -2241,15 +2397,15 @@

Definition at line 3716 of file ffmpeg_transcoder.cc.

+

Definition at line 3749 of file ffmpeg_transcoder.cc.

-

References add_albumart_frame(), Logging::debug(), decode_audio_frame(), decode_subtitle(), decode_video_frame(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), ffmpeg_rescale_q_rnd(), FFMPEGFS_AUDIO, FFMPEGFS_VIDEO, filename(), format_duration(), is_audio_stream(), is_frameset(), is_subtitle_stream(), is_video_stream(), FFmpeg_Transcoder::INPUTFILE::m_album_art, FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::OUTPUTFILE::m_audio_pts, m_copy_audio, m_copy_video, FFMPEGFS_PARAMS::m_decoding_errors, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_in, m_out, m_reset_pts, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, VIRTUALFILE::m_type, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Transcoder::OUTPUTFILE::m_video_pts, FFmpeg_Base::m_virtualfile, params, pts(), store_packet(), stream_exists(), virtname(), and VIRTUALTYPE_DVD.

+

References add_albumart_frame(), Logging::debug(), decode_audio_frame(), decode_subtitle(), decode_video_frame(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), ffmpeg_rescale_q_rnd(), FFMPEGFS_AUDIO, FFMPEGFS_VIDEO, filename(), format_duration(), is_audio_stream(), is_frameset(), is_subtitle_stream(), is_video_stream(), FFmpeg_Transcoder::INPUTFILE::m_album_art, FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::OUTPUTFILE::m_audio_pts, m_copy_audio, m_copy_video, FFMPEGFS_PARAMS::m_decoding_errors, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_in, m_out, m_reset_pts, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, VIRTUALFILE::m_type, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Transcoder::OUTPUTFILE::m_video_pts, FFmpeg_Base::m_virtualfile, params, store_packet(), stream_exists(), virtname(), and VIRTUALTYPE_DVD.

-

Referenced by read_decode_convert_and_store().

+

Referenced by read_decode_convert_and_store().

- +

◆ decode_subtitle() [1/2]

- +

◆ decode_subtitle() [2/2]

- +

◆ decode_video_frame()

@@ -2409,15 +2565,15 @@

Returns
On success, returns 0; on error, a negative AVERROR value.
-

Definition at line 3330 of file ffmpeg_transcoder.cc.

+

Definition at line 3356 of file ffmpeg_transcoder.cc.

-

References alloc_picture(), Logging::debug(), decode(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q_rnd(), filename(), format_duration(), get_next_segment(), goto_next_segment(), is_hls(), FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_frame_map, m_hwaccel_enable_dec_buffering, m_in, m_insert_keyframe, m_out, FFmpeg_Transcoder::INPUTFILE::m_pix_fmt, m_pos, m_pts, FFmpeg_Transcoder::StreamRef::m_start_time, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, m_sws_ctx, FFmpeg_Transcoder::INPUTFILE::m_video, pts(), FFmpeg_Frame::res(), send_filters(), and virtname().

+

References alloc_picture(), Logging::debug(), decode(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q_rnd(), filename(), format_duration(), get_next_segment(), goto_next_segment(), is_hls(), FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_frame_map, m_hwaccel_enable_dec_buffering, m_in, m_insert_keyframe, m_out, FFmpeg_Transcoder::INPUTFILE::m_pix_fmt, m_pos, m_pts, FFmpeg_Transcoder::StreamRef::m_start_time, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, m_sws_ctx, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Frame::res(), send_filters(), and virtname().

-

Referenced by decode_frame(), and flush_frames_single().

+

Referenced by decode_frame(), and flush_frames_single().

- +

◆ destname()

@@ -2443,15 +2599,15 @@

Returns
Returns filename.
-

Implements FFmpeg_Base.

+

Implements FFmpeg_Base.

-

Definition at line 6433 of file ffmpeg_transcoder.cc.

+

Definition at line 6481 of file ffmpeg_transcoder.cc.

References VIRTUALFILE::m_destfile, and FFmpeg_Base::m_virtualfile.

- +

◆ do_seek_frame()

- +

◆ duration()

- +

◆ encode_audio_frame()

- +

◆ encode_finish()

- +

◆ encode_image_frame()

- +

◆ encode_subtitle()

- +

◆ encode_video_frame()

- +

◆ filename()

- +

◆ find_sw_fmt_by_hw_type()

+ + +

◆ flush_buffers()

+ +
+
+

[in]codec_ctx- AVCodecContext of input stream.
[in]frame- Decoded frame
+ + + + + + +
void FFmpeg_Transcoder::flush_buffers ()
+

+ +

Flush FFmpeg's input buffers.

+ +

Definition at line 5022 of file ffmpeg_transcoder.cc.

+ +

References FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_in, and FFmpeg_Transcoder::INPUTFILE::m_video.

+ +

Referenced by start_new_segment().

- + +

◆ flush_delayed_audio()

+ +
+
+ + + + + + + +
int FFmpeg_Transcoder::flush_delayed_audio ()
+
+ +

Flush delayed audio packets, if there are any.

+ +

Definition at line 5102 of file ffmpeg_transcoder.cc.

+ +

References encode_audio_frame(), Logging::error(), ffmpeg_geterror(), FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_out, and virtname().

+ +

Referenced by process_single_fr().

+ +
+
+

◆ flush_delayed_subtitles()

@@ -2852,13 +3058,38 @@

Todo:
Implement flush_delayed_subtitles() if required
-

Definition at line 5122 of file ffmpeg_transcoder.cc.

+

Definition at line 5170 of file ffmpeg_transcoder.cc.

+ +

Referenced by process_single_fr().

+ +

+ + +

◆ flush_delayed_video()

+ +
+
+ + + + + + + +
int FFmpeg_Transcoder::flush_delayed_video ()
+
- +

◆ flush_frames_all()

- +

◆ flush_frames_single()

- +

◆ foreach_subtitle_file()

+ + +

◆ free_filters()

+ +
+
+ + + + + +
+ + + + + + + +
void FFmpeg_Transcoder::free_filters ()
+
+protected
+
+ +

Free filter sinks.

-

References Logging::error(), ffmpeg_geterror(), and filename().

+

Definition at line 6691 of file ffmpeg_transcoder.cc.

-

Referenced by add_external_subtitle_streams().

+

References m_buffer_sink_context, m_buffer_source_context, and m_filter_graph.

+ +

Referenced by close_input_file().

- +

◆ get_aspect_ratio()

- +

◆ get_format()

@@ -3108,7 +3372,7 @@

-

Callback to negotiate the pixelFormat

Parameters
+

Callback to negotiate the pixelFormat

Parameters
@@ -3123,13 +3387,15 @@

Definition at line 6733 of file ffmpeg_transcoder.cc.

+

Definition at line 6792 of file ffmpeg_transcoder.cc.

-

References m_have_seeked.

+

References Logging::error(), filename(), FFmpeg_Base::get_pix_fmt_name(), m_dec_hw_pix_fmt, FFMPEGFS_PARAMS::m_hwaccel_dec_device_type, and params.

+ +

Referenced by get_format_static().

- +

◆ get_format_static()

[in]input_codec_ctx- Input codec context
[in]pix_fmtsis the list of formats which are supported by the codec, it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. The first is always the native one.
@@ -3177,13 +3443,15 @@

Definition at line 6733 of file ffmpeg_transcoder.cc.

+

Definition at line 6786 of file ffmpeg_transcoder.cc.

+ +

References get_format().

-

Referenced by hwdevice_ctx_add_ref().

+

Referenced by hwdevice_ctx_add_ref().

- +

◆ get_hw_decoder_name()

@@ -3227,17 +3495,17 @@

Returns
0 on success, a negative AVERROR code on failure.
Todo:
HWACCEL - Supported formats
-

Tested and working: VA-API, MMAL and OMX.

-

Some VA-API formats do not yet work, see "fixit"

-

V4LM2M: implemented, but untested NIVIDA/CUDA: implemented, but untested

+

Tested and working: VA-API, MMAL and OMX.

+

Some VA-API formats do not yet work, see "fixit"

+

V4LM2M: implemented, but untested NIVIDA/CUDA: implemented, but untested

-

Definition at line 6991 of file ffmpeg_transcoder.cc.

+

Definition at line 7039 of file ffmpeg_transcoder.cc.

-

References get_hw_mmal_decoder_name(), get_hw_vaapi_codec_name(), HWACCELAPI_MMAL, HWACCELAPI_VAAPI, FFMPEGFS_PARAMS::m_hwaccel_dec_API, and params.

+

References get_hw_mmal_decoder_name(), get_hw_vaapi_codec_name(), HWACCELAPI_MMAL, HWACCELAPI_VAAPI, FFMPEGFS_PARAMS::m_hwaccel_dec_API, and params.

- +

◆ get_hw_encoder_name()

- +

◆ get_hw_mmal_decoder_name()

- +

◆ get_hw_omx_encoder_name()

- +

◆ get_hw_pix_fmt()

- +

◆ get_hw_v4l2m2m_encoder_name()

@@ -3524,13 +3792,13 @@

Definition at line 7341 of file ffmpeg_transcoder.cc.

+

Definition at line 7389 of file ffmpeg_transcoder.cc.

- +

◆ get_hw_vaapi_codec_name()

@@ -3573,18 +3841,18 @@

Returns
0 on success, AVERROR_DECODER_NOT_FOUND if no codec available.
-

*** Intel VAAPI de/encoder ***

-

h264_vaapi H.264/AVC (VAAPI) (codec h264) hevc_vaapi H.265/HEVC (VAAPI) (codec hevc) mjpeg_vaapi MJPEG (VAAPI) (codec mjpeg) mpeg2_vaapi MPEG-2 (VAAPI) (codec mpeg2video) vp1_vaapi VC1 (VAAPI) (codec vc1) seems to be possible on my hardware vp8_vaapi VP8 (VAAPI) (codec vp8) vp9_vaapi VP9 (VAAPI) (codec vp9)

+

*** Intel VAAPI de/encoder ***

+

h264_vaapi H.264/AVC (VAAPI) (codec h264) hevc_vaapi H.265/HEVC (VAAPI) (codec hevc) mjpeg_vaapi MJPEG (VAAPI) (codec mjpeg) mpeg2_vaapi MPEG-2 (VAAPI) (codec mpeg2video) vp1_vaapi VC1 (VAAPI) (codec vc1) seems to be possible on my hardware vp8_vaapi VP8 (VAAPI) (codec vp8) vp9_vaapi VP9 (VAAPI) (codec vp9)

Todo:
fixit, MPEG-1 decoding does not work...
-

Program terminated with signal SIGSEGV, Segmentation fault. #0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383 383 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: Datei oder Verzeichnis nicht gefunden. [Current thread is 1 (Thread 0x7f95a24d4700 (LWP 16179))] (gdb) bt #0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383 #1 0x00007f95903c4e26 in ?? () from /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so #2 0x00007f95aaae80b8 in vaGetImage () from /lib/x86_64-linux-gnu/libva.so.2 #3 0x00007f95af524bb5 in ?? () from /lib/x86_64-linux-gnu/libavutil.so.56 #4 0x00007f95af5250fb in ?? () from /lib/x86_64-linux-gnu/libavutil.so.56 #5 0x00007f95af51c37f in av_hwframe_transfer_data () from /lib/x86_64-linux-gnu/libavutil.so.56 #6 0x00007f95af51c406 in av_hwframe_transfer_data () from /lib/x86_64-linux-gnu/libavutil.so.56 #7 0x0000555da4fde146 in FFmpeg_Transcoder::decode_video_frame (this=0x7f9598002e90, pkt=0x7f95a24d2f90, decoded=0x7f95a24d2ec4) at ffmpeg_transcoder.cc:2655 #8 0x0000555da4fde5cd in FFmpeg_Transcoder::decode_frame (this=0x7f9598002e90, pkt=0x7f95a24d2f90) at ffmpeg_transcoder.cc:2852 #9 0x0000555da4fdea4b in FFmpeg_Transcoder::read_decode_convert_and_store (this=0x7f9598002e90, finished=0x7f95a24d3030) at ffmpeg_transcoder.cc:3189 #10 0x0000555da4fdfa73 in FFmpeg_Transcoder::process_single_fr (this=this@entry=0x7f9598002e90, status=@0x7f95a24d3134: 0) at ffmpeg_transcoder.cc:3987 #11 0x0000555da4f8c997 in transcoder_thread (arg=optimized out) at transcode.cc:874 #12 0x0000555da4fc54ef in thread_pool::loop_function (this=0x7f959c002b40) at thread_pool.cc:78 #13 0x00007f95aeaf4c10 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6 #14 0x00007f95ae9f0ea7 in start_thread (arg=optimized out) at pthread_create.c:477 #15 0x00007f95ae920d4f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

+

Program terminated with signal SIGSEGV, Segmentation fault. #0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383 383 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: Datei oder Verzeichnis nicht gefunden. [Current thread is 1 (Thread 0x7f95a24d4700 (LWP 16179))] (gdb) bt #0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383 #1 0x00007f95903c4e26 in ?? () from /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so #2 0x00007f95aaae80b8 in vaGetImage () from /lib/x86_64-linux-gnu/libva.so.2 #3 0x00007f95af524bb5 in ?? () from /lib/x86_64-linux-gnu/libavutil.so.56 #4 0x00007f95af5250fb in ?? () from /lib/x86_64-linux-gnu/libavutil.so.56 #5 0x00007f95af51c37f in av_hwframe_transfer_data () from /lib/x86_64-linux-gnu/libavutil.so.56 #6 0x00007f95af51c406 in av_hwframe_transfer_data () from /lib/x86_64-linux-gnu/libavutil.so.56 #7 0x0000555da4fde146 in FFmpeg_Transcoder::decode_video_frame (this=0x7f9598002e90, pkt=0x7f95a24d2f90, decoded=0x7f95a24d2ec4) at ffmpeg_transcoder.cc:2655 #8 0x0000555da4fde5cd in FFmpeg_Transcoder::decode_frame (this=0x7f9598002e90, pkt=0x7f95a24d2f90) at ffmpeg_transcoder.cc:2852 #9 0x0000555da4fdea4b in FFmpeg_Transcoder::read_decode_convert_and_store (this=0x7f9598002e90, finished=0x7f95a24d3030) at ffmpeg_transcoder.cc:3189 #10 0x0000555da4fdfa73 in FFmpeg_Transcoder::process_single_fr (this=this@entry=0x7f9598002e90, status=@0x7f95a24d3134: 0) at ffmpeg_transcoder.cc:3987 #11 0x0000555da4f8c997 in transcoder_thread (arg=optimized out) at transcode.cc:874 #12 0x0000555da4fc54ef in thread_pool::loop_function (this=0x7f959c002b40) at thread_pool.cc:78 #13 0x00007f95aeaf4c10 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6 #14 0x00007f95ae9f0ea7 in start_thread (arg=optimized out) at pthread_create.c:477 #15 0x00007f95ae920d4f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

-

Definition at line 7081 of file ffmpeg_transcoder.cc.

+

Definition at line 7129 of file ffmpeg_transcoder.cc.

-

Referenced by get_hw_decoder_name(), and get_hw_encoder_name().

+

Referenced by get_hw_decoder_name(), and get_hw_encoder_name().

- +

◆ get_next_segment()

- +

◆ get_out_subtitle_stream()

- +

◆ get_output_bit_rate()

- +

◆ get_output_sample_rate()

- +

◆ get_pix_formats()

- +

◆ get_prores_bitrate()

@@ -3903,15 +4171,15 @@

Returns
Bitrate in bit/s.
-

Definition at line 5598 of file ffmpeg_transcoder.cc.

+

Definition at line 5646 of file ffmpeg_transcoder.cc.

References m_prores_bitrate, and MAX_PRORES_FRAMERATE.

-

Referenced by video_size().

+

Referenced by video_size().

- +

◆ get_video_size()

- +

◆ goto_next_segment()

- +

◆ have_seeked()

- +

◆ hwdevice_ctx_add_ref()

- +

◆ hwdevice_ctx_create()

[in]input_codec_ctx- Input codec context
[in]pix_fmtsis the list of formats which are supported by the codec, it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. The first is always the native one.
@@ -4119,15 +4389,15 @@

Returns
0 on success, a negative AVERROR code on failure.
-

Definition at line 6768 of file ffmpeg_transcoder.cc.

+

Definition at line 6816 of file ffmpeg_transcoder.cc.

-

References Logging::error(), ffmpeg_geterror(), hwdevice_get_type_name(), and virtname().

+

References Logging::error(), ffmpeg_geterror(), hwdevice_get_type_name(), and virtname().

Referenced by open_bestmatch_video().

- +

◆ hwdevice_ctx_free()

@@ -4159,13 +4429,13 @@

Definition at line 6810 of file ffmpeg_transcoder.cc.

+

Definition at line 6858 of file ffmpeg_transcoder.cc.

-

Referenced by closeio(), and open_output().

+

Referenced by closeio(), and open_output().

- +

◆ hwframe_copy_from_hw()

[out]hwaccel_enc_device_ctx- On success, a reference to the newly-created device context will be written here.
@@ -4214,13 +4484,13 @@

Returns
0 on success, a negative AVERROR code on failure.
-

Definition at line 6924 of file ffmpeg_transcoder.cc.

+

Definition at line 6972 of file ffmpeg_transcoder.cc.

-

References Logging::error(), ffmpeg_geterror(), and filename().

+

References Logging::error(), ffmpeg_geterror(), and filename().

- +

◆ hwframe_copy_to_hw()

[in]output_codec_ctx- Codec context
[in,out]sw_frame- AVFrame to copy data to
@@ -4269,15 +4539,15 @@

Returns
0 on success, a negative AVERROR code on failure.
-

Definition at line 6945 of file ffmpeg_transcoder.cc.

+

Definition at line 6993 of file ffmpeg_transcoder.cc.

-

References Logging::error(), ffmpeg_geterror(), and virtname().

+

References Logging::error(), ffmpeg_geterror(), and virtname().

-

Referenced by encode_video_frame().

+

Referenced by encode_video_frame().

- +

◆ hwframe_ctx_set()

- +

◆ id3v1tag()

- +

◆ init_audio_output_frame()

- +

◆ init_converted_samples()

- +

◆ init_deinterlace_filters()

- +

◆ init_resampler()

- +

◆ init_rescaler()

- +

◆ input_read()

[in]output_codec_ctx- Codec context
[in,out]hw_frame- AVFrame to copy data to
@@ -4732,7 +5002,7 @@

Returns
On success, returns bytes read. May be less than size or even 0. On error, returns a negative AVERROR value.
-

Definition at line 6159 of file ffmpeg_transcoder.cc.

+

Definition at line 6207 of file ffmpeg_transcoder.cc.

References FileIO::eof(), FileIO::error(), Logging::error(), and FileIO::readio().

@@ -4740,7 +5010,7 @@

+

◆ is_audio_stream()

- +

◆ is_frameset()

- +

◆ is_hls()

- +

◆ is_multiformat()

@@ -4851,7 +5121,7 @@

Returns
Returns true for formats that export all frames as images.
-

Definition at line 6696 of file ffmpeg_transcoder.cc.

+

Definition at line 6744 of file ffmpeg_transcoder.cc.

References FFmpegfs_Format::is_multiformat(), and m_current_format.

@@ -4859,7 +5129,7 @@

+

◆ is_open()

- +

◆ is_video()

- +

◆ is_video_stream()

- +

◆ last_seek_frame_no()

- +

◆ mtime()

- +

◆ open_albumarts()

- +

◆ open_bestmatch_audio()

- +

◆ open_bestmatch_decoder()

- +

◆ open_bestmatch_video()

@@ -5251,13 +5521,13 @@

Definition at line 580 of file ffmpeg_transcoder.cc.

-

References Logging::debug(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), filename(), get_codec_name(), get_hw_encoder_name(), get_hwaccel_API_text(), hwdevice_ctx_create(), Logging::info(), is_video(), FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_current_format, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_hwaccel_enable_enc_buffering, FFMPEGFS_PARAMS::m_hwaccel_enc_API, FFMPEGFS_PARAMS::m_hwaccel_enc_device, m_hwaccel_enc_device_ctx, FFMPEGFS_PARAMS::m_hwaccel_enc_device_type, m_in, m_is_video, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, VIRTUALFILE::m_type, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Base::m_virtualfile, open_bestmatch_decoder(), params, FFmpeg_Transcoder::StreamRef::set_codec_ctx(), stream_exists(), Logging::trace(), FFmpegfs_Format::video_codec(), FFmpeg_Base::video_info(), virtname(), VIRTUALTYPE_BLURAY, and VIRTUALTYPE_DVD.

+

References Logging::debug(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), filename(), get_codec_name(), get_hw_encoder_name(), get_hwaccel_API_text(), hwdevice_ctx_create(), Logging::info(), is_video(), FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_current_format, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_hwaccel_enable_enc_buffering, FFMPEGFS_PARAMS::m_hwaccel_enc_API, FFMPEGFS_PARAMS::m_hwaccel_enc_device, m_hwaccel_enc_device_ctx, FFMPEGFS_PARAMS::m_hwaccel_enc_device_type, m_in, m_is_video, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, VIRTUALFILE::m_type, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Base::m_virtualfile, open_bestmatch_decoder(), params, FFmpeg_Transcoder::StreamRef::set_codec_ctx(), stream_exists(), Logging::trace(), FFmpegfs_Format::video_codec(), FFmpeg_Base::video_info(), virtname(), VIRTUALTYPE_BLURAY, and VIRTUALTYPE_DVD.

Referenced by open_input_file().

- +

◆ open_decoder()

- +

◆ open_input_file()

[in]opaque- Payload given to FFmpeg, basically the FileIO object
@@ -5387,13 +5657,13 @@

Definition at line 294 of file ffmpeg_transcoder.cc.

-

References FileIO::alloc(), FileIO::bufsize(), calculate_predicted_filesize(), FFMPEGFS_PARAMS::current_format(), Logging::debug(), FFmpeg_Base::dict_set_with_check(), FileIO::duration(), Logging::error(), FF_INPUT_BUFFER_PADDING_SIZE, ffmpeg_geterror(), ffmpeg_rescale_q(), filename(), get_filetype_from_list(), input_read(), is_open(), FFmpeg_Transcoder::INPUTFILE::m_audio, m_close_fileio, FFmpeg_Transcoder::StreamRef::m_codec_ctx, VIRTUALFILE::m_cuesheet_track, m_current_format, VIRTUALFILE::m_duration, m_fileio, FFmpeg_Transcoder::INPUTFILE::m_filetype, VIRTUALFILE::m_flags, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, VIRTUALFILE::m_framerate, VIRTUALFILE::m_height, m_in, m_mtime, FFMPEGFS_PARAMS::m_no_subtitles, VIRTUALFILE::m_predicted_size, VIRTUALFILE::m_st, VIRTUALFILE::CUESHEET_TRACK::m_start, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, VIRTUALFILE::m_type, FFmpeg_Transcoder::INPUTFILE::m_video, VIRTUALFILE::m_video_frame_count, FFmpeg_Base::m_virtualfile, VIRTUALFILE::m_width, open_albumarts(), open_bestmatch_audio(), open_bestmatch_video(), open_subtitles(), FileIO::openio(), params, seek(), stream_exists(), VIRTUALFLAG_CUESHEET, VIRTUALTYPE_BLURAY, VIRTUALTYPE_DVD, VIRTUALTYPE_VCD, and Logging::warning().

+

References FileIO::alloc(), FileIO::bufsize(), calculate_predicted_filesize(), FFMPEGFS_PARAMS::current_format(), Logging::debug(), FFmpeg_Base::dict_set_with_check(), FileIO::duration(), Logging::error(), FF_INPUT_BUFFER_PADDING_SIZE, ffmpeg_geterror(), ffmpeg_rescale_q(), filename(), get_filetype_from_list(), input_read(), is_open(), FFmpeg_Transcoder::INPUTFILE::m_audio, m_close_fileio, FFmpeg_Transcoder::StreamRef::m_codec_ctx, VIRTUALFILE::m_cuesheet_track, m_current_format, VIRTUALFILE::m_duration, m_fileio, FFmpeg_Transcoder::INPUTFILE::m_filetype, VIRTUALFILE::m_flags, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, VIRTUALFILE::m_framerate, VIRTUALFILE::m_height, m_in, m_mtime, FFMPEGFS_PARAMS::m_no_subtitles, VIRTUALFILE::m_predicted_size, VIRTUALFILE::m_st, VIRTUALFILE::CUESHEET_TRACK::m_start, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, VIRTUALFILE::m_type, FFmpeg_Transcoder::INPUTFILE::m_video, VIRTUALFILE::m_video_frame_count, FFmpeg_Base::m_virtualfile, VIRTUALFILE::m_width, open_albumarts(), open_bestmatch_audio(), open_bestmatch_video(), open_subtitles(), FileIO::openio(), params, seek(), stream_exists(), VIRTUALFLAG_CUESHEET, VIRTUALTYPE_BLURAY, VIRTUALTYPE_DVD, VIRTUALTYPE_VCD, and Logging::warning().

Referenced by transcode(), and transcoder_predict_filesize().

- +

◆ open_output()

@@ -5426,15 +5696,15 @@

Returns
On success, returns 0; on error, a negative AVERROR value.
-

Definition at line 1239 of file ffmpeg_transcoder.cc.

+

Definition at line 1265 of file ffmpeg_transcoder.cc.

-

References FFmpeg_Base::audio_info(), CACHE_FLAG_RW, close_output_file(), ffmpeg_rescale_q_rnd(), get_out_subtitle_stream(), VIRTUALFILE::get_segment_count(), HWACCELMODE_ENABLED, HWACCELMODE_FALLBACK, hwdevice_ctx_free(), Logging::info(), init_audio_fifo(), is_hls(), FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::OUTPUTFILE::m_audio_pts, m_buffer, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_current_format, m_current_segment, m_enc_hw_pix_fmt, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_hwaccel_enable_enc_buffering, m_hwaccel_enc_device_ctx, m_hwaccel_enc_mode, m_in, m_insert_keyframe, FFmpeg_Transcoder::OUTPUTFILE::m_last_mux_dts, m_out, FFmpeg_Transcoder::StreamRef::m_start_time, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_subtitle, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Transcoder::OUTPUTFILE::m_video_pts, FFmpeg_Base::m_virtualfile, map_in_to_out_stream(), Buffer::open_file(), open_output_filestreams(), predicted_filesize(), process_output(), stream_exists(), FFmpeg_Base::subtitle_info(), FFmpegfs_Format::video_codec(), FFmpeg_Base::video_info(), and virtname().

+

References FFmpeg_Base::audio_info(), CACHE_FLAG_RW, close_output_file(), ffmpeg_rescale_q_rnd(), get_out_subtitle_stream(), VIRTUALFILE::get_segment_count(), HWACCELMODE_ENABLED, HWACCELMODE_FALLBACK, hwdevice_ctx_free(), Logging::info(), init_audio_fifo(), is_hls(), FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::OUTPUTFILE::m_audio_pts, m_buffer, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_current_format, m_current_segment, m_enc_hw_pix_fmt, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_hwaccel_enable_enc_buffering, m_hwaccel_enc_device_ctx, m_hwaccel_enc_mode, m_in, m_insert_keyframe, FFmpeg_Transcoder::OUTPUTFILE::m_last_mux_dts, m_out, FFmpeg_Transcoder::StreamRef::m_start_time, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_subtitle, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Transcoder::OUTPUTFILE::m_video_pts, FFmpeg_Base::m_virtualfile, map_in_to_out_stream(), Buffer::open_file(), open_output_filestreams(), predicted_filesize(), process_output(), stream_exists(), FFmpeg_Base::subtitle_info(), FFmpegfs_Format::video_codec(), FFmpeg_Base::video_info(), and virtname().

-

Referenced by open_output_file(), and start_new_segment().

+

Referenced by open_output_file(), and start_new_segment().

- +

◆ open_output_file()

- +

◆ open_output_filestreams()

@@ -5500,15 +5770,15 @@

Returns
On success, returns 0; on error, a negative AVERROR value.
-

Definition at line 2568 of file ffmpeg_transcoder.cc.

+

Definition at line 2594 of file ffmpeg_transcoder.cc.

-

References add_albumart_stream(), add_external_subtitle_streams(), add_stream(), add_stream_copy(), add_subtitle_streams(), FFmpegfs_Format::albumart_supported(), FFmpegfs_Format::audio_codec(), can_copy_stream(), Logging::debug(), FFmpegfs_Format::desttype(), Logging::error(), FF_INPUT_BUFFER_PADDING_SIZE, FFMPEGFS_AUDIO, FFMPEGFS_VIDEO, FFmpegfs_Format::filetype(), FFmpegfs_Format::format_name(), Logging::info(), init_deinterlace_filters(), INVALID_STREAM, m_active_stream_msk, FFmpeg_Transcoder::INPUTFILE::m_album_art, FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_copy_audio, m_copy_video, m_current_format, FFMPEGFS_PARAMS::m_deinterlace, FFmpeg_Transcoder::INPUTFILE::m_filetype, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_in, m_inhibit_stream_msk, m_is_video, FFMPEGFS_PARAMS::m_noalbumarts, m_out, FFmpeg_Transcoder::INPUTFILE::m_pix_fmt, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_subtitle, FFmpeg_Transcoder::INPUTFILE::m_video, output_write(), params, seek(), stream_exists(), FFmpegfs_Format::video_codec(), and virtname().

+

References add_albumart_stream(), add_external_subtitle_streams(), add_stream(), add_stream_copy(), add_subtitle_streams(), FFmpegfs_Format::albumart_supported(), FFmpegfs_Format::audio_codec(), can_copy_stream(), Logging::debug(), FFmpegfs_Format::desttype(), Logging::error(), FF_INPUT_BUFFER_PADDING_SIZE, FFMPEGFS_AUDIO, FFMPEGFS_VIDEO, FFmpegfs_Format::filetype(), FFmpegfs_Format::format_name(), Logging::info(), init_deinterlace_filters(), INVALID_STREAM, m_active_stream_msk, FFmpeg_Transcoder::INPUTFILE::m_album_art, FFmpeg_Transcoder::INPUTFILE::m_audio, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_copy_audio, m_copy_video, m_current_format, FFMPEGFS_PARAMS::m_deinterlace, FFmpeg_Transcoder::INPUTFILE::m_filetype, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_in, m_inhibit_stream_msk, m_is_video, FFMPEGFS_PARAMS::m_noalbumarts, m_out, FFmpeg_Transcoder::INPUTFILE::m_pix_fmt, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_subtitle, FFmpeg_Transcoder::INPUTFILE::m_video, output_write(), params, seek(), stream_exists(), FFmpegfs_Format::video_codec(), and virtname().

-

Referenced by open_output().

+

Referenced by open_output().

- +

◆ open_output_frame_set()

@@ -5542,15 +5812,15 @@

Returns
On success, returns 0; on error, a negative AVERROR value.
Todo:
Make frame image compression rate command line settable
-

Definition at line 1089 of file ffmpeg_transcoder.cc.

+

Definition at line 1115 of file ffmpeg_transcoder.cc.

-

References CACHE_FLAG_RW, Logging::debug(), FFmpeg_Base::dict_set_with_check(), Logging::error(), FFmpeg_Base::get_pix_fmt_name(), get_pix_formats(), init_deinterlace_filters(), init_rescaler(), INVALID_STREAM, FFmpeg_Transcoder::INPUTFILE::m_audio, m_buffer, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_current_format, FFMPEGFS_PARAMS::m_deinterlace, m_have_seeked, m_in, m_out, FFmpeg_Transcoder::INPUTFILE::m_pix_fmt, m_seek_to_fifo, m_seek_to_fifo_mutex, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, Buffer::open_file(), params, predicted_filesize(), FFmpeg_Transcoder::StreamRef::set_codec_ctx(), FFmpegfs_Format::video_codec(), video_frame_count(), and virtname().

+

References CACHE_FLAG_RW, Logging::debug(), FFmpeg_Base::dict_set_with_check(), Logging::error(), FFmpeg_Base::get_pix_fmt_name(), get_pix_formats(), init_deinterlace_filters(), init_rescaler(), INVALID_STREAM, FFmpeg_Transcoder::INPUTFILE::m_audio, m_buffer, FFmpeg_Transcoder::StreamRef::m_codec_ctx, m_current_format, FFMPEGFS_PARAMS::m_deinterlace, m_have_seeked, m_in, m_out, FFmpeg_Transcoder::INPUTFILE::m_pix_fmt, m_seek_to_fifo, m_seek_to_fifo_mutex, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, Buffer::open_file(), params, predicted_filesize(), FFmpeg_Transcoder::StreamRef::set_codec_ctx(), FFmpegfs_Format::video_codec(), video_frame_count(), and virtname().

-

Referenced by open_output_file().

+

Referenced by open_output_file().

- +

◆ open_subtitles()

- +

◆ output_write()

- +

◆ predicted_filesize()

- +

◆ prepare_codec()

- +

◆ prepare_format()

- +

◆ process_albumarts()

- +

◆ process_metadata()

@@ -5832,15 +6102,15 @@

Returns
On success, returns 0; on error, a negative AVERROR value.
-

Definition at line 4899 of file ffmpeg_transcoder.cc.

+

Definition at line 4947 of file ffmpeg_transcoder.cc.

-

References copy_metadata(), FFmpeg_Base::dict_set_with_check(), is_audio_stream(), is_video_stream(), VIRTUALFILE::CUESHEET_TRACK::m_album, FFmpeg_Transcoder::INPUTFILE::m_album_art, VIRTUALFILE::CUESHEET_TRACK::m_artist, FFmpeg_Transcoder::INPUTFILE::m_audio, VIRTUALFILE::m_cuesheet_track, VIRTUALFILE::CUESHEET_TRACK::m_date, VIRTUALFILE::m_flags, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, VIRTUALFILE::CUESHEET_TRACK::m_genre, m_in, m_out, FFmpeg_Transcoder::StreamRef::m_stream, VIRTUALFILE::CUESHEET_TRACK::m_title, VIRTUALFILE::CUESHEET_TRACK::m_trackno, VIRTUALFILE::CUESHEET_TRACK::m_tracktotal, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Base::m_virtualfile, Logging::trace(), virtname(), and VIRTUALFLAG_CUESHEET.

+

References copy_metadata(), FFmpeg_Base::dict_set_with_check(), is_audio_stream(), is_video_stream(), VIRTUALFILE::CUESHEET_TRACK::m_album, FFmpeg_Transcoder::INPUTFILE::m_album_art, VIRTUALFILE::CUESHEET_TRACK::m_artist, FFmpeg_Transcoder::INPUTFILE::m_audio, VIRTUALFILE::m_cuesheet_track, VIRTUALFILE::CUESHEET_TRACK::m_date, VIRTUALFILE::m_flags, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, VIRTUALFILE::CUESHEET_TRACK::m_genre, m_in, m_out, FFmpeg_Transcoder::StreamRef::m_stream, VIRTUALFILE::CUESHEET_TRACK::m_title, VIRTUALFILE::CUESHEET_TRACK::m_trackno, VIRTUALFILE::CUESHEET_TRACK::m_tracktotal, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Base::m_virtualfile, Logging::trace(), virtname(), and VIRTUALFLAG_CUESHEET.

-

Referenced by process_output().

+

Referenced by process_output().

- +

◆ process_output()

- +

◆ process_single_fr()

@@ -5889,7 +6159,7 @@

-

Process a single frame of audio data. The encode_pcm_data() method of the Encoder will be used to process the resulting audio data, with the result going into the given Buffer.

Parameters
+

Process a single frame of audio data. The encode_pcm_data() method of the Encoder will be used to process the resulting audio data, with the result going into the given Buffer.

Parameters

[in,out]virtualfile- Virtualfile object for desired file. May be a physical file, a DVD, Blu-ray or video CD
[out]status- On success, returns DECODER_SUCCESS; if at EOF, returns DECODER_EOF; on error, returns DECODER_ERROR
@@ -5897,15 +6167,15 @@

Returns
On success, returns 0; on error, a negative AVERROR value. If EOF is reached, it returns 1.

-

Definition at line 5191 of file ffmpeg_transcoder.cc.

+

Definition at line 5239 of file ffmpeg_transcoder.cc.

-

References copy_audio_to_frame_buffer(), DECODER_EOF, DECODER_ERROR, DECODER_SUCCESS, encode_audio_frame(), encode_image_frame(), encode_subtitle(), encode_video_frame(), Logging::error(), flush_delayed_audio(), flush_delayed_subtitles(), flush_delayed_video(), get_next_segment(), goto_next_segment(), is_frameset(), is_hls(), m_active_stream_msk, FFmpeg_Transcoder::INPUTFILE::m_audio, m_copy_audio, m_frame_map, m_in, m_inhibit_stream_msk, m_out, FFMPEGFS_PARAMS::m_segment_duration, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Frame::m_stream_idx, FFmpeg_Subtitle::m_stream_idx, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, params, read_decode_convert_and_store(), seek_frame(), start_new_segment(), stream_exists(), and virtname().

+

References copy_audio_to_frame_buffer(), DECODER_EOF, DECODER_ERROR, DECODER_SUCCESS, encode_audio_frame(), encode_image_frame(), encode_subtitle(), encode_video_frame(), Logging::error(), flush_delayed_audio(), flush_delayed_subtitles(), flush_delayed_video(), get_next_segment(), goto_next_segment(), is_frameset(), is_hls(), m_active_stream_msk, FFmpeg_Transcoder::INPUTFILE::m_audio, m_copy_audio, m_frame_map, m_in, m_inhibit_stream_msk, m_out, FFMPEGFS_PARAMS::m_segment_duration, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Frame::m_stream_idx, FFmpeg_Subtitle::m_stream_idx, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, params, read_decode_convert_and_store(), seek_frame(), start_new_segment(), stream_exists(), and virtname().

Referenced by transcode().

- +

◆ produce_audio_dts()

- +

◆ pts()

+ + +

◆ purge()

+ +
+
+ + + + + +
+ + + + + + + +
void FFmpeg_Transcoder::purge ()
+
+protected
+
+ +

Purge FIFO and map buffers and report lost packets/frames/samples.

+ +

Definition at line 6338 of file ffmpeg_transcoder.cc.

+ +

References FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_out, VIRTUALFILE::m_virtfile, FFmpeg_Base::m_virtualfile, purge_audio_fifo(), purge_hls_fifo(), purge_multiframe_map(), and Logging::warning().

+ +

Referenced by close_output_file().

- +

◆ purge_audio_fifo()

@@ -6000,15 +6303,15 @@

Returns
Number of samples that have been purged. Function never fails.
-

Definition at line 6252 of file ffmpeg_transcoder.cc.

+

Definition at line 6300 of file ffmpeg_transcoder.cc.

References m_audio_fifo.

-

Referenced by purge().

+

Referenced by purge().

- +

◆ purge_hls_fifo()

- +

◆ purge_multiframe_map()

@@ -6068,15 +6371,15 @@

Returns
Number of frames that have been purged. Function never fails.
-

Definition at line 6266 of file ffmpeg_transcoder.cc.

+

Definition at line 6314 of file ffmpeg_transcoder.cc.

References m_frame_map.

-

Referenced by purge().

+

Referenced by purge().

- +

◆ read_aiff_chunk()

- +

◆ read_decode_convert_and_store()

@@ -6181,17 +6484,17 @@

Returns
On success, returns 0; on error, a negative AVERROR value.
-

<*

Todo:
Cue sheet track: Must check video stream, too and end if both all video and audio packets arrived. Discard packets exceeding duration.
+

<*

Todo:
Cue sheet track: Must check video stream, too and end if both all video and audio packets arrived. Discard packets exceeding duration.
-

Definition at line 4071 of file ffmpeg_transcoder.cc.

+

Definition at line 4105 of file ffmpeg_transcoder.cc.

-

References decode_frame(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), flush_frames_all(), is_audio_stream(), FFmpeg_Transcoder::INPUTFILE::m_audio, VIRTUALFILE::m_cuesheet_track, VIRTUALFILE::CUESHEET_TRACK::m_duration, VIRTUALFILE::m_flags, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_in, VIRTUALFILE::CUESHEET_TRACK::m_start, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Base::m_virtualfile, pts(), Logging::trace(), virtname(), and VIRTUALFLAG_CUESHEET.

+

References decode_frame(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), flush_frames_all(), is_audio_stream(), FFmpeg_Transcoder::INPUTFILE::m_audio, VIRTUALFILE::m_cuesheet_track, VIRTUALFILE::CUESHEET_TRACK::m_duration, VIRTUALFILE::m_flags, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_in, VIRTUALFILE::CUESHEET_TRACK::m_start, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Base::m_virtualfile, Logging::trace(), virtname(), and VIRTUALFLAG_CUESHEET.

-

Referenced by copy_audio_to_frame_buffer(), and process_single_fr().

+

Referenced by copy_audio_to_frame_buffer(), and process_single_fr().

- +

◆ read_packet()

- +

◆ seek()

@@ -6291,7 +6594,7 @@

Custom seek function for FFmpeg.

-

Write to virtual files, currently only physical files.

+

Write to virtual files, currently only physical files.

Parameters
@@ -6302,15 +6605,15 @@

Returns
On successs returns 0. On error, returns -1 and sets errno accordingly.
-

Definition at line 6205 of file ffmpeg_transcoder.cc.

+

Definition at line 6253 of file ffmpeg_transcoder.cc.

References Logging::error(), FileIO::seek(), and FileIO::size().

-

Referenced by open_input_file(), and open_output_filestreams().

+

Referenced by open_input_file(), and open_output_filestreams().

- +

◆ seek_frame()

- +

◆ segment_count()

- +

◆ send_filters()

- +

◆ skip_decoded_frames()

- +

◆ stack_seek_frame()

- +

◆ stack_seek_segment()

- +

◆ start_new_segment()

@@ -6567,15 +6870,15 @@

Returns
0 on success, a negative AVERROR code on failure.
Todo:
Set reasonable size here
-

Definition at line 5468 of file ffmpeg_transcoder.cc.

+

Definition at line 5516 of file ffmpeg_transcoder.cc.

-

References close_output_file(), encode_finish(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), FFMPEGFS_AUDIO, FFMPEGFS_VIDEO, flush_buffers(), VIRTUALFILE::get_segment_count(), Logging::info(), FFmpeg_Transcoder::INPUTFILE::m_audio, m_buffer, m_current_segment, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_have_seeked, m_hls_packet_fifo, m_in, m_inhibit_stream_msk, m_insert_keyframe, FFMPEGFS_PARAMS::m_min_seek_time_diff, m_out, VIRTUALFILE::m_predicted_size, m_reset_pts, m_seek_to_fifo, FFMPEGFS_PARAMS::m_segment_duration, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Base::m_virtualfile, open_output(), params, process_output(), pts(), purge_hls_fifo(), Buffer::segment_exists(), Buffer::set_segment(), stream_exists(), Buffer::tell(), and virtname().

+

References close_output_file(), encode_finish(), Logging::error(), ffmpeg_geterror(), ffmpeg_rescale_q(), FFMPEGFS_AUDIO, FFMPEGFS_VIDEO, flush_buffers(), VIRTUALFILE::get_segment_count(), Logging::info(), FFmpeg_Transcoder::INPUTFILE::m_audio, m_buffer, m_current_segment, FFmpeg_Transcoder::INPUTFILE::m_format_ctx, m_have_seeked, m_hls_packet_fifo, m_in, m_inhibit_stream_msk, m_insert_keyframe, FFMPEGFS_PARAMS::m_min_seek_time_diff, m_out, VIRTUALFILE::m_predicted_size, m_reset_pts, m_seek_to_fifo, FFMPEGFS_PARAMS::m_segment_duration, FFmpeg_Transcoder::StreamRef::m_stream, FFmpeg_Transcoder::StreamRef::m_stream_idx, FFmpeg_Transcoder::INPUTFILE::m_video, FFmpeg_Base::m_virtualfile, open_output(), params, process_output(), purge_hls_fifo(), Buffer::segment_exists(), Buffer::set_segment(), stream_exists(), Buffer::tell(), and virtname().

-

Referenced by process_single_fr().

+

Referenced by process_single_fr().

- +

◆ store_packet()

- +

◆ stream_exists()

- +

◆ tagcpy()

- +

◆ total_overhead()

- +

◆ update_codec()

- +

◆ update_format()

- +

◆ video_frame_count()

- +

◆ video_size()

- +

◆ virtname()

@@ -7019,17 +7322,17 @@

Returns
Returns filename.
-

Implements FFmpeg_Base.

+

Implements FFmpeg_Base.

-

Definition at line 6438 of file ffmpeg_transcoder.cc.

+

Definition at line 6486 of file ffmpeg_transcoder.cc.

References VIRTUALFILE::m_virtfile, and FFmpeg_Base::m_virtualfile.

-

Referenced by add_albumart_frame(), add_albumart_stream(), add_samples_to_fifo(), add_stream(), add_stream_copy(), add_subtitle_stream(), alloc_picture(), can_copy_stream(), convert_samples(), copy_metadata(), create_audio_frame(), decode_frame(), decode_subtitle(), decode_video_frame(), encode_audio_frame(), encode_image_frame(), encode_subtitle(), encode_video_frame(), flush_delayed_audio(), flush_delayed_video(), hwdevice_ctx_add_ref(), hwdevice_ctx_create(), hwframe_copy_to_hw(), hwframe_ctx_set(), init_audio_fifo(), init_audio_output_frame(), init_converted_samples(), init_deinterlace_filters(), init_resampler(), init_rescaler(), open_bestmatch_video(), open_output(), open_output_file(), open_output_filestreams(), open_output_frame_set(), process_metadata(), process_single_fr(), read_decode_convert_and_store(), send_filters(), skip_decoded_frames(), stack_seek_frame(), stack_seek_segment(), start_new_segment(), store_packet(), transcode_finish(), transcoder_thread(), update_codec(), update_format(), write_output_file_header(), and write_output_file_trailer().

+

Referenced by add_albumart_frame(), add_albumart_stream(), add_samples_to_fifo(), add_stream(), add_stream_copy(), add_subtitle_stream(), alloc_picture(), can_copy_stream(), convert_samples(), copy_metadata(), create_audio_frame(), decode_frame(), decode_subtitle(), decode_video_frame(), encode_audio_frame(), encode_image_frame(), encode_subtitle(), encode_video_frame(), flush_delayed_audio(), flush_delayed_video(), hwdevice_ctx_add_ref(), hwdevice_ctx_create(), hwframe_copy_to_hw(), hwframe_ctx_set(), init_audio_fifo(), init_audio_output_frame(), init_converted_samples(), init_deinterlace_filters(), init_resampler(), init_rescaler(), open_bestmatch_video(), open_output(), open_output_file(), open_output_filestreams(), open_output_frame_set(), process_metadata(), process_single_fr(), read_decode_convert_and_store(), send_filters(), skip_decoded_frames(), stack_seek_frame(), stack_seek_segment(), start_new_segment(), store_packet(), transcode_finish(), transcoder_thread(), update_codec(), update_format(), write_output_file_header(), and write_output_file_trailer().

- +

◆ write_output_file_header()

- +

◆ write_output_file_trailer()

Member Data Documentation

- -

◆ m_devicetype_map

+ +

◆ m_active_stream_msk

@@ -7108,45 +7411,1275 @@

[in]opaque- Payload given to FFmpeg, basically the FileIO object
- +
const FFmpeg_Transcoder::DEVICETYPE_MAP FFmpeg_Transcoder::m_devicetype_mapuint32_t FFmpeg_Transcoder::m_active_stream_msk
-staticprivate +private

+ + +

◆ m_audio_fifo

+ +
+
+ + + + + +
+ + + + +
AVAudioFifo* FFmpeg_Transcoder::m_audio_fifo
+
+private
+
+ +

Audio sample FIFO.

+ +

Definition at line 1228 of file ffmpeg_transcoder.h.

+ +

Referenced by add_samples_to_fifo(), copy_audio_to_frame_buffer(), create_audio_frame(), init_audio_fifo(), and purge_audio_fifo().

+ +
+
+ +

◆ m_audio_resample_ctx

+ +
+
+ + + + + +
+ + + + +
SwrContext* FFmpeg_Transcoder::m_audio_resample_ctx
+
+private
+
+ +

SwResample context for audio resampling.

+ +

Definition at line 1227 of file ffmpeg_transcoder.h.

+ +

Referenced by close_resample(), convert_samples(), decode_audio_frame(), and init_resampler().

+ +
+
+ +

◆ m_buffer

+ +
+
+ + + + + +
+ + + + +
Buffer* FFmpeg_Transcoder::m_buffer
+
+private
+
+ +

Pointer to cache buffer object.

+ +

Definition at line 1252 of file ffmpeg_transcoder.h.

+ +

Referenced by encode_finish(), encode_image_frame(), open_output(), open_output_frame_set(), seek_frame(), skip_decoded_frames(), and start_new_segment().

+ +
+
+ +

◆ m_buffer_sink_context

+ +
+
+ + + + + +
+ + + + +
AVFilterContext* FFmpeg_Transcoder::m_buffer_sink_context
+
+private
+
+ +

Video filter sink context.

+ +

Definition at line 1232 of file ffmpeg_transcoder.h.

+ +

Referenced by free_filters(), init_deinterlace_filters(), and send_filters().

+ +
+
+ +

◆ m_buffer_source_context

+ +
+
+ + + + + +
+ + + + +
AVFilterContext* FFmpeg_Transcoder::m_buffer_source_context
+
+private
+
+ +

Video filter source context.

+ +

Definition at line 1233 of file ffmpeg_transcoder.h.

+ +

Referenced by free_filters(), init_deinterlace_filters(), and send_filters().

+ +
+
+ +

◆ m_close_fileio

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_close_fileio
+
+private
+
+ +

If we own the FileIO object, we may close it in the end.

+ +

Definition at line 1208 of file ffmpeg_transcoder.h.

+ +

Referenced by close_input_file(), and open_input_file().

+ +
+
+ +

◆ m_copy_audio

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_copy_audio
+
+private
+
+ +

If true, copy audio stream from source to target (just remux, no recode).

+ +

Definition at line 1247 of file ffmpeg_transcoder.h.

+ +

Referenced by decode_frame(), flush_frames_single(), open_output_filestreams(), and process_single_fr().

+ +
+
+ +

◆ m_copy_video

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_copy_video
+
+private
+
+ +

If true, copy video stream from source to target (just remux, no recode).

+ +

Definition at line 1248 of file ffmpeg_transcoder.h.

+ +

Referenced by decode_frame(), flush_frames_single(), and open_output_filestreams().

+ +
+
+ +

◆ m_cur_ch_layout

+ +
+
+ + + + + +
+ + + + +
AVChannelLayout FFmpeg_Transcoder::m_cur_ch_layout
+
+private
+
+ +

Currently selected audio channel layout.

+ +

Definition at line 1223 of file ffmpeg_transcoder.h.

+ +

Referenced by FFmpeg_Transcoder(), and init_resampler().

+ +
+
+ +

◆ m_cur_sample_fmt

+ +
+
+ + + + + +
+ + + + +
AVSampleFormat FFmpeg_Transcoder::m_cur_sample_fmt
+
+private
+
+ +

Currently selected audio sample format.

+ +

Definition at line 1220 of file ffmpeg_transcoder.h.

+ +

Referenced by calculate_predicted_filesize(), and init_resampler().

+ +
+
+ +

◆ m_cur_sample_rate

+ +
+
+ + + + + +
+ + + + +
int FFmpeg_Transcoder::m_cur_sample_rate
+
+private
+
+ +

Currently selected audio sample rate.

+ +

Definition at line 1221 of file ffmpeg_transcoder.h.

+ +

Referenced by init_resampler().

+ +
+
+ +

◆ m_current_format

+ + + +

◆ m_current_segment

+ +
+
+ + + + + +
+ + + + +
uint32_t FFmpeg_Transcoder::m_current_segment
+
+private
+
+ +

HLS only: Segment file number currently being encoded.

+ +

Definition at line 1243 of file ffmpeg_transcoder.h.

+ +

Referenced by encode_finish(), goto_next_segment(), open_output(), and start_new_segment().

+ +
+
+ +

◆ m_dec_hw_pix_fmt

+ +
+
+ + + + + +
+ + + + +
AVPixelFormat FFmpeg_Transcoder::m_dec_hw_pix_fmt
+
+private
+
+ +

Requested decoder hardware pixel format.

+ +

Definition at line 1268 of file ffmpeg_transcoder.h.

+ +

Referenced by get_format().

+ +
+
+ +

◆ m_devicetype_map

+ +
+
+ + + + + +
+ + + + +
const FFmpeg_Transcoder::DEVICETYPE_MAP FFmpeg_Transcoder::m_devicetype_map
+
+staticprivate
+
+Initial value:
=
+
{
+
{ AV_HWDEVICE_TYPE_VAAPI, AV_PIX_FMT_NV12 },
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+
+

List of AVPixelFormats mapped to hardware acceleration types.

+ +

Definition at line 1260 of file ffmpeg_transcoder.h.

+ +

Referenced by find_sw_fmt_by_hw_type().

+ +
+
+ +

◆ m_enc_hw_pix_fmt

+ +
+
+ + + + + +
+ + + + +
AVPixelFormat FFmpeg_Transcoder::m_enc_hw_pix_fmt
+
+private
+
+ +

Requested encoder hardware pixel format.

+ +

Definition at line 1267 of file ffmpeg_transcoder.h.

+ +

Referenced by add_stream(), hwframe_ctx_set(), and open_output().

+ +
+
+ +

◆ m_fake_frame_no

+ +
+
+ + + + + +
+ + + + +
uint32_t FFmpeg_Transcoder::m_fake_frame_no
+
+private
+
+ +

The MJEPG codec requires monotonically growing PTS values so we fake some to avoid them going backwards after seeks.

+ +

Definition at line 1255 of file ffmpeg_transcoder.h.

+ +

Referenced by encode_image_frame().

+ +
+
+ +

◆ m_fileio

+ +
+
+ + + + + +
+ + + + +
FileIO* FFmpeg_Transcoder::m_fileio
+
+private
+
+ +

FileIO object of input file.

+ +

Definition at line 1207 of file ffmpeg_transcoder.h.

+ +

Referenced by calculate_predicted_filesize(), close_input_file(), and open_input_file().

+ +
+
+ +

◆ m_filter_graph

+ +
+
+ + + + + +
+ + + + +
AVFilterGraph* FFmpeg_Transcoder::m_filter_graph
+
+private
+
+ +

Video filter graph.

+ +

Definition at line 1234 of file ffmpeg_transcoder.h.

+ +

Referenced by free_filters(), and init_deinterlace_filters().

+ +
+
+ +

◆ m_frame_map

+ +
+
+ + + + + +
+ + + + +
MULTIFRAME_MAP FFmpeg_Transcoder::m_frame_map
+
+private
+
+ +

Audio/video/subtitle frame map.

+ +

Definition at line 1217 of file ffmpeg_transcoder.h.

+ +

Referenced by create_audio_frame(), decode_subtitle(), decode_video_frame(), process_single_fr(), pts(), and purge_multiframe_map().

+ +
+
+ +

◆ m_have_seeked

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_have_seeked
+
+private
+
+ +

After seek operations this is set to make sure the trancoding result is marked RESULTCODE_INCOMPLETE to start transcoding over next access to fill the gaps.

+ +

Definition at line 1213 of file ffmpeg_transcoder.h.

+ +

Referenced by do_seek_frame(), have_seeked(), open_output_frame_set(), and start_new_segment().

+ +
+
+ +

◆ m_hls_packet_fifo

+ +
+
+ + + + + +
+ + + + +
std::queue<AVPacket*> FFmpeg_Transcoder::m_hls_packet_fifo
+
+private
+
+ +

HLS packet FIFO.

+ +

Definition at line 1276 of file ffmpeg_transcoder.h.

+ +

Referenced by purge_hls_fifo(), start_new_segment(), and store_packet().

+ +
+
+ +

◆ m_hwaccel_dec_device_ctx

+ +
+
+ + + + + +
+ + + + +
AVBufferRef* FFmpeg_Transcoder::m_hwaccel_dec_device_ctx
+
+private
+
+ +

Hardware acceleration device context for decoder.

+ +

Definition at line 1266 of file ffmpeg_transcoder.h.

+ +

Referenced by closeio(), and hwdevice_ctx_add_ref().

+ +
+
+ +

◆ m_hwaccel_dec_mode

+ +
+
+ + + + + +
+ + + + +
HWACCELMODE FFmpeg_Transcoder::m_hwaccel_dec_mode
+
+private
+
+ +

Current hardware acceleration mode for decoder.

+ +

Definition at line 1262 of file ffmpeg_transcoder.h.

+ +
+
+ +

◆ m_hwaccel_enable_dec_buffering

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_hwaccel_enable_dec_buffering
+
+private
+
+ +

Enable hardware acceleration frame buffers for decoder.

+ +

Definition at line 1264 of file ffmpeg_transcoder.h.

+ +

Referenced by decode_video_frame(), and get_pix_formats().

+ +
+
+ +

◆ m_hwaccel_enable_enc_buffering

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_hwaccel_enable_enc_buffering
+
+private
+
+ +

Enable hardware acceleration frame buffers for encoder.

+ +

Definition at line 1263 of file ffmpeg_transcoder.h.

+ +

Referenced by add_stream(), encode_video_frame(), get_pix_formats(), open_bestmatch_video(), open_output(), and update_codec().

+ +
+
+ +

◆ m_hwaccel_enc_device_ctx

+ +
+
+ + + + + +
+ + + + +
AVBufferRef* FFmpeg_Transcoder::m_hwaccel_enc_device_ctx
+
+private
+
+ +

Hardware acceleration device context for encoder.

+ +

Definition at line 1265 of file ffmpeg_transcoder.h.

+ +

Referenced by add_stream(), closeio(), open_bestmatch_video(), and open_output().

+ +
+
+ +

◆ m_hwaccel_enc_mode

+ +
+
+ + + + + +
+ + + + +
HWACCELMODE FFmpeg_Transcoder::m_hwaccel_enc_mode
+
+private
+
+ +

Current hardware acceleration mode for encoder.

+ +

Definition at line 1261 of file ffmpeg_transcoder.h.

+ +

Referenced by add_stream(), and open_output().

+ +
+
+ +

◆ m_in

+ + + +

◆ m_inhibit_stream_msk

+ +
+
+ + + + + +
+ + + + +
uint32_t FFmpeg_Transcoder::m_inhibit_stream_msk
+
+private
+
+ +

HLS: Currently inhibited streams bit mask. Packets temporarly go to m_hls_packet_fifo and will be prepended to next segment. Set FFMPEGFS_AUDIO and/or FFMPEGFS_VIDEO.

+ +

Definition at line 1275 of file ffmpeg_transcoder.h.

+ +

Referenced by open_output_filestreams(), process_single_fr(), start_new_segment(), and store_packet().

+ +
+
+ +

◆ m_insert_keyframe

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_insert_keyframe
+
+private
+
+ +

HLS only: Allow insertion of 1 keyframe.

+ +

Definition at line 1244 of file ffmpeg_transcoder.h.

+ +

Referenced by decode_video_frame(), open_output(), and start_new_segment().

+ +
+
+ +

◆ m_is_video

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_is_video
+
+private
+
+ +

true if input is a video file

+ +

Definition at line 1215 of file ffmpeg_transcoder.h.

+ +

Referenced by calculate_predicted_filesize(), open_bestmatch_video(), and open_output_filestreams().

+ +
+
+ +

◆ m_last_seek_frame_no

+ +
+
+ + + + + +
+ + + + +
std::atomic_uint32_t FFmpeg_Transcoder::m_last_seek_frame_no
+
+private
+
+ +

If not 0, this is the last frame that we seeked to. Video sources only.

+ +

Definition at line 1212 of file ffmpeg_transcoder.h.

+ +

Referenced by encode_image_frame(), last_seek_frame_no(), and seek_frame().

+ +
+
+ +

◆ m_mtime

+ +
+
+ + + + + +
+ + + + +
time_t FFmpeg_Transcoder::m_mtime
+
+private
+
+ +

Modified time of input file.

+ +

Definition at line 1209 of file ffmpeg_transcoder.h.

+ +

Referenced by FFmpeg_Transcoder(), mtime(), and open_input_file().

+ +
+
+ +

◆ m_out

+ + + +

◆ m_pos

+ +
+
+ + + + + +
+ + + + +
int64_t FFmpeg_Transcoder::m_pos
+
+private
+
+ +

Generated position.

+ +

Definition at line 1236 of file ffmpeg_transcoder.h.

+ +

Referenced by decode_video_frame().

+ +
+
+ +

◆ m_prores_bitrate

+ +
+
+ + + + + +
+ + + + +
const std::vector< FFmpeg_Transcoder::PRORES_BITRATE > FFmpeg_Transcoder::m_prores_bitrate
+
+staticprivate
+
+ +

ProRes bitrate table. Used for file size prediction.

+ +

Definition at line 1257 of file ffmpeg_transcoder.h.

+ +

Referenced by get_prores_bitrate().

+ +
+
+ +

◆ m_pts

+ +
+
+ + + + + +
+ + + + +
int64_t FFmpeg_Transcoder::m_pts
+
+private
+
+ +

Generated PTS.

+ +

Definition at line 1235 of file ffmpeg_transcoder.h.

+ +

Referenced by decode_video_frame().

+ +
+
+ +

◆ m_reset_pts

+ +
+
+ + + + + +
+ + + + +
uint32_t FFmpeg_Transcoder::m_reset_pts
+
+private
+
+ +

We have to reset audio/video pts to the new position.

+ +

Definition at line 1254 of file ffmpeg_transcoder.h.

+ +

Referenced by decode_frame(), and start_new_segment().

+ +
+
+ +

◆ m_seek_to_fifo

+ +
+
+ + + + + +
+ + + + +
std::queue<uint32_t> FFmpeg_Transcoder::m_seek_to_fifo
+
+private
+
+ +

Stack of seek requests. Will be processed FIFO.

+ +

Definition at line 1211 of file ffmpeg_transcoder.h.

+ +

Referenced by open_output_frame_set(), seek_frame(), stack_seek_frame(), stack_seek_segment(), and start_new_segment().

+ +
+
+ +

◆ m_seek_to_fifo_mutex

+ +
+
+ + + + + +
+ + + + +
std::recursive_mutex FFmpeg_Transcoder::m_seek_to_fifo_mutex
+
+private
+
+ +

Access mutex for seek FIFO.

+ +

Definition at line 1210 of file ffmpeg_transcoder.h.

+ +

Referenced by open_output_frame_set(), seek_frame(), stack_seek_frame(), and stack_seek_segment().

+ +
+
+ +

◆ m_skip_next_frame

+ +
+
+ + + + + +
+ + + + +
bool FFmpeg_Transcoder::m_skip_next_frame
+
+private
+
+ +

After seek, skip next video frame.

+ +

Definition at line 1214 of file ffmpeg_transcoder.h.

+ +

Referenced by do_seek_frame(), and encode_image_frame().

+ +
+
+ +

◆ m_stream_map

+ +
+
+ + + + + +
+ + + + +
STREAM_MAP FFmpeg_Transcoder::m_stream_map
+
+private
+
+ +

Input stream to output stream map.

+ +

Definition at line 1241 of file ffmpeg_transcoder.h.

+ +

Referenced by add_stream_map(), and map_in_to_out_stream().

+ +
+
+ +

◆ m_sws_ctx

+ +
+
+ + + + + +
+ + + + +
SwsContext* FFmpeg_Transcoder::m_sws_ctx
+
+private
+
+ +

Context for video filtering.

+ +

Definition at line 1231 of file ffmpeg_transcoder.h.

-

Referenced by find_sw_fmt_by_hw_type().

+

Referenced by close_output_file(), decode_video_frame(), and init_rescaler().

@@ -7157,7 +8690,7 @@

diff --git a/html/classFFmpeg__Transcoder_1_1StreamRef-members.html b/html/classFFmpeg__Transcoder_1_1StreamRef-members.html index b417ff1cf..1fceaa886 100644 --- a/html/classFFmpeg__Transcoder_1_1StreamRef-members.html +++ b/html/classFFmpeg__Transcoder_1_1StreamRef-members.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
FFmpeg_Transcoder::StreamRef Member List
+
FFmpeg_Transcoder::StreamRef Member List
diff --git a/html/classFFmpeg__Transcoder_1_1StreamRef.html b/html/classFFmpeg__Transcoder_1_1StreamRef.html index b7ebe3878..9fa004d6a 100644 --- a/html/classFFmpeg__Transcoder_1_1StreamRef.html +++ b/html/classFFmpeg__Transcoder_1_1StreamRef.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: FFmpeg_Transcoder::StreamRef Class Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
Public Member Functions | Public Attributes | List of all members
-
-
FFmpeg_Transcoder::StreamRef Class Reference
+
FFmpeg_Transcoder::StreamRef Class Reference
@@ -80,42 +79,107 @@

#include <ffmpeg_transcoder.h>

- - - + +

+

Public Member Functions

void set_codec_ctx (AVCodecContext *codec_ctx)
 Set the AVCodecContext pointer. Will be shared and deleted after the last consumer freed it. More...
 
-void reset ()
 Close (reset) AVCodecContext pointer.
void reset ()
 Close (reset) AVCodecContext pointer. More...
 
- - - + + - - + + - - + + - - + +

+

Public Attributes

-std::shared_ptr< AVCodecContext > m_codec_ctx
 AVCodecContext for this encoder stream.
std::shared_ptr< AVCodecContext > m_codec_ctx
 AVCodecContext for this encoder stream. More...
 
-AVStream * m_stream
 AVStream for this encoder stream.
AVStream * m_stream
 AVStream for this encoder stream. More...
 
-int m_stream_idx
 Stream index in AVFormatContext.
int m_stream_idx
 Stream index in AVFormatContext. More...
 
-int64_t m_start_time
 Start time of the stream in stream time base units, may be 0.
int64_t m_start_time
 Start time of the stream in stream time base units, may be 0. More...
 

Detailed Description

-

In/output stream reference data.

-

<

+

In/output stream reference data.

+

<

Definition at line 113 of file ffmpeg_transcoder.h.

-

Member Function Documentation

- +

Constructor & Destructor Documentation

+ +

◆ StreamRef()

+ +
+
+ + + + + + + +
FFmpeg_Transcoder::StreamRef::StreamRef ()
+
+ +

Definition at line 170 of file ffmpeg_transcoder.cc.

+ +
+
+ +

◆ ~StreamRef()

+ +
+
+ + + + + +
+ + + + + + + +
FFmpeg_Transcoder::StreamRef::~StreamRef ()
+
+virtual
+
+ +

Definition at line 178 of file ffmpeg_transcoder.cc.

+ +
+
+

Member Function Documentation

+ +

◆ reset()

+ +
+
+ + + + + + + +
void FFmpeg_Transcoder::StreamRef::reset ()
+
+ +

Close (reset) AVCodecContext pointer.

+ +

Definition at line 211 of file ffmpeg_transcoder.cc.

+ +

Referenced by FFmpeg_Transcoder::close_input_file(), and FFmpeg_Transcoder::close_output_file().

+ +
+
+

◆ set_codec_ctx()

+
+

Member Data Documentation

+ +

◆ m_codec_ctx

+ + + +

◆ m_start_time

+ +
+
+ + + + +
int64_t FFmpeg_Transcoder::StreamRef::m_start_time
+
+ +

Start time of the stream in stream time base units, may be 0.

+ +

Definition at line 134 of file ffmpeg_transcoder.h.

+ +

Referenced by FFmpeg_Transcoder::create_audio_frame(), FFmpeg_Transcoder::decode_video_frame(), FFmpeg_Transcoder::open_output(), and FFmpeg_Transcoder::store_packet().

+ +
+
+ +

◆ m_stream

+ + + +

◆ m_stream_idx

+ + @@ -152,7 +297,7 @@

diff --git a/html/classFFmpeg__Transcoder__coll__graph.map b/html/classFFmpeg__Transcoder__coll__graph.map index 8a86010c8..e6c8d7adf 100644 --- a/html/classFFmpeg__Transcoder__coll__graph.map +++ b/html/classFFmpeg__Transcoder__coll__graph.map @@ -1,19 +1,19 @@ - - - - - - - + + + + + + + - - - - - - + + + + + + diff --git a/html/classFFmpeg__Transcoder__coll__graph.md5 b/html/classFFmpeg__Transcoder__coll__graph.md5 index fd13610fa..c7bdf72a0 100644 --- a/html/classFFmpeg__Transcoder__coll__graph.md5 +++ b/html/classFFmpeg__Transcoder__coll__graph.md5 @@ -1 +1 @@ -ec6e0acdad96c4bb516808fbd6bbc4d3 \ No newline at end of file +7967f91d70d82635cc92bdd38f76843e \ No newline at end of file diff --git a/html/classFFmpeg__Transcoder__coll__graph.png b/html/classFFmpeg__Transcoder__coll__graph.png index 24765496f1dc1d76dd937aadca63e3d599cbd036..254573abf6d9619324153ec30d98f5aa7bfe0fb6 100644 GIT binary patch literal 78136 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≪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%0A;eS^47;%aP^*;itEXbS%BZ!lgHV%>ICi zAuodG#CaOZ^@s?oo;|};!j1v{#P4*S&X4hj@pSqn zts6&ZY}9r)G;*b(xKfW@v;K8eRZ0#xNchqACujzMM(eR@)F_)=hTGM7v@FGFguJ6V zH&rfPWi(L+xHRtUW}{BwggP5kgCr6XDTE;q@nGy>jNv(2^Q@eZm>UX$A8bqn3_RV3 zc6#+Pz6j`#bh`e&()iJ~f?OfWo*Rl;%*`xUVrPJyb zt4uySeBWot&LJ=HXI$x|b?Q_f-H+)XV2L-~M>>tvT?4O5qwCrA9&EzKeDVc_~5;$G^rnMMOG$wG8p-)d`V? z<;3K_@OB@E!;oc2SCE_ZV2|Hwzi(_Gy(Sg;tX_>s?P8{!a-)^u(0*9>r_;w6jBC&4 zLdVC;b}{bk`g(rla(6w?_Vnt|i;q`iW(Qw?zlVLoqpF3@!hM-`_J91LTi~{QjISGI zb1L6bFsU+@w6jwFEOV~^D-p6G=lus7E60Iv`I>3|6cZH{G)@__VFWi{LJzuGBw=!|(B;oa8O*{}URdsw!Ci&mF-fIo)CP m(6MIxM`O39YMQdK*Z%^4NrKJ* literal 78986 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 diff --git a/html/classFFmpegfs__Format-members.html b/html/classFFmpegfs__Format-members.html index 3278b95d2..d480e370b 100644 --- a/html/classFFmpegfs__Format-members.html +++ b/html/classFFmpegfs__Format-members.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
FFmpegfs_Format Member List
+
FFmpegfs_Format Member List

This is the complete list of members for FFmpegfs_Format, including all inherited members.

- + - + - + - + - + - + - + - + - + - + - + - + - +
albumart_supported() constFFmpegfs_Format
audio_codec() constFFmpegfs_Format
audio_codec() constFFmpegfs_Format
audio_codec_list() constFFmpegfs_Format
desttype() constFFmpegfs_Format
desttype() constFFmpegfs_Format
FFmpegfs_Format()FFmpegfs_Format
fileext() constFFmpegfs_Format
fileext() constFFmpegfs_Format
filetype() constFFmpegfs_Format
format_name() constFFmpegfs_Format
format_name() constFFmpegfs_Format
init(const std::string &desttype)FFmpegfs_Format
is_audio_codec_supported(AVCodecID codec_id) constFFmpegfs_Format
is_audio_codec_supported(AVCodecID codec_id) constFFmpegfs_Format
is_frameset() constFFmpegfs_Format
is_hls() constFFmpegfs_Format
is_hls() constFFmpegfs_Format
is_multiformat() constFFmpegfs_Format
is_sample_fmt_supported() constFFmpegfs_Format
is_sample_fmt_supported() constFFmpegfs_Format
is_video_codec_supported(AVCodecID codec_id) constFFmpegfs_Format
m_cur_optsFFmpegfs_Formatprotected
m_cur_optsFFmpegfs_Formatprotected
m_desttypeFFmpegfs_Formatprotected
m_empty_optionsFFmpegfs_Formatprotected
m_empty_optionsFFmpegfs_Formatprotected
m_filetypeFFmpegfs_Formatprotected
m_options_mapFFmpegfs_Formatprotectedstatic
m_options_mapFFmpegfs_Formatprotectedstatic
OPTIONS_MAP typedefFFmpegfs_Formatprivate
sample_fmt_list() constFFmpegfs_Format
sample_fmt_list() constFFmpegfs_Format
sample_format() constFFmpegfs_Format
subtitle_codec(AVCodecID codec_id) constFFmpegfs_Format
subtitle_codec(AVCodecID codec_id) constFFmpegfs_Format
video_codec() constFFmpegfs_Format
video_codec_list() constFFmpegfs_Format
video_codec_list() constFFmpegfs_Format
diff --git a/html/classFFmpegfs__Format.html b/html/classFFmpegfs__Format.html index 1a2066eee..87dc57e3c 100644 --- a/html/classFFmpegfs__Format.html +++ b/html/classFFmpegfs__Format.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: FFmpegfs_Format Class Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
Static Protected Attributes | Private Types | List of all members
-
-
FFmpegfs_Format Class Reference
+
FFmpegfs_Format Class Reference
@@ -87,11 +86,10 @@
[legend]
- - - + + @@ -151,45 +149,88 @@

+

Public Member Functions

FFmpegfs_Format ()
 Construct FFmpegfs_Format object.
 FFmpegfs_Format ()
 Construct FFmpegfs_Format object. More...
 
bool init (const std::string &desttype)
 Get codecs for the selected destination type. More...
 Check if album arts are supported. More...
 
- - - + + - - + + - - + + - - + +

+

Protected Attributes

-const Format_Options m_empty_options
 Set of empty (invalid) options as default.
const Format_Options m_empty_options
 Set of empty (invalid) options as default. More...
 
-const Format_Optionsm_cur_opts
 Currently selected options. Will never be nullptr.
const Format_Optionsm_cur_opts
 Currently selected options. Will never be nullptr. More...
 
-std::string m_desttype
 Destination type: mp4, mp3 or other.
std::string m_desttype
 Destination type: mp4, mp3 or other. More...
 
-FILETYPE m_filetype
 File type, MP3, MP4, OPUS etc.
FILETYPE m_filetype
 File type, MP3, MP4, OPUS etc. More...
 
- - - + +

+

Static Protected Attributes

-static const OPTIONS_MAP m_options_map
 Map of options. One entry per supported destination type.
static const OPTIONS_MAP m_options_map
 Map of options. One entry per supported destination type. More...
 
- - - + +

+

Private Types

-typedef std::map< FILETYPE, const Format_OptionsOPTIONS_MAP
 Map of options. One entry per supported destination type.
typedef std::map< FILETYPE, const Format_OptionsOPTIONS_MAP
 Map of options. One entry per supported destination type. More...
 

Detailed Description

-

The FFmpegfs_Format class.

+

The FFmpegfs_Format class.

+ +

Definition at line 387 of file ffmpeg_utils.h.

+

Member Typedef Documentation

+ +

◆ OPTIONS_MAP

+ +
+
+ + + + + +
+ + + + +
typedef std::map<FILETYPE, const Format_Options> FFmpegfs_Format::OPTIONS_MAP
+
+private
+
+ +

Map of options. One entry per supported destination type.

+ +

Definition at line 389 of file ffmpeg_utils.h.

+ +
+
+

Constructor & Destructor Documentation

+ +

◆ FFmpegfs_Format()

+ +
+
+ + + + + + + +
FFmpegfs_Format::FFmpegfs_Format ()
+
+ +

Construct FFmpegfs_Format object.

-

Definition at line 391 of file ffmpeg_utils.h.

-

Member Function Documentation

- +

Definition at line 863 of file ffmpeg_utils.cc.

+ +
+
+

Member Function Documentation

+

◆ albumart_supported()

- +

◆ audio_codec()

- +

◆ audio_codec_list()

- +

◆ desttype()

- +

◆ fileext()

- +

◆ filetype()

- +

◆ format_name()

- +

◆ init()

- +

◆ is_audio_codec_supported()

- +

◆ is_frameset()

- +

◆ is_hls()

- +

◆ is_multiformat()

- +

◆ is_sample_fmt_supported()

- +

◆ is_video_codec_supported()

- +

◆ sample_fmt_list()

- +

◆ sample_format()

- +

◆ subtitle_codec()

- +

◆ video_codec()

- +

◆ video_codec_list()

+ +

Member Data Documentation

+ +

◆ m_cur_opts

+ +
+
+ + + + + +
+ + + + +
const Format_Options* FFmpegfs_Format::m_cur_opts
+
+protected
+
+
+ +

◆ m_desttype

+ +
+
+ + + + + +
+ + + + +
std::string FFmpegfs_Format::m_desttype
+
+protected
+
+ +

Destination type: mp4, mp3 or other.

+ +

Definition at line 508 of file ffmpeg_utils.h.

+ +

Referenced by desttype(), and init().

+ +
+
+ +

◆ m_empty_options

+ +
+
+ + + + + +
+ + + + +
const Format_Options FFmpegfs_Format::m_empty_options
+
+protected
+
+ +

Set of empty (invalid) options as default.

+ +

Definition at line 505 of file ffmpeg_utils.h.

+ +
+
+ +

◆ m_filetype

+ +
+
+ + + + + +
+ + + + +
FILETYPE FFmpegfs_Format::m_filetype
+
+protected
+
+ +

File type, MP3, MP4, OPUS etc.

+ +

Definition at line 509 of file ffmpeg_utils.h.

+ +

Referenced by filetype(), init(), is_frameset(), and is_hls().

+ +
+
+ +

◆ m_options_map

+ +
+
+ + + + + +
+ + + + +
const FFmpegfs_Format::OPTIONS_MAP FFmpegfs_Format::m_options_map
+
+staticprotected
+
+ +

Map of options. One entry per supported destination type.

+ +

Definition at line 507 of file ffmpeg_utils.h.

+ +

Referenced by init().

@@ -705,7 +885,7 @@

diff --git a/html/classFileIO-members.html b/html/classFileIO-members.html index 9bbf647fd..ea4dc6430 100644 --- a/html/classFileIO-members.html +++ b/html/classFileIO-members.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
FileIO Member List
+
FileIO Member List

This is the complete list of members for FileIO, including all inherited members.

- + - + - + - + - + - + - + - + - + - +
alloc(VIRTUALTYPE type)FileIOstatic
bufsize() const =0FileIOpure virtual
bufsize() const =0FileIOpure virtual
closeio()=0FileIOpure virtual
duration() const =0FileIOpure virtual
duration() const =0FileIOpure virtual
eof() const =0FileIOpure virtual
error() const =0FileIOpure virtual
error() const =0FileIOpure virtual
FileIO()FileIOexplicit
filename() constFileIO
filename() constFileIO
m_pathFileIOprivate
m_virtualfileFileIOprivate
m_virtualfileFileIOprivate
openio(LPVIRTUALFILE virtualfile)=0FileIOpure virtual
path() constFileIO
path() constFileIO
readio(void *data, size_t size)=0FileIOpure virtual
seek(int64_t offset, int whence)=0FileIOpure virtual
seek(int64_t offset, int whence)=0FileIOpure virtual
set_virtualfile(LPVIRTUALFILE virtualfile)FileIOprotected
size() const =0FileIOpure virtual
size() const =0FileIOpure virtual
tell() const =0FileIOpure virtual
type() const =0FileIOpure virtual
type() const =0FileIOpure virtual
virtualfile()FileIO
~FileIO()=defaultFileIOvirtual
~FileIO()=defaultFileIOvirtual
diff --git a/html/classFileIO.html b/html/classFileIO.html index 352cb0558..a1586bedd 100644 --- a/html/classFileIO.html +++ b/html/classFileIO.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: FileIO Class Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
Protected Member Functions | Private Attributes | List of all members
-
-
FileIO Class Referenceabstract
+
FileIO Class Referenceabstract
@@ -95,23 +94,22 @@
Collaboration graph
- - - + + + - - + +
[legend]
- - - + + - + @@ -144,9 +142,8 @@ - - + + @@ -158,35 +155,63 @@

+

Public Member Functions

FileIO ()
 Create FileIO object.
 FileIO ()
 Create FileIO object. More...
 
-virtual ~FileIO ()=default
+virtual ~FileIO ()=default
 Free FileIO object.
 
virtual VIRTUALTYPE type () const =0
virtual bool eof () const =0
 Check if at end of file. More...
 
-virtual void closeio ()=0
 Close virtual file.
virtual void closeio ()=0
 Close virtual file. More...
 
LPVIRTUALFILE virtualfile ()
 Get virtual file object. More...
 Path to source file (without file name) More...
 
-

+

Static Public Member Functions

static FileIOalloc (VIRTUALTYPE type)
 Allocate the correct object for type(). More...
 
-

+

Protected Member Functions

void set_virtualfile (LPVIRTUALFILE virtualfile)
 Set the virtual file object. More...
 
- - - + + - - + +

+

Private Attributes

-std::string m_path
 Source path (directory without file name)
std::string m_path
 Source path (directory without file name) More...
 
-LPVIRTUALFILE m_virtualfile
 Virtual file object of current file.
LPVIRTUALFILE m_virtualfile
 Virtual file object of current file. More...
 

Detailed Description

-

Base class for I/O.

+

Base class for I/O.

Definition at line 257 of file fileio.h.

-

Member Function Documentation

- +

Constructor & Destructor Documentation

+ +

◆ FileIO()

+ +
+
+ + + + + +
+ + + + + + + +
FileIO::FileIO ()
+
+explicit
+
+ +

Create FileIO object.

+ +

Definition at line 58 of file fileio.cc.

+ +
+
+

Member Function Documentation

+

◆ alloc()

@@ -211,7 +236,7 @@

Allocate the correct object for type().

-

Free with delete if no longer required.

+

Free with delete if no longer required.

Parameters
@@ -228,7 +253,7 @@

+

◆ bufsize()

- + +

◆ closeio()

+ +
+
+

[in]type- VIRTUALTYPE of new object.
+ + + + +
+ + + + + + + +
virtual void FileIO::closeio ()
+
+pure virtual
+

+ +

Close virtual file.

+ +

Implemented in BlurayIO, Buffer, DiskIO, DvdIO, and VcdIO.

+ +

Referenced by FFmpeg_Transcoder::close_input_file().

+ +
+
+

◆ duration()

- +

◆ eof()

- +

◆ error()

- +

◆ filename()

- +

◆ openio()

@@ -416,13 +472,13 @@

Returns
Upon successful completion, openio() returns 0.
On error, a nonzero value is returned and errno is set to indicate the error.
-

Implemented in VcdIO, DvdIO, DiskIO, Buffer, and BlurayIO.

+

Implemented in BlurayIO, Buffer, DiskIO, DvdIO, and VcdIO.

Referenced by FFmpeg_Transcoder::open_input_file().

- +

◆ path()

@@ -448,7 +504,7 @@

+

◆ readio()

@@ -495,13 +551,13 @@

error() will return 0 if at EOF. -

Implemented in VcdIO, DvdIO, DiskIO, Buffer, and BlurayIO.

+

Implemented in BlurayIO, Buffer, DiskIO, DvdIO, and VcdIO.

-

Referenced by FFmpeg_Transcoder::input_read().

+

Referenced by FFmpeg_Transcoder::input_read().

- +

◆ seek()

@@ -536,7 +592,7 @@

Seek to position in file.

-

Repositions the offset of the open file to the argument offset according to the directive whence.

+

Repositions the offset of the open file to the argument offset according to the directive whence.

Parameters
@@ -550,13 +606,13 @@

Returns
Upon successful completion, seek() returns the resulting offset location as measured in bytes from the beginning of the file.
On error, the value -1 is returned and errno is set to indicate the error.
-

Implemented in VcdIO, DvdIO, DiskIO, Buffer, and BlurayIO.

+

Implemented in BlurayIO, Buffer, DiskIO, DvdIO, and VcdIO.

-

Referenced by FFmpeg_Transcoder::seek().

+

Referenced by FFmpeg_Transcoder::seek().

- +

◆ set_virtualfile()

@@ -596,7 +652,7 @@

+

◆ size()

- +

◆ tell()

- +

◆ type()

- +

◆ virtualfile()

+ +

Member Data Documentation

+ +

◆ m_path

+ +
+
+

[in]offset- offset in bytes
+ + + + +
+ + + + +
std::string FileIO::m_path
+
+private
+

+ +

Source path (directory without file name)

+ +

Definition at line 371 of file fileio.h.

+ +

Referenced by path(), and set_virtualfile().

+ +
+ + +

◆ m_virtualfile

+ +
+
+ + + + + +
+ + + + +
LPVIRTUALFILE FileIO::m_virtualfile
+
+private
+
+ +

Virtual file object of current file.

+ +

Definition at line 372 of file fileio.h.

+ +

Referenced by filename(), set_virtualfile(), and virtualfile().

@@ -723,7 +836,7 @@

diff --git a/html/classFileIO__coll__graph.map b/html/classFileIO__coll__graph.map index 8638404f4..0c107e0fa 100644 --- a/html/classFileIO__coll__graph.map +++ b/html/classFileIO__coll__graph.map @@ -1,8 +1,8 @@ - - - + + + - - + + diff --git a/html/classFileIO__coll__graph.md5 b/html/classFileIO__coll__graph.md5 index fa54a3ac7..eb7c33d39 100644 --- a/html/classFileIO__coll__graph.md5 +++ b/html/classFileIO__coll__graph.md5 @@ -1 +1 @@ -27dd4d9f55cc584568ef51c92da0d57d \ No newline at end of file +db09dab7f4af407dbfadcaf79f935dc2 \ No newline at end of file diff --git a/html/classFileIO__coll__graph.png b/html/classFileIO__coll__graph.png index 34c78af8f61ef3b9dc3ba397451fcafadf5ad0ae..e47a4698b812bd8dca754f9292fa54d44fd240cb 100644 GIT binary patch literal 19979 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 - - + + FFmpegfs Fuse Multi Media Filesystem: Member List @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
-
-
Logging Member List
+
Logging Member List

This is the complete list of members for Logging, including all inherited members.

- + - + - + - - - + + + - + - + - + - + - + - +
debug(const T filename, const std::string &format_string, Args &&...args)Logginginlinestatic
error(const T filename, const std::string &format_string, Args &&...args)Logginginlinestatic
error(const T filename, const std::string &format_string, Args &&...args)Logginginlinestatic
format(const std::string &format_string, Args &&...args)Logginginlineprivatestatic
format_helper(const std::string &string_to_update, const size_t __attribute__((unused)) index_to_replace)Loggingprivatestatic
format_helper(const std::string &string_to_update, const size_t __attribute__((unused)) index_to_replace)Loggingprivatestatic
format_helper(const std::string &string_to_search, const size_t index_to_replace, T &&val, Args &&...args)Logginginlineprivatestatic
GetFail() constLogging
GetFail() constLogging
info(const T filename, const std::string &format_string, Args &&...args)Logginginlinestatic
init_logging(const std::string &logfile, LOGLEVEL max_level, bool to_stderr, bool to_syslog)Loggingstatic
Log(LOGLEVEL loglevel, const std::string &filename)Loggingfriend
log_with_level(LOGLEVEL loglevel, const char *filename, const std::string &message)Loggingstatic
init_logging(const std::string &logfile, LOGLEVEL max_level, bool to_stderr, bool to_syslog)Loggingstatic
LogLoggingfriend
log_with_level(LOGLEVEL loglevel, const char *filename, const std::string &message)Loggingstatic
log_with_level(LOGLEVEL loglevel, const std::string &filename, const std::string &message)Loggingstatic
LoggerLoggingprotected
LoggerLoggingprotected
Logging(const std::string &logfile, LOGLEVEL max_level, bool to_stderr, bool to_syslog)Loggingexplicit
LOGLEVEL enum nameLogging
LOGLEVEL enum nameLogging
m_logfileLoggingprotected
m_loggingLoggingprotectedstatic
m_loggingLoggingprotectedstatic
m_max_levelLoggingprotected
m_mutexLoggingprotectedstatic
m_mutexLoggingprotectedstatic
m_to_stderrLoggingprotected
m_to_syslogLoggingprotected
m_to_syslogLoggingprotected
show(LOGLEVEL loglevel)Logginginlinestatic
trace(const T filename, const std::string &format_string, Args &&...args)Logginginlinestatic
trace(const T filename, const std::string &format_string, Args &&...args)Logginginlinestatic
warning(const T filename, const std::string &format_string, Args &&...args)Logginginlinestatic
diff --git a/html/classLogging.html b/html/classLogging.html index 463e6dc2e..8c1f29333 100644 --- a/html/classLogging.html +++ b/html/classLogging.html @@ -2,8 +2,8 @@ - - + + FFmpegfs Fuse Multi Media Filesystem: Logging Class Reference @@ -19,10 +19,9 @@
- - + @@ -30,21 +29,22 @@
-
FFmpegfs Fuse Multi Media Filesystem -  2.14 +
+
FFmpegfs Fuse Multi Media Filesystem 2.14
- + +/* @license-end */ +
Static Private Member Functions | Friends | List of all members
-
-
Logging Class Reference
+
Logging Class Reference
@@ -90,13 +89,13 @@
[legend]
-

+

Classes

class  Logger
 Logging helper class. More...
 
-

+

Public Types

enum class  LOGLEVEL {
  LOGERROR = 1 @@ -110,7 +109,7 @@
 Logging level types enum. More...
 
- @@ -118,7 +117,7 @@

+

Public Member Functions

 Logging (const std::string &logfile, LOGLEVEL max_level, bool to_stderr, bool to_syslog)
 
 Check whether either failbit or badbit is set. More...
 
- @@ -153,41 +152,34 @@

+

Static Public Member Functions

static bool init_logging (const std::string &logfile, LOGLEVEL max_level, bool to_stderr, bool to_syslog)
 Initialise the logging facility. More...
 Check if log entry should be displayed at the current log level. More...
 
- - - + + - - + + - - + + - - + + - - + +

+

Protected Attributes

-friend Logger
 Make logger class our friend.
friend Logger
 Make logger class our friend. More...
 
-std::ofstream m_logfile
 Log file object for writing to disk.
std::ofstream m_logfile
 Log file object for writing to disk. More...
 
-const LOGLEVEL m_max_level
 The maximum level of log output to write.
const LOGLEVEL m_max_level
 The maximum level of log output to write. More...
 
-const bool m_to_stderr
 Whether to write log output to stderr.
const bool m_to_stderr
 Whether to write log output to stderr. More...
 
-const bool m_to_syslog
 Whether to write log output to syslog.
const bool m_to_syslog
 Whether to write log output to syslog. More...
 
- - - + + - - + +

+

Static Protected Attributes

-static Loggingm_logging
 Reference to self, Logging is a singleton.
static Loggingm_logging
 Reference to self, Logging is a singleton. More...
 
-static std::recursive_mutex m_mutex
 Access mutex.
static std::recursive_mutex m_mutex
 Access mutex. More...
 
- @@ -201,31 +193,31 @@

+

Static Private Member Functions

static std::string format_helper (const std::string &string_to_update, const size_t __attribute__((unused)) index_to_replace)
 Standard format_helper without parameters. More...
 format string with single token More...
 
-

+

Friends

Logger Log (LOGLEVEL loglevel, const std::string &filename)
 Make logger class our friend for our constructor. More...
 

Detailed Description

-

Logging facility

-

Within the log message text, escape sequences are supported for dynamically formatting the message.

-

Escape sequences have either the form n or %<format specifier>n, where the index n starts at 1.

-

The index specifies the position of the argument in the list. They can appear in any given order. An index can be used more than once, and not all indexes have to be present (in which case the argument will not be printed). The input value is automatically converted to string format and can be among std::string, char *, int, uint64_t and more.

-

The format specifier is the same as used in printf and sprintf.

+

Logging facility

+

Within the log message text, escape sequences are supported for dynamically formatting the message.

+

Escape sequences have either the form n or %<format specifier>n, where the index n starts at 1.

+

The index specifies the position of the argument in the list. They can appear in any given order. An index can be used more than once, and not all indexes have to be present (in which case the argument will not be printed). The input value is automatically converted to string format and can be among std::string, char *, int, uint64_t and more.

+

The format specifier is the same as used in printf and sprintf.

int channels = 2;
int sample_rate = 44100:
-
Logging::debug(filename, "Audio %1 channels %2 KHz", channels, sample_rate);
+
Logging::debug(filename, "Audio %1 channels %2 KHz", channels, sample_rate);
static void debug(const T filename, const std::string &format_string, Args &&...args)
Write debug level log entry.
Definition: logging.h:182
-

Prints "Audio 2 channels 44100 KHz".

+

Prints "Audio 2 channels 44100 KHz".

int channels = 2;
double sample_rate = 44.1:
-
Logging::debug(filename, "Audio %1 %<%.3f>2 KHz", channels == 2 ? "stereo" : "mono", sample_rate);
-

Prints "Audio stereo 44.100 KHz".

+
Logging::debug(filename, "Audio %1 %<%.3f>2 KHz", channels == 2 ? "stereo" : "mono", sample_rate);
+

Prints "Audio stereo 44.100 KHz".

Definition at line 79 of file logging.h.

Member Enumeration Documentation

- +

◆ LOGLEVEL

@@ -235,7 +227,7 @@

- +
enum Logging::LOGLEVELenum class Logging::LOGLEVEL
@@ -247,15 +239,15 @@

Logging level types enum.

- - - - -
Enumerator
LOGERROR 

Error level.

+
Enumerator
LOGERROR 

Error level.

LOGWARN 

Warning level.

+
LOGWARN 

Warning level.

LOGINFO 

Info level.

+
LOGINFO 

Info level.

LOGDEBUG 

Debug level.

+
LOGDEBUG 

Debug level.

LOGTRACE 

Error level.

+
LOGTRACE 

Error level.

@@ -264,7 +256,7 @@

Constructor & Destructor Documentation

- +

◆ Logging()

@@ -309,7 +301,7 @@

-

Construct Logging object.

+

Construct Logging object.

Parameters
@@ -329,7 +321,7 @@

Member Function Documentation

- +

◆ debug()

@@ -385,11 +377,11 @@

References format_helper(), log_with_level(), LOGDEBUG, and show().

-

Referenced by FFmpeg_Transcoder::add_albumart_stream(), FFmpeg_Transcoder::add_external_subtitle_stream(), FFmpeg_Transcoder::add_stream(), FFmpeg_Transcoder::add_subtitle_stream(), FFmpeg_Base::audio_info(), create_dvd_virtualfile(), FFmpeg_Transcoder::decode_frame(), FFmpeg_Transcoder::decode_video_frame(), ffmpegfs_getattr(), ffmpegfs_readdir(), FFmpeg_Transcoder::get_hw_pix_fmt(), get_source_properties(), FFmpeg_Transcoder::init_deinterlace_filters(), FFmpeg_Transcoder::init_resampler(), FFmpeg_Transcoder::init_rescaler(), kick_next(), link_up(), Cache::load_index(), FFmpeg_Transcoder::open_bestmatch_video(), Buffer::open_file(), FFmpeg_Transcoder::open_input_file(), FFmpeg_Transcoder::open_output_file(), FFmpeg_Transcoder::open_output_filestreams(), FFmpeg_Transcoder::open_output_frame_set(), BlurayIO::openio(), DiskIO::openio(), DvdIO::openio(), Cache_Entry::outdated(), parse_bluray(), parse_dvd(), parse_file(), parse_vcd(), prepare_script(), FFmpeg_Base::subtitle_info(), thread_pool::tear_down(), transcode(), transcode_finish(), transcoder_free(), transcoder_init(), transcoder_new(), Cache::upgrade_db(), and FFmpeg_Base::video_info().

+

Referenced by FFmpeg_Transcoder::add_albumart_stream(), FFmpeg_Transcoder::add_external_subtitle_stream(), FFmpeg_Transcoder::add_stream(), FFmpeg_Transcoder::add_subtitle_stream(), FFmpeg_Base::audio_info(), FFmpeg_Transcoder::can_copy_stream(), create_dvd_virtualfile(), FFmpeg_Transcoder::decode_frame(), FFmpeg_Transcoder::decode_video_frame(), ffmpegfs_getattr(), ffmpegfs_readdir(), FFmpeg_Transcoder::get_hw_pix_fmt(), get_source_properties(), FFmpeg_Transcoder::init_deinterlace_filters(), FFmpeg_Transcoder::init_resampler(), FFmpeg_Transcoder::init_rescaler(), kick_next(), link_up(), Cache::load_index(), FFmpeg_Transcoder::open_bestmatch_video(), Buffer::open_file(), FFmpeg_Transcoder::open_input_file(), FFmpeg_Transcoder::open_output_file(), FFmpeg_Transcoder::open_output_filestreams(), FFmpeg_Transcoder::open_output_frame_set(), BlurayIO::openio(), DiskIO::openio(), DvdIO::openio(), Cache_Entry::outdated(), parse_bluray(), parse_dvd(), parse_file(), parse_vcd(), prepare_script(), FFmpeg_Base::subtitle_info(), thread_pool::tear_down(), transcode(), transcode_finish(), transcoder_free(), transcoder_init(), transcoder_new(), Cache::upgrade_db(), and FFmpeg_Base::video_info().

- +

◆ error()

@@ -445,11 +437,11 @@

References format_helper(), log_with_level(), LOGERROR, and show().

-

Referenced by FFmpeg_Transcoder::add_albumart_frame(), FFmpeg_Transcoder::add_albumart_stream(), FFmpeg_Transcoder::add_external_subtitle_stream(), FFmpeg_Transcoder::add_external_subtitle_streams(), FFmpeg_Transcoder::add_samples_to_fifo(), FFmpeg_Transcoder::add_stream(), FFmpeg_Transcoder::add_stream_copy(), FFmpeg_Transcoder::add_subtitle_stream(), FFmpeg_Transcoder::alloc_picture(), audio_stream_info(), Cache::begin_transaction(), check_cuesheet(), Cache::check_min_version(), Buffer::clear(), Cache::column_exists(), FFmpeg_Transcoder::convert_samples(), Buffer::copy(), FFmpeg_Transcoder::create_audio_frame(), create_bluray_virtualfile(), create_cuesheet_virtualfile(), create_dvd_virtualfile(), Cache::create_table_cache_entry(), create_vcd_virtualfile(), FFmpeg_Transcoder::decode(), FFmpeg_Transcoder::decode_audio_frame(), FFmpeg_Transcoder::decode_frame(), FFmpeg_Transcoder::decode_subtitle(), FFmpeg_Transcoder::decode_video_frame(), FFmpeg_Base::dict_set_with_check(), FFmpeg_Transcoder::encode_audio_frame(), FFmpeg_Transcoder::encode_image_frame(), FFmpeg_Transcoder::encode_subtitle(), FFmpeg_Transcoder::encode_video_frame(), Cache::end_transaction(), ffmpegfs_fgetattr(), ffmpegfs_read(), ffmpegfs_readdir(), ffmpegfs_release(), find_original(), Buffer::flush(), FFmpeg_Transcoder::flush_delayed_audio(), FFmpeg_Transcoder::flush_delayed_video(), FFmpeg_Transcoder::foreach_subtitle_file(), FFmpeg_Transcoder::get_hw_pix_fmt(), FFmpeg_Transcoder::hwdevice_ctx_add_ref(), FFmpeg_Transcoder::hwdevice_ctx_create(), FFmpeg_Transcoder::hwframe_copy_from_hw(), FFmpeg_Transcoder::hwframe_copy_to_hw(), FFmpeg_Transcoder::hwframe_ctx_set(), Buffer::init(), FFmpeg_Transcoder::init_audio_fifo(), FFmpeg_Transcoder::init_audio_output_frame(), FFmpeg_Transcoder::init_converted_samples(), FFmpeg_Transcoder::init_deinterlace_filters(), FFmpeg_Transcoder::init_resampler(), FFmpeg_Transcoder::init_rescaler(), FFmpeg_Transcoder::input_read(), link_down(), link_up(), Cache::load_index(), Buffer::map_file(), FFmpeg_Transcoder::open_albumarts(), FFmpeg_Transcoder::open_bestmatch_audio(), FFmpeg_Transcoder::open_bestmatch_decoder(), FFmpeg_Transcoder::open_bestmatch_video(), FFmpeg_Transcoder::open_decoder(), FFmpeg_Transcoder::open_input_file(), FFmpeg_Transcoder::open_output_file(), FFmpeg_Transcoder::open_output_filestreams(), FFmpeg_Transcoder::open_output_frame_set(), FFmpeg_Transcoder::open_subtitles(), BlurayIO::openio(), DvdIO::openio(), FFmpeg_Base::opt_set_with_check(), FFmpeg_Transcoder::output_write(), parse_cuesheet(), parse_dvd(), parse_file(), Cache::prepare_stmts(), FFmpeg_Transcoder::process_single_fr(), FFmpeg_Transcoder::read_decode_convert_and_store(), Cache::read_info(), BlurayIO::readio(), DvdIO::readio(), Buffer::reserve(), Cache::rollback_transaction(), FFmpeg_Transcoder::seek(), FFmpeg_Transcoder::send_filters(), FFmpeg_Transcoder::skip_decoded_frames(), FFmpeg_Transcoder::stack_seek_frame(), FFmpeg_Transcoder::stack_seek_segment(), FFmpeg_Transcoder::start_new_segment(), start_timer(), stop_timer(), FFmpeg_Transcoder::store_packet(), Cache::table_exists(), transcoder_init(), transcoder_read_frame(), transcoder_set_filesize(), transcoder_thread(), Buffer::unmap_file(), Cache::upgrade_db(), video_stream_info(), FFmpeg_Transcoder::write_output_file_header(), and FFmpeg_Transcoder::write_output_file_trailer().

+

Referenced by FFmpeg_Transcoder::add_albumart_frame(), FFmpeg_Transcoder::add_albumart_stream(), FFmpeg_Transcoder::add_external_subtitle_stream(), FFmpeg_Transcoder::add_external_subtitle_streams(), FFmpeg_Transcoder::add_samples_to_fifo(), FFmpeg_Transcoder::add_stream(), FFmpeg_Transcoder::add_stream_copy(), FFmpeg_Transcoder::add_subtitle_stream(), FFmpeg_Transcoder::alloc_picture(), audio_stream_info(), Cache::begin_transaction(), check_cuesheet(), Cache::check_min_version(), Buffer::clear(), Cache::column_exists(), FFmpeg_Transcoder::convert_samples(), Buffer::copy(), FFmpeg_Transcoder::create_audio_frame(), create_bluray_virtualfile(), create_cuesheet_virtualfile(), create_dvd_virtualfile(), Cache::create_table_cache_entry(), create_vcd_virtualfile(), FFmpeg_Transcoder::decode(), FFmpeg_Transcoder::decode_audio_frame(), FFmpeg_Transcoder::decode_frame(), FFmpeg_Transcoder::decode_subtitle(), FFmpeg_Transcoder::decode_video_frame(), FFmpeg_Base::dict_set_with_check(), FFmpeg_Transcoder::encode_audio_frame(), FFmpeg_Transcoder::encode_image_frame(), FFmpeg_Transcoder::encode_subtitle(), FFmpeg_Transcoder::encode_video_frame(), Cache::end_transaction(), ffmpegfs_fgetattr(), ffmpegfs_read(), ffmpegfs_readdir(), ffmpegfs_release(), find_original(), Buffer::flush(), FFmpeg_Transcoder::flush_delayed_audio(), FFmpeg_Transcoder::flush_delayed_video(), FFmpeg_Transcoder::foreach_subtitle_file(), FFmpeg_Transcoder::get_format(), FFmpeg_Transcoder::get_hw_pix_fmt(), FFmpeg_Transcoder::hwdevice_ctx_add_ref(), FFmpeg_Transcoder::hwdevice_ctx_create(), FFmpeg_Transcoder::hwframe_copy_from_hw(), FFmpeg_Transcoder::hwframe_copy_to_hw(), FFmpeg_Transcoder::hwframe_ctx_set(), Buffer::init(), FFmpeg_Transcoder::init_audio_fifo(), FFmpeg_Transcoder::init_audio_output_frame(), FFmpeg_Transcoder::init_converted_samples(), FFmpeg_Transcoder::init_deinterlace_filters(), FFmpeg_Transcoder::init_resampler(), FFmpeg_Transcoder::init_rescaler(), FFmpeg_Transcoder::input_read(), link_down(), link_up(), Cache::load_index(), Buffer::map_file(), FFmpeg_Transcoder::open_albumarts(), FFmpeg_Transcoder::open_bestmatch_audio(), FFmpeg_Transcoder::open_bestmatch_decoder(), FFmpeg_Transcoder::open_bestmatch_video(), FFmpeg_Transcoder::open_decoder(), FFmpeg_Transcoder::open_input_file(), FFmpeg_Transcoder::open_output_file(), FFmpeg_Transcoder::open_output_filestreams(), FFmpeg_Transcoder::open_output_frame_set(), FFmpeg_Transcoder::open_subtitles(), BlurayIO::openio(), DvdIO::openio(), FFmpeg_Base::opt_set_with_check(), FFmpeg_Transcoder::output_write(), parse_cuesheet(), parse_dvd(), parse_file(), Cache::prepare_stmts(), FFmpeg_Transcoder::process_single_fr(), FFmpeg_Transcoder::read_decode_convert_and_store(), Cache::read_info(), BlurayIO::readio(), DvdIO::readio(), Buffer::reserve(), Cache::rollback_transaction(), FFmpeg_Transcoder::seek(), FFmpeg_Transcoder::send_filters(), FFmpeg_Transcoder::skip_decoded_frames(), FFmpeg_Transcoder::stack_seek_frame(), FFmpeg_Transcoder::stack_seek_segment(), FFmpeg_Transcoder::start_new_segment(), start_timer(), stop_timer(), FFmpeg_Transcoder::store_packet(), Cache::table_exists(), transcoder_init(), transcoder_read_frame(), transcoder_set_filesize(), transcoder_thread(), Buffer::unmap_file(), Cache::upgrade_db(), video_stream_info(), FFmpeg_Transcoder::write_output_file_header(), and FFmpeg_Transcoder::write_output_file_trailer().

- +

◆ format()

[in]logfile- The name of a file to write logging output to. If empty, no output will be written.
@@ -568,7 +560,7 @@

+

◆ format_helper() [2/2]

@@ -618,7 +610,7 @@

+

◆ GetFail()

- +

◆ init_logging()

@@ -771,7 +763,7 @@

+

◆ log_with_level() [1/2]

@@ -823,11 +815,13 @@

Definition at line 226 of file logging.cc.

-

Referenced by debug(), error(), ffmpeg_log(), info(), trace(), and warning().

+

References log_with_level().

+ +

Referenced by debug(), error(), ffmpeg_log(), info(), log_with_level(), trace(), and warning().

- +

◆ log_with_level() [2/2]

@@ -883,7 +877,7 @@

+

◆ show()

@@ -924,7 +918,7 @@

+

◆ trace()

@@ -980,11 +974,11 @@

References format_helper(), log_with_level(), LOGTRACE, and show().

-

Referenced by FFmpeg_Transcoder::add_albumart_frame(), FFmpeg_Transcoder::add_stream(), Cache_Entry::Cache_Entry(), check_bluray(), check_cuesheet(), check_dvd(), check_vcd(), Buffer::close_file(), FFmpeg_Transcoder::closeio(), Cache::closeio(), create_bluray_virtualfile(), create_dvd_virtualfile(), FFmpeg_Transcoder::encode_video_frame(), FFmpeg_Transcoder::FFmpeg_Transcoder(), ffmpegfs_fgetattr(), ffmpegfs_getattr(), ffmpegfs_open(), ffmpegfs_read(), ffmpegfs_readdir(), ffmpegfs_readlink(), ffmpegfs_release(), ffmpegfs_statfs(), get_format(), FFmpeg_Transcoder::init_rescaler(), thread_pool::loop_function(), Buffer::map_file(), master_check(), FFmpeg_Transcoder::open_albumarts(), FFmpeg_Transcoder::open_bestmatch_video(), Buffer::open_file(), Cache_Entry::openio(), Cache::openio(), DvdIO::openio(), parse_bluray(), parse_cuesheet_file(), parse_cuesheet_text(), parse_dvd(), parse_file(), prepare_script(), print_params(), FFmpeg_Transcoder::process_metadata(), FFmpeg_Transcoder::read_decode_convert_and_store(), Buffer::reallocate(), thread_pool::schedule_thread(), start_timer(), FFmpeg_Transcoder::store_packet(), transcode_until(), transcoder_new(), transcoder_predict_filesize(), transcoder_read(), transcoder_read_frame(), transcoder_set_filesize(), Buffer::unmap_file(), FFmpeg_Transcoder::update_codec(), FFmpeg_Transcoder::update_format(), Cache_Entry::~Cache_Entry(), and FFmpeg_Transcoder::~FFmpeg_Transcoder().

+

Referenced by FFmpeg_Transcoder::add_albumart_frame(), FFmpeg_Transcoder::add_stream(), Cache_Entry::Cache_Entry(), check_bluray(), check_cuesheet(), check_dvd(), check_vcd(), Buffer::close_file(), FFmpeg_Transcoder::closeio(), Cache::closeio(), create_bluray_virtualfile(), create_dvd_virtualfile(), FFmpeg_Transcoder::encode_video_frame(), FFmpeg_Transcoder::FFmpeg_Transcoder(), ffmpegfs_fgetattr(), ffmpegfs_getattr(), ffmpegfs_open(), ffmpegfs_read(), ffmpegfs_readdir(), ffmpegfs_readlink(), ffmpegfs_release(), ffmpegfs_statfs(), get_format(), FFmpeg_Transcoder::init_rescaler(), thread_pool::loop_function(), Buffer::map_file(), master_check(), FFmpeg_Transcoder::open_albumarts(), FFmpeg_Transcoder::open_bestmatch_video(), Buffer::open_file(), Cache_Entry::openio(), Cache::openio(), DvdIO::openio(), parse_bluray(), parse_cuesheet_file(), parse_cuesheet_text(), parse_dvd(), parse_file(), prepare_script(), print_params(), FFmpeg_Transcoder::process_metadata(), FFmpeg_Transcoder::read_decode_convert_and_store(), Buffer::reallocate(), thread_pool::schedule_thread(), start_timer(), FFmpeg_Transcoder::store_packet(), transcode_until(), transcoder_new(), transcoder_predict_filesize(), transcoder_read(), transcoder_read_frame(), transcoder_set_filesize(), Buffer::unmap_file(), FFmpeg_Transcoder::update_codec(), FFmpeg_Transcoder::update_format(), Cache_Entry::~Cache_Entry(), and FFmpeg_Transcoder::~FFmpeg_Transcoder().

- +

◆ warning()

Friends And Related Function Documentation

- +

◆ Log

@@ -1092,6 +1086,201 @@

Referenced by log_with_level().

+

+

+

Member Data Documentation

+ +

◆ Logger

+ +
+
+
[in]string_to_search- format string to be searched.
+ + + + +
+ + + + +
friend Logging::Logger
+
+protected
+

+ +

Make logger class our friend.

+ +

Definition at line 366 of file logging.h.

+ +
+

+ +

◆ m_logfile

+ +
+
+ + + + + +
+ + + + +
std::ofstream Logging::m_logfile
+
+protected
+
+ +

Log file object for writing to disk.

+ +

Definition at line 370 of file logging.h.

+ +

Referenced by GetFail(), Logging(), and Logging::Logger::~Logger().

+ +
+
+ +

◆ m_logging

+ +
+
+ + + + + +
+ + + + +
Logging * Logging::m_logging
+
+staticprotected
+
+ +

Reference to self, Logging is a singleton.

+ +

Definition at line 368 of file logging.h.

+ +

Referenced by init_logging(), show(), and Logging::Logger::~Logger().

+ +
+
+ +

◆ m_max_level

+ +
+
+ + + + + +
+ + + + +
const LOGLEVEL Logging::m_max_level
+
+protected
+
+ +

The maximum level of log output to write.

+ +

Definition at line 371 of file logging.h.

+ +

Referenced by show().

+ +
+
+ +

◆ m_mutex

+ +
+
+ + + + + +
+ + + + +
std::recursive_mutex Logging::m_mutex
+
+staticprotected
+
+ +

Access mutex.

+ +

Definition at line 369 of file logging.h.

+ +

Referenced by Logging::Logger::~Logger().

+ +
+
+ +

◆ m_to_stderr

+ +
+
+ + + + + +
+ + + + +
const bool Logging::m_to_stderr
+
+protected
+
+ +

Whether to write log output to stderr.

+ +

Definition at line 372 of file logging.h.

+ +

Referenced by Logging::Logger::~Logger().

+ +
+
+ +

◆ m_to_syslog

+ +
+
+ + + + + +
+ + + + +
const bool Logging::m_to_syslog
+
+protected
+
+ +

Whether to write log output to syslog.

+ +

Definition at line 373 of file logging.h.

+ +

Referenced by Logging(), and Logging::Logger::~Logger().

+

The documentation for this class was generated from the following files: