h264enc-9.3.7~dfsg/0000755000175000017500000000000011563751574013643 5ustar alessioalessioh264enc-9.3.7~dfsg/doc/0000755000175000017500000000000011234673530014376 5ustar alessioalessioh264enc-9.3.7~dfsg/doc/AUTHORS0000644000175000017500000000100111215474717015443 0ustar alessioalessio - Grozdan Nikolov aka microchip Author/maintainer/developer/packager - Aymeric Roynette aka Wedge Suggestions/code improvements/Slackware packager - Marcus Heuser Arch Linux packager - Conrad Meyer Fedora packager - Justin Poirier Bug tracker/testing - Harry Gunnarsson Bug tracker/testing - Quantin Jackson Bug tracker/testingh264enc-9.3.7~dfsg/doc/ChangeLog0000644000175000017500000040136011563751645016165 0ustar alessioalessio2011-05-15 - h264enc 9.3.7 * Removed the ssim and psnr options from the presets. Should only be used for benchmarking 2011-04-03 - h264enc 9.3.6 * Fixed the subtitles function which got broken when the get_selection_func() function got introduced 2011-03-29 - h264enc 9.3.5 * Added support for setting the crop rounding value 2011-03-09 - h264enc 9.3.4 * Fix option 4 and 5 of the video_deblock_func() function. Wrong vars used 2011-02-21 - h264enc 9.3.3 * Fixed a bug in directory batch mode were wrong conditional was used to check for the DEFOUTPUT variable * Display which file is currently being processed in batch mode * Check only for files while in batch mode * Do not exit if user types an incorrect answer to y/n questions. Instead, ask the question again. Patch by Jan-Hendrik Peters and friends 2011-01-08 - h264enc 9.3.2 * Use -demuxer lavf when trying to get the video length for bitrate calculation for a target file size. Should be more reliable on M2TS/TS files * Add support for the delogo filter. Patch by Haiko Michelfeit Config file version is bumped to 19 * Updated copyright dates 2010-12-05 - h264enc 9.3.1 * Fix for the custom preset (cp) option. 2010-11-26 - h264enc 9.3.0 * Remove double $HOME variable in the -scan option 2010-10-29 - h264enc 9.2.9 * Fix typo in the backup_file_func(): exisiting -> existing * Workaround multichan FAAC encoding. FAAC somehow does not like multichan PCM from MPlayer but it does if one treats it as raw using -P in FAAC. Nero/FLAC/Vorbis have no issues, though. Go figure * Added support for setting subtitle codepage during hardcoding of external subs * Added support for the audio equalizer filter. This updates the config file version to 18 * Removed 'time' requirement 2010-09-16 - h264enc 9.2.8 * Workaround mencoder stupidity. With recent versions of mencoder that have subs enabled by default (who came up with that great idea?), in case the user selects to dump a sub for importing into mkv/mp4, during multipass encoding the first sub will always get hardcoded due to missing -nosub option in the 2nd and 3rd pass code. This is only valid for multipass encodes so people using one pass modes (-1p, -qp or -crf) are safe. 2010-09-15 - h264enc 9.2.7 * Small update to the -scan option. Just check if input file is there, regardless if user provides the full path or not * Enable trellis in some presets that use CAVLC 2010-08-23 - h264enc 9.2.6 * Fixed a syntax error in the iphq preset 2010-08-21 - h264enc 9.2.5 * Update QuickTime & iPhone presets. Patch by gongloo 2010-07-21 - h264enc 9.2.4 * Typo fix in the display_quality_preset_func(); verslow -> veryslow. As this is an informative function, it does not affect the encoding configuration * Force -nosub option in case subtitles are skipped. This is to prevent auto-loading of subs 2010-06-25 - h264enc 9.2.3 * Added support for x264's preset, tune and profile options. This adds two additional optional args [-t (for tune) and -pf (for profile)] which can only be used with an x264 preset, not with the built-in script presets. If used with those, these args will be ignored. Examples on how to use x264 presets (which is also explained in the -help option) h264enc -crf -p slow h264enc -crf -p slow -t film h264enc -crf -p slow -pf main h264enc -crf -p slow -t film -pf high One can also switch the -t and -pf options, eg: h264enc -crf -p slow -pf high -t film * Updated the man page 2010-05-15 - h264enc 9.2.2 * Small bugfix in the get_devices_func() function; script exits when user hits enter to accept default device * Remove AVI menu entry as supported container when using FAAC for audio encoding 2010-04-29 - h264enc 9.2.1 * Reworked a bit the audio channels decode/output function. This function also got renamed from audio_channels_func() to audio_channels_decode_func() * Added support for the audio channels filter which can be used to add/remove/route channels This updates the config file to version 17 and adds variable ALLOW_AUD_CHANNELS * Bugfix: audio filters were not inserted when doing 1-pass encodes 2010-04-24 - h264enc 9.2.0 * Switch to using external FAAC encoder to work around an issue in mkvmerge where it flags AAC audio taken from an AVI as being Main profile regardless if LC profile is used for encoding or not. Problem noticed & reported by benpro. This updates the config file to version 16 and requires FAAC to be installed. * Same small cleanups * Updated the man page 2010-03-28 - h264enc 9.1.9 * Replaced sed with awk for checking available disk space. Should work better on FreeBSD systems. Patch by ennob from doom9 * Updated interlace options and presets to support the latest x264 from git. Note that due to these changes, h264enc's presets are incompatible with older x264 versions so please upgrade to latest x264 from git! * Small update to the preset.cfg file 2010-03-18 - h264enc 9.1.8 * Small bugfix: keyint and keyint_min weren't passed on to MEncoder when using some presets 2010-03-16 - h264enc 9.1.7 * Space escaped some previously missed variables * Use one variable in the presets (x264params) for all MEncoder x264 encoding options. Reduces some code and simplifies things a bit * Updated the preset.cfg file to support the "one variable for all x264 encoder opts" Note: those using custom preset files for encoding should read the preset.cfg file in the doc dir and adapt their existing preset files to be compatible with the changes. Previous older custom presets written by users will not work with this and future versions of h264enc! 2010-02-18 - h264enc 9.1.6 * Added new veriable 'DEFOUTPUT' to the config file which can be used to set a default output directory. This updates the config to version 15 * Modified the set_output_filename_func() function to support the above variable. - If the DEFOUTPUT variable is empty, user can either provide just the output name for the encode (in this case the script assumes $HOME as output dir), or the full path and output name, which in this case the script will create the output dir if it's not present or will do a write test when the dir is present to see if it's writable by the user. If creation of output dir or the write test fails, the script exits with a notice. - If the DEFOUTPUT variable contains a custom output dir, the script will test for it and create it if it's not present. If creation fails, the script exits with a notice. If the dir is present, the script will do a write test to see if the custom dir is writable. If not, the script exits with a notice. - The DEFOUTPUT variable can be overwritten on the command line. This means that if user has set a custom output dir in the DEFOUTPUT variable but provides a path when asked on the command line, that path will be used instead of the one in the DEFOUTPUT variable. The script then will either check and create the provided output dir on the command line (if that dir is not present) or will do a write test if the dir is present. Upon failure of creation or write test, the script exits with a notice. If no path is provided on the command line but only the output name for the encode, the script will use the one set in the DEFOUTPUT variable. 2010-01-30 - h264enc 9.1.5 * Reduced duplication in the audio encode exporting code by moving it inside functions * Reduced duplication in the MKV/MP4/TS/OGM exporting code by moving it inside functions * Reduced duplication in the code that prints some information before encoding starts * Various minor code improvements 2010-01-21 - h264enc 9.1.4 * Set default H.264 level to 'auto' and also accept integer numbers as levels in addition to accepting fixed point ones, ie both 41 and 4.1 are now accepted as valid levels * Renamed the rmconf() function to rmtemp() * Moved creation of temp dir, the interrupt_func() and rmtemp() functions at the beginning of the script * Fixed a bug in the DVD part of the -scan option where lsdvd doesn't get a valid device passed. Bug was introduced due to changes in the new get_devices_func() function * Reduced duplication in the mencoder_opts() function * Various small code improvements 2010-01-19 - h264enc 9.1.3 * Made the TEMPDIR variable escape spaces in directory names * Small update to the mkvtags_func() function * Removed the -a52drc option for AC3 encoding * Added new x264 intra_refresh option to the script and the preset.cfg file * Added two new variables, DVD_DEVICE and CDROM_DEVICE, to the config file where user can set a default block device to encode from. This updates the config file to version 14 * Merged the get_dvd_devices_func() and get_vcd_devices_func() functions into a new one called get_devices_func() 2009-12-23 - h264enc 9.1.2 * Fixed a severe bug that can cause in some cases severe data loss when using a custom temp directory. It manifests itself when using a 'top' directory as custom temp directory such as a partition mount point or even the user's home directory. In such cases, the top directory will be deleted upon script termination or when encoding finishes, resulting in possible massive data loss due to rm -rf $TEMPDIR if TEMPDIR was set to, for example, /home/username or points to a mount point or another directory that may be important to the user. From now on, always use a job directory inside the one set in the TEMPDIR variable so it'll only delete the job directory and not its parent one, minimizing possibility of a data loss disaster * Set nomixed_refs for the iphq/iphhq presets 2009-12-10 - h264enc 9.1.1 * Disabled weightp for the AppleTV presets * Added new option sliced_threads present in latest x264 from git * Enabled b_pyramid for some presets that use mbtree as it now works with mbtree * Updated the preset.cfg file. Added sliced_threads option * Changed all video ALLOW_* variables in the config file to ALLOW_VID_* * When using dd to dump a DVD to an ISO, use options noerror,sync and a bs size of 2048 * Added support for sending mails. This requires the 'mailx' program and a valid .mailrc file in the home directory. Mail notification can be enabled in the config file of h264enc which also offers an example of a gmail setting for .mailrc * Bumped config file version to 13 * Updated copyright dates 2009-11-09 - h264enc 9.1.0 * Implemented a simple telecine detector for NTSC DVDs. Currently it's a dumb solution which can't distinguish between hard telecine and interlacing but it's enough to detect soft telecine and mixed progressive/telecine content which is more common * Simplified the FPS detection code * Update to all presets: added new weightp x264 option. This requires latest x264 revision from git * Updated the preset.cfg file. Added weightp option * Small general code improvements and cosmetics 2009-11-04 - h264enc 9.0.9 * Replaced a few if conditionals with case statements in the neroaac_audio_func() function * Sed a comma at the end of resolution detection in case we're dealing with TS files. The default TS demuxer in MPlayer has a comma at the end of the resolution info which results in errorneous behavior in the bc calculation * Simplified the resolution detection code * Some small cleanups 2009-10-19 - h264enc 9.0.8 * Force stereo audio for Nero HE-AACv2 as it doesn't support anything else, thus it results in failure if user tries to encode with more than two channels. This updates the audio_channels_func() function and also adds a small new independent one called neroaac_hev2_func() which only sets the channels to two if the channels array variables are empty, as is the case when the user did not set the channels * Small improvements to the ABR/VBR default audio bitrates for the neroAacEnc encoder. Base the default bitrates on the chosen AAC profile, i.e. if user chooses HE-AACv1, default bitrate will be 55 kbps or in case of quality-based VBR encoding a value of 0.22. For LC-AAC and HE-AACv2, default bitrates and quality values will be 96 kbps or 0.35 and 25 kbps or 0.11, respectively. Note that this assumes the input audio is stereo so if it's anything else than that, it's up to the user to decide on bitrates or quality values * Set default to a capital letter in questions where one needs to answer with y or n * Update to all presets: updated the b_pyramid option to use the new args none/strict/normal present in latest x264 revision. Note that this requires both latest MPlayer from SVN and latest x264 revision from git * Small b_pyramid update to the preset.cfg file 2009-10-17 - h264enc 9.0.7 * Added new function video_subtitles_align_func() for subtitle alignment control. Requested by blaz on doom9.org forum. * Added new x264 option 'constrained_intra' to the preset.cfg file. * Added detection of VFR content (1000 fps as reported by MPlayer). * Added X264_VERSION and MKVMERGE_VERSION entries to the mkvtags_func() function. * Simplified a bit the audio exporting code for the first track. 2009-09-24 - h264enc 9.0.6 * MP3 (MPEG1 Layer 3) only supports sample frequencies of 32, 44.1 and 48 kHz so restrict to those only in the audio_resample_func() function * Set default for the pp7 deblocker to 3 * Fixed example typo in the DVD chapters code * Insert the ilpack filter before the scaler to correctly align chroma channels when preserving interlacing * Added AUDIO_CODEC_TRACK[1|2|3], AUDIO_LANGUAGE_TRACK[1|2|3] and H264ENC_PARAMETERS entries to the mkvtags_func() function * Enabled adaptive transform for the AppleTV HQ preset (atvhq) * Improved checking the availability of block devices * Added option 'global_header' to the preset.cfg file 2009-09-16 - h264enc 9.0.5 * Small bugfix: setting the H.264 level for the fghq preset wasn't possible * Small bugfix: the counter in set_output_filename_func() didn't increase itself * Added SOURCE, VIDEO_FILTERS, AUDIO_FILTERS_TRACK[1|2|3], ENCODER and X264_PARAMETERS entries to the mkvtags_func() function 2009-09-12 - h264enc 9.0.4 * Use only lowercase words in all case statements that deal with the input source * Some small improvements to the exit info in the audio code * Placed the -passlogfile option inside the PASSLOG variable * Set psy_rd to 0.3 for the Anime presets * Allow setting the H.264 level for the PC presets to "auto" so libx264 will decide itself which level to use based on options and resolution used * Added support for 2-pass Nero AAC audio encoding. Note that 2-pass is only supported by ABR/CBR encoding and ensures that the output quality is constant (like VBR) while also ensuring that a specified output bitrate is achieved (like CBR). Requested by punlo on doom9.org 2009-09-06 - h264enc 9.0.3 * Fixed a typo in the man page, MEnocder -> MEncoder * Small improvement to how the MKV XML tagging file gets exported. Also improved the XML formatting and added COMMENT string with text "Tagged by h264enc $version" * Added comment tag for MP4 and OGM with the same text as above * Small update to the video_deinterlace_func() function's menu * Add comment header with dates to batch files 2009-09-04 - h264enc 9.0.2 * Added new option sync_lookahead available in latest x264 git and updated the preset.cfg file * Added support for the noise video filter. This change updates the config file to version 12. Also, encoding priority now defaults to a nice value of 10 in the config file * Moved out the code which checks and backups/renames a file if it has the same name as the output provided by the user to a separate function called backup_file_func() and also improved it so that if there's already an existing backup file, the new one will increase its count number by one thus there's no more overwriting being done anymore. The same thing applies to existing chapter files and DVD subs * Added support for Year and Genre metadata tagging for the MKV/MP4/OGM containers. For MKV, the genre and year is set globally using an automatically generated XML file. MP4 uses the iTunes tagging and OGM the comment space * Updated the man page 2009-09-01 - h264enc 9.0.1 * Simplified the audio_channels_func() function a bit * Merged the QP and CRF settings * Increased rc_lookahead a bit for the ehq, uhq and ihq presets * Improved detection of DVD audio language codes. We now specifically grep for the language word and then print the 2nd positional which gives us the language code. It works more reliably if the DVD does not report its language code for the audio track(s) so if this is the case, we fall back to undefined language. The previous code fails in such cases due to the printing of the 8th positional which will print the "aid:" part when there's no language code after the "language:" word, resulting in MKV/MP4 muxing failures. Reported by WalterK from doom9.org * Moved the code that deals with DVD subs/cover files/metadata info/chapters and external subs for the MP4 container before its audio code * Added slicing to the Blu-ray and AVCHD presets. It increases compliancy with the Blu-ray specs. Slicing is only available in the latest x264 from git so please upgrade if you intend to use the Blu-ray/AVCHD presets * Added new options 'slices', 'slice_max_size' and 'slice_max_mbs' to the preset.cfg file * Fixed chapters import for the OGM container. Missing '@' before the chapters input file results in the file not being imported * Added support for audio language metadata info for the OGM container * Small improvements to how chapters information is added to the output file name 2009-08-15 - h264enc 9.0.0 * Renamed presets f9 and f9hq to fl and flhq * Added new preset 'fghq' specifically optimized for preserving film grain * Removed duplicate videofilters variable. This removes the check for the tfields filter as now deinterlacing will always be done after cropping (which also speeds up things a bit) so the crop filter will never complain about crop area being outside of the original if tfields is used. It also reduces filters maintenance a bit * Turn soft-clipping on in the volume audio filter * Use aq_mode=1 for presets that have mbtree enabled as it usually does better on fades than aq_mode=2 * Updated the man page 2009-08-11 - h264enc 8.9.9 * Reduced the amount of if conditional iterations for setting the scaler interlace variable * Print full path of the output file(s) at the end of encoding * 10L: forgot to enable MB tree for the anihq preset * Replaced variable CONFIGDIR with TEMPDIR. This change updates the config file to version 11 * Fixed some spacings issues by moving around some echo's * Simplified the sample encoding code. Reduced some code duplication * Upped psy_rd from 0.6 to 0.8 2009-08-07 - h264enc 8.9.8 * Added support for the audio panning filter. This change also updates the config file to version 10 * Simplifications to the audio_filters_func() and audio_filters_var_func() functions * Moved the audio filters functions after the audio codec ones * Fixed a bug in the audio_channels_func() function for the AAC codec. If user just hits return to accept the default AAC codec, the channels function was not called due to missing "" in the first case statement of that function * Enabled MB tree (macroblock tree ratecontrol) for the high quality presets and disabled b_pyramid for presets that have mbtree enabled as it currently doesn't support it. Note that mbtree produces a large passlog file when ran in 2-pass mode but can increase quality anywhere between 2-70%, depending on the content. mbtree is only available in latest x264 git so please upgrade * Added new options mbtree, rc_lookahead and nopsy to the preset.cfg file 2009-08-01 - h264enc 8.9.7 * Added new option -mfr which calculates the maximum allowed frame references within DPB (Decoded Picture Buffer) limits for different H.264 levels and resolutions * Call the track_echo_func() function inside the select_audio_codec_func() one. Removes pointless duplication * Don't call mplayer twice in the 2nd/3rd audio track code just to get the audio codec. Also removed a pointless case statement * Allow users to set the H.264 level when using the standard PC presets * Fixed a few typos in the preset.cfg file * Updated the man page 2009-07-30 - h264enc 8.9.6 * Increased subq to 10 (QP-RD) for the IHQ preset. Requires latest x264 from git. Also lowered frameref from 16 to 8 and bframes from 10 to 7 * Add example on how to encode only specific DVD chapters. Some people keep bugging me about this while it's actually very simple 2009-07-24 - h264enc 8.9.5 * Switched to the new Auto-variance AQ (aq_mode=2) for all presets. This requires latest x264 revision from git so please upgrade! * Decreased frame references for all iPod presets to 1 and increased subq to 8 for the HQ iPod presets * Minor improvments to the set_output_filename_func() function * Merged the audio code of the portable device presets. Moderately reduces code duplication in the audio functions calling code * Added two new presets (ag1 and ag1hq) for Android G1 devices. This brings the total presets count to 60 * Added support for the new gradfun debanding video filter. Although mostly recommended for playback due to the fact that encoding tends to bring back banding, it can be useful to deband input sources which show pretty bad and very noticable banding effects before passing the content to the encoder. The gradfun filter is only available in MPlayer SVN. This also adds a new variable ALLOW_DEBAND to the config file where one can enable or disable this filter * Added a small while loop to the video_crop_func() function which will keep asking the user for new crop values until he's satisfied with them. Patch by elektronaut from Doom9.org * Added a new variable PRIORITY to the config file which can be used to set a global priority nice value for the encoding process. The values one can use are between (and including) -20 and 19. However, if the script detects that the variable has a negative nice value set and the script is being executed with regular user privileges, it will print a notice and exit. This change updates the config file to version 9 * Updated the man page 2009-07-08 - h264enc 8.9.4 * Added detection for E-AC3 audio for stream copy and updated the MKV/TS muxing code to support it * Added new option -spr which calculates the Storage and Pixel Aspect Ratios (SAR/PAR) for various resolutions * Display the amount of chapters each DVD title has when scanning for titles * Display total pixels, SAR and PAR when scanning a file/vcd with the -scan option * Added --no-chapters mkvmerge option for audio files encoded by neroAacEnc so that chapters won't be copied over to the MKVs from these files * Small update to the install script * Updated the man page. Fix some small cosmetic issues, patch by Alessio Treglia 2009-07-01 - h264enc 8.9.3 * Fallback to undefined audio language in the AUDLANG[$i] variables if we detect unknown language from MPlayer's output * Added support for bitrate-based ABR Vorbis encoding in addition to quality-based VBR. ABR mode in Vorbis resembles quality-based VBR except the encoder averages a given nominal bitrate * Updated the Vorbis part of the video bitrate calculation code * Added new function ratio_and_pixels_func() which calculates and displays the Storage Aspect Ratio (SAR), Pixel Aspect Ratio (PAR) and total pixels from resolution * Bugfix for track 1 in the internal audio encoding code. If using aacplusenc to encode audio, the case statement had a wrong selection value (aac++ instead of aac+) resulting in displaying a failed message and forcing an exit even though the encoding may have succeeded * Simplifications to the internal audio encoding code which reduce code duplication * Small fixes to the video bitrate calculation code * Small tuning to the Blu-ray/AVCHD presets * Small cleanups 2009-06-26 - h264enc 8.9.2 * Set default audio codec for the Blu-ray/AVCHD presets to AC3 * Bugfix to the OGM muxing code. Second/third track were ignored when one selects AC3 audio * Added keyint, keyint_min, nr and interlaced variables to the custom preset skeleton file 'preset.cfg' * Moved the AACTYPE variable to the neroaac_audio_func() function and updated the specific parts that use it in the MKV/MP4 muxing code * Do not automatically detect audio sample rate in directory batch encoding mode. Only do it for single file/dvd/vcd encodings as in batch mode, detection will only print the sample rate of the first file but not the other files in the directory so this can mislead the user in thinking that all files in the directory have the sample rate reported by the script. It is possible to implement sample rate detection for all files but since we don't know how many files are in the directory, I do not want the user to see a full screen with sample rate info of each file if he deals with a directory with a few hundreds or more files in it * Disallow autocropping, if enabled in the config file, for directory batch encodings * Small reordering to the MP4 muxing code * Small update to the install script * Updated the man page 2009-06-24 - h264enc 8.9.1 * Removed audio filters for the 1st pass in 2-pass encoding and for the 1st & 2nd pass of a 3-pass encoding. They are useless here and it's something I've overlooked for a long time. Thanks to Mat Kanner for noticing and reporting * Some small changes to the way we pass FPS to MP4Box * Added support for MP4 hinting for RTP/RTSP sessions * Simplifications to the external subs importing code. Also fixed a bug in the MP4 subs importing code; missing -add option in the MP4SUBS variable will make MP4Box fail * Merged the MKV tagging code with the muxing one * Added support for detection of WMA audio for stream copy * Added support for per track audio codecs for DVD encodings. The user can now select if he wishes for each track a different audio codec. Mixing audio stream copy with compression codecs is also possible * Updated all relevant audio functions to support per track audio codecs * Updated the bitrate calculation code to support per track audio codecs * Updated the container muxing code to support the above audio changes 2009-06-22 - h264enc 8.9.0 * Small improvement to the MKV/MP4 tagging code: support audio tagging of single file encodes with audio stream copy * Use array variables ${SUBFILE[2]} and ${SUBFILE[3]} instead of ${OUTPUT%.*}_sub2 and ${OUTPUT%.*}_sub3 when dumping the second/third DVD subtitles * Simplified the MKV cover art importing code * Small improvements to video bitrate calculation with audio stream copy * Use only one named pipe for all tracks when encoding to neroAAC/AAC+/Vorbis/FLAC * Major audio code restructuring and partial rewrite. Converted virtually all audio code variables to array variables. This allows for easy extensibility and much less code duplication. It's very easy now to add as much audio tracks as one may want to the code with very little changes/updates needed to the containers code. Also the current changes may allow very easily to support different audio codecs per track in the future * Added support for a third DVD audio track * Updated the video bitrate calculation for target size to support the above audio changes * Converted most of the variables in the video_subtitles_func() function to arrays. This moderately reduces some code duplication * Updated the container muxing/tagging code to support the above audio changes * Use external flac encoder to encode to FLAC audio as doing it through mencoder is terribly broken. This updates the config file to version 8 and adds the 'flac' encoder as dependency * Set the default resampling filter to lavcresample as the other one gives problems when encoding to FLAC audio and resampling 2009-06-19 - h264enc 8.8.7 * Simplifications to the MKV tagging code which reduces some code duplication * Bugfix: FAAC acodec2 variable has wrong mpeg value. Must be mpeg=4 instead of mpeg4. This results in failure in encoding of the second audio track when one selects FAAC as encoder * Bugfix: FLAC audio was ignored for the second track due to missing value in the selection of the case statement * Added support for tagging of MKV files when doing a directory batch encoding * Replaced the IMPSUB1, IMPSUB2 and IMPSUB3 variables, used to import subs when input type is file/directory/vcd, by array variables EXTSUB[1], EXTSUB[2] and EXTSUB[3]. This allows for less code duplication as these array variables are shared by all input types (including DVD) and thus we only need to do a small loop and add their values if not empty to the MKVSUBS, MP4SUBS and OGMSUBS variables * Use as temp directory $HOME/.h264enc/job * Added new function audio_stream_copy_func() which will print a warning that audio stream copy in directory batch encoding mode is not recommended unless the user is certain that the files have a supported audio codec by the MKV/MP4/OGM/TS containers * Group audio filters under a submenu similar to how the video filters are grouped * Some small cleanups 2009-06-17 - h264enc 8.8.6 * Added support for per track audio bitrate for DVD encodings * Added support for per track audio normalization and volume adjustments for DVD encodings. Updated functions audio_volnorm_func() and audio_volume_func() * Added support for per track audio resampling for DVD encodings. Updated functions audio_resample_filters_func() and audio_resample_func() * Updated the video bitrate calculation code to support the above audio changes * Bugfix for the qt/bd/avchd presets: audio filters were not called for these presets * Added support for per track AAC profile settings (LC/HE/HEv2) when using the neroAacEnc audio encoder * Small modifications to the MKV/MP4 tagging and muxing code to support the per track neroAacEnc AAC profiles. This also includes optimizations to the way the tagging code handles different AAC profiles. If LC profile is chosen, audio will be tagged as LC-AAC (along with channels info). For HE and HEv2, audio will be tagged as HE-AACv1 and HE-AACv2 (along with channels info) respectively * Moved the MKV tagging code inside the MKV muxing code * Converted the EXTSUB1, EXTSUB2 and EXTSUB3 variables, used to import external DVD subs, to arrays so we can easily check different files for their file extensions * Only allow SRT subs as import into OGM. If another subs format is provided, the subs will be skipped. For MP4, do not allow ASS/SSA subs since it's not supported yet by MP4Box. For MKV, do not allow SUP and TTXT subs 2009-06-15 - h264enc 8.8.5 * Update to the video_subtitles_func() function: for DVD encodings, added support for importing up to three external subtitles into MKV/MP4/OGM. Also added support for hardcoding an external subtitle into the movie * Updated the MKV/MP4/OGM muxing code to support imports of external subtitles * Increased Psy RD from 0.5 to 0.6 for some presets * If dumping of the second and/or third DVD subtitle fails and user has selected to import the subs into MKV/MP4, force an exit since container conversion will fail as the muxing programs will complain about the missing subs. If no container conversion is chosen or user has chosen not to import the subs and dumping of subs fails, just continue since there's nothing critical in this case * Use mplayer -really-quiet option instead of redirection to /dev/null when dumping audio to a named pipe for neroAAC/Vorbis/AAC+ encoding * Some small updates to the man page * Updated the AUTHORS file 2009-06-12 - h264enc 8.8.4 * Replaced the --noaudio mkvmerge option with -A due to recent options changes in mkvmerge version 2.9.5. -A also works for older versions so nothing breaks here * Removed the check_outfile_func() function as its code has been added to the set_output_filename_func() function, which also has been improved * Added support for FLAC audio in MKV * Removed some code duplication in the MKV metadata tagging code 2009-06-09 - h264enc 8.8.3 * Added support for adding jpeg/png cover art files to MKV/MP4 * Added audio language meta-info for MP4 and TS files * Improved audio language meta-info for MKV files. This also adds metadata info for the second audio track * Fixed a small bug: the --aac-is-sbr mkvmerge parameter should be set to 0:1 for the second audio track when using aacplusenc as encoder 2009-06-08 - h264enc 8.8.2 * Add iTunes video title name to MP4 files 2009-05-24 - h264enc 8.8.1 * Use the same name for the log file as the output file name * Force using the libmpeg2 decoder when encoding DVDs/VCDs (works slightly better in specific cases compared to ffmpeg2) * Added support for IVTC 59.940 -> 23.976 fps * Some small code cosmetics 2009-05-12 - h264enc 8.8.0 * Added deinterlace combinations of Yadif + linear blend, linear interpolation, cubic interpolation, median deint, ffmpeg deint and lowpass 5 * Cosmetics to the help menu * Added global audio function audio_filters_func() for calling the resample, volume normalizing and volume filters * Added 16 new variables to the config file for enabling/disabling of specific audio/video filters and containers: ALLOW_FPS_CONVERSION, ALLOW_SCALER_TUNING, ALLOW_DSIZE, ALLOW_EXPAND, ALLOW_COLORSPACE, ALLOW_ASPECT, ALLOW_AUD_RESAMPLE, ALLOW_AUD_NORMALIZE, ALLOW_AUD_VOLUME, ALLOW_MKV_MUXING, ALLOW_MP4_MUXING, ALLOW_TS_MUXING, ALLOW_OGM_MUXING, ALLOW_SAMPLE_ENCODING, ALLOW_SCAN_MULTIPLE_VIDSTREAMS and ALLOW_SCAN_MULTIPLE_AUDSTREAMS, the last two are only effective on file and directory batch encodings * Updated the man page 2009-05-07 - h264enc 8.7.9 * Automatically add the shebang line to batch files and make them executable * Added new variable ALLOW_AUTOCROP to the config file which allows the user to enable or disable automatic cropping * Added MP3 presets and updated target file size code to support them (requested by Rogério Brito) * Some minor adjustments to the hq, vhq, ehq, uhq and ihq presets; decrease b-frames by one 2009-04-29 - h264ec 8.7.8 * Small bugfix: video filters variables in the config file were not respected when one chooses to encode VCDs. * Add video title meta-data for MKV and OGM when doing directory batch encodings 2009-04-28 - h264enc 8.7.7 * Optimize some variables by replacing piping to sed with VARIABLE1="${VARIABLE2%.*}.ext" * Move out the built-in -loop 1 mplayer option to the config file's MPLAYEROPTS variable * Add support for enabling/disabling specific pre/postprocessing filters in the config file. This adds 7 new variables to the config file where the user can either enable to ask questions about a specific filter or disable a specific variable, thus skipping questions about the filter * Moved the video filters code to a new function called video_filters_func(). This also reduces a bit of code duplication * Add a new option -e which allows the user to edit the config file directly from within the terminal. This adds a new variable EDITOR to the config file where the user can set his preferred text editor (defaults to nano) * Silence possible dvdxchap warnings * Updated the man page 2009-04-26 - h264enc 8.7.6 * Bugfix: missing 's' in the sed expression of the MP4OUT variable. This results in missing output file and will fail when one tries to remux to mp4 2009-04-22 - h264enc 8.7.5 * Dump first subtitle during the first pass of a multipass encode to avoid possible delay problems 2009-04-14 - h264enc 8.7.4 * Proper file extension handling for directory batch encodings * Removed workaround for bug present in old versions of tsMuxeR. Please upgrade to tsMuxeR version 1.9.1(b). The previous one is no longer supported * Optimizations to the Blu-ray and AVCHD muxing code * Add video fps value to the tsMuxeR meta file for TS/Blu-ray/AVCHD muxing * User request: add an mplayer variable to the config file where the user can set custom mplayer options. One should be careful which options he uses as some of them may introduce problems and make h264enc behave badly. The default option set in the new MPLAYEROPTS variable is '-noconfig all' which disables parsing of the mplayer config file * Made the VCD device scanning code a function -> get_vcd_devices_func() * Updated the -scan option to also support VCD scanning * Small cleanups 2009-04-12 - h264enc 8.7.3 * Optimize output file naming for file/vcd encodings. Based on a patch by Jouni Suorsa * Added support for the dsize video filter * Added support for VBR audio encoding when using FAAC or neroAacEnc as encoder. This automatically disables target file size calculation until I find out how to map quality values to bitrates for these codecs 2009-02-14 - h264enc 8.7.2 * Rewrote and simplified the video_denoise_func() function. Merged the presets with the denoise filters * Added two Archos 5 presets (ar5 and ar5hq) * Removed unused global_header variable from h264enc and the preset.cfg file * Add audio meta-data info for the MKV container when using aac, mp3, ac3 or vorbis audio * Revert back to the old crop detection method for DVDs as it was more precise in some cases than the currently used one. This forces the video codec during crop detection to mpeg12 instead of ffmpeg2 as the -sstep option doesn't play nice with ffmpeg2 * Updated the man page 2009-02-02 - h264enc 8.7.1 * Use keyint_min of 2 instead of 1 for the Blu-ray/AVCHD presets to prevent consecutive IDR frames * Added -loop 1 to MPlayer to prevent infinite looping if user has set -loop 0 in MPlayer's config file. Suggested by Jan Paral (Dept. of Physics, Univ. of Alberta, Canada) 2009-01-20 - h264enc 8.7.0 * Added support for setting the position of the expand filer when scaling is used. The user can now choose to place it before or after the scale filter. Previously the expand filter was always placed after the scale filter which is not optimal in certain cases * Small improvement/fix: when encoding two audio tracks to HE-AAC audio and muxing them into MKV, mkvmerge uses for both tracks the same track ID (1) while h264enc assumes that the second track uses track ID 2 which is wrong so the option --aac-is-sbr 2:1 is incorrect here and should actually be --aac-is-sbr 1:1 for the second audio track 2009-01-16 - h264enc 8.6.9 * Add title/movie name to MKV and OGM as meta-info. The title is taken from the output name provided by the user. For directory encodings, this will be skipped * Add audio codec and audio language meta-info to MKV when encoding DVDs and copying the audio track(s). Requested by Quentin Jackson * Added support for the expand video filter * Slightly improved info when the script is called without any parameters * Implemented denoising presets for the 'tn' temporal denoiser * Merge the mp3, aac, ac3 exporting code with the ffac3 and ffdts one since it's the same for the second audio track 2009-01-14 - h264enc 8.6.8 * Calculate and display the amount of frames when scanning a video file. Also display seconds in addition to minutes for the runtime * Replaced MB and GB with MiB and GiB * Updates to the hq, vhq, ehq, ihq, ani and anihq presets: lower b-frames from 16 to 5 for the hq, ani and anihq, from 16 to 6 for the vhq, from 16 to 7 for the ehq and from 16 to 8 for the ihq presets and use b_adapt=2 instead of b_adapt=1 These changes increase encoding time a bit but are worth it quality-wise * Updated QP range, add 0 for lossless mode 2009-01-04 - h264enc 8.6.7 * Added two AVCHD presets (avchd and avchdhq) * Removed tsMuxeR options insertSEI, contSPS and --vbv-len when using the Blu-ray and AVCDHD presets * Use 'source' instead of '.' for importing files into the script. Makes it easier for me to read when my eyes are tired * Moved the CONFIGDIR variable to the configuration file. This allows the user to set a custom temporary directory for storing temp files for encoding/remuxing. If the variable is unset in the config file, h264enc defaults to $HOME/.h264enc/h264enc_ This change updates the config file to version 3. Requested by Matyas Sustik * Improvements to the audio_resample_func() function. Automatically detect the audio sample rate of the content and display it. Also, moved the resample filters into a function called audio_resample_filters_func(). This change allows for comparing the detected with the selected sample rate and if both are the same, resampling will be skipped * For directory encodings, offer an option to automatically delete the AVI file after remuxing to the other containers. This can considerably reduce disk space usage, especially when encoding a directory with a lot of files in it. * Replaced all 'tail -1' commands with 'tail -n 1' since 'tail -1' is made obsolete as stated by the info page of tail * Lowered psy trellis by 0.1 for all presets that use it. Seems 0.3 can cause weak mosquito noise on some content, even at such low values * Use a weak AQ strength of 0.5 for the anime presets to reduce blocking in dark areas * Added -channels option when scanning a video file for its audio properties * Updated the man page 2008-12-12 - h264enc 8.6.6 * Added support for the software equalizer video filter (eq2) * Removed signal SIGTSTP from the trap list. The user can now suspend the encoding process with CTRL+Z and continue later on by typing fg in the terminal * Small loop modifications in the video_subtitles_func() function * Set default AAC profile when using neroAacEnc to LC instead of HE * Added support for VCD/SVCD encodings. Yeah, yeah (S)VCD is crap and old but nevertheless I'll support it. It's a small change to the codebase of h264enc anyways * Add option -ipod to the MP4Box muxing parameters. This removes the need of running MP4Box again after muxing just to rewrite the file for the iPod/iPhone * Added a condition to check if MP4Box is compiled with the PSP patch and if so, the -psp option will be added to the parameters when using the Sony PSP presets. The PSP patch along with install instructions can be downloaded from h264enc's site at http://h264enc.sourceforge.net/download.html * Small loop modifications to the get_dvd_devices_func() function * Small modifications to the install script * Updated the man page 2008-12-06 - h264enc 8.6.5 * Huge bugfix to the audio part of the portable device presets. Variable audiocodec2 was missing resulting in the second audio track being ignored. Everyone who uses these presets and wants a second audio track should upgrade ASAP * Offer nosound audio option for the portable device presets * Don't exit if the user has not added the .avi extension for the output file. Instead automatically add the extension to it 2008-12-05 - h264enc 8.6.4 * Request from yeye69: add three VDPAU/DXVA presets (vdhq, vdehq and vdihq) * Changed b_adapt=1 to b_adapt=2 for all presets that use 6 b-frames or less * Improved dealing with LPCM audio on DVDs. If the user has selected to encode a second audio track and that track uses LPCM as audio, the encoding will fail since -oac copy will not be able to copy LPCM in AVI. For this reason, h264enc will check to see if the second audio track is LPCM audio and will use -oac pcm instead of -oac copy * DVD channels settings can be now independently controlled for each audio track * Added support for AC3 in MP4. This requires latest gpac version 0.4.5 compiled with liba52 support! * Disabled AQ for the anime presets * Updated the man page 2008-12-03 - h264enc 8.6.3 * Small bugfix: IVTC/Telecine was still asked if user has selected to do FPS conversion using frame duplication (25 -> 50 fps, 50 -> 100 fps). This is due to wrong variable being tested: $fpsfilter instead of $frc * Use MEncoder to dump the video when remuxing to MP4 as MP4Box can crap out in certain cases. I'm tired of fixing MP4Box' problems :/ but the alternative (mp4creator) is a piece of crap too and is no longer maintained It doesn't support VobSub subtitles either, nor chapter files AFAIK * Made the Insane High Quality (IHQ) preset more insane. The IHQ preset is my baby so it gets very special treatment, haha! Increased frameref from 8 to 16, increased me_range from 64 to 128, enabled all partitions instead of using only p8x8,b8x8,i8x8,i4x4 and set trellis to 2. I hope the Japs are happy now :D * Added support for providing a custom factor value when using the video bitrate calculation formulas * Added initial support for a second audio track for DVD encodings. Below is a list of what currently works and what doesn't: * PCM audio is not supported yet. It's not a priority for me * If you're looking for second audio track in AVI, don't waste your time. I will never support it. Use the MKV/MP4/TS/OGM containers * Audio filters are supported for both tracks * Audio codecs and audio filters apply to both tracks. One can't use, for example, Vorbis audio for first and AAC audio for second track. One also can't set audio bitrate independently for each track * Audio stream copy is supported by the MKV/TS/OGM containers. For the MKV/TS containers one can copy AC3 + AC3 or AC3 + DTS audio. For OGM only AC3 + AC3 is supported since it knows nothing about DTS audio. If DTS audio is selected, it will be ignored * I use (very?) dirty tricks to maintain A/V sync when one uses frame altering video filters, like bobbing, interlacing, ivtc/telecine, FPS conversion * Updated the video bitrate calculation code to support a second audio track * Updated the MKV/MP4/TS/OGM containers code to support a second audio track * Better explanation about what the -r option does/is used for * Implemented audio_exit_func() function. This function kicks in effect if the audio encoding with an external audio encoder didn't succeed. If this is the case, the function will be called with the appropriate parameters and will force an exit to prevent container conversion. This is because if the audio encoding fails for some reason, container conversion will automatically fail too since the muxing programs will complain about the missing audio file and will exit, thus there is no point in continuing and displaying conversion failing messages * Reduced the amount of options displayed when one calls the script without any parameters. From now on it will just display: Usage: h264enc Use 'h264enc -help' for more information * Better wording in the preset.cfg skeleton file * Some old comments cleanups * Updated the man page 2008-11-29 - h264enc 8.6.2 * Replaced the -fq option by -qp and -crf for consistency with x264 * Replaced --help with -help for consistency with the other options * Added support for importing up to three subtitles (VobSub or SRT) into the MKV/MP4 containers when encoding a video file or a directory with files. Also hardcoding a subtitle is now possible for directory encodings * Lots of empty variables and code cleanups * Reduced a lot of code duplication in the batch exporting code by using only one variable to carry the output file * Optimized the MKV/MP4/OGM/TS/Blu-ray muxing code for directory encodings * Simplified the MKV/MP4 subtitles importing code. The new code is a bit ugly, but is much smaller and works quite well. It's basically a small loop which tests the subtitle variables for not being empty, and if so, it appends the values to the MKVSUBS/MP4SUBS variables * When encoding to neroAAC/AAC+/Vorbis audio and muxing to MKV, take the video directry from the AVI file instead of dumping it to disk. That way we can skip the dumping process and don't have to pass the FPS value of the raw video to mkvmerge since it takes it directly from the AVI. This also makes the code a bit more simple. When also muxing to MP4, MP4Box always dumps the video so we're safe here. Same thing for the TS container * Added support for detecting the audio codec of the video file/DVD when using audio stream copy. Based on the detected audio codec, decision is made if we allow or disallow muxing to MKV/MP4/TS/OGM * Updated the man page * Also today is h264enc's second public anniversary. On the 29th of November 2006, I released the first version (version 1.5) on SourceForge. Since then, h264enc has developed from a primitive and limited shell script to something more mature. When I looked back at the old code of version 1.5, I really had to laugh and wonder at the same time. I did a lot of stupid things back then 2008-11-25 - h264enc 8.6.1 * Empty variables cleanups * Bugfix: the vobsubout3 variable was not tested in the MKV/MP4 muxing code. This leads to the third subtitle not being imported into these containers * Added support for TS/Blu-ray muxing when batch encoding files in a directory * Small improvements for batch encoding of video files in a directory * New formulas to calculate the video bitrate for a target filesize. The user can choose between MeGUI's formula, h264enc's refactored MeGUI formula and the old h264enc/ripdvd formula 2008-11-23 - h264enc 8.6.0 * Bugfix: add the $ofps variable to MEncoder when dumping a second subtitle. Also enable pcm as audio to maintain sync with the video. A small performance hit but it's worth it * Added support for dumping one more subtitle. This brings it to a total of 3 subtitles that can be dumped to disk and imported into the MKV and/or MP4 container * Dramatically simplified the TS/Blu-ray muxing code * Implemented initial real batch support for files. As of now, one can encode a bunch of video files in a directory and automatically remux them to MKV/MP4/OGM. The TS container is not supported yet due to me being lazy. The user only needs to configure one of the files in a given directory, and all the settings will apply to the other files as well * Moved the DVD device detection code into its own function to reduce some code duplication * Made the encoding priority level global. It now applies to audio/video dumping, audio encoding, subtitles dumping and container muxing 2008-11-20 - h264enc 8.5.9 * Rewrote the DVD part of the video_subtitles_func() function. It now supports dumping two subtitles to disk * Updated the MP4/MKV muxing code to support importing of two subtitles * Dramatically simplified the MP4/MKV/OGM batch exporting code. This reduces a lot of code duplication * Bugfix in the video_subtitles_func() function for SRT subtitles for video files. Wrong variable used * When encoding samples, make sure to take care of any subtitles that might have been dumped to disk * Don't exit if the user provides a floating point value for the Vorbis audio codec. Instead warn and use the default value. * New formula to calculate the video bitrate for a target filesize. The previous formula, which was directly taken from the ripdvd project, incorrectly calculates the bitrate which often results by missing the target filesize by as much as 30 MB. The new formula also uses floating point precision and has been tested agains the calculators of MeGUI and Avidemux * Removed support for me-prepass * Removed neroAacEnc quality-based encoding mode. It is incompatible with video bitrate calculation for a target size and I cannot find any info on quality -> average bitrate mappings. * Updated the HW compatible presets. Changed H.264 Level for the SD presets from 3.1 to 3.0 and for the HD presets from 4.1 to 4.0. Also updated the vbv_maxrate values according to Level specs * Restructured the Blu-ray presets. Now there are four different Blu-ray presets available: bd40, bdhq40, bd41, bdhq41. bd40 is Main profile @ Level 4.0, bdhq40 is High profile @ Level 4.0, bd41 is Main profile @ Level 4.1 and bdhq41 is High profile @ Level 4.1 * Allow CRF encoding to be used with some device presets (ps3, xbox360, appletv) * Updated the man page * Some cleanups 2008-11-10 - h264enc 8.5.8 * Added support for the aacplusenc AAC+ audio encoder from Matteo Croce * Updated the MP4 & MKV batch exporting and muxing code to support the aacplusenc encoder * Display elapsed time when encoding samples * Added NAL HRD to the Blu-ray presets. This requires a patched x264 with the NAL HRD patch. The patch along with install instructions can be downloaded from http://h264enc.sourceforge.net/download.html * Added option nal_hrd to the 'preset.cfg' skeleton file * In some cases it is possible for h264enc to leave its unique temp directory. Find those directories and remove them if they are 15 or more days old * Added support for deinterlacing at half frame rate. Useful for interlaced content that's running at 50 or 59.940 fps (100i/120i) * Updated the source_fps_func() function * Removed support for the MP2, WMA and ADPCM audio codecs. No one uses these codecs in combination with H.264 video * Removed support for MPEG-2 AAC audio * Reduced some code duplication in the set_output_filename_func() function by moving path and extension checking into its own function * SSIM and PSNR statistics are now enabled by default * Removed the noise filter. No real use for it * Updated the audio_resample_func() function * Updated the check_audio_codec_func() function * Updated the genconfig_func() function * Updated the man page * Updated the README.h264enc file 2008-10-28 - h264enc 8.5.7 * Improved DVD handling. Now there's a menu where the user can select the input type: ISO image, VIDEO_TS folder or DVD drive * Presets updates: updated the b_adapt option. It supports parameters. Also updated the standard presets to use level 4.1 instead of 5.1 and enabled psy_rd (psychovisual optimization) for all presets that use subq 6 or higher * Added two Archos 605 presets (ar and arhq). The presets are directly lifted from AutoMKV (thanks buzzqw) but are a bit modified to get a somewhat higher quality * Added two Blackberry 9000 presets (bb and bbhq) * Added two Blu-ray presets (bd and bdhq). When using these presets, h264enc can create a Blu-ray disc structure if tsMuxeR is available on the user's system. Latest tsMuxeR version for Linux is 1.7.3(b) which has a bug when creating a Blu-ray structure. h264enc has a workaround for this * Added access unit delimiters (aud) for the PS3, Blu-ray and HW compatible presets * Set the field order of the tfields filter to auto detection * Bugfix: when using the presets for the iPod/iPhone, h264enc didn't set the SAR to 1:1 when remuxing to MP4. Bug was introduced due to renaming of the portable device presets * Removed AAC object type complexity menu. AAC (FAAC) is best used in low complexity mode * Small improvement to the TS container code. Always write the FPS value to the meta file when muxing to TS. Also use mencoder/mplayer instead of MP4Box to extract video and audio * Added extra strong denoising preset for the denoise3d & hqdn3d filters * Implemented configuration file support. As of this version, h264enc automatically generates a config file in its configuration directory. The config file can be used by the user to modify/set the paths to various programs. This can be useful if the user has multiple executables of the same program(s) but wants to use a specific one for the job. It can also be used to set the correct path to a program if the program in question is not located in a standard location and cannot be found by the system. The configuration file cannot be used to store encoding settings or other parameters! It is only meant for the tools needed for the correct operation of h264enc. The config file will be generated in /home/user_name/.h264enc/config. The config file has its own versioning system and will be automatically updated in case something changes in future versions of h264enc * Added -r option to reset the config file in case the user has made any changes to it and wants to restore the original values of the config file * Updated the man page 2008-10-19 - h264enc 8.5.6 * Updated the 'preset.cfg' skeleton file. Added support for psy_rd, Psychovisual optimization * Improved subtitle handling for video file encodings. Now the user can select to hardcode a given subtitle into the movie or import it into the MP4 and/or MKV container. Only two subtitle formats are supported and have been tested: VobSub and SRT * Added support for sample encoding and previewing. When encoding samples, one can specify the start position and the duration in seconds for the sample. Sample encoding respects encoding passes meaning if you execute h264enc in two-pass mode and want to encode a sample before the real encoding starts, then the sample will also be encoded in two-pass mode with all the options and filters selected by the user. Sample encoding can further be used to encode only specific parts of a video file or a DVD. In regards to DVDs, sample encoding does not respect selected DVD chapters meaning the given start position for the sample will overwrite the selected DVD chapter(s). This is a mencoder problem and there's nothing I can do about it. * Presets update: most presets for portable devices have been renamed. Please read the man page or execute 'h264enc --help' for more information * Added two QuickTime presets - qt and qthq * denoise3d & hqdn3d: implemented weak/medium/strong denoising presets * Removed quantization parameters for the spp, uspp, fspp and pp7 deblockers * Updated the crop preview code. Instead of sleeping for 15 seconds and then killing the PID value of mplayer, use the -endpos option * Updated the man page 2008-10-16 - h264enc 8.5.5 * Presets updates: most presets have been updated to reflect the recent changes made to the subme system in libx264. The options 'bime' and 'brdo' have also been removed as they are no longer available as separate options in libx264. 'bime' is automatically enabled if a preset uses subme >= 5, brdo has been included into the subme system. Please upgrade your libx264 to the latest version if you encounter problems when using the presets. * Updated the 'preset.cfg' preset skeleton file * Separated the 'normal' deinterlacers from the frame doubling ones * More optimizations to the TS container code * Disabled b_pyramid for the PS3 presets. Should increase compatibility with the PS3 a bit more * Added Vorbis audio support for the OGM container * denoise3d & hqdn3d: increased default denoising values to 3:2:3:2 * Removed path specification for MEncoder * Cosmetics & cleanups 2008-07-11 - h264enc 8.5.4 * Added support for DTS, MP3 and MP2 audio for the TS container * Optimizations to the TS container batch exporting code * iPod optimizations to the MP4 muxing code * Enabled neroAAC and Vorbis audio support for the Matroska container * Updated the audio part of the PS3 presets. Added audio copy support so a user can just copy the AC3 stream and later on mux it into a TS transport stream. Note that I'm not sure if the PS3 can play H.264 TS files since the PS3 doc only mentions MPEG2 TS and PS * Added tsMuxeR options "insertSEI" and "contSPS" as default when muxing to the TS container * Small tunings to the ps3vp preset. Made it main profile instead of high profile -> ps3hqvp is already high profile so no need for ps3vp to also be high profile * Disabled weight_b for the anime presets. According to Dark Shikari (an x264 developer) it decreases the effectiveness of multiref while providing no benefit * Do not ask for FPS conversion or pullup/pulldown if the user forces an output frame rate 2008-07-07 - h264enc 8.5.3 * Feature request: add the possibility to disable MEncoder's A/V sync algorithm when encoding video files. This can be used to fix input video files with bad A/V sync in them, however there are no guarantees that this will actually fix the problem * Added initial support for the TS container. This requires tsMuxeR and MP4Box (for audio/video dumps). When muxing to the TS container, only the FAAC AAC and AC3/copy audio codecs are supported. Read the README.h264enc which provides more information on where to get tsMuxeR. * Updated the -sc option, added tsMuxeR to the list * Enabled back the use of temporary directories based on process ID to store config files * Fixed a bug in the check_audio_codec_func() function. Variable MENOCDER should be MENCODER * Updated the requirements part in the README.h264enc file * Small clean ups * Updated the man page 2008-07-05 - h264enc 8.5.2 * Feature request: add the possibility to specify the path to MEncoder. Useful if the user has two or more versions of MEncoder but wants to use a specific one for the encoding * Check to see if destination directory is writable by writing a small file to it. * Updated the README.h264enc file * Updated the man page 2008-07-03 - h264enc 8.5.1 * Added support for using the neroAacEnc AAC audio encoder when using the portable device presets icvp, ichqvp, ivp, ihqvp, ipvp, iphqvp, avp, ahqvp, nks60vp, nks60hqvp, pspvp, psphqvp, ps3vp, ps3hqvp, zvp, zhqvp, xvp and xhqvp * Bugfix: when using the f9 or f9hq preset with the neroAAC audio codec, -oac pcm was not passed to the MEncoder options * Changed default unsharp mask / gaussian blur matrix to chroma & luma 5x5 as it provides a better balance than the 3x3 matrix 2008-06-30 - h264enc 8.5.0 * Added support for using the neroAacEnc AAC audio encoder with LC, HE and HEv2 profiles * Function renaming: aacplus_audio_func() -> neroaac_audio_func() * Variable renaming: aacplusbr -> neroaacbr * Audio codec renaming: AAC+ -> neroAAC 2008-06-25 - h264enc 8.4.9 * Bugfix: don't leave config files upon user interrupt * Removed reference to the Sonic audio codec in the -sc option as this codec is no longer supported 2008-06-23 - h264enc 8.4.8 * Disabled the use of unique temporary directories to store temporary configuration files. This fixes an MP4Box crash on newer systems 2008-06-18 - h264enc 8.4.7 * Added support for inclusion of external subtitles when encoding video files. The external subtitle will be hard coded into the encode * Updated the man page 2008-06-11 - h264enc 8.4.6 * Merged checking of the encoding modes for the specific presets that need it * Removed the Black & White presets since they are useless and the only difference in them from the others is that they don't use chroma motion estimation * Updated the man page 2008-06-04 - h264enc 8.4.5 * Fix for the sdb, sdm, sdh, hdb, hdm and hdh presets. These presets are only supported in 1-, 2-, or 3-pass mode since they use VBV maxrate and VBV bufsize with is not compatible with QP/CRF encoding modes 2008-05-30 - h264enc 8.4.4 * Small menu enhancements to the FPS settings * Fixed wrong explanation for the temporal denoiser * Removed support for the Sonic and SonicLS audio codecs since they are experimental and far from complete for daily use * Updated the man page 2008-04-28 - h264enc 8.4.3 * Clarify that the aspec ratio is the one for input sources * Added MP4Box -ipod switch for the iPod/iPhone profiles * Set the field order of the frame doubling yadif deinterlacer to auto detection * Implemented source_fps_func() function to reduce code duplication. This function automatically detects the FPS of the content and is shared between the deinterlace and interlace functions * Added support for applying denoising/deblocking on interlaced content. This is done by deinterleaving the content with the il=d filter, applying the denoising/deblocking on the deinterleaved content and interleaving it back with the il=i filter. That way we don't break the interlacing * Color enhancements to the -bpp and -bpb options 2008-04-25 - h264enc 8.4.2 * Fixed a problem where the detected resolution based on the crop values favored the values of the cropdetect filter instead of the user provided values. Reported by blaz from the Doom9 forum * Renamed resolution variable 'res' to 'vres' * Added support for doing 25 -> 50 fps and 29.970 -> 59.940 fps conversion using simple frame duplication * Updated the man page 2008-04-22 - h264enc 8.4.1 * Updated the keyframe auto detection * Updated the audio_channels_func() function * Updated the --help section * Set the field dominance of the yadif deinterlacer to auto-detection. If the decoder doesn't export the field order, it defaults to TFF (top field first) * Enabled multi-channel AAC audio for the Sony PS3 presets * Small update to the FPS conversion menu * Fixed a typo in the color() function * Small menu enhancements to the video_interlace_func() function * Added support for video bitrate calculation when using 5 channels PCM audio * Removed delay when exiting from user interrupt * Updated the audio codecs menu * Updated the README.encoding file 2008-04-19 - h264enc 8.4.0 * Updated the filmdint FPS conversion filter. Added dint_thres=256 to not do any deinterlacing while doing the conversion * Updated the man page 2008-04-15 - h264enc 8.3.9 * Fixed the cropping code. NTSC content was problematic * Added support for NTSC Double @ 60 fps 2008-04-09 - h264enc 8.3.8 * Updated the cropping code to support the latest SVN version of MEncoder * Replace underscores from DVD title names with spaces 2008-04-08 - h264enc 8.3.7 * Integrated the exit command into the rmconf() function * Added aq_metric for those who want to test the VAQ2 patch * Updated the preset.cfg file. Added aq_metric * Small clean ups 2008-03-27 - h264enc 8.3.6 * Use awk to get the current device when exporting DVD chapters information * When encoding specific chapters, append the chapters info at the end of the output file * Changed the nkvp and nkhqvp presets to nks60vp and nks60hqvp * Removed support for manual video codec configuration. This reduces the code and makes it less bloated. If a user wants to configure something manually, he can write his own custom preset and load it in h264enc * Removed support for MP3 high- and lowpass frequency settings. I'm sure many people don't use these options and accept the defaults * The threads option is now hard coded into the mencoder_opts() function * Removed keyint and keyint_min from the HW compatible presets. Use the default detected values for those * Updated the preset.cfg file * Updated the README.h264enc file. Added links for neroAacEnc and Vorbis * Removed SD/HD Extended presets. They are useless * Updated the man page 2008-03-23 - h264enc 8.3.5 * Use -vf rectangle= when previewing the crop values. Will give us a nice outline of the crop values * Removed accurate rounding of the software scaler since it does not work on a lot of systems * Updated the VAQ code to support the final version of the variance adaptive quantization patch -> replaced aq_sensitivity with aq_mode * Updated the preset.cfg file to support the new VAQ * Changed sample rate of the f9 and f9hq presets from 48000 Hz to 22050 Hz * Be silent when doing FPS conversion 2008-03-18 - h264enc 8.3.4.1 * Bugfix for the PSP presets. Multi-threading was not enabled 2008-03-15 - h264enc 8.3.4 * Removed niceness from the muxing commands * Clean ups to the batch exporting code * Added -nocache mplayer option to the AAC+/Vorbis muxing/exporting code * Disabled muxing to MKV if the user is using the AAC+ or Vorbis audio codec. The reason for this is that mkvmerge doesn't seem to honor the --default-duration flag when importing RAW h264 streams and will because of this generate files with major A/V sync issues. I've already filed a bug report. Until this is resolved I will not enable MKV muxing when using the AAC+ or Vorbis audio codec! * Replaced an 'if' conditional with a 'case' one in the AAC+/Vorbis batch exporting code * Updated the AUTHORS file. Added Harry Gunnarsson as bug reporter/testing 2008-03-13 - h264enc 8.3.3 * Minor clean ups and code improvements * Set default QP parameter to 0 for the spp, fspp and uspp postprocessing filters * Added support for CBR AAC+ audio * Made the CBR part of the audio codecs to be menu driven * Fixed a bug where the FPS conversion menu and the Telecine/IVTC don't show up due to missing interlaced variable. Bug was introduced during the grouping of the pre/postprocessing video filters 2008-03-10 - h264enc 8.3.2 * Pre/Postprocessing video filters are now grouped in one question * Fixed a small bug. The Nokia S60 presets are not allowed in fixed-quant mode since they have maximum allowed bitrate restrictions * Added autocompletion support. Patch by Nicolas Di Pietro * Added a skip option to most of the menus * Added support for AAC+ audio to the f9 and f9hq presets * Clean ups in the audio codecs code 2008-03-08 - h264enc 8.3.1 * Added checking for oggenc and neroAacEnc to the -sc option * Disabled the scalable sample rate option of the FAAC menu since it does not work. FAAC doesn't support HE-AAC * Color optimizations * Some minor code improvements * Use named pipes (fifo) to encode to AAC+ or Vorbis audio. This eliminates the audio dumping step and the required disk space * Updated the batch code to support named pipes 2008-03-07 - h264enc 8.3.0 * Simplifications and clean ups in the audio codecs code * More simplifications to the video bitrate calculation code * Fixed identification of AAC+ in the matroska muxing code. Should be --aac-is-sbr 1:1 and not --aac-is-sbr 1 * Disable accurate rounding of the software scaler on 64-bit systems since MEncoder has issues with it * Simplifications to the Matroska batch exporting code. This removes a lot of code duplication * Only extract audio and video if we deal with the AAC+ or Vorbis audio codec * Simplifications to the Matroska muxing code * Major simplifications to the MP4 muxing code. A lot of code duplication is removed 2008-03-06 - h264enc 8.2.9 * Video bitrate calculation: fixed the PCM part. It needs different bitrates for different audio channels. Resampling is not taken into account at the moment * Added support for multichannel AAC+. Note that in VBR mode, you must use a value of 0.37 or lower or else neroAacEnc will error out with invalid SBR configuration! * Added support for bitrate based ABR AAC+ * Added support for video bitrate calculation when using ABR AAC+ * Simplified the batch exporting code of the AAC+/Vorbis audio codecs. This removes code duplication * Removed the MP4SBR variable in the batch code of the AAC+ audio codec. The value of this variable is now carried by the AUDIOFILE variable. Also did a few small simplifications to this part * Added support for exporting the MP4 muxing commands to the batch file when using the NOSOUND audio option * Updated the signal traps * Replaced an 'if' conditional by a 'case' one in the video bitrate calculation code * Random clean ups 2008-03-05 - h264enc 8.2.8 * Merged the -sv option with -scan * Fixed an issue when scanning video files, especially TS ones, where printing the video resolution could get misaligned * Remove pointless removing of temp files. Since h264enc now uses unique temporary directories to store temp files, there's no point in removing them anymore as the unique directory will be removed upon user interrupt or user fault * Added support for the HE-AAC (aka AAC+) audio codec. This requires neroAacEnc. When encoding to this codec, the AVI will be first encoded with PCM audio. Then both the video and audio will be extracted from the AVI, the audio will be encoded to AAC+ and will be muxed together with the video to the mp4 and/or mkv container. Multichannel AAC+ audio is not supported yet as neroAacEnc for Linux doesn't seem to support it at the moment * Added support for the Vorbis audio codec. This requires oggenc. Multichannel audio is supported * Updated the batch code to support AAC+ and Vorbis audio * Updated the README.h264enc file * Updated the man page 2008-03-04 - h264enc 8.2.7 * Added two Flash Player 9 presets (f9 and f9hq) * Remove config directory on non-zero exit status * Implemented -sv option which scans an input video file and displays information about it * Some small code improvements * Updated the man page 2008-03-03 - h264enc 8.2.6 * Removed option 2, 3, 4 and 5 of the 60p -> 24p FPS conversion menu as these filter chains are not very reliable and often fail at doing the conversion. Also removed support for the decimate filter so now only framestep and filmdint are supported which give the best results * Refined the filmdint filter parameters for 60p -> 24p FPS conversion and set default filter to filmdint=fast=0/io=60:24 * Bugfix: missing ':' in the vbv_bufsize variable of the psphqvp preset. Reported by Harry Gunnarsson 2008-03-02 - h264enc 8.2.5 * Added support for 30p -> 24p FPS conversion * Added support for the decimate filter when doing 60p -> 24p FPS conversion * Small improvements to the crop preview code. Should come after the user has entered the crop values * Video file encodings: Use unique default output file based on process ID * Fixed a small bug where h264enc assumes that the $HOME/.h264enc directory already exists but that might not be the case, so it will fail at making an unique temporary directory. Reported by Nathaniel Gray * Added support for setting the quantization parameter for the spp, uspp and fspp postprocessing filters 2008-03-01 - h264enc 8.2.4 * Bugfix: forgot to add tinterlace before the detc filter for 60p -> 24p FPS conversion * Removed the '-p help' option as it is not very useful. --help displays everything one needs to know * Added more 60p -> 24p FPS conversion filters and set default filter to framestep=2,filmdint=fast=0 which gives the best results * Disabled colorspace conversion when interlacing, telecining or when doing FPS conversion as some of the filters (most?) don't like it. Also disabled colorspace conversion for the Nokia S60 presets * Made the script to use unique temporary directories to store the config/parsing files. That way, one can run multiple instances of h264enc at the same time without interference * Modified the batch exporting code to work with unique directories * Updated the man page 2008-02-29 - h264enc 8.2.3 * Added support for doing 60p -> 30p, 60p -> 24p and 50p -> 25p FPS conversion. Useful for HD content that runs at 59.94 or 50 fps. This option is mutually exclusive with interlacing and frame doubling deinterlacing filters * Added two Nokia S60 presets (nkvp and nkhqvp). Thanks to Matteo Croce (mp4tools) for the device info * Colorized automatic actions/info/menus * Fixed a small bug in the manual codec configuration where calculating of the keyint_min value fails * Updated the man page 2008-02-27 - h264enc 8.2.2 * Added support for calculating the video bitrate when encoding with the NOSOUND audio option * Added support for calculating the video bitrate when using the PCM audio codec * Converted the code for the bicubic software scaler parameters to be menu driven * Added one 'Insane High Quality' preset (ihq) which uses the Hadamard-based motion estimation algorithm * Enabled AAC audio support for the Matroska container. Please upgrade your mkvtoolnix to the latest SVN version! * Notify the user that the frame rate will change when using the inverse telecine/telecine filters * Clean ups in the MP4 muxing code * Improvements to the batch exporting code * Updated the man page 2008-02-24 - h264enc 8.2.1 * Removed the 'user defined' option from the deint_custom_fps_func() function as it can confuse users who don't really know what to enter there * Added support for different audio resampling modes * Added support for the 'lavcresample' audio resample filter * Made the audio_resample_func() function to be menu driven * Converted the MKV/MP4/OGM code to base its decision on variable $audiocodec instead of variable $audcodec. Makes the code less complicated * Updated the 'preset.cfg' file. Custom presets now support the following additional options: ratetol, vbv_maxrate, vbv_bufsize, vbv_init and cqm and me_prepass * Preparations for the motion estimation prepass patch * Added support for automatic detection of the video aspect * Don't continue if MEncoder exits with a non-zero status * Added two Black & White/Gray presets for BW movies (bw and bwhq) * Small improvements to the custom_matrix_func() function * Small improvements to the DVD titles scanning code * Small improvements to the check_diskspace_func() function. Patch by Gunter Ohrner * Updated the -sc option * Variable renamings and clean ups * Updated the man page 2008-02-20 - h264enc 8.2.0 * Fixed a bug in the deint_custom_fps_func() function. Variable deintfsp for NTSC @ 59.94 fps should be deintfps * Fixed a bug in option 8 of the $dfilter variable which was using a invalid underscore. Should be -field-dominance 1 instead of -field_dominance 1 * Clean ups of old commented out code * Reordered the deinterlacing menu. Separated the normal deinterlacers from the frame doubling ones * Small improvements to the audio_channels_func() function * Renamed variable $ss to $softscale * Added two iPod Classic presets for iPods that support only H.264 @ Level 1.3 (icvp and ichqvp) * Updated the README.h264enc file * Updated the man page 2008-02-18 - h264enc 8.1.9 * Updated the DVD chapters code to support the latest SVN version of MPlayer/MEncoder * Small improvements to the cropping code * Fall back to 'dd' for ISO dumps if 'pv' is not available on the user's system * Set default noise pattern to be Luma + temporal instead of Luma & Chroma + temporal * Added support for the lossless format of the Sonic audio codec * Added the X-Men 3 matrix, Q matrix, Q2 matrix, Soulhunter V1 matrix, Soulhunter V2 matrix, MP4Guy's low bitrate matrix, Audionut high bitrate matrix and Audionut general matrix to the package. Thanks to Audionut, MP4Guy and Soulhunter * Bugfix: the ivtc/telecine process should check for the $deintfilter variable instead of the $deintfps one. ivtc/telecine is mutually exclusive with deinterlacing * Improvements to the MP4 muxing part when exporting the options to the batch file. From now on, the FPS needed for MP4Box is directly taken from the AVI file. This approach is much more reliable and the user no longer needs to edit the FPS value for MP4Box when exporting the options of NTSC content to the batch file. * Added one Anime high-quality preset (anihq) * Updated the presets_keyint_func() function * Added support for the Tfields deinterlacer @ original frame speed and Tfields + fast/medium/slow/slowest Mcdeint @ original frame speed * Replaced a few 'if' conditionals with 'case' conditionals * Updated the README.matrices file * Typo fixes * Updated the man page 2008-02-14 - h264enc 8.1.8 * Export testing condition to the batch file for the output of MEncoder and for the output directory as well * Changed FPS naming for Silent Speed to Silent Film * Added support for automatic brightness/contrast control * Bugfix: Only ask for deletion of the AVI file if the user has chosen to remux it to one of the supported containers * Removed duplicate $quiet variable in the video_deinterlace_func() function when deinterlacing with a frame doubler * Modified the -iso option to use 'pv' for DVD ISO dumping instead of 'dd'. 'pv' provides us with a nice progress bar which is useful as it takes a long time to dump a DVD, so the user can follow the progress. 'dd' provides no such thing. * Updated the -iso option to support dual-layer DVD discs (~8.54 GB) * Added support for setting the subtitle alignment * Added support for setting the subtitle Gaussian variance strength when hardcoding subtitles into the movie * Use $IDXFILE variable for the MP4SUB and MKVSUB variables * Tweaks to the HD presets. Increased VBV buffer size to 14475 and set keyint to 14 and keyint_min to 2 for the SD/HD presets. Also increased b-frames usage from 3 to 6 * Various small code improvements * Updated the man page 2008-02-12 - h264enc 8.1.7 * Bugfix: the manual in-loop deblock filter setting errors out due to wrong conditional check for a comma. Reported by Justin Poirier * Added support for fast/medium/slow/slowest mcdeint combined with the Yadif and Tfields deinterlacers. This brings it to a total of 45 deinterlacing modes * Implemented -iso option for dumping the DVD content with 'dd' to an ISO image to disk * Added 'sleep 3' delay for the exported options * Added one Anime preset (ani) * Small tweaks to the NLQ and UHQ presets * Made the deint_custom_fps_func() function to be menu driven * Use detected FPS value in the bits_per_pixel_func() and bits_per_block_func() functions instead of falling back to 25 if the user doesn't set/force the FPS value * Replaced a few 'sed' commands with 'awk' * Changed the -o option to -b to better reflect that this option is for batch encoding. Also default output file of the options file will be $HOME/batchfile * Updated the FPS values for VFR Anime sources and Silent Speed films * Variable renamings and code duplication clean ups * Decreased VBV buffer size from 6000 to 5000 for the SD presets, frameref to 3 and B-Frames to 3 for the SD/HD presets * Updated the AUTHORS file * Updated the man page 2008-02-09 - h264enc 8.1.6 * Added support for the OGM container * Cosmetics: forgot to put a few 'echo' statements in the video_deblock_func() function * Renamed presets hwpb, hwpe, hwpm and hwph to hdb, hde, hdm and hdh * Added 4 stand-alone HW players SD presets @ L3.1 (sdb, sde sdm and sdh) * Removed the 'hwcompat_preset.cfg' file as HW players presets are now hard coded in the script * Made the call to the presets_keyint_func() function global instead of per preset based. This reduces code duplication * Added the -tmp flag to the MP4Box commands to not run out of disk space in case of large files. Suggested by Henk Schoneveld * Switched from trellis=2 to trellis=1 for the EHQ and UHQ presets as trellis=2 can kill detail quality since it overdecimates too strongly on the blocks. This should also speed up things a bit * Improvements to the video_interlace_func() function * Added the -field-dominance flag to the MEncoder parameters for deinterlacers that support setting the field order * Changed variable $df to $dfilter * Disabled exporting the MP4 muxing commands to the options file when using NOSOUND as the code base does not allow it * Removed support for optimization of the MP4 file layout as the 'mpeg4ip' tools are no longer actively developed * Fixed a typo in the deint_custom_fps_func() function * Removed support for file splitting as the code/operation is not very reliable, especially with embedded subs in the MKV/MP4 containers. Further, the code to support 4 containers is pretty large and unmanageable * Small clean ups * Updated the man page * Updated the README.h264enc file * Updated the README.encoding file 2008-02-07 - h264enc 8.1.5 * Fixed a small bug. Don't ask for MKV conversion if using the Sonic audio codec as mkvmerge doesn't support it. * Simplified the Matroska exporting code * Added support for exporting the MP4 muxing commands to the options file. * Added support for previewing the crop values for 15 seconds * Renamed variable $audio_codec to $audcodec * Simplified the MP4 muxing code a bit. Reduced a bit of code duplication * Some improvements to the audio scanning menu * Notify the user that the frame rate will change if he is interlacing progressive content * Removed displaying "Checking for lsdvd..." every time the user chooses for DVD encoding * Don't enable interlace-aware software scaler when telecining progressive content as the telecine filter comes after the scale filter * Some clean ups 2008-02-05 - h264enc 8.1.4 * Added vbv_maxrate=25000 and vbv_bufsize=9000 to the hwpb, hwpe, hwpm and hwph presets to fully conform to Level 4.1 for stand alone HW players * Switched to bitrate rate control for the first pass in a 2- and 3-pass encoding mode so we can get a better quant distribution * Added support for adding noise to the encoding with the 'noise' video filter * Updated the 'hwpcompat_preset.cfg' file * Increased B-Frames usage with 2 for the standard presets * Added support for exporting the Matroska muxing commands to the options file. User request from Harry Gunnarsson. * Reordered the input frame rate selection menu of the video_interlace_func() function * Added support for the Sonic audio codec * Updated the man page 2008-02-03 - h264enc 8.1.3 * Added support for deblocking-only of DVDs/video files with the ha/va filters * Added 4 built-in stand-alone HW players presets (hwpb, hwpe, hwpm, hwph) * Preparations for the upcoming Variance Adaptive Quantization (VAQ) The code is ready to use but is disabled and will stay so until the VAQ patch gets committed to SVN * Made the custom FPS code for deinterlacing a function. This reduces code duplication * Changed contact email address due to some issues with my current ISP provider * Added support for setting/forceing the video aspec ratio * Fixed a small bug in the manual configuration where setting the motion search range wasn't available when using 'tesa' motion estimation. * Updated the AUTHORS file. Added Justin Poirier as bug reporter * Updated the 'preset.cfg' skeleton preset file * Updated the man page * Clean ups 2008-01-31 - h264enc 8.1.2.1 * Fixed a potential bug where MP4Box/mkvmerge can fail to parse the filename of the subtitle during importing 2008-01-29 - h264enc 8.1.2 * Added support for deringing-only of DVDs/video files. * Fixed a bug in the $threads variable in the manual codec configuration. Thanks to Justin Poirier for discovering and reporting this bug. * Reset variable $aid when using the 'nosound' audio option. * Added support for the new fullpel motion estimation hadamard-based 'tesa' (SATD) algorithm presented in x264 revision r730. * Switched to the new 'tesa' fullpell ME algorithm for the UHQ preset. Please upgrade your x264 program to revision r730 or higher if you intend to use this preset! * Switched to the 'esa' fullpell ME algorithm for the EHQ preset. * Updated the 'preset.cfg' skeleton preset file. * Clean ups 2008-01-24 - h264enc 8.1.1 * Bugfix: added a condition to check if the 'tfields' filter is used, and if so, to place it after the crop filter. The reason for this is that 'tfields' alters the resolution and if this filter comes before the crop filter, the crop values will no longer be correct so MEncoder will error out with a "crop area outside of the original" message. * Implemented menu driven -scan option for DVD information. With -scan one can display extensive information about a DVD or can export the information to a file on disk in text, perl, python, ruby or xml format. * Added support for auto-detection of the FPS value and setting it to double when deinterlacing with a frame doubling deinterlacer * Added a note that NTSC FPS detection is not 100% reliable. This comes from the fact that h264enc only detects the FPS flag set in the video content but many NTSC DVDs "lie" about their true FPS value. And of course, the FPS won't be correct at all if we deal with soft telecined content. * Removed partition type i8x8 from the LQ and VLQ presets as these presets don't use adaptive spatial transform (8x8dct) so i8x8 does nothing there * Enabled partition type i8x8 for the Sony PS3 presets * Switched from partitions=all to partitions=p8x8,b8x8,i8x8,i4x4 for the EHQ and UHQ presets. This removes support for the useless p4x4 partition type which provides almost no benefit in compresability and quality improvement and only slows down the encoding * Updated the deinterlacing menu * Added some extra comments to the aac_audio_func() function * Added the -nocache option to MPlayer for faster execution * Updated the signal traps * Updated the man page 2008-01-21 - h264enc 8.1.0 * Made the audio codec selection to be menu driven. Also set the default audio codec to be AAC instead of MP3. * Made scanning for multiple audio streams in video files to be optional. * Added back support for the old ha/va/dr postprocessing deblock/dering filters. * Added support for interleaving even lines from even frames with odd lines from odd frames with the 'tinterlace' filter in mode 4 * Added support for the frame doubling 'tfields' temporal fields filter and 'tfields' + 'mcdeint' * Enabled chrominance filtering for the temporal 'tn' denoiser * Some small code improvements to the 'sed' parsing. * Cleanups in the quality presets. Made the 2- and 3-pass $turbo variable to be global instead of per preset based. This reduces code duplication. * Fixed a small bug when using user defined frame rate during the frame doubling deinterlacing process. Integer input values were not multiplied by 2. Also added a note that the provided FPS will be multiplied by 2 2008-01-18 - h264enc 8.0.9 * Added support for user defined frame rate when using a deinterlacer which doubles the output frame rate. * Bugfix: second pass in a three pass encoding mode cannot use CRF rate control. Thanks to Justin Poirier for reporting this bug. * Fixed typo in the 'hwcompat_preset.cfg' file. Should be Decoded Picture Buffer and not Display Picture Buffer. 2008-01-14 - h264enc 8.0.8 * Changed default (un)sharp mask/gaussian blur matrix to luma & chroma 7x7 as it provides a better balance than the 3x3 matrix. * Added a tip for the 'denoise3d' and 'hqdn3d' filters that one can do only Spatial, only Temporal or Spatial and Temporal filtering with these filters. Spatial-only filtering is achieved by setting the last two values to 0, Temporal-only filtering is achieved by setting the first two values to 0. Spatial and Temporal filtering is achieved by using all values. * Added support for adjusting the filter strength of the 'fspp' postprocessing filter. * Added support for doubling the frame rate of the content during the deinterlacing process with the 'yadif' and 'mcdeint' filters. * Added support for interlacing progressive 100 fps PAL and progressive 119.88 fps NTSC content. * Updated the FPS code. Added support for PAL/SECAM/NTSC Quad (100 and 119.880 fps) and reordered the menu. Also disabled frame rate selection when interlacing progressive content or deinterlacing interlaced content with a deinterlace filter which doubles the output frame rate. Both actions are mutually exclusive with setting the output frame rate as the chosen interlace/deinterlace process will take care of the fps. * Enabled x264 interlace-aware mode if the user is interlacing progressive content with the 'tinterlace' and 'phase' filters. * Placed the interlace filters 'tinterlace' and 'phase' after the harddup filter so that duplicate frames will never get interlaced. * Renamed variables $pullup, $telecine, $cropping, $colorspace, $ivtc_filter, $int_fps and $int_ofps to $ivtcfilter, $telecinefilter, $cropfilter, $colorspacefilter, $ivtcfilt, $intfps and $intofps 2008-01-11 - h264enc 8.0.7 * Modifications to the output filename code. As of now, for DVD encodings, h264enc will scan the DVD for its title and will set the default output filename according to the title found on the DVD disc. If the DVD title is not found, h264enc defaults to the old method. * Added two iPhone video profile presets (iPVP and iPHQVP) * Bugfix: don't ask for colorspace conversion if the user doesn't scale the content. Colorspace conversion only works with the scale filter. * Bugfix: revert using local variables in the bits_per_pixel_func() and bits_per_block_func() functions. Local variables don't work when a function is called inside another one. * Some cleanups in the audio_resample_func() function. * Moved the internal x264 denoise filter into the Denoise settings. * Added support for the 'unsharp' (un)sharp mask/gaussian blur filter * Removed the 'nr' variable from the 'preset.cfg' skeleton file as denoising is handled in the Denoise settings * Added support for selecting the frame dropping mode of the inverse telecine 'detc' filter. * Switched to ESA Motion Estimation for the UHQ preset. As of x264 revision r676 (2007-09-15), the ESA algorithm is made multi-threaded so there is no reason not to use it anymore. Also the current changes to ESA in x264 revision r718 give it a 30% boost in speed over the previous implementation. * Improvements to the DVD subtitle menu. * Updated the man page. 2008-01-08 - h264enc 8.0.6 * Disabled b_pyramid for the PSP presets and enabled 8x8dct for the PS3 and XBOX 360 presets * Added two AppleTV video profile presets (AVP and AHQVP) * Changed the audio sample rate to 48 kHz for the Zune video profile presets. Also enabled WMA audio and lifted MP3 CBR-only restrictions as the Zune supports CBR/VBR/ABR MP3 audio up to 320 kbps. The same goes for AAC-LC audio * Use local variables inside the bits_per_pixel_func() and bits_per_block_func() functions * Added support for yadif=2 deinterlacing mode which skips spatial interlacing checking * Added support for interlacing of progressive content with the 'tinterlace' filter combined with 'phase'. Note that only 50 fps progressive PAL and 59.94 fps progressive NTSC content is supported! When interlacing such content, the frame rate will be dropped to 25 fps for PAL and 29.97 fps for NTSC * AAC audio: don't exit if the user has provided a bitrate which is higher than the maximum allowed bitrate by some portable devices. Instead fall back to 128 kbps * Colorspace conversion does not work with deinterlacing and interlacing filters so disable it if the user uses some of these filters. Also disabled colorspace conversion for the portable device presets (iPod, PSP, Zune) * Improvements to the audio codecs code. Switched from the 'if' conditional to the 'case' conditional. Makes the code much easier to read/manage * Changed variables $scaler, $iss, $ss_parameters and $accurate_vertical to $sws, $isws, $swsparam and $swsaccurate * Changed the order of the video filters. The softskip filter should come after filters which need to see duplicate or skipped frames in order to operate correctly. This includes any filter that does temporal processing, like the temporal denoiser, hqdn3d/denoise3d/ow and all the inverse telecine filters. The softskip filter should also come before scaling so that the scale filter will be skipped if a frame is going to be dropped. Deinterlacing or pullup should be done before cropping. The harddup filter should be placed before the telecine one so that duplicate frames will never get telecined, we don't want that. The interlace filters should be placed after the softskip and scale filters and before the harddup filter. * Updated the 'hwcompat_preset.cfg' preset file. Decreased frameref to 3 to not cause problems for some players. Also removed unneeded options, increased B-Frames usage to 10, increased me_range to 24 and added some extra comments * Improvements to the DVD chapters exporting code. The user no longer needs to provide a path/filename to export the chapters to disk. As of now, the path and filename are automatically detected and set based on the provided output file name and path for the encoding * Improved the chapters loading code for the MP4/MKV containers * Some modifications to the 'sed' parsing * Updated the man page 2008-01-05 - h264enc 8.0.5 * Added a 'hwcompat_preset.cfg' preset file which is compatible with stand-alone hardware players. If you plan to play your encoded content on a stand alone player, then you can load and use this preset with h264enc. Look in the 'doc' directory for it * Added support for the Motion Compensating Deinterlacer (mcdeint) combined with Yadif * Renamed variable $ilaced to $interlaced * Increased B-Frames usage with 2 in the quality presets * Disabled asking for custom matrices if the user uses the ulq, elq, vlq, lq, mq, nq and the nlq presets. As these presets are not High profile, they are not allowed to use custom matrices. * Added support for setting the audio volume gain with the 'volume' filter * Disabled automatic scanning of input video files to see if they hold up more than one video stream. Some MPEG-TS files can cause troubles for h264enc which will enter into an endless loop when scanning for multiple video streams * Updated the man page 2008-01-02 - h264enc 8.0.4 * Added support for loading a custom preset file. As of this version, the package includes a 'preset.cfg' skeleton file which you can use as reference to write your own custom presets and load them with h264enc. Please read through the notes of the 'preset.cfg' file which is located in the doc directory. * Added support for colorspace conversion during scaling * Added support for the older 3D denoise filter (denoise3d) * Added support for the Temporal Denoise filter (tn) * Changed $use_threads variable to $threads * Changed H.264's in-loop deblock variable from $deblockparam to $deblock * Changed the video filters variables $denoise and $deblock to $denoisefilter and $deblockfilter * Merged the $srate variable with the $resample * Small improvements to the fps detection code * Some cleanups/cosmetic changes * Updated the AUTHORS file * Updated the man page 2007-12-23 - h264enc 8.0.3 * Added support for the Temporal Chroma Strength parameter in the hqdn3d denoise filter. * Added support for the new Overcomplete Wavelet Denoise filter. This filter is very new and still not optimized so it is extremely processor intensive! * Added two XBOX 360 video presets (xvp and xhqvp) * Removed MP3 support for the Sony PSP presets as MP3 audio is not officially supported. * Placed all video filters in a single variable called $videofilters. Since all filter settings are the same for all encoding passes, we place them in a single variable to reduce code duplication in the mencoder_opts() function. The same goes for the audio filters which are now carried by the $audiofilters variable. This also reduces filters maintenance for each pass. * Optimized the options exporting code. Now if the user uses presets and wants to export the MEncoder options to a file, the default output name of the file will be h264enc-preset-outputname (where 'preset' is the chosen preset and 'outputname' is the name of the output file). If no presets are used, then the default output name of the file will be h264enc-options-outputname. * Updated the man page. 2007-12-22 - h264enc 8.0.2 * Added support for the spp, uspp, fspp and pp7 postprocessing deblock filters. This removes support for the old 'pp' postprocessing filters and replaces them with the new and more efficient ones. It also fixes the nasty hack in the video_deinterlace_func() function and removes code duplication for DVD and video files in that function. * Removed variables $yadif and $kerndeint as they are no longer required because of the changes above. All deinterlacing filters are now carried by the $deintfilter variable. Deblock/dering filters are carried by the $deblock variable. * Added support for deringing/deblocking of DVDs. Although not really useful for most DVDs, in some rare cases it can be handy, like for custom made DVDs with a very low bitrate and blocking artifacts. * Added support for denoising of input video files. * Tuning to the NLQ preset * Video functions reordering. * Updated the README.h264enc file. * Updated the man page. 2007-12-21 - h264enc 8.0.1 * Changed contact email address * Forced MPEG-4 in AAC audio for the iPod profiles as MPEG-2 is not compatible with the iPod devices * Placed most of the audio codecs code into functions for easier integration in possible future video profiles for portable devices * Included the Prestige matrix in the package which can be used on grainy sources * Added two Sony PSP video profiles (pspvp and psphqvp) * Added two Sony PS3 video profiles (ps3vp and ps3hqvp) * Added two MS Zune video profiles (zvp and zhqvp) * Added warning notification when using more than 4 frame references as it can cause problems on stand-alone players and/or hardware accelerated video cards. This is only valid for HD 1080p resolutions (1920x1080) * Added presets_keyint_func() function for the quality presets which automatically detects and sets the correct minimum and maximum keyframe intervals based on the chosen or detected FPS value * Updated the man page * Small cleanups 2007-12-15 - h264enc 8.0.0 * Disabled asking for optimization of the MP4 file layout if the user has chosen to embed subtitles in the container. If optimization is ran on a MP4 file with embedded subtitles, the subtitles will all be black and unreadable * Bugfix: moved the MP4 output variable before the optimization function as it is required by the function but won't be detected if it comes after * Added a 'nice' value of 10 when remuxing to the MKV and the MP4 containers * Merged the vobsubout and the vobsuboutindex variables 2007-12-14 - h264enc 7.9.9 * Removed support for the old mkvmerge 1.x versions * Added support for importing ripped VobSub subtitles into the Matroska and the MP4 container * Improved the chapters loading code. Now spaces in file names are supported when importing a chapters file * Added -sc switch for sanity check. This will check for the programs which are required for the correct operation of the script and it will print the status in a list. It will also display which audio codecs are supported by MEncoder. * Some cleanups * Updated the man page 2007-12-06 - h264enc 7.9.8 * Updated the M4G matrices * Small tweaks to the HQ, VHQ, EHQ and UHQ presets * User request: add support for subtitles for input video files. Useful if user wants to get the subtitles from a VOB file on disk 2007-12-01 - h264enc 7.9.7 * Added support for importing chapters information from a file when remuxing into the MP4 container. * Changed default output name for the chapters file from 'h264chapters' to 'h264chaps' * Added destination directory checking when exporting DVD chapters to a file 2007-11-30 - h264enc 7.9.6 * Added support for exporting all chapters information from a DVD to a file. This requires 'dvdxchap' from 'ogmtools' * Added support for importing chapters information into the Matroska container when remuxing 2007-11-15 - h264enc 7.9.5 * Enabled MP2 audio support for the MP4 container * Removed global_header from the iPod profiles as it crashes MP4Box 2007-11-12 - h264enc 7.9.4 * User request: Improved the DVD chapter code. Now each available chapter is displayed in a menu list together with its start position. This requires MPlayer 1.0rc2 so please upgrade to use this feature! * Some cleanups 2007-11-07 - h264enc 7.9.3 * Added vbv_maxrate, vbv_bufsize and global_header to the x264 options for the iPod presets * user request: when exporting the MEncoder parameters to a file, if the file already exists, do not overwrite it but just append the new parameters to it * Increased the crop scanning from 15 to 30 frames for a better detection of the crop values * Typo fix in the help section of the script 2007-10-26 - h264enc 7.9.2 * Added iPod High-Quality Video Profile preset (iHQVP) * Tuning in the iPod Video Profile preset (iVP) * Updated the man page 2007-10-25 - h264enc 7.9.1 * Added iPod Video Profile preset (user request). I cannot guarantee that this preset will work on all iPods as I do not have one to test with. Any feedback is welcome * Modified the audio codec code to only allow AAC audio for the iPod preset * Modified the video bitrate calculation for a target file size to support the iPod preset * Set the audio resample filter to always use 48 kHz for the iPod preset * Audio bitrate and video resolution checks for the iPod preset (audio may not exceed 160 kbps, resolution may not be higher than 640x480) * Cleanups * Updated the man page 2007-10-05 - h264enc 7.9.0 * Added support for loading of custom quantization matrices when using quality presets (user request) 2007-09-14 - h264enc 7.8.9 * Bugfix: wrong variable $VIDFP used in the bits_per_pixel_func function. Should be $VIDFPS or the function will error out when printing the BPP if user wants to calculate the video bitrate. 2007-08-31 - h264enc 7.8.8 * Disabled alias expansions in the shell, just in case it might interfere with aliases in the .bashrc file * Added support for the FLAC audio codec (user request) * Changed the way the -o option operates (user request) * Updated the man page 2007-08-15 - h264enc 7.8.7 * Removed the audio surround filter in AC3 since it's not really useful and is only used on video files with matrix encoded audio * Rewrote the audio_volnorm_func() function because of the changes made to the audio filter chain * Added condition to check if any audio filters are used so we can add the -af option to the MEncoder parameters * Added audio_channels_func() function for AC3, AAC, PCM and COPY * Some small cleanups * Manual codec config: trellis quantization requires CABAC so disable it if user doesn't use CABAC * Some small tweaks to the quality presets; enabled RDO for B-Frames in the vhq preset * Faster code to detect FPS values * FPS: now both fractions (for Progressive NTSC/NTSC) and integer for (PAL/SECAM) are supported * Changed Megabyte to Mebibyte in video bitrate calculation 2007-08-08 - h264enc 7.8.6 * Added the harddup filter at the end of the filter chain to further eliminate possible A/V sync problems when muxing to the MKV and/or MP4 containers * Disabled the check_video_filters_func() function as it is made obsolete by the harddup filter since this filter will always be appended to the filter chain and the -vf option will always be required even if no other filters are used * Added support for channel selection when using audio stream copy * Manual codec config: disabled deadzones if user uses trellis quantization since they don't work with it * Added support for encoding from a different DVD angle * Now video bitrate calculation for a target file size works with audio stream copy * Disabled asking for telecine/inverse telecine if content is PAL/SECAM * Updated the man page 2007-08-05 - h264enc 7.8.5 * Fixed a potential problem in the inverse telecine/pullup code where A/V could get out of sync due to missing -fps 30000/1001 value * Enabled audio encoding for first pass in 2- and 3-pass mode. After extensive testings, without audio encoding for the first pass, MEncoder can break A/V sync, especially when doing a inverse telecine/pullup process where frame dropping and duplicate frames are involved. * Squashed a bug in the subtitle code which hardcoded the subtitles into the movie even if user has selected to dump them to files on disk * Added support for the DETC inverse telecine filter * Added warning notification if resolution width and/or height is not divisible by 16 as compression will suffer * Moved the call to the check_video_filters_func() function outside of the scaling section * Only ask for telecine/inverse telecine filters if user doesn't use interlaced encoding as it is mutual exclusive with it * Switched to turbo=2 for 2- and 3-pass modes when using quality presets as quality loss is almost unmeasurable compared to turbo=1 2007-07-30 - h264enc 7.8.4 * Added support for the Yadif deinterlacing filter * Added support for Donald Graft's adaptive kernel deinterlacing filter * Added support for Pulldown Reversal/Inverse Telecine. Please read the FAQ at http://h264enc.sourceforge.net on how and when to use these filters! Currently 3 filters are supported, the pullup, filmdint and ivtc filters * Added support for Hard Telecine/3:2 Pulldown. Again read the FAQ on how and when to use it, if at all! * Reverted back to fractions for FPS values. According to MPlayer's doc, integer/float should not be used anymore with MEncoder. This change also updates the bits_per_pixel_func(), bits_per_block_func() and keyframe variable * Due to the high versioning, as of this version, h264enc will continue to use a microversion. When I started writing the script, I didn't think of going public with it so that's why versioning wasn't important... * Updated the man page 2007-07-28 - h264enc 7.8.3 * Enabled turbo mode in first pass for 2- and 3-pass modes in the mq, nq, hq, vhq, ehq and uhq quality presets. This will speed up the first pass up to 3x withouth hurting the quality of the second or third pass. * Changed QP to CRF for first pass in 2- and 3-pass encodings as CRF is much more efficient/intelligent than QP 2007-07-27 - h264enc 7.8.2 * Changed shell interpreter from /bin/sh to /bin/bash as there were some problems reported by Ubuntu/Debian users. Sorry for the inconvenience 2007-07-26 - h264enc 7.8.1 * Merged the -bpp and -bpb options * Added bitrate calculation to the -bpp option which is based on the bits per pixel value * Fixed a bug in the video bitrate calculation for a target file size. If user has chosen to encode a video file which has more than one video stream in it, and if the selected video stream for encoding is not the first one, the calculated bitrate will be wrong as the $vid variable was missing thus mplayer will get the length of the first video stream instead of the stream selected by the user 2007-07-25 - h264enc 7.8 * Updated the AAC part of the audio resample function. In addition to 48000 and 96000 Hertz, AAC also supports 64000 and 88200 Hertz * Some parenthesis changes * Added support for optimizing the MP4 file layout with mp4creator. This is not a hard dependency! If mp4creator is missing, this option will be skipped. h264enc still uses MP4Box for MP4 muxing * Changed the output FPS format to integer and float * Updated the bits_per_pixel(), bits_per_block() and keyframe to support the new integer/float FPS format * Disabled converting the final AVI to MKV if user has chosen to use the AAC audio codec. I've spoken to Moritz Bunkus, the author of mkvmerge, and he confirmed that at the moment he hasn't found a way yet to extract the AAC headers from AVIs so for the time being, it is not possible to convert AVIs with AAC audio to the Matroska container. * Added backwards compatibility for mkvmerge versions < 2.0.0 which do not officially support H.264 video in AVIs unless forced with the '--engage allow_avc_in_vfw_mode' option * Added support for input video files which contain more than one video stream. Note that cropping won't be auto-detected on any other stream except on the first one (stream 0) as MPlayer seems to have issues with the -sstep option and I still haven't got an answer from the developers on how to fix it * Converted the get_filesize_func() function from integer to float for more accurate file size reportings * Changed bitrate mode for first pass of 2-pass and first and second pass of 3-pass encoding to use the QP constant instead of chosen bitrate. This may not be compatible with older versions of libx264, so please upgrate to a recent version if 2- or 3-pass errors out * Updated the AUTHORS file * Updated the man page 2007-07-20 - h264enc 7.7 * Implemented user_interrupt_func() function for when the user hits CTRL+C or CTRL+ALT+C * Added support for displaying the DVD disc title * Some improvements to the config directory code * Some tweaks to the presets * Updated the MKV conversion code. This requires at least version 2.0.2 of mkvmerge if you want to convert AVIs to MKV. mkvmerge 2.0.2 and up officially supports H.264 video in vfw AVIs and the option '--engage allow_avc_in_vfw_mode' is removed * Changed default ABR AAC bitrate from 140 to 110 since AAC is much more efficient * Implemented -bpp option for calculating the Bits Per Pixel values Many thanks to Aymeric for the help on this one * Implemented -bpb option for calculating the Bits Per Block values * Updated the man page 2007-07-13 - h264enc 7.6.1 * Fixed a bug in the bits_per_block_func() function. The formula was wrong which made this function display incorrect bpb values * Fixed a typo in the man page 2007-07-12 - h264enc 7.6 * Fixed a typo in the help section - thanks to Adam for pointing out * Added bits_per_block_func() function for calculating and displaying how many bits are used for each 16x16 macroblock * Updated the MKV and MP4 container conversion code. Now user can convert the AVI to both formats, not just only one of them * Complete rewrite of the file splitting code. Removed the 702 MB requirement before the split option kicks in. The new splitting code is much more flexible now despite of its large size. Now if user has chosen to convert the AVI to MKV or to MP4 or to both formats, he can choose which formats to split * Updated the destination output checking code. Now this code respects user permissions and warns the user and exits if creation of the destination directory has failed * Added support for dumping subtitles to a file on disk * Added support for AAC object type complexity profiles * Updated the AUTHORS file * Updated the README.h264enc file 2007-07-05 - h264enc 7.5 * Web site launched for h264enc at http://h264enc.sourceforge.net * Fixed a small bug in the Matroska code * Added bits_per_pixel_func() function for calculating and displaying the BPP value based on video bitrate, width, height and FPS * More tuning to the presets * Updated the man page 2007-07-04 - h264enc 7.4 * Added Near Lossless Quality (NLQ) preset. This preset is supported only in fixed-quant mode! * Updated the man page 2007-07-02 - h264enc 7.3 * Fixed a severe bug in the MP4 muxing code. MP4Box by default falls back to 25 FPS for video content and doesn't do auto detection. If the input source has a different FPS value, like in NTSC or Prograssive Scan, not passing the correct value to MP4Box will result in severe audio/video desync. * Moved global headers option inside the manual configuration 2007-07-01 - h264enc 7.2 * Fixed a bug in the audio_resample_func() which didn't recognize the WMA audio codec * Added support for 96 kHz sampling for AAC audio to the audio_resample_func() function * Added support for Multi-channel AAC audio encoding. Note that this can introduce bitrate variations into the audio stream so that video bitrate calculation for a target file size won't be very accurate! * Added support for both MPEG formats supported by AAC audio (MPEG2 and MPEG4) * Merged code of the WMAv1 and WMAv2 audio codecs into one * Updated the man page 2007-06-28 - h264enc 7.1 * Added support for the WMAv1 and WMAv2 audio codecs. Note that this requires latest version of SVN MPlayer or MPlayer 1.0rc2 as previous MPlayer versions do not support encoding to the above mentioned audio codecs. * Updated the man page and README.h264enc file 2007-05-31 - h264enc 7.0 * Implemented '-p help' option for quick help on quality presets usage. Now user can use 'h264enc -p help' to get a quick help on presets and how to use them. * Added one more quality preset (Normal Quality (NQ)) and changed recommended presets to 'nq' and 'hq' from 'mq' and 'hq' * Added support for converting AVI's to the MP4 format. This requires MP4Box from gpac and only works with MP3/AAC audio or NOSOUND as MP4Box doesn't support the other audio codecs. User can only convert the final AVI if conversion to Matroska is not selected! (you can't do both) * Added audio_codec_in_video_file_func() function. This function will only be used for input video file encodings and only if user wants to copy the audio (no re-encoding). It will scan the input video file for its audio codec and if it detects MP3 or AAC audio, it will set a flag so that the user can convert the encode to MP4 afterwards (if he wants to). This will not work though if the input video file has more than 1 audio channel (like in mkv files) and the user has selected a audio channel other that the first one. It will also not work if input video file has no audio in it. * Modified the file splitting code to support the MP4 format * Added support for checking disk space left over in the destination output directory and the h264enc config directory. If < 4 GB then user will be warned that he's running out of disk space in one of the directories * Removed obsolete checking for resolution format since the $scale variable translates it to the correct MEncoder format no matter if user uses a : or x for the resolution * Decreased default difference threshold deblocking value for video files to 70 as a too high value can smear details too much * Removed an extra "layer" of piping in variables. There's no need to "cat" a file and then pipe the output to "grep" to get a specific value from that file as "grep" can do it by itself. No need to do $(cat /path/to/file/file_name | grep "value") instead use $(grep "value" /path/to/file/file_name) * Small cosmetic changes * Updated the man page 2007-05-25 - h264enc 6.5 * Removed duplicate and long standing $turbo variable in the MEncoder parameters for 2- and 3-pass modes * Added informant display_quality_preset_func() function * Improved resolution code. Now if user has chosen to crop the input source, default resolution value will fall back to the visible resolution area after cropping, (eg, the left over area of the resolution after removing the black bands with the crop filter). If no cropping selected, default resolution value will be the original one from the input source * Small tuning in the quality presets * Added support for encoder priority settings ("nice" values) * Fixed a small bug in the cropping function that will fail if user wants to crop a video file which contains spaces in its file name * Updated the man page 2007-05-23 - h264enc 6.4 * Implemented 9 different video quality presets * Updated the man page 2007-05-22 - h264enc 6.3 * Added support for displaying available devices from /proc/sys/dev/cdrom/info * Added support for video file cropping * Updated the audio resample function 2007-05-14 - h264enc 6.2 * Improvement in the DVD unlocking code * Improvement in the chapter and subtitle scanning code * Improvement in the DVD audio channel scanning code * Improvement in the aspect ratio detecting code for MKV conversion 2007-05-08 - h264enc 6.1 * Added support for audio channel selection in video files * Decreased internal scanning time point for FPS detection * Updated the man page 2007-04-20 - h264enc 6.0 * Only check for lsdvd if user wants to encode a DVD * Added support for AC3 Dynamic Range Compression * Updated the man page 2007-04-06 - h264enc 5.9 * Updated the cropping and video bitrate calc code to support SVN MPlayer * Updated detection of aspect ratio for mkvmerge to support SVN MPlayer * Added Subpel Refinement Quality explanations * Moved 'mixed framerefs' option after the 'frameref' one * Moved check_video_filters_func() * More cleanups 2007-04-03 - h264enc 5.8 * Rewrote the DVD cropping code (more precise now) * Removed the '-q' option of mkvmerge for more verbose output * Small cleanups 2007-03-20 - h264enc 5.7 * Added basic support for muxing the final AVI file into Matroska container (requires mkvmerge) * Modified the splitting code to support the Matroska container * Updated the man page 2007-03-18 - h264enc 5.6 * Further improvements to the options saving code * Fixed a bug in the video bitrate calculation (missing $device variable) * Small improvements to the DVD displaying code * Moved passlog files to $CONFIGDIR 2007-03-13 - h264enc 5.5 * Improvements to the options exporting code * Fixed FPS detection for video files * Implemented automatic video bitrate calculation based on target size, video length and chosen audio bitrate * Updated the man page 2007-03-11 - h264enc 5.4 * Added support for displaying all DVD titles (user request) * Added support for inspecting MEncoder options before encoding (user request) * Added support for exporting all MEncoder options to a file * Added support for loading script generated options from a file for debugging purposes * Temporary files go to $HOME/.h264enc now instead of /tmp * Updated the man page 2007-03-09 - h264enc 5.3 * Improvements to the threading code * Added count function before encoding * Compound command changes 2007-03-02 - h264enc 5.2 * Added support for thread encoding (useful for SMP/Multicore CPUs) * Target directory checking and creation * Small cleanups 2007-02-11 - h264enc 5.1 * Added more matrices from MP4Guy to the package * Added MEncoder flags to options for more clarity * Updated the man page 2007-02-06 - h264enc 5.0 * Added EQM-AVC-HR matrix file to the package * Improved matrix loading code * Improved DVD or video file checking * Updated the man page * Updated the install script * Added README.matrix file * Organized the package 2007-02-04 - h264enc 4.9 * Added support for auto-detecting frame rate value * Overall small code improvements 2007-02-02 - h264enc 4.8 * Fixed a bug in the check_video_filters_func function * Fixed a small bug where script leaves the resolution temp file after getting the values * Added support for predefined/custom quantization matrices * Added support for bypassing audio encoding (useful for muxing video into other containers and/or with other audio file) * Improvements to the resolution detection code 2007-01-31 - h264enc 4.7 * Added support for auto resolution detection * Added support to bypass scaling if user decides to use original source resolution * Further improvements to the DVD title scanning and cropping code * Improvements in the audio codec checking code (placed it into a function) * Small improvements to the high-quality denoise filter code * Small improvements to the default encoding values of the script * Updated the man page 2007-01-30 - h264enc 4.6 * Added support for displaying all available DVD audio channels * Added support for chapter scanning for the chosen DVD title * More improvements to the DVD subtitle, title scanning and cropping detection * Small improvements to the in-loop deblocking filter code * Temporary files go to /tmp now instead of user's home directory * Updated the man page * Updated the README.h264enc file 2007-01-28 - h264enc 4.5 * Improved the DVD title scanning code (if DVD is locked, 'lsdvd' will fail to read it so mplayer must unlock the DVD before running 'lsdvd') * Improved the subtitle code * Added support for auto-detecting DVD cropping values 2007-01-27 - h264enc 4.4 * Added support for auto-selecting the longest DVD title using 'lsdvd' * Added support for displaying available DVD subtitles * Updated the README.h264enc file * Updated the man page 2007-01-17 - h264enc 4.3 * Added support for 3-pass encodings * Fixed a bug in 2-pass encoding mode (turbo variable was missing) * Updated the man page * Updated the README.encoding file 2007-01-15 - h264enc 4.2 * Added input/output file name checking for video file encodings * Improved the output frame rate code 2007-01-10 - h264enc 4.1 * Fixed a bug where the device variable won't work if empty 2007-01-08 - h264enc 4.0 * Default min/max keyframe intervals are now auto-calculated from the output frame rate value * Only ask for the internal H.264 noise reduction filter if user didn't use the default MEncoder filter * Improved the output frame rate code * Improved MEncoder/libx264 checking * Fixed a typo in the help section * Overall small improvements * Updated the man page * Updated the README.encoding file 2007-01-05 - h264enc 3.9 * Added support for difference and flatness deblocking thresholds * Rewrote the output frame rate code (uses now video standard formats - PAL/SECAM/NTSC/Progressive NTSC) * Changed default B-Frames value from 2 to 3 * Updated the man page 2007-01-04 - h264enc 3.8 * Improved the splitting section (only ask user for splitting if file size is > 702 MB) * Added man page to the package * Updated Copyright dates * Updated the README.h264 file * Updated the install script 2006-12-22 - h264enc 3.7 * Moved the audio volume normalizing into a function * Added support for both fixed-quant modes (QP and CRF) 2006-12-20 - h264enc 3.6 * Changed default format of output FPS to float * Small overall improvements 2006-12-17 - h264enc 3.5 * Little code improvements for better error reporting 2006-12-15 - h264enc 3.4 * Added support for chroma quantizer offset * Small code cleanups 2006-12-14 - h264enc 3.3 * Fixed a major bug in the MP3 filter config code where it won't work if user has chosen to resample the audio (-af was missing - the bug was introduced while fixing the code of the volnorm and resample filters) * Changed default AAC quality to 200 * Updated the README.h264enc file 2006-12-14 - h264enc 3.2 * Fixed the volume normalizing filter (should come before the resample filter) * Fixed the surround filter for video files (should come before the resample filter) * Rewrote the MP3 code (much smaller and cleaner now) * Added support for MP3 channel modes * Added support for MP3 lowpass and highpass frequency filtering * Updated the README.encoding file 2006-12-13 - h264enc 3.1 * Fixed a small bug in the RD B-Frames code where it was still used even if B-Frames were disabled * Fixed a bug in the audio resample function where it won't work if user has chosen to use the AAC codec * Added support for Adaptive PCM audio encoding (ADPCM) * Enabled the volume normalizing audio filter to do precise calculations * Added support for accurate rounding of the vertical software scaler * Small improvements to the install script * Updated the README.h264enc file 2006-12-12 - h264enc 3.0 * Fixed a bug in the deblocking settings where the 'deblock' option was used twice if user has chosen to tune the deblocking parameters of the filter * Fixed a bug in the B-Frames code where B-Frames options/questions were still used/asked even if user has specified not to use B-Frames by providing 0 when asked * Added support for AAC audio encoding (Advanced Audio Coding) * Small improvements to the install script * Updated the README.h264enc file 2006-12-12 - h264enc 2.9 * Added support for displaying SSM statistics after encoding 2006-12-11 - h264enc 2.8 * Changed default AC3 bitrate to 192 * Small fixes/improvements all over the place * Improvements to the install script 2006-12-09 - h264enc 2.7 * Added install/uninstall script * Added info/encoding tips to the package (README.encoding) * Little code cleanup * Updated the README.h264enc file 2006-12-08 - h264enc 2.6 * Added support for tuning the software scalers * Made the deinterlacing code a function (commonly shared between the 2 input sources) * Updated the README file 2006-12-07 - h264enc 2.5 * Moved quantizer compression/temporal blur to a different place * Small improvements to the splitting code * Added support for advanced options for experienced users, which includes - Bitrate tolerance - VBV maximum bitrate - VBV buffer size - Initial buffer occupancy - Inter luma quantization deadzone - Intra luma quantization deadzone - H.264 bitstream level 2006-12-07 - h264enc 2.4 * Changed default quantizer in fixed quant mode from 18 to 20 * Added support for Minimum Keyframe Intervals * Updated the README file 2006-12-06 - h264enc 2.3 * Rewrote the file splitting code * Various small improvements 2006-12-06 - h264enc 2.2 * Fixed default output name (was XviD.avi due to code sharing with the xvidenc script) * Added checking if output file exists 2006-12-06 - h264enc 2.1 * Squashed a severe bug in the fixed quant selection code (qp_constant is replaced by qp in MEncoder) * Quantizer compression only supported in 1- or 2-pass (what am I doing?) * Added support for Quantizer stepping * Added support for custom output file names * Added initial support for splitting files using avisplit from transcode 2006-12-05 - h264enc 2.0 * Fixed a typo in the cropping explanation text * Added support for all subtitle anti-aliasing modes * Changed default FPS value to 26000/1001 (25 FPS) * Fixed the Quantizer compression code (only supported in ABR or 2-pass) * Added support for AlphaC0 and Beta deblocking parameters * Rewrote the denoise filter code 2006-12-04 - h264enc 1.9 * Removed checking for 'bc' and 'tr' from the code as they are no longer needed * Added support for Scenecut * Added support for I/P/B-Frames factors 2006-12-04 - h264enc 1.8 * Fixed a bug in the resolution checking code * Improved the cropping code * Small code optimizations 2006-12-01 - h264enc 1.7 * Optimizations in 2-pass logfile code * Added support for output FPS 2006-11-29 - h264enc 1.6 * Initial public releaseh264enc-9.3.7~dfsg/doc/LICENSE0000644000175000017500000004310311215474717015411 0ustar alessioalessio GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. h264enc-9.3.7~dfsg/doc/README.h264enc0000644000175000017500000000560111223721366016427 0ustar alessioalessio ================================================= | h264enc - the interactive shell script ripper | ================================================= 1) Why a script? - Because GUI programs take a lot of time to write and debug/optimize - Because GUI programs eat more memory - Because GUI programs do nothing for 90% of the encoding process - Because scripts are a lot easier to read/write/debug - Because I love shell scripting :) 2) Introduction h264enc is a shell script which can be used to encode DVDs or video files to the H.264 format, also known as AVC (Advanced Video Coding) or MPEG-4 Part 10, using the encoding utility 'MEncoder' from 'MPlayer'. There is also a Web site available for h264enc at http://h264enc.sourceforge.net The script supports all the useful options an end-user would need to make a successful encode. Things like software scaling, deblocking/deringing of video files, DVD deinterlacing, DVD cropping, DVD denoising, DVD subtitle inclusion, interlaced DVD encodings, and various audio codecs like MP3, AC3, AAC, AAC+, Vorbis, FLAC and PCM are supported as well. There's a man page which provides further info on the h264enc script. To access it after installation, open a console and type "man h264enc" without the quotes. Note: instead of typing 'n' every time you don't want to use a specific option, you can just hit enter. I also suggest to read the x264 part of the MPlayer man page so you can get more familiar with what a specific option does as most of the x264 options supported by this script may have a huge impact on quality/encoding speed. To obtain best performance, I suggest to download MPlayer and the libx264 library and compile them yourself. You should use the appropriate CFLAGS at compilation time to optimize the code for your hardware architecture (example: CFLAGS="-O3 march=athlon-xp mtune=athlon-xp -finline-functions -freorder-blocks -fexpensive-optimizations") For more info on the MPEG compression, read the 'README.encoding' file 3) Requirements - MPlayer/MEncoder >= 1.0rc2 (http://www.mplayerhq.hu) - lsdvd (http://sourceforge.net/projects/lsdvd) - mkvtoolnix (http://bunkus.org/videotools/mkvtoolnix/) - gpac (http://gpac.sourceforge.net/) - ogmtools (http://www.bunkus.org/videotools/ogmtools/) - libx264 (ftp://ftp.videolan.org/pub/videolan/x264/snapshots) - LAME (http://www.mp3dev.org) - FAAC (http://www.audiocoding.com/) - neroAacEnc (http://www.nero.com/eng/down-ndaudio.php) - aacplusenc (http://teknoraver.net/software/mp4tools) - Vorbis (http://www.vorbis.com/setup_linux/) - FLAC (http://flac.sourceforge.net/) - Pipeviewer (http://sourceforge.net/projects/pipeviewer) - tsMuxeR (http://www.smlabs.net/tsmuxer_en.html) 4) Installation Just run the 'install' script as root, or copy the h264enc script to a valid path (eg /home/your_username/bin) Note: this only applies if you have downloaded the compressed 'h264enc.tar.gz' package, not the RPM one h264enc-9.3.7~dfsg/doc/README.encoding0000644000175000017500000001657211215474717017063 0ustar alessioalessio =========================================== | ENCODING TIPS FOR MPEG TYPE COMPRESSION | =========================================== Always do a 2 or 3-pass encode if you can ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The complexity (and thus the number of bits) required to compress the frames of a movie can vary greatly from one scene to another. Modern video encoders can adjust to these needs as they go and vary the bitrate. However, they cannot exceed the requested average bitrate for long stretches of time, because they do not know the bitrate needs of future scenes. 2-pass encoding solves this problem by encoding the movie twice. During the first pass, statistics are generated regarding the number of bits used by each frame and the quantization level (quality) at which it was encoded. Then, when the second pass begins, the encoder reads these statistics and redistributes the bits from frames where they are in excess to frames that are suffering from low quality. In order for the process to work properly, the encoder should be given exactly the same sequence of frames during both passes. This means that the same filters must be used, the same encoder parameters must be used (with the possible exception of bitrate), and the same frame drops and duplications (if any) must take place. Always crop the black borders of a DVD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Due to the nature of MPEG-type compression, there are various constraints you should follow for maximal quality. MPEG splits the video up into 16x16 squares called macroblocks, each composed of 4 8x8 blocks of luma (intensity) information and two half-resolution 8x8 chroma (color) blocks (one for red-cyan axis and the other for the blue-yellow axis). Even if your movie width and height are not multiples of 16, the encoder will use enough 16x16 macroblocks to cover the whole picture area, and the extra space will go to waste. So in the interests of maximizing quality at a fixed filesize, it is a bad idea to use dimensions that are not multiples of 16. Most DVDs also have some degree of black borders at the edges. Leaving these in place can hurt quality in several ways. - MPEG-type compression is also highly dependent on frequency domain transformations, in particular the Discrete Cosine Transform (DCT), which is similar to the Fourier transform. This sort of encoding is efficient for representing patterns and smooth transitions, but it has a hard time with sharp edges. In order to encode them it must use many more bits, or else an artifact known as ringing will appear. - The frequency transform (DCT) takes place separately on each macroblock (actually each block), so this problem only applies when the sharp edge is inside a block. If your black borders begin exactly at multiple-of-16 pixel boundaries, this is not a problem. However, the black borders on DVDs rarely come nicely aligned, so in practice you will always need to crop to avoid this penalty. In addition to frequency domain transforms, MPEG-type compression uses motion vectors to represent the change from one frame to the next. Motion vectors naturally work much less efficiently for new content coming in from the edges of the picture, because it is not present in the previous frame. As long as the picture extends all the way to the edge of the encoded region, motion vectors have no problem with content moving out the edges of the picture. However, in the presence of black borders, there can be trouble: - For each macroblock, MPEG-type compression stores a vector identifying which part of the previous frame should be copied into this macroblock as a base for predicting the next frame. Only the remaining differences need to be encoded. If a macroblock spans the edge of the picture and contains part of the black border, then motion vectors from other parts of the picture will overwrite the black border. This means that lots of bits must be spent either re-blackening the border that was overwritten, or (more likely) a motion vector will not be used at all and all the changes in this macroblock will have to be coded explicitly. Either way, encoding efficiency is greatly reduced. Again, this problem only applies if black borders do not line up on multiple-of-16 boundaries. - Finally, suppose we have a macroblock in the interior of the picture, and an object is moving into this block from near the edge of the image. MPEG-type coding cannot say "copy the part that is inside the picture but not the black border." So the black border will get copied inside too, and lots of bits will have to be spent encoding the part of the picture that is supposed to be there. If the picture runs all the way to the edge of the encoded area, MPEG has special optimizations to repeatedly copy the pixels at the edge of the picture when a motion vector comes from outside the encoded area. This feature becomes useless when the movie has black borders. Unlike problems 1 and 2, aligning the borders at multiples of 16 does not help here. - Despite the borders being entirely black and never changing, there is at least a minimal amount of overhead involved in having more macroblocks. For all of these reasons, it is recommended to fully crop black borders. Further, if there is an area of noise/distortion at the edge of the picture, cropping this will improve encoding efficiency as well. Videophile purists who want to preserve the original as close as possible may object to this cropping, but unless you plan to encode at constant quantizer, the quality you gain from cropping will considerably exceed the amount of information lost at the edges. Do not scale down too much ~~~~~~~~~~~~~~~~~~~~~~~~~~ Scaling is always been an issue in MPEG compression. One might want to scale down a movie for different reasons, to lower the bitrate or file size of the encode. However, the MPEG compression does not like scaling down too much. If you scale down the original source to, lets say, 512x208, then you'll get the annoying stair steps in red colors, though this is not really MPEG's fault but has also to do with software scaling. Every time you see a bright/full red color in the movie, it will have lines (stair steps) in it. Another point in favour of not trying to scale down too much is that the MPEG compression has to compress high frequencies much more than low frequencies and it doesn't like that at all. Choose your software scaler ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you do need to scale down the source, then make sure to choose the right software scaler. For example, if you're going to scale down a lot, I found out that a more blurry image will look much better than a more sharper one. The Bilinear software scaler is very good for hard scaled down content because it will produce much less noise and ringing around objects. Sharp scalers that preserve a lot of image details, like the Bicubic or Bicubic Spline, will produce much more noise/ringing when used in conjunction with a (very) low bitrate and low resolution. Also those scalers will require much more bits to preserve their sharpness/details, thus they are not really recommended when doing low bitrate/hard scaled down encodes. -------------------------------------------------------------------- NOTE: some content is taken directly from the MPlayer documentation. Copyright goes to the author(s) who wrote ith264enc-9.3.7~dfsg/doc/README.matrices0000644000175000017500000001033011215474717017066 0ustar alessioalessio ================================= | H.264 Matrices | ================================= As of h264enc version 5.1, the package includes matrix files from Sharktooth, MP4Guy, Audionut and Soulhunter The "eqm_avc_hr_matrix" file is the Sharktooth Quantization Matrix and is designed for these purposes: - High-quality backups of DVDs at full resolution (anamorphic) and bitrates of at least 1300-1400 kbps - non anamorphic/vertically resized encodes at bitrates of at least 1000 kbps The package futher includes different quantization matrices from MP4Guy, Audionut and Soulhunter. Below follows a short description. mp4guy_lrm_matrix ----------------- The LRM matrix is designed for low to very low bitrate encodes. It is designed to avoid artifacts more than to preserve detail. mp4guy_mrm_matrix ----------------- The MRM matrix is designed to work well at moderate bitrates and sometimes works very well at low or high bitrates. It is designed to keep a fair balance between artifacts and detail. mp4guy_hrm_matrix ----------------- The HRM matrix is for high to very high bitrates. This matrix is also designed to perform well with other bitrates. mp4guy_low_bitrate_matrix ------------------------- This matrix does the following... -Intra more aggresively compressed then inter -Chroma roughly twice as aggressively compressed as luma -High frequencies are dropped aggressively on intra -High frequencies are dropped semi-aggressively on inter mp4guy_high_detail_matrix ------------------------- The high-detail matrix is designed to be very sharp and works best at moderate bitrates. mp4guy_smooth_matrix -------------------- The smooth matrix is an all purpose matrix that blocks very little and gives a similar smooth look like in MPEG2 video. prestige_matrix --------------- This matrix is specifically designed for grainy sources and preserves the grain very well. This matrix is also used on some Blueray DVD titles (The Prestige) xmen3_matrix ------------ This matrix was used when encoding the X-Men 3 movie. It is a rather flat matrix which performs well on clean sources and often on grainy sources as well q_matrix -------- The "q_matrix", coming with the avc reference software, uses the same values in all intra4x4 matrices and the same values in all inter4x4 matrices q2_matrix --------- The "q2_matrix", coming with the avc reference software, uses the same values in all intra4x4 matrices and the same values in all inter4x4 matrices soulhunter_v1_matrix -------------------- This matrix does the following... - It quantizes intra-frames stronger than inter-frames - It drops high frequencys stronger than low ones - It treats the luma and the chroma equally soulhunter_v2_matrix -------------------- This matrix does the following... - It quantizes intra-frames and inter-frames equally - It drops a lot high frequencys in the 4X4 chroma - It generally drops a lot high frequencys audionut_high_bitrate_matrix ---------------------------- As the name says it, this matrix is specifically designed to perform well on high bitrates (>1000 kbps) audionut_general_matrix ----------------------- This is a matrix designed for general use which goes well with low and medium bitrates ======================================================================== You can load a matrix file with the help of the 'h264enc' script if you choose for the 'Advanced Options' option when asked and come to the point where the script asks you if you want to use predefined or custom matrix. Answer 'y', choose for option 2 and provide the full path to the matrix file. I suggest you copy the matrix file to your home directory or to your 'Documents' directory. Example of loading matrix file with h264enc: Provide the Custom Matrix file: /home/your_username/eqm_avc_hr_matrix ======================================================================== By default, when you run the 'install' script of the package, it will install all matrix files in this directory: /usr/local/share/doc/h264enc-/matrices or if you have obtained the RPM package, then the matrix files will be in: /usr/share/doc/h264enc-/matrices or /usr/share/doc/packages/h264enc-/matrices Thanks to Sharktooth, MP4Guy, Audionut and Soulhunter :) h264enc-9.3.7~dfsg/doc/preset.cfg0000644000175000017500000000606111353642664016372 0ustar alessioalessio# # Custom preset skeleton file for h264enc # # This is an example file on how to write a custom # preset file and load it in h264enc. You can # use it as reference for write your own presets # and use them for the encoding. # There's only one variable (x264params) that holds # all the x264 encoder options. Note that the very # first option in that variable *must* begin with a # colon like in the example at the bottom, or else the # options line won't be valid and MEncoder will exit # with an error. You can add or remove any of the x264 # options supported by MEncoder, with the exception of # adding the bitrate/crf, pass and the turbo options # which are added automatically by h264enc, based on # user choice. # # I encourage you to have a look at the x264 part # in the man page of MPlayer if you are uncertain # about some of the options/values. Comments, notes, # etc are preceded by a # character. You can load # this preset and try it out yourself. Use for example: # # h264enc -crf -p cp /path/to/this/preset/preset.cfg # # Some notes: # # - Deadzones do not work when trellis is enabled. # To use them, disable trellis (trellis=0) # # - Trellis does not work when cabac is disabled. # # - b_adapt, b_pyramid and weight_b do not work # when no B-Frames are used (bframes=0). # The same goes for direct_pred # # - mixed_refs only works if frameref is higher # than 1 # # - chroma_me only works with subq of 5 or higher # # - me_range only works with me=umh, me=esa or # me=tesa. It does not work with me=dia or # me=hex # # - Partition type i8x8 only works when 8x8dct # is enabled. # # - weightp does not work in Baseline profile # # - When using vbv_maxrate, vbv_bufsize *must* # be set as well # # - vbv_init only works with vbv_maxrate and # vbv_bufsize set # # - psy_rd requires subq of 6 or higher. First # parameter defines the rate-distortion strength # while the second one defines the trellis strength # and requires trellis to be enabled # # - nopsy disables all psy optimizations that don't improve # PSNR or SSIM. This disables psy-RD/trellis (psy_rd), but also # other more subtle internal psy optimizations that can't be # controlled directly via external parameters # # - nal_hrd is only available if x264 was patched with # the NAL HRD patch. When using nal_hrd, both vbv_maxrate # and vbv_bufsize must be set # # - mbtree does not work yet with b_pyramid enabled and also # produces a large passlog file when ran in 2-pass mode but # can increase quality anywhere between 2-70%, depending on # the content # # - rc_lookahead controls the distance MB tree looks ahead to # perform propagation analysis and requires mbtree being # enabled. Larger values will be slower and require more # memory but give more accurate results # x264params=":force_cfr:frameref=3:mixed_refs:bframes=4:b_adapt=2:b_pyramid=normal:weight_b:weightp=1:direct_pred=auto:aq_mode=1:me=umh:me_range=16:subq=6:mbtree:psy_rd=0.8,0.2:rc_lookahead=50:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto:ssim:psnr" h264enc-9.3.7~dfsg/man/0000755000175000017500000000000011215474717014411 5ustar alessioalessioh264enc-9.3.7~dfsg/man/h264enc.10000644000175000017500000002577011411154456015650 0ustar alessioalessio.\" Hey, EMACS: -*- nroff -*- .\" add new suboption .de IPs .IP "\\$1" .. .TH h264enc 1 "Jun 25, 2010" .SH NAME h264enc \- the interactive shell script ripper .SH SYNOPSIS .B h264enc [\-1p|\-2p|\-3p|\-qp|\-crf|\-b|\-e|\-r|\-sc|\-scan|\-iso|\-spr|\-mfr|\-bpp|\-bpb|\-v|\-help] [\-p ] [preset_file] .br .SH DESCRIPTION \fBh264enc\fR is an advanced and powerful interactive menu-driven shell script which uses the encoding utility \fBMEncoder\fR from the \fBMPlayer\fR project. The script can be used to encode DVDs, (S)VCDs or regular video files to the high-quality H.264 video format (also known as AVC (Advanced Video Coding) or MPEG-4 Part 10). At the moment, the script supports virtually all options of the libx264 library and a variety of audio codecs, including support for \fBup to three\fR DVD audio tracks muxed into the MKV/MP4/OGM/TS containers. \fBh264enc\fR is targeted primarily at power users or users who understand the process of video encoding and want to tweak their settings in order to achieve the best possible quality/file size of their encodes. For more information and a FAQ, visit \fPhttp://h264enc.sourceforge.net\fR .LP \fBh264enc\fR uses a configuration file stored in the user's home directory inside a hidden directory named as .h264enc where the user can enable or disable many of the supported audio/video filters and containers. This can reduce the time it takes to pass through the script when the user disables filters and/or containers he never intends to use. Further, the configuration file stores the paths to the required programs and a few other things like some script options, MPlayer flags and email support. .SH REQUIREMENTS - MPlayer/MEncoder >= 1.0rc2 compiled with libx264 support (SVN highly recommended) .br - libx264 .br - lsdvd .br - dvdxchap from 'ogmtools' (for DVD chapter export) .br - LAME (for MP3 audio encoding) .br - FAAC (for AAC audio encoding) .br - neroAacEnc (for AAC/AAC+ audio encoding) .br - aacplusenc (for AAC+ audio encoding) .br - oggenc (for Vorbis audio encoding) .br - flac (for FLAC audio encoding) .br - MP4Box from 'gpac' (for AVI -> MP4 container conversion) .br - mkvtoolnix (for AVI -> MKV container conversion) .br - ogmtools (for AVI -> OGM container conversion) .br - tsMuxeR (for AVI -> TS container conversion) .br .SH PARAMETERS .TP .B -1p Encode in 1-pass mode .TP .B -2p Encode in 2-pass mode .TP .B -3p Encode in 3-pass mode .TP .B -qp Encode in fixed-quant mode .TP .B -crf Encode in constant rate factor mode .TP .B -p [-t ] [-pf ] Use a predefined H.264 quality preset, where \fB\fR is the desired encoding mode (\fB-1p\fR or \fB-2p\fR or \fP-3p\fR or \fP-qp\fR or \fP-crf\fR) and \fB\fR is the desired quality preset to use (see below). Note that the \fP-t\fR and \fP-pf\fR options only work with the x264 presets below! See examples at the end of this option. . .TP .RS .IPs .B cp --------> Load a custom preset file (see example below) .br .B ulq -------> Ultra Low Quality preset .br .B elq -------> Extreme Low Quality preset .br .B vlq -------> Very Low Quality preset .br .B lq --------> Low Quality preset .br .B mq --------> Medium Quality preset .br .B nq --------> Normal Quality preset (recommended) .br .B hq --------> High Quality preset (recommended) .br .B vhq -------> Very High Quality preset (recommended) .br .B ehq -------> Extreme High Quality preset .br .B uhq -------> Ultra High Quality preset .br .B ihq -------> Insane High Quality preset .br .B nlq -------> Near Lossless Quality preset .br .B fghq ------> Film Grain optimized High Quality preset .br .B ani -------> Anime preset .br .B anihq -----> Anime High Quality preset .br .B vdhq ------> VDPAU/DXVA High Quality (High@L4.1) preset .br .B vdehq -----> VDPAU/DXVA Extreme High Quality (High@L4.1) preset .br .B vdihq -----> VDPAU/DXVA Insane High Quality (High@L4.1) preset .br .B fl --------> Flash Player preset .br .B flhq ------> Flash Player High Quality preset .br .B qt --------> QuickTime preset .br .B qthq ------> QucikTime High Quality preset .br .B bd40 ------> Blu-ray (Main@L4.0) preset .br .B bdhq40 ----> Blu-ray High Quality (High@L4.0) preset .br .B bd41 ------> Blu-ray (Main@L4.1) preset .br .B bdhq41 ----> Blu-ray High Quality (High@L4.1) preset .br .B avchd -----> AVCHD (Main@L4.0) preset .br .B avchdhq ---> AVCHD High Quality (High@L4.1) preset .br .B sdb -------> Stand-alone HW players SD (Baseline@L3.1) preset .br .B sdm -------> Stand-alone HW players SD (Main@L3.1) preset .br .B sdh -------> Stand-alone HW players SD (High@L3.1) preset .br .B hdb -------> Stand-alone HW players HD (Baseline@L4.1) preset .br .B hdm -------> Stand-alone HW players HD (Main@L4.1) preset .br .B hdh -------> Stand-alone HW players HD (High@L4.1) preset .br .B ag1 -------> Android G1 preset .br .B ag1hq -----> Android G1 High Quality preset .br .B ipc -------> Apple iPod Classic preset .br .B ipchq -----> Apple iPod Classic High Quality preset .br .B ip --------> Apple iPod preset .br .B iphq ------> Apple iPod High Quality preset .br .B iph -------> Apple iPhone preset .br .B iphhq -----> Apple iPhone High Quality preset .br .B atv -------> AppleTV preset .br .B atvhq -----> AppleTV High Quality preset .br .B ar --------> Archos 605 preset .br .B arhq ------> Archos 605 High Quality preset .br .B ar5 -------> Archos 5 preset .br .B ar5hq -----> Archos 5 High Quality preset .br .B bb --------> Blackberry 9000 preset .br .B bbhq ------> Blackberry 9000 High Quality preset .br .B nks60 -----> Nokia S60 preset .br .B nks60hq ---> Nokia S60 High Quality preset .br .B psp -------> Sony PSP preset .br .B psphq -----> Sony PSP High Quality preset .br .B ps3 -------> Sony PS3 preset .br .B ps3hq -----> Sony PS3 High Quality preset .br .B mz --------> Microsoft Zune preset .br .B mzhq ------> Microsoft Zune High Quality preset .br .B mx --------> Microsoft XBOX 360 preset .br .B mxhq ------> Microsoft XBOX 360 High Quality preset .br .B ultrafast (x264 preset) .br .B superfast (x264 preset) .br .B veryfast (x264 preset) .br .B faster (x264 preset) .br .B fast (x264 preset) .br .B medium (x264 preset) .br .B slow (x264 preset) .br .B slower (x264 preset) .br .B veryslow (x264 preset) .br .B placebo (x264 preset) .RE . .TP .RS .IPs Example of presets usage: \fBh264enc \-2p \-p hq\fR .IPs The above example will encode the DVD or input video file in 2-pass mode using the High Quality (HQ) preset .IPs Load a custom preset from a file: .br \fBh264enc \-2p \-p cp /path/to/file/preset.cfg\fR .IPs Please have a look at the \fBpreset.cfg\fR file inside the h264enc package to give you an example on how to write a custom preset. The \fBpreset.cfg\fR file is usually located inside the doc directory of the h264enc package. .IPs Examples of x264 presets/tune/profiles usage: .br \fBh264enc -2p -p slow .br h264enc -2p -p slow -t film .br h264enc -2p -p slow -pf main .br h264enc -2p -p slow -t film -pf high\fR .IPs The first example encodes the input with x264's slow preset. The second one does the same but tunes the encode settings for film footage. The third example is as the first one but selects the main H.264 profile and the last example uses both a tuning for film and selects the high H.264 profile. You can also switch the \fB-t\fR and \fB-pf\fR options, eg: \fBh264enc -2p -p slow -pf main -t film\fR .RE . .TP .B -b /path/to/file/batchfile Load a batch file generated by \fBthis\fR script. This option can be useful for testing or debugging the MEncoder parameters and for batch encoding. .TP .B -e Edit the config file from within the terminal. This option defaults to using the 'nano' text editor but one can manually set his preferred editor in the EDITOR variable of the config file. The config file is located in \fB/home/username/.h264enc\fR .TP .B -r Reset configuration file. As of version 8.5.7, h264enc uses a configuration file which contains the paths to the programs needed for its correct operation. This option tells the script to remove and recreate the config file using the default values. It can be used to restore the original values of the config file in case the user has modified it and wants to get rid of those modifications. It is also used for resetting the config file in case the user has installed a required program \fBafter\fR h264enc has generated its config file. If this is the case, the config file will not contain the path to the newly installed program so one has to reset the file in order to find it. This is because the config file is generated/updated only once: if it's not available on the user's system and during config version updates. The configuration file is located in \fB/home/username/.h264enc/config\fR .TP .B -sc Perform a sanity check. This will check for the programs which are required for the correct operation of this script and it will print the status in a list. It will also display which audio codecs are supported by MEncoder. .TP .B -scan Scan the DVD disc and display extensive information about it. With this option, one can display or export the information to a file on disk in text, perl, python, ruby or xml format. .TP .B -iso Create an ISO image of the DVD disc. Note that this option does no do any stripping of specific titles, audio languages and/or subtitles. It dumps the DVD content 1:1 to an ISO image. .TP .B -spr Calculate the Storage and Pixel Aspect Ratios (SAR/PAR) for various resolutions. .TP .B -mfr Calculate the maximum allowed frame references within DPB (Decoded Picture Buffer) limits for different H.264 levels and resolutions. .TP .B -bpp This is an informative option which lets you calculate the Bits Per Pixel (bpp) values for various resolutions. The bpp value represents how much bits each pixel gets. The higher the bpp value is, the more distinct colors the pixels will have which leads to a higher overall picture quality. Note that these values are not absolute! For video content with a lot of black in it, a bpp value of 0.14 may look very good. Video content with a lot of high motion scenes may still look bad with a bpp value of 0.20, so this really depends on the content you are willing to encode and the resolution you choose when scaling down. .TP .B -bpb This option is similar to the \fB-bpp\fR one, except it calculates the Bits Per Block (bpb) values for various resolutions. The bpb value expresses how many bits each 16x16 macroblock gets. Good bpb values are between 37-52. As is the case with Bits Per Pixel, the bpb values are not absolute and depend on the video content you are willing to encode and the resolution you choose when scaling down. .TP .B -help Display built-in help of the h264enc script and exit .TP .B -v Display version of the h264enc script and exit .SH SEE ALSO .BR mencoder (1), .BR lsdvd (1), .BR dvdxchap (1), .BR lame (1), .BR oggenc (1), .BR flac (1), .BR mkvmerge (1), .BR ogmmerge (1), .BR mp4box (1) .SH AUTHORS .B h264enc was written by Grozdan Nikolov .PP This manual page was written by the author of h264enc .SH BUG REPORTS Please send all bug reports and/or questions/suggestions to .SH WWW http://h264enc.sourceforge.net h264enc-9.3.7~dfsg/install0000755000175000017500000000336511420024217015221 0ustar alessioalessio#!/bin/bash # # installation script for h264enc # PREFIX=/usr/local # Check for root if [ $PREFIX = "/usr/local" ] && [ $UID != 0 ]; then echo "-> Login as root to install!" exit 1 fi BINDIR=$PREFIX/bin DOCDIR=$PREFIX/share/doc/h264enc MANDIR=$PREFIX/man/man1 # Remove previously installed doc dirs for i in $PREFIX/share/doc/h264enc*; do test -d $i && rm -rf $i done # make dirs if needed for i in $BINDIR $DOCDIR $MANDIR; do if [ ! -d $i ]; then mkdir -p -m 755 $i 2>/dev/null if [ $? != 0 ]; then echo "-> Failed to make directories... exiting!" exit 1 fi fi done # Copy h264enc script & doc/man files cp -f $(pwd)/h264enc $BINDIR && chmod 755 $BINDIR/h264enc cp -f $(pwd)/man/h264enc.1 $MANDIR && gzip -9 $MANDIR/h264enc.1 && chmod 644 $MANDIR/h264enc.1.gz cp -f $(pwd)/doc/* $DOCDIR && chmod 644 $DOCDIR/* # Make matrix dir in doc & copy matrix files mkdir -p -m 755 $DOCDIR/matrices && cp -f $(pwd)/matrices/* $DOCDIR/matrices && chmod 644 $DOCDIR/matrices/* # Create uninstall script in $DOCDIR cat<>$DOCDIR/uninstall #!/bin/bash if [ \$UID != 0 ]; then echo "-> Login as root to uninstall!" exit 1 fi rm -f $BINDIR/h264enc rm -f $MANDIR/h264enc.1.gz rm -rf $DOCDIR echo "" echo "-> Done" echo "-> Thanks for using h264enc!" echo "" exit 0 EOF echo "" echo "-> Installation successful" echo "" echo "-> Script is installed in $BINDIR" echo "-> Doc files are installed in $DOCDIR" echo "-> Matrix files are installed in $DOCDIR/matrices" echo "-> Man page is installed in $MANDIR" echo "" if [ -f $DOCDIR/uninstall ]; then chmod 755 $DOCDIR/uninstall echo "If you want to uninstall the program and all of its files" echo "afterwards, go to the doc directory in $DOCDIR" echo "and run as root the 'uninstall' script" fi echo "" exit 0 h264enc-9.3.7~dfsg/h264enc0000755000175000017500000104400611563751703014741 0ustar alessioalessio#!/bin/bash # $Id: h264enc, v 9.3.7, 2011/05/15, gn Exp $ # UUID: 099ef3da-dc34-41bd-a488-5786f78ab95b # # Encode DVDs/VCDs/video files to the H.264/AVC/MPEG-4 Part 10/JVT/H26L # video format using MEncoder from MPlayer # # Copyright (C) 2006-2011, Grozdan Nikolov # # h264enc is free software ; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation ; either version 2 of the License, or # (at your option) any later version. # # h264enc is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY ; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program ; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA shopt -u expand_aliases export PATH=$PATH:/usr/local/bin version=9.3.7 configversion=19 green() { echo -e "\e[1;32m$1\e[0;39;49m"; } brown() { echo -e "\e[0;33m$1\e[0;39;49m"; } error() { echo -e "\e[1;31m$1\e[0;39;49m"; } # Create config dir H264ENCDIR=$HOME/.h264enc test -d $H264ENCDIR || mkdir -p $H264ENCDIR # In case h264enc did not remove its unique temp # directories, remove them after 5 days rm -rf $(find "$H264ENCDIR" -name 'job*' -ctime +4 -type d) >/dev/null 2>&1 # Generate config file genconfig_func() { cat<>$H264ENCDIR/config ############## Configuration file for h264enc ############## # # Version: $configversion - do not modify or remove this line! # # This file is used by the h264enc script and contains the # paths to the programs needed for its correct operation. # The user can use it to modify the path to the various programs # in case one or more of these programs is not in a standard location # and connot be found by the system. It can also be used in # case the user has multiple executables of the same program but # wants to use a specific executable for the job. # Note that this file cannot be used to store encoding settings # or other parameters! They will be ignored. Everything after # a # sign is a comment. # # The EDITOR variable is used to set the preferred text editor for # editing the config file through the terminal. It defaults to the # nano text editor. # # The ALLOW_* variables can be used to enable or disable specific # audio/video filters and containers. Setting a variable to 'n' will # skip asking questions about the specific filter/container. # # The DEFOUTPUT variable can be used to provide a custom output directory # for your encodes. If left empty, h264enc defaults to your home # directory for output. If set, h264enc checks for it and will create # the directory if it's not present. The DEFOUTPUT variable can be # overwritten on the command line, meaning that if it's set but the # user provides a path on the command line, that path will be used # instead. # # The TEMPDIR variable below can be used to change the location # of the temporary directory used by h264enc. If unset, h264enc # will default to /home/username/.h264enc/job # If used, you must provide the full path to a directory. If the # directory is missing, h264enc will create it. # # The MPLAYEROPTS variable can be used to set other mplayer options. # Be careful which options you use as they may introduce problems # when using the script. # # The PRIORITY variable is used to set a 'nice' value for the encoding # process. The values one can use are between -20 and 19 where -20 # will give the highest possible priority and 19 the least favorable # one. Please note that only root can set/use a negative nice value. # Regular users can only use/set values 0 to 19. If the variable is # empty, then the default nice value of 0 is used. If the variable # contains a negative value but the script is ran with normal user # privileges, h264enc will print a notice and exit. # # The DVD_DEVICE and CDROM_DEVICE variables can be used to specify a # preferred device to encode from. Note that only block devices are # supported in these variables. CDROM_DEVICE is used for (S)VCD encoding # # h264enc can also send mails if configured to do so. There are four # variables that need to be set in the mail settings below: # MAILNOTIFY # Enable/disable sending mail with y or n # EMAIL # The recepient's email address # MAILSUBJ # The mail's subject # MAILMSG # The actual mail message # # There is no need to add date/time to your email message as this is # being done automatically. # # h264enc uses the 'mail' program which reads the mail settings from # /home/username/.mailrc. If there's no such file present or it is # configured incorrectly, mail sending will fail. A gmail example # settings for .mailrc can look like this: # # set smtp-use-starttls # set smtp=smtp://smtp.gmail.com:587 # set smtp-auth=login # set smtp-auth-user=your-email@gmail.com # set smtp-auth-password=your-password # EDITOR="nano" # Video filters ALLOW_VID_DEINTERLACE="y" ALLOW_VID_INTERLACE="y" ALLOW_VID_DEBLOCK="y" ALLOW_VID_DELOGO="y" ALLOW_VID_DENOISE="y" ALLOW_VID_NOISE="y" ALLOW_VID_DEBAND="y" ALLOW_VID_UNSHARP="y" ALLOW_VID_BRIGHTNESS="y" ALLOW_VID_EQUALIZER="y" ALLOW_VID_AUTOCROP="n" ALLOW_VID_FPS_CONVERSION="y" ALLOW_VID_SCALER_TUNING="n" ALLOW_VID_DSIZE="y" ALLOW_VID_EXPAND="y" ALLOW_VID_COLORSPACE="n" ALLOW_VID_ASPECT="y" # Audio filters ALLOW_AUD_CHANNELS="y" ALLOW_AUD_RESAMPLE="y" ALLOW_AUD_NORMALIZE="y" ALLOW_AUD_VOLUME="y" ALLOW_AUD_EQUALIZER="y" ALLOW_AUD_PAN="y" # Containers ALLOW_MKV_MUXING="y" ALLOW_MP4_MUXING="y" ALLOW_TS_MUXING="y" ALLOW_OGM_MUXING="y" # Misc ALLOW_SAMPLE_ENCODING="y" ALLOW_SCAN_MULTIPLE_VIDSTREAMS="y" ALLOW_SCAN_MULTIPLE_AUDSTREAMS="y" # Script/mplayer settings DEFOUTPUT="" TEMPDIR="" PRIORITY="10" MPLAYEROPTS="-noconfig all -loop 1" DVD_DEVICE="" CDROM_DEVICE="" # Mail settings MAILNOTIFY="n" EMAIL="" MAILSUBJ="[h264enc]: Encoding finished" MAILMSG="This is a notification mail from the h264enc script to inform you that encoding has finished." # Paths to executables MPLAYER="$(which mplayer 2>/dev/null)" MENCODER="$(which mencoder 2>/dev/null)" X264="$(which x264 2>/dev/null)" LSDVD="$(which lsdvd 2>/dev/null)" DVDXCHAP="$(which dvdxchap 2>/dev/null)" MP4BOX="$(which MP4Box 2>/dev/null)" MKVMERGE="$(which mkvmerge 2>/dev/null)" OGMMERGE="$(which ogmmerge 2>/dev/null)" TSMUXER="$(which tsMuxeR 2>/dev/null)" OGGENC="$(which oggenc 2>/dev/null)" FLAC="$(which flac 2>/dev/null)" NEROAACENC="$(which neroAacEnc 2>/dev/null)" AACPLUSENC="$(which aacplusenc 2>/dev/null)" FAAC="$(which faac 2>/dev/null)" MAIL="$(which mail 2>/dev/null)" BC="$(which bc 2>/dev/null)" PV="$(which pv 2>/dev/null)" DD="$(which dd 2>/dev/null)" EOF } if [ -f $H264ENCDIR/config ]; then cver=$(grep '^# Version' $H264ENCDIR/config | awk '{print $3}') if [[ $cver -lt $configversion ]]; then mv -f $H264ENCDIR/config $H264ENCDIR/config.old genconfig_func echo error "Important notice! The configuration file of h264enc located in" error "'$H264ENCDIR/config' has been updated to the latest version!" echo error "If you have made any prior changes to the configuration file," error "please commit those changes again and restart h264enc!" error "If no changes are made, just restart h264enc to get rid of" error "this notice." echo exit 1 else source $H264ENCDIR/config fi else genconfig_func source $H264ENCDIR/config fi # converts a given string from upper to lower chars tolower() { echo $1 |\ sed -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' } # takes a usual question as an argument # tokenizes it into the question and the possible answers # if the user mistypes an answer, the question is asked again get_selection_func() { # extract options: # Select the Input type [file/dir/dvd/vcd]: # -> # file dir dvd vcd options=$(\ echo ${1} \ | sed -e 's/[^\[]*\[\([^]]*\)\].*/\1/' \ | sed -e 's,/, ,g' \ ) # an option that contains an upper case letter is the default # option (if several do, the last one wins) i=0 for option in ${options}; do if echo ${option} | grep -e '[ABCDEFGHIJKLMNOPQRSTUVWXYZ]' 2>&1>/dev/null; then default=$(tolower "${option}") fi done # convert all options to lowercase options=$(for option in ${options}; do echo $(tolower "${option}") done) while true; do read -p "${1}" selection selection=$(tolower "$selection") if [ -n "${selection}" ]; then for value in ${options}; do if [ "${selection}" = "${value}" ]; then echo ${selection} return 0 fi done elif [ -n "${default}" ] ; then echo ${default} return 0 fi done } send_email_func() { if [ -x "$MAIL" -a "$MAILNOTIFY" = "y" -a ! -z "$EMAIL" -a ! -z "$MAILSUBJ" -a ! -z "$MAILMSG" ]; then case "$1" in exp) echo "test -f $HOME/.mailrc && echo -e \"$MAILMSG\n\nEncoding finished on \$(date)\" | $MAIL -s \"$MAILSUBJ\" \"$EMAIL\"" echo ;; *) test -f $HOME/.mailrc && echo -e "$MAILMSG\n\nEncoding finished on $(date)" | $MAIL -s "$MAILSUBJ" "$EMAIL" ;; esac fi } # Make temp dir if [ -z "$TEMPDIR" ]; then TEMPDIR="$H264ENCDIR/job$$" test -d "$TEMPDIR" || mkdir -p "$TEMPDIR" else TEMPDIR="$TEMPDIR/job$$" if [ ! -d "$TEMPDIR" ]; then mkdir -p "$TEMPDIR" 2>/dev/null if [ $? != 0 ]; then error "-> Could not create custom temp dir: $TEMPDIR" exit 1 fi fi fi # User interrupt interrupt_func() { echo "" error "-> Exiting..." rm -rf "$TEMPDIR" $H264ENCDIR/batch$$ exit 1 } trap 'interrupt_func' SIGHUP SIGINT SIGQUIT SIGKILL SIGABRT SIGFPE SIGSEGV SIGTERM SIGPIPE SIGIO # Remove temp dir on # user error/exit rmtemp() { rm -rf "$TEMPDIR" $H264ENCDIR/batch$$ exit 1 } # Get devices get_devices_func() { case "$1" in dvd) DEVTYPE="DVD" DEVSYM="/dev/dvd*" DEVOPT="-dvd-device" CONFIGDEV="$DVD_DEVICE" DEFAULTDEV="/dev/dvd" ;; vcd) DEVTYPE="CD-ROM" DEVSYM="/dev/cdrom* /dev/cdrw*" DEVOPT="-cdrom-device" CONFIGDEV="$CDROM_DEVICE" DEFAULTDEV="/dev/cdrom" ;; esac echo if [ -r /proc/sys/dev/cdrom/info ]; then DRIVE=$(grep 'drive name' /proc/sys/dev/cdrom/info | sed 's|drive name:||g') if [ ! -z "$DRIVE" ]; then for i in $DRIVE; do green "-> Found device: /dev/$i" done fi else error "-> Could not detect the $DEVTYPE device(s)!" fi for i in $DEVSYM; do if [ -L $i ]; then green "-> Found symbolic link to $DEVTYPE device: $(ls -l $i | grep -o '/dev.*')" fi done if [ ! -z "$CONFIGDEV" ]; then if [ ! -b "$CONFIGDEV" ]; then error "-> Invalid device '$CONFIGDEV' in the config file!" echo rmtemp fi green "-> Using device '$CONFIGDEV' specified in the config file" device="$DEVOPT $CONFIGDEV" else echo printf "Specify the $DEVTYPE Device [default is $DEFAULTDEV]: " read -e dev if [ -z "$dev" -a ! -b "$DEFAULTDEV" ]; then error "-> No such block device: $DEFAULTDEV" rmtemp else if [ -z "$dev" ]; then device="$DEVOPT $DEFAULTDEV" else if [ ! -b "$dev" ]; then error "-> No such block device: $dev" rmtemp else device="$DEVOPT $dev" fi fi fi fi } case "$1" in "") echo "Usage: h264enc " echo "Quick start: h264enc -p [-t ] [-pf ]" echo "Use 'h264enc -help' for more information" rmtemp ;; -v) echo "h264enc $version" rmtemp ;; -help) echo "" brown "+=======================================================+" brown "| h264enc - the interactive shell script ripper |" brown "+=======================================================+" echo "" echo "h264enc is a small script which uses the encoding utility" echo "MEncoder from MPlayer to encode a DVD or a video file to" echo "the high-quality H.264 video format [also known as Advanced Video" echo "Coding (AVC) or MPEG-4 Part 10]" echo "Note: this script requires MEncoder version 1.0rc2 or higher!" echo "For more information, read the man page of h264enc (man h264enc)" echo "or visit its official Web site at http://h264enc.sourceforge.net" echo "" brown "Options" brown "~~~~~~~" echo " $(green "-1p") Encode in one pass mode" echo "" echo " $(green "-2p") Encode in two pass mode" echo "" echo " $(green "-3p") Encode in three pass mode" echo "" echo " $(green "-qp") Encode in fixed-quant mode" echo "" echo " $(green "-crf") Encode in constant rate factor mode" echo "" green " -p [-t ] [-pf ]" echo "" echo " Use a predefined H.264 quality preset, where is" echo " the desired encoding mode (-1p or -2p or -3p or -qp or -crf)" echo " and is the desired preset to use (see below). Note" echo " that the -t and -pf options only work with the x264 presets" echo " below! See examples at the end of this option." echo "" echo " PC Presets" echo " ~~~~~~~~~~" echo " cp --------> Load a custom preset file (see example below)" echo " ulq -------> Ultra Low Quality preset" echo " elq -------> Extreme Low Quality preset" echo " vlq -------> Very Low Quality preset" echo " lq --------> Low Quality preset" echo " mq --------> Medium Quality preset" echo " nq --------> Normal Quality preset" echo " hq --------> High Quality preset (recommended)" echo " vhq -------> Very High Quality preset (recommended)" echo " ehq -------> Extreme High Quality preset (recommended)" echo " uhq -------> Ultra High Quality preset" echo " ihq -------> Insane High Quality preset" echo " nlq -------> Near Lossless Quality preset" echo " fghq ------> Film Grain optimized High Quality preset" echo " ani -------> Anime preset" echo " anihq -----> Anime High Quality preset" echo " vdhq ------> VDPAU/DXVA High Quality (High@L4.1) preset" echo " vdehq -----> VDPAU/DXVA Extreme High Quality (High@L4.1) preset" echo " vdihq -----> VDPAU/DXVA Insane High Quality (High@L4.1) preset" echo "" echo " Software Compatible Presets" echo " ~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo " fl --------> Flash Player preset" echo " flhq ------> Flash Player High Quality preset" echo " qt --------> QuickTime preset" echo " qthq ------> QuickTime High Quality preset" echo "" echo " Device Presets" echo " ~~~~~~~~~~~~~~" echo " bd40 ------> Blu-ray (Main@L4.0) preset" echo " bdhq40 ----> Blu-ray High Quality (High@L4.0) preset" echo " bd41 ------> Blu-ray (Main@L4.1) preset" echo " bdhq41 ----> Blu-ray High Quality (High@L4.1) preset" echo " avchd -----> AVCHD (Main@L4.0) preset" echo " avchdhq ---> AVCHD High Quality (High@L4.1) preset" echo " sdb -------> Stand-alone HW players SD (Baseline@L3.0) preset" echo " sdm -------> Stand-alone HW players SD (Main@L3.0) preset" echo " sdh -------> Stand-alone HW players SD (High@L3.0) preset" echo " hdb -------> Stand-alone HW players HD (Baseline@L4.0) preset" echo " hdm -------> Stand-alone HW players HD (Main@L4.0) preset" echo " hdh -------> Stand-alone HW players HD (High@L4.0) preset" echo " ag1 -------> Android G1 preset" echo " ag1hq -----> Android G1 High Quality preset" echo " ipc -------> Apple iPod Classic preset" echo " ipchq -----> Apple iPod Classic High Quality preset" echo " ip --------> Apple iPod preset" echo " iphq ------> Apple iPod High Quality preset" echo " iph -------> Apple iPhone preset" echo " iphhq -----> Apple iPhone High Quality preset" echo " atv -------> AppleTV preset" echo " atvhq -----> AppleTV High Quality preset" echo " ar --------> Archos 605 preset" echo " arhq ------> Archos 605 High Quality preset" echo " ar5 -------> Archos 5 preset" echo " ar5hq -----> Archos 5 High Quality preset" echo " bb --------> Blackberry Bold 9000 preset" echo " bbhq ------> Blackberry Bold 9000 High Quality preset" echo " nks60 -----> Nokia S60 preset" echo " nks60hq ---> Nokia S60 High Quality preset" echo " psp -------> Sony PSP preset" echo " psphq -----> Sony PSP High Quality preset" echo " ps3 -------> Sony PS3 preset" echo " ps3hq -----> Sony PS3 High Quality preset" echo " mz --------> Microsoft Zune preset" echo " mzhq ------> Microsoft Zune High Quality preset" echo " mx --------> Microsoft XBOX 360 preset" echo " mxhq ------> Microsoft XBOX 360 High Quality preset" echo "" echo " x264 Presets x264 Tune x264 Profiles" echo " ~~~~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~~~~~" echo " ultrafast film baseline" echo " superfast animation main" echo " veryfast grain high" echo " faster stillimage" echo " fast psnr" echo " medium ssim" echo " slow fastdecode" echo " slower zerolatency" echo " veryslow" echo " placebo" echo "" echo " Example of presets usage: h264enc -2p -p hq" echo "" echo " The above example will encode the DVD/VCD or input video file" echo " in 2-pass mode using the High Quality (HQ) preset" echo "" echo " Load a custom preset from a file:" echo " h264enc -2p -p cp /path/to/file/preset.cfg" echo "" echo " Please have a look at the 'preset.cfg' file inside the" echo " h264enc package to give you an example on how to write" echo " a custom preset. The 'preset.cfg' file is usually located" echo " inside the doc directory of the h264enc package." echo "" echo " Examples of x264 presets/tune/profiles usage:" echo " h264enc -2p -p slow" echo " h264enc -2p -p slow -t film" echo " h264enc -2p -p slow -pf main" echo " h264enc -2p -p slow -t film -pf high" echo "" echo " The first example encodes the input with x264's slow preset." echo " The second one does the same but tunes the encode settings for" echo " film footage. The third example is as the first one but selects" echo " the main H.264 profile and the last example uses both a tuning for" echo " film and selects the high H.264 profile. You can also switch the" echo " -t and -pf options, eg: h264enc -2p -p slow -pf main -t film" echo "" green " -b /path/to/file/batchfile" echo "" echo " Load a batch file generated by *this* script. This option" echo " can be used for testing or debugging the encoding parameters" echo " and for batch encoding." echo "" echo " $(green "-e") Edit the config file from within the terminal. This option defaults" echo " to using the 'nano' text editor but one can manually set his" echo " preferred editor in the EDITOR variable of the config file." echo " The config file is located in $H264ENCDIR" echo "" echo " $(green "-r") Reset configuration file. As of version 8.5.7, h264enc uses a" echo " configuration file which contains the paths to the programs" echo " needed for its correct operation. This option tells the script" echo " to remove and recreate the configuration file using the default" echo " values. It can be used to restore the original values of the" echo " config file in case the user has modified it and wants to get" echo " rid of those modifications. It is also used for resetting the" echo " config file in case the user has installed a required program" echo " AFTER h264enc has generated its config file. If this is the case," echo " the config file will not contain the path to the newly installed" echo " program so one has to reset the file in order to find it. This is" echo " because the config file is generated/updated only once: if it's not" echo " available on the user's system and during config version updates." echo " The configuration file is located in $H264ENCDIR/config" echo "" echo " $(green "-sc") Perform a sanity check. This will check for the programs" echo " required for the correct operation of this script and it" echo " will print the status in a list. It will also display" echo " which audio codecs are supported by MEncoder." echo "" echo " $(green "-scan") Scan the DVD disc/video file and display extensive information" echo " about it. With this option, one can display or export the information" echo " to a file on disk in text, perl, python, ruby or xml format (only" echo " for DVD scans)" echo "" echo " $(green "-iso") Create an ISO image of the DVD disc. Note that this option" echo " does not do any stripping of specific titles, audio languages and/or" echo " subtitles. It dumps the DVD content 1:1 to an ISO image." echo "" echo " $(green "-spr") Calculate the Storage and Pixel Aspect Ratios (SAR/PAR) for" echo " various resolutions." echo "" echo " $(green "-mfr") Calculate the maximum allowed frame references within DPB" echo " (Decoded Picture Buffer) limits for different H.264 levels and resolutions." echo "" echo " $(green "-bpp") This is an informative option which lets you calculate" echo " the Bits Per Pixel (bpp) values for various resolutions." echo " The bpp value represents how much bits each pixel gets. The" echo " higher the bpp value is, the more distinct colors the pixels" echo " will have which leads to a higher overall picture quality." echo " Note that these values are not absolute! For video content" echo " with a lot of black in it, a bpp value of 0.14 may look" echo " very good. Video content with a lot of high motion scenes" echo " may still look bad with a bpp value of 0.20, so this really" echo " depends on the content you are willing to encode and the" echo " video bitrate and resolution you choose when scaling down." echo "" echo " $(green "-bpb") This option is similar to the -bpp one, except it calculates" echo " the Bits Per Block (bpb) values for various resolutions." echo " The bpb value expresses how many bits each 16x16 macroblock" echo " gets. Good bpb values are between 37-52. As is the case with" echo " Bits Per Pixel, the bpb values are not absolute and depend" echo " on the video content you are willing to encode and the" echo " video bitrate and resolution you choose when scaling down." echo "" echo " $(green "-v") Display version of this script and exit" echo "" echo " $(green "-help") Display this help screen and exit" echo "" echo "" echo "TIP: if you don't want to use an option, instead of always answering" echo "with 'n', just press Enter." echo "" echo "For bug reporting, suggestions, comments, questions, or if this script" echo "was useful to you, send me an e-mail at " echo "" rmtemp ;; -bpp|-bpb|-spr|-mfr) # Bits per pixel/block, SAR and PAR calculation if [ ! -x "$BC" ]; then error "-> Checking for 'bc'... FAILED!" rmtemp fi case "$1" in -bpp) echo "" brown "+============================+" brown "| Bits Per Pixel Calculation |" brown "+============================+" echo "" ;; -bpb) echo "" brown "+============================+" brown "| Bits Per Block Calculation |" brown "+============================+" echo "" ;; -spr) echo brown "+==================================================+" brown "| Storage/Pixel Aspect Ratio (SAR/PAR) Calculation |" brown "+==================================================+" echo ;; -mfr) echo brown "+==============================================+" brown "| Maximum Allowed Frame References Calculation |" brown "+==============================================+" echo ;; esac cal0() { echo "scale=0; $1" | $BC -l | sed 's|^\.|0\.|' } cal4() { echo "scale=4; $1" | $BC -l | sed 's|^\.|0\.|' } round() { D_PART=$(echo "$1" | awk -F. '{print $1}') F_PART=$(echo "$1" | awk -F. '{print $2}') if [ $F_PART -lt 500 ]; then echo $D_PART else echo $[$D_PART+1] fi } printf "Provide the resolution [default is 720x576]: " read O_RES if [ -z "$O_RES" ]; then RES=720x576 R_ASP=$(cal4 "720/576") else RES=$O_RES R_ASP=$(cal4 $(echo $O_RES | tr '[:alpha:]' '/')) fi case "$1" in -bpp|-bpb) printf "Provide the original unscaled but cropped resolution [WxH]: " read U_RES if [ -z "$U_RES" ]; then error "-> Cropped resolution value is required!" rmtemp fi ;; esac printf "Provide the aspect ratio [16/9, 4/3, 1.3333, 1.7778... - default is 16/9]: " read AR if [ -z "$AR" ]; then A_RAT=16/9 else A_RAT=$AR fi case "$1" in -bpp|-bpb) printf "Provide the video bitrate: " read V_BTR if [ -z "$V_BTR" ]; then error "-> Video bitrate is required!" rmtemp fi printf "Provide the video's FPS value [integer or float - default is 25]: " read VFPS if [ -z "$VFPS" ]; then M_FPS=25 else M_FPS=$VFPS fi U_WID=$(echo $U_RES | awk -Fx '{print $1}') U_HEI=$(echo $U_RES | awk -Fx '{print $2}') E_RAT=$(cal4 "$A_RAT") S_WID=$(cal0 "$U_WID*$E_RAT/$R_ASP") S_HEI=$U_HEI P_AR=$(cal4 "$S_WID/$S_HEI") ;; -spr|-mfr) U_WID=$(echo $RES | awk -Fx '{print $1}') U_HEI=$(echo $RES | awk -Fx '{print $2}') E_RAT=$(cal4 "$A_RAT") S_WID=$(cal0 "$U_WID*$E_RAT/$R_ASP") S_HEI=$U_HEI P_AR=$(cal4 "$S_WID/$S_HEI") case "$1" in -mfr) echo brown "H.264 Levels" brown "~~~~~~~~~~~~" echo "0 -> Level 1.0 8 --> Level 3.1" echo "1 -> Level 1.1 9 --> Level 3.2" echo "2 -> Level 1.2 10 -> Level 4.0" echo "3 -> Level 1.3 11 -> Level 4.1" echo "4 -> Level 2.0 12 -> Level 4.2" echo "5 -> Level 2.1 13 -> Level 5.0" echo "6 -> Level 2.2 14 -> Level 5.1" echo "7 -> Level 3.0" echo printf "Select the H.264 Level [default is 11]: " read level case "$level" in 0) DPB=148 ;; 1) DPB=337 ;; 2|3|4) DPB=891 ;; 5) DPB=1782 ;; 6|7) DPB=3037 ;; 8) DPB=6750 ;; 9) DPB=7680 ;; 10|11|"") DPB=12288 ;; 12) DPB=13056 ;; 13) DPB=41400 ;; 14) DPB=69120 ;; *) error "-> No such option!" rmtemp ;; esac ;; esac ;; esac echo case "$1" in -bpp) for ((WID=$U_WID; WID>=320; WID=WID-16)); do R_H=$(cal4 "$WID/$P_AR/16") HEI=$((16*$(round "$R_H"))) BPP=$(cal4 "1000*$V_BTR/($WID*$HEI*$M_FPS)") BITRATE=$(cal0 "($WID*$HEI*$M_FPS*$BPP)/1000") PIX=$(($WID*$HEI)) echo "Resolution: $(green "${WID}x$HEI") -- Total Pixels: $(green "$PIX") -- BPP: $(green $BPP) -- Bitrate based on BPP: $(green "$BITRATE kbps")" done ;; -bpb) for ((WID=$U_WID; WID>=320; WID=WID-16)); do R_H=$(cal4 "$WID/$P_AR/16") HEI=$((16*$(round "$R_H"))) BPB=$(cal4 "$V_BTR*1000/($M_FPS*($WID*$HEI)/(16*16))") PIX=$(($WID*$HEI)) echo "Resolution: $(green "${WID}x$HEI") -- Total Pixels: $(green "$PIX") -- BPB: $(green $BPB)" done ;; -spr) for ((WID=$U_WID; WID>=320; WID=WID-16)); do R_H=$(cal4 "$WID/$P_AR/16") HEI=$((16*$(round "$R_H"))) SAR=$(cal4 "$WID/$HEI") PAR=$(cal4 "$E_RAT/$SAR") PIX=$(($WID*$HEI)) echo "Resolution: $(green "${WID}x$HEI") -- Total Pixels: $(green "$PIX") -- SAR: $(green "$SAR:1") -- PAR: $(green "$PAR:1")" done ;; -mfr) for ((WID=$U_WID; WID>=320; WID=WID-16)); do R_H=$(cal4 "$WID/$P_AR/16") HEI=$((16*$(round "$R_H"))) FRCALC=$(cal0 "($DPB*1024/1.5)/($WID*$HEI)") if [[ $FRCALC -gt 16 ]]; then REFS=16 BPYREFS=$(($REFS-1)) else REFS=$FRCALC if [[ $REFS -eq 0 ]]; then BPYREFS=0 else BPYREFS=$(($REFS-1)) fi fi echo "Resolution: $(green "${WID}x$HEI") -- Max allowed frame references: $(green "$REFS") -- With b_pyramid=normal: $(green "$BPYREFS")" done ;; esac echo rmtemp ;; -b) if [ -z "$2" ]; then error "-> Option '-b' requires an input file!" error "-> Use: h264enc -help" rmtemp fi if [ ! -f "$2" ]; then error "-> No such file: '$2'" rmtemp fi source "$2" rmtemp ;; -e) CFGFILE="$H264ENCDIR/config" if [ ! -f "$CFGFILE" ]; then error "-> config file '$CFGFILE' does not exist!" error "-> Run: 'h264enc -r' to create it!" rmtemp fi if [ -z "$EDITOR" ]; then error "-> Variable 'EDITOR' in the config file is empty!" error "-> Please manually set your editor in the config file!" rmtemp fi if [ ! -x "$(which $EDITOR)" ]; then error "-> Specified text editor '$EDITOR' does not exist!" error "-> Either install it or manually set a different" error " one in the config file!" rmtemp fi $EDITOR $CFGFILE rmtemp ;; -r) green "-> Resetting the config file values" rm -f $H264ENCDIR/config genconfig_func rmtemp ;; -sc) echo "" if [ -x "$MPLAYER" ]; then echo "-> Checking for 'MPlayer'..................... $(green OK)" else echo "-> Checking for 'MPlayer'..................... $(error FAILED!)" fi if [ -x "$MENCODER" ]; then echo "-> Checking for 'MEncoder'.................... $(green OK)" if [ -z "$($MENCODER -ovc help 2>/dev/null | awk '{print $1}' | grep 'x264')" ]; then echo "-> H.264 video support in MEncoder............ $(error NO)" else echo "-> H.264 video support in MEncoder............ $(green YES)" fi if [ -z "$($MENCODER -oac help 2>/dev/null | awk '{print $1}' | grep 'faac')" ]; then echo "-> AAC (FAAC) audio support in MEncoder....... $(error NO)" else echo "-> AAC (FAAC) audio support in MEncoder....... $(green YES)" fi if [ -z "$($MENCODER -oac help 2>/dev/null | awk '{print $1}' | grep 'mp3lame')" ]; then echo "-> MP3 (LAME) audio support in MEncoder....... $(error NO)" else echo "-> MP3 (LAME) audio support in MEncoder....... $(green YES)" fi if [ -z "$($MENCODER -oac help 2>/dev/null | awk '{print $1}' | grep 'lavc')" ]; then echo "-> AC3 (lavc) audio support in MEncoder....... $(error NO)" else echo "-> AC3 (lavc) audio support in MEncoder....... $(green YES)" fi if [ -z "$($MENCODER -oac help 2>/dev/null | awk '{print $1}' | grep 'pcm')" ]; then echo "-> PCM audio support in MEncoder.............. $(error NO)" else echo "-> PCM audio support in MEncoder.............. $(green YES)" fi else echo "-> Checking for MEncoder...................... $(error FAILED!)" fi echo "" if [ -x "$BC" ]; then echo "-> Checking for 'bc'.......................... $(green OK)" else echo "-> Checking for 'bc'.......................... $(error FAILED!)" fi if [ -x "$PV" ]; then echo "-> Checking for 'pv'.......................... $(green OK)" else echo "-> Checking for 'pv'.......................... $(error "FAILED! [no support for DVD ISO dumps]")" fi if [ -x "$DD" ]; then echo "-> Checking for 'dd'.......................... $(green OK)" else echo "-> Checking for 'dd'.......................... $(error "FAILED! [no support for DVD ISO dumps]")" fi if [ -x "$NEROAACENC" ]; then echo "-> Checking for 'neroAacEnc'.................. $(green OK)" else echo "-> Checking for 'neroAacEnc'.................. $(error "FAILED! [no support for AAC+ audio]")" fi if [ -x "$AACPLUSENC" ]; then echo "-> Checking for 'aacplusenc'.................. $(green OK)" else echo "-> Checking for 'aacplusenc'.................. $(error "FAILED! [no support for AAC+ audio]")" fi if [ -x "$OGGENC" ]; then echo "-> Checking for 'oggenc'...................... $(green OK)" else echo "-> Checking for 'oggenc'...................... $(error "FAILED! [no support for Vorbis audio]")" fi if [ -x "$FLAC" ]; then echo "-> Checking for 'flac'........................ $(green OK)" else echo "-> Checking for 'flac'........................ $(error "FAILED! [no support for FLAC audio]")" fi if [ -x "$FAAC" ]; then echo "-> Checking for 'faac'........................ $(green OK)" else echo "-> Checking for 'faac'........................ $(error "FAILED! [no support for AAC audio]")" fi if [ -x "$(which less 2>/dev/null)" ]; then echo "-> Checking for 'less'........................ $(green OK)" else echo "-> Checking for 'less'........................ $(error FAILED!)" fi if [ -x "$LSDVD" ]; then echo "-> Checking for 'lsdvd'....................... $(green OK)" else echo "-> Checking for 'lsdvd'....................... $(error "FAILED! [no support for DVD title scans]")" fi if [ -x "$DVDXCHAP" ]; then echo "-> Checking for 'dvdxchap' (from ogmtools).... $(green OK)" else echo "-> Checking for 'dvdxchap' (from ogmtools).... $(error "FAILED! [no support for DVD chapters export]")" fi if [ -x "$MKVMERGE" ]; then echo "-> Checking for 'mkvmerge' (from mkvtoolnix).. $(green OK)" else echo "-> Checking for 'mkvmerge' (from mkvtoolnix).. $(error "FAILED! [no support for the MKV container]")" fi if [ -x "$OGMMERGE" ]; then echo "-> Checking for 'ogmmerge' (from ogmtools).... $(green OK)" else echo "-> Checking for 'ogmmerge' (from ogmtools).... $(error "FAILED! [no support for the OGM container]")" fi if [ -x "$MP4BOX" ]; then echo "-> Checking for 'MP4Box' (from gpac).......... $(green OK)" else echo "-> Checking for 'MP4Box' (from gpac).......... $(error "FAILED! [no support for the MP4 container]")" fi if [ -x "$TSMUXER" ]; then echo "-> Checking for 'tsMuxeR'..................... $(green OK)" else echo "-> Checking for 'tsMuxeR'..................... $(error "FAILED! [no support for the TS container]")" fi echo echo "If you have installed a required program but the script" echo "can't find it, run 'h264enc -r' to reset the config file." echo rmtemp ;; -scan) echo "" printf "Would you like to scan a video file or a DVD? [file/vcd/dvd]: " read scantype case "$scantype" in file|vcd) if [ ! -x "$BC" -o ! -x "$MPLAYER" ]; then error "-> bc or mplayer missing!" rmtemp fi case "$scantype" in file) printf "Provide the input video file: " read -e infile if [ -z "$infile" ]; then error "-> No input specified!" rmtemp elif [ ! -e "$infile" ]; then error "-> No such file: '$infile'" rmtemp fi echo green "-> Scanning the file..." ;; vcd) get_devices_func vcd vcdurl="vcd://2" echo green "-> Scanning the VCD..." ;; esac INFO="$TEMPDIR/info$$" $MPLAYER "$infile" $vcdurl $device $MPLAYEROPTS -identify -vo null -nocache -channels 6 -frames 1 2>/dev/null > "$INFO" echo "" echo "MPlayer Demuxer: $(grep '^ID_DEMUXER' "$INFO" | tail -n 1 | awk -F= '{print $2}')" echo "Video Format: $(grep '^ID_VIDEO_FORMAT' "$INFO" | awk -F= '{print $2}')" echo "Video Bitrate: $(echo "scale=1; $(grep '^ID_VIDEO_BITRATE' "$INFO" | awk -F= '{print $2}')/1000" | $BC -l) kbps" echo "Video FPS: $(grep '^ID_VIDEO_FPS' "$INFO" | awk -F= '{print $2}')" echo "Video Resolution: $(grep '^VIDEO:' "$INFO" | tail -n 1 | awk '{print $3}') ($(($(grep '^VIDEO:' "$INFO" | tail -n 1 | awk '{print $3}' | sed 's|x|*|'))) pixels)" echo "Video Aspect: $(grep '^ID_VIDEO_ASPECT' "$INFO" | tail -n 1 | awk -F= '{print $2}'):1" echo "Video SAR: $(echo "scale=4; $(grep '^VIDEO:' "$INFO" | tail -n 1 | awk '{print $3}' | sed 's|x|/|')" | $BC -l | sed 's|^\.|0\.|'):1" echo "Video PAR: $(echo "scale=4; $(grep '^ID_VIDEO_ASPECT' "$INFO" | tail -n 1 | awk -F= '{print $2}')/($(grep '^VIDEO:' "$INFO" | tail -n 1 | awk '{print $3}' | sed 's|x|/|'))" | $BC -l | sed 's|^\.|0\.|'):1" echo "Video Length: $(grep '^ID_LENGTH' "$INFO" | awk -F= '{print $2}') seconds or $(echo "scale=1; $(grep '^ID_LENGTH' "$INFO" | awk -F= '{print $2}')/60" | $BC -l | sed 's/^\./0\./') minutes (May not be accurate)" echo "Number Of Frames: $(echo "scale=0; $(grep '^ID_LENGTH' "$INFO" | awk -F= '{print $2}') * $(grep '^ID_VIDEO_FPS' "$INFO" | awk -F= '{print $2}')" | $BC -l | awk -F. '{print $1}') (May not be accurate)" echo "" echo "Audio Codec: $(grep '^ID_AUDIO_CODEC' "$INFO" | tail -n 1 | awk -F= '{print $2}')" echo "Audio Bitrate: $(($(grep '^ID_AUDIO_BITRATE' "$INFO" | tail -n 1 | awk -F= '{print $2}')/1000)) kbps" echo "Audio Sample Rate: $(grep '^ID_AUDIO_RATE' "$INFO" | tail -n 1 | awk -F= '{print $2}') Hz" echo "Audio Channels: $(grep '^ID_AUDIO_NCH' "$INFO" | tail -n 1 | awk -F= '{print $2}')" echo "" rmtemp ;; dvd) # Scan the DVD disc and display # info about it, titles, chapters, # audio streams, subs, cells, etc... if [ ! -x "$MPLAYER" -o ! -x "$LSDVD" -o ! -x "$(which less 2>/dev/null)" ]; then error "-> 'mplayer', 'lsdvd' or 'less' missing!" rmtemp fi get_devices_func dvd echo green "-> Unlocking the DVD disc..." GET_TITLES="$($MPLAYER dvd://1 $device $MPLAYEROPTS -nosound -nocache -vo null -frames 1 2>/dev/null | grep -m1 'titles')" TITLE="$(echo $GET_TITLES | awk '{print $3}')" green "-> $GET_TITLES" green "-> $($LSDVD $(echo $device | awk '{print $2}') 2>/dev/null | grep 'Longest' | sed 's|track:|title:|')" echo "" brown "DVD Information Menu" brown "~~~~~~~~~~~~~~~~~~~~" echo "0 -> Display Audio Streams" echo "1 -> Display Cells" echo "2 -> Display Angles" echo "3 -> Display Chapters" echo "4 -> Display Subtitles" echo "5 -> Display Palette Info" echo "6 -> Display Title/Video Info" echo "7 -> Display All Of The Above" echo "8 -> Export Info To A File" echo "9 -> Exit" echo "" printf "Select an option: " read option case "$option" in [0-8]) true ;; 9) rmtemp ;; ""|*) error "-> Option unknown or not specified!" rmtemp ;; esac printf "Specify the DVD title [1-$TITLE/all]: " read dvd_title if [ "$dvd_title" != "all" ]; then title="-t $dvd_title" titlenum="title$dvd_title" else title= titlenum="alltitles" fi case "$option" in 0) $LSDVD $title -a -Oh $(echo $device | awk '{print $2}') 2>/dev/null | less ;; 1) $LSDVD $title -d -Oh $(echo $device | awk '{print $2}') 2>/dev/null | less ;; 2) $LSDVD $title -n -Oh $(echo $device | awk '{print $2}') 2>/dev/null | less ;; 3) $LSDVD $title -c -Oh $(echo $device | awk '{print $2}') 2>/dev/null | less ;; 4) $LSDVD $title -s -Oh $(echo $device | awk '{print $2}') 2>/dev/null | less ;; 5) $LSDVD $title -P -Oh $(echo $device | awk '{print $2}') 2>/dev/null | less ;; 6) $LSDVD $title -v -Oh $(echo $device | awk '{print $2}') 2>/dev/null | less ;; 7) $LSDVD $title -x -Oh $(echo $device | awk '{print $2}') 2>/dev/null | less ;; 8) printf "Which option to export? [0-7/all]: " read opt case "$opt" in 0) info="-a" ;; 1) info="-d" ;; 2) info="-n" ;; 3) info="-c" ;; 4) info="-s" ;; 5) info="-P" ;; 6) info="-v" ;; 7|all) info="-x" ;; ""|*) error "-> Option unknown or not specified!" rmtemp ;; esac printf "In which format to export? [text/perl/python/ruby/xml]: " read format case "$format" in text) ext="txt" ;; perl) ext="pl" ;; python) ext="py" ;; ruby) ext="rb" ;; xml) ext="xml" ;; ""|*) error "-> Format unsupported or not specified!" rmtemp ;; esac DT="$($LSDVD $(echo $device | awk '{print $2}') 2>/dev/null | grep '^Disc Title' | awk -F': ' '{print $2}')" if [ ! -z "$DT" ]; then DISC_TITLE="$DT" else DISC_TITLE="DVD" fi store_func() { case "$1" in 0) EXPORT_FILE="$HOME/$DISC_TITLE-$titlenum-audiostreams.$ext" ;; 1) EXPORT_FILE="$HOME/$DISC_TITLE-$titlenum-cells.$ext" ;; 2) EXPORT_FILE="$HOME/$DISC_TITLE-$titlenum-angles.$ext" ;; 3) EXPORT_FILE="$HOME/$DISC_TITLE-$titlenum-chapters.$ext" ;; 4) EXPORT_FILE="$HOME/$DISC_TITLE-$titlenum-subtitles.$ext" ;; 5) EXPORT_FILE="$HOME/$DISC_TITLE-$titlenum-palette.$ext" ;; 6) EXPORT_FILE="$HOME/$DISC_TITLE-$titlenum-title+video.$ext" ;; 7|all) EXPORT_FILE="$HOME/$DISC_TITLE-$titlenum-allinfo.$ext" ;; esac } info_func() { echo green "-> Saving to '$EXPORT_FILE'" echo } case "$format" in text) store_func $opt info_func $LSDVD $title $info -Oh $(echo $device | awk '{print $2}') 2>/dev/null > $EXPORT_FILE ;; perl) store_func $opt info_func $LSDVD $title $info -Op $(echo $device | awk '{print $2}') 2>/dev/null > $EXPORT_FILE ;; python) store_func $opt info_func $LSDVD $title $info -Oy $(echo $device | awk '{print $2}') 2>/dev/null > $EXPORT_FILE ;; ruby) store_func $opt info_func $LSDVD $title $info -Or $(echo $device | awk '{print $2}') 2>/dev/null > $EXPORT_FILE ;; xml) store_func $opt info_func $LSDVD $title $info -Ox $(echo $device | awk '{print $2}') 2>/dev/null > $EXPORT_FILE ;; esac ;; esac rmtemp ;; *|"") error "-> You didn't specify the source" rmtemp ;; esac ;; -iso) # DVD ISO dumping. This requiers # 'pv' but we fall back to 'dd' # if 'pv' is not on the user's # system if [ ! -x "$BC" -o ! -x "$DD" -o ! -x "$MPLAYER" -o ! -x "$LSDVD" ]; then error "-> bc, dd, mplayer or lsdvd missing!" rmtemp fi interrupt_iso_func() { echo "" error "-> Exiting..." rm -f "$OUTPUT" 2>/dev/null rmtemp } trap 'interrupt_iso_func' SIGHUP SIGTSTP SIGINT SIGQUIT SIGKILL SIGABRT SIGFPE SIGSEGV SIGTERM SIGPIPE SIGIO check_space_func() { HDSPACE="$(df -m "$(dirname "$OUTPUT")" | tail -n 1 | awk '{print $4}')" if [ $HDSPACE -le 9216 ]; then echo "" error "-> You are running out of disk space in '$(dirname "$OUTPUT")'" error "-> Space left over: $HDSPACE MiB ($(echo "scale=3; $HDSPACE/1024" | $BC -l | sed 's|^\.|0\.|') GiB)" error "-> Please provide a different output directory!" echo "" rmtemp fi } echo brown "+=======================+" brown "| DVD ISO Image Dumping |" brown "+=======================+" get_devices_func dvd echo green "-> Unlocking the DVD disc..." $MPLAYER dvd://1 $device $MPLAYEROPTS -vo null -nosound -nocache -frames 1 >/dev/null 2>&1 green "-> Scanning for DVD title name..." TITLE="$($LSDVD $(echo $device | awk '{print $2}') 2>/dev/null | grep '^Disc Title' | awk -F': ' '{print $2}')" if [ ! -z "$TITLE" ]; then OUT="$HOME/$TITLE.iso" else OUT="$HOME/DVD-$$.iso" fi test -e "$OUT" && mv -f "$OUT" "$OUT.old" echo "" printf "Specify the Output for the ISO image [default is $OUT]: " read -e iso_out if [ -z "$iso_out" ]; then OUTPUT="$OUT" check_space_func else if [ -z "$(echo $iso_out | grep '^/')" ]; then error "-> You have to provide the full path!" rmtemp fi test -d "$(dirname "$iso_out")" || mkdir -p "$(dirname "$iso_out")" 2>/dev/null OUTPUT="$iso_out" check_space_func fi echo "" green "-> Available disk space: $HDSPACE MiB ($(echo "scale=3; $HDSPACE/1024" | $BC -l) GiB)" green "-> Dumping disc content to ISO image, please wait..." green "-> This can take a while..." echo "" if [ -x "$PV" ]; then $PV "$(echo $device | awk '{print $2}')" > "$OUTPUT" else $DD if="$(echo $device | awk '{print $2}')" bs=2048 conv=noerror,sync of="$OUTPUT" 2>/dev/null fi green "-> Done" echo "" rmtemp ;; -[1-3]p|-qp|-crf) case "$2" in -p) case "$3" in ulq|elq|vlq|lq|mq|nq|hq|vhq|ehq|uhq|ihq|nlq|fghq|ani|anihq|vdhq|vdehq|vdihq|sdb|sdm|sdh|hdb|hdm|hdh|fl|flhq|qt|qthq|bd40|bdhq40|bd41|bdhq41|avchd|avchdhq|ag1|ag1hq|ipc|ipchq|ip|iphq|iph|iphhq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq|ps3|ps3hq|mz|mzhq|mx|mxhq) true ;; ultrafast|superfast|veryfast|faster|fast|medium|slow|slower|veryslow|placebo) true ;; cp) if [ -z "$4" ]; then error "-> You have to load a custom preset file!" error "-> Use: h264enc $1 -p cp /path/to/file/preset.cfg" rmtemp fi if [ ! -f "$4" ]; then error "-> No such file: '$4'" rmtemp fi ;; "") error "-> No preset specified!" error "-> Use: 'h264enc -help'" rmtemp ;; *) error "-> Unknown preset: '$3'" error "-> Use: 'h264enc -help'" rmtemp ;; esac ;; "") error "-> No preset specified!" error "-> Use: 'h264enc -help'" rmtemp ;; *) error "-> Unknown option: '$2'" error "-> Use: 'h264enc -help'" rmtemp ;; esac ;; *) error "-> Unknown option: '$1'" error "-> Use: 'h264enc -help'" rmtemp ;; esac # x264 tune/profile case "$4" in -t|-pf) case "$5" in film|animation|grain|stillimage|psnr|ssim|fastdecode|zerolatency) x264tune=":tune=$5" ;; baseline|main|high) x264profile=":profile=$5" ;; "") error "-> No tune or profile setting specified!" error "-> Use: 'h264enc -help'" rmtemp ;; *) error "-> Unknown tune or profile setting: '$5'" error "-> Use: 'h264enc -help'" rmtemp ;; esac ;; "") true ;; *) if [ "$3" != "cp" ]; then error "-> Unknown option: '$4'" error "-> Use: 'h264enc -help'" rmtemp fi ;; esac case "$6" in -t|-pf) case "$7" in film|animation|grain|stillimage|psnr|ssim|fastdecode|zerolatency) x264tune=":tune=$7" ;; baseline|main|high) x264profile=":profile=$7" ;; "") error "-> No tune or profile setting specified!" error "-> Use: 'h264enc -help'" rmtemp ;; *) error "-> Unknown tune or profile setting: '$7'" error "-> Use: 'h264enc -help'" rmtemp ;; esac ;; "") true ;; *) if [ "$3" != "cp" ]; then error "-> Unknown option: '$6'" error "-> Use: 'h264enc -help'" rmtemp fi ;; esac # The NLQ preset is suppored only in # fixed-quant mode! Check and warn user # about that. if [ "$3" = "nlq" ]; then if [ "$1" != "-crf" ]; then error "-> The Near Lossless Quality (NLQ) preset is only supported in CRF mode!" error "-> Use: h264enc -crf -p nlq" rmtemp fi fi # Some portable device presets are # not supported in -qp/-crf mode. case "$3" in ag1|ag1hq|ipc|ipchq|ip|iphq|iph|iphhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq|mz|mzhq) if [ "$1" = "-qp" -o "$1" = "-crf" ]; then error "-> The '$3' preset is only supported in 1-, 2-, or 3-pass encoding mode!" rmtemp fi ;; esac # Check priority value and exit if we # detect it's a negative one but user # is running the script with regular # privileges if [ ! -z "$PRIORITY" ]; then if [ ! -z "$(echo $PRIORITY | grep '^\-')" -a "$UID" != "0" ]; then echo error "-> The encoding priority value in the config file is" error " set to $PRIORITY but you are executing h264enc as regular" error " user which does not have the ability to set/use such" error " a value. Please modify the PRIORITY variable in the" error " config file and set it to something between 0 and 19!" echo rmtemp fi fi # Informative function for displaying # the selected quality preset display_quality_preset_func() { case "$1" in cp) green "-> Using custom preset file: '$2'" ;; ulq) green "-> Using \"Ultra Low Quality\" preset" ;; elq) green "-> Using \"Extreme Low Quality\" preset" ;; vlq) green "-> Using \"Very Low Quality\" preset" ;; lq) green "-> Using \"Low Quality\" preset" ;; mq) green "-> Using \"Medium Quality\" preset" ;; nq) green "-> Using \"Normal Quality\" preset" ;; hq) green "-> Using \"High Quality\" preset" ;; vhq) green "-> Using \"Very High Quality\" preset" ;; ehq) green "-> Using \"Extreme High Quality\" preset" ;; uhq) green "-> Using \"Ultra High Quality\" preset" ;; ihq) green "-> Using \"Insane High Quality\" preset" ;; nlq) green "-> Using \"Near Lossless Quality\" preset" ;; fghq) green "-> Using \"Film Grain optimized High Quality\" preset" ;; ani) green "-> Using \"Anime\" preset" ;; anihq) green "-> Using \"Anime High Quality\" preset" ;; vdhq) green "-> Using \"VDPAU/DXVA High Quality (High@L4.1)\" preset" ;; vdehq) green "-> Using \"VDPAU/DXVA Extreme High Quality (High@L4.1)\" preset" ;; vdihq) green "-> Using \"VDPAU/DXVA Insane High Quality (High@L4.1)\" preset" ;; fl) green "-> Using \"Flash Player\" preset" ;; flhq) green "-> Using \"Flash Player High Quality\" preset" ;; qt) green "-> Using \"QuickTime\" preset" ;; qthq) green "-> Using \"QuickTime High Quality\" preset" ;; bd40) green "-> Using \"Blu-ray (Main@L4.0)\" preset" ;; bdhq40) green "-> Using \"Blu-ray High Quality (High@L4.0)\" preset" ;; bd41) green "-> Using \"Blu-ray (Main@L4.0)\" preset" ;; bdhq41) green "-> Using \"Blu-ray High Quality (High@L4.1)\" preset" ;; avchd) green "-> Using \"AVCHD (Main@L4.0)\" preset" ;; avchdhq) green "-> Using \"AVCHD High Quality (High@L4.1)\" preset" ;; sdb) green "-> Using \"Stand-alone HW Players SD (Baseline@L3.0)\" preset" ;; sdm) green "-> Using \"Stand-alone HW Players SD (Main@L3.0)\" preset" ;; sdh) green "-> Using \"Stand-alone HW Players SD (High@L3.0)\" preset" ;; hdb) green "-> Using \"Stand-alone HW Players HD (Baseline@L4.0)\" preset" ;; hdm) green "-> Using \"Stand-alone HW Players HD (Main@L4.0)\" preset" ;; hdh) green "-> Using \"Stand-alone HW Players HD (High@L4.0)\" preset" ;; ag1) green "-> Using \"Android G1\" preset" ;; ag1hq) green "-> Using \"Android G1 High Quality\" preset" ;; ipc) green "-> Using \"Apple iPod Classic\" preset" ;; ipchq) green "-> Using \"Apple iPod Classic High Quality\" preset" ;; ip) green "-> Using \"Apple iPod\" preset" ;; iphq) green "-> Using \"Apple iPod High Quality\" preset" ;; iph) green "-> Using \"Apple iPhone\" preset" ;; iphhq) green "-> Using \"Apple iPhone High Quality\" preset" ;; atv) green "-> Using \"AppleTV\" preset" ;; atvhq) green "-> Using \"AppleTV High Quality\" preset" ;; ar) green "-> Using \"Archos 605\" preset" ;; arhq) green "-> Using \"Archos 605 High Quality\" preset" ;; ar5) green "-> Using \"Archos 5\" preset" ;; ar5hq) green "-> Using \"Archos 5 High Quality\" preset" ;; bb) green "-> Using \"Blackberry 9000\" preset" ;; bbhq) green "-> Using \"Blackberry 9000 High Quality\" preset" ;; nks60) green "-> Using \"Nokia S60\" preset" ;; nks60hq) green "-> Using \"Nokia S60 High Quality\" preset" ;; psp) green "-> Using \"Sony PSP\" preset" ;; psphq) green "-> Using \"Sony PSP High Quality\" preset" ;; ps3) green "-> Using \"Sony PS3\" preset" ;; ps3hq) green "-> Using \"Sony PS3 High Quality\" preset" ;; mz) green "-> Using \"Microsoft Zune\" preset" ;; mzhq) green "-> Using \"Microsoft Zune High Quality\" preset" ;; mx) green "-> Using \"Microsoft XBOX 360\" preset" ;; mxhq) green "-> Using \"Microsoft XBOX 360\" preset" ;; ultrafast) green "-> Using \"x264 ultrafast\" preset" ;; superfast) green "-> Using \"x264 superfast\" preset" ;; veryfast) green "-> Using \"x264 veryfast\" preset" ;; faster) green "-> Using \"x264 faster\" preset" ;; fast) green "-> Using \"x264 fast\" preset" ;; medium) green "-> Using \"x264 medium\" preset" ;; slow) green "-> Using \"x264 slow\" preset" ;; slower) green "-> Using \"x264 slower\" preset" ;; veryslow) green "-> Using \"x264 veryslow\" preset" ;; placebo) green "-> Using \"x264 placebo\" preset" ;; esac } ########################################### ############## Requirements ############### ########################################### if [ ! -x "$BC" ]; then error "-> Checking for utility 'bc'... FAILED!" rmtemp fi if [ ! -x "$MENCODER" ]; then error "-> Checking for MEncoder... FAILED!" rmtemp fi if [ -z "$($MENCODER -ovc help 2>/dev/null | awk '{print $1}' | grep 'x264')" ]; then error "-> Checking for libx264 support in MEncoder... FAILED!" error "-> Download libx264 and recompile MPlayer" rmtemp fi if [ ! -x "$MPLAYER" ]; then error "-> Checking for MPlayer... FAILED!" rmtemp fi ##################################################################### #### Video functions shared by both DVD and video file encodings #### ##################################################################### # # Video filters that come before the 'scale' filter # must have a , (comma) appended at their end. # Video filters that come after the 'scale' filter, # must be preceded by a , (comma). # # Frame rate selection for # frame doubling deinterlace # filters. Kicks only in effect # if the script couldn't detect # a supported FPS value or if # we deal with NTSC content. deint_custom_fps_func() { echo "" brown "Deinterlace Frame Rate Selection" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 --> Silent Film @ 31.97 fps (2*16000/1001)" echo "1 --> Silent Film @ 35.96 fps (2*18000/1001)" echo "2 --> Film @ 48 fps (2*24)" echo "3 --> PAL/SECAM @ 50 fps (2*25)" echo "4 --> PAL/SECAM @ 100 fps (2*50)" echo "5 --> PAL/SECAM @ 200 fps (2*100)" echo "6 --> NTSC @ 47.95 fps (2*24000/1001)" echo "7 --> NTSC @ 59.94 fps (2*30000/1001)" echo "8 --> NTSC @ 60 fps (2*30)" echo "9 --> NTSC @ 119.88 fps (2*60000/1001)" echo "10 -> NTSC @ 239.76 fps (2*120000/1001)" echo "" printf "Select the Deinterlace double frame rate [no default!]: " read dfr case "$dfr" in 0) deintfps="32000/1001"; deintofps="32000/1001" ;; 1) deintfps="36000/1001"; deintofps="36000/1001" ;; 2) deintfps="48"; deintofps="48" ;; 3) deintfps="50"; deintofps="50" ;; 4) deintfps="100"; deintofps="100" ;; 5) deintfps="200"; deintofps="200" ;; 6) deintfps="48000/1001"; deintofps="48000/1001" ;; 7) deintfps="60000/1001"; deintofps="60000/1001" ;; 8) deintfps="60"; deintofps="60" ;; 9) deintfps="120000/1001"; deintofps="120000/1001" ;; 10) deintfps="240000/1001"; deintofps="240000/1001" ;; ""|*) error "-> Option unknown or deinterlace frame rate not specified!" error "-> Exiting in function: deint_custom_fps_func()" rmtemp ;; esac } # Detect the source FPS value # of the content. This function # is used by the deinterlace and # interlace functions source_fps_func() { echo "" green "-> Detecting source FPS value..." $MPLAYER "$sourcetype" $device $vid $MPLAYEROPTS -identify -vo null -nosound -frames 1 -nocache 2>/dev/null > "$TEMPDIR/sourcefps" SOURCEFPS=$(grep '^ID_VIDEO_FPS' "$TEMPDIR/sourcefps" | tail -n 1 | awk -F= '{print $2}') rm -f "$TEMPDIR/sourcefps" case "$1" in deinthalf) calc_fps_func() { green "-> Setting input/output frame rate to $(echo "scale=3; $deintfps" | $BC -l)/$(echo "scale=3; $deintofps" | $BC -l) FPS" green "-> Using '$(echo $deintfilter | sed 's/,$//')' video filters" } ;; deintdouble) calc_fps_func() { green "-> Setting input/output frame rate to $(echo "scale=3; $SOURCEFPS*2" | $BC -l) FPS" green "-> Using '$(echo $deintfilter | sed 's/,$//')' video filter(s)" } ;; interlace) calc_fps_func() { green "-> Setting input/output frame rate to $(echo "scale=3; $intfps" | $BC -l)/$(echo "scale=3; $intofps" | $BC -l) FPS" green "-> Using '$(echo $intfilter | sed 's/^,//')' video filter(s)" echo "" } ;; esac } # Deinterlacing function video_deinterlace_func() { int=$(get_selection_func "Is the $type Interlaced? [y/N]: ") if [ "$int" = "y" ]; then preint=$(get_selection_func "Would you like to Preserve the Interlacing? [y/N]: ") if [ "$preint" = "y" ]; then # Turn on interlace-aware mode in libx264 and add # the ilpack filter to correctly align chroma printf "Specify the Interlace field order [tff/bff - default is tff]: " read int_order case "$int_order" in tff|"") interlaced=":tff:pic_struct" ;; bff) interlaced=":bff:pic_struct" ;; *) error "-> Unknown interlace option!" error "-> Exiting in function: video_deinterlace_func()" rmtemp ;; esac ilpack="ilpack=1," # Ask if the user will be using denoise/deblock filters # so we can deinterleave the content, apply the denoising, # deblocking and interleave the content. This way we can # process the content without breaking the interlacing ddbc=$(get_selection_func "Will you be using Denoise/Deblock filters later on? [y/N]: ") if [ "$ddbc" = "y" ]; then ild="il=d," ili="il=i," fi else interlaced=":nointerlaced" echo "" brown "Deinterlace Methods" brown "~~~~~~~~~~~~~~~~~~~" echo "0 -> Deinterlace at half frame rate" echo "1 -> Deinterlace at original frame rate" echo "2 -> Deinterlace at double frame rate (bobbing)" echo "3 -> Skip deinterlacing" echo "" printf "Select the deinterlacing method [default is 1]: " read deintmethod case "$deintmethod" in 0) echo "" brown "Available Deinterlacing Filters @ Half FPS" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 --> Linear Blend Deinterlacer" echo "1 --> Linear Interpolating Deinterlacer" echo "2 --> Cubic Interpolating Deinterlacer" echo "3 --> Median Deinterlacer" echo "4 --> FFmpeg Deinterlacer" echo "5 --> FIR Lowpass 5 Deinterlacer" echo "6 --> Donald Graft's Adaptive Kernel Deinterlacer" echo "7 --> Yadif Deinterlacer" echo "8 --> Fast Yadif Deinterlacer" echo "9 --> Yadif & Linear Blend" echo "10 -> Yadif & Linear Interpolation" echo "11 -> Yadif & Cubic Interpolation" echo "12 -> Yadif & Median deint" echo "13 -> Yadif & FFmpeg deint" echo "14 -> Yadif & FIR Lowpass 5" echo "" printf "Select a deinterlacing filter [default is 7]: " read dfilter case "$dfilter" in 0) deintfilter="pp=lb,framestep=2," ;; 1) deintfilter="pp=li,framestep=2," ;; 2) deintfilter="pp=ci,framestep=2," ;; 3) deintfilter="pp=md,framestep=2," ;; 4) deintfilter="pp=fd,framestep=2," ;; 5) deintfilter="pp=l5,framestep=2," ;; 6) printf "Specify the deinterlacing threshold [0-255 - default is 5]: " read kerntres if [ -z "$kerntres" ]; then deintfilter="kerndeint=5,framestep=2," else deintfilter="kerndeint=$kerntres,framestep=2," fi ;; 7|"") deintfilter="yadif=0,framestep=2,"; field_dominance="-field-dominance -1" ;; 8) deintfilter="yadif=2,framestep=2,"; field_dominance="-field-dominance -1" ;; 9) deintfilter="yadif=0,pp=lb,framestep=2,"; field_dominance="-field-dominance -1" ;; 10) deintfilter="yadif=0,pp=li,framestep=2,"; field_dominance="-field-dominance -1" ;; 11) deintfilter="yadif=0,pp=ci,framestep=2,"; field_dominance="-field-dominance -1" ;; 12) deintfilter="yadif=0,pp=md,framestep=2,"; field_dominance="-field-dominance -1" ;; 13) deintfilter="yadif=0,pp=fd,framestep=2,"; field_dominance="-field-dominance -1" ;; 14) deintfilter="yadif=0,pp=l5,framestep=2,"; field_dominance="-field-dominance -1" ;; *) error "-> Unknown option: '$dfilter'" error "-> Exiting in function: video_deinterlace_func()" rmtemp ;; esac source_fps_func deinthalf case "$SOURCEFPS" in 50.00|50.000) deintfps="50" deintofps="25" green "-> Detected $SOURCEFPS FPS (PAL/SECAM Double)" calc_fps_func echo "" ;; 59.94|59.940) deintfps="60000/1001" deintofps="30000/1001" green "-> Detected $SOURCEFPS FPS (NTSC Double)" calc_fps_func echo "" ;; 60.00|60.000) deintfps="60" deintofps="30" green "-> Detected $SOURCEFPS FPS (NTSC Double)" calc_fps_func echo "" ;; "") error "-> Could not detect the FPS value" error "-> Exiting in function: video_deinterlace_func()" echo "" rmtemp ;; *) green "-> Detected $SOURCEFPS FPS" error "-> Only 50/59.940/60 FPS are supported!" error "-> Exiting in function: video_deinterlace_func()" echo "" rmtemp ;; esac ;; 1|"") echo "" brown "Available Deinterlacing Filters @ Original FPS" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 --> Linear Blend Deinterlacer" echo "1 --> Linear Interpolating Deinterlacer" echo "2 --> Cubic Interpolating Deinterlacer" echo "3 --> Median Deinterlacer" echo "4 --> FFmpeg Deinterlacer" echo "5 --> FIR Lowpass 5 Deinterlacer" echo "6 --> Donald Graft's Adaptive Kernel Deinterlacer" echo "7 --> Yadif Deinterlacer" echo "8 --> Fast Yadif Deinterlacer" echo "9 --> Yadif & Linear Blend" echo "10 -> Yadif & Linear Interpolation" echo "11 -> Yadif & Cubic Interpolation" echo "12 -> Yadif & Median deint" echo "13 -> Yadif & FFmpeg deint" echo "14 -> Yadif & FIR Lowpass 5" echo "15 -> Yadif & Fast Mcdeint (top fields)" echo "16 -> Yadif & Fast Mcdeint (bottom fields)" echo "17 -> Fast Yadif & Fast Mcdeint (top fields)" echo "18 -> Fast Yadif & Fast Mcdeint (bottom fields)" echo "19 -> Yadif & Medium Mcdeint (top fields)" echo "20 -> Yadif & Medium Mcdeint (bottom fields)" echo "21 -> Fast Yadif & Medium Mcdeint (top fields)" echo "22 -> Fast Yadif & Medium Mcdeint (bottom fields)" echo "23 -> Yadif & Slow Mcdeint (top fields)" echo "24 -> Yadif & Slow Mcdeint (bottom fields)" echo "25 -> Fast Yadif & Slow Mcdeint (top fields)" echo "26 -> Fast Yadif & Slow Mcdeint (bottom fields)" echo "27 -> Yadif & Slowest Mcdeint (top fields)" echo "28 -> Yadif & Slowest Mcdeint (bottom fields)" echo "29 -> Fast Yadif & Slowest Mcdeint (top fields)" echo "30 -> Fast Yadif & Slowest Mcdeint (bottom fields)" echo "31 -> Tfields" echo "32 -> Tfields & Fast Mcdeint (top fields)" echo "33 -> Tfields & Fast Mcdeint (bottom fields)" echo "34 -> Tfields & Medium Mcdeint (top fields)" echo "35 -> Tfields & Medium Mcdeint (bottom fields)" echo "36 -> Tfields & Slow Mcdeint (top fields)" echo "37 -> Tfields & Slow Mcdeint (bottom fields)" echo "38 -> Tfields & Slowest Mcdeint (top fields)" echo "39 -> Tfields & Slowest Mcdeint (bottom fields)" echo "" echo "Tip: Yadif is a good fast general purpose deinterlacer. If you" echo " deal with sports, then the Linear blend deinterlacer may" echo " be preferrable. Yadif & Mcdeint and Tfields & Mcdeint give" echo " the best results but are pretty slow." echo "" printf "Select a deinterlacing filter [default is 7]: " read dfilter case "$dfilter" in 0) deintfilter="pp=lb," ;; 1) deintfilter="pp=li," ;; 2) deintfilter="pp=ci," ;; 3) deintfilter="pp=md," ;; 4) deintfilter="pp=fd," ;; 5) deintfilter="pp=l5," ;; 6) printf "Specify the deinterlacing threshold [0-255 - default is 5]: " read kerntres if [ -z "$kerntres" ]; then deintfilter="kerndeint=5," else deintfilter="kerndeint=$kerntres," fi ;; 7|"") deintfilter="yadif=0,"; field_dominance="-field-dominance -1" ;; 8) deintfilter="yadif=2,"; field_dominance="-field-dominance -1" ;; 9) deintfilter="yadif=0,pp=lb," field_dominance="-field-dominance -1" ;; 10) deintfilter="yadif=0,pp=li," field_dominance="-field-dominance -1" ;; 11) deintfilter="yadif=0,pp=ci," field_dominance="-field-dominance -1" ;; 12) deintfilter="yadif=0,pp=md," field_dominance="-field-dominance -1" ;; 13) deintfilter="yadif=0,pp=fd," field_dominance="-field-dominance -1" ;; 14) deintfilter="yadif=0,pp=l5," field_dominance="-field-dominance -1" ;; 15) deintfilter="yadif=1,mcdeint=0:0:10,framestep=2,"; field_dominance="-field-dominance 0" ;; 16) deintfilter="yadif=1,mcdeint=0:1:10,framestep=2,"; field_dominance="-field-dominance 1" ;; 17) deintfilter="yadif=3,mcdeint=0:0:10,framestep=2,"; field_dominance="-field-dominance 0" ;; 18) deintfilter="yadif=3,mcdeint=0:1:10,framestep=2,"; field_dominance="-field-dominance 1" ;; 19) deintfilter="yadif=1,mcdeint=1:0:10,framestep=2,"; field_dominance="-field-dominance 0" ;; 20) deintfilter="yadif=1,mcdeint=1:1:10,framestep=2,"; field_dominance="-field-dominance 1" ;; 21) deintfilter="yadif=3,mcdeint=1:0:10,framestep=2,"; field_dominance="-field-dominance 0" ;; 22) deintfilter="yadif=3,mcdeint=1:1:10,framestep=2,"; field_dominance="-field-dominance 1" ;; 23) deintfilter="yadif=1,mcdeint=2:0:10,framestep=2,"; field_dominance="-field-dominance 0"; quiet="2>/dev/null" ;; 24) deintfilter="yadif=1,mcdeint=2:1:10,framestep=2,"; field_dominance="-field-dominance 1"; quiet="2>/dev/null" ;; 25) deintfilter="yadif=3,mcdeint=2:0:10,framestep=2,"; field_dominance="-field-dominance 0"; quiet="2>/dev/null" ;; 26) deintfilter="yadif=3,mcdeint=2:1:10,framestep=2,"; field_dominance="-field-dominance 1"; quiet="2>/dev/null" ;; 27) deintfilter="yadif=1,mcdeint=3:0:10,framestep=2,"; field_dominance="-field-dominance 0"; quiet="2>/dev/null" ;; 28) deintfilter="yadif=1,mcdeint=3:1:10,framestep=2,"; field_dominance="-field-dominance 1"; quiet="2>/dev/null" ;; 29) deintfilter="yadif=3,mcdeint=3:0:10,framestep=2,"; field_dominance="-field-dominance 0"; quiet="2>/dev/null" ;; 30) deintfilter="yadif=3,mcdeint=3:1:10,framestep=2,"; field_dominance="-field-dominance 1"; quiet="2>/dev/null" ;; 31) deintfilter="tfields=4,framestep=2,"; field_dominance="-field-dominance -1" ;; 32) deintfilter="tfields=4,mcdeint=0:0:10,framestep=2,"; field_dominance="-field-dominance 0" ;; 33) deintfilter="tfields=4,mcdeint=0:1:10,framestep=2,"; field_dominance="-field-dominance 1" ;; 34) deintfilter="tfields=4,mcdeint=1:0:10,framestep=2,"; field_dominance="-field-dominance 0" ;; 35) deintfilter="tfields=4,mcdeint=1:1:10,framestep=2,"; field_dominance="-field-dominance 1" ;; 36) deintfilter="tfields=4,mcdeint=2:0:10,framestep=2,"; field_dominance="-field-dominance 0"; quiet="2>/dev/null" ;; 37) deintfilter="tfields=4,mcdeint=2:1:10,framestep=2,"; field_dominance="-field-dominance 1"; quiet="2>/dev/null" ;; 38) deintfilter="tfields=4,mcdeint=3:0:10,framestep=2,"; field_dominance="-field-dominance 0"; quiet="2>/dev/null" ;; 39) deintfilter="tfields=4,mcdeint=3:1:10,framestep=2,"; field_dominance="-field-dominance 1"; quiet="2>/dev/null" ;; *) error "-> Unknown option: '$dfilter'" error "-> Exiting in function: video_deinterlace_func()" rmtemp ;; esac ;; 2) quiet="2>/dev/null" echo "" brown "Available Deinterlacing Filters @ Double FPS" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 --> Yadif Deinterlacer" echo "1 --> Fast Yadif Deinterlacer" echo "2 --> Yadif & Fast Mcdeint (top fields)" echo "3 --> Yadif & Fast Mcdeint (bottom fields)" echo "4 --> Fast Yadif & Fast Mcdeint (top fields)" echo "5 --> Fast Yadif & Fast Mcdeint (bottom fields)" echo "6 --> Yadif & Medium Mcdeint (top fields)" echo "7 --> Yadif & Medium Mcdeint (bottom fields)" echo "8 --> Fast Yadif & Medium Mcdeint (top fields)" echo "9 --> Fast Yadif & Medium Mcdeint (bottom fields)" echo "10 -> Yadif & Slow Mcdeint (top fields)" echo "11 -> Yadif & Slow Mcdeint (bottom fields)" echo "12 -> Fast Yadif & Slow Mcdeint (top fields)" echo "13 -> Fast Yadif & Slow Mcdeint (bottom fields)" echo "14 -> Yadif & Slowest Mcdeint (top fields)" echo "15 -> Yadif & Slowest Mcdeint (bottom fields)" echo "16 -> Fast Yadif & Slowest Mcdeint (top fields)" echo "17 -> Fast Yadif & Slowest Mcdeint (bottom fields)" echo "18 -> Tfields (top fields)" echo "19 -> Tfields (bottom fields)" echo "20 -> Tfields & Fast Mcdeint (top fields)" echo "21 -> Tfields & Fast Mcdeint (bottom fields)" echo "22 -> Tfields & Medium Mcdeint (top fields)" echo "23 -> Tfields & Medium Mcdeint (bottom fields)" echo "24 -> Tfields & Slow Mcdeint (top fields)" echo "25 -> Tfields & Slow Mcdeint (bottom fields)" echo "26 -> Tfields & Slowest Mcdeint (top fields)" echo "27 -> Tfields & Slowest Mcdeint (bottom fields)" echo "" printf "Select a deinterlacing filter [default is 0]: " read dfilter case "$dfilter" in 0|"") deintfilter="yadif=1,"; field_dominance="-field-dominance -1" ;; 1) deintfilter="yadif=3,"; field_dominance="-field-dominance -1" ;; 2) deintfilter="yadif=1,mcdeint=0:0:10,"; field_dominance="-field-dominance 0" ;; 3) deintfilter="yadif=1,mcdeint=0:1:10,"; field_dominance="-field-dominance 1" ;; 4) deintfilter="yadif=3,mcdeint=0:0:10,"; field_dominance="-field-dominance 0" ;; 5) deintfilter="yadif=3,mcdeint=0:1:10,"; field_dominance="-field-dominance 1" ;; 6) deintfilter="yadif=1,mcdeint=1:0:10,"; field_dominance="-field-dominance 0" ;; 7) deintfilter="yadif=1,mcdeint=1:1:10,"; field_dominance="-field-dominance 1" ;; 8) deintfilter="yadif=3,mcdeint=1:0:10,"; field_dominance="-field-dominance 0" ;; 9) deintfilter="yadif=3,mcdeint=1:1:10,"; field_dominance="-field-dominance 1" ;; 10) deintfilter="yadif=1,mcdeint=2:0:10,"; field_dominance="-field-dominance 0" ;; 11) deintfilter="yadif=1,mcdeint=2:1:10,"; field_dominance="-field-dominance 1" ;; 12) deintfilter="yadif=3,mcdeint=2:0:10,"; field_dominance="-field-dominance 0" ;; 13) deintfilter="yadif=3,mcdeint=2:1:10,"; field_dominance="-field-dominance 1" ;; 14) deintfilter="yadif=1,mcdeint=3:0:10,"; field_dominance="-field-dominance 0" ;; 15) deintfilter="yadif=1,mcdeint=3:1:10,"; field_dominance="-field-dominance 1" ;; 16) deintfilter="yadif=3,mcdeint=3:0:10,"; field_dominance="-field-dominance 0" ;; 17) deintfilter="yadif=3,mcdeint=3:1:10,"; field_dominance="-field-dominance 1" ;; 18) deintfilter="tfields=4,"; field_dominance="-field-dominance 0" ;; 19) deintfilter="tfields=4,"; field_dominance="-field-dominance 1" ;; 20) deintfilter="tfields=4,mcdeint=0:0:10,"; field_dominance="-field-dominance 0" ;; 21) deintfilter="tfields=4,mcdeint=0:1:10,"; field_dominance="-field-dominance 1" ;; 22) deintfilter="tfields=4,mcdeint=1:0:10,"; field_dominance="-field-dominance 0" ;; 23) deintfilter="tfields=4,mcdeint=1:1:10,"; field_dominance="-field-dominance 1" ;; 24) deintfilter="tfields=4,mcdeint=2:0:10,"; field_dominance="-field-dominance 0" ;; 25) deintfilter="tfields=4,mcdeint=2:1:10,"; field_dominance="-field-dominance 1" ;; 26) deintfilter="tfields=4,mcdeint=3:0:10,"; field_dominance="-field-dominance 0" ;; 27) deintfilter="tfields=4,mcdeint=3:1:10,"; field_dominance="-field-dominance 1" ;; *) error "-> Unknown option: '$dfilter'" error "-> Exiting in function: video_deinterlace_func()" rmtemp ;; esac source_fps_func deintdouble case "$SOURCEFPS" in 15.98[4-5]|15.98) deintfps="32000/1001" deintofps="32000/1001" green "-> Detected $SOURCEFPS FPS (Silent Film)" calc_fps_func echo "" ;; 17.982|17.98) deintfps="36000/1001" deintofps="36000/1001" green "-> Detected $SOURCEFPS FPS (Silent Film)" calc_fps_func echo "" ;; 24.000|24.00) deintfps="48" deintofps="48" green "-> Detected $SOURCEFPS FPS (Film)" calc_fps_func echo "" ;; 25.000|25.00) deintfps="50" deintofps="50" green "-> Detected $SOURCEFPS FPS (PAL/SECAM Film/Video)" calc_fps_func echo "" ;; 50.000|50.00) deintfps="100" deintofps="100" green "-> Detected $SOURCEFPS FPS (PAL/SECAM Double)" calc_fps_func echo "" ;; 100.000|100.00) deintfps="200" deintofps="200" green "-> Detected $SOURCEFPS FPS (PAL/SECAM Quad)" calc_fps_func echo "" ;; 23.976|23.97) deintfps="48000/1001" deintofps="48000/1001" green "-> Detected $SOURCEFPS FPS (NTSC Film)" calc_fps_func echo "" ;; 29.970|29.97) set_manual=yes deintfps="60000/1001" deintofps="60000/1001" green "-> Detected $SOURCEFPS FPS (NTSC Video)" calc_fps_func green "-> Note: NTSC FPS detection is not 100% reliable!" echo "" ;; 30.000|30.00) deintfps="60" deintofps="60" green "-> Detected $SOURCEFPS FPS (NTSC Video)" calc_fps_func echo "" ;; 59.940|59.94) deintfps="120000/1001" deintofps="120000/1001" green "-> Detected $SOURCEFPS FPS (NTSC Double)" calc_fps_func echo "" ;; 60.000|60.00) deintfps="120" deintofps="120" green "-> Detected $SOURCEFPS FPS (NTSC Double)" calc_fps_func echo "" ;; 119.880|119.88) deintfps="240000/1001" deintofps="240000/1001" green "-> Detected $SOURCEFPS FPS (NTSC Quad)" calc_fps_func echo "" ;; ""|*) green "-> Could not detect a supported frame rate!" green "-> You have to set it manually!" deint_custom_fps_func ;; esac # Offer the user an option to set the # fps manually as detection of NTSC # is not very reliable! Damn the NTSC # crapware! if [ "$set_manual" = "yes" ]; then printf "Continue (c) with the current setting or set FPS manually (m)? [c/m]: " read cfpsm case "$cfpsm" in c|C) true ;; m|M) deint_custom_fps_func ;; ""|*) error "-> Option unknown or not specified!" error "-> Exiting in function: video_deinterlace_func()" rmtemp ;; esac fi ;; 3) false ;; *) error "-> Unknown deinterlace method: '$deintmethod'" error "-> Exiting in function: video_deinterlace_func()" rmtemp ;; esac fi else interlaced=":nointerlaced" fi } # Video interlacing. video_interlace_func() { if [ -z "$deintfilter" -a "$interlaced" = ":nointerlaced" ]; then intenc=$(get_selection_func "Would you like to Interlace the encoding? [y/N]: ") if [ "$intenc" = "y" ]; then interlaced=":interlaced:pic_struct" echo "" brown "Interlace Field And Frame Orders" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "With the filters below, one can produce interlaced" echo "content out of progressive one. Note that only progressive" echo "PAL 50 and 100 fps and progressive NTSC 59.94 and 119.88" echo "fps content is supported as input! After the encoding is" echo "done, you will either have 25 or 50 fps interlaced PAL or" echo "29.97 or 59.94 fps interlaced NTSC encode." echo "" echo "0 -> Top field first order + odd frames output" echo "1 -> Top field first order + even frames output" echo "2 -> Bottom field first order + odd frames output" echo "3 -> Bottom field first order + even frames output" echo "4 -> Capture unknown/varying (auto) + odd frames output" echo "5 -> Capture unknown/varying (auto) + even frames output" echo "6 -> Auto-select by field flags + odd frames output" echo "7 -> Auto-select by field flags + even frames output" echo "8 -> Interleave even lines from even frames with odd" echo " lines from odd frames" echo "9 -> Skip interlacing" echo "" printf "Select the Interlacing method [default is 1]: " read intmeth case "$intmeth" in 0) intfilter=",phase=t,tinterlace=1" ;; 1|"") intfilter=",phase=t,tinterlace=2" ;; 2) intfilter=",phase=b,tinterlace=1" ;; 3) intfilter=",phase=b,tinterlace=2" ;; 4) intfilter=",phase=u,tinterlace=1" ;; 5) intfilter=",phase=u,tinterlace=2" ;; 6) intfilter=",phase=a,tinterlace=1" ;; 7) intfilter=",phase=a,tinterlace=2" ;; 8) intfilter=",tinterlace=4" ;; 9) interlaced=":nointerlaced" ;; *) error "-> Unknown interlace option: '$intmeth'" error "-> Exiting in function: video_interlace_func()" rmtemp ;; esac case "$intmeth" in [0-8]|"") quiet="2>/dev/null" source_fps_func interlace case "$SOURCEFPS" in 50.000|50.00) intfps="50" intofps="25" green "-> Detected $SOURCEFPS FPS (PAL/SECAM Double)" calc_fps_func ;; 100.000|100.00) intfps="100" intofps="50" green "-> Detected $SOURCEFPS FPS (PAL/SECAM Quad)" calc_fps_func ;; 59.940|59.94) intfps="60000/1001" intofps="30000/1001" green "-> Detected $SOURCEFPS FPS (NTSC Double)" calc_fps_func ;; 60.000|60.00) intfps="60" intofps="30" green "-> Detected $SOURCEFPS FPS (NTSC Double)" calc_fps_func ;; 119.880|119.88) intfps="120000/1001" intofps="60000/1001" green "-> Detected $SOURCEFPS FPS (NTSC Quad)" calc_fps_func ;; "") error "-> Could not detect the source FPS value!" error "-> Exiting in function: video_interlace_func()" echo "" rmtemp ;; *) error "-> The detected source FPS ($SOURCEFPS) is not supported!" error "-> Supported frame rates are: 50/100/59.940/60/119.880 FPS" error "-> Exiting in function: video_interlace_func()" echo "" rmtemp ;; esac ;; esac fi fi } # Postprocessing video_deblock_func() { db=$(get_selection_func "Would you like to Deblock/Dering the $type? [y/N]: ") if [ "$db" = "y" ]; then echo "" brown "Postprocessing Deblock/Dering Filters" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "The filters below have tunable parameters." echo "Higher values will filter the content more" echo "but can also introduce too much blurring" echo "and/or smear it. Note to only use deblocking" echo "filters if your $type shows blocking artifacts" echo "" echo "0 -> spp: Simple postprocessing filter" echo "1 -> uspp: Ultra simple/slow postprocessing filter" echo "2 -> fspp: Fast simple postprocessing filter" echo "3 -> pp7: Variant of spp with 7 points DCT" echo "4 -> ha/va/dr: Deblock/dering postprocessing filters" echo "5 -> ha/va: Deblock postprocessing filters" echo "6 -> dr: Dering postprocessing filter" echo "7 -> Skip postprocessing" echo "" printf "Select a Deblock/Dering filter [default is 0]: " read dbfilter case "$dbfilter" in 0|"") printf "Specify the Quality level [0-6 - default is 3]: " read dbqlevel if [ -z "$dbqlevel" ]; then deblockfilter="spp=3," else deblockfilter="spp=$dbqlevel," fi ;; 1) printf "Specify the Quality level [0-8 - default is 2]: " read dbqlevel if [ -z "$dbqlevel" ]; then deblockfilter="uspp=2," else deblockfilter="uspp=$dbqlevel," fi ;; 2) printf "Specify the Quality level [0-6 - default is 4]: " read dbqlevel if [ -z "$dbqlevel" ]; then deblockfilter="fspp=4," else deblockfilter="fspp=$dbqlevel," fi ;; 3) printf "Specify the Quality Quantization parameter [0-31 - default is 3]: " read dbqlevel if [ -z "$dbqlevel" ]; then deblockfilter="pp7=3," else deblockfilter="pp7=$dbqlevel," fi ;; 4) echo "" brown "ha/va/dr deblock/dering filters" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "The 'ha' and 'va' filters are the old" echo "postprocessing deblock filters. Both share" echo "two threshold values. The first value is" echo "the difference factor where a higher value" echo "will do more deblocking. The second value" echo "is the flatness threshold where a lower" echo "value will do more deblocking. The 'dr'" echo "filter is the deringing filter. The format" echo "is as follows: difference:flatness" echo "" printf "Specify the Difference and Flatness values [default is 164:7]: " read dfv if [ -z "$dfv" ]; then deblockfilter="pp=ha:164:7:c/va:c/dr:c," else deblockfilter="pp=ha:$dfv:c/va:c/dr:c," fi ;; 5) echo "" brown "ha/va deblocking filters" brown "~~~~~~~~~~~~~~~~~~~~~~~~" echo "The 'ha' and 'va' filters are the old" echo "postprocessing deblock filters. Both share" echo "two threshold values. The first value is" echo "the difference factor where a higher value" echo "will do more deblocking. The second value" echo "is the flatness threshold where a lower" echo "value will do more deblocking. The format" echo "is as follows: difference:flatness" echo "" printf "Specify the Difference and Flatness values [default is 164:7]: " read dfv if [ -z "$dfv" ]; then deblockfilter="pp=ha:164:7:c/va:c," else deblockfilter="pp=ha:$dfv:c/va:c," fi ;; 6) deblockfilter="pp=dr:c," ;; 7) false ;; *) error "-> Unknown deblock/dering option: '$dbfilter'" error "-> Exiting in function: video_deblock_func()" rmtemp ;; esac fi } # Postprocessing video_delogo_func() { db=$(get_selection_func "Would you like to Delogo the $type? [y/N]: ") if [ "$db" = "y" ]; then HANDLE="$TEMPDIR/fifofile" wd=10 hd=10 xd=10 yd=10 wv=25 hv=25 xv=1 yv=1 mkfifo $HANDLE $MPLAYER -quiet -slave -input file="$HANDLE" -vf rectangle="$wv":"$hv":"$xv":"$yv" "$infile" >/dev/null 2>&1 & while [ 0 ]; do echo "" brown "Delogo Video Filter" brown "~~~~~~~~~~~~~~~~~~~" echo "Suppresses a TV station logo by a simple" echo "interpolation of the surrounding pixels." echo "Just set a rectangle covering the logo" echo "and watch it disappear (and sometimes" echo "something even uglier appear - your mileage" echo "may vary)." echo "Specify the positon and size:" echo "" echo "0 -> Change X-Pos." echo "1 -> Change Y-Pos." echo "2 -> Change Width" echo "3 -> Change Height" echo "4 -> Finish" echo "" printf "Select a Delogo function: " read delogoval case "$delogoval" in 0) while [ 0 ]; do clear echo "" brown "Delogo Video Filter - X-Position" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" printf "Change X-Pos=$xv [default is $xd, q to finish]: " read v if [ -z "$v" ]; then v=$xd elif [ "$v" = "q" -o "$v" = "Q" ]; then break; fi xd=$v let xv=$xv+$v echo "change_rectangle 2 $v" >> $HANDLE done ;; 1) while [ 0 ]; do clear echo "" brown "Delogo Video Filter - Y-Position" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" printf "Change Y-Pos=$yv [default is $yd, q to finish]: " read v if [ -z "$v" ]; then v=$yd elif [ "$v" = "q" -o "$v" = "Q" ]; then break; fi yd=$v let yv=$yv+$v echo "change_rectangle 3 $v" >> $HANDLE done ;; 2) while [ 0 ]; do clear echo "" brown "Delogo Video Filter - Width" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~" printf "Change Width=$wv [default is $wd, q to finish]: " read v if [ -z "$v" ]; then v=$wd elif [ "$v" = "q" -o "$v" = "Q" ]; then break; fi wd=$v let wv=$wv+$v echo "change_rectangle 0 $v" >> $HANDLE done ;; 3) while [ 0 ]; do clear echo "" brown "Delogo Video Filter - Height" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~" printf "Change Height=$hv [default is $hd, q to finish]: " read v if [ -z "$v" ]; then v=$hd elif [ "$v" = "q" -o "$v" = "Q" ]; then break; fi hd=$v let hv=$hv+$v echo "change_rectangle 1 $v" >> $HANDLE done ;; 4) break; ;; esac done echo "quit" >> $HANDLE delogofilter="delogo=$xv:$yv:$wv:$hv:1," fi } # Denoising video_denoise_func() { denoise=$(get_selection_func "Would you like to Denoise the $type? [y/N]: ") if [ "$denoise" = "y" ]; then echo "" brown "3D Denoiser HQ 3D Denoiser" brown "~~~~~~~~~~~ ~~~~~~~~~~~~~~" echo "0 --> denoise3d: weak 5 --> hqdn3d: weak" echo "1 --> denoise3d: medium 6 --> hqdn3d: medium" echo "2 --> denoise3d: strong 7 --> hqdn3d: strong" echo "3 --> denoise3d: extra strong 8 --> hqdn3d: extra strong" echo "4 --> denoise3d: user defined 9 --> hqdn3d: user defined" echo "" brown "Overcomplete Wavelet Denoiser Temporal Denoiser" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~" echo "10 -> ow: weak 15 -> tn: weak" echo "11 -> ow: medium 16 -> tn: medium" echo "12 -> ow: strong 17 -> tn: strong" echo "13 -> ow: extra strong 18 -> tn: extra strong" echo "14 -> ow: user defined 19 -> tn: user defined" echo "" brown " x264 Internal Denoiser" brown " ~~~~~~~~~~~~~~~~~~~~~~" echo " 20 -> x264: weak" echo " 21 -> x264: medium" echo " 22 -> x264: strong" echo " 23 -> x264: extra strong" echo " 24 -> x264: user defined" echo " 25 -> Skip denoising" echo "" printf "Select a Denoise filter and strength [default is 6]: " read dnfilt case "$dnfilt" in 0) denoisefilter="denoise3d=3:2:5," ;; 1) denoisefilter="denoise3d=4:3:6," ;; 2) denoisefilter="denoise3d=7:6:9," ;; 3) denoisefilter="denoise3d=10:9:12," ;; 4) printf "Specify the Denoise values [default is 3:2:4]: " read dnvalues if [ -z "$dnvalues" ]; then denoisefilter="denoise3d=3:2:4," else denoisefilter="denoise3d=$dnvalues," fi ;; 5) denoisefilter="hqdn3d=3:2:5," ;; 6|"") denoisefilter="hqdn3d=4:3:6," ;; 7) denoisefilter="hqdn3d=7:6:9," ;; 8) denoisefilter="hqdn3d=10:9:12," ;; 9) printf "Specify the Denoise values [default is 3:2:4]: " read dnvalues if [ -z "$dnvalues" ]; then denoisefilter="hqdn3d=3:2:4," else denoisefilter="hqdn3d=$dnvalues," fi ;; 10) denoisefilter="ow=3:1.2:1.2," ;; 11) denoisefilter="ow=6:1.2:1.2," ;; 12) denoisefilter="ow=9:1.2:1.2," ;; 13) denoisefilter="ow=12:1.2:1.2," ;; 14) printf "Specify the Denoise values [default is 5:1.2:1.2]: " read dnvalues if [ -z "$dnvalues" ]; then denoisefilter="ow=5:1.2:1.2," else denoisefilter="ow=$dnvalues," fi ;; 15) denoisefilter="pp=tn:32:64:128:c," ;; 16) denoisefilter="pp=tn:64:128:256:c," ;; 17) denoisefilter="pp=tn:128:256:512:c," ;; 18) denoisefilter="pp=tn:256:512:1024:c," ;; 19) printf "Specify the Denoise values [default is 64:128:256]: " read dnvalues if [ -z "$dnvalues" ]; then denoisefilter="pp=tn:64:128:256:c," else denoisefilter="pp=tn:$dnvalues:c," fi ;; 20) nr=":nr=250" ;; 21) nr=":nr=600" ;; 22) nr=":nr=1200" ;; 23) nr=":nr=2400" ;; 24) printf "Specify the Denoise value [0-100000 - default is 300]: " read dnvalues if [ -z "$dnvalues" ]; then nr=":nr=300" else nr=":nr=$dnvalues" fi ;; 25) false ;; *) error "-> Unknown denoise option: '$dnfilt'" error "-> Exiting in function: video_denoise_func()" rmtemp ;; esac fi } # Noise filter video_noise_func() { if [ -z "$denoisefilter" -a -z "$nr" ]; then noise=$(get_selection_func "Would you like to add Noise to the $type? [y/N]: ") if [ "$noise" = "y" ]; then echo brown "Noise Types" brown "~~~~~~~~~~~" echo "u -> Uniform noise" echo "t -> Temporal noise" echo "a -> Averaged temporal noise" echo "h -> High quality" echo "p -> Mix random noise with a (semi)regular pattern" echo echo "Example of filter's usage: 8ha:2t" echo echo "The first value sets the Luma amount and noise type(s)" echo "while the second one does so for Chroma. The Luma/Chroma" echo "ranges are between 0 and 100 with 0 completely disabling" echo "filtering on the Luma and/or Chroma planes. Mixing different" echo "types of noise is possible as shown in the above example." echo printf "Specify the Noise filter parameters [press 'Enter' to skip]: " read noiseparam if [ ! -z "$noiseparam" ]; then noisefilter=",noise=$noiseparam" fi fi fi } # Debanding filter video_deband_func() { deband=$(get_selection_func "Would you like to Deband the $type? [y/N]: ") if [ "$deband" = "y" ]; then printf "Specify the Deband filter strength and radius [default is 1.2:16]: " read debandparam if [ -z "$debandparam" ]; then debandfilter="gradfun=1.2:16," else debandfilter="gradfun=$debandparam," fi fi } # (Un)sharp mask/gaussian blur # video filter video_unsharp_func() { sharpblur=$(get_selection_func "Would you like to Sharpen or Blur the $type? [y/N]: ") if [ "$sharpblur" = "y" ]; then echo "" brown "(Un)sharp Mask/Gaussian Blur Video Filter" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "With the '(un)sharp mask / gaussian blur' filter" echo "one can sharpen or blur the content. The filter" echo "can operate only on the Luma (light) components," echo "only on the Chroma (color) components or on both" echo "at the same time. It is recommended to use very" echo "small values or the content will become too sharp" echo "or too blurry. The sane range for the amount of blur" echo "or sharpness to add to the image is between -1.50 and" echo "1.50. Negative values will blur the image, positive" echo "values will sharpen the image. A value of 0.00 (or 0" echo "or 0.0) will disable filtering. The filter also uses" echo "an odd-sized matrix which defines its operating area" echo "in width and height. Below are the recommended" echo "matrices one can choose from. Small matrix sizes" echo "are usually better, but this depends on the source." echo "" echo "0 -> Luma 3x3 matrix 6 --> Chroma 3x3 matrix" echo "1 -> Luma 5x5 matrix 7 --> Chroma 5x5 matrix" echo "2 -> Luma 7x7 matrix 8 --> Chroma 7x7 matrix" echo "3 -> Luma 9x9 matrix 9 --> Chroma 9x9 matrix" echo "4 -> Luma 11x11 matrix 10 -> Chroma 11x11 matrix" echo "5 -> Luma 13x11 matrix 11 -> Chroma 13x11 matrix" echo "" echo " 12 -> Luma & Chroma 3x3 matrix" echo " 13 -> Luma & Chroma 5x5 matrix" echo " 14 -> Luma & Chroma 7x7 matrix" echo " 15 -> Luma & Chroma 9x9 matrix" echo " 16 -> Luma & Chroma 11x11 matrix" echo " 17 -> Luma & Chroma 13x11 matrix" echo " 18 -> Skip sharpen/blur" echo "" printf "Select the Filtering Mode and Matrix Size [default is 13]: " read fmms case "$fmms" in [0-5]) printf "Specify the amount of Luma filtering [default is 0.00]: " read lumafilt if [ -z "$lumafilt" ]; then lumavalue="0.00" else lumavalue="$lumafilt" fi case "$fmms" in 0) unsharpfilter=",unsharp=l3x3:$lumavalue" ;; 1) unsharpfilter=",unsharp=l5x5:$lumavalue" ;; 2) unsharpfilter=",unsharp=l7x7:$lumavalue" ;; 3) unsharpfilter=",unsharp=l9x9:$lumavalue" ;; 4) unsharpfilter=",unsharp=l11x11:$lumavalue" ;; 5) unsharpfilter=",unsharp=l13x11:$lumavalue" ;; esac ;; [6-9]|1[0-1]) printf "Specify the amount of Chroma filtering [default is 0.00]: " read chromafilt if [ -z "$chromafilt" ]; then chromavalue="0.00" else chromavalue="$chromafilt" fi case "$fmms" in 6) unsharpfilter=",unsharp=c3x3:$chromavalue" ;; 7) unsharpfilter=",unsharp=c5x5:$chromavalue" ;; 8) unsharpfilter=",unsharp=c7x7:$chromavalue" ;; 9) unsharpfilter=",unsharp=c9x9:$chromavalue" ;; 10) unsharpfilter=",unsharp=c11x11:$chromavalue" ;; 11) unsharpfilter=",unsharp=c13x11:$chromavalue" ;; esac ;; 1[2-7]|"") printf "Specify the amount of Luma filtering [default is 0.00]: " read lumafilt if [ -z "$lumafilt" ]; then lumavalue="0.00" else lumavalue="$lumafilt" fi printf "Specify the amount of Chroma filtering [default is 0.00]: " read chromafilt if [ -z "$chromafilt" ]; then chromavalue="0.00" else chromavalue="$chromafilt" fi case "$fmms" in 12) unsharpfilter=",unsharp=l3x3:$lumavalue:c3x3:$chromavalue" ;; 13|"") unsharpfilter=",unsharp=l5x5:$lumavalue:c5x5:$chromavalue" ;; 14) unsharpfilter=",unsharp=l7x7:$lumavalue:c7x7:$chromavalue" ;; 15) unsharpfilter=",unsharp=l9x9:$lumavalue:c9x9:$chromavalue" ;; 16) unsharpfilter=",unsharp=l11x11:$lumavalue:c11x11:$chromavalue" ;; 17) unsharpfilter=",unsharp=l13x11:$lumavalue:c13x11:$chromavalue" ;; esac ;; 18) false ;; *) error "-> Unknown filtering mode and matrix option: '$fmms'" error "-> Exiting in function: video_unsharp_func()" rmtemp ;; esac fi } # Automatic brightness/contrast # control function video_brightness_func() { abc=$(get_selection_func "Would you like to use Automatic Brightness/Contrast? [y/N]: ") if [ "$abc" = "y" ]; then echo "" brown "Automatic Brightness/Contrast Control" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Luminance-only control" echo "1 -> Chrominance-only control" echo "2 -> Luminance & Chrominance control" echo "3 -> Skip automatic brightness/contrast" echo "" printf "Select the Automatic brightness/contrast control [default is 2]: " read abcc case "$abcc" in 0) brightnessfilter="pp=al:y," ;; 1) brightnessfilter="pp=al:n," ;; 2|"") brightnessfilter="pp=al:c," ;; 3) false ;; *) error "-> Unknown brightness/contrast option: '$abcc'" error "-> Exiting in function: video_brightness_func()" rmtemp ;; esac fi } # Software EQ filter. Mutually # exclusive with the above one video_equalizer_func() { if [ -z "$brightnessfilter" ]; then softeq=$(get_selection_func "Would you like to use the Software Equalizer filter? [y/N]: ") if [ "$softeq" = "y" ]; then echo brown "Video Software Equalizer Filter" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "The eq2 software equalizer filter operates just like" echo "hardware equalizers. In addition to simple brightness" echo "and contrast adjustments, it also allows for gamma and" echo "saturation corrections. If you're not familiar with" echo "its parameters, I suggest consulting the man page of" echo "MPlayer and look for the eq2 filter." echo "" echo "The format is as follows:" echo "gamma:contrast:brightness:saturation:rg:gg:bg:weight" echo printf "Specify the eq2 values [default is filter defaults]: " read eq2 if [ -z "$eq2" ]; then eq2filter=",eq2" else eq2filter=",eq2=$eq2" fi fi fi } # Colorspace conversion. Can only # be used when the user is scaling # the content as this filter needs # the 'scale' filter to do the real # colorspace conversion. Don't ask # for colorspace conversion if we # use a deinterlacer or are # interlacing progressive content # as it does not work with these # filters video_colorspace_func() { if [ -z "$deintfilter" -a -z "$intfilter" ]; then csconv=$(get_selection_func "Would you like to perform a Colorspace conversion? [y/N]: ") if [ "$csconv" = "y" ]; then echo "" brown "Colorspace Formats" brown "~~~~~~~~~~~~~~~~~~" echo "0 --> 444P (YUV444P - Planar)" echo "1 --> 422P (YUV422P - Planar)" echo "2 --> 411P (YUV411P - Planar)" echo "3 --> YUY2 (YUYV422 - Packed)" echo "4 --> UYVY (UYVY422 - Packed)" echo "5 --> YVU9 (YUV410P - Planar)" echo "6 --> IF09 (YUV410P - Planar)" echo "7 --> YV12 (YUV420P - Planar)" echo "8 --> I420 (YUV420P - Planar)" echo "9 --> Y800 (Gray - Planar)" echo "10 -> Skip colorspace conversion" echo "" printf "Select a Colorspace format [default is 7]: " read csp case "$csp" in 0) colorspacefilter="format=444p," ;; 1) colorspacefilter="format=422p," ;; 2) colorspacefilter="format=411p," ;; 3) colorspacefilter="format=yuy2," ;; 4) colorspacefilter="format=uyvy," ;; 5) colorspacefilter="format=yvu9," ;; 6) colorspacefilter="format=if09," ;; 7|"") colorspacefilter= ;; 8) colorspacefilter="format=i420," ;; 9) colorspacefilter="format=y800," ;; 10) false ;; *) error "-> Unknown colorspace option: '$csp'" error "-> Exiting in function: video_colorspace_func()" rmtemp ;; esac fi fi } # Subtitles get_subtitles_func() { echo "" green "-> Scanning for subtitles..." $MPLAYER "$sourcetype" $device $MPLAYEROPTS -nosound -vo null -frames 1 -nocache 2>/dev/null > "$TEMPDIR/subs" SUBS=$(grep '^subtitle' "$TEMPDIR/subs") rm -f "$TEMPDIR/subs" echo "" brown "Available Subtitles On Disc" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~" if [ ! -z "$SUBS" ]; then echo "$SUBS" | sed -e 's/^subtitle //g' -e 's/( sid ):/Subtitle ID:/g' -e 's/language:/- Language:/g' else green "-> No subtitles available or failed to detect them!" fi echo "" } video_subtitles_align_func() { echo brown "Subtitle Alignment" brown "~~~~~~~~~~~~~~~~~~" echo "0 -> Original position" echo "1 -> Align at top (original behavior)" echo "2 -> Align at center" echo "3 -> Align at bottom" echo printf "Select the Subtitle alignment [default is 1]: " read subalign case "$subalign" in 0) spualign="-spualign -1" ;; 1|"") spualign="-spualign 0" ;; 2) spualign="-spualign 1" ;; 3) spualign="-spualign 2" ;; *) error "-> Unknown option: '$subalign'" error "-> Exiting in sub-function: video_subtitles_align_func()" rmtemp ;; esac } video_subtitles_codepage_func() { printf "Specify a Codepage for the subtitle [press 'Enter' to skip]: " read subcodepage if [ ! -z "$subcodepage" ]; then subcp="-subcp $subcodepage" fi } video_subtitles_func() { sub=$(get_selection_func "Would you like to include/rip a Subtitle? [y/N]: ") if [ "$sub" = "y" ]; then case "$source" in file|dir|vcd) echo "" brown "Subtitle Methods" brown "~~~~~~~~~~~~~~~~" echo "0 -> Hardcode a given subtitle into the video" echo "1 -> Import subtitle(s) into the MKV/MP4/OGM containers" echo "2 -> Skip subtitle inclusion" echo "" printf "Select the Subtitle Method [default is 0]: " read submethod case "$submethod" in 0|"") printf "Provide the subtitle file [press 'Enter' to skip]: " read -e subfile if [ ! -z "$subfile" ]; then if [ ! -f "$subfile" ]; then echo green "-> No such file: '$subfile'" green "-> Skipping subtitle" echo else video_subtitles_codepage_func case "${subfile##*.}" in idx|IDX|sub|SUB) video_subtitles_align_func ;; esac subtitle[1]="-sub \"$subfile\" -subfont-autoscale 1 $spualign $subcp" fi fi ;; 1) for i in {1..3}; do printf "Provide the subtitle file (sub $i) [press 'Enter' to skip]: " read -e subfile[$i] if [ ! -z "${subfile[$i]}" ]; then if [ ! -f "${subfile[$i]}" ]; then echo green "-> No such file: '${subfile[$i]}'" green "-> Skipping subtitle $i" echo else EXTSUB[$i]="${subfile[$i]}" fi fi done ;; 2) nosub="-nosub" ;; *) error "-> Unknown option: '$submethod'" error "-> Exiting in function: video_subtitles_func()" rmtemp ;; esac ;; dvd) echo "" brown "Subtitle Methods" brown "~~~~~~~~~~~~~~~~" echo "0 -> Hardcode a DVD subtitle into the movie" echo echo "1 -> Hardcode an external subtitle into the movie" echo echo "2 -> Dump DVD subtitle(s) to file(s) on disk" echo " and optionally import them into MKV/MP4" echo echo "3 -> Import external subtitle(s) into MKV/MP4/OGM" echo echo "4 -> Skip subtitle inclusion" echo "" printf "Select the Subtitle Method [default is 2]: " read submethod case "$submethod" in 0) get_subtitles_func printf "Specify the Subtitle ID number [press 'Enter' to skip]: " read subid if [ ! -z "$(echo $subid | grep '[a-zA-Z]')" ]; then echo green "-> You have to specify the Subtitle ID number, not the language code!" green "-> Skipping subtitle" echo else if [ ! -z "$subid" ]; then video_subtitles_align_func subtitle[1]="-sid $subid -spuaa 4 -spugauss 0.7 $spualign" fi fi ;; 1) printf "Provide the subtitle file [press 'Enter' to skip]: " read -e exthcsub if [ ! -z "$exthcsub" ]; then if [ ! -e "$exthcsub" ]; then echo error "-> No such file: '$exthcsub'" error "-> Skipping..." echo else video_subtitles_codepage_func case "${exthcsub##*.}" in idx|IDX|sub|SUB) video_subtitles_align_func ;; esac subtitle[1]="-sub \"$exthcsub\" -subfont-autoscale 1 $spualign $subcp" fi fi ;; 2|"") # First subtitle gets dumped during # encoding time, second/third one after # encoding has finished get_subtitles_func for i in {1..3}; do printf "Specify the Subtitle ID number (sub $i) [press 'Enter' to skip]: " read subid[$i] if [ ! -z "$(echo ${subid[$i]} | grep '[a-zA-Z]')" ]; then echo green "-> You have to specify the Subtitle ID number, not the language code!" green "-> Skipping subtitle $i" echo else if [ ! -z "${subid[$i]}" ]; then subtitle[$i]="-sid ${subid[$i]}" vobsubout[$i]="-vobsubout \"${OUTPUT%.*}_sub$i\" -vobsuboutindex $(($i-1))" IDXFILE[$i]="${OUTPUT%.*}_sub$i.idx" SUBFILE[$i]="${OUTPUT%.*}_sub$i.sub" fi fi done ;; 3) for i in {1..3}; do printf "Provide the subtitle file (sub $i) [press 'Enter' to skip]: " read -e extsub[$i] if [ ! -z "${extsub[$i]}" ]; then if [ ! -f "${extsub[$i]}" ]; then echo green "-> No such file: '${extsub[$i]}'" green "-> Skipping subtitle $i" echo else EXTSUB[$i]="${extsub[$i]}" fi fi done ;; 4) nosub="-nosub" ;; *) error "-> Unknown subtitle method option: '$submethod'" error "-> Exiting in function: video_subtitles_func()" rmtemp ;; esac ;; esac else nosub="-nosub" fi } # Video cropping video_crop_func() { case "$source" in dir) echo error "-> Cropping in directory batch encoding mode is not" error " recommended unless you know what you're doing!" ;; esac printf "Specify the Crop rounding value [4/8/16 - default is 16]: " read cropround if [ -z "$cropround" ]; then cropdetect="cropdetect=24:16" else cropdetect="cropdetect=24:$cropround" fi echo green "-> Detecting crop values with 'cropdetect'..." $MPLAYER "$sourcetype" $device $vid $MPLAYEROPTS -identify -vo null -ao null -frames 1 -nocache 2>/dev/null > "$TEMPDIR/cropdetect" VLENGTH=$(grep '^ID_LENGTH' "$TEMPDIR/cropdetect" | cut -f '2' -d '=' | cut -f '1' -d '.') case "$source" in dvd|vcd) if [ ! -z "$($MPLAYER -vc help 2>/dev/null | grep 'libmpeg2')" ]; then MPEGVC="-vc mpeg12" fi CROPOPTS="-frames 30 -sstep $(($VLENGTH/30)) $MPEGVC" ;; *) CROPOPTS="-frames 500 -ss $(($VLENGTH/2))" ;; esac GETCROP=$($MPLAYER "$sourcetype" $device $vid $MPLAYEROPTS -vf $cropdetect -nosound -vo null $CROPOPTS -nocache 2>/dev/null | tr '\r' '\n' | grep "crop=" | tail -n 1 | awk '{print $9}' | sed 's/crop=//g; s/).//g') rm -f "$TEMPDIR/cropdetect" if [ ! -z "$GETCROP" ]; then green "-> Found crop values: $GETCROP" else green "-> Failed to get the crop values!" green "-> You have to specify them yourself!" green "-> The format is as follows: width:height:x:y" GETCROP="??" fi echo CROPDETERMINED="n" while [ "$CROPDETERMINED" != "y" ]; do if [ -z "$cropvalues" ]; then printf "Specify the crop values [default is $GETCROP]: " else printf "Specify the crop values [last try: "$cropvalues"]: " fi read cropvalues if [ -z "$cropvalues" -a "$GETCROP" = "??" ]; then cropfilter= else if [ -z "$cropvalues" ]; then cropfilter="crop=$GETCROP," crop_preview="$GETCROP" else cropfilter="crop=$cropvalues," crop_preview="$cropvalues" fi precrop=$(get_selection_func "Preview the crop values for 15 seconds? [y/N]: ") if [ "$precrop" = "y" ]; then printf "Specify the start position in hour:min:sec [default is 0:02:00]: " read timepos if [ -z "$timepos" ]; then startpos="0:02:00" else startpos="$timepos" fi $MPLAYER "$sourcetype" $device $vid $MPLAYEROPTS -vf rectangle=$crop_preview -nocache -nosound -ss $startpos -endpos 15 >/dev/null 2>&1 fi fi CROPDETERMINED=$(get_selection_func "Are you satisfied with the crop area? [y/N]: ") done } calcbits() { echo "scale=3; $1" | $BC -l | sed 's@^\.@0\.@' } # Bits per pixel calculation # # $videobitrate * 1000 # $bpp = ----------------------- # $width * $height * $fps # bits_per_pixel_func() { if [ "$vres" = "$GETRES" -o -z "$vres" ]; then WIDTH=$(echo $GETRES | tr '[:alpha:]' ' ' | awk '{print $1}') HEIGHT=$(echo $GETRES | tr '[:alpha:]' ' ' | awk '{print $2}') else WIDTH=$(echo $vres | tr '[:alpha:]' ' ' | awk '{print $1}') HEIGHT=$(echo $vres | tr '[:alpha:]' ' ' | awk '{print $2}') fi if [ -z "$ofps" ]; then VIDFPS="$GETFPS" else VIDFPS="$(echo $ofps | awk '{print $2}')" fi if [ "$calcvidbit" = "y" -o "$calcvidbit" = "Y" ]; then BPP=$(calcbits "$VBITRATE*1000/($WIDTH*$HEIGHT*$VIDFPS)") else echo "" green "-> Bits Per Pixel value: $(calcbits "$(echo $bitrate | awk -F= '{print $2}')*1000/($WIDTH*$HEIGHT*$VIDFPS)") bpp" fi } # Bits per block calculation # # MPEG type compression breaks each # frame into many smaller 16x16 blocks # and assigns a quantizer to each one # of them. The below formula can be # used to calculate how many bits # each one of these blocks gets # # $videobitrate * 1000 # $bpb = --------------------------------------------------- # $(($fps * $(($(($width * $height))/$((16 * 16)))))) # bits_per_block_func() { if [ "$vres" = "$GETRES" -o -z "$vres" ]; then WIDTH=$(echo $GETRES | tr '[:alpha:]' ' ' | awk '{print $1}') HEIGHT=$(echo $GETRES | tr '[:alpha:]' ' ' | awk '{print $2}') else WIDTH=$(echo $vres | tr '[:alpha:]' ' ' | awk '{print $1}') HEIGHT=$(echo $vres | tr '[:alpha:]' ' ' | awk '{print $2}') fi if [ -z "$ofps" ]; then VIDFPS="$GETFPS" else VIDFPS="$(echo $ofps | awk '{print $2}')" fi if [ "$calcvidbit" = "y" -o "$calcvidbit" = "Y" ]; then BPB=$(calcbits "$VBITRATE*1000/($VIDFPS*($WIDTH*$HEIGHT)/(16*16))") else green "-> Bits Per Block value: $(calcbits "$(echo $bitrate | awk -F= '{print $2}')*1000/($VIDFPS*($WIDTH*$HEIGHT)/(16*16))") bpb" fi } set_output_filename_func() { case "$source" in file|vcd) printf "Provide a name for the Output File [default is H264-$$]: " read -e outfile if [ -z "$outfile" ]; then OUTPUT="H264-$$" else OUTPUT="$outfile" fi ;; dvd) green "-> Scanning for DVD title name..." GET_TITLE=$($LSDVD $(echo $device | awk '{print $2}') 2>/dev/null | grep '^Disc Title:' | sed -e 's|Disc Title: ||' -e 's|_| |g') if [ ! -z "$GET_TITLE" ]; then SET_NAME="$GET_TITLE" else SET_NAME="H264-$$" fi echo printf "Provide a name for the Output File [default is $SET_NAME]: " read -e outfile if [ -z "$outfile" ]; then OUTPUT="$SET_NAME" else OUTPUT="$outfile" fi ;; esac test_write_func() { TESTFILE="$DEFPATH/.testfile$$" touch "$TESTFILE" 2>/dev/null if [ $? != 0 ]; then echo error "-> Output directory '$DEFPATH' is not writable!" error "-> Exiting in sub-function: test_write_func()" echo rmtemp else rm -f "$TESTFILE" 2>/dev/null fi } if [ ! -z "$DEFOUTPUT" ]; then if [ ! -z "$(echo "$OUTPUT" | grep '^/')" ]; then if [ ! -d "$(dirname "$OUTPUT")" ]; then mkdir -p "$(dirname "$OUTPUT")" 2>/dev/null if [ $? != 0 ]; then echo error "-> Could not create output dir '$(dirname "$OUTPUT")'" error "-> Maybe a permissions problem?" error "-> Exiting in function: set_output_filename_func()" echo rmtemp else DEFPATH="$(dirname "$OUTPUT")" fi else DEFPATH="$(dirname "$OUTPUT")" test_write_func fi else if [ ! -d "$DEFOUTPUT" ]; then mkdir -p "$DEFOUTPUT" 2>/dev/null if [ $? != 0 ]; then echo error "-> Could not create default output dir '$DEFOUTPUT'" error "-> Defaulting to '$HOME'" echo DEFPATH="$HOME" else DEFPATH="$DEFOUTPUT" fi else DEFPATH="$DEFOUTPUT" test_write_func fi fi else if [ ! -z "$(echo "$OUTPUT" | grep '^/')" ]; then if [ ! -d "$(dirname "$OUTPUT")" ]; then mkdir -p "$(dirname "$OUTPUT")" 2>/dev/null if [ $? != 0 ]; then echo error "-> Could not create output dir '$(dirname "$OUTPUT")'" error "-> Defaulting to '$HOME'" echo DEFPATH="$HOME" else DEFPATH="$(dirname "$OUTPUT")" fi else DEFPATH="$(dirname "$OUTPUT")" test_write_func fi else DEFPATH="$HOME" fi fi OUTPUT="$DEFPATH/$(basename "${OUTPUT%.*}.avi")" } backup_file_func() { case "$1" in files|chaps) case "$1" in files) EXTFILE="$OUTPUT" ;; chaps) EXTFILE="$CHAPTERSFILE" ;; esac if [ -e "$EXTFILE" ]; then counter=1 while [ -e "$EXTFILE.$counter.old" ]; do counter=$(($counter+1)) done BKOUT="$EXTFILE.$counter.old" echo green "-> Renaming existing file to '$(basename "$BKOUT")'" case "$1" in files) case "$source" in file|vcd|dir) echo ;; esac ;; chaps) echo ;; esac mv -f "$EXTFILE" "$BKOUT" fi ;; subs) if [ ! -z "${vobsubout[*]}" ]; then for i in {1..3}; do if [ -e "${IDXFILE[$i]}" -o -e "${SUBFILE[$i]}" ]; then echo break fi done fi counter=1 for i in {1..3}; do while [ -e "${IDXFILE[$i]}.$counter.old" -o -e "${SUBFILE[$i]}.$counter.old" ]; do counter=$(($counter+1)) done if [ -e "${IDXFILE[$i]}" ]; then green "-> Renaming existing file to '$(basename "${IDXFILE[$i]}.$counter.old")'" mv -f "${IDXFILE[$i]}" "${IDXFILE[$i]}.$counter.old" fi if [ -e "${SUBFILE[$i]}" ]; then green "-> Renaming existing file to '$(basename "${SUBFILE[$i]}.$counter.old")'" mv -f "${SUBFILE[$i]}" "${SUBFILE[$i]}.$counter.old" fi done ;; esac } check_diskspace_func() { HDOUT="$(df -m "$(dirname "$OUTPUT")" | tail -n 1 | awk '{print $4}')" HDCONF="$(df -m "$TEMPDIR" | tail -n 1 | awk '{print $4}')" if [ $HDOUT -le 4096 -o $HDCONF -le 4096 ]; then echo "" echo "Note that you are running out of disk space in" echo "the destination output directory and/or in the" echo "configuration directory of h264enc!" echo "" echo "This could be a problem if you want to convert" echo "the final encode to MKV, OGM, TS or to the MP4" echo "container. It is recommended to free up some disk" echo "space or provide a different destination output" echo "directory before continuing with the encoding" echo "process if you intend to do some of the above" echo "tasks!" echo "" error "Space left over in '$(dirname "$OUTPUT")': $HDOUT MiB" error "Space left over in '$TEMPDIR': $HDCONF MiB" echo "" printf "#### Press 'Enter' to continue, CTRL+C to exit ####" read continue_encoding case "$source" in file|dir) echo ;; esac fi } video_filters_func() { if [ "$vfilters" = "y" ]; then echo brown "+==================================+" brown "| Pre/Postprocessing Video Filters |" brown "+==================================+" echo test "$ALLOW_VID_DEINTERLACE" = "y" && video_deinterlace_func test "$ALLOW_VID_INTERLACE" = "y" && video_interlace_func test "$ALLOW_VID_DEBLOCK" = "y" && video_deblock_func test "$ALLOW_VID_DELOGO" = "y" && video_delogo_func test "$ALLOW_VID_DENOISE" = "y" && video_denoise_func test "$ALLOW_VID_NOISE" = "y" && video_noise_func test "$ALLOW_VID_DEBAND" = "y" && video_deband_func test "$ALLOW_VID_UNSHARP" = "y" && video_unsharp_func test "$ALLOW_VID_BRIGHTNESS" = "y" && video_brightness_func test "$ALLOW_VID_EQUALIZER" = "y" && video_equalizer_func else interlaced=":nointerlaced" fi if [ "$ALLOW_VID_AUTOCROP" = "y" ]; then # Skip autocropping for directory # batch encoding mode case "$source" in file|dvd|vcd) video_crop_func ;; esac else cropping=$(get_selection_func "Would you like to Crop the $type? [y/N]: ") if [ "$cropping" = "y" ]; then video_crop_func fi fi } ########################################################## ############## DVD/VCD/video file settings ############### ########################################################## clear echo "" brown "+=============================================================+" brown "|<<<<<<< h264enc - the interactive shell script ripper >>>>>>>|" brown "|-------------------------------------------------------------|" brown "|<<<<<< version: $version - (C) 2006-2011, Grozdan Nikolov >>>>>>|" brown "+=============================================================+" echo "" echo "" source=$(get_selection_func "Select the Input type [file/dir/dvd/vcd]: ") case "$source" in file) type="Video file" printf "Provide the Input Video File: " read -e infile if [ ! -f "$infile" ]; then error "-> No such file: '$infile'" rmtemp fi set_output_filename_func check_diskspace_func sourcetype="$infile" if [ "$sourcetype" = "$OUTPUT" ]; then error "-> You cannot use the same file name for both the input and output file!" rmtemp fi backup_file_func files # Scan to see if input file has # more than one video stream if [ "$ALLOW_SCAN_MULTIPLE_VIDSTREAMS" = "y" ]; then mvs=$(get_selection_func "Scan for multiple video streams? [y/N]: ") if [ "$mvs" = "y" ]; then echo "" green "-> Scanning for video streams..." $MPLAYER "$sourcetype" $MPLAYEROPTS -identify -vo null -nosound -frames 1 -nocache 2>/dev/null > "$TEMPDIR/videostreams" if [ $(grep '^ID_VIDEO_ID' "$TEMPDIR/videostreams" | wc -l) -lt 2 ]; then vid= green "-> Found only one video stream" green "-> Skipping stream selection" echo "" else echo "" for i in $(grep '^ID_VIDEO_ID' "$TEMPDIR/videostreams"); do echo "$(echo "Video stream: $(echo $i | awk -F= '{print $2}')")" done echo "" VIDSTREAM=$(grep '^ID_VIDEO_ID' "$TEMPDIR/videostreams" | awk -F= '{print $2}') printf "Specify the video stream number for encoding [default is $(echo $VIDSTREAM | awk '{print $1}')]: " read vidstream if [ -z "$vidstream" ]; then vid="-vid 0" else vid="-vid $vidstream" fi fi rm -f "$TEMPDIR/videostreams" fi fi vfilters=$(get_selection_func "Would you like to use Pre/Postprocessing video filters? [y/N]: ") video_filters_func video_subtitles_func ;; dir) type="Video files" printf "Provide one Input Video File from the directory: " read -e infile if [ ! -f "$infile" ]; then error "-> No such file: '$infile'" rmtemp fi sourcetype="$infile" test -d "$DEFOUTPUT" && DEFBATCHDIR="$DEFOUTPUT" || DEFBATCHDIR="$HOME" printf "Where to store the encodings? [default is $DEFBATCHDIR/h264enc_$$]: " read -e outdir if [ -z "$outdir" ]; then OUTPUTDIR="$DEFBATCHDIR/h264enc_$$" if [ ! -d "$OUTPUTDIR" ]; then mkdir -p "$OUTPUTDIR" 2>/dev/null if [ $? != 0 ]; then error "-> Failed to create the output directory!" error "-> Maybe a permissions problem?" rmtemp fi fi else if [ "$(dirname "$sourcetype")" = "$outdir" ]; then error "-> You can't use the input directory as output directory!" rmtemp fi OUTPUTDIR="$outdir" if [ ! -d "$OUTPUTDIR" ]; then mkdir -p "$OUTPUTDIR" 2>/dev/null if [ $? != 0 ]; then error "-> Failed to create the output directory!" error "-> Maybe a permissions problem?" rmtemp fi fi fi OUTPUT="$OUTPUTDIR/\${i%.*}.avi" vfilters=$(get_selection_func "Would you like to use Pre/Postprocessing video filters? [y/N]: ") video_filters_func video_subtitles_func ;; dvd) type="DVD" if [ ! -x "$LSDVD" ]; then error "-> Checking for lsdvd... FAILED!" rmtemp fi check_spaces_func() { if [ ! -z "$(echo "$device" | sed 's/-dvd-device //' | grep ' ')" ]; then error "-> Spaces in file names for devices/ISO/VIDEO_TS not supported!" rmtemp fi } echo "" brown "Input Selection" brown "~~~~~~~~~~~~~~~" echo "0 -> Encode from a DVD disc/drive" echo "1 -> Encode from a DVD ISO image" echo "2 -> Encode from a DVD VIDEO_TS directory" echo "" printf "Select the input [default is 0]: " read dvdsource case "$dvdsource" in 0|"") get_devices_func dvd check_spaces_func ;; 1) printf "Provide the DVD ISO image: " read -e dvdiso if [ -z "$dvdiso" -o ! -e "$dvdiso" ]; then error "-> ISO image not specified or does not exist!" rmtemp else device="-dvd-device $dvdiso" fi check_spaces_func ;; 2) printf "Provide the DVD VIDEO_TS directory: " read -e dvdvt if [ -z "$dvdvt" -o ! -d "$dvdvt" ]; then error "-> Directory not specified or does not exist!" rmtemp else device="-dvd-device $dvdvt" fi check_spaces_func ;; *) error "-> Unknown option: '$dvdsource'" rmtemp ;; esac # Before scanning the DVD with 'lsdvd' it has to be # unlocked or 'lsdvd' will fail to read it, so we # run mplayer here just to unlock it echo "" green "-> Unlocking the DVD disc..." $MPLAYER dvd:// $device $MPLAYEROPTS -nosound -vo null -frames 1 -nocache >/dev/null 2>&1 set_output_filename_func check_diskspace_func backup_file_func files echo "" green "-> Scanning for DVD titles..." $LSDVD $(echo $device | awk '{print $2}') 2>/dev/null > "$TEMPDIR/dvdtitles" ALLTITLES=$(grep '^Title' "$TEMPDIR/dvdtitles" | awk '{print $1,$2,$5,$6,$3,$4}' | sed 's|,| -|g' | cut -f '1' -d '.' | awk '{print $1,$2,$3,$7,$8,$6,$4,$5}') DVDTITLE=$(grep 'Longest' "$TEMPDIR/dvdtitles" | awk '{print $3}' | sed 's/^0//') TOTAL_TITLES=$(grep '^Title' "$TEMPDIR/dvdtitles" | sed 's/,//g' | awk 'END{print $2}' | sed 's/^0//') TITLE_LENGTH=$($LSDVD -t $DVDTITLE $(echo $device | awk '{print $2}') 2>/dev/null | grep "Length" | awk '{print $4}' | cut -f '1' -d '.') rm -f "$TEMPDIR/dvdtitles" echo "" if [ -z "$DVDTITLE" ]; then brown "Disc Title: $GET_TITLE" echo "$ALLTITLES" echo "" green "-> Titles On Disc: $TOTAL_TITLES" green "-> Failed to detect longest DVD title!" green "-> You have to specify it yourself!" DVDTITLE="??" else brown "Disc Title: $GET_TITLE" echo "$ALLTITLES" echo "" green "-> Titles On Disc: $TOTAL_TITLES" green "-> Longest Title: $DVDTITLE - Title Length: $TITLE_LENGTH" fi echo "" printf "Specify the DVD title for encoding [default/longest is $DVDTITLE]: " read title if [ -z "$title" -a "$DVDTITLE" = "??" ]; then error "-> You have to specify the DVD title for encoding!" rmtemp fi if [ -z "$title" ]; then sourcetype="dvd://$DVDTITLE" else sourcetype="dvd://$title" fi angle=$(get_selection_func "Would you like to encode from a different DVD angle? [y/N]: ") if [ "$angle" = "y" ]; then echo "" green "-> Scanning for angles in title $(echo $sourcetype | sed 's|dvd://||')..." ANGLES=$($MPLAYER $sourcetype $device $MPLAYEROPTS -nosound -vo null -frames 1 -nocache 2>/dev/null | grep "angles") if [ ! -z "$ANGLES" ]; then green "-> $ANGLES" else green "-> Could not detect any angles in this DVD title!" fi echo "" printf "From which angle to encode the DVD? [default is 1]: " read dvd_angle if [ ! -z "$dvd_angle" ]; then dvdangle="-dvdangle $dvd_angle" fi fi chap=$(get_selection_func "Would you like to encode only Specific Chapters? [y/N]: ") if [ "$chap" = "y" ]; then echo "" green "-> Scanning for chapters in title $(echo $sourcetype | sed 's|dvd://||')..." $MPLAYER $sourcetype $device $MPLAYEROPTS -nosound -vo null -frames 1 -identify -nocache 2>/dev/null > "$TEMPDIR/chapters" echo "" brown "Available Chapters On Disc" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~" if [ ! -z "$(grep '^CHAPTERS' "$TEMPDIR/chapters")" ]; then grep '^CHAPTERS' "$TEMPDIR/chapters" | sed -e 's/CHAPTERS: //' -e 's/,/ /g' > "$TEMPDIR/getchaps" for i in $(cat "$TEMPDIR/getchaps"); do echo "Chapter: $i - Start position: " >> "$TEMPDIR/lschaps" done nl "$TEMPDIR/lschaps" | awk '{print $2,$1,$4,$5,$6,$3}' else green "-> Could not detect any chapters in this DVD title!" fi rm -f "$TEMPDIR/*" echo echo "Example: to encode only chapter 2, type: 2-2" echo "Example: to encode from chapter 5 until the end of the DVD, type: 5" echo "Example: to encode from chapter 1 until the end of 3, type: 1-3" echo printf "Which chapter(s) to encode from this DVD title? [press 'Enter' to skip]: " read chapenc if [ ! -z "$chapenc" ]; then chapters="-chapter $chapenc" # Overwirte output name and # append chapter info to it if [ ! -z "$(echo $chapenc | grep '-')" ]; then CHAP1="$(echo $chapenc | awk -F- '{print $1}')" CHAP2="$(echo $chapenc | awk -F- '{print $2}')" if [ "$CHAP1" -eq "$CHAP2" ]; then OUTPUT="${OUTPUT%.*} - chapter $CHAP1.avi" else OUTPUT="${OUTPUT%.*} - chapter $chapenc.avi" fi else OUTPUT="${OUTPUT%.*} - chapter $chapenc.avi" fi backup_file_func files fi fi # Export chapters information to a file. # This can be used to import chapters # info when muxing into MKV/MP4/OGM. It # requires ogmtools' 'dvdxchap'. if [ -x "$DVDXCHAP" ]; then chapexp=$(get_selection_func "Export DVD chapters information to a file on disk? [y/N]: ") if [ "$chapexp" = "y" ]; then CHAPTERSFILE="${OUTPUT%.*}.chaps" backup_file_func chaps $DVDXCHAP -t $(echo $sourcetype | sed 's|dvd://||') $(echo $device | awk '{print $2}') 2>/dev/null | grep '^CHAPTER' > "$CHAPTERSFILE" fi fi vfilters=$(get_selection_func "Would you like to use Pre/Postprocessing video filters? [y/N]: ") video_filters_func video_subtitles_func backup_file_func subs ;; vcd) type="VCD" get_devices_func vcd echo green "-> Scanning for VCD tracks..." $MPLAYER vcd:// $device $MPLAYEROPTS -identify -vo null -frames 1 -ao null -nocache 2>/dev/null > "$TEMPDIR/vcdtracks" VCDTRACKS=$(grep '^ID_VCD_TRACK_.*' "$TEMPDIR/vcdtracks") rm -f "$TEMPDIR/vcdtracks" if [ ! -z "$VCDTRACKS" ]; then echo for i in $VCDTRACKS; do echo "Track: $(echo $i | sed -e 's|[A-Z]||g' -e 's|_||g' -e 's|=| - Length: |g')" done else green "-> Could not detect any VCD tracks!" fi echo printf "Specify the VCD track for encoding [default is 2]: " read vcdtrack if [ -z "$vcdtrack" ]; then sourcetype="vcd://2" else sourcetype="vcd://$vcdtrack" fi set_output_filename_func check_diskspace_func backup_file_func files vfilters=$(get_selection_func "Would you like to use Pre/Postprocessing video filters? [y/N]: ") video_filters_func video_subtitles_func ;; *|"") error "-> You have to specify the input type (file/dir/dvd/vcd)" rmtemp ;; esac # Mutually exclusive with bobbing and interlacing # as FPS is already detected and set in the functions if [ -z "$intfilter" -a -z "$deintfps" ]; then detect_fps_func() { case "$1" in other) scanopts="-vo null -ao null -identify -frames 1 -nocache" ;; ntsc) scanopts="-vo null -nosound -identify -nocache -benchmark" ;; esac $MPLAYER "$sourcetype" $MPLAYEROPTS $device $vid $scanopts 2>/dev/null > "$TEMPDIR/fps" GETFPS=$(grep '^ID_VIDEO_FPS' "$TEMPDIR/fps" | tail -n 1 | awk -F= '{print $2}') GETLENGTH=$(grep '^ID_LENGTH' "$TEMPDIR/fps" | awk -F= '{print $2}') } echo case "$source" in dvd) # Try to detect NTSC type. Currently a fast # dumb solution and one that also can't # distinguish between true hard telecine # and interlacing but it works for soft # telecine and mixed progressive/telecine # content which is more common detect_fps_func other case "$GETFPS" in 29.970|29.97) green "-> Detecting NTSC type and FPS value" green "-> Scanning can take a while..." detect_fps_func ntsc TC=$(grep 'demux_mpg' "$TEMPDIR/fps" | wc -l) case "$TC" in 0) GETFPS="29.970" green "-> Detected 0 'demux_mpg' frame rate switchings" green "-> $type appears to be Progressive or Hard Telecined (may need IVTC!)" ;; 1) GETFPS="23.976" green "-> Detected 1 'demux_mpg' frame rate switching" green "-> $type appears to be Soft Telecined (needs FPS force to 23.976!)" ;; *) GETFPS="23.976" green "-> Detected $TC 'demux_mpg' frame rate switchings" green "-> $type appears to be Mixed Progressive and Telecine (needs IVTC!)" ;; esac ;; *) green "-> Detecting FPS value..." green "-> Detected $GETFPS FPS" ;; esac ;; *) green "-> Detecting FPS value..." detect_fps_func other green "-> Detected $GETFPS FPS" ;; esac green "-> Number of frames: $(echo "scale=0; $GETLENGTH * $GETFPS" | $BC -l | awk -F. '{print $1}')" rm -f "$TEMPDIR/fps" echo outfps=$(get_selection_func "Would you like to set/force the Output Frame Rate (FPS)? [y/N]: ") if [ "$outfps" = "y" ]; then setfps="yes" echo "" brown "Frame Rate Selection" brown "~~~~~~~~~~~~~~~~~~~~" echo "0 --> 15.984 fps (Silent Film)" echo "1 --> 17.982 fps (Silent Film)" echo "2 --> 24 fps (Film)" echo "3 --> 25 fps (PAL/SECAM Film/Video)" echo "4 --> 50 fps (PAL/SECAM Double)" echo "5 --> 100 fps (PAL/SECAM Quad)" echo "6 --> 23.976 fps (NTSC Film)" echo "7 --> 29.970 fps (NTSC Video)" echo "8 --> 30 fps (NTSC Video)" echo "9 --> 59.940 fps (NTSC Double)" echo "10 -> 60 fps (NTSC Double)" echo "11 -> 119.880 fps (NTSC Quad)" echo "12 -> User Defined" echo "13 -> Skip frame rate settings" echo "" printf "Select a Frame Rate format [default is 3]: " read frf case "$frf" in 0) ofps="-ofps 16000/1001" ;; 1) ofps="-ofps 18000/1001" ;; 2) ofps="-ofps 24" ;; 3|"") ofps="-ofps 25" ;; 4) ofps="-ofps 50" ;; 5) ofps="-ofps 100" ;; 6) ofps="-ofps 24000/1001" ;; 7) ofps="-ofps 30000/1001" ;; 8) ofps="-ofps 30" ;; 9) ofps="-ofps 60000/1001" ;; 10) ofps="-ofps 60" ;; 11) ofps="-ofps 120000/1001" ;; 12) printf "Specify the Frame Rate value [default is 25]: " read frame_rate if [ ! -z "$(echo $frame_rate | grep '\.')" ]; then error "-> Float is not allowed. Use fractions instead!" error "-> Example: 30000/1001" rmtemp fi if [ -z "$frame_rate" ]; then ofps="-ofps 25" else if [ "$(echo $frame_rate | awk -F/ '{print $2}')" != "1001" ]; then error "-> You have to use 1001 as last value of the fraction!" error "-> Example: 30000/1001" rmtemp fi ofps="-ofps $frame_rate" fi ;; 13) false ;; *) error "-> Unknown frame rate option: '$frf'" rmtemp ;; esac else setfps="no" fi else GETFPS="25" setfps="yes" fi # Frame rate conversion. Mutually # exclusive with frame doubling # deinterlacers and interlacing # filters if [ "$ALLOW_VID_FPS_CONVERSION" = "y" ]; then case "$GETFPS" in 25.000|25.00|29.970|29.97|50.000|50.00|100.000|100.00|59.940|59.94|60.000|60.00|119.880|119.88|"") if [ "$setfps" = "no" -a -z "$deintfps" -a -z "$intfps" -a "$interlaced" = ":nointerlaced" ]; then fpsconv=$(get_selection_func "Would you like to do Frame Rate Conversion? [y/N]: ") if [ "$fpsconv" = "y" ]; then quiet="2>/dev/null" echo "" brown "Frame Rate Conversion" brown "~~~~~~~~~~~~~~~~~~~~~" echo "0 -> 50 fps ------> 25 fps (PAL/SECAM Double -> PAL/SECAM)" echo "1 -> 100 fps -----> 50 fps (PAL/SECAM Quad -> PAL/SECAM Double)" echo "2 -> 29.970 fps --> 23.976 fps (NTSC Video -> NTSC Film)" echo "3 -> 59.940 fps --> 23.976 fps (NTSC Double -> NTSC Film)" echo "4 -> 59.940 fps --> 29.970 fps (NTSC Double -> NTSC Video)" echo "5 -> 60 fps ------> 30 fps (NTSC Double -> NTSC Video)" echo "6 -> 119.880 fps -> 59.940 fps (NTSC Quad -> NTSC Double)" echo "7 -> 25 fps ------> 50 fps (PAL/SECAM -> PAL/SECAM Double)" echo "8 -> 29.970 fps --> 59.940 fps (NTSC Video -> NTSC Double)" echo "9 -> Skip frame rate conversion" echo "" printf "Select the frame rate conversion [no default!]: " read frc frc_func() { echo "" green "-> Setting input/output frame rate to $(echo "scale=3; $(echo $fps | awk '{print $2}')" | $BC -l)/$(echo "scale=3; $(echo $ofps | awk '{print $2}')" | $BC -l) FPS" green "-> Using '$(echo $fpsfilter | sed 's/,$//')' video filter(s)" } case "$frc" in 0|1) echo "" brown "FPS Conversion Filters" brown "~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Framestep" echo "1 -> Filmdint" echo "" printf "Which filter to use? [default is 1]: " read fpscf case "$frc" in 0) case "$fpscf" in 0) fpsfilter="framestep=2," ;; 1|"") fpsfilter="filmdint=fast=0/io=50:25/dint_thres=256," ;; *) error "-> Unknown filters option: '$fpscf'"; rmtemp ;; esac fps="-fps 50" ofps="-ofps 25" frc_func ;; 1) case "$fpscf" in 0) fpsfilter="framestep=2," ;; 1|"") fpsfilter="filmdint=fast=0/io=100:50/dint_thres=256," ;; *) error "-> Unknown filters option: '$fpscf'"; rmtemp ;; esac fps="-fps 100" ofps="-ofps 50" frc_func ;; esac ;; 2) fpsfilter="filmdint=fast=0/io=30:24/dint_thres=256," fps="-fps 30000/1001" ofps="-ofps 24000/1001" frc_func ;; 3) echo "" brown "FPS Conversion Filters" brown "~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Framestep & Filmdint" echo "1 -> Filmdint" echo "" printf "Which filter(s) to use? [default is 1]: " read fpscf case "$fpscf" in 0) fpsfilter="framestep=2,filmdint=fast=0/io=30:24/dint_thres=256," ;; 1|"") fpsfilter="filmdint=fast=0/io=60:24/dint_thres=256," ;; *) error "-> Unknown filters option: '$fpscf'"; rmtemp ;; esac fps="-fps 60000/1001" ofps="-ofps 24000/1001" frc_func ;; 4|5|6) echo "" brown "FPS Conversion Filters" brown "~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Framestep" echo "1 -> Filmdint" echo "" printf "Which filter to use? [default is 1]: " read fpscf case "$frc" in 4) case "$fpscf" in 0) fpsfilter="framestep=2," ;; 1|"") fpsfilter="filmdint=fast=0/io=60:30/dint_thres=256," ;; *) error "-> Unknown filters option: '$fpscf'"; rmtemp ;; esac fps="-fps 60000/1001" ofps="-ofps 30000/1001" frc_func ;; 5) case "$fpscf" in 0) fpsfilter="framestep=2," ;; 1|"") fpsfilter="filmdint=fast=0/io=60:30/dint_thres=256," ;; *) error "-> Unknown filters option: '$fpscf'"; rmtemp ;; esac fps="-fps 60" ofps="-ofps 30" frc_func ;; 6) case "$fpscf" in 0) fpsfilter="framestep=2," ;; 1|"") fpsfilter="filmdint=fast=0/io=120:60/dint_thres=256," ;; *) error "-> Unknown filters option: '$fpscf'"; rmtemp ;; esac fps="-fps 120000/1001" ofps="-ofps 60000/1001" frc_func ;; esac ;; 7) fps="-fps 25" ofps="-ofps 50" echo "" green "-> Setting input/output frame rate to 25/50 FPS" ;; 8) fps="-fps 30000/1001" ofps="-ofps 60000/1001" echo "" green "-> Setting input/output frame rate to 29.970/59.940 FPS" ;; 9) false ;; *|"") error "-> Unknown option or frame rate conversion not selected!" rmtemp ;; esac fi fi ;; esac fi # Pulldown reversal/inverse telecine/telecine # 3:2 pulldown filters. Mutually exclusive with # (frame doubling) deinterlacing filters and # FPS conversion case "$GETFPS" in 23.976|29.970|23.97|29.97|59.94|59.940|"") if [ "$setfps" = "no" -a "$interlaced" = ":nointerlaced" -a -z "$deintfilter" -a -z "$frc" ]; then tpp=$(get_selection_func "Apply a Telecine/3:2 Pulldown/IVTC/Pullup process? [y/N]: ") if [ "$tpp" = "y" ]; then echo "" brown "Telecine/3:2 Pulldown/IVTC/Pullup" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Inverse Telecine: 29.970 -> 23.976 fps" echo "1 -> Inverse Telecine: 59.940 -> 23.976 fps (filmdint/framestep)" echo "2 -> Inverse Telecine: 59.940 -> 23.976 fps (tinterlace/filmdint)" echo "3 -> Hard Telecine: 23.976 -> 29.970 fps" echo "4 -> Skip the Telecine/Pullup process" echo "" printf "Which process to use? [default is 0]: " read telproc case "$telproc" in 0|"") echo "" brown "Available IVTC Filters" brown "~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Pullup (4th generation IVTC filter)" echo "1 -> Filmdint (3rd generation IVTC filter)" echo "2 -> IVTC (2nd generation IVTC filter)" echo "3 -> DETC (1st generation IVTC filter)" echo "" printf "Which Inverse Telecine/Pullup filter to use? [default is 0]: " read ivtc case "$ivtc" in 0|"") ivtcfilter="pullup," ;; 1) ivtcfilter="filmdint=fast=0," ;; 2) ivtcfilter="ivtc=1," ;; 3) echo "" brown "DETC Frame Dropping Modes" brown "~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Always drop a frame if there has been" echo " no drops or telecine merges in past" echo " 5 frames. (detc=dr=1)" echo "" echo "1 -> Always maintain exact 5:4 input to" echo " output frame ratio. (detc=dr=2)" echo "" printf "Select a DETC frame dropping mode [default is 0]: " read detcmode case "$detcmode" in 0|""|*) ivtcfilter="detc=dr=1," ;; 1) ivtcfilter="detc=dr=2," ;; esac ;; *) error "-> Unknown IVTC option: '$ivtc'" rmtemp ;; esac echo "" green "-> Setting input/output frame rate to 29.970 / 23.976 FPS" green "-> Using '$(echo $ivtcfilter | sed 's/,$//')' video filter(s)" fps="-fps 30000/1001" ofps="-ofps 24000/1001" ;; 1) fps="-fps 60000/1001" ofps="-ofps 24000/1001" ivtcfilter="filmdint=fast=0,framestep=2," echo green "-> Setting input/output frame rate to 59.940 / 23.976 FPS" green "-> Using '$(echo $ivtcfilter | sed 's/,$//')' video filter(s)" ;; 2) fps="-fps 60000/1001" ofps="-ofps 24000/1001" ivtcfilter="tinterlace=4,filmdint=fast=0," echo green "-> Setting input/output frame rate to 59.940 / 23.976 FPS" green "-> Using '$(echo $ivtcfilter | sed 's/,$//')' video filter(s)" ;; 3) # Both fps and ofps *must* be # 30000/1001 or we will lose # A/V sync due to limitations # in the filter layer of MEncoder fps="-fps 30000/1001" ofps="-ofps 30000/1001" telecinefilter=",telecine" interlaced=":interlaced:pic_struct" echo "" green "-> Setting input/output frame rate to 29.970 FPS" green "-> Using '$(echo $telecinefilter | sed 's/^,//')' video filter(s)" ;; 4) false ;; *) error "-> Unknown IVTC/Pulldown option: '$telproc'" rmtemp ;; esac fi fi ;; esac # Overwrite input/output frame rate if the # user has chosen to interlace his progressive # content during the encoding process or if # the user is deinterlacing it with a deinterlace # filter which doubles the output frame rate. # Only one at a time of the below conditionals # can be true, the appropriate functions take # care of that. if [ ! -z "$intfilter" ]; then fps="-fps $intfps" ofps="-ofps $intofps" fi if [ ! -z "$deintfps" ]; then fps="-fps $deintfps" ofps="-ofps $deintofps" fi # Valid resolutions for # portable devices device_resolution_info() { case "$1" in fl|flhq) green "-> Valid Flash Player resolutions: unrestricted, up to 1080p (1920x1080)" ;; ag1|ag1hq) green "-> Valid Android G1 resolutions: up to 480x368" ;; ipc|ipchq) green "-> Valid iPod Classic resolutions: 320x240" ;; ip|iphq) green "-> Valid iPod resolutions: 320x240|480x320|640x480" ;; iph|iphhq) green "-> Valid iPhone resolutions: 320x240|640x480" ;; atv|atvhq) green "-> Valid AppleTV resolutions: unrestricted, up to 720p (1280x720)" ;; ar|arhq|ar5|ar5hq) green "-> Valid Archos 605/5 resolutions: up to 720x576" ;; bb|bbhq) green "-> Valid Blackberry 9000 resolutions: 320x240|480x320|640x480" ;; nks60|nks60hq) green "-> Valid Nokia S60 resolutions: 320x240|352x416" ;; psp|psphq) green "-> Valid Sony PSP resolutions: 320x240|368x208|352x480|480x272|720x480" ;; ps3|ps3hq) green "-> Valid Sony PS3 resolutions: unrestricted, up to 1080p (1920x1080)" ;; mz|mzhq) green "-> Valid MS Zune resolutions: 320x240|720x480|720x576" ;; mx|mxhq) green "-> Valid XBOX 360 resolutions: unrestricted, up to 1080p (1920x1080)" ;; bd40|bdhq40|bd41|bdhq41) green "-> Valid Blu-ray resolutions: 720i/p (1280x720) and 1080i/p (1920x1080)" ;; avchd|avchdhq) green "-> Valid AVCHD resolutions: 1920x1080, 1440x1080, 1280x720, 720x480, 720x576" ;; esac } # Get resolution from the source and ask # user if he wants to keep it. If cropping # was used, then default resolution value # will be that of the visible area left # over after the cropping. If no cropping # was used, then default resolution value # will be the original one from the source get_resolution_func() { $MPLAYER "$sourcetype" $device $vid $MPLAYEROPTS -identify -vo null -nosound -frames 1 -nocache 2>/dev/null > "$TEMPDIR/resolution" RATIO=$(grep '^ID_VIDEO_ASPECT' "$TEMPDIR/resolution" | tail -n 1 | awk -F= '{print $2}') } ratio_and_pixels_func() { SAR=$(echo "scale=4; $(echo $GETRES | sed 's|x|/|')" | $BC -l | sed 's|^\.|0\.|') PAR=$(echo "scale=4; $RATIO/$SAR" | $BC -l | sed 's|^\.|0\.|') PIXELS=$(($(echo $GETRES | sed 's|x|*|'))) echo green "-> Detected Aspect Ratio (AR): $RATIO:1" green "-> Storage Aspect Ratio (SAR): $SAR:1" green "-> Pixel Aspect Ratio (PAR): $PAR:1" green "-> Total pixels: $PIXELS" } echo if [ ! -z "$cropfilter" ]; then restype="Cropped" green "-> Detecting cropped resolution..." get_resolution_func GETRES=$(echo $cropfilter | sed 's|crop=||; s|,||; s|:|x|' | awk -F: '{print $1}') else restype="Original" green "-> Detecting original resolution..." get_resolution_func GETRES=$(grep '^VIDEO:' "$TEMPDIR/resolution" | tail -n 1 | awk '{print $3}' | sed 's|,$||') fi if [ ! -z "$GETRES" ]; then green "-> $restype resolution: $GETRES" device_resolution_info $3 ratio_and_pixels_func else error "-> Failed to detect the $restype resolution!" error "-> You have to provide it yourself!" device_resolution_info $3 GETRES="??" fi rm -f "$TEMPDIR/resolution" echo printf "Specify the desired Resolution [default is $GETRES]: " read vres if [ -z "$vres" -a "$GETRES" = "??" ]; then error "-> You have to specify the resolution!" rmtemp fi case "$vres" in $GETRES|"") if [ ! -z "$ilpack" ]; then scale="${ilpack}scale=::1" fi ;; *) scale="${ilpack}scale=$(echo $vres | tr '[:alpha:]' ':')" # Interlace parameters for the scaler if [ "$interlaced" = ":tff:pic_struct" -o "$interlaced" = ":bff:pic_struct" -a -z "$intfilter" -a -z "$telecinefilter" ]; then isws=":1" else isws=":0" fi echo "" brown "Available Software Scalers" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 --> Fast Bilinear" echo "1 --> Bilinear" echo "2 --> Bicubic" echo "3 --> Experimental" echo "4 --> Nearest Neighbor/Point" echo "5 --> Area Averaging" echo "6 --> Luma Bicubic/Chroma Bilinear" echo "7 --> Gaussian" echo "8 --> Sinc" echo "9 --> Lanczos" echo "10 -> Natural Bicubic Spline" echo "" # Check if width & height are divisible # by 16 and if not display a warning WMOD16=$(echo "scale=3; $(echo $scale | sed "s|${ilpack}scale=||" | awk -F: '{print $1}')/16" | $BC -l | awk -F. '{print $2}') HMOD16=$(echo "scale=3; $(echo $scale | sed "s|${ilpack}scale=||" | awk -F: '{print $2}')/16" | $BC -l | awk -F. '{print $2}') if [ "$WMOD16" != "000" -o "$HMOD16" != "000" ]; then error "-> Warning: width and/or height not divisible by 16!" error "-> Compression will suffer a bit!" echo "" fi GETSAR=$(echo "scale=4; $(echo $scale | sed "s|${ilpack}scale=||; s|:|/|")" | $BC -l | sed 's|^\.|0\.|') green "-> Storage Aspect Ratio (SAR): $GETSAR:1" green "-> Pixel Aspect Ratio (PAR): $(echo "scale=4; $RATIO/$GETSAR" | $BC -l | sed 's|^\.|0\.|'):1" green "-> Total pixels: $(($(echo $scale | sed "s|${ilpack}scale=||; s|:|*|")))" echo printf "Select a Software Scaler [default is 10]: " read softscale if [ -z "$softscale" ]; then sws="-sws 10" else sws="-sws $softscale" fi # software scaler tuning, only supported # by bicubic, bicubic spline, gaussian # and lanczos scalers if [ "$ALLOW_VID_SCALER_TUNING" = "y" ]; then case $(echo "$sws" | awk '{print $2}') in 2|10) sstune=$(get_selection_func "Would you like to tune the Software Scaler? [y/N]: ") if [ "$sstune" = "y" ]; then echo "" brown "Software Scaler Parameters" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "Here you can tune some parameters of" echo "the Bicubic/Natural Bicubic Spline" echo "software scalers. The first value" echo "represents the amount of blurring while" echo "the second value represents the amount" echo "of ringing. The higher the values, the" echo "more blurring/ringing you'll get." echo "" echo "Below are some frequently used settings" echo "Format is as follows: blurring:ringing" echo "" echo "0 -> 0.00:0.60 -> Default" echo "1 -> 0.00:0.75 -> VirtualDub's \"Precise Bicubic\"" echo "2 -> 0.00:0.50 -> Catmull-Rom Spline" echo "3 -> 0.33:0.33 -> Mitchell-Netravali Spline" echo "4 -> 1.00:0.00 -> Cubic B-Spline" echo "5 -> User defined" echo "6 -> Skip parameter settings" echo "" printf "Select the Software Scaler Parameters [default is 0]: " read ssparam case "$ssparam" in 0|"") swsparam="::0.00:0.60" ;; 1) swsparam="::0.00:0.75" ;; 2) swsparam="::0.00:0.50" ;; 3) swsparam="::0.33:0.33" ;; 4) swsparam="::1.00:0.00" ;; 5) printf "Specify the Software Scaler Parameters [default is 0.00:0.60]: " read ssp if [ -z "$ssp" ]; then swsparam="::0.00:0.60" else swsparam="::$ssp" fi ;; 6) false ;; *) error "-> Unknown software scaler parameters option: '$ssparam'" rmtemp ;; esac fi ;; 7) sstune=$(get_selection_func "Would you like to tune the Software Scaler? [y/N]: ") if [ "$sstune" = "y" ]; then echo "" brown "Software Scaler Parameters" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "Here you can tune the sharpness of the" echo "Gaussian software scaler. Values are" echo "between 0 and 100. The higher the value" echo "the sharper the image will be" echo "" printf "Specify the Software Scaler Parameter [default is 0]: " read ssparam if [ ! -z "$ssparam" ]; then swsparam="::$ssparam" fi fi ;; 9) sstune=$(get_selection_func "Would you like to tune the Software Scaler? [y/N]: ") if [ "$sstune" = "y" ]; then echo "" brown "Software Scaler Parameters" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "Here you can tune the filter length of" echo "the Lanczos software scaler. Values are" echo "between 1 and 10. The higher the value" echo "the sharper the image will be" echo "" printf "Specify the Software Scaler Parameter [default is 1]: " read ssparam if [ ! -z "$ssparam" ]; then swsparam="::$ssparam" fi fi ;; esac fi ;; esac if [ "$ALLOW_VID_DSIZE" = "y" ]; then if [ ! -z "$scale" ]; then printf "Specify the Display size/aspect [press 'Enter' to skip]: " read dsize if [ ! -z "$dsize" ]; then dsizefilter="dsize=$dsize," fi fi fi if [ "$ALLOW_VID_EXPAND" = "y" ]; then printf "Specify the Expand filter parameters [press 'Enter' to skip]: " read exp_param if [ ! -z "$exp_param" ]; then if [ ! -z "$scale" ]; then printf "Place the filter (b) before or (a) after the scale filter? [b/a - default is b]: " read expandpos if [ -z "$expandpos" -o "$expandpos" = "b" ]; then expandfilter_bfr="expand=$exp_param," elif [ "$expandpos" = "a" ]; then expandfilter_afr=",expand=$exp_param" fi else expandfilter_bfr="expand=$exp_param," fi fi fi # Do a colorspace conversion? # Don't ask for this when using # the portable device presets if [ "$ALLOW_VID_COLORSPACE" = "y" ]; then case "$3" in bd40|bdhq40|bd41|bdhq41|avchd|avchdhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|ipc|ipchq|ip|iphq|iph|iphhq|psp|psphq|mz|mzhq) false ;; *) if [ ! -z "$scale" ]; then if [ -z "$fpsfilter" -a -z "$intfilter" -a -z "$telecinefilter" -a "$interlaced" = ":nointerlaced" ]; then video_colorspace_func fi fi ;; esac fi # Aspect ratio if [ "$ALLOW_VID_ASPECT" = "y" ]; then aratio=$(get_selection_func "Would you like to set/force the input Video Aspect Ratio? [y/N]: ") if [ "$aratio" = "y" ]; then echo "" green "-> Detecting video aspect ratio..." if [ ! -z "$RATIO" ]; then green "-> Detected: $RATIO" V_ASPECT="$RATIO" else green "-> Could not detect the video aspect!" V_ASPECT="16:9" fi echo "" printf "Specify the Aspect Ratio [4:3/16:9/1.3333/1.7778... - default is $V_ASPECT]: " read asra if [ -z "$asra" ]; then aspect="-aspect $V_ASPECT" else aspect="-aspect $asra" fi fi fi ############################################## ############## H.264 Settings ################ ############################################## echo "" brown "+=============================+" brown "| H.264 Encoder Configuration |" brown "+=============================+" echo "" # Skip bitrate/quant settings if # user chooses the NLQ preset if [ "$3" = "nlq" ]; then false else case "$1" in -[1-3]p) printf "Specify the desired Video Bitrate in kbps [default is 1000]: " read vbitrate if [ -z "$vbitrate" ]; then bitrate="bitrate=1000" else bitrate="bitrate=$vbitrate" fi # Check to see if we're not overflowing # the maximum allowed bitrate by some # devices case "$3" in bd40) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 20000 ]; then error "-> Blu-ray video bitrate may not exceed 20000 kbps!" rmtemp fi ;; bdhq40) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 25000 ]; then error "-> Blu-ray video bitrate may not exceed 25000 kbps!" rmtemp fi ;; bd41|bdhq41) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 30000 ]; then error "-> Blu-ray video bitrate may not exceed 30000 kbps!" rmtemp fi ;; avchd|avchdhq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 17000 ]; then error "-> AVCHD bitrate may not exceed 17000 kbps!" rmtemp fi ;; ag1|ag1hq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 2000 ]; then error "-> Android G1 video bitrate may not exceed 2000 kbps!" rmtemp fi ;; ipc|ipchq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 768 ]; then echo "" green "-> iPod Classic bitrate may not exceed 768 kbps!" green "-> Falling back to maximum allowed bitrate!" bitrate="bitrate=768" fi ;; ip|iphq|mz|mzhq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 2500 ]; then error "-> iPod/Zune video bitrate may not exceed 2500 kbps!" rmtemp fi ;; iph|iphhq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 1500 ]; then error "-> iPhone video bitrate may not exceed 1500 kbps!" rmtemp fi ;; atv|atvhq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 12000 ]; then error "-> AppleTV video bitrate may not exceed 12000 kbps!" rmtemp fi ;; ar|arhq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 5000 ]; then error "-> Archos 605 video bitrate may not exceed 5000 kbps!" rmtemp fi ;; ar5|ar5hq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 2000 ]; then error "-> Archos 5 video bitrate may not exceed 2000 kbps!" rmtemp fi ;; bb|bbhq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 1500 ]; then error "-> Blackberry 9000 video bitrate may not exceed 1500 kbps!" rmtemp fi ;; nks60|nks60hq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 384 ]; then echo "" green "-> Nokia S60 video bitrate may not exceed 384 kbps!" green "-> Falling back to maximum allowed bitrate!" bitrate="bitrate=384" fi ;; psp|psphq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 4000 ]; then error "-> PSP video bitrate may not exceed 4000 kbps!" rmtemp fi ;; ps3|ps3hq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 20000 ]; then error "-> PS3 video bitrate may not exceed 20000 kbps!" rmtemp fi ;; mx|mxhq) if [ $(echo $bitrate | awk -F= '{print $2}') -gt 20000 ]; then error "-> XBOX 360 video bitrate may not exceed 20000 kbps!" rmtemp fi ;; esac bits_per_pixel_func bits_per_block_func ;; -qp|-crf) printf "Specify the desired $(echo $1 | sed 's|-||' | tr '[:lower:]' '[:upper:]') value [0-51.0 - default is 20.0]: " read crfqp if [ -z "$crfqp" ]; then bitrate="$(echo $1 | sed 's|-||')=20" else bitrate="$(echo $1 | sed 's|-||')=$crfqp" fi echo ;; esac fi ############################################# ############### Presets ##################### ############################################# # Set min/max keyframes according # to chosen/detected FPS value case "$GETFPS" in 5.000|5.00) keyint=":keyint=50" ;; 10.000|10.00) keyint=":keyint=100" ;; 12.000|12.00) keyint=":keyint=120" ;; 15.000|15.00) keyint=":keyint=150" ;; 15.98[4-5]|15.98) keyint=":keyint=160" ;; 17.982|17.98) keyint=":keyint=180" ;; 25.000|25.00) keyint=":keyint=250" ;; 50.000|50.00) keyint=":keyint=500" ;; 100.000|100.00) keyint=":keyint=1000" ;; 23.976|24.000|23.97|24.00) keyint=":keyint=240" ;; 29.970|29.97|30.000|30.00) keyint=":keyint=300" ;; 59.940|59.94|60.000|60.00) keyint=":keyint=600" ;; 119.880|119.88) keyint=":keyint=1200" ;; *|"") keyint=":keyint=250" ;; esac # Overwrite the above if the user has # chosen to set the fps manually or # has chosen to do an ivtc/3:2 pulldown # or if he wants to interlace his # progressive content during the encoding # or deinterlace it with a frame doubling # filter. if [ ! -z "$ofps" ]; then if [ ! -z "$(echo $ofps | grep '/')" ]; then keyint=":keyint=$(($(echo $ofps | awk '{print $2}')+1))0" else keyint=":keyint=$(echo $ofps | awk '{print $2}')0" fi fi keyint_min=":keyint_min=$(($(echo $keyint | awk -F= '{print $2}')/10))" display_quality_preset_func $3 $4 case "$3" in ulq|elq|vlq|lq|mq|nq|hq|vhq|ehq|uhq|ihq|nlq|ani|anihq|fghq) echo printf "Specify the H.264 Level [default is auto]: " read level case "$level" in auto|"") true ;; 1.[0-3]|1[0-3]|2.[0-2]|2[0-2]|3.[0-2]|3[0-2]|4.[0-2]|4[0-2]|5.[0-1]|5[0-1]) h264level=":level_idc=$(echo $level | sed 's|\.||')" ;; *) echo green "-> Unknown H.264 level: $level" green "-> Valid levels: 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 2.2, 3.0" green " 3.1, 3.2, 4.0, 4.1, 4.2, 5.0, 5.1, auto" green "-> Falling back to level 4.1" echo h264level=":level_idc=41" ;; esac ;; esac case "$3" in cp) source "$4" ;; ulq) x264params=":force_cfr:frameref=0:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=dia:subq=1:nombtree:nochroma_me:trellis=0:nocabac:nodeblock:no8x8dct:partitions=none:fast_pskip:dct_decimate:threads=auto$keyint$keyint_min$h264level" ;; elq) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=dia:subq=2:nombtree:nochroma_me:trellis=0:nocabac:nodeblock:no8x8dct:partitions=none:fast_pskip:dct_decimate:threads=auto$keyint$keyint_min$h264level" ;; vlq) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=4:b_adapt=1:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=dia:subq=3:nombtree:nochroma_me:trellis=0:nocabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:dct_decimate:threads=auto$keyint$keyint_min$h264level" ;; lq) x264params=":force_cfr:frameref=2:nomixed_refs:bframes=6:b_adapt=1:b_pyramid=normal:noweight_b:weightp=0:direct_pred=spatial:aq_mode=2:me=dia:subq=4:nombtree:nochroma_me:trellis=0:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:dct_decimate:threads=auto$keyint$keyint_min$h264level" ;; mq) x264params=":force_cfr:frameref=2:mixed_refs:bframes=8:b_adapt=1:b_pyramid=normal:weight_b:weightp=0:direct_pred=spatial:aq_mode=2:me=hex:subq=4:nombtree:nochroma_me:trellis=0:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:dct_decimate:threads=auto$keyint$keyint_min$h264level" ;; nq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=10:b_adapt=1:b_pyramid=normal:weight_b:weightp=1:direct_pred=spatial:aq_mode=2:me=hex:subq=5:nombtree:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; hq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=4:b_adapt=2:b_pyramid=normal:weight_b:weightp=1:direct_pred=auto:aq_mode=1:me=umh:me_range=16:subq=6:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; vhq) x264params=":force_cfr:frameref=4:mixed_refs:bframes=5:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; ehq) x264params=":force_cfr:frameref=5:mixed_refs:bframes=6:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=32:subq=8:mbtree:rc_lookahead=50:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; uhq) x264params=":force_cfr:frameref=6:mixed_refs:bframes=7:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=esa:me_range=48:subq=9:mbtree:rc_lookahead=60:psy_rd=0.8,0.2:chroma_me:trellis=2:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; ihq) x264params=":force_cfr:frameref=10:mixed_refs:bframes=7:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=tesa:me_range=64:subq=10:mbtree:rc_lookahead=70:psy_rd=0.8,0.2:chroma_me:trellis=2:cabac:deblock:8x8dct:partitions=all:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; nlq) bitrate="crf=15"; x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=normal:weight_b:weightp=1:direct_pred=auto:aq_mode=1:me=hex:subq=6:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; fghq) x264params=":force_cfr:frameref=4:mixed_refs:bframes=5:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:aq_strength=0.5:me=umh:me_range=24:subq=7:mbtree:psy_rd=1.0,0.25:chroma_me:trellis=0:cabac:deblock=-2,-2:ip_factor=1.1:pb_factor=1.1:deadzone_intra=6:deadzone_inter=6:qcomp=0.8:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; ani) x264params=":force_cfr:frameref=8:mixed_refs:bframes=5:b_adapt=2:b_pyramid=normal:noweight_b:weightp=1:direct_pred=auto:aq_mode=2:aq_strength=0.5:me=hex:subq=10:nombtree:psy_rd=0.3,0.0:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; anihq) x264params=":force_cfr:frameref=10:mixed_refs:bframes=5:b_adapt=2:b_pyramid=normal:noweight_b:weightp=2:direct_pred=auto:aq_mode=1:aq_strength=0.5:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.3,0.0:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:threads=auto$keyint$keyint_min$h264level" ;; vdhq) x264params=":force_cfr:frameref=4:mixed_refs:bframes=3:b_adapt=2:b_pyramid=normal:weight_b:weightp=1:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:vbv_maxrate=5000:vbv_bufsize=5000:threads=auto$keyint$keyint_min" ;; vdehq) x264params=":force_cfr:frameref=4:mixed_refs:bframes=3:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=8:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=2:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:vbv_maxrate=5000:vbv_bufsize=5000:threads=auto$keyint$keyint_min" ;; vdihq) x264params=":force_cfr:frameref=4:mixed_refs:bframes=3:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=tesa:me_range=32:subq=9:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=2:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:vbv_maxrate=5000:vbv_bufsize=5000:threads=auto$keyint$keyint_min" ;; fl) x264params=":force_cfr:frameref=2:mixed_refs:bframes=3:b_adapt=2:b_pyramid=none:weight_b:weightp=1:direct_pred=spatial:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:threads=auto$keyint$keyint_min" ;; flhq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=6:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:threads=auto$keyint$keyint_min" ;; qt) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=none:weight_b:weightp=1:direct_pred=auto:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:threads=auto$keyint$keyint_min" ;; qthq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:threads=auto$keyint$keyint_min" ;; bd40) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=strict:weight_b:weightp=0:direct_pred=auto:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:slices=4:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=40:aud:nal_hrd=vbr:keyint=$(($(echo $keyint | sed 's|:keyint=||')/10)):keyint_min=1:vbv_maxrate=20000:vbv_bufsize=20000:threads=auto" ;; bdhq40) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=strict:weight_b:weightp=0:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:slices=4:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=40:aud:nal_hrd=vbr:keyint=$(($(echo $keyint | sed 's|:keyint=||')/10)):keyint_min=1:vbv_maxrate=25000:vbv_bufsize=20000:threads=auto" ;; bd41) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=strict:weight_b:weightp=0:direct_pred=auto:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:slices=4:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:aud:nal_hrd=vbr:keyint=$(($(echo $keyint | sed 's|:keyint=||')/10)):keyint_min=1:vbv_maxrate=30000:vbv_bufsize=30000:threads=auto" ;; bdhq41) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=strict:weight_b:weightp=0:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:slices=4:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:aud:nal_hrd=vbr:keyint=$(($(echo $keyint | sed 's|:keyint=||')/10)):keyint_min=1:vbv_maxrate=30000:vbv_bufsize=30000:threads=auto" ;; avchd) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=strict:weight_b:weightp=0:direct_pred=auto:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:slices=4:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=40:aud:nal_hrd=vbr:keyint=$(($(echo $keyint | sed 's|:keyint=||')/10)):keyint_min=1:vbv_maxrate=17000:vbv_bufsize=16000:threads=auto" ;; avchdhq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=strict:weight_b:weightp=0:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=2:cabac:deblock:8x8dct:slices=4:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:aud:nal_hrd=vbr:keyint=$(($(echo $keyint | sed 's|:keyint=||')/10)):keyint_min=1:vbv_maxrate=17000:vbv_bufsize=16000:threads=auto" ;; sdb|hdb) case "$3" in sdb) level_idc=":level_idc=30"; vbv_maxrate=":vbv_maxrate=10000"; vbv_bufsize=":vbv_bufsize=5000" ;; hdb) level_idc=":level_idc=40"; vbv_maxrate=":vbv_maxrate=20000"; vbv_bufsize=":vbv_bufsize=14475" ;; esac x264params=":force_cfr:frameref=3:mixed_refs:bframes=0:b_adapt=0:b_pyramid=strict:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=umh:me_range=24:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:nodct_decimate:aud:threads=auto$level_idc$vbx_maxrate$vbv_bufsize$keyint$keyint_min" ;; sdm|sdh|hdm|hdh) case "$3" in sdm) a8x8dct=":no8x8dct"; partitions=":partitions=p8x8,b8x8,i4x4"; level_idc=":level_idc=30"; vbv_maxrate=":vbv_maxrate=10000"; vbv_bufsize=":vbv_bufsize=5000" ;; sdh) a8x8dct=":8x8dct"; partitions=":partitions=p8x8,b8x8,i8x8,i4x4"; level_idc=":level_idc=30"; vbv_maxrate=":vbv_maxrate=12500"; vbv_bufsize=":vbv_bufsize=5000" ;; hdm) a8x8dct=":no8x8dct"; partitions=":partitions=p8x8,b8x8,i4x4"; level_idc=":level_idc=40"; vbv_maxrate=":vbv_maxrate=20000"; vbv_bufsize=":vbv_bufsize=14475" ;; hdh) a8x8dct=":8x8dct"; partitions=":partitions=p8x8,b8x8,i8x8,i4x4"; level_idc=":level_idc=40"; vbv_maxrate=":vbv_maxrate=25000"; vbv_bufsize=":vbv_bufsize=14475" ;; esac x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=strict:noweight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:nofast_pskip:nodct_decimate:aud:threads=auto$a8x8dct$partitions$level_idc$vbx_maxrate$vbv_bufsize$keyint$keyint_min" ;; ag1) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.0:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:fast_pskip:dct_decimate:level_idc=30:vbv_maxrate=2000:vbv_bufsize=2000:threads=auto$keyint$keyint_min" ;; ag1hq) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=1:me=umh:subq=8:mbtree:psy_rd=0.8,0.0:chroma_me:trellis=2:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:fast_pskip:dct_decimate:level_idc=30:vbv_maxrate=2000:vbv_bufsize=2000:threads=auto$keyint$keyint_min" ;; ipc) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.0:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:fast_pskip:dct_decimate:level_idc=13:vbv_maxrate=768:vbv_bufsize=500:threads=auto$keyint$keyint_min" ;; ipchq) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=1:me=umh:subq=8:mbtree:psy_rd=0.8,0.0:chroma_me:trellis=2:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:level_idc=13:vbv_maxrate=768:vbv_bufsize=500:threads=auto$keyint$keyint_min" ;; ip|iph) case "$3" in ip) vbv_maxrate=":vbv_maxrate=2500"; vbv_bufsize=":vbv_bufsize=2000" ;; iph) vbv_maxrate=":vbv_maxrate=1500"; vbv_bufsize=":vbv_bufsize=1000" ;; esac x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.0:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:fast_pskip:dct_decimate:level_idc=30:threads=auto$vbv_maxrate$vbv_bufsize$keyint$keyint_min" ;; iphq|iphhq) case "$3" in iphq) level_idc=":level_idc=30"; vbv_maxrate=":vbv_maxrate=2500"; vbv_bufsize=":vbv_bufsize=2000" ;; iphhq) level_idc=":level_idc=31"; vbv_maxrate=":vbv_maxrate=10000"; vbv_bufsize=":vbv_bufsize=10000" ;; esac x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=1:me=umh:subq=8:mbtree:psy_rd=0.8,0.0:chroma_me:trellis=2:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:threads=auto$level_idc$vbv_maxrate$vbv_bufsize$keyint$keyint_min" ;; atv) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=2:b_adapt=2:b_pyramid=none:noweight_b:weightp=0:direct_pred=auto:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.0:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:dct_decimate:level_idc=30:vbv_maxrate=12000:vbv_bufsize=5000:threads=auto$keyint$keyint_min" ;; atvhq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=normal:weight_b:weightp=0:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.0:chroma_me:trellis=2:nocabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:dct_decimate:level_idc=30:vbv_maxrate=12000:vbv_bufsize=5000:threads=auto$keyint$keyint_min" ;; ar) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.0:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:level_idc=30:vbv_maxrate=5000:vbv_bufsize=3000:threads=auto$keyint$keyint_min" ;; arhq) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=1:me=umh:me_range=24:subq=8:mbtree:psy_rd=0.8,0.0:chroma_me:trellis=2:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:level_idc=30:vbv_maxrate=5000:vbv_bufsize=3000:threads=auto$keyint$keyint_min" ;; ar5) x264params=":force_cfr:frameref=3:mixed_refs:bframes=2:b_adapt=2:b_pyramid=strict:weight_b:weightp=1:direct_pred=auto:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=40:vbv_maxrate=2000:vbv_bufsize=1700:threads=auto$keyint$keyint_min" ;; ar5hq) x264params=":force_cfr:frameref=4:mixed_refs:bframes=4:b_adapt=2:b_pyramid=strict:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=40:vbv_maxrate=2000:vbv_bufsize=1700:threads=auto$keyint$keyint_min" ;; bb) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.0:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:level_idc=30:vbv_maxrate=1500:vbv_bufsize=1000:threads=auto$keyint$keyint_min" ;; bbhq) x264params=":force_cfr:frameref=2:mixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=1:me=umh:subq=8:mbtree:psy_rd=0.8,0.0:chroma_me:trellis=2:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:level_idc=30:vbv_maxrate=1500:vbv_bufsize=1000:threads=auto$keyint$keyint_min" ;; nks60) x264params=":force_cfr:frameref=2:mixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.0:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:level_idc=12:vbv_maxrate=384:vbv_bufsize=900:threads=auto$keyint$keyint_min" ;; nks60hq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=1:me=umh:subq=8:mbtree:psy_rd=0.8,0.0:chroma_me:trellis=2:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:level_idc=12:vbv_maxrate=384:vbv_bufsize=900:threads=auto$keyint$keyint_min" ;; psp) x264params=":force_cfr:frameref=2:mixed_refs:bframes=3:b_adapt=2:b_pyramid=none:weight_b:weightp=1:direct_pred=spatial:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:fast_pskip:nodct_decimate:level_idc=30:vbv_maxrate=4000:vbv_bufsize=2500:threads=auto$keyint$keyint_min" ;; psphq) x264params=":force_cfr:frameref=2:mixed_refs:bframes=3:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=30:vbv_maxrate=4000:vbv_bufsize=2500:threads=auto$keyint$keyint_min" ;; ps3) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=none:weight_b:weightp=1:direct_pred=spatial:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:aud:vbv_maxrate=20000:vbv_bufsize=20000:threads=auto$keyint$keyint_min" ;; ps3hq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=3:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:aud:vbv_maxrate=20000:vbv_bufsize=20000:threads=auto$keyint$keyint_min" ;; mz) x264params=":force_cfr:frameref=1:nomixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.0:chroma_me:trellis=1:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:fast_pskip:dct_decimate:level_idc=30:vbv_maxrate=2500:vbv_bufsize=2000:threads=auto$keyint$keyint_min" ;; mzhq) x264params=":force_cfr:force_cfr:frameref=3:mixed_refs:bframes=0:b_adapt=0:b_pyramid=none:noweight_b:weightp=0:direct_pred=none:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.0:chroma_me:trellis=2:nocabac:deblock:no8x8dct:partitions=p8x8,i4x4:nofast_pskip:dct_decimate:level_idc=30:vbv_maxrate=2500:vbv_bufsize=2000:threads=auto$keyint$keyint_min" ;; mx) x264params=":force_cfr:frameref=2:mixed_refs:bframes=3:b_adapt=2:b_pyramid=none:weight_b:weightp=1:direct_pred=spatial:aq_mode=2:me=hex:subq=6:nombtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:no8x8dct:partitions=p8x8,b8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:vbv_maxrate=20000:vbv_bufsize=20000:threads=auto$keyint$keyint_min" ;; mxhq) x264params=":force_cfr:frameref=3:mixed_refs:bframes=6:b_adapt=2:b_pyramid=normal:weight_b:weightp=2:direct_pred=auto:aq_mode=1:me=umh:me_range=24:subq=7:mbtree:psy_rd=0.8,0.2:chroma_me:trellis=1:cabac:deblock:8x8dct:partitions=p8x8,b8x8,i8x8,i4x4:nofast_pskip:nodct_decimate:level_idc=41:vbv_maxrate=20000:vbv_bufsize=20000:threads=auto$keyint$keyint_min" ;; ultrafast|superfast|veryfast|faster|fast|medium|slow|slower|veryslow|placebo) x264params=":preset=$3$x264tune$x264profile$keyint$keyint_min:force_cfr" ;; esac # Custom matrices are only # supported by presets which # use High profile settings case "$3" in cp) false ;; hq|vhq|ehq|uhq|ihq|ani|anihq|vdhq|vdehq|vdihq|flhq|bdhq40|bdhq41|avchdhq|sdh|hdh|ps3hq|mxhq) cuma=$(get_selection_func "Would you like to use Predefined/Custom Quantization Matrices (cqm)? [y/N]: ") if [ "$cuma" = "y" ]; then echo brown "Predefined/Custom Quantization Matrices" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Flat -> Predefined flat 16 matrix" echo "1 -> JVT --> Predefined JVT matrix" echo "2 -> Load a custom matrix file" echo "3 -> Skip loading/using matrices" echo printf "Which one to use? [default is 0]: " read cmatrix case "$cmatrix" in 0|"") cqm=":cqm=flat" ;; 1) cqm=":cqm=jvt" ;; 2) printf "Provide the Custom Matrix file: " read -e matrixfile if [ ! -f "$matrixfile" ]; then echo green "-> No such file: '$matrixfile'" green "-> Skipping loading of matrix" echo else cqm=":cqm=$matrixfile" fi ;; *) false ;; esac fi ;; esac # Set priority (nice value) of the whole # encoding process if [ ! -z "$PRIORITY" ]; then priority_level="nice -n $PRIORITY" else priolevel=$(get_selection_func "Would you like to set the encoder Priority Level? [y/N]: ") if [ "$priolevel" = "y" ]; then if [ $UID != 0 ]; then printf "Specify the encoder priority level [0-19 - default is 0]: " read nice_value case "$nice_value" in [0-9]|1[0-9]) priority_level="nice -n $nice_value" ;; -[1-9]|-1[0-9]|-20) echo green "-> You do not have the privilege to set a negative 'nice' value!" green "-> Continuing with default 'nice' value of 0" ;; esac else printf "Specify the encoder priority level [-20-19 - default is 0]: " read nice_value case "$nice_value" in -[1-9]|-1[0-9]|-20|[0-9]|1[0-9]) priority_level="nice -n $nice_value" ;; esac fi fi fi ##################################################### ############## Audio Configuration ################## ##################################################### echo brown "+=====================+" brown "| Audio Configuration |" brown "+=====================+" case "$source" in dir|vcd) echo TRACKID[1]=yes ;; dvd) echo TRACKID[1]=yes green "-> Scanning for audio streams..." $MPLAYER $sourcetype $device $MPLAYEROPTS -nosound -vo null -frames 1 -nocache 2>/dev/null > "$TEMPDIR/audiostreams" STREAMS=$(grep "^audio stream" "$TEMPDIR/audiostreams") if [ ! -z "$STREAMS" ]; then echo echo "$STREAMS" | sed -e 's/^audio/Audio/g' -e 's/format:/Format:/g' -e 's/language:/Language:/g' \ -e 's/aid:/ID:/g' -e 's/ac3/AC3/g' -e 's/dts/DTS/g' -e 's/lpcm/LPCM/g' -e 's/pcm/PCM/g' else green "-> Could not detect any audio streams!" fi echo printf "Track 1: Specify the DVD Audio Stream ID [default is 128]: " read dac if [ ! -z "$(echo $dac | grep '[a-zA-Z]')" ]; then error "-> You have to specify the 'ID' number, not the language code!" rmtemp fi if [ -z "$dac" ]; then aid[1]="-aid 128" else aid[1]="-aid $dac" fi for i in {2..3}; do printf "Track $i: Specify the DVD Audio Stream ID [press 'Enter' to skip]: " read dac[$i] if [ ! -z "$(echo ${dac[$i]} | grep '[a-zA-Z]')" ]; then error "-> You have to specify the 'ID' number, not the language code!" rmtemp fi if [ ! -z "${dac[$i]}" ]; then TRACKID[$i]=yes aid[$i]="-aid ${dac[$i]}" fi done for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then GETLANG[$i]="$(grep "$(echo ${aid[$i]} | awk '{print $2}')" "$TEMPDIR/audiostreams" \ | grep -o 'language.*' | awk '{print $2}')" if [ ! -z "${GETLANG[$i]}" ]; then if [ "${GETLANG[$i]}" = "unknown" ]; then AUDLANG[$i]="und" else AUDLANG[$i]="${GETLANG[$i]}" fi else AUDLANG[$i]="und" fi fi done rm -f "$TEMPDIR/audiostreams" ;; file) TRACKID[1]=yes if [ "$ALLOW_SCAN_MULTIPLE_AUDSTREAMS" = "y" ]; then echo multiaudio=$(get_selection_func "Scan for multiple Audio streams? [y/N]: ") if [ "$multiaudio" = "y" ]; then echo "" green "-> Scanning for audio streams..." $MPLAYER "$sourcetype" $MPLAYEROPTS -nosound -vo null -identify -frames 1 -nocache 2>/dev/null > "$TEMPDIR/audiostreams" if [ $(grep "^ID_AUDIO_ID" "$TEMPDIR/audiostreams" | wc -l) -le 1 ]; then green "-> Zero or one audio stream found" green "-> Skipping stream selection" else echo for i in $(grep "^ID_AUDIO_ID" "$TEMPDIR/audiostreams"); do echo "$(echo "Audio Stream ID: $(echo $i | awk -F= '{print $2}')")" done echo AID=$(grep "^ID_AUDIO_ID" "$TEMPDIR/audiostreams" | awk -F= '{print $2}') printf "Track 1: Specify the Audio Stream ID [default is $(echo $AID | awk '{print $1}')]: " read dac if [ -z "$dac" ]; then aid[1]="-aid $(echo $AID | awk '{print $1}')" else aid[1]="-aid $dac" fi fi rm -f "$TEMPDIR/audiostreams" fi fi ;; esac ############################################### ########## Audio Codec Functions ############## ############################################### mp3_audio_func() { printf "Track $i: Specify the MP3 Audio Encoding Mode [ABR/CBR/VBR/PRESET - default is ABR]: " read mp3mode[$i] case "${mp3mode[$i]}" in a*|A*|"") printf "Track $i: Specify the MP3 Average Bitrate [default is 140]: " read ab[$i] if [ -z "${ab[$i]}" ]; then abitrate[$i]="abr:br=140" else abitrate[$i]="abr:br=${ab[$i]}" fi ;; c*|C*) echo brown "Track $i: MP3 Audio Bitrates" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> 32 kbps 7 --> 112 kbps" echo "1 -> 40 kbps 8 --> 128 kbps" echo "2 -> 48 kbps 9 --> 160 kbps" echo "3 -> 56 kbps 10 -> 192 kbps" echo "4 -> 64 kbps 11 -> 224 kbps" echo "5 -> 80 kbps 12 -> 256 kbps" echo "6 -> 96 kbps 13 -> 320 kbps" echo printf "Track $i: Select the MP3 Audio Bitrate [default is 8]: " read ab[$i] case "${ab[$i]}" in 0) abitrate[$i]="cbr:br=32" ;; 1) abitrate[$i]="cbr:br=40" ;; 2) abitrate[$i]="cbr:br=48" ;; 3) abitrate[$i]="cbr:br=56" ;; 4) abitrate[$i]="cbr:br=64" ;; 5) abitrate[$i]="cbr:br=80" ;; 6) abitrate[$i]="cbr:br=96" ;; 7) abitrate[$i]="cbr:br=112" ;; 8|"") abitrate[$i]="cbr:br=128" ;; 9) abitrate[$i]="cbr:br=160" ;; 10) abitrate[$i]="cbr:br=192" ;; 11) abitrate[$i]="cbr:br=224" ;; 12) abitrate[$i]="cbr:br=256" ;; 13) abitrate[$i]="cbr:br=320" ;; *) error "-> Track $i: Unknown option: '${ab[$i]}'" error "-> Exiting in function: mp3_audio_func()" rmtemp ;; esac ;; v*|V*) printf "Track $i: Specify the desired MP3 Audio Quality [0-9 - default is 3]: " read ab[$i] if [ -z "${ab[$i]}" ]; then abitrate[$i]="q=3" else abitrate[$i]="q=${ab[$i]}" fi ;; p*|P*) echo brown "Track $i: MP3 Presets" brown "~~~~~~~~~~~~~~~~~~~~" echo "0 -> Medium (VBR: 150-180 kbps)" echo "1 -> Standard (VBR: 170-210 kbps)" echo "2 -> Extreme (VBR: 200-240 kbps)" echo "3 -> Insane (CBR: 320 kbps)" echo printf "Track $i: Select an MP3 preset [default is 0]: " read mp3preset[$i] case "${mp3preset[$i]}" in 0|"") abitrate[$i]="preset=medium" ;; 1) abitrate[$i]="preset=standard" ;; 2) abitrate[$i]="preset=extreme" ;; 3) abitrate[$i]="preset=insane" ;; *) error "-> Track $i: Unknown MP3 preset!" error "-> Exiting in function: mp3_audio_func()" rmtemp ;; esac ;; *) error "-> Track $i: Unknown MP3 encoding mode: '${mp3mode[$i]}'" error "-> Exiting in function: mp3_audio_func()" rmtemp ;; esac printf "Track $i: Specify the MP3 Algorithmic Quality [0-9 - default is 4]: " read aq[$i] if [ -z "${aq[$i]}" ]; then aquality[$i]=":aq=4" else aquality[$i]=":aq=${aq[$i]}" fi printf "Track $i: Specify the MP3 Audio Input Gain [0.0-10.0 - default is 2.2]: " read aig[$i] if [ -z "${aig[$i]}" ]; then again[$i]=":vol=2.2" else again[$i]=":vol=${aig[$i]}" fi echo "" brown "Track $i: MP3 Channel Modes" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Stereo" echo "1 -> Joint-Stereo" echo "2 -> Dual Channel" echo "3 -> Mono" echo "" printf "Track $i: Select the MP3 Channel Mode [default is 1]: " read mp3chan[$i] case "${mp3chan[$i]}" in 0) mp3channel[$i]=":mode=0" ;; 1|"") mp3channel[$i]=":mode=1" ;; 2) mp3channel[$i]=":mode=2" ;; 3) mp3channel[$i]=":mode=3" ;; *) error "-> Track $i: Unknown MP3 channel option: '${mp3chan[$i]}'" error "-> Exiting in function: mp3_audio_func()" rmtemp ;; esac acodec[$i]="-oac mp3lame -lameopts ${abitrate[$i]}${aquality[$i]}${again[$i]}${mp3channel[$i]}" } ac3_audio_func() { echo brown "Track $i: AC3 Audio Bitrates" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> 32 kbps 9 --> 160 kbps" echo "1 -> 40 kbps 10 -> 192 kbps" echo "2 -> 48 kbps 11 -> 224 kbps" echo "3 -> 56 kbps 12 -> 256 kbps" echo "4 -> 64 kbps 13 -> 320 kbps" echo "5 -> 80 kbps 14 -> 448 kbps" echo "6 -> 96 kbps 15 -> 512 kbps" echo "7 -> 112 kbps 16 -> 576 kbps" echo "8 -> 128 kbps 17 -> 640 kbps" echo printf "Track $i: Select the AC3 Audio Bitrate [default is 10]: " read ab[$i] case "${ab[$i]}" in 0) abitrate[$i]="32" ;; 1) abitrate[$i]="40" ;; 2) abitrate[$i]="48" ;; 3) abitrate[$i]="56" ;; 4) abitrate[$i]="64" ;; 5) abitrate[$i]="80" ;; 6) abitrate[$i]="96" ;; 7) abitrate[$i]="112" ;; 8) abitrate[$i]="128" ;; 9) abitrate[$i]="160" ;; 10|"") abitrate[$i]="192" ;; 11) abitrate[$i]="224" ;; 12) abitrate[$i]="256" ;; 13) abitrate[$i]="320" ;; 14) abitrate[$i]="448" ;; 15) abitrate[$i]="512" ;; 16) abitrate[$i]="576" ;; 17) abitrate[$i]="640" ;; *) error "-> Track $i: Unknown option: '${ab[$i]}'" error "-> Exiting in function: ac3_audio_func()" rmtemp ;; esac acodec[$i]="-oac lavc -lavcopts acodec=ac3:abitrate=${abitrate[$i]}" } aac_audio_func() { acodec[$i]="-oac pcm" case "$1" in fl|flhq|qt|qthq|ag1|ag1hq|ipc|ipchq|ip|iphq|iph|iphhq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq|ps3|ps3hq|mz|mzhq) printf "Track $i: Specify the AAC Average Bitrate [default is 128]: " read abitrate[$i] if [ -z "${abitrate[$i]}" ]; then br[$i]="-b 128" else br[$i]="-b ${abitrate[$i]}" fi case "$1" in ag1|ag1hq|ipc|ipchq|ip|iphq|iph|iphhq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq) # Restrict audio bitrate for devices # with a maximum allowed bitrate if [ $(echo ${br[$i]} | awk '{print $2}') -gt 160 ]; then echo green "-> Track $i: Audio bitrate for this portable device may not exceed 160 kbps!" green "-> Track $i: Falling back to 128 kbps!" echo br[$i]="-b 128" fi ;; esac ;; *) printf "Track $i: Specify the AAC encoding mode [ABR/VBR - default is ABR]: " read aacmode[$i] case "${aacmode[$i]}" in a*|A*|"") printf "Track $i: Specify the AAC Average Bitrate [default is 110]: " read abitrate[$i] if [ -z "${abitrate[$i]}" ]; then br[$i]="-b 110" else br[$i]="-b ${abitrate[$i]}" fi ;; v*|V*) SKIPBTRCALC=yes printf "Track $i: Specify the AAC Quality value [10-500 - default is 150]: " read abitrate[$i] if [ -z "${abitrate[$i]}" ]; then br[$i]="-q 150" else br[$i]="-q ${abitrate[$i]}" fi ;; *) error "-> Track $i: Unknown AAC encoding mode: '${aacmode[$i]}'" error "-> Exiting in function: aac_audio_func()" rmtemp ;; esac ;; esac tempns[$i]=$(get_selection_func "Track $i: Enable AAC Temporal Noise Shaping? [y/N]: ") if [ "${tempns[$i]}" = "y" ]; then tns[$i]="--tns" fi } neroaac_audio_func() { acodec[$i]="-oac pcm" case "$1" in qt|qthq|ag1|ag1hq|ipc|ipchq|ip|iphq|iph|iphhq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq|ps3|ps3hq|mz|mzhq|mx|mxhq) aacprof[$i]="-lc" AACTYPE[$i]=LC-AAC printf "Track $i: Specify the AAC Audio Bitrate in kbps [default is 128]: " read ab[$i] if [ -z "${ab[$i]}" ]; then neroaacbr[$i]="-br 128000 ${aacprof[$i]}" else neroaacbr[$i]="-br $((${ab[$i]}*1000)) ${aacprof[$i]}" fi case "$1" in ag1|ag1hq|ipc|ipchq|ip|iphq|iph|iphhq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq) if [ $(echo ${neroaacbr[$i]} | awk '{print $2}') -gt 160000 ]; then echo green "-> Track $i: Audio bitrate for this preset may not exceed 160 kbps!" green "-> Track $i: Falling back to 128 kbps!" echo neroaacbr[$i]="-br 128000 ${aacprof[$i]}" fi ;; esac nero2p[$i]=$(get_selection_func "Track $i: Use 2-pass AAC encoding instead of 1-pass? [y/N]: ") if [ "${nero2p[$i]}" = "y" ]; then neroaacbr[$i]="${neroaacbr[$i]} -2pass" fi ;; *) printf "Track $i: Which AAC Profile to use? [LC/HE/HEv2 - default is LC]: " read aac_profile[$i] case "${aac_profile[$i]}" in LC|lc|"") aacprof[$i]="-lc"; AACTYPE[$i]=LC-AAC ;; HE|he) aacprof[$i]="-he"; AACTYPE[$i]=HE-AACv1 ;; HEv2|hev2) aacprof[$i]="-hev2"; AACTYPE[$i]=HE-AACv2 ;; *) error "-> Track $i: Unknown AAC profile" error "-> Exiting in function: neroaac_audio_func()" rmtemp ;; esac printf "Track $i: Specify the AAC Encoding Mode [ABR/CBR/VBR - default is ABR]: " read aacmode[$i] case "${aacmode[$i]}" in a*|A*|"") case "${aacprof[$i]}" in -lc) defaacbr[$i]="96" ;; -he) defaacbr[$i]="55" ;; -hev2) defaacbr[$i]="25" ;; esac printf "Track $i: Specify the AAC Average Bitrate in kbps [default is ${defaacbr[$i]}]: " read ab[$i] if [ -z "${ab[$i]}" ]; then neroaacbr[$i]="-br $((${defaacbr[$i]}*1000)) ${aacprof[$i]}" else neroaacbr[$i]="-br $((${ab[$i]}*1000)) ${aacprof[$i]}" fi ;; c*|C*) echo brown "Track $i: AAC Audio Bitrates" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> 32 kbps 7 --> 112 kbps" echo "1 -> 40 kbps 8 --> 128 kbps" echo "2 -> 48 kbps 9 --> 160 kbps" echo "3 -> 56 kbps 10 -> 192 kbps" echo "4 -> 64 kbps 11 -> 224 kbps" echo "5 -> 80 kbps 12 -> 256 kbps" echo "6 -> 96 kbps 13 -> 320 kbps" echo printf "Track $i: Select the AAC Audio Bitrate [default is 6]: " read ab[$i] case "${ab[$i]}" in 0) neroaacbr[$i]="-cbr 32000 ${aacprof[$i]}" ;; 1) neroaacbr[$i]="-cbr 40000 ${aacprof[$i]}" ;; 2) neroaacbr[$i]="-cbr 48000 ${aacprof[$i]}" ;; 3) neroaacbr[$i]="-cbr 56000 ${aacprof[$i]}" ;; 4) neroaacbr[$i]="-cbr 64000 ${aacprof[$i]}" ;; 5) neroaacbr[$i]="-cbr 80000 ${aacprof[$i]}" ;; 6|"") neroaacbr[$i]="-cbr 96000 ${aacprof[$i]}" ;; 7) neroaacbr[$i]="-cbr 112000 ${aacprof[$i]}" ;; 8) neroaacbr[$i]="-cbr 128000 ${aacprof[$i]}" ;; 9) neroaacbr[$i]="-cbr 160000 ${aacprof[$i]}" ;; 10) neroaacbr[$i]="-cbr 192000 ${aacprof[$i]}" ;; 11) neroaacbr[$i]="-cbr 224000 ${aacprof[$i]}" ;; 12) neroaacbr[$i]="-cbr 256000 ${aacprof[$i]}" ;; 13) neroaacbr[$i]="-cbr 320000 ${aacprof[$i]}" ;; *) error "-> Track $i: Unknown option: '${ab[$i]}'" error "-> Exiting in function: neroaac_audio_func()" rmtemp ;; esac ;; v*|V*) SKIPBTRCALC=yes case "${aacprof[$i]}" in -lc) defaacbr[$i]="0.35" ;; -he) defaacbr[$i]="0.22" ;; -hev2) defaacbr[$i]="0.11" ;; esac printf "Track $i: Specify the AAC Quality value [0.0-1.0 - default is ${defaacbr[$i]}]: " read ab[$i] if [ -z "${ab[$i]}" ]; then neroaacbr[$i]="-q ${defaacbr[$i]} ${aacprof[$i]}" else neroaacbr[$i]="-q ${ab[$i]} ${aacprof[$i]}" fi ;; *) error "-> Track $i: Unknown option: '${aacmode[$i]}'" error "-> Exiting in function: neroaac_audio_func()" rmtemp ;; esac case "${aacmode[$i]}" in a*|A*|c*|C*|"") nero2p[$i]=$(get_selection_func "Track $i: Use 2-pass AAC encoding instead of 1-pass? [y/N]: ") if [ "${nero2p[$i]}" = "y" ]; then neroaacbr[$i]="${neroaacbr[$i]} -2pass" fi ;; esac ;; esac } aacplus_audio_func() { acodec[$i]="-oac pcm" channels[$i]="-channels 2" printf "Track $i: Specify the AAC+ Audio Bitrate in kbps [default is 55]: " read ab[$i] if [ -z "${ab[$i]}" ]; then aacplusbr[$i]="55" else if [[ ${ab[$i]} -ge 64 ]]; then echo green "-> Track $i: Bitrates of 64 kbps and up are not supported!" green "-> Track $i: Using default bitrate of 55 kbps" echo aacplusbr[$i]="55" elif [[ ${ab[$i]} -lt 48 ]]; then echo green "-> Track $i: Bitrates below 48 kbps use Parametric Stereo" green " which is not recommended!" green "-> Track $i: Using default bitrate of 55 kbps" echo aacplusbr[$i]="55" else aacplusbr[$i]="${ab[$i]}" fi fi } vorbis_audio_func() { acodec[$i]="-oac pcm" printf "Track $i: Select the Vorbis encoding mode [ABR/VBR - default is VBR]: " read vorbmode[$i] case "${vorbmode[$i]}" in a*|A*) printf "Track $i: Specify the Vorbis nominal bitrate in kbps [default is 112]: " read ab[$i] if [ -z "${ab[$i]}" ]; then vorbq[$i]="-b 112" else vorbq[$i]="-b ${ab[$i]}" fi ;; v*|V*|"") printf "Track $i: Specify the Vorbis audio quality [-1-10 - default is 3]: " read ab[$i] if [ -z "${ab[$i]}" ]; then vorbq[$i]="-q 3" else if [ ! -z "$(echo ${ab[$i]} | grep '\.')" ]; then echo green "-> Track $i: Floating point values are not supported yet!" green "-> Track $i: Rounding value to $(echo ${ab[$i]} | awk -F. '{print $1}')" echo vorbq[$i]="-q $(echo ${ab[$i]} | awk -F. '{print $1}')" else vorbq[$i]="-q ${ab[$i]}" fi fi ;; *) error "-> Unknown option: '${vorbmode[$i]}'" error "-> Exiting in function: vorbis_audio_func()" rmtemp ;; esac } flac_audio_func() { acodec[$i]="-oac pcm" printf "Track $i: Specify the FLAC Audio compression [0(low)-8(high) - default is 5]: " read ab[$i] if [ -z "${ab[$i]}" ]; then flacq[$i]="-5" else flacq[$i]="-${ab[$i]}" fi } # Check availability of the # selected audio codec check_audio_codec_func() { case "${audiocodec[$i]}" in ac3) if [ -z "$($MENCODER -oac help 2>/dev/null | awk '{print $1}' | grep 'lavc')" ]; then error "-> MEncoder does not support the libavcodecs audio collection!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; mp3) if [ -z "$($MENCODER -oac help 2>/dev/null | awk '{print $1}' | grep 'mp3lame')" ]; then error "-> MEncoder does not support MP3 audio encoding!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; aac|"") if [ ! -x "$FAAC" ]; then error "-> 'faac' is missing from your system!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; neroaac) if [ ! -x "$NEROAACENC" ]; then error "-> 'neroAacEnc' is missing from your system!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; aac+) if [ ! -x "$AACPLUSENC" ]; then error "-> 'aacplusenc' is missing from your system!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; vorbis) if [ ! -x "$OGGENC" ]; then error "-> 'oggenc' is missing from your system!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; flac) if [ ! -x "$FLAC" ]; then error "-> 'flac' is missing from your system!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; pcm) if [ -z "$($MENCODER -oac help 2>/dev/null | awk '{print $1}' | grep 'pcm')" ]; then error "-> MEncoder does not support PCM audio encoding!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; copy) if [ -z "$($MENCODER -oac help 2>/dev/null | awk '{print $1}' | grep 'copy')" ]; then error "-> MEncoder does not support audio stream copy!" error "-> Exiting in function: check_audio_codec_func()" rmtemp fi ;; esac } ############################################### ########## Audio Filters Functions ############ ############################################### # Resample function audio_resample_filters_func() { echo brown "Track $i: Audio Resample Filters And Modes" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "0 -> Resample: standard mode, linear interpolation" echo "1 -> Resample: HQ mode, linear interpolation" echo "2 -> Resample: standard mode, polyphase filterbank & integer processing" echo "3 -> Resample: HQ mode, polyphase filterbank & integer processing" echo "4 -> Resample: standard mode, polyphase filterbank & floating point processing" echo "5 -> Resample: HQ mode, polyphase filterbank & floating point processing" echo "6 -> Lavcresample: standard mode" echo "7 -> Lavcresample: linear interpolated polyphase filterbank" echo "8 -> Skip audio resampling" echo printf "Track $i: Select a Resample filter [default is 7]: " read rsmpfilter[$i] case "${rsmpfilter[$i]}" in 0) resample[$i]="resample=${hertz[$i]}:1:0 -srate ${hertz[$i]}" ;; 1) resample[$i]="resample=${hertz[$i]}:0:0 -srate ${hertz[$i]}" ;; 2) resample[$i]="resample=${hertz[$i]}:1:1 -srate ${hertz[$i]}" ;; 3) resample[$i]="resample=${hertz[$i]}:0:1 -srate ${hertz[$i]}" ;; 4) resample[$i]="resample=${hertz[$i]}:1:2 -srate ${hertz[$i]}" ;; 5) resample[$i]="resample=${hertz[$i]}:0:2 -srate ${hertz[$i]}" ;; 6) resample[$i]="lavcresample=${hertz[$i]}:16:0 -srate ${hertz[$i]}" ;; 7|"") resample[$i]="lavcresample=${hertz[$i]}:16:1 -srate ${hertz[$i]}" ;; 8) skiprsmp=yes ;; *) error "-> Track $i: Unknown option: '${rsmpfilter[$i]}'" error "-> Exiting in function: audio_resample_filters_func()" rmtemp ;; esac } audio_resample_func() { rsmp[$i]=$(get_selection_func "Track $i: Would you like to Resample the Audio? [y/N]: ") if [ "${rsmp[$i]}" = "y" ]; then case "$source" in file|vcd|dvd) echo green "-> Track $i: Detecting audio sample rate..." AUDSAMPLE[$i]=$($MPLAYER "$sourcetype" $MPLAYEROPTS $device ${aid[$i]} -identify -vo null -vc null -ao null -frames 0 -nocache 2>/dev/null \ | grep '^ID_AUDIO_RATE' | tail -n 1 | awk -F= '{print $2}') if [ ! -z "${AUDSAMPLE[$i]}" ]; then green "-> Track $i: Detected: ${AUDSAMPLE[$i]} Hz ($(echo "scale=1; ${AUDSAMPLE[$i]} / 1000" | $BC -l) kHz)" else green "-> Track $i: could not detect the sample rate!" fi ;; esac echo brown "Track $i: Available Sample Frequencies" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" case "${audiocodec[$i]}" in pcm|vorbis) echo "0 -> 8000 Hz (8 kHz)" echo "1 -> 11025 Hz (11 kHz)" echo "2 -> 12000 Hz (12 kHz)" echo "3 -> 16000 Hz (16 kHz)" echo "4 -> 22050 Hz (22 kHz)" echo "5 -> 24000 Hz (24 kHz)" echo "6 -> 32000 Hz (32 kHz)" echo "7 -> 44100 Hz (44.1 kHz)" echo "8 -> 48000 Hz (48 kHz)" echo printf "Track $i: Select a Sample frequency [default is 7]: " read freq[$i] case "${freq[$i]}" in 0) hertz[$i]="8000" ;; 1) hertz[$i]="11025" ;; 2) hertz[$i]="12000" ;; 3) hertz[$i]="16000" ;; 4) hertz[$i]="22050" ;; 5) hertz[$i]="24000" ;; 6) hertz[$i]="32000" ;; 7|"") hertz[$i]="44100" ;; 8) hertz[$i]="48000" ;; *) error "-> Track $i: Unknown option: '${freq[$i]}'" error "-> Exiting in function: audio_resample_func()" rmtemp ;; esac ;; aac|neroaac|flac|"") echo "0 --> 8000 Hz (8 kHz)" echo "1 --> 11025 Hz (11 kHz)" echo "2 --> 12000 Hz (12 kHz)" echo "3 --> 16000 Hz (16 kHz)" echo "4 --> 22050 Hz (22 kHz)" echo "5 --> 24000 Hz (24 kHz)" echo "6 --> 32000 Hz (32 kHz)" echo "7 --> 44100 Hz (44.1 kHz)" echo "8 --> 48000 Hz (48 kHz)" echo "9 --> 64000 Hz (64 kHz)" echo "10 -> 88200 Hz (88.2 kHz)" echo "11 -> 96000 Hz (96 kHz)" echo printf "Track $i: Select a Sample frequency [default is 7]: " read freq[$i] case "${freq[$i]}" in 0) hertz[$i]="8000" ;; 1) hertz[$i]="11025" ;; 2) hertz[$i]="12000" ;; 3) hertz[$i]="16000" ;; 4) hertz[$i]="22050" ;; 5) hertz[$i]="24000" ;; 6) hertz[$i]="32000" ;; 7|"") hertz[$i]="44100" ;; 8) hertz[$i]="48000" ;; 9) hertz[$i]="64000" ;; 10) hertz[$i]="88200" ;; 11) hertz[$i]="96000" ;; *) error "-> Track $i: Unknown option: '${freq[$i]}'" error "-> Exiting in function: audio_resample_func()" rmtemp ;; esac ;; aac+|ac3|mp3) echo "0 -> 32000 Hz (32 kHz)" echo "1 -> 44100 Hz (44.1 kHz)" echo "2 -> 48000 Hz (48 kHz)" echo printf "Track $i: Select a Sample frequency [default is 1]: " read freq[$i] case "${freq[$i]}" in 0) hertz[$i]="32000" ;; 1|"") hertz[$i]="44100" ;; 2) hertz[$i]="48000" ;; *) error "-> Track $i: Unknown option: '${freq[$i]}'" error "-> Exiting in function: audio_resample_func()" rmtemp ;; esac ;; esac case "$source" in dir) audio_resample_filters_func ;; *) if [ "${AUDSAMPLE[$i]}" = "${hertz[$i]}" ]; then echo green "-> Track $i: Detected sample rate equals selected one!" green "-> Track $i: ${AUDSAMPLE[$i]} Hz <=> ${hertz[$i]} Hz" green "-> Track $i: Skipping resampling" resample[$i]= else audio_resample_filters_func fi ;; esac fi } # Audio EQ audio_equalizer_func() { audioeq[$i]=$(get_selection_func "Track $i: Would you like to use the Audio Equalizer? [y/N]: ") if [ "${audioeq[$i]}" = "y" ]; then printf "Track $i: Specify the Audio Equalizer parameters [press 'Enter' to skip]: " read audeqparams[$i] if [ ! -z "${audeqparams[$i]}" ]; then audeq[$i]="equalizer=${audeqparams[$i]}," fi fi } # Volume normalization audio_volnorm_func() { norm[$i]=$(get_selection_func "Track $i: Would you like to Normalize the Audio volume? [y/N]: ") if [ "${norm[$i]}" = "y" ]; then volnorm[$i]="volnorm=2," fi } # Audio volume gain. # Mutually exclusive # with the volnorm filter audio_volume_func() { if [ -z "${volnorm[$i]}" ]; then avolume[$i]=$(get_selection_func "Track $i: Would you like to set the Audio volume? [y/N]: ") if [ "${avolume[$i]}" = "y" ]; then printf "Track $i: Specify the Audio volume in dB [-200-60 - default is 5]: " read dbgain[$i] if [ -z "${dbgain[$i]}" ]; then volume[$i]="volume=5:1," else volume[$i]="volume=${dbgain[$i]}:1," fi fi fi } # Audio panning audio_pan_func() { audpan[$i]=$(get_selection_func "Track $i: Would you like to Pan the Audio? [y/N]: ") if [ "${audpan[$i]}" = "y" ]; then printf "Track $i: Specify the panning filter values [press 'Enter' to skip]: " read panval[$i] if [ ! -z "${panval[$i]}" ]; then pan[$i]="pan=${panval[$i]}," fi fi } # Audio channel routing/removing/adding filter audio_channels_func() { audroute[$i]=$(get_selection_func "Track $i: Would you like to add/remove/route Audio channels? [y/N]: ") if [ "${audroute[$i]}" = "y" ]; then printf "Track $i: Specify the Audio channels filter parameters [press 'Enter' to skip]: " read audchanparams[$i] if [ ! -z "${audchanparams[$i]}" ]; then audchannels[$i]="channels=${audchanparams[$i]}," fi fi } # Audio channels decode function audio_channels_decode_func() { case "${audiocodec[$i]}" in ac3|aac|neroaac|vorbis|flac|pcm|"") chan[$i]=$(get_selection_func "Track $i: Would you like to decode/output more than 2 Audio Channels? [y/N]: ") if [ "${chan[$i]}" = "y" ]; then printf "Track $i: How many channels to decode/output? [2/4/6/8 - default is 2]: " read chanuse[$i] if [ -z "${chanuse[$i]}" ]; then channels[$i]="-channels 2" else channels[$i]="-channels ${chanuse[$i]}" fi if [ "${aacprof[$i]}" = "-hev2" ]; then if [ "$(echo ${channels[$i]} | awk '{print $2}')" != "2" ]; then echo green "-> HE-AACv2 only supports stereo!" green "-> Forcing stereo output decoding" echo channels[$i]="-channels 2" fi fi fi ;; copy) case "$source" in dvd) copychans[$i]="6" ;; *) copychans[$i]="2" ;; esac printf "Track $i: How many channels to copy? [2/4/6/8 - default is ${copychans[$i]}]: " read chancopy[$i] if [ -z "${chancopy[$i]}" ]; then channels[$i]="-channels ${copychans[$i]}" else channels[$i]="-channels ${chancopy[$i]}" fi ;; esac } neroaac_hev2_func() { if [ "${aacprof[$i]}" = "-hev2" ]; then if [ -z "${channels[$i]}" ]; then channels[$i]="-channels 2" fi fi } # Global function for calling # the above audio filters audio_filters_func() { aud_filters_func() { case "${audiocodec[$i]}" in mp3) test "$ALLOW_AUD_CHANNELS" = "y" && audio_channels_func test "$ALLOW_AUD_PAN" = "y" && audio_pan_func test "$ALLOW_AUD_EQUALIZER" = "y" && audio_equalizer_func ;; *) test "$ALLOW_AUD_CHANNELS" = "y" && audio_channels_func test "$ALLOW_AUD_PAN" = "y" && audio_pan_func test "$ALLOW_AUD_EQUALIZER" = "y" && audio_equalizer_func test "$ALLOW_AUD_NORMALIZE" = "y" && audio_volnorm_func test "$ALLOW_AUD_VOLUME" = "y" && audio_volume_func ;; esac } if [ "$ALLOW_AUD_CHANNELS" = "y" -o "$ALLOW_AUD_PAN" = "y" -o "$ALLOW_AUD_NORMALIZE" = "y" \ -o "$ALLOW_AUD_VOLUME" = "y" -o "$ALLOW_AUD_RESAMPLE" = "y" -o "$ALLOW_AUD_EQUALIZER" = "y" ]; then use_audfilters[$i]=$(get_selection_func "Track $i: Would you like to use Audio filters? [y/N]: ") if [ "${use_audfilters[$i]}" = "y" ]; then case "$1" in fl|flhq|ag1|ag1hq|ipc|ipchq|ip|iphq|iph|iphhq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq|ps3|ps3hq|mz|mzhq|mx|mxhq) # Resampling is skipped here. See the # audio_filters_var_func function below # for resampling for these presets aud_filters_func ;; *) aud_filters_func test "$ALLOW_AUD_RESAMPLE" = "y" && audio_resample_func ;; esac fi fi } audio_filters_var_func() { case "$1" in fl|flhq) afilters[$i]="${volnorm[$i]}${volume[$i]}${pan[$i]}${audchannels[$i]}${audeq[$i]},lavcresample=22050:16:1 -srate 22050" channels[$i]="-channels 2" ;; qt|qthq) afilters[$i]="${volnorm[$i]}${volume[$i]}${pan[$i]}${audchannels[$i]}${audeq[$i]}${resample[$i]}" channels[$i]="-channels 2" ;; ag1|ag1hq|ipc|ipchq|ip|iphq|iph|iphhq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|psp|psphq|mz|mzhq|mx|mxhq) afilters[$i]="${volnorm[$i]}${volume[$i]}${pan[$i]}${audchannels[$i]}${audeq[$i]},lavcresample=48000:16:1 -srate 48000" channels[$i]="-channels 2" ;; ps3|ps3hq) afilters[$i]="${volnorm[$i]}${volume[$i]}${pan[$i]}${audchannels[$i]}${audeq[$i]},lavcresample=48000:16:1 -srate 48000" ;; nks60|nks60hq) afilters[$i]="${volnorm[$i]}${volume[$i]}${pan[$i]}${audchannels[$i]}${audeq[$i]},lavcresample=44100:16:1 -srate 44100" channels[$i]="-channels 2" ;; *) afilters[$i]="${volnorm[$i]}${volume[$i]}${pan[$i]}${audchannels[$i]}${audeq[$i]}${resample[$i]}" ;; esac } audio_stream_copy_func() { case "$source" in dir) case "${audiocodec[1]}" in copy) echo error "-> Audio stream copy is not recommended with" error " directory batch encoding if you are going" error " to remux the encodes to MKV/MP4/TS/OGM" echo ;; esac ;; esac } track_echo_func() { if [ "${TRACKID[2]}" = "yes" -o "${TRACKID[3]}" = "yes" ]; then echo fi } select_audio_codec_func() { for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "$1" in qt|qthq|iph|iphhq|fl|flhq) echo printf "Track $i: Select the Audio Codec [AAC/neroAAC/AAC+/NOSOUND - default is AAC]: " ;; ag1|ag1hq|ipc|ipchq|ip|iphq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq|mx|mxhq) echo printf "Track $i: Select the Audio Codec [AAC/neroAAC/NOSOUND - default is AAC]: " ;; bd40|bdhq40|bd41|bdhq41|avchd|avchdhq) echo printf "Track $i: Select the Audio Codec [AC3/COPY/NOSOUND - default is AC3]: " ;; ps3|ps3hq) echo printf "Track $i: Select the Audio Codec [AAC/neroAAC/COPY/NOSOUND - default is AAC]: " ;; mz|mzhq) echo printf "Track $i: Select the Audio Codec [MP3/AAC/neroAAC/NOSOUND - default is AAC]: " ;; *) printf "Track $i: Select the Audio Codec [default is AAC]: " ;; esac read audiocodec[$i] audiocodec[$i]="$(echo ${audiocodec[$i]} | tr '[:upper:]' '[:lower:]')" check_audio_codec_func audio_stream_copy_func fi done track_echo_func } # Call the audio functions above. # Order is important here and the # correct way to call the functions # is as follows: # # *_audio_func # audio_channels_decode_func # audio_filters_func # audio_filters_var_func # track_echo_func case "$3" in qt|qthq|iph|iphhq|fl|flhq) select_audio_codec_func $3 for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in aac|"") aac_audio_func $3 audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; neroaac) neroaac_audio_func neroaac_hev2_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; aac+) aacplus_audio_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; nosound) acodec[$i]="-nosound" aid[$i]= ;; *) error "-> Unknown audio codec" rmtemp ;; esac fi done ;; ag1|ag1hq|ipc|ipchq|ip|iphq|atv|atvhq|ar|arhq|ar5|ar5hq|bb|bbhq|nks60|nks60hq|psp|psphq|mx|mxhq) select_audio_codec_func $3 for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in aac|"") aac_audio_func $3 audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; neroaac) neroaac_audio_func $3 audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; nosound) acodec[$i]="-nosound" aid[$i]= ;; *) error "-> Unknown audio codec" rmtemp ;; esac fi done ;; bd40|bdhq40|bd41|bdhq41|avchd|avchdhq) select_audio_codec_func $3 for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in ac3|"") audiocodec[$i]=ac3 ac3_audio_func audio_channels_decode_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; copy) audio_channels_decode_func track_echo_func acodec[$i]="-oac copy" ;; nosound) acodec[$i]="-nosound" aid[$i]= ;; *) error "-> Unknown audio codec" rmtemp ;; esac fi done ;; ps3|ps3hq) select_audio_codec_func $3 for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in aac|"") aac_audio_func $3 audio_channels_decode_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; neroaac) neroaac_audio_func $3 audio_channels_decode_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; copy) audio_channels_decode_func acodec[$i]="-oac copy" ;; nosound) acodec[$i]="-nosound" aid[$i]= ;; *) error "-> Unknown audio codec" rmtemp ;; esac fi done ;; mz|mzhq) select_audio_codec_func $3 for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in mp3) mp3_audio_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; aac|"") aac_audio_func $3 audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; neroaac) neroaac_audio_func $3 audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; nosound) acodec[$i]="-nosound" aid[$i]= ;; *) error "-> Unknown audio codec" rmtemp ;; esac fi done ;; *) echo brown "Available Audio Codecs" brown "~~~~~~~~~~~~~~~~~~~~~~" echo "MP3 -----> Container support: AVI, MKV, MP4, OGM, TS" echo "AC3 -----> Container support: AVI, MKV, MP4, OGM, TS" echo "AAC -----> Container support: MKV, MP4, TS" echo "AAC+ ----> Container support: MP4, MKV" echo "neroAAC -> Container support: MP4, MKV" echo "VORBIS --> Container support: MP4, MKV, OGM" echo "FLAC ----> Container support: MKV" echo "PCM -----> Container support: AVI, MKV, OGM" echo "COPY ----> Container support: Depends on audio codec" echo "NOSOUND -> Container support: AVI, MKV, MP4, OGM, TS" echo select_audio_codec_func $3 for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in mp3) mp3_audio_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; ac3) ac3_audio_func audio_channels_decode_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; aac|"") aac_audio_func audio_channels_decode_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; aac+) aacplus_audio_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; neroaac) neroaac_audio_func audio_channels_decode_func neroaac_hev2_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; vorbis) vorbis_audio_func audio_channels_decode_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; flac) flac_audio_func audio_channels_decode_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func ;; pcm) for t in {2..3}; do if [ "${TRACKID[$t]}" = "yes" ]; then error "-> Track $t: PCM audio not supported yet!" rmtemp fi done audio_channels_decode_func audio_filters_func $3 audio_filters_var_func $3 track_echo_func acodec[$i]="-oac pcm" ;; copy) audio_channels_decode_func track_echo_func acodec[$i]="-oac copy" ;; nosound) acodec[$i]="-nosound" aid[$i]= ;; *) error "-> Track $i: Unknown audio codec: '${audiocodec[$i]}'" rmtemp ;; esac fi done ;; esac echo "" brown "+=============================+" brown "| Miscellaneous Configuration |" brown "+=============================+" echo "" # AAC VBR not supported case "$SKIPBTRCALC" in yes) false ;; *) case "$1" in -[1-3]p) case "${audiocodec[1]}" in mp3|ac3|aac|aac+|neroaac|vorbis|pcm|copy|nosound|"") calcvidbit=$(get_selection_func "Would you like to set a target file size? [y/N]: ") if [ "$calcvidbit" = "y" ]; then echo "" brown "Video Bitrate Calculation/Target File Size" brown "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "h264enc can calculate the video bitrate for you" echo "based on the video length, chosen audio bitrate and" echo "target file size. The only thing you have to provide" echo "here is the desired target size in Mebibytes for the" echo "encode. After that, you can choose to keep the bitrate" echo "calculated by h264enc, or you can provide a new one." echo "" printf "Specify the desired Target File Size in Mebibytes [default is 700]: " read tfsm if [ -z "$tfsm" ]; then TARGET_SIZE=700 else TARGET_SIZE=$tfsm fi # Get the chosen audio bitrate for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in ac3) AUDIO_BITRATE[$i]=${abitrate[$i]} ;; mp3) case "${mp3mode[$i]}" in a*|A*|c*|C*|"") AUDIO_BITRATE[$i]=$(echo ${abitrate[$i]} | awk -F= '{print $2}') ;; v*|V*) # Use 10 kbps lesser compared # to the LAME specs case "${abitrate[$i]}" in q=0) AUDIO_BITRATE[$i]=230 ;; q=1) AUDIO_BITRATE[$i]=200 ;; q=2) AUDIO_BITRATE[$i]=180 ;; q=3) AUDIO_BITRATE[$i]=165 ;; q=4) AUDIO_BITRATE[$i]=155 ;; q=5) AUDIO_BITRATE[$i]=120 ;; q=6) AUDIO_BITRATE[$i]=105 ;; q=7) AUDIO_BITRATE[$i]=90 ;; q=8) AUDIO_BITRATE[$i]=75 ;; q=9) AUDIO_BITRATE[$i]=54 ;; esac ;; p*|P*) case "${mp3preset[$i]}" in 0|"") AUDIO_BITRATE[$i]=160 ;; 1) AUDIO_BITRATE[$i]=185 ;; 2) AUDIO_BITRATE[$i]=210 ;; 3) AUDIO_BITRATE[$i]=320 ;; esac ;; esac ;; aac|"") AUDIO_BITRATE[$i]=$(echo ${br[$i]} | awk '{print $2}') ;; aac+) AUDIO_BITRATE[$i]=${aacplusbr[$i]} ;; neroaac) AUDIO_BITRATE[$i]=$(($(echo ${neroaacbr[$i]} | awk '{print $2}')/1000)) ;; vorbis) case "${vorbmode[$i]}" in a*|A*) AUDIO_BITRATE[$i]=$(echo ${vorbq[$i]} | awk '{print $2}') ;; v*|V*|"") # Quality values -> bitrate mappings case "$(echo ${vorbq[$i]} | awk '{print $2}')" in -1) AUDIO_BITRATE[$i]=45 ;; 0) AUDIO_BITRATE[$i]=64 ;; 1) AUDIO_BITRATE[$i]=80 ;; 2) AUDIO_BITRATE[$i]=96 ;; 3) AUDIO_BITRATE[$i]=112 ;; 4) AUDIO_BITRATE[$i]=128 ;; 5) AUDIO_BITRATE[$i]=160 ;; 6) AUDIO_BITRATE[$i]=192 ;; 7) AUDIO_BITRATE[$i]=224 ;; 8) AUDIO_BITRATE[$i]=256 ;; 9) AUDIO_BITRATE[$i]=320 ;; 10) AUDIO_BITRATE[$i]=500 ;; esac ;; esac ;; pcm) # Get channels info. Resampling is not # taken into account so we assume 48 kHz case "$(echo ${channels[$i]} | awk '{print $2}')" in 2|""|*) AUDIO_BITRATE[$i]=1536 ;; 4) AUDIO_BITRATE[$i]=3072 ;; 5) AUDIO_BITRATE[$i]=3840 ;; 6) AUDIO_BITRATE[$i]=4608 ;; esac ;; copy) $MPLAYER "$sourcetype" $device $MPLAYEROPTS ${aid[$i]} -identify -vo null -frames 1 -nocache 2>/dev/null > "$TEMPDIR/copybitrate$i" AUDIO_BITRATE[$i]=$(echo $(($(grep '^ID_AUDIO_BITRATE' "$TEMPDIR/copybitrate$i" | tail -n 1 | awk -F= '{print $2}')/1000)) | awk -F. '{print $1}') rm -f "$TEMPDIR/copybitrate$i" ;; nosound) AUDIO_BITRATE[$i]=0 ;; esac fi done if [ ! -z "${aid[2]}" -a ! -z "${aid[3]}" ]; then AUDBTR=$((${AUDIO_BITRATE[1]}+${AUDIO_BITRATE[2]}+${AUDIO_BITRATE[3]})) BTRINFO="(${AUDIO_BITRATE[1]} kbps + ${AUDIO_BITRATE[2]} kbps + ${AUDIO_BITRATE[3]} kbps)" elif [ ! -z "${aid[2]}" -a -z "${aid[3]}" ]; then AUDBTR=$((${AUDIO_BITRATE[1]}+${AUDIO_BITRATE[2]})) BTRINFO="(${AUDIO_BITRATE[1]} kbps + ${AUDIO_BITRATE[2]} kbps)" elif [ -z "${aid[2]}" -a ! -z "${aid[3]}" ]; then AUDBTR=$((${AUDIO_BITRATE[1]}+${AUDIO_BITRATE[3]})) BTRINFO="(${AUDIO_BITRATE[1]} kbps + ${AUDIO_BITRATE[3]} kbps)" else AUDBTR=${AUDIO_BITRATE[1]} fi echo "" brown "Available Formulas" brown "~~~~~~~~~~~~~~~~~~" echo "0 -> MeGUI formula" echo "1 -> h264enc's refactored MeGUI formula" echo "2 -> h264enc/ripdvd old formula" echo "3 -> Use a custom factor value" echo "" printf "Which formula to use? [default is 0]: " read formula case "$formula" in 0|"") FACTOR="0.125" ;; 1) FACTOR="0.1244" ;; 2) FACTOR= ;; 3) echo brown "Custom Factor Value" brown "~~~~~~~~~~~~~~~~~~~" echo "You can provide a custom factor value which is" echo "used to adjust the formula's bitrate calculation." echo "Lower factor values result in higher bitrates while" echo "higher factor values result in lower bitrates. The" echo "default factor is that of the MeGUI formula, which" echo "is 0.125. The factor of h264enc's refactored MeGUI" echo "formula is 0.1244 resulting in roughly 10 kbps higher" echo "bitrate, thus increasing the final file size by a few" echo "Megabytes. A factor of 0.127 for example, will result" echo "in a bitrate of ~20 kbps less that the default factor" echo "of 0.125" echo printf "Provide the Factor value [default is 0.125 (MeGUI's factor)]: " read customfactor if [ -z "$customfactor" ]; then FACTOR="0.125" else FACTOR="$customfactor" fi ;; *) error "-> Unknown option: '$formula'" rmtemp ;; esac echo "" green "-> Detecting video length..." $MPLAYER "$sourcetype" $device $vid $MPLAYEROPTS -demuxer lavf -identify -vo null -frames 1 -ao null -nocache 2>/dev/null > "$TEMPDIR/videoinfo" VIDEO_LENGTH=$(grep "^ID_LENGTH" "$TEMPDIR/videoinfo" | awk -F= '{print $2}') rm -f "$TEMPDIR/videoinfo" if [ -z "$VIDEO_LENGTH" ]; then echo green "-> Could not detect the video length!" green "-> Skipping video bitrate calculation!" echo else if [ ! -z "$ofps" ]; then FRAMES=$(echo "scale=0; $VIDEO_LENGTH * $(echo "$ofps" | awk '{print $2}')" | $BC -l | awk -F. '{print $1}') else FRAMES=$(echo "scale=0; $VIDEO_LENGTH * $GETFPS" | $BC -l | awk -F. '{print $1}') fi case "$formula" in 0|1|3|"") VBITRATE=$(echo "scale=0; ($TARGET_SIZE * 1024 * 1024 - $FRAMES * 24 - $AUDBTR * 1000 * $VIDEO_LENGTH * $FACTOR) / ($VIDEO_LENGTH * $FACTOR) / 1000" | $BC -l) ;; 2) VBITRATE=$(echo "scale=0; ($TARGET_SIZE * 8192 / $VIDEO_LENGTH) - $AUDBTR" | $BC -l) ;; esac bits_per_pixel_func bits_per_block_func green "-> Video length is $(echo "scale=2; $VIDEO_LENGTH / 60" | $BC -l) minutes or $VIDEO_LENGTH seconds" green "-> Number of frames: $FRAMES" green "-> Chosen/detected audio bitrate is $AUDBTR kbps $BTRINFO" echo green "-> Estimated video bitrate for $TARGET_SIZE MiB: $VBITRATE kbps" green "-> Bits Per Pixel value: $BPP bpp" green "-> Bits Per Block value: $BPB bpb" echo printf "Specify the new video bitrate in kbps [default is $VBITRATE]: " read new_vbitrate if [ -z "$new_vbitrate" ]; then bitrate="bitrate=$VBITRATE" else bitrate="bitrate=$new_vbitrate" fi fi fi ;; esac ;; esac ;; esac ############################################################### ################# MEncoder configuration ###################### ############################################################### # Audio/video filters variables for all # passes. Since all filters are the same in # each pass, we put them in a single # variable to reduce code duplication and # filter maintenance. # # The softskip filter should come after filters # which need to see duplicate or skipped frames # in order to operate correctly. This includes any # filter that does temporal processing, like the # temporal denoiser, hqdn3d/denoise3d and all the # inverse telecine filters. The softskip filter # should also come before scaling so that the scale # filter will be skipped if a frame is going to be # dropped. Deinterlacing or pullup should be done # before cropping but it can also be done after it # (it's faster that way too) and since I don't want to # maintain two filter chains, one for when tfields is # used and one when it isn't, we'll always deinterlace # after cropping. The harddup filter should be placed # before the telecine one so that duplicate frames will # never get telecined, we don't want that. The interlace # filters should be placed after the softskip and scale # filters and after the harddup filter so that duplicate # frames will never get interlaced. The (un)sharp mask / # gaussian blur filter should come after the scale filter. # The 'tfields' filter should come after the crop filter # as it alters the resolution and MEncoder will error out # with a "crop area outside of the original" message. # # Video filters chain videofilters="-vf $(echo $ivtcfilter$delogofilter$cropfilter$deintfilter$fpsfilter$ild$deblockfilter$denoisefilter$debandfilter$ili$brightnessfilter$colorspacefilter,softskip,$dsizefilter$expandfilter_bfr$scale$isws$swsparam$expandfilter_afr$noisefilter$unsharpfilter$eq2filter,harddup$intfilter$telecinefilter | sed 's|^,||; s|,,|,|g; s|,$||')" # Audio filters chain for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then if [ ! -z "${afilters[$i]}" ]; then audiofilters[$i]="-af $(echo ${afilters[$i]} | sed 's|^,||; s|,,|,|g; s|,$||')" fi fi done # Dump first sub during the first pass case "$1" in -1p|-qp|-crf) if [ ! -z "${vobsubout[1]}" ]; then menc_subtitle="${subtitle[1]} ${vobsubout[1]}" else menc_subtitle="${subtitle[1]}" fi ;; -[2-3]p) if [ ! -z "${vobsubout[1]}" ]; then menc_subtitle="${subtitle[1]} ${vobsubout[1]}" menc_hardsub="-nosub" else menc_subtitle="${subtitle[1]}" menc_hardsub="${subtitle[1]}" fi # Log file for 2- and 3-pass case "$source" in dir) PASSLOG="-passlogfile \"$TEMPDIR/\${i%.*}.log\"" ;; *) PASSLOG="-passlogfile \"$TEMPDIR/$(basename "${OUTPUT%.*}.log")\"" ;; esac ;; esac # MEncoder options case "$source" in dvd|vcd) if [ ! -z "$($MPLAYER -vc help 2>/dev/null | grep 'libmpeg2')" ]; then MPEGVC="-vc mpeg12" fi ;; esac mencoder_opts() { case "$1" in -1p|-crf|-qp) pass_output1="-o \"$OUTPUT\"" ;; -2p) passopt1="pass=1:turbo=2:"; passopt2="pass=2:"; pass_output1="-o /dev/null"; pass_output2="-o \"$OUTPUT\"" ;; -3p) passopt1="pass=1:turbo=2:"; passopt2="pass=3:"; pass_output1="-o /dev/null"; pass_output2="-o /dev/null" ;; esac # Pass one echo "$priority_level $MENCODER \"$sourcetype\" $pass_output1 $PASSLOG $MPEGVC $device $vid $chapters $dvdangle $nosub $menc_subtitle $fps $ofps $videofilters $field_dominance $aspect $sws \ ${aid[1]} ${audiofilters[1]} ${channels[1]} ${acodec[1]} -ovc x264 -x264encopts $passopt1$bitrate$interlaced$cqm$x264params $quiet" case "$1" in -[2-3]p) echo # Pass two echo "$priority_level $MENCODER \"$sourcetype\" $pass_output2 $PASSLOG $MPEGVC $device $vid $chapters $dvdangle $nosub $menc_hardsub $fps $ofps $videofilters $field_dominance $aspect $sws \ ${aid[1]} ${audiofilters[1]} ${channels[1]} ${acodec[1]} -ovc x264 -x264encopts $passopt2$bitrate$interlaced$cqm$x264params $quiet" case "$1" in -3p) echo # Pass three echo "$priority_level $MENCODER \"$sourcetype\" -o \"$OUTPUT\" $PASSLOG $MPEGVC $device $vid $chapters $dvdangle $nosub $menc_hardsub $fps $ofps $videofilters $field_dominance $aspect $sws \ ${aid[1]} ${audiofilters[1]} ${channels[1]} ${acodec[1]} -ovc x264 -x264encopts $passopt2$bitrate$interlaced$cqm$x264params $quiet" ;; esac ;; esac } # Export the MEncoder parameters to file(s) # These files will be used to execute MEncoder # with its parameters. H264_1PFQ="$TEMPDIR/pass1_crfqp" H264_2P1="$TEMPDIR/pass1" H264_2P2="$TEMPDIR/pass2" H264_2P3="$TEMPDIR/pass3" case "$source" in dir) BATCH="$H264ENCDIR/batch$$" echo "#!/bin/bash" > "$BATCH" echo "# Automatically generated batch file by h264enc $version on $(date)" >> "$BATCH" echo "" >> "$BATCH" chmod 755 "$BATCH" echo "################### START OF COMMANDS ###################" >> "$BATCH" echo "" >> "$BATCH" echo "cd \"$(dirname "$sourcetype")\"" >> "$BATCH" echo "test -d \"$(dirname "$OUTPUT")\" || mkdir -p \"$(dirname "$OUTPUT")\"" >> "$BATCH" echo "" >> "$BATCH" echo "for i in *; do" >> "$BATCH" echo "" >> "$BATCH" echo "if [ -f \"\$i\" ]; then" >> "$BATCH" echo "" >> "$BATCH" echo "test -d \"$TEMPDIR\" || mkdir -p \"$TEMPDIR\"" >> "$BATCH" echo "" >> "$BATCH" echo "echo" >> "$BATCH" echo "echo -e \"\e[1;32m-> Processing file '$(dirname "$sourcetype")/\$i'\e[0;39;49m\"" >> "$BATCH" echo "echo" >> "$BATCH" echo "sleep 3" >> "$BATCH" echo "" >> "$BATCH" echo "$(mencoder_opts $1 | sed "s|$sourcetype|\$i|g")" >> "$BATCH" echo "" >> "$BATCH" ;; *) case "$1" in -1p|-qp|-crf) mencoder_opts $1 > "$H264_1PFQ" ;; -2p) mencoder_opts $1 > "$TEMPDIR/h264enc_2pass" # Split 2pass file # into two files cat "$TEMPDIR/h264enc_2pass" | head -n 1 > "$H264_2P1" cat "$TEMPDIR/h264enc_2pass" | tail -n 1 > "$H264_2P2" rm -f "$TEMPDIR/h264enc_2pass" ;; -3p) mencoder_opts $1 > "$TEMPDIR/h264enc_3pass" # Split 3pass file # into three files cat "$TEMPDIR/h264enc_3pass" | head -n 1 > "$H264_2P1" cat "$TEMPDIR/h264enc_3pass" | head -n 3 | tail -n 1 > "$H264_2P2" cat "$TEMPDIR/h264enc_3pass" | tail -n 1 > "$H264_2P3" rm -f "$TEMPDIR/h264enc_3pass" ;; esac ;; esac # Display the options before encoding. # This was a request from a few users :) # Currently, there's no way how to modify # these options if the user wants it case "$source" in file|dvd|vcd) inspect=$(get_selection_func "Would you like to inspect the MEncoder options? [y/N]: ") if [ "$inspect" = "y" ]; then echo "" brown "+===========================+" brown "| MEncoder encoding options |" brown "+===========================+" echo "" case "$1" in -1p|-qp|-crf) echo $(cat $H264_1PFQ) ;; -2p) brown "First pass options" brown "~~~~~~~~~~~~~~~~~~" echo $(cat $H264_2P1) echo "" brown "Second pass options" brown "~~~~~~~~~~~~~~~~~~~" echo $(cat $H264_2P2) ;; -3p) brown "First pass options" brown "~~~~~~~~~~~~~~~~~~" echo $(cat $H264_2P1) echo "" brown "Second pass options" brown "~~~~~~~~~~~~~~~~~~~" echo $(cat $H264_2P2) echo "" brown "Third pass options" brown "~~~~~~~~~~~~~~~~~~" echo $(cat $H264_2P3) ;; esac echo "" fi ;; esac # Encode a sample if [ "$ALLOW_SAMPLE_ENCODING" = "y" ]; then case "$source" in file|dvd|vcd) sample=$(get_selection_func "Would you like to encode a Sample? [y/N]: ") if [ "$sample" = "y" ]; then printf "Specify the start position in hour:min:sec [default is 0:02:00]: " read sample_startpos if [ -z "$sample_startpos" ]; then samplepos="-ss 0:02:00" else samplepos="-ss $sample_startpos" fi printf "Specify the duration in seconds for the sample [default is 30]: " read sample_duration if [ -z "$sample_duration" ]; then sampledur="-endpos 30" else sampledur="-endpos $sample_duration" fi echo green "-> Encoding sample, please wait..." test -e $HOME/sample_$$.avi && mv -f $HOME/sample_$$.avi $HOME/sample_$$.avi.old case "$1" in -1p|-qp|-crf) cat "$H264_1PFQ" | sed -e "s|$MENCODER|$MENCODER $samplepos $sampledur|" -e "s|\"$OUTPUT\"|$HOME/sample_$$.avi|" > "$TEMPDIR/sampleopts1" ;; -2p) cat "$H264_2P1" | sed "s|$MENCODER|$MENCODER $samplepos $sampledur|" > "$TEMPDIR/sampleopts1" cat "$H264_2P2" | sed -e "s|$MENCODER|$MENCODER $samplepos $sampledur|" -e "s|\"$OUTPUT\"|$HOME/sample_$$.avi|" > "$TEMPDIR/sampleopts2" ;; -3p) cat "$H264_2P1" | sed "s|$MENCODER|$MENCODER $samplepos $sampledur|" > "$TEMPDIR/sampleopts1" cat "$H264_2P2" | sed "s|$MENCODER|$MENCODER $samplepos $sampledur|" > "$TEMPDIR/sampleopts2" cat "$H264_2P3" | sed -e "s|$MENCODER|$MENCODER $samplepos $sampledur|" -e "s|\"$OUTPUT\"|$HOME/sample_$$.avi|" > "$TEMPDIR/sampleopts3" ;; esac for i in {1..3}; do if [ -f "$TEMPDIR/sampleopts$i" ]; then green "-> Running pass $i..." source "$TEMPDIR/sampleopts$i" >/dev/null 2>&1 green "-> Done" fi done for i in sampleopts* *.log *.mbtree; do rm -f "$TEMPDIR/$i" done # Remove subs if any test -e "${IDXFILE[1]}" && rm -f "${IDXFILE[1]}" "${SUBFILE[1]}" if [ -e "$HOME/sample_$$.avi" ]; then green "-> Previewing..." sleep 1 $MPLAYER $MPLAYEROPTS -nocache "$HOME/sample_$$.avi" >/dev/null 2>&1 else error "-> Failed" fi echo fi ;; esac fi # Export the MEncoder parameters to an # options file. Useful for inspection # of the parameters or for batch encoding. case "$source" in file|dvd|vcd) saveopts=$(get_selection_func "Would you like to save the MEncoder options to a file? [y/N]: ") if [ "$saveopts" = "y" ]; then printf "Where to store the options? [default is $HOME/batchfile]: " read -e storeopts if [ -z "$storeopts" ]; then OPTSFILE="$HOME/batchfile" else if [ -z "$(echo "$storeopts" | grep '^/')" ]; then echo "" green "-> You have to provide the full path!" green "-> Using default file: $HOME/batchfile" echo "" OPTSFILE="$HOME/batchfile" else OPTSFILE="$storeopts" fi fi CMDSTART="################### START OF COMMANDS ###################" DIRTEST="test -d \"$(dirname "$OUTPUT")\" || mkdir -p \"$(dirname "$OUTPUT")\"" CONFTEST="test -d \"$TEMPDIR\" || mkdir -p \"$TEMPDIR\"" FILETEST="test -e \"$OUTPUT\" && mv -f \"$OUTPUT\" \"$OUTPUT.old\"" # Dump the second and/or third # subtitle if selected case "${audiocodec[1]}" in nosound) audfmt="-nosound" ;; *) audfmt="-oac pcm" ;; esac if [ ! -z "${subtitle[2]}" ]; then SUB2="$MENCODER $sourcetype $device $MPEGVC $chapters $ofps ${subtitle[2]} ${vobsubout[2]} ${aid[1]} $audfmt -ovc copy -o /dev/null" fi if [ ! -z "${subtitle[3]}" ]; then SUB3="$MENCODER $sourcetype $device $MPEGVC $chapters $ofps ${subtitle[3]} ${vobsubout[3]} ${aid[1]} $audfmt -ovc copy -o /dev/null" fi # Write out... if [ -e "$OPTSFILE" ]; then if [ -z "$(grep '^#!/bin/bash' "$OPTSFILE")" ]; then mv -f "$OPTSFILE" "$OPTSFILE$$" echo "#!/bin/bash" > "$OPTSFILE" echo "# Automatically generated by h264enc $version on $(date)" >> "$OPTSFILE" echo "" >> "$OPTSFILE" cat "$OPTSFILE$$" >> "$OPTSFILE" rm -f "$OPTSFILE$$" chmod 755 "$OPTSFILE" fi else echo "#!/bin/bash" > "$OPTSFILE" echo "# Automatically generated by h264enc $version on $(date)" >> "$OPTSFILE" echo "" >> "$OPTSFILE" chmod 755 "$OPTSFILE" fi echo "$CMDSTART" >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo "$DIRTEST" >> "$OPTSFILE" echo "$CONFTEST" >> "$OPTSFILE" echo "$FILETEST" >> "$OPTSFILE" echo "" >> "$OPTSFILE" case "$1" in -1p|-qp|-crf) echo $(cat $H264_1PFQ) >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo "$SUB2" >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo "$SUB3" >> "$OPTSFILE" echo "sleep 2" >> "$OPTSFILE" echo "" >> "$OPTSFILE" ;; -2p) echo $(cat $H264_2P1) >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo $(cat $H264_2P2) >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo "$SUB2" >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo "$SUB3" >> "$OPTSFILE" echo "sleep 2" >> "$OPTSFILE" echo "" >> "$OPTSFILE" ;; -3p) echo $(cat $H264_2P1) >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo $(cat $H264_2P2) >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo $(cat $H264_2P3) >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo "$SUB2" >> "$OPTSFILE" echo "" >> "$OPTSFILE" echo "$SUB3" >> "$OPTSFILE" echo "sleep 2" >> "$OPTSFILE" echo "" >> "$OPTSFILE" ;; esac fi ;; esac # Audio code for all audio tracks. Currently # we have to separate the code for the first # track from the 2nd & 3rd since if the user # selects to copy only one track from a DVD, # we'll get extra encoder options which the for # loop adds but which must *not* be there. # This approach results in a bit more code but # what the heck, maybe one day I'll fix it :) # # Nasty hack for ivtc/fps/deint filters. # Filter order is all wrong but who # cares at this point if [ ! -z "$ivtcfilter" ]; then vidfilter=",$(echo $ivtcfilter | sed 's|,$||')" fi if [ ! -z "$fpsfilter" ]; then vidfilter=",$(echo $fpsfilter | sed 's|,$||')" fi if [ "$deintmethod" = "0" ]; then vidfilter=",framestep=2" elif [ "$deintmethod" = "2" ]; then vidfilter=",yadif=3" fi vidfilteropts="-sws 1 -vf scale=16:16$vidfilter$intfilter$telecinefilter,softskip,harddup" vidcodecopts="-ovc lavc -lavcopts vcodec=mpeg2video" # For neroAAC, FAAC, AAC+, Vorbis and FLAC audio # $FIFO is used only once and is global # meaning it is used for all audio tracks # Workaround for multichan FAAC encoding. # FAAC somehow does not like multichan PCM # from MPlayer, but it does like it when one # treats it as raw. Nero has no issues, though. # Go figure case "${audiocodec[1]}" in aac|"") if [[ $(echo ${channels[1]} | awk '{print $2}') -gt 2 ]]; then if [ ! -z "${resample[1]}" ]; then FAACAUDRATE="${hertz[1]}" else FAACAUDRATE="$($MPLAYER "$sourcetype" $device $MPLAYEROPTS ${aid[1]} -vo null -identify -frames 1 -nocache 2>/dev/null | grep '^ID_AUDIO_RATE' | tail -n 1 | awk -F= '{print $2}')" fi faacparams="-P -X -B 16 -C $(echo ${channels[1]} | awk '{print $2}') -R $FAACAUDRATE" fi ;; esac mkfifo "$TEMPDIR/audio.wav" FIFO="test -p \"$TEMPDIR/audio.wav\" || mkfifo \"$TEMPDIR/audio.wav\"" MPL="$MPLAYER \"$OUTPUT\" $MPLAYEROPTS -really-quiet -vc null -vo null -nocache ${channels[1]} -ao pcm:fast:file=\"$TEMPDIR/audio.wav\"" NERO="$NEROAACENC -ignorelength ${neroaacbr[1]} -if \"$TEMPDIR/audio.wav\" -of \"$TEMPDIR/audio.aac\" &" AACPLUS="$AACPLUSENC \"$TEMPDIR/audio.wav\" \"$TEMPDIR/audio.aac\" ${aacplusbr[1]} &" OGG="$OGGENC ${vorbq[1]} \"$TEMPDIR/audio.wav\" -o \"$TEMPDIR/audio.ogg\" &" FLACENC="$FLAC ${flacq[1]} \"$TEMPDIR/audio.wav\" -o \"$TEMPDIR/audio.flac\" &" FAACENC="$FAAC -w --mpeg-vers 4 ${br[1]} ${tns[1]} $faacparams \"$TEMPDIR/audio.wav\" -o \"$TEMPDIR/audio.aac\" &" case "${audiocodec[1]}" in aac|aac+|neroaac|vorbis|flac|"") case "$source" in dir) AUDIOENC[1]="$BATCH" ;; *) AUDIOENC[1]="$TEMPDIR/audioenc1" ;; esac aud1_encoder_func() { echo "$FIFO" case "${audiocodec[1]}" in aac|"") echo "$FAACENC" ;; aac+) echo "$AACPLUS" ;; neroaac) echo "$NERO" ;; vorbis) echo "$OGG" ;; flac) echo "$FLACENC" ;; esac echo "$MPL" if [ "${nero2p[1]}" = "y" -o "${nero2p[1]}" = "Y" ]; then echo "sleep 2" echo "$MPL" fi echo "sleep 2" echo } aud1_encoder_func >> "${AUDIOENC[1]}" if [ "$saveopts" = "y" -o "$saveopts" = "Y" ]; then aud1_encoder_func >> "$OPTSFILE" fi ;; esac # Get the audio codec from the # input source when using audio # stream copy. Based on detected # audio codec, decision is made # if we allow certain containers case "${audiocodec[1]}" in copy) echo green "-> Track 1: Detecting audio codec..." AUDCODEC=$($MPLAYER "$sourcetype" $device $MPLAYEROPTS ${aid[1]} -vo null -frames 1 -identify -nocache 2>/dev/null | grep '^ID_AUDIO_CODEC' | tail -n 1 | awk -F= '{print $2}') case "$AUDCODEC" in *a52*|*ac3*) audiocodec[1]="ffac3"; detectaud[1]="AC3" ;; *eac3*) audiocodec[1]="ffeac3"; detectaud[1]="E-AC3" ;; *dca*|*dts*) audiocodec[1]="ffdts"; detectaud[1]="DTS" ;; *dvdpcm*) audiocodec[1]="unsupported"; detectaud[1]="LPCM" ;; *vorbis*) audiocodec[1]="ffvorbis"; detectaud[1]="Vorbis" ;; *pcm*) audiocodec[1]="ffpcm"; detectaud[1]="PCM" ;; *faad*|*aac*) audiocodec[1]="ffaac"; detectaud[1]="AAC" ;; *mp3*|*mad*) audiocodec[1]="ffmp3"; detectaud[1]="MP3" ;; *flac*) audiocodec[1]="ffflac"; detectaud[1]="FLAC" ;; *wma*) audiocodec[1]="unsupported"; detectaud[1]="WMA" ;; *|"") audiocodec[1]="unsupported"; detectaud[1]="unknown/unsupported" ;; esac green "-> Track 1: Detected ${detectaud[1]} audio" if [ "${audiocodec[1]}" = "unsupported" ]; then green "-> Skipping MKV/MP4/TS/OGM containers" fi ;; esac # Code for second/third DVD audio track for i in {2..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then # Set global variables case "${audiocodec[$i]}" in aac|"") if [[ $(echo ${channels[$i]} | awk '{print $2}') -gt 2 ]]; then if [ ! -z "${resample[$i]}" ]; then FAACAUDRATE[$i]="${hertz[$i]}" else FAACAUDRATE[$i]="$($MPLAYER "$sourcetype" $device $MPLAYEROPTS ${aid[$i]} -vo null -identify -frames 1 -nocache 2>/dev/null | grep '^ID_AUDIO_RATE' | tail -n 1 | awk -F= '{print $2}')" fi faacparams[$i]="-P -X -B 16 -C $(echo ${channels[$i]} | awk '{print $2}') -R ${FAACAUDRATE[$i]}" fi ;; esac AUDIOENC[$i]="$TEMPDIR/audioenc$i" NERO[$i]="$NEROAACENC -ignorelength ${neroaacbr[$i]} -if \"$TEMPDIR/audio.wav\" -of \"$TEMPDIR/audio$i.aac\" &" AACPLUS[$i]="$AACPLUSENC \"$TEMPDIR/audio.wav\" \"$TEMPDIR/audio$i.aac\" ${aacplusbr[$i]} &" OGG[$i]="$OGGENC ${vorbq[$i]} \"$TEMPDIR/audio.wav\" -o \"$TEMPDIR/audio$i.ogg\" &" FLACENC[$i]="$FLAC ${flacq[$i]} \"$TEMPDIR/audio.wav\" -o \"$TEMPDIR/audio$i.flac\" &" FAACENC[$i]="$FAAC -w --mpeg-vers 4 ${br[$i]} ${tns[$i]} ${faacparams[$i]} \"$TEMPDIR/audio.wav\" -o \"$TEMPDIR/audio$i.aac\" &" MPL[$i]="$MPLAYER \"$TEMPDIR/audio$i.avi\" $MPLAYEROPTS ${channels[$i]} ${audiofilters[$i]} -really-quiet -vc null -vo null -nocache -ao pcm:fast:file=\"$TEMPDIR/audio.wav\"" # Check for LPCM audio on DVDs AUDCODEC[$i]=$($MPLAYER $sourcetype $device $MPLAYEROPTS ${aid[$i]} -vo null -frames 1 -identify -nocache 2>/dev/null | grep '^ID_AUDIO_CODEC' | tail -n 1 | awk -F= '{print $2}') case "${AUDCODEC[$i]}" in *dvdpcm*) AUDCODECOPTS[$i]="-oac pcm" ;; *) AUDCODECOPTS[$i]="-oac copy" ;; esac # Identify audio codec of the DVD # for audio stream copy case "${audiocodec[$i]}" in copy) echo green "-> Track $i: Detecting audio codec..." case "${AUDCODEC[$i]}" in *a52*|*ac3*) audiocodec[$i]="ffac3"; detectaud[$i]="AC3" ;; *dca*|*dts*) audiocodec[$i]="ffdts"; detectaud[$i]="DTS" ;; *dvdpcm*) audiocodec[$i]="unsupported"; detectaud[$i]="LPCM" ;; *|"") audiocodec[$i]="unsupported"; detectaud[$i]="unknown/unsupported" ;; esac green "-> Track $i: Detected ${detectaud[$i]} audio" if [ "${audiocodec[$i]}" = "unsupported" ]; then green "-> Skipping track $i for the MKV/MP4/TS/OGM containers" fi ;; esac case "${audiocodec[$i]}" in mp3|ac3) MENC[$i]="$MENCODER $sourcetype $device $MPEGVC $chapters ${aid[$i]} ${channels[$i]} $fps $ofps ${acodec[$i]} ${audiofilters[$i]} $vidfilteropts $vidcodecopts -of rawaudio -o \"$TEMPDIR/audio$i.${audiocodec[$i]}\"" ;; ffac3|ffdts) MENC[$i]="$MENCODER $sourcetype $device $MPEGVC $chapters ${aid[$i]} ${channels[$i]} $fps $ofps $vidcodecopts $vidfilteropts -oac copy -of rawaudio -o \"$TEMPDIR/audio$i.raw\"" ;; aac|aac+|neroaac|vorbis|flac|"") MENC[$i]="$MENCODER $sourcetype $device $MPEGVC $chapters ${aid[$i]} ${channels[$i]} $fps $ofps $vidcodecopts $vidfilteropts ${AUDCODECOPTS[$i]} -o \"$TEMPDIR/audio$i.avi\"" ;; esac aud23_encoder_func() { case "${audiocodec[$i]}" in mp3|ac3|ffac3|ffdts) echo "$FIFO" echo "${MENC[$i]}" echo "sleep 2" ;; aac|aac+|neroaac|vorbis|flac|"") echo "$FIFO" echo "${MENC[$i]}" echo "sleep 2" echo case "${audiocodec[$i]}" in aac|"") echo "${FAACENC[$i]}" ;; aac+) echo "${AACPLUS[$i]}" ;; neroaac) echo "${NERO[$i]}" ;; vorbis) echo "${OGG[$i]}" ;; flac) echo "${FLACENC[$i]}" ;; esac echo "${MPL[$i]}" if [ "${nero2p[$i]}" = "y" -o "${nero2p[$i]}" = "Y" ]; then echo "sleep 2" echo "${MPL[$i]}" fi echo "sleep 2" ;; esac echo } aud23_encoder_func >> "${AUDIOENC[$i]}" if [ "$saveopts" = "y" -o "$saveopts" = "Y" ]; then aud23_encoder_func >> "$OPTSFILE" fi fi done test ! -z "${detectaud[*]}" && echo # Get audio channels info # Used for audio tagging for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then if [ ! -z "${channels[$i]}" ]; then case "$(echo "${channels[$i]}" | awk '{print $2}')" in 1) chaninfo[$i]="Mono" ;; 2) chaninfo[$i]="Stereo" ;; 3) chaninfo[$i]="3.0" ;; 4) chaninfo[$i]="4.0" ;; 5) chaninfo[$i]="5.0" ;; 6) chaninfo[$i]="5.1" ;; 7) chaninfo[$i]="6.1" ;; 8) chaninfo[$i]="7.1" ;; *) chaninfo[$i]="$(echo "${channels[$i]}" | awk '{print $2}')" ;; esac else chaninfo[$i]="Stereo" fi fi done # Ask user if he wants to convert # from AVI to Matroska container. if [ "$ALLOW_MKV_MUXING" = "y" ]; then case "${audiocodec[1]}" in mp3|ffmp3|aac|aac+|neroaac|ffaac|vorbis|ffvorbis|ac3|ffac3|ffeac3|ffdts|pcm|ffpcm|flac|ffflac|nosound|"") avi_mkv=$(get_selection_func "Would you like to convert the final encode from AVI to MKV? [y/N]: ") if [ "$avi_mkv" = "y" ]; then # Check for mkvmerge if [ ! -x "$MKVMERGE" ]; then avi_to_mkv=no echo "" green "-> Utility 'mkvmerge' is missing!" green "-> Skipping AVI to MKV conversion!" echo "" else avi_to_mkv=yes # Import of external subtitles. # Input type agnostic. Only # allow supported subtitle formats # by MKV. Others will be skipped for i in {1..3}; do if [ ! -z "${EXTSUB[$i]}" ]; then case "${EXTSUB[$i]##*.}" in idx|IDX|srt|SRT|ass|ASS|ssa|SSA) MKVSUBS="$MKVSUBS \"$(eval "echo \${EXTSUB[$i]}")\"" ;; *) echo green "-> Subtitle format '$(echo ${EXTSUB[$i]##*.} | tr '[:lower:]' '[:upper:]')' not supported by MKV!" green "-> Supported subtitle formats are: IDX, SRT, ASS/SSA" green "-> Skipping import of '${EXTSUB[$i]}'" echo ;; esac fi done case "$source" in file|dvd|vcd) # Set MKV title MKVTITLE="--title \"$(basename "${OUTPUT%.*}")\"" TRACKTITLE="--track-name 0:\"$(basename "${OUTPUT%.*}")\"" printf "Specify the Release Year of the content [press 'Enter' to skip]: " read mkvyear printf "Specify a Genre for the content [press 'Enter' to skip]: " read mkvgenre # Add cover printf "Provide a Cover file in jpeg/png format [press 'Enter' to skip]: " read -e mkvcover if [ ! -z "$mkvcover" ]; then if [ ! -f "$mkvcover" ]; then echo error "-> No such file: '$mkvcover'" error "-> Skipping embedding of cover file" echo else IMGTYPE="$(basename "${mkvcover##*.}" | tr '[:upper:]' '[:lower:]')" case "$IMGTYPE" in jpg|jpeg|png) MKVCOVER="--attachment-mime-type image/$(echo $IMGTYPE | sed 's|jpg|jpeg|') --attachment-name Cover --attach-file \"$mkvcover\"" ;; *) echo error "-> Image type not supported" error "-> Skipping embedding of cover file" echo ;; esac fi fi case "$source" in dvd) # DVD audio language for track 1 case "${audiocodec[1]}" in aac+|vorbis|flac) MKVAUDLANG1="--language 0:${AUDLANG[1]}" ;; *) MKVAUDLANG1="--language 1:${AUDLANG[1]}" ;; esac # DVD audio language for track 2 & 3 for i in {2..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then MKVAUDLANG[$i]="--language -1:${AUDLANG[$i]}" fi done # Chapters for MKV if [ "$chapexp" = "y" -o "$chapexp" = "Y" ]; then mkvimpchap=$(get_selection_func "Import chapters information into the MKV container? [y/N]: ") if [ "$mkvimpchap" = "y" ]; then MKVCHAPS="--chapters \"$CHAPTERSFILE\"" fi fi # DVD subs for MKV if [ ! -z "${vobsubout[1]}" -o ! -z "${vobsubout[2]}" -o ! -z "${vobsubout[3]}" ]; then mkvimpsub=$(get_selection_func "Import the ripped subtitle(s) into the MKV container? [y/N]: ") if [ "$mkvimpsub" = "y" ]; then for i in {1..3}; do [[ -z $(eval "echo \${IDXFILE[$i]}") ]] || MKVSUBS="$MKVSUBS \"$(eval "echo \${IDXFILE[$i]}")\"" done fi fi ;; esac ;; dir) MKVTITLE="--title \"\${i%.*}\"" TRACKTITLE="--track-name 0:\"\${i%.*}\"" ;; esac # Global tags mkvtags_func() { echo "" echo "" echo echo "" echo " " echo " " echo " Source" echo " $(echo $type | sed 's|s$||')" echo " " echo " " echo " Title" case "$source" in dir) echo " \${i%.*}" ;; *) echo " $(basename "${OUTPUT%.*}")" ;; esac echo " " if [ ! -z "$mkvyear" ]; then echo " " echo " Release Date" echo " $mkvyear" echo " " fi if [ ! -z "$mkvgenre" ]; then echo " " echo " Genre" echo " $mkvgenre" echo " " fi echo " " echo " Video Filters" echo " $(echo $videofilters | sed 's|^\-vf ||')" echo " " for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then if [ ! -z "${audiofilters[$i]}" ]; then echo " " echo " Audio Filters (Track $i)" echo " $(echo ${audiofilters[$i]} | sed 's|^\-af ||; s| \-srate.*||')" echo " " fi if [ "${audiocodec[$i]}" != "nosound" ]; then echo " " echo " Audio Codec (Track $i)" case "${audiocodec[$i]}" in aac|"") echo " LC-AAC ${chaninfo[$i]}" ;; neroaac) echo " ${AACTYPE[$i]} ${chaninfo[$i]}" ;; aac+) echo " HE-AACv1 ${chaninfo[$i]}" ;; vorbis) echo " Vorbis ${chaninfo[$i]}" ;; mp3) echo " MP3 ${chaninfo[$i]}" ;; ac3) echo " AC3 ${chaninfo[$i]}" ;; flac) echo " FLAC ${chaninfo[$i]}" ;; pcm) echo " PCM ${chaninfo[$i]}" ;; *) echo " ${detectaud[$i]} ${chaninfo[$i]}" ;; esac echo " " case "$source" in dvd) echo " " echo " Audio Language (Track $i)" echo " ${AUDLANG[$i]}" echo " " ;; esac fi fi done echo " " echo " Encoder" echo " $($MENCODER 2>/dev/null | head -n 1)" echo " " echo " " echo " x264 parameters" echo " $(mencoder_opts $1 | tail -n 1 | grep -o '\-x264encopts.*' | sed 's|\-x264encopts ||; s| ||g; s|2>/dev/null||')" echo " " echo " " echo " x264 version" echo " $($X264 --version | head -n 1 | awk '{print $2}')" echo " " echo " " echo " mkvmerge version" echo " $($MKVMERGE --version | awk '{print $2}' | sed 's|v||')" echo " " echo " " echo " h264enc parameters" echo " h264enc $@" echo " " echo " " echo " Comment" echo " Tagged by h264enc $version on $(date +%Y/%m/%d)" echo " " echo " " echo "" } MKVTAGS="--global-tags \"$TEMPDIR/mkvtags.xml\"" case "$source" in dir) DIRTAGS="echo \"$(mkvtags_func $@ | sed 's|\"|\\"|g')\" > \"$TEMPDIR/mkvtags.xml\"" ;; *) mkvtags_func $@ > "$TEMPDIR/mkvtags.xml" ;; esac # MKV audio & tagging for track 1 case "${audiocodec[1]}" in aac+) NOAUDIO="-A" TRACKNAME="$TRACKTITLE" MKVAUD1="--track-name 0:\"HE-AACv1 ${chaninfo[1]}\" $MKVAUDLANG1 --aac-is-sbr 0:1 \"$TEMPDIR/audio.aac\"" ;; neroaac) NOAUDIO="-A" TRACKNAME="$TRACKTITLE" case "${aacprof[1]}" in -he|-hev2) MKVSBR="--aac-is-sbr 1:1" ;; esac MKVAUD1="--track-name 1:\"${AACTYPE[1]} ${chaninfo[1]}\" $MKVAUDLANG1 $MKVSBR --no-chapters \"$TEMPDIR/audio.aac\"" ;; vorbis) NOAUDIO="-A" TRACKNAME="$TRACKTITLE" MKVAUD1="--track-name 0:\"Vorbis ${chaninfo[1]}\" $MKVAUDLANG1 \"$TEMPDIR/audio.ogg\"" ;; flac) NOAUDIO="-A" TRACKNAME="$TRACKTITLE" MKVAUD1="--track-name 0:\"FLAC ${chaninfo[1]}\" $MKVAUDLANG1 \"$TEMPDIR/audio.flac\"" ;; ffac3|ffeac3|ffdts|ffaac|ffvorbis|ffmp3|ffpcm|ffflac) TRACKNAME="$TRACKTITLE $MKVAUDLANG1 --track-name 1:\"${detectaud[1]} ${chaninfo[1]}\"" ;; aac|"") NOAUDIO="-A" TRACKNAME="$TRACKTITLE" MKVAUD1="--track-name 1:\"LC-AAC ${chaninfo[1]}\" $MKVAUDLANG1 --no-chapters \"$TEMPDIR/audio.aac\"" ;; mp3|ac3) TRACKNAME="$TRACKTITLE $MKVAUDLANG1 --track-name 1:\"$(echo ${audiocodec[1]} | tr '[:lower:]' '[:upper:]') ${chaninfo[1]}\"" ;; esac # MKV audio & tagging for track 2 & 3 for i in {2..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in # ffac3|ffdts is equivalent to # audio stream copy ffac3|ffdts) MKVAUD[$i]="--track-name -1:\"${detectaud[$i]} ${chaninfo[$i]}\" ${MKVAUDLANG[$i]} \"$TEMPDIR/audio$i.raw\"" ;; mp3|ac3) MKVAUD[$i]="--track-name -1:\"$(echo ${audiocodec[$i]} | tr '[:lower:]' '[:upper:]') ${chaninfo[$i]}\" ${MKVAUDLANG[$i]} \"$TEMPDIR/audio$i.${audiocodec[$i]}\"" ;; aac+) MKVAUD[$i]="--track-name -1:\"HE-AACv1 ${chaninfo[$i]}\" ${MKVAUDLANG[$i]} --aac-is-sbr 0:1 \"$TEMPDIR/audio$i.aac\"" ;; neroaac) case "${aacprof[$i]}" in -he|-hev2) MKVSBR[$i]="--aac-is-sbr 1:1" ;; esac MKVAUD[$i]="--track-name -1:\"${AACTYPE[$i]} ${chaninfo[$i]}\" ${MKVAUDLANG[$i]} ${MKVSBR[$i]} --no-chapters \"$TEMPDIR/audio$i.aac\"" ;; aac|"") MKVAUD[$i]="--track-name -1:\"LC-AAC ${chaninfo[$i]}\" ${MKVAUDLANG[$i]} --no-chapters \"$TEMPDIR/audio$i.aac\"" ;; vorbis) MKVAUD[$i]="--track-name -1:\"Vorbis ${chaninfo[$i]}\" ${MKVAUDLANG[$i]} \"$TEMPDIR/audio$i.ogg\"" ;; flac) MKVAUD[$i]="--track-name -1:\"FLAC ${chaninfo[$i]}\" ${MKVAUDLANG[$i]} \"$TEMPDIR/audio$i.flac\"" ;; esac fi done # Export commands to files case "$source" in dir) MKVOUT="$OUTPUTDIR/\${i%.*}.mkv" MKVMUXING="$BATCH" ;; *) MKVOUT="${OUTPUT%.*}.mkv" MKVMUXING="$TEMPDIR/mkvmuxing" ;; esac echo "$DIRTAGS" >> "$MKVMUXING" mkv_export_func() { echo "test -e \"$MKVOUT\" && mv -f \"$MKVOUT\" \"$MKVOUT.old\"" echo "$MKVMERGE $MKVCOVER $MKVTAGS $NOAUDIO $MKVTITLE $TRACKNAME \"$OUTPUT\" $MKVAUD1 ${MKVAUD[2]} ${MKVAUD[3]} $MKVSUBS $MKVCHAPS -o \"$MKVOUT\"" echo "sleep 2" echo } mkv_export_func >> "$MKVMUXING" if [ "$saveopts" = "y" -o "$saveopts" = "Y" ]; then echo "echo \"$(mkvtags_func $@ | sed 's|\"|\\"|g')\" > \"$TEMPDIR/mkvtags.xml\"" >> "$OPTSFILE" mkv_export_func >> "$OPTSFILE" fi fi else avi_to_mkv=no fi ;; *|"") avi_to_mkv=no ;; esac else avi_to_mkv=no fi # Ask for AVI -> MP4 conversion if [ "$ALLOW_MP4_MUXING" = "y" ]; then case "${audiocodec[1]}" in mp3|ffmp3|aac|aac+|neroaac|ffaac|ac3|ffac3|vorbis|ffvorbis|nosound|"") avi_mp4=$(get_selection_func "Would you like to convert the final encode from AVI to MP4? [y/N]: ") if [ "$avi_mp4" = "y" ]; then if [ ! -x "$MP4BOX" ]; then avi_to_mp4=no echo "" green "-> MP4Box (from gpac) is missing!" green "-> Skipping AVI to MP4 conversion!" echo "" else avi_to_mp4=yes # Global variables MP4FPS="$MPLAYER \"$OUTPUT\" $MPLAYEROPTS -identify -nosound -vo null -nocache -frames 1 2>/dev/null | grep '^ID_VIDEO_FPS' | tail -n 1 | awk -F= '{print \$2}' > \"$TEMPDIR/mp4fps\"" MP4VID="$MENCODER \"$OUTPUT\" -nosound -ovc copy -of rawvideo -o \"$TEMPDIR/h264_video.h264\"" VIDEOINPUT="-add \"$TEMPDIR/h264_video.h264\"" RMMP4VID="rm -f \"$TEMPDIR/h264_video.h264\"" case "$3" in ipc|ipchq|ip|iphq|iph|iphhq) MP4DEVOPTS="-ipod" ;; psp|psphq) if [ ! -z "$($MP4BOX -h general | grep '\-psp')" ]; then MP4DEVOPTS="-psp" fi ;; esac # Import of external subtitles. # Input type agnostic. Only # allow supported subtitle formats # by MP4. Others will be skipped for i in {1..3}; do if [ ! -z "${EXTSUB[$i]}" ]; then case "${EXTSUB[$i]##*.}" in idx|IDX|srt|SRT|ttxt|TTXT) MP4SUBS="$MP4SUBS -add \"$(eval "echo \${EXTSUB[$i]}")\"" ;; *) echo green "-> Subtitle format '$(echo ${EXTSUB[$i]##*.} | tr '[:lower:]' '[:upper:]')' not supported by MP4!" green "-> Supported subtitle formats are: IDX, SRT, TTXT" green "-> Skipping import of '${EXTSUB[$i]}'" echo ;; esac fi done # Add cover/chaps/DVD subs case "$source" in file|dvd|vcd) # Year - a bit misleading # since created could also # mean when the file was # encoded printf "Specify the Release Year of the content [press 'Enter' to skip]: " read mp4year if [ ! -z "$mp4year" ]; then MP4YEAR=":created=\"$mp4year\"" fi # Genre printf "Specify a Genre for the content [press 'Enter' to skip]: " read mp4genre if [ ! -z "$mp4genre" ]; then MP4GENRE=":genre=\"$mp4genre\"" fi # Cover printf "Provide a Cover file in jpeg/png format [press 'Enter' to skip]: " read -e mp4cover if [ ! -z "$mp4cover" ]; then if [ ! -f "$mp4cover" ]; then echo error "-> No such file: '$mp4cover'" error "-> Skipping embedding of cover file" echo else case "$(basename "${mp4cover##*.}" | tr '[:upper:]' '[:lower:]')" in jpg|jpeg|png) MP4COVER=":cover=\"$mp4cover\"" ;; *) echo error "-> Image type not supported" error "-> Skipping embedding of cover file" echo ;; esac fi fi case "$source" in dvd) # Audio language info for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then MP4AUDLANG[$i]=":lang=${AUDLANG[$i]}" fi done # Chapters for MP4 if [ "$chapexp" = "y" -o "$chapexp" = "Y" ]; then mp4impchap=$(get_selection_func "Import chapters information into the MP4 container? [y/N]: ") if [ "$mp4impchap" = "y" ]; then MP4CHAPS="-chap \"$CHAPTERSFILE\"" fi fi # DVD subs for MP4 if [ ! -z "${vobsubout[1]}" -o ! -z "${vobsubout[2]}" -o ! -z "${vobsubout[3]}" ]; then mp4impsub=$(get_selection_func "Import the ripped subtitle(s) into the MP4 container? [y/N]: ") if [ "$mp4impsub" = "y" ]; then for i in {1..3}; do [[ -z $(eval "echo \${IDXFILE[$i]}") ]] || MP4SUBS="$MP4SUBS -add \"$(eval "echo \${IDXFILE[$i]}")\"" done fi fi ;; esac ;; esac # MP4 hinting mp4hint=$(get_selection_func "Hint the MP4 file for RTP/RTSP streaming sessions? [y/N]: ") if [ "$mp4hint" = "y" ]; then MP4HINT="-hint" fi # First audio track for MP4 case "${audiocodec[1]}" in mp3|ffmp3) MP4AUD="$MP4BOX -aviraw audio \"$OUTPUT\" -out \"$TEMPDIR/mp3.mp3\"" AUDIOINPUT="-add \"$TEMPDIR/mp3_audio.mp3\"#audio:name=\"MP3 Stereo\"${MP4AUDLANG[1]}" RMMP4AUD="rm -f \"$TEMPDIR/mp3_audio.mp3\"" ;; ffaac) MP4AUD="$MP4BOX -aviraw audio \"$OUTPUT\" -out \"$TEMPDIR/aac.raw\"" MVRAW="mv -f \"$TEMPDIR/aac_audio.raw\" \"$TEMPDIR/aac_audio.aac\"" AUDIOINPUT="-add \"$TEMPDIR/aac_audio.aac\"#audio:name=\"LC-AAC ${chaninfo[1]}\"${MP4AUDLANG[1]}" RMMP4AUD="rm -f \"$TEMPDIR/aac_audio.aac\"" ;; aac+) AUDIOINPUT="-add \"$TEMPDIR/audio.aac\"#audio:sbr:name=\"HE-AACv1 Stereo\"${MP4AUDLANG[1]}" RMMP4AUD="rm -f \"$TEMPDIR/audio.aac\"" ;; neroaac) RMMP4AUD="rm -f \"$TEMPDIR/audio.aac\"" case "${aacprof[1]}" in -he|-hev2) AACSBR=":sbr" ;; esac AUDIOINPUT="-add \"$TEMPDIR/audio.aac\"#audio:name=\"${AACTYPE[1]} ${chaninfo[1]}\"$AACSBR${MP4AUDLANG[1]}" ;; aac|"") AUDIOINPUT="-add \"$TEMPDIR/audio.aac\"#audio:name=\"LC-AAC ${chaninfo[1]}\"${MP4AUDLANG[1]}" ;; ac3|ffac3) MP4AUD="$MP4BOX -aviraw audio \"$OUTPUT\" -out \"$TEMPDIR/ac3.raw\"" MVRAW="mv -f \"$TEMPDIR/ac3_audio.raw\" \"$TEMPDIR/ac3_audio.ac3\"" AUDIOINPUT="-add \"$TEMPDIR/ac3_audio.ac3\"#audio:name=\"AC3 ${chaninfo[1]}\"${MP4AUDLANG[1]}" RMMP4AUD="rm -f \"$TEMPDIR/ac3_audio.ac3\"" ;; ffvorbis) MP4AUD="$MP4BOX -aviraw audio \"$OUTPUT\" -out \"$TEMPDIR/vorbis.raw\"" MVRAW="mv -f \"$TEMPDIR/vorbis_audio.raw\" \"$TEMPDIR/vorbis_audio.ogg\"" AUDIOINPUT="-add \"$TEMPDIR/vorbis_audio.ogg\"#audio:name=\"Vorbis ${chaninfo[1]}\"${MP4AUDLANG[1]}" ;; vorbis) AUDIOINPUT="-add \"$TEMPDIR/audio.ogg\"#audio:name=\"Vorbis ${chaninfo[1]}\"${MP4AUDLANG[1]}" ;; esac # Second & third audio tracks for MP4 for i in {2..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in ffac3) # ffac3 is equivalent to # audio stream copy AUDIOINPUT[$i]="-add \"$TEMPDIR/audio$i.ac3\"#audio:name=\"AC3 ${chaninfo[$i]}\"${MP4AUDLANG[$i]}" ;; mp3|ac3) AUDIOINPUT[$i]="-add \"$TEMPDIR/audio$i.${audiocodec[$i]}\"#audio:name=\"$(echo ${audiocodec[$i]} | tr '[:lower:]' '[:upper:]') ${chaninfo[$i]}\"${MP4AUDLANG[$i]}" ;; vorbis) AUDIOINPUT[$i]="-add \"$TEMPDIR/audio$i.ogg\"#audio:name=\"Vorbis ${chaninfo[$i]}\"${MP4AUDLANG[$i]}" ;; aac+) AUDIOINPUT[$i]="-add \"$TEMPDIR/audio$i.aac\"#audio:sbr:name=\"HE-AACv1 Stereo\"${MP4AUDLANG[$i]}" ;; aac|"") AUDIOINPUT[$i]="-add \"$TEMPDIR/audio$i.aac\"#audio:name=\"LC-AAC ${chaninfo[$i]}\"${MP4AUDLANG[$i]}" ;; neroaac) RMNEROAUD[$i]="rm -f \"$TEMPDIR/audio$i.aac\"" case "${aacprof[$i]}" in -he|-hev2) AACSBR[$i]=":sbr" ;; esac AUDIOINPUT[$i]="-add \"$TEMPDIR/audio$i.aac\"#audio:name=\"${AACTYPE[$i]} ${chaninfo[$i]}\"${AACSBR[$i]}${MP4AUDLANG[$i]}" ;; esac fi done # Stupid MP4Box, moving around files as it's # too dumb to find out the format by itself :/ if [ ! -z "${aid[2]}" ]; then case "${audiocodec[2]}" in ffac3) MVRAW2="mv -f \"$TEMPDIR/audio2.raw\" \"$TEMPDIR/audio2.ac3\"" MVRAW3="mv -f \"$TEMPDIR/audio2.ac3\" \"$TEMPDIR/audio2.raw\"" ;; esac fi if [ ! -z "${aid[3]}" ]; then case "${audiocodec[3]}" in ffac3) MVRAW4="mv -f \"$TEMPDIR/audio3.raw\" \"$TEMPDIR/audio3.ac3\"" MVRAW5="mv -f \"$TEMPDIR/audio3.ac3\" \"$TEMPDIR/audio3.raw\"" ;; esac fi # Export commands to files case "$source" in dir) MP4OUT="$OUTPUTDIR/\${i%.*}.mp4" MP4TAGS="-itags name=\"\${i%.*}\":comment=\"Tagged by h264enc $version on \$(date)\"" MP4MUXING="$BATCH" ;; *) MP4OUT="${OUTPUT%.*}.mp4" MP4TAGS="-itags name=\"$(basename "${OUTPUT%.*}")\"$MP4YEAR$MP4GENRE$MP4COVER:comment=\"Tagged by h264enc $version on \$(date)\"" MP4MUXING="$TEMPDIR/mp4muxing" ;; esac mp4_export_func() { echo "test -e \"$MP4OUT\" && mv -f \"$MP4OUT\" \"$MP4OUT.old\"" echo "$MP4VID" echo "sleep 2" echo "$MP4AUD" echo "$MVRAW" echo "$MVRAW2" echo "$MVRAW4" echo "$MP4FPS" echo "$MP4BOX -fps \$(cat \"$TEMPDIR/mp4fps\") -tmp \"$TEMPDIR\" $VIDEOINPUT $MP4HINT $AUDIOINPUT ${AUDIOINPUT[2]} ${AUDIOINPUT[3]} $MP4TAGS $MP4SUBS $MP4CHAPS $MP4DEVOPTS -mpeg4 -new \"$MP4OUT\"" echo "$MVRAW3" echo "$MVRAW5" echo "sleep 2" echo "$RMMP4VID" echo "$RMMP4AUD" echo "${RMNEROAUD[2]}" echo "${RMNEROAUD[3]}" echo "sleep 2" echo } mp4_export_func >> "$MP4MUXING" if [ "$saveopts" = "y" -o "$saveopts" = "Y" ]; then mp4_export_func >> "$OPTSFILE" fi fi else avi_to_mp4=no fi ;; *) avi_to_mp4=no ;; esac else avi_to_mp4=no fi # AVI -> TS/Blu-ray if [ "$ALLOW_TS_MUXING" = "y" ]; then case "${audiocodec[1]}" in aac|ffaac|mp3|ffmp3|ac3|ffac3|ffeac3|ffdts|nosound|"") case "$3" in bd40|bdhq40|bd41|bdhq41) TSTYPE="Blu-ray" ;; avchd|avchdhq) TSTYPE="AVCHD" ;; *) TSTYPE="TS" ;; esac avi_ts=$(get_selection_func "Would you like to convert the final encode from AVI to $TSTYPE? [y/N]: ") if [ "$avi_ts" = "y" ]; then # Check for tsMuxeR if [ ! -x "$TSMUXER" ]; then avi_to_ts=no echo "" green "-> Utility 'tsMuxeR' is missing!" green "-> Skipping AVI to TS/Blu-ray/AVCHD conversion!" echo "" else avi_to_ts=yes # Global variables TSVID="$MENCODER \"$OUTPUT\" -nosound -ovc copy -of rawvideo -o \"$TEMPDIR/videots.h264\"" TSFPS="$MPLAYER \"$OUTPUT\" $MPLAYEROPTS -identify -nosound -vo null -nocache -frames 1 2>/dev/null | grep '^ID_VIDEO_FPS' | tail -n 1 | awk -F= '{print \$2}' > \"$TEMPDIR/tsfps\"" case "$3" in bd40|bdhq40|bd41|bdhq41|avchd|avchdhq) if [ "$3" = "avchd" -o "$3" = "avchdhq" ]; then TSOPT="--avchd" else TSOPT="--blu-ray" fi METAOPT="echo \"MUXOPT --no-pcr-on-video-pid --new-audio-pes $TSOPT --auto-chapters=5 --vbr\" >> \"$TEMPDIR/tsmuxer.meta\"" METAVID="echo \"V_MPEG4/ISO/AVC, \\\"$TEMPDIR/videots.h264\\\", fps=\$(cat \"$TEMPDIR/tsfps\")\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; *) METAOPT="echo \"MUXOPT --no-pcr-on-video-pid --new-audio-pes --vbr\" >> \"$TEMPDIR/tsmuxer.meta\"" METAVID="echo \"V_MPEG4/ISO/AVC, \\\"$TEMPDIR/videots.h264\\\", insertSEI, contSPS, fps=\$(cat \"$TEMPDIR/tsfps\")\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; esac case "$source" in dvd) for i in {1..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then TSAUDLANG[$i]=", lang=${AUDLANG[$i]}" fi done ;; esac case "${audiocodec[1]}" in ffaac|mp3|ffmp3|ac3|ffac3|ffeac3|ffdts) TSAUD="$MPLAYER \"$OUTPUT\" $MPLAYEROPTS -vo null -vc null ${channels[1]} -dumpaudio -dumpfile \"$TEMPDIR/audiots.raw\"" ;; esac case "${audiocodec[1]}" in ffaac) METAAUD="echo \"A_AAC, \\\"$TEMPDIR/audiots.raw\\\"${TSAUDLANG[1]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; aac|"") METAAUD="echo \"A_AAC, \\\"$TEMPDIR/audio.aac\\\"${TSAUDLANG[1]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; mp3|ffmp3) METAAUD="echo \"A_MP3, \\\"$TEMPDIR/audiots.raw\\\"${TSAUDLANG[1]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; ac3|ffac3|ffeac3) METAAUD="echo \"A_AC3, \\\"$TEMPDIR/audiots.raw\\\"${TSAUDLANG[1]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; ffdts) METAAUD="echo \"A_DTS, \\\"$TEMPDIR/audiots.raw\\\"${TSAUDLANG[1]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; esac # Second & third audio track for DVD encodings for i in {2..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in aac|"") METAAUD[$i]="echo \"A_AAC, \\\"$TEMPDIR/audio$i.aac\\\"${TSAUDLANG[$i]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; mp3) METAAUD[$i]="echo \"A_MP3, \\\"$TEMPDIR/audio$i.mp3\\\"${TSAUDLANG[$i]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; ac3) METAAUD[$i]="echo \"A_AC3, \\\"$TEMPDIR/audio$i.ac3\\\"${TSAUDLANG[$i]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; ffac3) METAAUD[$i]="echo \"A_AC3, \\\"$TEMPDIR/audio$i.raw\\\"${TSAUDLANG[$i]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; ffdts) METAAUD[$i]="echo \"A_DTS, \\\"$TEMPDIR/audio$i.raw\\\"${TSAUDLANG[$i]}\" >> \"$TEMPDIR/tsmuxer.meta\"" ;; esac fi done # Export commands to files case "$source" in dir) case "$3" in bd40|bdhq40|bd41|bdhq41) TSOUT="$OUTPUTDIR/\${i%.*}.bluray" ;; avchd|avchdhq) TSOUT="$OUTPUTDIR/\${i%.*}.avchd" ;; *) TSOUT="$OUTPUTDIR/\${i%.*}.ts" ;; esac TSMUXING="$BATCH" ;; *) case "$3" in bd40|bdhq40|bd41|bdhq41) TSOUT="${OUTPUT%.*}.bluray" ;; avchd|avchdhq) TSOUT="${OUTPUT%.*}.avchd" ;; *) TSOUT="${OUTPUT%.*}.ts" ;; esac TSMUXING="$TEMPDIR/tsmuxing" ;; esac ts_export_func() { echo "test -e \"$TSOUT\" && mv -f \"$TSOUT\" \"$TSOUT.old\"" echo "$TSVID" echo "$TSAUD" echo "$TSFPS" echo echo "$METAOPT" echo "$METAVID" echo "$METAAUD" echo "${METAAUD[2]}" echo "${METAAUD[3]}" echo "$TSMUXER \"$TEMPDIR/tsmuxer.meta\" \"$TSOUT\"" echo "sleep 2" echo } ts_export_func >> "$TSMUXING" if [ "$saveopts" = "y" -o "$saveopts" = "Y" ]; then ts_export_func >> "$OPTSFILE" fi fi else avi_to_ts=no fi ;; *) avi_to_ts=no ;; esac else avi_to_ts=no fi # Ask for AVI -> OGM # ogmmerge doesn't like raw h264 # video so instead we take it # directly from the AVI file if [ "$ALLOW_OGM_MUXING" = "y" ]; then case "${audiocodec[1]}" in mp3|ffmp3|vorbis|ffvorbis|ac3|ffac3|pcm|ffpcm|nosound) avi_ogm=$(get_selection_func "Would you like to convert the final encode from AVI to OGM? [y/N]: ") if [ "$avi_ogm" = "y" ]; then # Check for ogmmerge if [ ! -x "$OGMMERGE" ]; then avi_to_ogm=no echo "" green "-> Utility 'ogmmerge' is missing!" green "-> Skipping AVI to OGM conversion!" else avi_to_ogm=yes case "${audiocodec[1]}" in vorbis) # We take the video directly from the AVI, # hence the --noaudio option which ignores # audio from the AVI NOAUDIO="--noaudio" case "$source" in dvd) OGMAUD="-c LANGUAGE=${AUDLANG[1]} \"$TEMPDIR/audio.ogg\"" ;; *) OGMAUD="\"$TEMPDIR/audio.ogg\"" ;; esac ;; mp3|ac3|ffac3|pcm) case "$source" in dvd) OGMAUDLANG="-c LANGUAGE=${AUDLANG[1]}" ;; esac ;; esac # Second & third audio track for DVD encodings for i in {2..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then case "${audiocodec[$i]}" in # ffac3 is equivalent to # AC3 audio stream copy ffac3) OGMAUD[$i]="-c LANGUAGE=${AUDLANG[$i]} \"$TEMPDIR/audio$i.raw\"" ;; ac3|mp3) OGMAUD[$i]="-c LANGUAGE=${AUDLANG[$i]} \"$TEMPDIR/audio$i.${audiocodec[$i]}\"" ;; vorbis) OGMAUD[$i]="-c LANGUAGE=${AUDLANG[$i]} \"$TEMPDIR/audio$i.ogg\"" ;; esac fi done # Title/Genre/Year for OGM case "$source" in file|dvd|vcd) OGMTITLE="-c TITLE=\"$(basename "${OUTPUT%.*}")\"" printf "Specify the Release Year of the content [press 'Enter' to skip]: " read ogmyear if [ ! -z "$ogmyear" ]; then OGMYEAR="-c YEAR=\"$ogmyear\"" fi printf "Provide a Genre for the content [press 'Enter' to skip]: " read ogmgenre if [ ! -z "$ogmgenre" ]; then OGMGENRE="-c GENRE=\"$ogmgenre\"" fi ;; dir) OGMTITLE="-c TITLE=\"\${i%.*}\"" ;; esac # Import of external subtitles. # Input type agnostic. Only # allow supported subtitle formats # by OGM. Others will be skipped for i in {1..3}; do if [ ! -z "${EXTSUB[$i]}" ]; then case "${EXTSUB[$i]##*.}" in srt|SRT) OGMSUBS="$OGMSUBS \"$(eval "echo \${EXTSUB[$i]}")\"" ;; *) echo green "-> Subtitle format '$(echo ${EXTSUB[$i]##*.} | tr '[:lower:]' '[:upper:]')' not supported by OGM!" green "-> Supported subtitle formats are: SRT" green "-> Skipping import of '${EXTSUB[$i]}'" echo ;; esac fi done case "$source" in dvd) # Chapters for OGM if [ "$chapexp" = "y" -o "$chapexp" = "Y" ]; then ogmimpchap=$(get_selection_func "Import chapters information into the OGM container? [y/N]: ") if [ "$ogmimpchap" = "y" ]; then OGMCHAPS="-c @\"$CHAPTERSFILE\"" fi fi ;; esac # Export commands to files case "$source" in dir) OGMOUT="$OUTPUTDIR/\${i%.*}.ogm" OGMMUXING="$BATCH" ;; *) OGMOUT="${OUTPUT%.*}.ogm" OGMMUXING="$TEMPDIR/ogmmuxing" ;; esac OGMCOMMENT="-c COMMENT=\"Tagged by h264enc $version on \$(date)\"" ogm_export_func() { echo "test -e \"$OGMOUT\" && mv -f \"$OGMOUT\" \"$OGMOUT.old\"" echo "$OGMMERGE $NOAUDIO $OGMTITLE $OGMYEAR $OGMGENRE $OGMAUDLANG $OGMCOMMENT $OGMCHAPS \"$OUTPUT\" $OGMAUD ${OGMAUD[2]} ${OGMAUD[3]} $OGMSUBS -o \"$OGMOUT\"" echo "sleep 2" echo } ogm_export_func >> "$OGMMUXING" if [ "$saveopts" = "y" -o "$saveopts" = "Y" ]; then ogm_export_func >> "$OPTSFILE" fi fi else avi_to_ogm=no fi ;; *|"") avi_to_ogm=no ;; esac else avi_to_ogm=no fi # Footers for batch files case "$source" in dir) if [ "$avi_to_mkv" = "yes" -o "$avi_to_mp4" = "yes" -o "$avi_to_ts" = "yes" -o "$avi_to_ogm" = "yes" ]; then rmavi=$(get_selection_func "Delete the AVI file after remuxing? [y/N]: ") if [ "$rmavi" = "y" ]; then echo "rm -f \"$OUTPUT\"" >> "$BATCH" fi fi echo "rm -rf \"$TEMPDIR\"" >> "$BATCH" echo "" >> "$BATCH" echo "fi" >> "$BATCH" echo "" >> "$BATCH" echo "done" >> "$BATCH" echo "" >> "$BATCH" send_email_func exp >> "$BATCH" echo "#################### END OF COMMANDS ####################" >> "$BATCH" ;; *) if [ "$saveopts" = "y" -o "$saveopts" = "Y" ]; then echo "rm -rf \"$TEMPDIR\"" >> "$OPTSFILE" echo "" >> "$OPTSFILE" send_email_func exp >> "$OPTSFILE" echo "#################### END OF COMMANDS ####################" >> "$OPTSFILE" echo "" >> "$OPTSFILE" fi if [ "$avi_to_mkv" = "no" -a "$avi_to_mp4" = "no" -a "$avi_to_ts" = "no" -a "$avi_to_ogm" = "no" ]; then if [ "${TRACKID[2]}" = "yes" -o "${TRACKID[3]}" = "yes" ]; then echo error "-> 2nd/3rd audio track only supported by" error " the MKV/MP4/TS/OGM containers!" echo rmtemp fi case "${audiocodec[1]}" in neroaac|aac+|vorbis|flac) echo error "-> ${audiocodec[1]} audio not supported by the AVI container!" echo rmtemp ;; esac fi ;; esac case "$1" in -1p) passmode="1-pass mode" ;; -qp) passmode="fixed-quant mode" ;; -crf) passmode="constant rate factor mode" ;; -2p) passmode="2-pass mode" ;; -3p) passmode="3-pass mode" ;; esac echo case "$source" in dir) green "-> Starting to batch encode $type in '$(dirname "$sourcetype")'" display_quality_preset_func $3 $4 green "-> Using '$(dirname "$OUTPUT")' as output directory for all $type" green "-> Using $passmode for all $type" green "-> Batch file located in '$BATCH'" ;; *) green "-> Starting to encode the $type in $passmode" display_quality_preset_func $3 $4 case "$1" in -2p) green "-> Using '/dev/null' as output for the first pass"; finalpass="for the second pass" ;; -3p) green "-> Using '/dev/null' as output for the first & second pass"; finalpass="for the third pass" ;; esac green "-> Using '$OUTPUT' as output file $finalpass" ;; esac echo # Give user a few more seconds # to read the above sleep 3 # Small counter :) counter() { for i in 5 4 3 2 1; do sleep 1 && echo -n "$i " done } # Set counter color color() { BLUE="\033[01;34m" NORMAL="\e[0;0m" case $1 in blue) printf "$BLUE" ;; normal) echo -ne "$NORMAL" ;; esac } mencoder_exit() { if [ $? != 0 ]; then error "-> MEncoder has exited with a non-zero value!" error "-> Exiting in function: mencoder_exit()" rmtemp fi } color blue && printf "Starting to encode in: " && counter color normal && echo "" # Start encoding case "$source" in dir) if [ -f "$BATCH" ]; then cp -f $BATCH $HOME source $BATCH echo "" brown "-> Have a nice day ^_^" echo "" rmtemp else error "-> File '$BATCH' is missing!" error "-> Exiting..." rmtemp fi ;; *) case "$1" in -1p|-qp|-crf) source "$H264_1PFQ" mencoder_exit ;; -2p) source "$H264_2P1" mencoder_exit echo "" brown "==============================================================" echo "" color blue && printf "Starting the second pass of the encoding process in: " && counter color normal && echo "" source "$H264_2P2" mencoder_exit ;; -3p) # Here's how it works... # 1-pass -> collects statistics and stores them to a file # 2-pass -> reads those statistics and bases ratecontrol on them # 3-pass -> simultaniously reads statistics, overwrites them # and encodes the content source "$H264_2P1" mencoder_exit echo "" brown "==============================================================" echo "" color blue && printf "Starting the second pass of the encoding process in: " && counter color normal && echo "" source "$H264_2P2" mencoder_exit echo "" brown "==============================================================" echo "" color blue && printf "Starting the third pass of the encoding process in: " && counter color normal && echo "" source "$H264_2P3" mencoder_exit ;; esac ;; esac # Dump the second/third subtitle if selected case "${audiocodec[1]}" in nosound) audfmt="-nosound" ;; copy|ffac3|ffdts) audfmt="-oac copy" ;; *) audfmt="-oac pcm" ;; esac for i in {2..3}; do if [ ! -z "${subtitle[$i]}" ]; then echo green "-> Dumping subtitle $i, please wait..." sleep 2 $MENCODER $sourcetype $device $MPEGVC $chapters $ofps ${aid[1]} ${subtitle[$i]} -vobsubout "${SUBFILE[$i]%.*}" -vobsuboutindex $(($i-1)) $audfmt -ovc copy -o /dev/null >/dev/null 2>&1 if [ -e "${IDXFILE[$i]}" ]; then green "-> Done" else error "-> Failed!" if [ "$avi_to_mkv" = "yes" -o "$avi_to_mp4" = "yes" ]; then if [ "$mkvimpsub" = "y" -o "$mkvimpsub" = "Y" -o "$mp4impsub" = "y" -o "$mp4impsub" = "Y" ]; then error "-> Exiting as container conversion will also fail!" echo rmtemp fi fi echo fi fi done # Encode audio to neroAAC/AAC+/Vorbis/FLAC if [ "$avi_to_mkv" = "yes" -o "$avi_to_mp4" = "yes" -o "$avi_to_ogm" = "yes" -o "$avi_to_ts" = "yes" ]; then audio_exit_func() { case "$1" in audiofile) error "-> Failed!" ;; track1) error "-> File '${AUDIOENC[1]}' is missing!" ;; track23) error "-> File '${AUDIOENC[$i]}' is missing!" ;; esac error "-> Exiting as container conversion will also fail!" echo rmtemp } case "${audiocodec[1]}" in aac|aac+|neroaac|vorbis|flac|"") echo case "${audiocodec[1]}" in aac|"") audfile="$TEMPDIR/audio.aac" green "-> Track 1: Encoding audio with 'faac' to LC-AAC, please wait..." green "-> Track 1: This can take a while..." ;; aac+) audfile="$TEMPDIR/audio.aac" green "-> Track 1: Encoding audio with 'aacplusenc' to HE-AACv1, please wait..." green "-> Track 1: This can take a while..." ;; neroaac) audfile="$TEMPDIR/audio.aac" green "-> Track 1: Encoding audio with 'neroAacEnc' to ${AACTYPE[1]}, please wait..." green "-> Track 1: This can take a while..." ;; vorbis) audfile="$TEMPDIR/audio.ogg" green "-> Track 1: Encoding audio with 'oggenc' to Vorbis, please wait..." green "-> Track 1: This can take a while..." ;; flac) audfile="$TEMPDIR/audio.flac" green "-> Track 1: Encoding audio with 'flac' to FLAC, please wait..." green "-> Track 1: This can take a while..." ;; esac sleep 2 if [ -f "${AUDIOENC[1]}" ]; then source "${AUDIOENC[1]}" >/dev/null 2>&1 if [ -e "$audfile" ]; then green "-> Track 1: Done" else audio_exit_func audiofile fi else audio_exit_func track1 fi ;; esac # Second & third audio track for DVD encodings for i in {2..3}; do if [ "${TRACKID[$i]}" = "yes" ]; then sleep 2 echo case "${audiocodec[$i]}" in ffac3|ffdts) audfile[$i]="$TEMPDIR/audio$i.raw" green "-> Track $i: Dumping ${detectaud[$i]} audio, please wait..." ;; mp3|ac3) audfile[$i]="$TEMPDIR/audio$i.${audiocodec[$i]}" green "-> Track $i: Encoding audio to $(echo ${audiocodec[$i]} | tr '[:lower:]' '[:upper:]'), please wait..." ;; neroaac) audfile[$i]="$TEMPDIR/audio$i.aac" green "-> Track $i: Dumping & encoding audio with 'neroAacEnc' to ${AACTYPE[$i]}, please wait..." green "-> Track $i: This can take a while..." ;; aac|"") audfile[$i]="$TEMPDIR/audio$i.aac" green "-> Track $i: Dumping & encoding audio with 'faac' to LC-AAC, please wait..." green "-> Track $i: This can take a while..." ;; aac+) audfile[$i]="$TEMPDIR/audio$i.aac" green "-> Track $i: Dumping & encoding audio with 'aacplusenc' to HE-AACv1, please wait..." green "-> Track $i: This can take a while..." ;; vorbis) audfile[$i]="$TEMPDIR/audio$i.ogg" green "-> Track $i: Dumping & encoding audio with 'oggenc' to Vorbis, please wait..." green "-> Track $i: This can take a while..." ;; flac) audfile[$i]="$TEMPDIR/audio$i.flac" green "-> Track $i: Dumping & encoding audio with 'flac' to FLAC, please wait..." green "-> Track $i: This can take a while..." ;; esac if [ -f "${AUDIOENC[$i]}" ]; then source "${AUDIOENC[$i]}" >/dev/null 2>&1 if [ -e "${audfile[$i]}" ]; then green "-> Track $i: Done" else audio_exit_func audiofile fi else audio_exit_func track23 fi fi done fi ############################################################## ########## Container conversion (MKV/MP4/OGM/TS) ############# ############################################################## # AVI -> MKV conversion if [ "$avi_to_mkv" = "yes" ]; then echo "" green "-> Converting AVI file to the MKV container, please wait..." sleep 3 if [ -f "$MKVMUXING" ]; then source "$MKVMUXING" >/dev/null 2>&1 if [ -e "$MKVOUT" ]; then green "-> Done" else error "-> Failed!" fi else error "-> File '$MKVMUXING' is missing!" error "-> Skipping AVI to MKV conversion!" fi fi # AVI -> MP4 conversion if [ "$avi_to_mp4" = "yes" ]; then echo "" green "-> Converting AVI file to the MP4 container, please wait..." sleep 3 if [ -f "$MP4MUXING" ]; then source "$MP4MUXING" >/dev/null 2>&1 if [ -e "$MP4OUT" ]; then green "-> Done" else error "-> Failed!" fi else error "-> File '$MP4MUXING' is missing!" error "-> Skipping AVI to MP4 conversion!" fi fi # AVI -> TS conversion if [ "$avi_to_ts" = "yes" ]; then echo "" case "$3" in bd40|bdhq40|bd41|bdhq41|avchd|avchdhq) green "-> Converting AVI file to Blu-ray/AVCHD disc structure, please wait..." ;; *) green "-> Converting AVI file to the TS container, please wait..." ;; esac sleep 3 if [ -f "$TSMUXING" ]; then source "$TSMUXING" >/dev/null 2>&1 if [ -e "$TSOUT" ]; then green "-> Done" else error "-> Failed!" fi else error "-> File '$TSMUXING' is missing!" error "-> Skipping AVI to TS/Blu-ray/AVCHD conversion!" fi fi # AVI -> OGM conversion if [ "$avi_to_ogm" = "yes" ]; then echo "" green "-> Converting AVI file to the OGM container, please wait..." sleep 3 if [ -f "$OGMMUXING" ]; then source "$OGMMUXING" >/dev/null 2>&1 if [ -e "$OGMOUT" ]; then green "-> Done" else error "-> Failed!" fi else error "-> File '$OGMMUXING' is missing!" error "-> Skipping AVI to OGM conversion!" fi fi rm -rf "$TEMPDIR" # Report final file size FSIZE_AVI=$(echo "scale=3; $(stat -c %s "$OUTPUT" 2>/dev/null)/1048576" | $BC -l | sed 's|^\.|0\.|') echo "" green "-> AVI file size: $FSIZE_AVI MiB ($OUTPUT)" if [ "$avi_to_mkv" = "yes" ]; then if [ -e "$MKVOUT" ]; then FSIZE_MKV=$(echo "scale=3; $(stat -c %s "$MKVOUT" 2>/dev/null)/1048576" | $BC -l | sed 's|^\.|0\.|') green "-> MKV file size: $FSIZE_MKV MiB ($MKVOUT)" fi fi if [ "$avi_to_ts" = "yes" ]; then if [ -e "$TSOUT" ]; then case "$3" in bd40|bdhq40|bd41|bdhq41) green "-> Blu-ray disc structure created in: $TSOUT" ;; avchd|avchdhq) green "-> AVCHD disc structure created in: $TSOUT" ;; *) FSIZE_TS=$(echo "scale=3; $(stat -c %s "$TSOUT" 2>/dev/null)/1048576" | $BC -l | sed 's|^\.|0\.|') green "-> TS file size: $FSIZE_TS MiB ($TSOUT)" ;; esac fi fi if [ "$avi_to_mp4" = "yes" ]; then if [ -e "$MP4OUT" ]; then FSIZE_MP4=$(echo "scale=3; $(stat -c %s "$MP4OUT" 2>/dev/null)/1048576" | $BC -l | sed 's|^\.|0\.|') green "-> MP4 file size: $FSIZE_MP4 MiB ($MP4OUT)" fi fi if [ "$avi_to_ogm" = "yes" ]; then if [ -e "$OGMOUT" ]; then FSIZE_OGM=$(echo "scale=3; $(stat -c %s "$OGMOUT" 2>/dev/null)/1048576" | $BC -l | sed 's|^\.|0\.|') green "-> OGM file size: $FSIZE_OGM MiB ($OGMOUT)" fi fi send_email_func if [ "$avi_to_mkv" = "yes" -o "$avi_to_mp4" = "yes" -o "$avi_to_ogm" = "yes" -o "$avi_to_ts" = "yes" ]; then echo "" delavi=$(get_selection_func "Delete the AVI file? [y/N]: ") if [ "$delavi" = "y" ]; then rm -f "$OUTPUT" fi fi echo "" brown "-> Have a nice day ^_^" echo "" exit 0