1# $Id: BitrateCalc.pm 2187 2006-08-16 19:34:38Z joern $
2
3#-----------------------------------------------------------------------
4# Copyright (C) 2001-2006 J�rn Reder <joern AT zyn.de>.
5# All Rights Reserved. See file COPYRIGHT for details.
6#
7# This module is part of Video::DVDRip, which is free software; you can
8# redistribute it and/or modify it under the same terms as Perl itself.
9#-----------------------------------------------------------------------
10
11package Video::DVDRip::BitrateCalc;
12use Locale::TextDomain qw (video.dvdrip);
13
14use base Video::DVDRip::Base;
15use strict;
16
17my $VCD_ADDITION_FACTOR = 2324 / 2048;
18my $VCD_DISC_OVERHEAD   = 600 * 2324;
19my $AVI_VIDEO_OVERHEAD  = 45;
20my $AVI_AUDIO_OVERHEAD  = 15;
21my $OGG_SIZE_OVERHEAD   = 0.25 / 100;
22my $VCD_VIDEO_RATE      = 1152;
23my $MAX_SVCD_SUM_RATE   = 2748;
24my $MAX_SVCD_VIDEO_RATE = 2600;
25my $MAX_VIDEO_RATE      = 9000;
26
27my %VORBIS_NOMINAL_BITRATES = (
28    0  => 60,
29    1  => 80,
30    2  => 96,
31    3  => 112,
32    4  => 128,
33    5  => 160,
34    6  => 192,
35    7  => 224,
36    8  => 256,
37    9  => 320,
38    10 => 498,
39);
40
41# methods for calculation parameters
42
43sub title			{ shift->{title}			}
44sub with_sheet			{ shift->{with_sheet}			}
45sub audio_size			{ shift->{audio_size}			}
46sub vobsub_size			{ shift->{vobsub_size}			}
47sub vcd_video_rate		{ shift->{vcd_video_rate}		}
48sub max_svcd_sum_rate		{ shift->{max_svcd_sum_rate}		}
49sub max_svcd_video_rate		{ shift->{max_svcd_video_rate}		}
50sub max_video_rate		{ shift->{max_video_rate}		}
51
52sub set_title			{ shift->{title}		= $_[1]	}
53sub set_with_sheet		{ shift->{with_sheet}		= $_[1]	}
54sub set_audio_size		{ shift->{audio_size}		= $_[1]	}
55sub set_vobsub_size		{ shift->{vobsub_size}		= $_[1]	}
56sub set_vcd_video_rate		{ shift->{vcd_video_rate}	= $_[1]	}
57sub set_max_svcd_sum_rate	{ shift->{max_svcd_sum_rate}	= $_[1]	}
58sub set_max_svcd_video_rate	{ shift->{max_svcd_video_rate}	= $_[1]	}
59sub set_max_video_rate		{ shift->{max_video_rate}	= $_[1]	}
60
61# methods for the result of calculation
62
63sub video_bitrate		{ shift->{video_bitrate}		}
64sub video_bpp			{ shift->{video_bpp}			}
65sub audio_bitrate		{ shift->{audio_bitrate}		}
66sub vcd_reserve_bitrate		{ shift->{vcd_reserve_bitrate}		}
67sub target_size			{ shift->{target_size}			}
68sub disc_size			{ shift->{disc_size}			}
69sub video_size			{ shift->{video_size}			}
70sub cont_overhead_size		{ shift->{cont_overhead_size}		}
71sub other_size			{ shift->{other_size}			}
72sub frames			{ shift->{frames}			}
73sub runtime			{ shift->{runtime}			}
74sub file_size			{ shift->{file_size}			}
75sub sheet			{ shift->{sheet}			}
76
77sub set_video_bitrate		{ shift->{video_bitrate}	= $_[1]	}
78sub set_video_bpp		{ shift->{video_bpp}		= $_[1]	}
79sub set_audio_bitrate		{ shift->{audio_bitrate}	= $_[1]	}
80sub set_vcd_reserve_bitrate	{ shift->{vcd_reserve_bitrate}	= $_[1]	}
81sub set_target_size		{ shift->{target_size}		= $_[1]	}
82sub set_disc_size		{ shift->{disc_size}		= $_[1]	}
83sub set_video_size		{ shift->{video_size}		= $_[1]	}
84sub set_cont_overhead_size	{ shift->{cont_overhead_size}	= $_[1]	}
85sub set_other_size		{ shift->{other_size}		= $_[1]	}
86sub set_frames			{ shift->{frames}		= $_[1]	}
87sub set_runtime			{ shift->{runtime}		= $_[1]	}
88sub set_file_size		{ shift->{file_size}		= $_[1]	}
89sub set_sheet			{ shift->{sheet}		= $_[1]	}
90
91sub non_video_size {
92    my $self = shift;
93
94    return $self->audio_size + $self->cont_overhead_size + $self->other_size;
95}
96
97sub new {
98    my $class = shift;
99    my %par = @_;
100    my  ($title, $with_sheet, $video_bitrate, $video_bpp) =
101    @par{'title','with_sheet','video_bitrate','video_bpp'};
102    my  ($video_size, $audio_size, $audio_bitrate, $target_size) =
103    @par{'video_size','audio_size','audio_bitrate','target_size'};
104    my  ($disc_size, $vobsub_size) =
105    @par{'disc_size','vobsub_size'};
106
107    my $self = {
108        title               => $title,
109        with_sheet          => $with_sheet,
110
111        video_bitrate       => $video_bitrate,
112        video_bpp           => $video_bpp,
113        video_size          => $video_size,
114
115        audio_size          => $audio_size,
116        audio_bitrate       => $audio_bitrate,
117
118        target_size         => $target_size,
119        disc_size           => $disc_size,
120        vobsub_size         => $vobsub_size,
121
122        sheet               => [],
123        vcd_video_rate      => $VCD_VIDEO_RATE,
124        max_svcd_sum_rate   => $MAX_SVCD_SUM_RATE,
125        max_svcd_video_rate => $MAX_SVCD_VIDEO_RATE,
126        max_video_rate      => $MAX_VIDEO_RATE,
127    };
128
129    return bless $self, $class;
130}
131
132sub add_audio_size {
133    my $self    = shift;
134    my %par     = @_;
135    my ($bytes) = @par{'bytes'};
136
137    $self->log( sprintf( "Add audio size: %.2f MB", $bytes / 1024 / 1024 ) );
138
139    $self->set_audio_size( $bytes + $self->audio_size );
140
141    1;
142}
143
144sub add_vobsub_size {
145    my $self    = shift;
146    my %par     = @_;
147    my ($bytes) = @par{'bytes'};
148
149    $self->set_vobsub_size( $bytes + $self->vobsub_size );
150
151    1;
152}
153
154sub add_to_sheet {
155    my $self = shift;
156    return 1 if not $self->with_sheet;
157    my ($href) = @_;
158    push @{ $self->sheet }, $href;
159    1;
160}
161
162sub calc_frames_and_runtime {
163    my $self = shift;
164
165    my $title     = $self->title;
166    my $frames    = $title->frames;
167    my $framerate = $title->tc_video_framerate;
168    my $runtime   = $title->runtime;
169
170    if ( $title->tc_use_chapter_mode eq 'select' ) {
171
172        # get sum of chapter frames (if chapter mode enabled)
173        if ( not $title->real_actual_chapter ) {
174            $frames = 0;
175            my $chapters = $title->get_chapters;
176            foreach my $chapter ( @{$chapters} ) {
177                $frames += $title->chapter_frames->{$chapter};
178            }
179        }
180        else {
181            $frames = $title->chapter_frames->{ $title->actual_chapter };
182        }
183
184    }
185    elsif ( $title->tc_video_bitrate_range ) {
186
187        # reduce sum of frames (if a range was set)
188        if (   $title->tc_start_frame ne ''
189            or $title->tc_end_frame ne '' ) {
190            $frames = $title->tc_end_frame || $title->frames;
191            $frames = $frames - $title->tc_start_frame
192                if $title->has_vob_nav_file;
193            $frames ||= $title->frames;
194        }
195        if ( $frames < 0 ) {
196            $frames = $title->frames;
197        }
198    }
199
200    # document frames and recalculate runtime
201    if ( $frames and $framerate ) {
202        $runtime = $frames / $framerate;
203        $self->add_to_sheet(
204            {   label    => __ "Number of frames",
205                operator => "=",
206                value    => $frames,
207                unit     => "",
208            }
209        );
210        $self->add_to_sheet(
211            {   label    => __ "Frames per second",
212                operator => "/",
213                value    => $framerate,
214                unit     => "fps",
215            }
216        );
217        $self->add_to_sheet(
218            {   label    => __ "Runtime",
219                operator => "=",
220                value    => $runtime,
221                unit     => "s",
222            }
223        );
224    }
225
226    $frames  ||= 1;
227    $runtime ||= 1;
228
229    $self->set_frames($frames);
230    $self->set_runtime($runtime);
231
232    1;
233}
234
235sub calc_audio_size_and_bitrate {
236    my $self       = shift;
237    my %par        = @_;
238    my ($operator) = @par{'operator'};
239
240    my $title = $self->title;
241
242    my $audio_size = 0;
243    my $audio_bitrate;
244
245    my $runtime   = $self->runtime;
246    my $frames    = $self->frames;
247    my $container = $title->tc_container;
248    if ( $self->audio_size ) {
249
250        # audio size is known already, no need to calculate it.
251        $audio_size = sprintf( "%.2f", $self->audio_size / 1024 / 1024 );
252        $self->log(
253            __x("Audio size is given with {audio_size} MB",
254                audio_size => $audio_size
255            )
256        );
257        $self->add_to_sheet(
258            {   label    => __ "Audio size",
259                operator => "+",
260                value    => $audio_size,
261                unit     => "MB",
262            }
263        );
264    }
265    else {
266        my $nr = -1;
267        foreach my $audio ( @{ $title->audio_tracks } ) {
268            ++$nr;
269            next if $audio->tc_target_track == -1;
270
271            my $bitrate = $audio->tc_bitrate;
272
273            if (    $audio->tc_audio_codec eq 'vorbis'
274                and $audio->tc_vorbis_quality_enable ) {
275
276                # derive a bitrate from vorbis quality setting
277                $bitrate = $VORBIS_NOMINAL_BITRATES{
278                    int( $audio->tc_vorbis_quality + 0.5 ) };
279            }
280            my $track_size = $runtime * $bitrate * 1000 / 8 / 1024 / 1024;
281            my $audio_overhead;
282            $audio_overhead = $AVI_AUDIO_OVERHEAD * $frames / 1024 / 1024
283                if $container eq 'avi';
284
285            $track_size = sprintf( "%.2f", $track_size + $audio_overhead );
286
287            my $comment;
288
289            if ( $container eq 'avi' ) {
290                $comment = " "
291                    . __x(
292                    "(incl. {avi_overhead} byte" . " AVI overhead per frame)",
293                    avi_overhead => $AVI_AUDIO_OVERHEAD
294                    );
295            }
296
297            if ( $audio->tc_audio_codec eq 'vorbis' ) {
298                if ( $audio->tc_vorbis_quality_enable ) {
299                    $comment = " "
300                        . __ "(assume nominal bitrate for this quality)";
301                }
302                else {
303                    $comment = " " . __ "(exact bitrate match assumed)";
304                }
305            }
306
307            $self->add_to_sheet(
308                {   label => __x( "Audio track #{nr}", nr => $nr ) . $comment,
309                    operator => $operator,
310                    value    => $track_size,
311                    unit     => "MB",
312                }
313            );
314
315            $audio_size    += $track_size;
316            $audio_bitrate += $bitrate;
317        }
318    }
319
320    $self->set_audio_size($audio_size);
321    $self->set_audio_bitrate($audio_bitrate);
322
323    1;
324}
325
326sub calc_container_overhead {
327    my $self       = shift;
328    my %par        = @_;
329    my ($operator) = @par{'operator'};
330
331    my $title              = $self->title;
332    my $container          = $title->tc_container;
333    my $frames             = $self->frames;
334    my $container_overhead = 0;
335
336    if ( $container eq 'avi' ) {
337        $container_overhead
338            = sprintf( "%.2f", $AVI_VIDEO_OVERHEAD * $frames / 1024 / 1024 );
339
340        $self->add_to_sheet(
341            {   label => __x(
342                    "AVI video overhead ({avi_overhead} bytes per frame)",
343                    avi_overhead => $AVI_VIDEO_OVERHEAD
344                ),
345                operator => $operator,
346                value    => $container_overhead,
347                unit     => "MB",
348            }
349        );
350
351    }
352    elsif ( $container eq 'ogg' ) {
353        my $file_size;
354        if ( $self->video_size ) {
355            $file_size = $self->video_size + $self->audio_size;
356        }
357        else {
358            $file_size = $self->target_size - $self->non_video_size;
359        }
360        $container_overhead
361            = sprintf( "%.2f", $OGG_SIZE_OVERHEAD * $file_size );
362
363        $self->add_to_sheet(
364            {   label => __x(
365                    "OGG overhead ({ogg_overhead} percent of video+audio size)",
366                    ogg_overhead => $OGG_SIZE_OVERHEAD * 100
367                ),
368                operator => $operator,
369                value    => $container_overhead,
370                unit     => "MB",
371            }
372        );
373    }
374
375    $self->set_cont_overhead_size($container_overhead);
376
377    # calculate vcd multiplex bitrate reserve
378    my $vcd_reserve_bitrate = $self->audio_bitrate +
379        int( ( $self->audio_bitrate + $self->video_bitrate ) * 0.02 );
380
381    $self->set_vcd_reserve_bitrate($vcd_reserve_bitrate);
382
383    1;
384}
385
386sub calc_target_size {
387    my $self = shift;
388
389    my $title = $self->title;
390
391    my $target_size;
392    if ($title->tc_disc_cnt * $title->tc_disc_size == $title->tc_target_size )
393    {
394
395        # Number of discs
396        my $disc_cnt = $title->tc_disc_cnt;
397        $self->add_to_sheet(
398            {   label    => __ "Number of discs",
399                operator => "",
400                value    => $disc_cnt,
401                unit     => "",
402            }
403        );
404
405        # Size of a disc
406        my $disc_size = $title->tc_disc_size;
407        $self->add_to_sheet(
408            {   label    => __ "Disc size",
409                operator => "*",
410                value    => $disc_size,
411                unit     => "MB",
412            }
413        );
414
415        $target_size = $disc_cnt * $disc_size;
416    }
417    else {
418        $target_size = $title->tc_target_size;
419    }
420
421    $self->add_to_sheet(
422        {   label    => __ "Target size",
423            operator => "=",
424            value    => $target_size,
425            unit     => "MB",
426        }
427    );
428
429    $self->set_target_size($target_size);
430
431    1;
432}
433
434sub calc_disc_size {
435    my $self = shift;
436
437    my $title = $self->title;
438
439    my $disc_size = $title->tc_disc_size;
440    $disc_size = int(
441        $disc_size * $VCD_ADDITION_FACTOR - $VCD_DISC_OVERHEAD / 1024 / 1024 )
442        if $title->tc_container eq 'vcd';
443
444    $self->set_disc_size($disc_size);
445
446    1;
447}
448
449sub calc_svcd_overhead {
450    my $self = shift;
451
452    my $title       = $self->title;
453    my $target_size = $self->target_size || 1;
454    my $container   = $title->tc_container;
455
456    if (    $container eq 'vcd'
457        and $title->tc_disc_cnt * $title->tc_disc_size
458        == $title->tc_target_size ) {
459        my $addition = sprintf( "%.2f", ( 2324 / 2048 - 1 ) * $target_size );
460        $self->add_to_sheet(
461            {   label    => __ "VCD sector size addition (factor: 2324/2048)",
462                operator => "+",
463                value    => $addition,
464                unit     => "MB",
465            }
466        );
467        $target_size += $addition;
468
469        my $disc_overhead = sprintf( "%.2f",
470            $VCD_DISC_OVERHEAD * $title->tc_disc_cnt / 1024 / 1024 );
471        $self->add_to_sheet(
472            {   label    => __ "VCD per disc overhead (600 sectors)",
473                operator => "-",
474                value    => $disc_overhead,
475                unit     => "MB",
476            }
477        );
478        $target_size -= $disc_overhead;
479
480        $self->add_to_sheet(
481            {   label    => __ "(X)(S)VCD/CVD target size",
482                operator => "=",
483                value    => $target_size,
484                unit     => "MB",
485            }
486        );
487
488        $self->set_target_size($target_size);
489    }
490
491    1;
492}
493
494sub calc_vobsub_size {
495    my $self       = shift;
496    my %par        = @_;
497    my ($operator) = @par{'operator'};
498
499    my $title = $self->title;
500
501    my $vobsub_size = 0;
502
503    if ( $self->vobsub_size ) {
504
505        # vobsub size is known already, no need to calculate it.
506        $vobsub_size = sprintf( "%.2f", $self->vobsub_size / 1024 / 1024 );
507        $self->add_to_sheet(
508            {   label    => __ "vobsub size",
509                operator => $operator,
510                value    => $vobsub_size,
511                unit     => "MB",
512            }
513        );
514    }
515    else {
516        foreach my $subtitle ( sort { $a->id <=> $b->id }
517            values %{ $title->subtitles } ) {
518            next if not $subtitle->tc_vobsub;
519            $vobsub_size += 1;
520            $self->add_to_sheet(
521                {   label => __x(
522                        "vobsub size subtitle #{nr}",
523                        nr => $subtitle->id
524                    ),
525                    operator => $operator,
526                    value    => 1,
527                    unit     => "MB",
528                }
529            );
530        }
531    }
532
533    $self->set_vobsub_size($vobsub_size);
534
535    1;
536}
537
538sub calc_video_size_and_bitrate {
539    my $self = shift;
540
541    my $title = $self->title;
542
543    my $runtime       = $self->runtime;
544    my $audio_bitrate = $self->audio_bitrate;
545
546    my ( $width, $height ) = $title->get_effective_ratio( type => "clip2" );
547
548    # video size
549    my $video_size = $self->target_size - $self->non_video_size;
550
551    $self->add_to_sheet(
552        {   label    => __ "Space left for video",
553            operator => "=",
554            value    => $video_size,
555            unit     => "MB",
556        }
557    );
558
559    # resulting video bitrate
560    my $video_bitrate
561        = int( $video_size / $runtime / 1000 * 1024 * 1024 * 8 );
562
563    $self->add_to_sheet(
564        {   label    => __("Resulting video bitrate, rounded"),
565            operator => "~",
566            value    => $video_bitrate,
567            unit     => "kbit/s",
568        }
569    );
570
571    # probably too high for selected video codec
572    $video_bitrate
573        = $self->calc_video_bitrate_limit( video_bitrate => $video_bitrate, );
574
575    # calculate bpp
576    my $bpp = 0;
577    if ( $title->tc_video_bitrate_mode eq 'bpp' ) {
578        $bpp = sprintf( "%.3f", $title->tc_video_bpp_manual );
579    }
580    else {
581        my $pps = $title->frame_rate * $width * $height;
582        $bpp = $video_bitrate * 1000 / $pps if $pps != 0;
583        $bpp = sprintf( "%.3f", $bpp );
584    }
585
586    $self->add_to_sheet(
587        {   label    => __("Resulting BPP"),
588            operator => "",
589            value    => $bpp,
590            unit     => "bpp",
591        }
592    );
593
594    # calculate *real* video size, if bitrate has changed
595    # after calculation (due to limits)
596    $video_size = sprintf( "%.2f",
597        $video_bitrate * $runtime * 1000 / 1024 / 1024 / 8 );
598
599    $self->add_to_sheet(
600        {   label    => __ "Resulting video size",
601            operator => "~",
602            value    => $video_size,
603            unit     => "MB",
604        }
605    );
606
607    $self->set_video_bitrate($video_bitrate);
608    $self->set_video_bpp($bpp);
609    $self->set_video_size($video_size);
610
611    1;
612}
613
614sub calc_video_bitrate_limit {
615    my $self            = shift;
616    my %par             = @_;
617    my ($video_bitrate) = @par{'video_bitrate'};
618
619    my $title         = $self->title;
620    my $audio_bitrate = $self->audio_bitrate;
621
622    my $comment;
623    if ( $video_bitrate > $self->max_video_rate ) {
624        $video_bitrate = $self->max_video_rate;
625        $comment       = __x(
626            "Bitrate too high, set to {max_video_rate}",
627            max_video_rate => $self->max_video_rate
628        );
629    }
630
631    if (    $title->tc_video_codec =~ /^(SVCD|CVD|VCD)$/
632        and $video_bitrate + $audio_bitrate > $self->max_svcd_sum_rate ) {
633        $video_bitrate = $self->max_svcd_sum_rate - $audio_bitrate;
634        $comment       = __ "Bitrate too high, limited";
635    }
636
637    if (    $title->tc_video_codec =~ /^(SVCD|CVD|VCD)$/
638        and $video_bitrate > $self->max_svcd_video_rate ) {
639        $video_bitrate = $self->max_svcd_video_rate;
640        $comment       = __ "Bitrate too high, limited";
641    }
642
643    if (    $title->tc_video_codec =~ /^VCD$/
644        and $title->tc_video_bitrate_mode ne 'manual' ) {
645        $video_bitrate = $self->vcd_video_rate;
646        $comment       = __ "VCD has fixed rate";
647    }
648
649    if ($comment) {
650        $self->add_to_sheet(
651            {   label    => $comment,
652                operator => "=",
653                value    => $video_bitrate,
654                unit     => "kbit/s",
655            }
656        );
657    }
658
659    return $video_bitrate;
660}
661
662sub calc_video_size_from_bitrate {
663    my $self = shift;
664
665    my $title = $self->title;
666
667    my $video_bitrate = $title->tc_video_bitrate_manual;
668    my $video_bpp     = $title->tc_video_bpp_manual;
669    my ( $width, $height ) = $title->get_effective_ratio( type => "clip2" );
670
671    # pixel per second
672    my $pps = $title->frame_rate * $width * $height;
673
674    if ( $title->tc_video_bitrate_mode eq 'bpp' ) {
675        $video_bitrate = int( $video_bpp * $pps / 1000 );
676        $video_bitrate = 100 if $video_bitrate < 100;
677        $video_bpp     = sprintf( "%.3f", $video_bpp );
678        $self->add_to_sheet(
679            {   label    => __ "Manual BPP setting",
680                operator => "=",
681                value    => $video_bpp,
682                unit     => "bpp",
683            }
684        );
685        $self->add_to_sheet(
686            {   label    => __ "Resulting Video Bitrate",
687                operator => "~",
688                value    => $video_bitrate,
689                unit     => "kbit/s",
690            }
691        );
692        $video_bitrate = $self->calc_video_bitrate_limit(
693            video_bitrate => $video_bitrate, );
694    }
695    else {
696        $video_bpp = $video_bitrate * 1000 / $pps if $pps != 0;
697        $video_bpp = sprintf( "%.3f", $video_bpp );
698        $self->add_to_sheet(
699            {   label    => __ "Manual video bitrate setting",
700                operator => "=",
701                value    => $video_bitrate,
702                unit     => "kbit/s",
703            }
704        );
705        $video_bitrate = $self->calc_video_bitrate_limit(
706            video_bitrate => $video_bitrate, );
707        $self->add_to_sheet(
708            {   label    => __ "Resulting BPP",
709                operator => "~",
710                value    => $video_bpp,
711                unit     => "bpp",
712            }
713        );
714    }
715
716    my $video_size = sprintf( "%.2f",
717        $video_bitrate * $self->runtime * 1000 / 1024 / 1024 / 8 );
718
719    $self->add_to_sheet(
720        {   label    => __ "Resulting Video Size",
721            operator => "=",
722            value    => $video_size,
723            unit     => "MB",
724        }
725    );
726
727    $self->set_video_bitrate($video_bitrate);
728    $self->set_video_bpp($video_bpp);
729    $self->set_video_size($video_size);
730
731    1;
732}
733
734sub calc_file_size {
735    my $self = shift;
736
737    my $file_size
738        = $self->video_size + $self->audio_size + $self->cont_overhead_size
739        + $self->other_size;
740
741    $self->add_to_sheet(
742        {   label    => __ "Resulting File Size",
743            operator => "=",
744            value    => $file_size,
745            unit     => "MB",
746        }
747    );
748
749    $self->set_file_size($file_size);
750
751    1;
752}
753
754sub calc_other_size {
755    my $self = shift;
756
757    my $other_size = $self->vobsub_size;
758
759    $self->set_other_size($other_size);
760
761    1;
762}
763
764sub calculate {
765    my $self = shift;
766
767    my $title = $self->title;
768
769    if ( $title->tc_video_bitrate_mode eq 'size' ) {
770        return $self->calculate_video_bitrate;
771    }
772    else {
773        return $self->calculate_with_manual_bitrate;
774    }
775}
776
777sub calculate_video_bitrate {
778    my $self = shift;
779
780    # init sheet
781    $self->set_sheet( [] );
782
783    # 1. frames and runtime
784    $self->calc_frames_and_runtime;
785
786    # 2. target size
787    $self->calc_target_size;
788
789    # 3. (S)VCD addition? (probably changes target_size)
790    $self->calc_svcd_overhead;
791
792    # 4. Audio tracks
793    $self->calc_audio_size_and_bitrate( operator => "-" );
794
795    # 5. vobsub size
796    $self->calc_vobsub_size( operator => "-" );
797
798    # 7. AVI / OGG overhead
799    $self->calc_container_overhead( operator => "-" );
800
801    # 6. resulting video size
802    $self->calc_video_size_and_bitrate;
803
804    # 8. calculate real disc size (inkl. vcd addition)
805    $self->calc_disc_size;
806
807    # 9. calculate other size
808    $self->calc_other_size;
809
810    # 10. calculate final file size
811    $self->calc_file_size;
812
813    return $self->video_bitrate;
814}
815
816sub calculate_with_manual_bitrate {
817    my $self = shift;
818
819    # init sheet
820    $self->set_sheet( [] );
821
822    # 1. frames and runtime
823    $self->calc_frames_and_runtime;
824
825    # 2. resulting video size, bitrate or bpp
826    $self->calc_video_size_from_bitrate;
827
828    # 3. Audio tracks
829    $self->calc_audio_size_and_bitrate( operator => "+" );
830
831    # 4. vobsub size
832    $self->calc_vobsub_size( operator => "+" );
833
834    # 5. AVI / OGG overhead
835    $self->calc_container_overhead( operator => "+" );
836
837    # 6. calculate real disc size (inkl. vcd addition)
838    $self->calc_disc_size;
839
840    # 7. calculate other size
841    $self->calc_other_size;
842
843    # 8. calc target size as sum of all calculated sizes
844    $self->calc_file_size;
845
846    return $self->video_bitrate;
847}
848
8491;
850