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 | |
---|
11 | package 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 | |
---|
169 | 1; #return true |
---|
170 | |
---|
171 | # vim:ts=4:sw=4:ai:et:si:sts=4 |
---|