FFmpegfs Fuse Multi Media Filesystem 2.16
blurayparser.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017-2024 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[FORMAT::VIDEO].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[FORMAT::VIDEO].fileext().c_str()); // can safely assume this is a video format
471
472 }
473
474 LPVIRTUALFILE virtualfile = nullptr;
475 if (!ffmpeg_format[FORMAT::VIDEO].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:45
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.
static int parse_find_best_audio_stream()
Find best match audio stream.
static bool audio_stream_info(const std::string &path, BLURAY_STREAM_INFO *ss, int *channels, int *sample_rate)
Get information about Blu-ray stream.
Definition: blurayparser.cc:61
static int parse_find_best_video_stream()
Find best match video stream.
static bool video_stream_info(const std::string &path, BLURAY_STREAM_INFO *ss, int *width, int *height, AVRational *framerate, bool *interleaved)
Get information about Blu-ray stream.
Blu-ray parser.
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.
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:737
@ VIDEO
FFmpegfs_Format info, 0: video file.
Definition: ffmpeg_utils.h:517
FFMPEGFS_FORMAT_ARR ffmpeg_format
Two FFmpegfs_Format infos, 0: video file, 1: audio file.
Definition: ffmpegfs.cc:73
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: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: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
@ BLURAY
Blu-ray disk file.
Provide various log facilities to stderr, disk or syslog.
unsigned m_chapter_no
Chapter number (1...n)
Definition: fileio.h:214
uint32_t m_title_no
Track number (1...n)
Definition: fileio.h:212
uint32_t m_playlist_no
Playlist number (1...n)
Definition: fileio.h:213
unsigned m_angle_no
Selected angle number (1...n)
Definition: fileio.h:215
Virtual file definition.
Definition: fileio.h:123
int m_sample_rate
Audio sample rate - Filled in for the DVD/Blu-ray directory.
Definition: fileio.h:247
bool m_full_title
If true, ignore m_chapter_no and provide full track.
Definition: fileio.h:155
size_t m_predicted_size
Use this as the size instead of computing it over and over.
Definition: fileio.h:157
int m_width
Video width - Filled in for the DVD/Blu-ray directory.
Definition: fileio.h:249
int m_height
Video height - Filled in for the DVD/Blu-ray directory.
Definition: fileio.h:250
int m_channels
Audio channels - Filled in for the DVD/Blu-ray directory.
Definition: fileio.h:246
AVRational m_framerate
Video frame rate - Filled in for the DVD/Blu-ray directory.
Definition: fileio.h:251
struct stat m_st
stat structure with size etc.
Definition: fileio.h:153
struct VIRTUALFILE::BLURAY_CHAPTER m_bluray
Blu-ray title/chapter info.
size_t m_format_idx
Index into params.format[] array.
Definition: fileio.h:149
uint32_t m_video_frame_count
Number of frames in video or 0 if not a video.
Definition: fileio.h:158
int64_t m_duration
Track/chapter duration, in AV_TIME_BASE fractional seconds.
Definition: fileio.h:156
bool transcoder_set_filesize(LPVIRTUALFILE virtualfile, int64_t duration, BITRATE audio_bit_rate, int channels, int sample_rate, AVSampleFormat sample_format, BITRATE video_bit_rate, int width, int height, bool interleaved, const AVRational &framerate)
Set the file size.
Definition: transcode.cc:288
bool transcoder_cached_filesize(LPVIRTUALFILE virtualfile, struct stat *stbuf)
Simply get encoded file size (do not create the whole encoder/decoder objects)
Definition: transcode.cc:261
File transcoder interface (for use with by FUSE)