Ticket #2976: X264.pm

File X264.pm, 6.8 KB (added by devsk, 17 years ago)

a new module for doing x264 encoding with mencoder

Line 
1#
2# $Date: 2006-04-14 13:45:22 -0700 (Fri, 14 Apr 2006) $
3# $Revision: 245 $
4# $Author: xris $
5#
6#  export::mencoder::X264
7#  Copied from transcode.pm
8#  and modified by Ryan Dearing <mythtv@mythtv.us>
9#
10
11package export::mencoder::X264;
12    use base 'export::mencoder';
13
14# Load the myth and nuv utilities, and make sure we're connected to the database
15    use nuv_export::shared_utils;
16    use nuv_export::cli;
17    use nuv_export::ui;
18    use mythtv::db;
19    use mythtv::recordings;
20
21# Load the following extra parameters from the commandline
22    add_arg('quantisation|q=i', 'Quantisation');
23    add_arg('a_bitrate|a=i',    'Audio bitrate');
24    add_arg('v_bitrate|v=i',    'Video bitrate');
25    add_arg('multipass!',       'Enable two-pass encoding.');
26
27    sub new {
28        my $class = shift;
29        my $self  = {
30                     'cli'      => qr/\bx264\b/i,
31                     'name'     => 'Export to X264 (using mencoder)',
32                     'enabled'  => 1,
33                     'errors'   => [],
34                     'defaults' => {},
35                    };
36        bless($self, $class);
37
38    # Initialize the default parameters
39        $self->load_defaults();
40
41    # Verify any commandline or config file options
42        die "Audio bitrate must be > 0\n" unless (!defined $self->val('a_bitrate') || $self->{'a_bitrate'} > 0);
43        die "Video bitrate must be > 0\n" unless (!defined $self->val('v_bitrate') || $self->{'v_bitrate'} > 0);
44        die "Width must be > 0\n"         unless (!defined $self->val('width')     || $self->{'width'} =~ /^\s*\D/  || $self->{'width'}  > 0);
45        die "Height must be > 0\n"        unless (!defined $self->val('height')    || $self->{'height'} =~ /^\s*\D/ || $self->{'height'} > 0);
46
47    # VBR, multipass, etc.
48        if ($self->val('multipass')) {
49            $self->{'vbr'} = 1;
50        }
51        elsif ($self->val('quantisation')) {
52            die "Quantisation must be a number between 1 and 31 (lower means better quality).\n" if ($self->{'quantisation'} < 1 || $self->{'quantisation'} > 31);
53            $self->{'vbr'} = 1;
54        }
55
56    # Initialize and check for mencoder
57        $self->init_mencoder();
58
59    # Any errors?  disable this function
60        $self->{'enabled'} = 0 if ($self->{'errors'} && @{$self->{'errors'}} > 0);
61    # Return
62        return $self;
63    }
64
65# Load default settings
66    sub load_defaults {
67        my $self = shift;
68    # Load the parent module's settings
69        $self->SUPER::load_defaults();
70    # Not really anything to add
71    }
72
73# Gather settings from the user
74    sub gather_settings {
75        my $self = shift;
76    # Load the parent module's settings
77        $self->SUPER::gather_settings();
78    # Audio Bitrate
79        $self->{'a_bitrate'} = query_text('Audio bitrate?',
80                                          'int',
81                                          $self->val('a_bitrate'));
82    # VBR options
83        if (!$is_cli) {
84            $self->{'vbr'} = query_text('Variable bitrate video?',
85                                        'yesno',
86                                        $self->val('vbr'));
87            if ($self->{'vbr'}) {
88                $self->{'multipass'} = query_text('Multi-pass (slower, but better quality)?',
89                                                  'yesno',
90                                                  $self->val('multipass'));
91                if (!$self->{'multipass'}) {
92                    while (1) {
93                        my $quantisation = query_text('VBR quality/quantisation (1-31)?', 'float', $self->val('quantisation'));
94                        if ($quantisation < 1) {
95                            print "Too low; please choose a number between 1 and 31.\n";
96                        }
97                        elsif ($quantisation > 31) {
98                            print "Too high; please choose a number between 1 and 31\n";
99                        }
100                        else {
101                            $self->{'quantisation'} = $quantisation;
102                            last;
103                        }
104                    }
105                }
106            }
107        # Ask the user what audio and video bitrates he/she wants
108            if ($self->{'multipass'} || !$self->{'vbr'}) {
109                $self->{'v_bitrate'} = query_text('Video bitrate?',
110                                                  'int',
111                                                  $self->val('v_bitrate'));
112            }
113        }
114    # Query the resolution
115        $self->query_resolution();
116    }
117
118    sub export {
119        my $self    = shift;
120        my $episode = shift;
121    # Build the mencoder string
122        my $params = " -ovc x264 -vf scale=$self->{'width'}:$self->{'height'}"
123        #my $params = " -ovc x264"
124        #." -N 0x55" # make *sure* we're exporting mp3 audio
125
126        #." -oac mp3lame -lameopts vbr=3:br=$self->{'a_bitrate'}"
127                    ;
128       # unless ($episode->{'finfo'}{'fps'} =~ /^2(?:5|4\.9)/) {
129       #    $params .= " -J modfps=buffers=7 --export_fps 23.976";
130       # }
131    # Dual pass?
132        if ($self->{'multipass'}) {
133        # Add the temporary file to the list
134            push @tmpfiles, "/tmp/xvid.$$.log";
135        # Back up the path and use /dev/null for the first pass
136            my $path_bak = $self->{'path'};
137            $self->{'path'} = '/dev/null';
138        # First pass
139            print "First pass...\n";
140            $self->{'mencoder_xtra'} = "  $params"
141                                       ." -passlogfile /tmp/xvid.$$.log"
142                                       ." -oac copy"
143                                       ." -x264encopts bitrate=$self->{'v_bitrate'}:pass=1:threads=3:subq=4:bframes=3:b_pyramid:weight_b:psnr:turbo=1 ";
144            $self->SUPER::export($episode, '', 1);
145        # Restore the path
146            $self->{'path'} = $path_bak;
147        # Second pass
148            print "Final pass...\n";
149            $self->{'mencoder_xtra'} = " $params"
150                                       ." -oac mp3lame -lameopts cbr:br=$self->{'a_bitrate'}"
151                                       ." -passlogfile /tmp/xvid.$$.log"
152                                       ." -x264encopts bitrate=$self->{'v_bitrate'}:pass=2:threads=3:psnr:subq=6:frameref=5:me=umh:weight_b:bframes=3:b_pyramid ";
153        }
154    # Single pass
155        else {
156            $self->{'mencoder_xtra'} = " $params"
157                                       ." -oac mp3lame -lameopts cbr:br=$self->{'a_bitrate'}";
158            if ($self->{'quantisation'}) {
159                $self->{'mencoder_xtra'} .= " -x264encopts crf=".$self->{'quantisation'};
160            }
161            else {
162                $self->{'mencoder_xtra'} .= " -x264encopts threads=3:subq=6:me=umh:frameref=5:bframes=3:b_pyramid:weight_b:bitrate=$self->{'v_bitrate'} ";
163            }
164        }
165    # Execute the (final pass) encode
166        $self->SUPER::export($episode, '.avi');
167    }
168
1691;  #return true
170
171# vim:ts=4:sw=4:ai:et:si:sts=4