diff --git a/x264.h b/x264.h
-index e5a1600..f635d9e 100644
+index b88f510..7dd0891 100644
--- a/x264.h
+++ b/x264.h
@@ -41,7 +41,17 @@
#include "x264_config.h"
--#define X264_BUILD 133
+-#define X264_BUILD 135
+/*
+ * Define the full version explicitly so that it survives a git --archive.
+ *
+#ifdef X264_VERSION
+#undef X264_VERSION
+#endif
-+#define X264_BUILD 133
-+#define X264_VERSION " r2334 a3ac64b"
++#define X264_BUILD 135
++#define X264_VERSION " r2345 f0c1c53"
/* Application developers planning to link against a shared library version of
* libx264 from a Microsoft Visual Studio or similar development environment
$(eval $(call import.MODULE.defs,X264,x264,YASM PTHREADW32))
$(eval $(call import.CONTRIB.defs,X264))
-X264.FETCH.url = http://download.handbrake.fr/handbrake/contrib/x264-r2334-a3ac64b.tar.gz
+X264.FETCH.url = http://download.handbrake.fr/handbrake/contrib/x264-r2345-f0c1c53.tar.gz
X264.EXTRACT.tarbase = x264
X264.CONFIGURE.deps =
X264.CONFIGURE.shared =
-X264.CONFIGURE.static =
-X264.CONFIGURE.extra = --disable-cli --enable-static --enable-strip
-X264.CONFIGURE.extra += --disable-gpac --disable-avs --disable-lavf --disable-ffms --disable-swscale --disable-opencl
+X264.CONFIGURE.extra = --enable-strip --bit-depth=8 --chroma-format=420
+X264.CONFIGURE.extra += --disable-lavf --disable-ffms --disable-avs --disable-swscale --disable-gpac --disable-cli
ifeq (1-mingw,$(BUILD.cross)-$(BUILD.system))
X264.CONFIGURE.extra += --cross-prefix=$(BUILD.spec)-
AS_HELP_STRING([--enable-faac], [enable faac encoder]),
use_faac=yes, use_faac=no)
+AC_ARG_ENABLE(mp4v2,
+ AS_HELP_STRING([--enable-mp4v2], [enable mp4v2 muxer]),
+ use_mp4v2=yes, use_mp4v2=no)
+
+AC_ARG_ENABLE(libmkv,
+ AS_HELP_STRING([--enable-libmkv], [enable libmkv muxer]),
+ use_libmkv=yes, use_libmkv=no)
+
AC_ARG_ENABLE(gst,
AS_HELP_STRING([--disable-gst], [disable gstreamer (live preview)]),
gst_disable=yes, gst_disable=no)
;;
esac
-HB_LIBS="-lhb -la52 -lmkv -lavresample -lavformat -lavcodec -lavutil -ldvdnav -ldvdread -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate -lx264 -lmp4v2 -lswscale -ltheoraenc -ltheoradec -lz -lbz2 -lpthread -lbluray -lass -lfontconfig -lfreetype -lxml2"
+HB_LIBS="-lhb -la52 -lavresample -lavformat -lavcodec -lavutil -ldvdnav -ldvdread -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate -lx264 -lswscale -ltheoraenc -ltheoradec -lz -lbz2 -lpthread -lbluray -lass -lfontconfig -lfreetype -lxml2"
if test "x$use_fdk_aac" = "xyes" ; then
HB_LIBS+=" -lfdk-aac"
HB_LIBS+=" -lfaac"
fi
+if test "x$use_mp4v2" = "xyes" ; then
+ HB_LIBS+=" -lmp4v2"
+fi
+
+if test "x$use_libmkv" = "xyes" ; then
+ HB_LIBS+=" -lmkv"
+fi
+
AC_SUBST(HB_LIBS)
AC_SUBST(GHB_TOOLS_CFLAGS)
AC_SUBST(GHB_TOOLS_LIBS)
%install
make -C build DESTDIR=$RPM_BUILD_ROOT install-strip
+%find_lang ghb
## blow away stuff we don't want
/bin/rm -f $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/icon-theme.cache
gtk-update-icon-cache -q %{_datadir}/icons/hicolor
fi
-%files gui
+%files gui -f ghb.lang
%defattr(-,root,root,-)
%doc NEWS AUTHORS CREDITS THANKS COPYING
%{_datadir}/icons/hicolor
ifeq (1,$(FEATURE.faac))
GTK.CONFIGURE.extra += --enable-faac
endif
+
+ifeq (1,$(FEATURE.mp4v2))
+ GTK.CONFIGURE.extra += --enable-mp4v2
+endif
+
+ifeq (1,$(FEATURE.libmkv))
+ GTK.CONFIGURE.extra += --enable-libmkv
+endif
# please keep this list sorted alphabetically
#
+ru
# List of source files containing translatable strings.
-
src/main.c
+src/ghb.ui
--- /dev/null
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Victor Ryzhykh <victorr2007@yandex.ru>, 2013.
+msgid ""
+msgstr ""
+"Project-Id-Version: handbrake\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-13 12:44+0400\n"
+"PO-Revision-Date: 2013-07-26 15:32+0300\n"
+"Last-Translator: \n"
+"Language-Team: Russian <victorr2007@yandex.ru>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
+"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;'nX-Generator: Lokalize "
+"1.5\n"
+"X-Generator: Lokalize 1.5\n"
+
+#: rc.cpp:1
+msgctxt "NAME OF TRANSLATORS"
+msgid "Your names"
+msgstr "Виктор Рыжих"
+
+#: rc.cpp:2
+msgctxt "EMAIL OF TRANSLATORS"
+msgid "Your emails"
+msgstr "victorr2007@yandex.ru"
+
+msgid "File:"
+msgstr "Файл:"
+
+msgid "_File"
+msgstr "_Файл"
+
+msgid "_Queue"
+msgstr "_Очередь"
+
+msgid "_View"
+msgstr "_Вид"
+
+msgid "Format:"
+msgstr "Формат:"
+
+msgid "<b>Source:</b>"
+msgstr "<b>Источник:</b>"
+
+msgid "_Source"
+msgstr "_Добавить папку"
+
+msgid "Single _Title"
+msgstr "Выбрать _файл"
+
+msgid "_Destination"
+msgstr "_Файл выхода"
+
+msgid "_Make Default"
+msgstr "_Сделать по умолчанию"
+
+msgid "Start Encoding"
+msgstr "Начать кодирование"
+
+msgid "_Start Encoding"
+msgstr "_Начать кодирование"
+
+msgid "_Pause Encoding"
+msgstr "_Приостановить кодирование"
+
+msgid "Pause Encoding"
+msgstr "Приостановить кодирование"
+
+msgid "_Stop Encoding"
+msgstr "_Остановить кодирование"
+
+msgid "Stop Encoding"
+msgstr "Остановить кодирование"
+
+msgid "_Resume Encoding"
+msgstr "_Продолжить кодирование"
+
+msgid "Resume Encoding"
+msgstr "Продолжить кодирование"
+
+msgid "Add Queue"
+msgstr "Добавить в очередь"
+
+msgid "_Add Queue"
+msgstr "_Добавить в очередь"
+
+msgid "Add A_ll Queue"
+msgstr "Добавить в_се в очередь"
+
+msgid "_Start Queue"
+msgstr "_Начать очередь"
+
+msgid "Start Queue"
+msgstr "Начать очередь"
+
+msgid "_Pause Queue"
+msgstr "_Приостановить очередь"
+
+msgid "Pause Queue"
+msgstr "Приостановить очередь"
+
+msgid "_Resume Queue"
+msgstr "_Продолжить очередь"
+
+msgid "Resume Queue"
+msgstr "Продолжить очередь"
+
+msgid "_Stop Queue"
+msgstr "_Остановить очередь"
+
+msgid "S_top Queue"
+msgstr "О_становить очередь"
+
+msgid "Stop Queue"
+msgstr "Остановить очередь"
+
+msgid "None"
+msgstr "Нет"
+
+msgid "<b>Picture:</b> Source: <small>%d x %d, Output %d x %d %s</small>\n"
+msgstr ""
+"<b>Изображение</b> Источник: <small>%d x %d, Вывод %d x %d %s</small>\n"
+
+msgid "No Titles"
+msgstr "Без названия"
+
+msgid "hh:mm:ss"
+msgstr "чч:мм:сс"
+
+msgid "HandBrake For _Dumbies"
+msgstr ""
+
+msgid "Show Presets"
+msgstr "Показать предустановки"
+
+msgid "_Picture Settings"
+msgstr "_Настройка изображения"
+
+msgid "_Activity Window"
+msgstr "_Окно процесса обработки"
+
+msgid "Show _Queue"
+msgstr "Показать _очередь"
+
+msgid "_Help"
+msgstr "_Помощь"
+
+msgid "_Guide"
+msgstr "_Руководство"
+
+msgid "_Minimize/Maximize"
+msgstr "_Свернуть/распахнуть"
+
+msgid "New _Folder"
+msgstr "Создать _папку"
+
+msgid "_Export"
+msgstr "_Экспорт"
+
+msgid "_Import"
+msgstr "_Импорт"
+
+msgid "_Update Built-in Presets"
+msgstr "_Обновить предустановки"
+
+msgid "Choose Video Source"
+msgstr "Выбрать исходное видео"
+
+msgid "Add to Queue"
+msgstr "Добавить в очередь"
+
+msgid "Enqueue"
+msgstr "Очерёдность"
+
+msgid "Show Queue"
+msgstr "Показать очередь"
+
+msgid "Queue"
+msgstr "Очередь"
+
+msgid ""
+"Open Picture Settings and Preview window. Here you can adjust cropping, "
+"resolution, aspect ratio, and filters."
+msgstr ""
+"Открыть настройки изображения и окно просмотра. Здесь вы можете "
+"отрегулировать обрезку, разрешение, соотношение сторон и фильтры."
+
+msgid "Picture Settings"
+msgstr "Настройка изображения"
+
+msgid "Show Activity Window"
+msgstr "Показать окно процесса обработки"
+
+msgid "Activity"
+msgstr "Активность"
+
+msgid ""
+"Set the title to encode. By default the longest title is chosen. This is "
+"often the feature title of a DVD."
+msgstr ""
+"Установить заголовок для кодирования. По умолчанию выбрано длинное "
+"название. Часто это заголовок функций DVD."
+
+msgid "Angle:"
+msgstr "Угол:"
+
+msgid "For multi-angle DVD's, select the desired angle to encode."
+msgstr "Для нескольких ракурсов DVD, выберите нужный ракурс для кодирования."
+
+msgid "Range of title to encode. Can be chapters, seconds, or frames."
+msgstr ""
+"Диапазон заглавий для кодирования. Могут быть главы, секунды или кадры."
+
+msgid ""
+"The source subtitle track\n"
+"\n"
+"You can choose any of the subtitles\n"
+"recognized in your source file.\n"
+"\n"
+"In addition, there is a special track option\n"
+"\"Foreign Audio Search\". This option will add\n"
+"an extra pass to the encode that searches for\n"
+"subtitles that may correspond to a foreign\n"
+"language scene. This option is best used in\n"
+"conjunction with the \"Forced\" option."
+msgstr ""
+
+msgid "<b>Track</b>"
+msgstr "<b>Дорожка</b>"
+
+msgid "<b>Forced Only</b>"
+msgstr "<b>Только встроенные</b>"
+
+msgid ""
+"Use only subtitles that have been flagged\n"
+"as forced in the source subtitle track\n"
+"\n"
+"\"Forced\" subtitles are usually used to show\n"
+"subtitles during scenes where someone is speaking\n"
+"a foreign language.\n"
+msgstr ""
+
+msgid "<b>Burned In</b>"
+msgstr "<b>Встроенные</b>"
+
+msgid ""
+"Render the subtitle over the video.\n"
+"\n"
+"The subtitle will be part of the video and can not be disabled."
+msgstr ""
+"Отображение субтитров на видео.\n"
+"\n"
+"Субтитры будут на части видео и не могут быть отключены."
+
+msgid "<b>Default</b>"
+msgstr "<b>По умолчанию</b>"
+
+msgid ""
+"Set the default output subtitle track.\n"
+"\n"
+"Most players will automatically display this\n"
+"subtitle track whenever the video is played.\n"
+"\n"
+"This is usefule for creating a \"forced\" track\n"
+"in your output."
+msgstr ""
+
+msgid "<b>SRT Offset</b>"
+msgstr "<b>Смещение SRT</b>"
+
+msgid ""
+"Add (or subtract) an offset (in milliseconds)\n"
+"to the start of the SRT subtitle track.\n"
+"\n"
+"Often, the start of an external SRT file\n"
+"does not coincide with the start of the video.\n"
+"This setting allows you to synchronize the files."
+msgstr ""
+
+msgid "Set the first chapter to encode."
+msgstr "Установить первую главу для кодирования."
+
+msgid "through"
+msgstr "по"
+
+msgid "Set the last chapter to encode."
+msgstr "Установить последнюю главу для кодирования."
+
+msgid "Duration:"
+msgstr "Продолжительность:"
+
+msgid "Destination Directory"
+msgstr "Каталог назначения"
+
+msgid "Destination directory for your encode."
+msgstr "Папка назначения для перекодированных файлов."
+
+msgid "Destination filename for your encode."
+msgstr "Название папки для перекодированных файлов."
+
+msgid "Format to mux encoded tracks to."
+msgstr "Формат мультиплексора кодирования треков."
+
+msgid "iPod 5G Support"
+msgstr "Поддержка iPod 5G"
+
+msgid "Add iPod Atom needed by some older iPods."
+msgstr "Добавить iPod Atom, необходимый некоторым старым плеерам."
+
+msgid "Web optimized"
+msgstr "Веб оптимизация"
+
+msgid ""
+"Optimize the layout of the MP4 file for progressive download. This allows a "
+"player to initiate playback before downloading the entire file."
+msgstr ""
+"Оптимизировать структуру файлов MP4 для последовательной загрузки. Это "
+"позволяет проигрывателю начать воспроизведение до загрузки всего файла."
+
+msgid "Large file (>4GB)"
+msgstr "Большой файл (>4GB)"
+
+msgid ""
+"Allow 64 bit MP4 file which can be over 4GB.\n"
+"\n"
+" <b>Caution:</b> This option may break device compatibility."
+msgstr ""
+"Разрешить 64 битный MP4 файл, который может быть более 4 ГБ.\n"
+"\n"
+" <b>Внимание:</b> Эта опция может сломать совместимость устройств."
+
+msgid "<b><u>D</u>estination</b>"
+msgstr "<b><u>Н</u>азначение</b>"
+
+msgid "Source Codec:"
+msgstr "Кодек источника:"
+
+msgid "Dimensions:"
+msgstr "Размер:"
+
+msgid "Aspect: "
+msgstr "Соотношение сторон: "
+
+msgid "Frame Rate:"
+msgstr "Частота кадров:"
+
+msgid "<b>Source Picture Parameters</b>"
+msgstr "<b>Параметры картинки источника</b>"
+
+msgid "Autocrop:"
+msgstr "Автокадрирование:"
+
+msgid "On"
+msgstr "Вкл"
+
+msgid "Crop:"
+msgstr "Кадрирование:"
+
+msgid "Scale Dimensions:"
+msgstr "Масштаб:"
+
+msgid "Optimal for Source:"
+msgstr "Оптимально для источника:"
+
+msgid "Off"
+msgstr "Вкл"
+
+msgid "Anamorphic:"
+msgstr "Анаморфотный:"
+
+msgid "<b>Scaling</b>"
+msgstr "<b>Масштабирование</b>"
+
+msgid "Presentation Dimensions:"
+msgstr "Размеры презентации:"
+
+msgid "Summary"
+msgstr "Описание"
+
+msgid "Video Encoder:"
+msgstr "Видео кодеки:"
+
+msgid "Available video encoders."
+msgstr "Доступные видео кодеки."
+
+msgid "Framerate:"
+msgstr "Частота кадров:"
+
+msgid ""
+"Output framerate. 'Same as source' is recommended. If your source video has "
+"a variable framerate, 'Same as source' will preserve it."
+msgstr ""
+"Частота кадров на выходе. Рекомендуется 'Так же, как в источнике'. Если "
+"исходное видео имеет переменную частоту кадров, выбор 'Так же, как в "
+"источнике' сохранит ее."
+
+msgid "Constant Framerate"
+msgstr "Постоянная частота кадров"
+
+msgid ""
+"Enables variable framerate output with a peak rate determined by the "
+"framerate setting. VFR is not compatible with some players."
+msgstr ""
+"Включает переменную частоту кадров на выходе с пиковой скоростью, "
+"определенной настройкой частоты кадров. VFR не совместим с некоторыми "
+"проигрывателями."
+
+msgid "Peak Framerate (VFR)"
+msgstr "Пик частоты кадров (VFR)"
+
+msgid ""
+"Enables variable framerate output. VFR is not compatible with some players."
+msgstr ""
+"Включает переменную частоту кадров на выходе. VFR не совместим с некоторыми "
+"проигрывателями."
+
+msgid "Variable Framerate"
+msgstr "Переменная частота кадров"
+
+msgid ""
+"Set the desired quality factor. The encoder targets a certain quality. The "
+"scale used by each video encoder is different. \n"
+"\n"
+" x264's scale is logarithmic and lower values coorespond to "
+"higher quality. So small decreases in value will result in progressively "
+"larger increases in the resulting file size. A value of 0 means lossless "
+"and will result in a file size that is larger than the original source, "
+"unless the source was also lossless.\n"
+"\n"
+" FFMpeg's and Theora's scale is more linear. These encoders do "
+"not have a lossless mode."
+msgstr ""
+
+msgid "Constant Quality:"
+msgstr "Постоянное качество:"
+
+msgid ""
+"Set the average bitrate. The instantaneous bitrate can be much higher or "
+"lower at any point in time. But the average over a long duration will be "
+"the value set here. If you need to limit instantaneous bitrate, look into "
+"x264's vbv-bufsize and vbv-maxrate settings."
+msgstr ""
+
+msgid "Bitrate (kbps): "
+msgstr "Битрейт (кбит/с): "
+
+msgid ""
+"Set the average bitrate. The instantaneous bitrate can be much higher or "
+"lower at any point in time. But the average over a long duration will be "
+"the value set here. If you need to limit instantaneous bitrate, look into "
+"x264 vbv-bufsize and vbv-maxrate."
+msgstr ""
+
+msgid ""
+"Perform 2 Pass Encoding. The 'Bitrate' option is prerequisite. During the "
+"1st pass, statistics about the video are collected. Then in the second "
+"pass, those statistics are used to make bitrate allocation decisions."
+msgstr ""
+
+msgid "2-Pass Encoding"
+msgstr "Кодировка в 2-прохода"
+
+msgid ""
+"During the 1st pass of a 2 pass encode, use settings that speed things along."
+msgstr ""
+"Во время 1-го проход при 2-х проходном кодировании используйте настройки "
+"скоростного прохода."
+
+msgid "Turbo First Pass"
+msgstr "Первый проход турбо"
+
+msgid ""
+"Use advanced options Tab for x264 settings.\n"
+"\n"
+" Use at your own risk!"
+msgstr ""
+"Используйте вкладку дополнительных настроек для настройки x264. \n"
+"\n"
+" Используйте на свой страх и риск!"
+
+msgid "Use Advanced Options"
+msgstr "Использовать дополнительные параметры"
+
+msgid "x264 Preset:"
+msgstr "Предустановки x264:"
+
+msgid ""
+"Adjusts x264 settings to trade off compression efficiency against encoding "
+"speed.\n"
+"\n"
+" This establishes your default x264 settings. Tunes, profiles, "
+"levels and advanced option string will be applied to this.\n"
+"\n"
+" You should generally set this option to the slowest you can bear "
+"since slower settings will result in better quality or smaller files."
+msgstr ""
+
+msgid "x264 Tune:"
+msgstr "Настройки x264 :"
+
+msgid ""
+"Tune settings to optimize for common scenarios.\n"
+"\n"
+" This can improve effeciency for particular source "
+"characteristics or set characteristics of the output file.\n"
+"\n"
+" Changes will be applied after the preset but before all other "
+"parameters."
+msgstr ""
+"Настройки параметров оптимизированных для выполнения типовых сценариев.\n"
+"\n"
+" Это может улучшить содержание для конкретных характеристик "
+"исходного или заданных характеристик выходного файла.\n"
+"\n"
+" Изменения вступят в силу по завершении установленных заранее, но "
+"перед всеми другими параметрами."
+
+msgid ""
+"Reduce decoder CPU usage.\n"
+"\n"
+" Set this if your device is struggling to play the output "
+"(dropped frames)."
+msgstr ""
+"Уменьшает использование CPU при декодировании.\n"
+"\n"
+" Установите ее, если ваше устройство испытывает затруднения с "
+"воспроизведением на выходе (пропускает кадры)."
+
+msgid "Fast Decode"
+msgstr "Быстрое кодирование"
+
+msgid ""
+"Minimize latency between input to encoder and output of decoder.\n"
+"\n"
+" This is useful for broadcast of live streams.\n"
+" Since HandBrake is not suitable for live stream broadcast "
+"purposes, this setting is of little value here."
+msgstr ""
+
+msgid "Zero Latency"
+msgstr "Нулевая задержка"
+
+msgid "H.264 Profile:"
+msgstr "Профиль x264:"
+
+msgid ""
+"Limit the H.264 profile of the output stream.\n"
+"\n"
+" Overrides all other settings."
+msgstr ""
+"Профиль ограничения вывода потока H.264.\n"
+"\n"
+" Доминирует над всеми остальными настройками."
+
+msgid "H.264 Level:"
+msgstr "Уровень x264:"
+
+msgid ""
+"Sets and ensures compliance with the specified H.264 level.\n"
+"\n"
+" Overrides all other settings."
+msgstr ""
+
+msgid "More Settings:"
+msgstr "Дополнительно:"
+
+msgid ""
+"Additional x264 settings.\n"
+"\n"
+" Colon separated list of x264 options."
+msgstr ""
+"Дополнительные настройки x264.\n"
+"\n"
+" Список вариантов опций разделять двоеточиями x264."
+
+msgid "Video"
+msgstr "Видео"
+
+msgid "Add new audio settings to the list"
+msgstr "Добавить новые аудио настройки в список"
+
+msgid "Remove the selected audio settings"
+msgstr "Удалить выбранные настройки звука"
+
+msgid "Auto Passthru:"
+msgstr "Авто-выбор декодера:"
+
+msgid ""
+"Enable this if your playback device supports AAC. This permits AAC passthru "
+"to be selected when automatic passthru selection is enabled."
+msgstr ""
+
+msgid ""
+"Enable this if your playback device supports AC-3. This permits AC-3 "
+"passthru to be selected when automatic passthru selection is enabled."
+msgstr ""
+
+msgid ""
+"Enable this if your playback device supports DTS. This permits DTS passthru "
+"to be selected when automatic passthru selection is enabled."
+msgstr ""
+
+msgid ""
+"Enable this if your playback device supports DTS-HD. This permits DTS-HD "
+"passthru to be selected when automatic passthru selection is enabled."
+msgstr ""
+
+msgid "Passthru Fallback:"
+msgstr "Резервный декодер:"
+
+msgid ""
+"Set the audio codec to encode with when a suitable track can not be found "
+"for audio passthru."
+msgstr ""
+"Установить аудио кодек для кодирования с тем, что бы использовать когда "
+"подходящий декодер не найден."
+
+msgid "Track Name:"
+msgstr "Название дорожки:"
+
+msgid ""
+"Set the audio track name. Players may use this in the audio selection list."
+msgstr ""
+"Установить название звуковой дорожки. Проигрыватели могут использовать это "
+"списке выбора звука. "
+
+msgid "Sample Rate:"
+msgstr "Частота дискретизации:"
+
+msgid "Set the sample rate of the output audio track."
+msgstr "Установить частоту дискретизации дорожки вывода звука."
+
+msgid "Gain:"
+msgstr "Усиление:"
+
+msgid ""
+"<b>Audio Gain:</b> Adjust the amplification or attenuation of the output "
+"audio track."
+msgstr ""
+"<b>Усиление звука:</b> Регулирует усиление или ослабление звуковой дорожки "
+"вывода."
+
+msgid ""
+"<b>Dynamic Range Compression:</b> Adjust the dynamic range of the output "
+"audio track. \n"
+"\n"
+" For source audio that has a wide dynamic "
+"range (very loud and very soft sequences), DRC allows you to 'compress' the "
+"range by making loud sections softer and soft sections louder."
+msgstr ""
+"<b>Динамическое сжатие диапазона:</b> Устанавливает динамический диапазон "
+"для звуковой дорожки вывода. \n"
+"\n"
+" Для источника звука, который имеет широкий "
+"динамический диапазона (очень громкие и очень мягкие последовательности), "
+"DRC позволяет «сжимать» диапазон, делая громкие разделы мягче и мягкие "
+"разделы громче."
+
+msgid ""
+"<b>Dynamic Range Compression:</b> Adjust the dynamic range of the output "
+"audio track. \n"
+"\n"
+" For source audio that has a wide dynamic "
+"range (very loud and very soft sequences), DRC allows you to 'compress' the "
+"range by making loud sections softer and soft sections louder."
+msgstr ""
+"<b>Динамическое сжатие диапазона:</b> Устанавливает динамический диапазон "
+"для звуковой дорожки вывода. \n"
+"\n"
+" Для источника звука, который имеет "
+"широкий динамический диапазона (очень громкие и очень мягкие "
+"последовательности), DRC позволяет «сжимать» диапазон, делая громкие разделы "
+"мягче и мягкие разделы громче."
+
+msgid "Quality:"
+msgstr "Качество:"
+
+msgid ""
+"<b>Quality:</b> For output codec's that support it, adjust the quality of "
+"the output.</b>"
+msgstr ""
+"<b>Качество:</b> Для выходного кодека, который поддерживают это, установить "
+"качество вывода.</b>"
+
+msgid "Track"
+msgstr "Дорожка"
+
+msgid "Encoder"
+msgstr "Кодек"
+
+msgid "Bitrate"
+msgstr "Битрэйт"
+
+msgid "Mix"
+msgstr "Микшер"
+
+msgid "List of audio tracks available from your source."
+msgstr "Список доступных в источнике звуковых дорожек."
+
+msgid "Set the audio codec to encode this track with."
+msgstr "Установить аудио кодек для кодирования этой дорожки."
+
+msgid "Set the bitrate to encode this track with."
+msgstr "Установить битрейт для кодирования этой дорожки."
+
+msgid "Set the mixdown of the output audio track."
+msgstr "Установить микширование выходной звуковой дорожки."
+
+msgid "Audio"
+msgstr "Аудио"
+
+msgid "Add new subtitle to the list"
+msgstr "Добавить новый список субтитров"
+
+msgid "Add new SRT subtitle to the list"
+msgstr "Добавить новый список субтитров SRT"
+
+msgid "Remove the selected subtitle settings"
+msgstr "Удалить выбранные настройки субтитров"
+
+msgid "Language"
+msgstr "Язык"
+
+msgid "Character Code"
+msgstr "Кодировка"
+
+msgid "File"
+msgstr "Файл"
+
+msgid "Offset (ms)"
+msgstr "Смещение (мс)"
+
+msgid "List of subtitle tracks available from your source."
+msgstr "Список дорожек субтитров доступных из источника."
+
+msgid ""
+"Set the language of this subtitle. This value will be used by players in "
+"subtitle menus."
+msgstr ""
+"Установить язык этих субтитров. Это значение будет использоваться "
+"проигрывателями в меню субтитров."
+
+msgid ""
+"Set the character code used by the SRT file you are importing. SRTs come in "
+"all flavours of character sets. We translate the character set to UTF-8. "
+"The source's character code is needed in order to perform this translation."
+msgstr ""
+
+msgid "Srt File"
+msgstr "Файл srt"
+
+msgid "Select the SRT file to import."
+msgstr "Выберите файл srt для импорта."
+
+msgid "Adjust the offset in milliseconds between video and SRT timestamps"
+msgstr "Установить смещение в миллисекундах между видео и метками времени SRT"
+
+msgid "Subtitles"
+msgstr "Субтитры"
+
+msgid "<small>Reference Frames:</small>"
+msgstr "<small>Ссылочные фреймы:</small>"
+
+msgid ""
+"Sane values are ~1-6. The more you add, the better the compression, but the "
+"slower the encode. Cel animation tends to benefit from more reference "
+"frames a lot more than film content. Note that many hardware devices have "
+"limitations on the number of supported reference frames, so if you're "
+"encoding for a handheld or standalone player, don't touch this unless you're "
+"absolutely sure you know what you're doing!"
+msgstr ""
+
+msgid "<small>Maximum B-Frames:</small>"
+msgstr "<small>Максимальные B-кадры:</small>"
+
+msgid ""
+"Sane values are ~2-5. This specifies the maximum number of sequential B-"
+"frames that the encoder can use. Large numbers generally won't help "
+"significantly unless Adaptive B-frames is set to Optimal. Cel-animated "
+"source material and B-pyramid also significantly increase the usefulness of "
+"larger values. Baseline profile, as required for iPods and similar devices, "
+"requires B-frames to be set to 0 (off)."
+msgstr ""
+
+msgid "<small>Pyramidal B-Frames:</small>"
+msgstr "<small>Пирамидальные B-кадры:</small>"
+
+msgid ""
+"B-pyramid improves compression by creating a pyramidal structure (hence the "
+"name) of B-frames, allowing B-frames to reference each other to improve "
+"compression. Requires Max B-frames greater than 1; optimal adaptive B-"
+"frames is strongly recommended for full compression benefit."
+msgstr ""
+
+msgid "<small>Weighted P-Frames:</small>"
+msgstr "<small>Взвешенные P-кадры:</small>"
+
+msgid ""
+"Performs extra analysis to decide upon weighting parameters for each frame. "
+"This improves overall compression slightly and improves the quality of fades "
+"greatly. Baseline profile, as required for iPods and similar devices, "
+"requires weighted P-frame prediction to be disabled. Note that some devices "
+"and players, even those that support Main Profile, may have problems with "
+"Weighted P-frame prediction: the Apple TV is completely incompatible with "
+"it, for example."
+msgstr ""
+
+msgid ""
+"The 8x8 transform is the single most useful feature of x264 in terms of "
+"compression-per-speed. It improves compression by at least 5% at a very "
+"small speed cost and may provide an unusually high visual quality benefit "
+"compared to its compression gain. However, it requires High Profile, which "
+"many devices may not support."
+msgstr ""
+
+msgid "8x8 Transform"
+msgstr "Преобразование 8x8 "
+
+msgid ""
+"After the encoder has done its work, it has a bunch of data that needs to be "
+"compressed losslessly, similar to ZIP or RAR. H.264 provides two options "
+"for this: CAVLC and CABAC. CABAC decodes a lot slower but compresses "
+"significantly better (10-30%), especially at lower bitrates. If you're "
+"looking to minimize CPU requirements for video playback, disable this "
+"option. Baseline profile, as required for iPods and similar devices, "
+"requires CABAC to be disabled."
+msgstr ""
+
+msgid "CABAC Entropy Encoding"
+msgstr "Энтропийное кодирование CABAC"
+
+msgid "<small><b>Encoding Features</b></small>"
+msgstr "<small><b>Функции кодирования</b></small>"
+
+msgid "<small>Motion Est. Method:</small>"
+msgstr "<small>Метод движения Est.:</small>"
+
+msgid ""
+"Controls the motion estimation method. Motion estimation is how the encoder "
+"estimates how each block of pixels in a frame has moved. A better motion "
+"search method improves compression at the cost of speed.\n"
+"\n"
+" Diamond: performs an extremely fast and simple search using a "
+"diamond pattern.\n"
+"\n"
+" Hexagon: performs a somewhat more effective but slightly slower "
+"search using a hexagon pattern.\n"
+"\n"
+" Uneven Multi-Hex: performs a very wide search using a variety of "
+"patterns, more accurately capturing complex motion.\n"
+"\n"
+" Exhaustive: performs a \"dumb\" search of every pixel in a wide "
+"area. Significantly slower for only a small compression gain.\n"
+"\n"
+" Transformed Exhaustive: Like exhaustive, but makes even more "
+"accurate decisions. Accordingly, somewhat slower, also for only a small "
+"improvement."
+msgstr ""
+
+msgid "<small>Subpel ME & Mode:</small>"
+msgstr ""
+
+msgid ""
+"This setting controls both subpixel-precision motion estimation and mode "
+"decision methods.\n"
+"\n"
+" Subpixel motion estimation is used for refining motion estimates "
+"beyond mere pixel accuracy, improving compression.\n"
+"\n"
+" Mode decision is the method used to choose how to encode each block "
+"of the frame: a very important decision.\n"
+"\n"
+" SAD is the fastest method, followed by SATD, RD, RD refinement, and "
+"the slowest, QPRD.\n"
+"\n"
+" 6 or higher is strongly recommended: Psy-RD, a very powerful psy "
+"optimization that helps retain detail, requires RD.\n"
+"\n"
+" 11 disables all early terminations in analysis.\n"
+"\n"
+" 10 and 11, the most powerful and slowest options, require adaptive "
+"quantization (aq-mode > 0) and trellis 2 (always)."
+msgstr ""
+
+msgid "<small>Motion Est. Range:</small>"
+msgstr "<small>Диапазон движения Est.:</small>"
+
+msgid ""
+"This is the distance x264 searches from its best guess at the motion of a "
+"block in order to try to find its actual motion. The default is fine for "
+"most content, but extremely high motion video, especially at HD resolutions, "
+"may benefit from higher ranges, albeit at a high speed cost."
+msgstr ""
+
+msgid "<small>Adaptive Direct Mode:</small>"
+msgstr "<small>Прямой адаптивный режим:</small>"
+
+msgid ""
+"H.264 allows for two different prediction modes, spatial and temporal, in B-"
+"frames.\n"
+"\n"
+" Spatial, the default, is almost always better, but temporal is "
+"sometimes useful too.\n"
+"\n"
+" x264 can, at the cost of a small amount of speed (and accordingly "
+"for a small compression gain), adaptively select which is better for each "
+"particular frame."
+msgstr ""
+
+msgid "<small>Adaptive B-Frames:</small>"
+msgstr "<small>Адаптивные B-кадры:</small>"
+
+msgid ""
+"x264 has a variety of algorithms to decide when to use B-frames and how many "
+"to use.\n"
+"\n"
+" Fast mode takes roughly the same amount of time no matter how many B-"
+"frames you specify. However, while fast, its decisions are often "
+"suboptimal.\n"
+"\n"
+" Optimal mode gets slower as the maximum number of B-Frames "
+"increases, but makes much more accurate decisions, especially when used with "
+"B-pyramid."
+msgstr ""
+
+msgid "<small>Partitions:</small>"
+msgstr "<small>Разделы:</small>"
+
+msgid ""
+"Mode decision picks from a variety of options to make its decision: this "
+"option chooses what options those are. Fewer partitions to check means "
+"faster encoding, at the cost of worse decisions, since the best option might "
+"have been one that was turned off."
+msgstr ""
+
+msgid "<small>Trellis:</small>"
+msgstr "<small>Решетчатое кодирование:</small>"
+
+msgid ""
+"Trellis fine-tunes the rounding of transform coefficients to squeeze out "
+"3-5% more compression at the cost of some speed. \"Always\" uses trellis not "
+"only during the main encoding process, but also during analysis, which "
+"improves compression even more, albeit at great speed cost. Trellis costs "
+"more speed at higher bitrates and requires CABAC."
+msgstr ""
+
+msgid "<small><b>Analysis</b></small>"
+msgstr "<small><b>Анализ</b></small>"
+
+msgid "<small>Adaptive Quantization Strength:</small>"
+msgstr "<small>Адаптивная сила квантования:</small>"
+
+msgid ""
+"Adaptive quantization controls how the encoder distributes bits across the "
+"frame. Higher values take more bits away from edges and complex areas to "
+"improve areas with finer detail."
+msgstr ""
+
+msgid "<small>Psychovisual Rate Distortion:</small>"
+msgstr "<small>Соотношение психовизуального искажения:</small>"
+
+msgid ""
+"Psychovisual rate-distortion optimization takes advantage of the "
+"characteristics of human vision to dramatically improve apparent detail and "
+"sharpness. The effect can be made weaker or stronger by adjusting the "
+"strength. Being an RD algorithm, it requires mode decision to be at least "
+"\"6\"."
+msgstr ""
+"Психовизуальная оптимизация соотношению сигнал-шум использует преимущества "
+"характеристик человеческого зрения, чтобы значительно улучшить детали и "
+"резкость. Эффект можно ослабить или усилить, регулируя силу. Алгоритм RD "
+"требует по меньшей мере установки режима \"6\"."
+
+msgid "<small>Psychovisual Trellis:</small>"
+msgstr "<small>Психовизуальное решетчатое:</small>"
+
+msgid ""
+"Psychovisual trellis is an experimental algorithm to further improve "
+"sharpness and detail retention beyond what Psychovisual RD does. "
+"Recommended values are around 0.2, though higher values may help for very "
+"grainy video or lower bitrate encodes. Not recommended for cel animation "
+"and other sharp-edged graphics."
+msgstr ""
+
+msgid "Deblocking: "
+msgstr "Деблокирование: "
+
+msgid ""
+"H.264 has a built-in deblocking filter that smooths out blocking artifacts "
+"after decoding each frame. This not only improves visual quality, but also "
+"helps compression significantly. The deblocking filter takes a lot of CPU "
+"power, so if you're looking to minimize CPU requirements for video playback, "
+"disable it.\n"
+"\n"
+" The deblocking filter has two adjustable parameters, \"strength"
+"\" (Alpha) and \"threshold\" (Beta). The former controls how strong (or "
+"weak) the deblocker is, while the latter controls how many (or few) edges it "
+"applies to. Lower values mean less deblocking, higher values mean more "
+"deblocking. The default is 0 (normal strength) for both parameters."
+msgstr ""
+
+msgid ""
+"x264 normally zeroes out nearly-empty data blocks to save bits to be better "
+"used for some other purpose in the video. However, this can sometimes have "
+"slight negative effects on retention of subtle grain and dither. Don't "
+"touch this unless you're having banding issues or other such cases where you "
+"are having trouble keeping fine noise."
+msgstr ""
+"x264 обычно обнуляет почти пустые блоки данных для сохранения битов, которые "
+"будут лучше использовать для других целей в видео. Тем не менее, иногда это "
+"может иметь небольшое отрицательное воздействие на сохранение тонких мелких "
+"частиц и размытие. Не касайтесь этого, если не имеете проблем хранения "
+"мелких шумов."
+
+msgid "No DCT Decimate"
+msgstr "Не опустошать DCT"
+
+msgid "<small><b>Psychovisual</b></small>"
+msgstr "<small><b>Психовизуальное</b></small>"
+
+msgid ""
+"Your selected options will appear here. \n"
+" You can edit these and add additional options. \n"
+"\n"
+" Default values will not be shown. The defaults are:\n"
+" ref=3:bframes=3:b-adapt=fast:direct=spatial:\n"
+" b-pyramid=normal:weightp=2:me=hex:merange=16:\n"
+" subme=7:partitions=p8x8,b8x8,i8x8,i4x4:8x8dct=1:\n"
+" deblock=0,0:trellis=1:psy-rd=1,0:aq-strength=1.0:\n"
+" no-fast-pskip=0:no-dct-decimate=0:cabac=1"
+msgstr ""
+
+msgid "<small><b>Current x264 Advanced Option String</b></small>"
+msgstr "<small><b>Дополнительная строка текущей опции x264</b></small>"
+
+msgid ""
+"Your selected options will appear here. \n"
+" You can edit these and add additional options."
+msgstr ""
+
+msgid "<small><b>Current FFMpeg Advanced Option String</b></small>"
+msgstr "<small><b>Дополнительная строка текущей опции FFMpeg</b></small>"
+
+msgid "Advanced"
+msgstr "Дополнительно"
+
+msgid "Add chapter markers to output file."
+msgstr "Добавить маркеры глав в выходной файл."
+
+msgid "Chapter Markers"
+msgstr "Маркеры глав"
+
+msgid "Chapters"
+msgstr "Главы"
+
+msgid "Title:"
+msgstr "Название:"
+
+msgid "Actors:"
+msgstr "Актеры:"
+
+msgid "Director:"
+msgstr "Режиссёр:"
+
+msgid "Release Date:"
+msgstr "Дата выпуска:"
+
+msgid "Comment:"
+msgstr "Комментарий:"
+
+msgid "Genre:"
+msgstr "Жанр:"
+
+msgid "Description:"
+msgstr "Описание:"
+
+msgid "Plot:"
+msgstr "Сюжет:"
+
+msgid "Tags"
+msgstr "Теги"
+
+msgid "_Save"
+msgstr "_Сохранить"
+
+msgid "Save current settings to new preset."
+msgstr "Сохранить текущие настройки в новую предустановку."
+
+msgid "Delete the currently selected preset."
+msgstr "Удалить сейчас выбранную предустановку."
+
+msgid "_Options"
+msgstr "_Параметры"
+
+msgid "Preset Options"
+msgstr "Параметры предустановок"
+
+msgid "<b>Presets</b>"
+msgstr "<b>Предустановки</b>"
+
+msgid "Preferences"
+msgstr "Параметры"
+
+msgid "Automatically check for updates"
+msgstr "Автоматически проверять наличие обновлений"
+
+msgid "When all encodes are complete"
+msgstr "Когда все кодирование завершено"
+
+msgid "Use automatic naming (uses modified source name)"
+msgstr ""
+"Использовать автоматический идентификатор (использует измененное исходное "
+"имя)"
+
+msgid "Add chapters to destination name"
+msgstr "Добавить главы в имя назначения"
+
+msgid "Add title # to destination name"
+msgstr "Добавить название # в имя назначения"
+
+msgid "Use iPod/iTunes friendly (.m4v) file extension for MP4"
+msgstr "Использовать дружественное iPod/iTunes расширение файла (.m4v) для MP4"
+
+msgid "Number of previews"
+msgstr "Число миниатюр"
+
+msgid "Filter short titles (seconds)"
+msgstr "Фильтр коротких наименований (в секундах)"
+
+msgid "Show system tray icon"
+msgstr "Показывать значек в системном лотке"
+
+msgid "General"
+msgstr "Общие"
+
+msgid "Preferred Language:"
+msgstr "Предпочитаемый язык:"
+
+msgid "DUB Foreign language audio"
+msgstr "Дублированный иностранный язык аудио"
+
+msgid "Use foreign language audio and add subtitles"
+msgstr "Использовать иностранный язык аудио и добавлять субтитры"
+
+msgid "Add Closed Captions when available"
+msgstr "Добавлять субтитры для глухих когда возможно"
+
+msgid "Audio/Subtitles"
+msgstr "Аудио/субтитры"
+
+msgid "Constant Quality fractional granularity"
+msgstr "Постоянное качество детализации"
+
+msgid "Use dvdnav (instead of libdvdread)"
+msgstr "Использовать dvdnav (вместо libdvdread)"
+
+msgid "Put individual encode logs in same location as movie"
+msgstr ""
+"Класть индивидуальные логи кодирования в то же расположение что и фильм"
+
+msgid "Activity Log Verbosity Level"
+msgstr "Подробный журнал уровня деятельности"
+
+msgid "Activity Log Longevity"
+msgstr "Долговечный журнала операций"
+
+msgid "Scale down High Definition previews"
+msgstr "Уменьшать высокий размер просмотра"
+
+msgid "Automatically Scan DVD when loaded"
+msgstr "Автоматически сканировать DVD при загрузке"
+
+msgid "Scans the DVD whenever a new disc is loaded"
+msgstr "Сканировать DVD после загрузки нового диска"
+
+msgid "Enable Advanced Auto-Passthru options"
+msgstr "Включить дополнительные опции авто-выбора декодера"
+
+msgid ""
+"Enabling this adds extra widgets to the audio panel that allow\n"
+" you to specify which particular codecs shall be passed\n"
+" and which codec to use when passthru is not possible"
+msgstr ""
+
+msgid "Hide Advanced Video Options Tab"
+msgstr "Скрыть вкладку дополнительной настройки видео"
+
+msgid ""
+"Use advanced video options at your own risk.\n"
+"We recommend that you use the controls available\n"
+"on the Video tab instead."
+msgstr ""
+
+msgid "Allow Tweaks"
+msgstr "Разрешить тонкие настройки"
+
+msgid "Allow HandBrake For Dummies"
+msgstr ""
+
+msgid "Setting:"
+msgstr "Настройка:"
+
+msgid "Folder Name:"
+msgstr "Имя папки::"
+
+msgid "Preset Name:"
+msgstr "Название предустановки:"
+
+msgid "<b>Custom Picture Dimensions</b>"
+msgstr "<b>Пользовательский размер изображения</b>"
+
+msgid "Maximum Width:"
+msgstr "Максимальная ширина:"
+
+msgid "Enable maximum width limit."
+msgstr "Включить лимит максимальной ширины."
+
+msgid ""
+"This is the maximum width that the video will be stored at. Whenever a new "
+"source is loaded, this value will be applied if the source width is greater. "
+"Setting this to 0 means there is no maximum width."
+msgstr ""
+
+msgid "Maximum Height:"
+msgstr "Максимальная высота:"
+
+msgid "Enable maximum height limit."
+msgstr "Включить лимит максимальной высоты."
+
+msgid ""
+"This is the maximum height that the video will be stored at. Whenever a new "
+"source is loaded, this value will be applied if the source height is "
+"greater. Setting this to 0 means there is no maximum height."
+msgstr ""
+
+msgid "<b>Description</b>"
+msgstr "<b>Описание</b>"
+
+msgid "HandBrake Queue"
+msgstr "Очередь"
+
+msgid "Start"
+msgstr "Старт"
+
+msgid "Pause"
+msgstr "Пауза"
+
+msgid "Edit"
+msgstr "Изменить"
+
+msgid "_Start"
+msgstr "_Старт"
+
+msgid "_Pause"
+msgstr "_Пауза"
+
+msgid "_Edit"
+msgstr "_Изменить"
+
+msgid "Open Preview Window"
+msgstr "Открыть окно предварительного просмотра"
+
+msgid "Show Preview"
+msgstr "Предварительный просмотр"
+
+msgid "Left Crop"
+msgstr "Обрезка слева"
+
+msgid "Top Crop"
+msgstr "Обрезка сверху"
+
+msgid "Bottom Crop"
+msgstr "Обрезка снизу"
+
+msgid "Right Crop"
+msgstr "Обрезка справа"
+
+msgid "Auto Crop"
+msgstr "Автокадрирование"
+
+msgid "Automatically crop black borders around edges of the video."
+msgstr "Автоматически обрезать черные полосы по краям видео."
+
+msgid "Loose Crop"
+msgstr "Произвольное кадрирование"
+
+msgid "Loose"
+msgstr "Произвольно"
+
+msgid "Crop Dimensions:"
+msgstr "Размер:"
+
+msgid "<b>Cropping</b>"
+msgstr "<b>Кадрирование</b>"
+
+msgid "width:"
+msgstr "Ширина:"
+
+msgid ""
+"This is the width that the video will be stored at. The actual display "
+"dimensions will differ if the pixel aspect ratio is not 1:1."
+msgstr ""
+
+msgid "height:"
+msgstr "Высота:"
+
+msgid ""
+"This is the height that the video will be stored at. The actual display "
+"dimensions will differ if the pixel aspect ratio is not 1:1."
+msgstr ""
+
+msgid "Optimal for source"
+msgstr "Оптимально для источника"
+
+msgid ""
+"If enabled, select the 'optimal' storage resolution. This will be the "
+"resolution that most closely matches the source resolution after cropping."
+msgstr ""
+
+msgid ""
+"<b>Anamorphic Modes:</b>\n"
+"<small><tt>\n"
+"None - Force pixel aspect ratio to 1:1.\n"
+"Loose - Align dimensions to chosen 'Alignment' value \n"
+" and pick pixel aspect ratio that preserves the\n"
+" original display aspect ratio\n"
+"Strict - Keep original source dimensions and pixel \n"
+" aspect ratio</tt></small>"
+msgstr ""
+
+msgid "Alignment:"
+msgstr "Выравнивание:"
+
+msgid ""
+"Align storage dimensions to multiples of this value.\n"
+"\n"
+"Encoders are most effecient when the video dimensions are aligned to some "
+"specific value (usually 16). Setting this to some other value will result in "
+"slightly larger file size."
+msgstr ""
+
+msgid "<b>Storage</b>"
+msgstr "<b>Разрешение</b>"
+
+msgid ""
+"This is the display width. It is the result of scaling the storage "
+"dimensions by the pixel aspect."
+msgstr ""
+
+msgid "Pixel Aspect:"
+msgstr "Соотношение пикселей:"
+
+msgid ""
+"Pixel aspect defines the shape of the pixels. A 1:1 ratio defines a square "
+"pixel. Other values define rectangular shapes. Players will scale the image "
+"in order to achieve the specified aspect."
+msgstr ""
+
+msgid ""
+"If enabled, the original display aspect of the source will be maintained."
+msgstr ""
+"Если включено, оригинальный формата соотношения источника будет сохранен."
+
+msgid "Display Aspect:"
+msgstr "Соотношение:"
+
+msgid "<b>Display</b>"
+msgstr "<b> Отображение</b>"
+
+msgid "Dimensions"
+msgstr "Размер"
+
+msgid "Grayscale"
+msgstr "Градации серого"
+
+msgid "If enabled, filter colour components out of video."
+msgstr "Если включено, фильтр выходных компонентов цвета из видео."
+
+msgid "Deblock:"
+msgstr "Разделять блоки:"
+
+msgid ""
+"The deblocking filter removes a common type of compression artifact. If your "
+"source exhibits 'blockiness', this filter may help clean it up."
+msgstr ""
+
+msgid "Denoise:"
+msgstr "Шумоподавление:"
+
+msgid ""
+"The denoise filter is a low pass filter that removes noise. Film grain and "
+"other types of high frequency noise are difficult to compress. Using this "
+"filter on such sources can result in smaller file sizes."
+msgstr ""
+
+msgid ""
+"Custom denoise filter string format\n"
+" SpatialLuma:SpatialChroma:TemporalLuma:TemporalChroma"
+msgstr ""
+"Пользовательский фильтр удаления шумов формата\n"
+" SpatialLuma:SpatialChroma:TemporalLuma:TemporalChroma"
+
+msgid "Detelecine:"
+msgstr "Обратная телекинопроекция:"
+
+msgid ""
+"This filter removes 'combing' artifacts that are the result of telecining. "
+"Telecining is a process that adjusts film framerates that are 24fps to NTSC "
+"video frame rates which are 30fps."
+msgstr ""
+
+msgid ""
+"Custom detelecine filter string format\n"
+" JunkLeft:JunkRight:JunkTop:JunkBottom:StrictBreaks:MetricPlane:Parity"
+msgstr ""
+
+msgid "Decomb"
+msgstr "Убрать гребенку"
+
+msgid ""
+"Choose decomb or deinterlace filter options.\n"
+"\n"
+"The decomb filter selectively deinterlaces frames that appear to be "
+"interlaced. This will preserve quality in frames that are not interlaced.\n"
+"\n"
+"The classic deinterlace filter is applied to all frames. Frames that are not "
+"interlaced will suffer some quality degradation."
+msgstr ""
+
+msgid "Deinterlace"
+msgstr "Деинтерлейсинг"
+
+msgid "Decomb:"
+msgstr "Убрать гребенку:"
+
+msgid ""
+"The decomb filter selectively deinterlaces frames that appear to be "
+"interlaced. This will preserve quality in frames that are not interlaced."
+msgstr ""
+
+msgid ""
+"Custom decomb filter string format\n"
+" Mode:SpatialMetric:MotionThresh:SpatialThresh:BlockThresh:BlockWidth:"
+"BlockHeight:MagnitudeThres:VarianceThres:LaplacianThresh:DilationThresh:"
+"ErosionThresh:NoiseThresh:MaxSearchDistance:PostProcessing:Parity"
+msgstr ""
+
+msgid "Deinterlace:"
+msgstr "Деинтерлейсинг:"
+
+msgid ""
+"The classic deinterlace filter is applied to all frames. Frames that are not "
+"interlaced will suffer some quality degradation."
+msgstr ""
+
+msgid ""
+"Custom deinterlace filter string format\n"
+" YadifMode:YadifParity:McdintMode:McdeintQp"
+msgstr ""
+
+msgid "Filters"
+msgstr "Фильтры"
+
+msgid "Select preview frames."
+msgstr "Выбор кадра для миниатюры."
+
+msgid ""
+"Encode and play a short sequence of video starting from the current preview "
+"position."
+msgstr ""
+"Кодировать и воспроизводить короткие последовательности видео, начиная с "
+"текущего положения просмотра."
+
+msgid "<b>Duration:</b>"
+msgstr "<b>Продолжительность:</b>"
+
+msgid "Set the duration of the live preview in seconds."
+msgstr "Установить продолжительность предварительного просмотра в секундах."
+
+msgid "Show Cropped area of the preview"
+msgstr "Показать просмотр обрезанных областей"
+
+msgid "Show Crop"
+msgstr "Показать кадрирование"
+
+msgid "View Fullscreen Preview"
+msgstr "Вид просмотра в полный экран"
+
+msgid "Fullscreen"
+msgstr "Полный экран"
+
+msgid "Hide the picture settings window while leaving the preview visible."
+msgstr ""
+"Скрыть окно настройки изображения, оставляя видным предварительный просмотр."
+
+msgid "Hide Settings"
+msgstr "Скрыть настройки"
+
+msgid "Preview"
+msgstr "Предварительный просмотр"
+
+msgid "About HandBrake"
+msgstr "О программе"
+
+msgid "<b>A new version of HandBrake is available!</b>"
+msgstr "<b>Доступна новая версия HandBrake!</b>"
+
+msgid "HandBrake xxx is now available (you have yyy)."
+msgstr "Доступна новая версия HandBrake xxx (у вас версия yyy)."
+
+msgid "Release Notes"
+msgstr "Заметка о релизе"
+
+msgid "Skip This Version"
+msgstr "Пропустить эту версию"
+
+msgid "Remind Me Later"
+msgstr "Напомнить позже"
+
+msgid "Title Number:"
+msgstr "Номер названия:"
+
+msgid "Detected DVD devices:"
+msgstr "Обнаружено устройство DVD:"
+
+msgid "Same As Source:"
+msgstr "Так же, как в источнике:"
+
+msgid "Same As Source"
+msgstr "Так же, как в источнике"
+
+msgid "<small>Same as source</small>"
+msgstr "<small>Так же, как в источнике</small>"
+
+msgid "Same as source"
+msgstr "Так же, как в источнике"
+
+msgid "Same as source "
+msgstr "Так же, как в источнике "
+
+msgid "Source"
+msgstr "Источник"
+
+msgid "Codec"
+msgstr "Кодек"
+
+msgid "Gain"
+msgstr "Усиление"
+
+msgid "Sample Rate"
+msgstr "Частота дискретизации"
+
+msgid "Import SRT"
+msgstr "Импорт SRT"
+
+msgid "Subtitle"
+msgstr "Субтитры"
+
+msgid "Index"
+msgstr "Индекс"
+
+msgid "Duration"
+msgstr "Продолжительность"
+
+msgid "Title"
+msgstr "Название"
+
+msgid "Stop Scan"
+msgstr "Остановить сканирование"
+
+msgid "Encode Complete"
+msgstr "Кодирование завершено"
+
+msgid ""
+"Encode Complete\n"
+"Put down that cocktail, Your HandBrake queue is done!"
+msgstr ""
+"Кодирование завершено\n"
+"HandBrake завершил кодировать этот коктейль!"
+
+msgid "Put down that cocktail, Your HandBrake queue is done!"
+msgstr "HandBrake завершил кодировать этот коктейль!"
+
+msgid "HandBrake's normal, default settings."
+msgstr "Предустановка нормального качества, настройки по умолчанию."
+
+msgid ""
+"HandBrake's settings for compatibility with all Apple devices (including the "
+"iPod 6G and later). Includes Dolby Digital audio for surround sound."
+msgstr ""
+"Настройки для совместимости со всеми устройствами Apple, (в том числе iPod "
+"6G и более поздних). Включает в себя аудио Dolby Digital для объемного звука."
+
+msgid "Universal"
+msgstr "Универсальный"
+
+msgid ""
+"HandBrake's settings for playback on the iPod with Video (all generations)."
+msgstr "Настройки для воспроизведения на iPod с видео (всех поколений)."
+
+msgid "iPod"
+msgstr ""
+
+msgid ""
+"HandBrake's settings for handheld iOS devices (iPhone 4, iPod touch 3G and "
+"later)."
+msgstr ""
+"Настройки для карманных устройств IOS (iPhone 4, IPod Touch 3G и выше)."
+
+msgid "iPhone & iPod touch"
+msgstr ""
+
+msgid "HandBrake's settings for playback on the iPad (all generations)."
+msgstr "Настройки для воспроизведения на IPad (всех поколений)."
+
+msgid "iPad"
+msgstr ""
+
+msgid ""
+"HandBrake's settings for the original AppleTV. Includes Dolby Digital audio "
+"for surround sound. Also compatible with iOS devices released since 2009."
+msgstr ""
+"Настройки для оригинального AppleTV. Включают в себя аудио Dolby Digital для "
+"объемного звука. Также совместим с устройствами IOS, выпущенных после 2009 "
+"года."
+
+msgid "AppleTV"
+msgstr ""
+
+msgid ""
+"HandBrake's settings for the second-generation AppleTV. Includes Dolby "
+"Digital audio for surround sound. NOT compatible with the original AppleTV."
+msgstr ""
+"Настройки для второго поколения AppleTV. Включают в себя аудио Dolby Digital "
+"для объемного звука. Не совместим с оригинальным AppleTV."
+
+msgid "AppleTV 2"
+msgstr ""
+
+msgid ""
+"HandBrake's settings for the third-generation AppleTV. Includes Dolby "
+"Digital audio for surround sound. NOT compatible with the original AppleTV. "
+"May stutter on the second-generation AppleTV."
+msgstr ""
+"Настройки для третьего поколения AppleTV. Включают в себя аудио Dolby "
+"Digital для объемного звука. Не совместим с оригинальным AppleTV. Может "
+"заикаться на второом поколении AppleTV."
+
+msgid "AppleTV 3"
+msgstr ""
+
+msgid "HandBrake's settings for midrange devices running Android 2.3 or later."
+msgstr ""
+"Настройки для устройств среднего класса под управлением Android 2.3 или "
+"более поздних."
+
+msgid "Android"
+msgstr "Андроид"
+
+msgid "HandBrake's preset for tablets running Android 2.3 or later."
+msgstr "Предустановка для планшета Android 2.3 или более поздних."
+
+msgid "Android Tablet"
+msgstr "Планшет андроид"
+
+msgid "Normal"
+msgstr "Стандартный"
+
+msgid "HandBrake's general-purpose preset for High Profile H.264 video."
+msgstr "Предустановка общего назначения для видео высокого качества H.264."
+
+msgid "High Profile"
+msgstr "Высокое качество"
+
+msgid "Regular"
+msgstr "Обычные"
+
+msgid "Devices"
+msgstr "Устройства"
+
+msgid "Keep Aspect"
+msgstr "Сохранять соотношение"
+
+msgid "Encoding: %s%s%.2f %%"
+msgstr "Кодирование: %s%s%.2f %%"
+
+msgid "Chapter"
+msgstr "Глава"
+
+msgid "Chapter %2d"
+msgstr "Глава %2d"
* any later version.
*/
+#include <glib/gi18n.h>
#include "ghbcompat.h"
#include "hb.h"
#include "settings.h"
if (enc->codec == fallback &&
!(enc->muxers & mux))
{
- if ( mux == HB_MUX_MKV )
+ if ( mux & HB_MUX_MASK_MKV )
fallback = HB_ACODEC_LAME;
else
fallback = HB_ACODEC_FAAC;
drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
if (drc < 1.0)
- s_drc = g_strdup("Off");
+ s_drc = g_strdup(_("Off"));
else
s_drc = g_strdup_printf("%.1f", drc);
drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
if (drc < 1.0)
- s_drc = g_strdup("Off");
+ s_drc = g_strdup(_("Off"));
else
s_drc = g_strdup_printf("%.1f", drc);
format_drc_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
{
if (val < 1.0)
- return g_strdup_printf("%-7s", "Off");
+ return g_strdup_printf("%-7s", _("Off"));
else
return g_strdup_printf("%-7.1f", val);
}
char *s_drc;
if (drc < 0.99)
- s_drc = g_strdup("Off");
+ s_drc = g_strdup(_("Off"));
else
s_drc = g_strdup_printf("%.1f", drc);
ghb_ui_update( ud, "AudioTrackDRCValue", ghb_string_value(s_drc));
drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
if (drc < 1.0)
- s_drc = g_strdup("Off");
+ s_drc = g_strdup(_("Off"));
else
s_drc = g_strdup_printf("%.1f", drc);
#include <time.h>
#include <glib/gstdio.h>
+#include <glib/gi18n.h>
#include <gio/gio.h>
#include "ghbcompat.h"
g_debug("on_quit1_activate ()");
if (state & (GHB_STATE_WORKING|GHB_STATE_SEARCHING))
{
- if (ghb_cancel_encode2(ud, "Closing HandBrake will terminate encoding.\n"))
+ if (ghb_cancel_encode2(ud, _("Closing HandBrake will terminate encoding.\n")))
{
ghb_hb_cleanup(FALSE);
prune_logs(ud);
get_extension(GValue *settings)
{
int container;
- const gchar *extension = "error";
+ const gchar *extension;
container = ghb_settings_combo_int(settings, "FileFormat");
- if (container == HB_MUX_MP4)
- {
- extension = "mp4";
- if (ghb_settings_get_boolean(settings, "UseM4v"))
- {
- extension = "m4v";
- }
- }
- else if (container == HB_MUX_MKV)
+ if ((container & HB_MUX_MASK_MP4) &&
+ ghb_settings_get_boolean(settings, "UseM4v"))
{
- extension = "mkv";
+ return "m4v";
}
+ extension = hb_container_get_default_extension(container);
+ if (extension == NULL)
+ extension = "error";
return extension;
}
}
else
{
- label = "No Title Found";
+ label = _("No Title Found");
gtk_label_set_text (GTK_LABEL(widget), label);
ghb_settings_set_string(ud->settings, "volume_label", label);
return FALSE;
gtk_combo_box_get_model(GTK_COMBO_BOX(combo))));
link = drives = dvd_device_list();
- gtk_combo_box_text_append_text (combo, "Not Selected");
+ gtk_combo_box_text_append_text (combo, _("Not Selected"));
while (link != NULL)
{
gchar *name = get_dvd_device_name(link->data);
gtk_widget_show(GTK_WIDGET(progress));
label = GTK_LABEL(GHB_WIDGET(ud->builder, "source_title"));
- gtk_label_set_text( label, "Scanning ..." );
+ gtk_label_set_text( label, _("Scanning ...") );
}
static void
widget = GHB_WIDGET(ud->builder, "sourcetoolbutton");
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-stop");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Stop Scan");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Stop Scan");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Stop Scan"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Stop Scan"));
//gtk_widget_set_sensitive(widget, FALSE);
action = GHB_ACTION(ud->builder, "source_action");
void
ghb_update_destination_extension(signal_user_data_t *ud)
{
- static gchar *containers[] = {".mkv", ".mp4", ".m4v", NULL};
+ static gchar *containers[] = {".mkv", ".mp4", ".m4v", ".error", NULL};
gchar *filename;
const gchar *extension;
gint ii;
g_debug("window_delete_event_cb ()");
if (state & (GHB_STATE_WORKING|GHB_STATE_SEARCHING))
{
- if (ghb_cancel_encode2(ud, "Closing HandBrake will terminate encoding.\n"))
+ if (ghb_cancel_encode2(ud, _("Closing HandBrake will terminate encoding.\n")))
{
ghb_hb_cleanup(FALSE);
prune_logs(ud);
ghb_grey_combo_options (ud);
}
+static void
+set_visible(GtkWidget *widget, gboolean visible)
+{
+ if (visible)
+ {
+ gtk_widget_show_now(widget);
+ }
+ else
+ {
+ gtk_widget_hide(widget);
+ }
+}
+
+static void show_container_options(signal_user_data_t *ud)
+{
+ GtkWidget *w1, *w2, *w3;
+ w1 = GHB_WIDGET(ud->builder, "Mp4LargeFile");
+ w2 = GHB_WIDGET(ud->builder, "Mp4HttpOptimize");
+ w3 = GHB_WIDGET(ud->builder, "Mp4iPodCompatible");
+
+ gint mux = ghb_settings_combo_int(ud->settings, "FileFormat");
+ gint enc = ghb_settings_combo_int(ud->settings, "VideoEncoder");
+
+ set_visible(w1, (mux == HB_MUX_MP4V2));
+ set_visible(w2, (mux & HB_MUX_MASK_MP4));
+ set_visible(w3, (mux & HB_MUX_MASK_MP4) && (enc == HB_VCODEC_X264));
+}
+
G_MODULE_EXPORT void
container_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
g_debug("container_changed_cb ()");
ghb_widget_to_setting(ud->settings, widget);
ghb_check_dependency(ud, widget, NULL);
+ show_container_options(ud);
update_acodec_combo(ud);
ghb_update_destination_extension(ud);
ghb_clear_presets_selection(ud);
}
else
{
- gchar *label = "No Title Found";
+ gchar *label = _("No Title Found");
gtk_label_set_text (GTK_LABEL(widget), label);
ghb_settings_set_string(ud->settings, "volume_label", label);
}
}
else
{
- gchar *label = "No Title Found";
+ gchar *label = _("No Title Found");
ghb_settings_set_string(settings, "volume_label", label);
}
}
ghb_widget_to_setting(ud->settings, widget);
ghb_check_dependency(ud, widget, NULL);
+ show_container_options(ud);
ghb_clear_presets_selection(ud);
ghb_live_reset(ud);
ghb_vquality_range(ud, &vqmin, &vqmax, &step, &page, &digits, &inverted);
gchar *text;
- text = ghb_settings_get_boolean(ud->settings, "PictureAutoCrop") ? "On" : "Off";
+ text = ghb_settings_get_boolean(ud->settings, "PictureAutoCrop") ? _("On") : _("Off");
widget = GHB_WIDGET (ud->builder, "crop_auto");
gtk_label_set_text (GTK_LABEL(widget), text);
- text = ghb_settings_get_boolean(ud->settings, "autoscale") ? "On" : "Off";
+ text = ghb_settings_get_boolean(ud->settings, "autoscale") ? _("On") : _("Off");
widget = GHB_WIDGET (ud->builder, "scale_auto");
gtk_label_set_text (GTK_LABEL(widget), text);
switch (ghb_settings_combo_int(ud->settings, "PicturePAR"))
{
case 0:
- text = "Off";
+ text = _("Off");
break;
case 1:
- text = "Strict";
+ text = _("Strict");
break;
case 2:
- text = "Loose";
+ text = _("Loose");
break;
case 3:
- text = "Custom";
+ text = _("Custom");
break;
default:
- text = "Unknown";
+ text = _("Unknown");
break;
}
widget = GHB_WIDGET (ud->builder, "scale_anamorphic");
gtk_main_quit();
return FALSE;
}
- str = g_strdup_printf("%s\n\n%s in %d seconds ...",
+ str = g_strdup_printf(_("%s\n\n%s in %d seconds ..."),
cd->msg, cd->action, cd->timeout);
gtk_message_dialog_set_markup(cd->dlg, str);
g_free(str);
gtk_main_quit();
return FALSE;
}
- str = g_strdup_printf("%s\n\n%s in %d seconds ...",
+ str = g_strdup_printf(_("%s\n\n%s in %d seconds ..."),
cd->msg, cd->action, cd->timeout);
gtk_message_dialog_set_markup(cd->dlg, str);
g_free(str);
ghb_suspend_gpm();
return FALSE;
}
- str = g_strdup_printf("%s\n\n%s in %d seconds ...",
+ str = g_strdup_printf(_("%s\n\n%s in %d seconds ..."),
cd->msg, cd->action, cd->timeout);
gtk_message_dialog_set_markup(cd->dlg, str);
g_free(str);
// Toss up a warning dialog
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
type, GTK_BUTTONS_NONE,
- "%s\n\n%s in %d seconds ...",
+ _("%s\n\n%s in %d seconds ..."),
message, action, timeout);
gtk_dialog_add_buttons( GTK_DIALOG(dialog),
cancel, GTK_RESPONSE_CANCEL,
// Toss up a warning dialog
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
- "%sYour movie will be lost if you don't continue encoding.",
+ _("%sYour movie will be lost if you don't continue encoding."),
extra_msg);
gtk_dialog_add_buttons( GTK_DIALOG(dialog),
- "Cancel Current and Stop", 1,
- "Cancel Current, Start Next", 2,
- "Finish Current, then Stop", 3,
- "Continue Encoding", 4,
+ _("Cancel Current and Stop"), 1,
+ _("Cancel Current, Start Next"), 2,
+ _("Finish Current, then Stop"), 3,
+ _("Continue Encoding"), 4,
NULL);
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy (dialog);
// Toss up a warning dialog
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
- "%sYour movie will be lost if you don't continue encoding.",
+ _("%sYour movie will be lost if you don't continue encoding."),
extra_msg);
gtk_dialog_add_buttons( GTK_DIALOG(dialog),
- "Cancel Current and Stop", 1,
- "Continue Encoding", 4,
+ _("Cancel Current and Stop"), 1,
+ _("Continue Encoding"), 4,
NULL);
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy (dialog);
}
if (qcount > 1)
{
- job_str = g_strdup_printf("job %d of %d, ", index+1, qcount);
+ job_str = g_strdup_printf(_("job %d of %d, "), index+1, qcount);
}
else
{
{
if (status->job_cur == 1 && subtitle_scan)
{
- task_str = g_strdup_printf("pass %d (subtitle scan) of %d, ",
+ task_str = g_strdup_printf(_("pass %d (subtitle scan) of %d, "),
status->job_cur, status->job_count);
}
else
{
- task_str = g_strdup_printf("pass %d of %d, ",
+ task_str = g_strdup_printf(_("pass %d of %d, "),
status->job_cur, status->job_count);
}
}
if (status->rate_cur > 0.0)
{
status_str= g_strdup_printf(
- "Encoding: %s%s%.2f %%"
- " (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)",
+ _("Encoding: %s%s%.2f %%"
+ " (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)"),
job_str, task_str,
100.0 * status->progress,
status->rate_cur, status->rate_avg, status->hours,
else
{
status_str= g_strdup_printf(
- "Encoding: %s%s%.2f %%"
- " (ETA %02dh%02dm%02ds)",
+ _("Encoding: %s%s%.2f %%"
+ " (ETA %02dh%02dm%02ds)"),
job_str, task_str,
100.0 * status->progress,
status->hours, status->minutes, status->seconds );
else
{
status_str= g_strdup_printf(
- "Encoding: %s%s%.2f %%",
+ _("Encoding: %s%s%.2f %%"),
job_str, task_str,
100.0 * status->progress );
}
index = find_queue_job(ud->queue, status->unique_id, &js);
if (qcount > 1)
{
- job_str = g_strdup_printf("job %d of %d, ", index+1, qcount);
+ job_str = g_strdup_printf(_("job %d of %d, "), index+1, qcount);
}
else
{
job_str = g_strdup("");
}
- task_str = g_strdup_printf("Searching for start time, ");
+ task_str = g_strdup_printf(_("Searching for start time, "));
if(status->seconds > -1)
{
status_str= g_strdup_printf(
- "Encoding: %s%s%.2f %%"
- " (ETA %02dh%02dm%02ds)",
+ _("Encoding: %s%s%.2f %%"
+ " (ETA %02dh%02dm%02ds)"),
job_str, task_str,
100.0 * status->progress,
status->hours, status->minutes, status->seconds );
else
{
status_str= g_strdup_printf(
- "Encoding: %s%s%.2f %%",
+ _("Encoding: %s%s%.2f %%"),
job_str, task_str,
100.0 * status->progress );
}
if (status.scan.title_cur == 0)
{
- status_str = g_strdup ("Scanning...");
+ status_str = g_strdup (_("Scanning..."));
}
else
{
if (status.scan.preview_cur == 0)
- status_str = g_strdup_printf("Scanning title %d of %d...",
+ status_str = g_strdup_printf(_("Scanning title %d of %d..."),
status.scan.title_cur, status.scan.title_count );
else
status_str = g_strdup_printf(
- "Scanning title %d of %d preview %d...",
+ _("Scanning title %d of %d preview %d..."),
status.scan.title_cur, status.scan.title_count,
status.scan.preview_cur);
widget = GHB_WIDGET(ud->builder, "sourcetoolbutton");
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-source");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Source");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Choose Video Source");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Source"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Choose Video Source"));
action = GHB_ACTION(ud->builder, "source_action");
gtk_action_set_sensitive(action, TRUE);
hb_title_t * title = ghb_get_title_info(titleindex);
if (title == NULL)
{
- gtk_label_set_text(label, "None");
+ gtk_label_set_text(label, _("None"));
}
ghb_clear_scan_state(GHB_STATE_SCANDONE);
if (ghb_queue_edit_settings)
{
// This needs to be in scanning and working since scanning
// happens fast enough that it can be missed
- gtk_label_set_text (work_status, "Scanning ...");
+ gtk_label_set_text (work_status, _("Scanning ..."));
gtk_progress_bar_set_fraction (progress, 0);
}
else if (status.queue.state & GHB_STATE_SCANDONE)
}
else if (status.queue.state & GHB_STATE_PAUSED)
{
- gtk_label_set_text (work_status, "Paused");
+ gtk_label_set_text (work_status, _("Paused"));
}
else if (status.queue.state & GHB_STATE_SEARCHING)
{
switch( status.queue.error )
{
case GHB_ERROR_NONE:
- gtk_label_set_text (work_status, "Encode Done!");
+ gtk_label_set_text (work_status, _("Encode Done!"));
qstatus = GHB_QUEUE_DONE;
if (js != NULL)
{
}
break;
case GHB_ERROR_CANCELED:
- gtk_label_set_text (work_status, "Encode Canceled.");
+ gtk_label_set_text (work_status, _("Encode Canceled."));
qstatus = GHB_QUEUE_CANCELED;
if (js != NULL)
{
}
break;
default:
- gtk_label_set_text (work_status, "Encode Failed.");
+ gtk_label_set_text (work_status, _("Encode Failed."));
qstatus = GHB_QUEUE_CANCELED;
if (js != NULL)
{
}
else if (status.queue.state & GHB_STATE_MUXING)
{
- gtk_label_set_text (work_status, "Muxing: This may take a while...");
+ gtk_label_set_text (work_status, _("Muxing: This may take a while..."));
}
if (status.scan.state & GHB_STATE_WORKING)
else if (status.queue.state & GHB_STATE_SEARCHING)
status_str = searching_status_string(ud, &status.queue);
else if (status.queue.state & GHB_STATE_WORKDONE)
- status_str = g_strdup("Encode Complete");
+ status_str = g_strdup(_("Encode Complete"));
else
status_str = g_strdup("HandBrake");
return TRUE;
}
-static void
-set_visible(GtkWidget *widget, gboolean visible)
-{
- if (visible)
- {
- gtk_widget_show_now(widget);
- }
- else
- {
- gtk_widget_hide(widget);
- }
-}
-
G_MODULE_EXPORT void
show_activity_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
{
gchar *message;
message = g_strdup_printf(
- "Invalid Settings:\n%s",
+ _("Invalid Settings:\n%s"),
tweak);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
g_free(message);
{
if (val < 5.0)
{
- return g_strdup_printf("Off");
+ return g_strdup_printf(_("Off"));
}
else
{
{
if (val == 0.0)
{
- return g_strdup_printf("RF: %.4g (Warning: lossless)", val);
+ return g_strdup_printf(_("RF: %.4g (Warning: lossless)"), val);
}
else
{
{
goto done;
}
- msg = g_strdup_printf("HandBrake %s/%s is now available (you have %s/%d).",
+ msg = g_strdup_printf(_("HandBrake %s/%s is now available (you have %s/%d)."),
version, build, hb_get_version(NULL), hb_get_build(NULL));
label = GHB_WIDGET(ud->builder, "update_message");
gtk_label_set_text(GTK_LABEL(label), msg);
#if !defined(_WIN32)
NotifyNotification *notification;
notification = notify_notification_new(
- "Encode Complete",
- "Put down that cocktail, Your HandBrake queue is done!",
+ _("Encode Complete"),
+ _("Put down that cocktail, Your HandBrake queue is done!"),
NULL
#if NOTIFY_CHECK_VERSION (0, 7, 0)
);
if (ghb_can_shutdown_gsm())
{
ghb_countdown_dialog(GTK_MESSAGE_WARNING,
- "Your encode is complete.",
- "Shutting down the computer",
- "Cancel", (GSourceFunc)shutdown_cb, ud, 60);
+ _("Your encode is complete."),
+ _("Shutting down the computer"),
+ _("Cancel"), (GSourceFunc)shutdown_cb, ud, 60);
}
}
if (ghb_settings_combo_int(ud->settings, "WhenComplete") == 2)
if (ghb_can_suspend_gpm())
{
ghb_countdown_dialog(GTK_MESSAGE_WARNING,
- "Your encode is complete.",
- "Putting computer to sleep",
- "Cancel", (GSourceFunc)suspend_cb, ud, 60);
+ _("Your encode is complete."),
+ _("Putting computer to sleep"),
+ _("Cancel"), (GSourceFunc)suspend_cb, ud, 60);
}
}
if (ghb_settings_combo_int(ud->settings, "WhenComplete") == 4)
{
ghb_countdown_dialog(GTK_MESSAGE_WARNING,
- "Your encode is complete.",
- "Quiting Handbrake",
- "Cancel", (GSourceFunc)quit_cb, ud, 60);
+ _("Your encode is complete."),
+ _("Quiting Handbrake"),
+ _("Cancel"), (GSourceFunc)quit_cb, ud, 60);
}
}
Name=HandBrake
GenericName=Media Transcoder
Comment=Transcodes DVD, Bluray, and other media
-Exec=ghb
+Exec=ghb %f
Icon=hb-icon
Terminal=false
Type=Application
<object class="GtkAction" id="source_action">
<property name="stock_id">gtk-open</property>
<property name="name">source_action</property>
- <property name="label">_Source</property>
+ <property name="label" translatable="yes">_Source</property>
<signal handler="source_button_clicked_cb" name="activate"/>
</object>
</child>
<object class="GtkAction" id="source_single_action">
<property name="stock_id">gtk-open</property>
<property name="name">source_single_action</property>
- <property name="label">Single _Title</property>
+ <property name="label" translatable="yes">Single _Title</property>
<signal handler="single_title_source_cb" name="activate"/>
</object>
</child>
<object class="GtkAction" id="destination1">
<property name="stock_id">gtk-save-as</property>
<property name="name">destination1</property>
- <property name="label">_Destination</property>
+ <property name="label" translatable="yes">_Destination</property>
<signal handler="destination_browse_clicked_cb" name="activate"/>
</object>
</child>
<property name="sensitive">False</property>
<property name="icon-name">hb-add-queue</property>
<property name="name">queue_add_menu</property>
- <property name="label">_Add Queue</property>
+ <property name="label" translatable="yes">_Add Queue</property>
<signal handler="queue_add_clicked_cb" name="activate"/>
</object>
</child>
<property name="sensitive">False</property>
<property name="icon-name">hb-add-queue</property>
<property name="name">queue_add_all_menu</property>
- <property name="label">Add A_ll Queue</property>
+ <property name="label" translatable="yes">Add A_ll Queue</property>
<signal handler="queue_add_all_clicked_cb" name="activate"/>
</object>
</child>
<property name="sensitive">False</property>
<property name="icon-name">hb-start</property>
<property name="name">queue_start_menu</property>
- <property name="label">_Start Queue</property>
+ <property name="label" translatable="yes">_Start Queue</property>
<signal handler="queue_start_clicked_cb" name="activate"/>
</object>
</child>
<object class="GtkMenu" id="presets_menu">
<child>
<object class="GtkImageMenuItem" id="presets_default">
- <property name="label">_Make Default</property>
+ <property name="label" translatable="yes">_Make Default</property>
<property name="image">image12</property>
<property name="visible">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
+ <property name="y_options"></property>
</packing>
</child>
<child>
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="expanded">False</property>
- <property name="label">Advanced</property>
+ <property name="label" translatable="yes">Advanced</property>
<child>
<object class="GtkVBox" id="vbox44">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Add new subtitle to the list</property>
<property name="relief">GTK_RELIEF_NONE</property>
- <property name="label">Subtitle</property>
+ <property name="label" translatable="yes">Subtitle</property>
<property name="image">subtitle_add_image</property>
<signal handler="subtitle_add_clicked_cb" name="clicked"/>
</object>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip-text" translatable="yes">Add new SRT subtitle to the list</property>
<property name="relief">GTK_RELIEF_NONE</property>
- <property name="label">Import SRT</property>
+ <property name="label" translatable="yes">Import SRT</property>
<property name="image">srt_add_image</property>
<signal handler="srt_add_clicked_cb" name="clicked"/>
</object>
#include "hb.h"
#include "ghbcompat.h"
#include <glib/gstdio.h>
+#include <glib/gi18n.h>
#include "hb-backend.h"
#include "settings.h"
#include "callbacks.h"
static options_map_t d_point_to_point_opts[] =
{
- {"Chapters:", "chapter", 0, "0"},
- {"Seconds:", "time", 1, "1"},
- {"Frames:", "frame", 2, "2"},
+ {N_("Chapters:"), "chapter", 0, "0"},
+ {N_("Seconds:"), "time", 1, "1"},
+ {N_("Frames:"), "frame", 2, "2"},
};
combo_opts_t point_to_point_opts =
{
static options_map_t d_when_complete_opts[] =
{
- {"Do Nothing", "nothing", 0, "0"},
- {"Show Notification", "notify", 1, "1"},
- {"Quit Handbrake", "quit", 4, "4"},
- {"Put Computer To Sleep", "sleep", 2, "2"},
- {"Shutdown Computer", "shutdown", 3, "3"},
+ {N_("Do Nothing"), "nothing", 0, "0"},
+ {N_("Show Notification"), "notify", 1, "1"},
+ {N_("Quit Handbrake"), "quit", 4, "4"},
+ {N_("Put Computer To Sleep"), "sleep", 2, "2"},
+ {N_("Shutdown Computer"), "shutdown", 3, "3"},
};
combo_opts_t when_complete_opts =
{
static options_map_t d_par_opts[] =
{
- {"Off", "0", 0, "0"},
- {"Strict", "1", 1, "1"},
- {"Loose", "2", 2, "2"},
- {"Custom", "3", 3, "3"},
+ {N_("Off"), "0", 0, "0"},
+ {N_("Strict"), "1", 1, "1"},
+ {N_("Loose"), "2", 2, "2"},
+ {N_("Custom"), "3", 3, "3"},
};
combo_opts_t par_opts =
{
static options_map_t d_log_longevity_opts[] =
{
- {"Week", "week", 7, "7"},
- {"Month", "month", 30, "30"},
- {"Year", "year", 365, "365"},
- {"Immortal", "immortal", 366, "366"},
+ {N_("Week"), "week", 7, "7"},
+ {N_("Month"), "month", 30, "30"},
+ {N_("Year"), "year", 365, "365"},
+ {N_("Immortal"), "immortal", 366, "366"},
};
combo_opts_t log_longevity_opts =
{
static options_map_t d_appcast_update_opts[] =
{
- {"Never", "never", 0, "never"},
- {"Daily", "daily", 1, "daily"},
- {"Weekly", "weekly", 2, "weekly"},
- {"Monthly", "monthly", 3, "monthly"},
+ {N_("Never"), "never", 0, "never"},
+ {N_("Daily"), "daily", 1, "daily"},
+ {N_("Weekly"), "weekly", 2, "weekly"},
+ {N_("Monthly"), "monthly", 3, "monthly"},
};
combo_opts_t appcast_update_opts =
{
static options_map_t d_detel_opts[] =
{
- {"Off", "off", 0, ""},
- {"Custom", "custom", 1, ""},
- {"Default","default",2, NULL},
+ {N_("Off"), "off", 0, ""},
+ {N_("Custom"), "custom", 1, ""},
+ {N_("Default"),"default",2, NULL},
};
combo_opts_t detel_opts =
{
static options_map_t d_decomb_opts[] =
{
- {"Off", "off", 0, ""},
- {"Custom", "custom", 1, ""},
- {"Default","default",2, NULL},
- {"Fast", "fast", 3, "7:2:6:9:1:80"},
- {"Bob", "bob", 4, "455"},
+ {N_("Off"), "off", 0, ""},
+ {N_("Custom"), "custom", 1, ""},
+ {N_("Default"),"default",2, NULL},
+ {N_("Fast"), "fast", 3, "7:2:6:9:1:80"},
+ {N_("Bob"), "bob", 4, "455"},
};
combo_opts_t decomb_opts =
{
static options_map_t d_deint_opts[] =
{
- {"Off", "off", 0, ""},
- {"Custom", "custom", 1, ""},
- {"Fast", "fast", 2, "0:-1:-1:0:1"},
- {"Slow", "slow", 3, "1:-1:-1:0:1"},
- {"Slower", "slower", 4, "3:-1:-1:0:1"},
- {"Bob", "bob", 5, "15:-1:-1:0:1"},
+ {N_("Off"), "off", 0, ""},
+ {N_("Custom"), "custom", 1, ""},
+ {N_("Fast"), "fast", 2, "0:-1:-1:0:1"},
+ {N_("Slow"), "slow", 3, "1:-1:-1:0:1"},
+ {N_("Slower"), "slower", 4, "3:-1:-1:0:1"},
+ {N_("Bob"), "bob", 5, "15:-1:-1:0:1"},
};
combo_opts_t deint_opts =
{
static options_map_t d_denoise_opts[] =
{
- {"Off", "off", 0, ""},
- {"Custom", "custom", 1, ""},
- {"Weak", "weak", 2, "2:1:2:3"},
- {"Medium", "medium", 3, "3:2:2:3"},
- {"Strong", "strong", 4, "7:7:5:5"},
+ {N_("Off"), "off", 0, ""},
+ {N_("Custom"), "custom", 1, ""},
+ {N_("Weak"), "weak", 2, "2:1:2:3"},
+ {N_("Medium"), "medium", 3, "3:2:2:3"},
+ {N_("Strong"), "strong", 4, "7:7:5:5"},
};
combo_opts_t denoise_opts =
{
static options_map_t d_direct_opts[] =
{
- {"None", "none", 0, "none"},
- {"Spatial", "spatial", 1, "spatial"},
- {"Temporal", "temporal", 2, "temporal"},
- {"Automatic", "auto", 3, "auto"},
+ {N_("None"), "none", 0, "none"},
+ {N_("Spatial"), "spatial", 1, "spatial"},
+ {N_("Temporal"), "temporal", 2, "temporal"},
+ {N_("Automatic"), "auto", 3, "auto"},
};
combo_opts_t direct_opts =
{
static options_map_t d_badapt_opts[] =
{
- {"Off", "0", 0, "0"},
- {"Fast", "1", 1, "1"},
- {"Optimal", "2", 2, "2"},
+ {N_("Off"), "0", 0, "0"},
+ {N_("Fast"), "1", 1, "1"},
+ {N_("Optimal"), "2", 2, "2"},
};
combo_opts_t badapt_opts =
{
static options_map_t d_bpyramid_opts[] =
{
- {"Off", "none", 0, "none"},
- {"Strict", "strict", 1, "strict"},
- {"Normal", "normal", 2, "normal"},
+ {N_("Off"), "none", 0, "none"},
+ {N_("Strict"), "strict", 1, "strict"},
+ {N_("Normal"), "normal", 2, "normal"},
};
combo_opts_t bpyramid_opts =
{
static options_map_t d_weightp_opts[] =
{
- {"Off", "0", 0, "0"},
- {"Simple", "1", 1, "1"},
- {"Smart", "2", 2, "2"},
+ {N_("Off"), "0", 0, "0"},
+ {N_("Simple"), "1", 1, "1"},
+ {N_("Smart"), "2", 2, "2"},
};
combo_opts_t weightp_opts =
{
static options_map_t d_me_opts[] =
{
- {"Diamond", "dia", 0, "dia"},
- {"Hexagon", "hex", 1, "hex"},
- {"Uneven Multi-Hexagon", "umh", 2, "umh"},
- {"Exhaustive", "esa", 3, "esa"},
- {"Hadamard Exhaustive", "tesa", 4, "tesa"},
+ {N_("Diamond"), "dia", 0, "dia"},
+ {N_("Hexagon"), "hex", 1, "hex"},
+ {N_("Uneven Multi-Hexagon"), "umh", 2, "umh"},
+ {N_("Exhaustive"), "esa", 3, "esa"},
+ {N_("Hadamard Exhaustive"), "tesa", 4, "tesa"},
};
combo_opts_t me_opts =
{
static options_map_t d_subme_opts[] =
{
- {"0: SAD, no subpel", "0", 0, "0"},
- {"1: SAD, qpel", "1", 1, "1"},
- {"2: SATD, qpel", "2", 2, "2"},
- {"3: SATD: multi-qpel", "3", 3, "3"},
- {"4: SATD, qpel on all", "4", 4, "4"},
- {"5: SATD, multi-qpel on all", "5", 5, "5"},
- {"6: RD in I/P-frames", "6", 6, "6"},
- {"7: RD in all frames", "7", 7, "7"},
- {"8: RD refine in I/P-frames", "8", 8, "8"},
- {"9: RD refine in all frames", "9", 9, "9"},
- {"10: QPRD in all frames", "10", 10, "10"},
- {"11: No early terminations in analysis", "11", 11, "11"},
+ {N_("0: SAD, no subpel"), "0", 0, "0"},
+ {N_("1: SAD, qpel"), "1", 1, "1"},
+ {N_("2: SATD, qpel"), "2", 2, "2"},
+ {N_("3: SATD: multi-qpel"), "3", 3, "3"},
+ {N_("4: SATD, qpel on all"), "4", 4, "4"},
+ {N_("5: SATD, multi-qpel on all"), "5", 5, "5"},
+ {N_("6: RD in I/P-frames"), "6", 6, "6"},
+ {N_("7: RD in all frames"), "7", 7, "7"},
+ {N_("8: RD refine in I/P-frames"), "8", 8, "8"},
+ {N_("9: RD refine in all frames"), "9", 9, "9"},
+ {N_("10: QPRD in all frames"), "10", 10, "10"},
+ {N_("11: No early terminations in analysis"), "11", 11, "11"},
};
combo_opts_t subme_opts =
{
static options_map_t d_analyse_opts[] =
{
- {"Most", "p8x8,b8x8,i8x8,i4x4", 0, "p8x8,b8x8,i8x8,i4x4"},
- {"None", "none", 1, "none"},
- {"Some", "i4x4,i8x8", 2, "i4x4,i8x8"},
- {"All", "all", 3, "all"},
- {"Custom", "custom", 4, "all"},
+ {N_("Most"), "p8x8,b8x8,i8x8,i4x4", 0, "p8x8,b8x8,i8x8,i4x4"},
+ {N_("None"), "none", 1, "none"},
+ {N_("Some"), "i4x4,i8x8", 2, "i4x4,i8x8"},
+ {N_("All"), "all", 3, "all"},
+ {N_("Custom"), "custom", 4, "all"},
};
combo_opts_t analyse_opts =
{
static options_map_t d_trellis_opts[] =
{
- {"Off", "0", 0, "0"},
- {"Encode only", "1", 1, "1"},
- {"Always", "2", 2, "2"},
+ {N_("Off"), "0", 0, "0"},
+ {N_("Encode only"), "1", 1, "1"},
+ {N_("Always"), "2", 2, "2"},
};
combo_opts_t trellis_opts =
{
return VOBSUB;
}
-const char*
-ghb_subtitle_track_source_name(GValue *settings, gint track)
-{
- gint titleindex;
- const gchar * name = "Unknown";
-
- if (track == -2)
- {
- name = "SRT";
- goto done;
- }
- if (track == -1)
- {
- name = "Bitmap";
- goto done;
- }
-
- titleindex = ghb_settings_combo_int(settings, "title");
- if (titleindex < 0)
- goto done;
-
- hb_title_t * title;
- hb_subtitle_t * sub;
-
- title = ghb_get_title_info( titleindex );
- if (title == NULL)
- goto done;
-
- sub = hb_list_item( title->list_subtitle, track);
- if (sub != NULL)
- {
- name = hb_subsource_name(sub->source);
- }
-
-done:
- return name;
-}
-
const gchar*
ghb_subtitle_track_lang(GValue *settings, gint track)
{
gtk_list_store_clear(store);
// Add an item for "Same As Source"
gtk_list_store_append(store, &iter);
+ str = g_strdup_printf("<small>%s</small>", _("Same as source"));
gtk_list_store_set(store, &iter,
- 0, "<small>Same as source</small>",
+ 0, str,
1, TRUE,
2, "source",
3, 0.0,
4, "source",
-1);
+ g_free(str);
const hb_rate_t *rate;
for (rate = hb_audio_samplerate_get_next(NULL); rate != NULL;
// Add an item for "Same As Source"
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, "Same as source",
+ 0, _("Same as source"),
1, TRUE,
2, "source",
3, 0.0,
gchar *option;
if (strcmp(rate->name, "23.976") == 0)
{
- desc = "(NTSC Film)";
+ desc = _("(NTSC Film)");
}
else if (strcmp(rate->name, "25") == 0)
{
- desc = "(PAL Film/Video)";
+ desc = _("(PAL Film/Video)");
}
else if (strcmp(rate->name, "29.97") == 0)
{
- desc = "(NTSC Video)";
+ desc = _("(NTSC Video)");
}
option = g_strdup_printf ("%s %s", rate->name, desc);
gtk_list_store_append(store, &iter);
// No titles. Fill in a default.
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, "No Titles",
+ 0, _("No Titles"),
1, TRUE,
2, "none",
3, -1.0,
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, "None",
+ 0, _("None"),
1, TRUE,
2, "none",
3, (gdouble)0,
{
// No audio. set some default
gtk_list_store_append(store, &iter);
+ str = g_strdup_printf("<small>%s</small>", _("No Audio"));
gtk_list_store_set(store, &iter,
- 0, "<small>No Audio</small>",
+ 0, str,
1, TRUE,
2, "none",
3, -1.0,
4, "none",
-1);
+ g_free(str);
audio_track_opts.map[0].option = g_strdup("No Audio");
audio_track_opts.map[0].shortOpt = "none";
audio_track_opts.map[0].ivalue = -1;
}
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, "Foreign Audio Search",
+ 0, _("Foreign Audio Search"),
1, TRUE,
2, "-1",
3, -1.0,
{
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, opts->map[ii].option,
+ 0, _(opts->map[ii].option),
1, TRUE,
2, opts->map[ii].shortOpt,
3, opts->map[ii].ivalue,
for (ii = 0; ii < opts->count; ii++)
{
gtk_list_store_append(store, &iter);
- str = g_strdup_printf("<small>%s</small>", opts->map[ii].option);
+ str = g_strdup_printf("<small>%s</small>", _(opts->map[ii].option));
gtk_list_store_set(store, &iter,
0, str,
1, TRUE,
if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
- "Invalid Deinterlace Settings:\n\n%s\n",
+ _("Invalid Deinterlace Settings:\n\n%s\n"),
str);
- ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ ghb_message_dialog(GTK_MESSAGE_ERROR, message, _("Cancel"), NULL);
g_free(message);
g_free(str);
return FALSE;
if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
- "Invalid Detelecine Settings:\n\n%s\n",
+ _("Invalid Detelecine Settings:\n\n%s\n"),
str);
- ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ ghb_message_dialog(GTK_MESSAGE_ERROR, message, _("Cancel"), NULL);
g_free(message);
g_free(str);
return FALSE;
if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
- "Invalid Decomb Settings:\n\n%s\n",
+ N_("Invalid Decomb Settings:\n\n%s\n"),
str);
- ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ ghb_message_dialog(GTK_MESSAGE_ERROR, message, _("Cancel"), NULL);
g_free(message);
g_free(str);
return FALSE;
if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
- "Invalid Denoise Settings:\n\n%s\n",
+ _("Invalid Denoise Settings:\n\n%s\n"),
str);
- ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ ghb_message_dialog(GTK_MESSAGE_ERROR, message, _("Cancel"), NULL);
g_free(str);
g_free(message);
return FALSE;
mux = ghb_settings_combo_int(settings, "FileFormat");
vcodec = ghb_settings_combo_int(settings, "VideoEncoder");
- if ((mux == HB_MUX_MP4) && (vcodec == HB_VCODEC_THEORA))
+ if ((mux & HB_MUX_MASK_MP4) && (vcodec == HB_VCODEC_THEORA))
{
// mp4/theora combination is not supported.
message = g_strdup_printf(
- "Theora is not supported in the MP4 container.\n\n"
+ _("Theora is not supported in the MP4 container.\n\n"
"You should choose a different video codec or container.\n"
- "If you continue, FFMPEG will be chosen for you.");
- if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue"))
+ "If you continue, FFMPEG will be chosen for you."));
+ if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, _("Cancel"), _("Continue")))
{
g_free(message);
return FALSE;
// MP4 can only handle burned vobsubs. make sure there isn't
// already something burned in the list
message = g_strdup_printf(
- "Only one subtitle may be burned into the video.\n\n"
+ _("Only one subtitle may be burned into the video.\n\n"
"You should change your subtitle selections.\n"
- "If you continue, some subtitles will be lost.");
- if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue"))
+ "If you continue, some subtitles will be lost."));
+ if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, _("Cancel"), _("Continue")))
{
g_free(message);
return FALSE;
if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
{
message = g_strdup_printf(
- "Srt file does not exist or not a regular file.\n\n"
+ _("Srt file does not exist or not a regular file.\n\n"
"You should choose a valid file.\n"
- "If you continue, this subtitle will be ignored.");
+ "If you continue, this subtitle will be ignored."));
if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message,
- "Cancel", "Continue"))
+ _("Cancel"), _("Continue")))
{
g_free(message);
return FALSE;
{
// Not supported. AC3 is passthrough only, so input must be AC3
message = g_strdup_printf(
- "The source does not support Pass-Thru.\n\n"
+ _("The source does not support Pass-Thru.\n\n"
"You should choose a different audio codec.\n"
- "If you continue, one will be chosen for you.");
- if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue"))
+ "If you continue, one will be chosen for you."));
+ if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, _("Cancel"), _("Continue")))
{
g_free(message);
return FALSE;
{
codec = HB_ACODEC_AC3;
}
- else if (mux == HB_MUX_MKV)
+ else if (mux & HB_MUX_MASK_MKV)
{
codec = HB_ACODEC_LAME;
}
}
gchar *a_unsup = NULL;
gchar *mux_s = NULL;
- if (mux == HB_MUX_MP4)
+ if (mux & HB_MUX_MASK_MP4)
{
mux_s = "MP4";
// mp4/vorbis|DTS combination is not supported.
if (a_unsup)
{
message = g_strdup_printf(
- "%s is not supported in the %s container.\n\n"
+ _("%s is not supported in the %s container.\n\n"
"You should choose a different audio codec.\n"
- "If you continue, one will be chosen for you.", a_unsup, mux_s);
- if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue"))
+ "If you continue, one will be chosen for you."), a_unsup, mux_s);
+ if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, _("Cancel"), _("Continue")))
{
g_free(message);
return FALSE;
if (mix_unsup)
{
message = g_strdup_printf(
- "The source audio does not support %s mixdown.\n\n"
+ _("The source audio does not support %s mixdown.\n\n"
"You should choose a different mixdown.\n"
- "If you continue, one will be chosen for you.", mix_unsup);
- if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue"))
+ "If you continue, one will be chosen for you."), mix_unsup);
+ if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, _("Cancel"), _("Continue")))
{
g_free(message);
return FALSE;
if (vcodec == HB_VCODEC_X264 && vquality == 0.0)
{
message = g_strdup_printf(
- "Warning: lossless h.264 selected\n\n"
+ _("Warning: lossless h.264 selected\n\n"
"Lossless h.264 is not well supported by\n"
"many players and editors.\n\n"
"It will produce enormous output files.\n\n"
- "Are you sure you wish to use this setting?");
+ "Are you sure you wish to use this setting?"));
if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message,
- "Cancel", "Continue"))
+ _("Cancel"), _("Continue")))
{
g_free(message);
return FALSE;
else if (vquality < min || vquality > max)
{
message = g_strdup_printf(
- "Interesting video quality choice: %d\n\n"
+ _("Interesting video quality choice: %d\n\n"
"Typical values range from %d to %d.\n\n"
- "Are you sure you wish to use this setting?",
+ "Are you sure you wish to use this setting?"),
(gint)vquality, min, max);
if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message,
- "Cancel", "Continue"))
+ _("Cancel"), _("Continue")))
{
g_free(message);
return FALSE;
}
job->mux = ghb_settings_combo_int(js, "FileFormat");
- if (job->mux == HB_MUX_MP4)
+ if (job->mux & HB_MUX_MASK_MP4)
{
job->largeFileSize = ghb_settings_get_boolean(js, "Mp4LargeFile");
job->mp4_optimize = ghb_settings_get_boolean(js, "Mp4HttpOptimize");
}
job->vcodec = ghb_settings_combo_int(js, "VideoEncoder");
- if ((job->mux == HB_MUX_MP4 ) && (job->vcodec == HB_VCODEC_THEORA))
+ if ((job->mux & HB_MUX_MASK_MP4 ) && (job->vcodec == HB_VCODEC_THEORA))
{
// mp4/theora combination is not supported.
job->vcodec = HB_VCODEC_FFMPEG_MPEG4;
}
- if ((job->vcodec == HB_VCODEC_X264) && (job->mux == HB_MUX_MP4))
+ if ((job->vcodec == HB_VCODEC_X264) && (job->mux & HB_MUX_MASK_MP4))
{
job->ipod_atom = ghb_settings_get_boolean(js, "Mp4iPodCompatible");
}
gint ghb_get_title_number(gint titleindex);
int ghb_get_title_count();
gint ghb_subtitle_track_source(GValue *settings, gint track);
-const char* ghb_subtitle_track_source_name(GValue *settings, gint track);
const gchar* ghb_subtitle_track_lang(GValue *settings, gint track);
gboolean ghb_validate_vquality(GValue *settings);
#endif
#include <glib/gstdio.h>
+#include <glib/gi18n.h>
#include <gio/gio.h>
#include "hb.h"
#include "renderer_button.h"
/*
* Standard gettext macros.
*/
-#ifdef ENABLE_NLS
-# include <libintl.h>
-# undef _
-# define _(String) dgettext(PACKAGE, String)
-# ifdef gettext_noop
-# define N_(String) gettext_noop(String)
-# else
-# define N_(String) (String)
-# endif
-#else
+#ifndef ENABLE_NLS
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
static GOptionEntry entries[] =
{
- { "device", 'd', 0, G_OPTION_ARG_FILENAME, &dvd_device, "The device or file to encode", NULL },
- { "preset", 'p', 0, G_OPTION_ARG_STRING, &arg_preset, "The preset values to use for encoding", NULL },
- { "debug", 'x', 0, G_OPTION_ARG_NONE, &ghb_debug, "Spam a lot", NULL },
+ { "device", 'd', 0, G_OPTION_ARG_FILENAME, &dvd_device, N_("The device or file to encode"), NULL },
+ { "preset", 'p', 0, G_OPTION_ARG_STRING, &arg_preset, N_("The preset values to use for encoding"), NULL },
+ { "debug", 'x', 0, G_OPTION_ARG_NONE, &ghb_debug, N_("Spam a lot"), NULL },
{ NULL }
};
textdomain(GETTEXT_PACKAGE);
#endif
- context = g_option_context_new("- Transcode media formats");
+ context = g_option_context_new(_("- Transcode media formats"));
g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE);
g_option_context_add_group(context, gtk_get_option_group(TRUE));
#if defined(_ENABLE_GST)
import collections
import plistlib
+import sys
DepEntry = collections.namedtuple('DepEntry', 'widget dep enable die hide')
dep_map = (
DepEntry("VideoFramerate", "VideoFrameratePFR", "source", True, True),
DepEntry("VideoFramerate", "VideoFramerateVFR", "source", False, True),
DepEntry("VideoTwoPass", "VideoTurboTwoPass", "TRUE", False, False),
- DepEntry("FileFormat", "Mp4LargeFile", "mp4", False, True),
- DepEntry("FileFormat", "Mp4HttpOptimize", "mp4", False, True),
- DepEntry("FileFormat", "Mp4iPodCompatible", "mp4", False, True),
DepEntry("PictureDecombDeinterlace", "PictureDeinterlace", "TRUE", True, True),
DepEntry("PictureDecombDeinterlace", "PictureDeinterlaceCustom", "TRUE", True, True),
DepEntry("PictureDecombDeinterlace", "PictureDeinterlaceLabel", "TRUE", True, True),
DepEntry("VideoEncoder", "x264_tab", "x264", False, True),
DepEntry("VideoEncoder", "x264VideoSettings", "x264", False, True),
DepEntry("VideoEncoder", "lavc_mpeg4_tab", "ffmpeg|ffmpeg4|ffmpeg2", False, True),
- DepEntry("VideoEncoder", "Mp4iPodCompatible", "x264", False, False),
DepEntry("AudioTrackQualityEnable", "AudioBitrateLabel", "TRUE", True, False),
DepEntry("AudioTrackQualityEnable", "AudioBitrate", "TRUE", True, False),
DepEntry("AudioEncoderActual", "AudioBitrateLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
#include <unistd.h>
#include <glib.h>
#include <glib/gstdio.h>
+#include <glib/gi18n.h>
#include <glib-object.h>
#include "ghbcompat.h"
gchar *message, *desc;
desc = gst_missing_plugin_message_get_description(msg);
message = g_strdup_printf(
- "Missing GStreamer plugin\n"
- "Audio or Video may not play as expected\n\n%s",
+ _("Missing GStreamer plugin\n"
+ "Audio or Video may not play as expected\n\n%s"),
desc);
ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Ok", NULL);
g_free(message);
window = GHB_WIDGET(ud->builder, "settings_window");
if (!active)
{
- gtk_button_set_label(GTK_BUTTON(toggle), "Hide Settings");
+ gtk_button_set_label(GTK_BUTTON(toggle), _("Hide Settings"));
gtk_widget_set_tooltip_text(toggle,
- "Hide the picture settings window while "
- "leaving the preview visible.");
+ _("Hide the picture settings window while "
+ "leaving the preview visible."));
gtk_widget_show(window);
}
else
{
- gtk_button_set_label(GTK_BUTTON(toggle), "Show Settings");
- gtk_widget_set_tooltip_text(toggle, "Show picture settings.");
+ gtk_button_set_label(GTK_BUTTON(toggle), _("Show Settings"));
+ gtk_widget_set_tooltip_text(toggle, _("Show picture settings."));
gtk_widget_hide(window);
}
}
#include "ghbcompat.h"
#include <glib/gstdio.h>
+#include <glib/gi18n.h>
#include <gio/gio.h>
#include "hb.h"
#include "settings.h"
vqtype = ghb_settings_get_boolean(settings, "vquality_type_constant");
if (!vqtype)
pass2 = ghb_settings_get_boolean(settings, "VideoTwoPass");
- const gchar *points = "Chapters";
+ const gchar *points = _("Chapters");
if (ghb_settings_combo_int(settings, "PtoPType") == 0)
- points = "Chapters";
+ points = _("Chapters");
else if (ghb_settings_combo_int(settings, "PtoPType") == 1)
- points = "Seconds";
+ points = _("Seconds");
else if (ghb_settings_combo_int(settings, "PtoPType") == 2)
- points = "Frames";
+ points = _("Frames");
info = g_strdup_printf
(
"<big><b>%s</b></big> "
g_string_append_printf(str,
"<b>Format:</b> <small>%s Container</small>\n", container);
}
- if (mux == HB_MUX_MP4)
+ if (mux & HB_MUX_MASK_MP4)
{
gboolean ipod, http, large;
if (strcmp(dest, filename) == 0)
{
message = g_strdup_printf(
- "Destination: %s\n\n"
+ _("Destination: %s\n\n"
"Another queued job has specified the same destination.\n"
- "Do you want to overwrite?",
+ "Do you want to overwrite?"),
dest);
- if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Overwrite"))
+ if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, _("Cancel"), _("Overwrite")))
{
g_free(filename);
g_free(dest);
if (!g_file_test(destdir, G_FILE_TEST_IS_DIR))
{
message = g_strdup_printf(
- "Destination: %s\n\n"
- "This is not a valid directory.",
+ _("Destination: %s\n\n"
+ "This is not a valid directory."),
destdir);
- ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ ghb_message_dialog(GTK_MESSAGE_ERROR, message, _("Cancel"), NULL);
g_free(dest);
g_free(message);
g_free(destdir);
if (g_access(destdir, R_OK|W_OK) != 0)
{
message = g_strdup_printf(
- "Destination: %s\n\n"
- "Can not read or write the directory.",
+ _("Destination: %s\n\n"
+ "Can not read or write the directory."),
destdir);
- ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
+ ghb_message_dialog(GTK_MESSAGE_ERROR, message, _("Cancel"), NULL);
g_free(dest);
g_free(message);
g_free(destdir);
if (size < fsize)
{
message = g_strdup_printf(
- "Destination filesystem is almost full: %uM free\n\n"
- "Encode may be incomplete if you proceed.\n",
+ _("Destination filesystem is almost full: %uM free\n\n"
+ "Encode may be incomplete if you proceed.\n"),
(guint)(size / (1024L*1024L)));
- if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Proceed"))
+ if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, _("Cancel"), _("Proceed")))
{
g_free(dest);
g_free(message);
if (g_file_test(dest, G_FILE_TEST_EXISTS))
{
message = g_strdup_printf(
- "Destination: %s\n\n"
+ _("Destination: %s\n\n"
"File already exists.\n"
- "Do you want to overwrite?",
+ "Do you want to overwrite?"),
dest);
- if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Overwrite"))
+ if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, _("Cancel"), _("Overwrite")))
{
g_free(dest);
g_free(message);
{
gtk_widget_set_sensitive (widget, TRUE);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-stop");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Stop");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Stop Encoding");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Stop"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Stop Encoding"));
}
else
{
gtk_widget_set_sensitive (widget, show_start);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-start");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Start");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Start Encoding");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Start"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Start Encoding"));
}
widget = GHB_WIDGET (ud->builder, "queue_start2");
if (show_stop)
{
gtk_widget_set_sensitive (widget, TRUE);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-stop");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Stop");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Stop Encoding");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Stop"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Stop Encoding"));
}
else
{
gtk_widget_set_sensitive (widget, show_start);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-start");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Start");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Start Encoding");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Start"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Start Encoding"));
}
widget = GHB_WIDGET (ud->builder, "queue_pause1");
if (paused)
{
gtk_widget_set_sensitive (widget, show_stop);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-start");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Resume");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Resume Encoding");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Resume"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Resume Encoding"));
}
else
{
gtk_widget_set_sensitive (widget, show_stop);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-pause");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Pause");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Pause Encoding");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Pause"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Pause Encoding"));
}
widget = GHB_WIDGET (ud->builder, "queue_pause2");
if (paused)
{
gtk_widget_set_sensitive (widget, show_stop);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-start");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Resume");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Resume Encoding");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Resume"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Resume Encoding"));
}
else
{
gtk_widget_set_sensitive (widget, show_stop);
gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-pause");
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Pause");
- gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Pause Encoding");
+ gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), _("Pause"));
+ gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), _("Pause Encoding"));
}
action = GHB_ACTION (ud->builder, "queue_start_menu");
gtk_action_set_sensitive (action, TRUE);
#if GTK_CHECK_VERSION(2, 16, 0)
gtk_action_set_icon_name(action, "hb-stop");
- gtk_action_set_label(action, "S_top Queue");
- gtk_action_set_tooltip(action, "Stop Encoding");
+ gtk_action_set_label(action, _("S_top Queue"));
+ gtk_action_set_tooltip(action, _("Stop Encoding"));
#else
g_object_set_property(G_OBJECT(action), "icon-name",
ghb_string_value("hb-stop"));
g_object_set_property(G_OBJECT(action), "label",
- ghb_string_value("S_top Queue"));
+ ghb_string_value(_("S_top Queue")));
g_object_set_property(G_OBJECT(action), "tooltip",
- ghb_string_value("Stop Encoding"));
+ ghb_string_value(_("Stop Encoding")));
#endif
}
else
gtk_action_set_sensitive (action, show_start);
#if GTK_CHECK_VERSION(2, 16, 0)
gtk_action_set_icon_name(action, "hb-start");
- gtk_action_set_label(action, "_Start Queue");
- gtk_action_set_tooltip(action, "Start Encoding");
+ gtk_action_set_label(action, _("_Start Queue"));
+ gtk_action_set_tooltip(action, _("Start Encoding"));
#else
g_object_set_property(G_OBJECT(action), "icon-name",
ghb_string_value("hb-start"));
g_object_set_property(G_OBJECT(action), "label",
- ghb_string_value("_Start Queue"));
+ ghb_string_value(_("_Start Queue")));
g_object_set_property(G_OBJECT(action), "tooltip",
- ghb_string_value("Start Encoding"));
+ ghb_string_value(_("Start Encoding")));
#endif
}
action = GHB_ACTION (ud->builder, "queue_pause_menu");
g_object_set_property(G_OBJECT(action), "icon-name",
ghb_string_value("hb-start"));
g_object_set_property(G_OBJECT(action), "label",
- ghb_string_value("_Resume Queue"));
+ ghb_string_value(_("_Resume Queue")));
g_object_set_property(G_OBJECT(action), "tooltip",
- ghb_string_value("Resume Encoding"));
+ ghb_string_value(_("Resume Encoding")));
#endif
}
else
gtk_action_set_sensitive (action, show_stop);
#if GTK_CHECK_VERSION(2, 16, 0)
gtk_action_set_icon_name(action, "hb-pause");
- gtk_action_set_label(action, "_Pause Queue");
- gtk_action_set_tooltip(action, "Pause Encoding");
+ gtk_action_set_label(action, _("_Pause Queue"));
+ gtk_action_set_tooltip(action, _("Pause Encoding"));
#else
g_object_set_property(G_OBJECT(action), "icon-name",
ghb_string_value("hb-pause"));
g_object_set_property(G_OBJECT(action), "label",
- ghb_string_value("_Pause Queue"));
+ ghb_string_value(_("_Pause Queue")));
g_object_set_property(G_OBJECT(action), "tooltip",
- ghb_string_value("Pause Encoding"));
+ ghb_string_value(_("Pause Encoding")));
#endif
}
}
if (state & (GHB_STATE_WORKING | GHB_STATE_SEARCHING |
GHB_STATE_SCANNING | GHB_STATE_MUXING))
{
- ghb_cancel_encode(ud, "You are currently encoding. "
- "What would you like to do?");
+ ghb_cancel_encode(ud, _("You are currently encoding. "
+ "What would you like to do?\n\n"));
return;
}
if (unfinished)
{
message = g_strdup_printf(
- "You have %d unfinished job%s in a saved queue.\n\n"
- "Would you like to reload %s?",
- unfinished,
- (unfinished > 1) ? "s" : "",
- (unfinished > 1) ? "them" : "it");
- if (ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "No", "Yes"))
+ _("You have %d unfinished job(s) in a saved queue.\n\n"
+ "Would you like to reload them?"), unfinished);
+ if (ghb_message_dialog(GTK_MESSAGE_QUESTION, message, _("No"), _("Yes")))
{
GtkWidget *widget = GHB_WIDGET (ud->builder, "queue_window");
gtk_widget_show (widget);
hb_encoder_internal_t hb_video_encoders[] =
{
// legacy encoders, back to HB 0.9.4 whenever possible (disabled)
- { { "FFmpeg", "ffmpeg", HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG4, },
+ { { "FFmpeg", "ffmpeg", HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG4, },
{ { "MPEG-4 (FFmpeg)", "ffmpeg4", HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG4, },
{ { "MPEG-2 (FFmpeg)", "ffmpeg2", HB_VCODEC_FFMPEG_MPEG2, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_MPEG2, },
{ { "VP3 (Theora)", "libtheora", HB_VCODEC_THEORA, HB_MUX_MASK_MKV, }, NULL, 0, HB_GID_VCODEC_THEORA, },
// actual encoders
- { { "H.264 (x264)", "x264", HB_VCODEC_X264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
- { { "H.264 (Intel QSV)", "qsv_h264",HB_VCODEC_QSV_H264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
+ { { "H.264 (x264)", "x264", HB_VCODEC_X264, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_H264, },
+ { { "H.264 (Intel QSV)", "qsv_h264", HB_VCODEC_QSV_H264, HB_MUX_MP4V2 | HB_MUX_LIBMKV, }, NULL, 1, HB_GID_VCODEC_H264, },
{ { "MPEG-4", "mpeg4", HB_VCODEC_FFMPEG_MPEG4, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_MPEG4, },
{ { "MPEG-2", "mpeg2", HB_VCODEC_FFMPEG_MPEG2, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_MPEG2, },
{ { "Theora", "theora", HB_VCODEC_THEORA, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_VCODEC_THEORA, },
hb_container_internal_t hb_containers[] =
{
// legacy muxers, back to HB 0.9.4 whenever possible (disabled)
- { { "M4V file", "m4v", "m4v", 0, }, NULL, 0, HB_GID_MUX_MP4, },
- { { "MP4 file", "mp4", "mp4", 0, }, NULL, 0, HB_GID_MUX_MP4, },
- { { "MKV file", "mkv", "mkv", 0, }, NULL, 0, HB_GID_MUX_MKV, },
+ { { "M4V file", "m4v", "m4v", 0, }, NULL, 0, HB_GID_MUX_MP4, },
+ { { "MP4 file", "mp4", "mp4", 0, }, NULL, 0, HB_GID_MUX_MP4, },
+ { { "MKV file", "mkv", "mkv", 0, }, NULL, 0, HB_GID_MUX_MKV, },
// actual muxers
- { { "MPEG-4 (mp4v2)", "mp4v2", "mp4", HB_MUX_MP4V2, }, NULL, 1, HB_GID_MUX_MP4, },
- { { "Matroska (libmkv)", "libmkv", "mkv", HB_MUX_LIBMKV, }, NULL, 1, HB_GID_MUX_MKV, },
+ { { "MPEG-4 (mp4v2)", "mp4v2", "mp4", HB_MUX_MP4V2, }, NULL, 1, HB_GID_MUX_MP4, },
+ { { "Matroska (libmkv)", "libmkv", "mkv", HB_MUX_LIBMKV, }, NULL, 1, HB_GID_MUX_MKV, },
+ { { "MPEG-4 (avformat)", "av_mp4", "mp4", HB_MUX_AV_MP4, }, NULL, 1, HB_GID_MUX_MP4, },
+ { { "Matroska (avformat)", "av_mkv", "mkv", HB_MUX_AV_MKV, }, NULL, 1, HB_GID_MUX_MKV, },
};
int hb_containers_count = sizeof(hb_containers) / sizeof(hb_containers[0]);
static int hb_container_is_enabled(int format)
{
switch (format)
{
-#if 1 //#ifdef USE_MP4V2
+#ifdef USE_MP4V2
case HB_MUX_MP4V2:
- return 1;
#endif
-
- // the following muxers are always enabled
+#ifdef USE_LIBMKV
case HB_MUX_LIBMKV:
+#endif
+#ifdef USE_AVFORMAT
+ case HB_MUX_AV_MP4:
+ case HB_MUX_AV_MKV:
+#endif
return 1;
default:
return ((hb_rate_internal_t*)last)->next;
}
+// Get limits and hints for the UIs.
+//
+// granularity sets the minimum step increments that should be used
+// (it's ok to round up to some nice multiple if you like)
+//
+// direction says whether 'low' limit is highest or lowest
+// quality (direction 0 == lowest value is worst quality)
+void hb_video_quality_get_limits(uint32_t codec, float *low, float *high,
+ float *granularity, int *direction)
+{
+ switch (codec)
+ {
+ case HB_VCODEC_X264:
+ *direction = 1;
+ *granularity = 0.1;
+ *low = 0.;
+ *high = 51.;
+ break;
+
+ case HB_VCODEC_THEORA:
+ *direction = 0;
+ *granularity = 1.;
+ *low = 0.;
+ *high = 63.;
+ break;
+
+ case HB_VCODEC_FFMPEG_MPEG2:
+ case HB_VCODEC_FFMPEG_MPEG4:
+ default:
+ *direction = 1;
+ *granularity = 1.;
+ *low = 1.;
+ *high = 31.;
+ break;
+ }
+}
+
+const char* hb_video_quality_get_name(uint32_t codec)
+{
+ switch (codec)
+ {
+ case HB_VCODEC_X264:
+ return "RF";
+
+ default:
+ return "QP";
+ }
+}
+
// Get limits and hints for the UIs.
//
// granularity sets the minimum step increments that should be used
int hb_subtitle_can_pass( int source, int mux )
{
- if ( mux == HB_MUX_MKV )
+ switch (mux)
{
- switch( source )
- {
- case PGSSUB:
- case VOBSUB:
- case SSASUB:
- case SRTSUB:
- case UTF8SUB:
- case TX3GSUB:
- case CC608SUB:
- case CC708SUB:
- return 1;
+ case HB_MUX_AV_MKV:
+ case HB_MUX_LIBMKV:
+ switch( source )
+ {
+ case PGSSUB:
+ case VOBSUB:
+ case SSASUB:
+ case SRTSUB:
+ case UTF8SUB:
+ case TX3GSUB:
+ case CC608SUB:
+ case CC708SUB:
+ return 1;
- default:
- return 0;
- }
- }
- else if ( mux == HB_MUX_MP4 )
- {
- switch( source )
- {
- case VOBSUB:
- case SSASUB:
- case SRTSUB:
- case UTF8SUB:
- case TX3GSUB:
- case CC608SUB:
- case CC708SUB:
+ default:
+ return 0;
+ } break;
+
+ case HB_MUX_MP4V2:
+ if (source == VOBSUB)
+ {
return 1;
+ } // fall through to next case...
+ case HB_MUX_AV_MP4:
+ switch( source )
+ {
+ case SSASUB:
+ case SRTSUB:
+ case UTF8SUB:
+ case TX3GSUB:
+ case CC608SUB:
+ case CC708SUB:
+ return 1;
- default:
- return 0;
- }
- }
- else
- {
- // Internal error. Should never get here.
- hb_error("internel error. Bad mux %d\n", mux);
- return 0;
+ default:
+ return 0;
+ } break;
+
+ default:
+ // Internal error. Should never get here.
+ hb_error("internel error. Bad mux %d\n", mux);
+ return 0;
}
}
void hb_audio_bitrate_get_limits(uint32_t codec, int samplerate, int mixdown, int *low, int *high);
const hb_rate_t* hb_audio_bitrate_get_next(const hb_rate_t *last);
+void hb_video_quality_get_limits(uint32_t codec, float *low, float *high, float *granularity, int *direction);
+const char* hb_video_quality_get_name(uint32_t codec);
+
void hb_audio_quality_get_limits(uint32_t codec, float *low, float *high, float *granularity, int *direction);
float hb_audio_quality_get_best(uint32_t codec, float quality);
float hb_audio_quality_get_default(uint32_t codec);
*/
#define HB_MUX_MASK 0xFF0000
#define HB_MUX_MP4V2 0x010000
-#define HB_MUX_MASK_MP4 0x0F0000
+#define HB_MUX_AV_MP4 0x020000
+#define HB_MUX_MASK_MP4 0x030000
#define HB_MUX_LIBMKV 0x100000
-#define HB_MUX_MASK_MKV 0xF00000
+#define HB_MUX_AV_MKV 0x200000
+#define HB_MUX_MASK_MKV 0x300000
+#define HB_MUX_MASK_AV 0x220000
/* default muxer for each container */
#define HB_MUX_MP4 HB_MUX_MP4V2
#define HB_MUX_MKV HB_MUX_LIBMKV
int normalize_mix_level; /* mix level normalization (boolean) */
int dither_method; /* dither algorithm */
char * name; /* Output track name */
+ int delay;
} out;
/* Input */
* Put this subtitle in a hb_buffer_t and shove it into the subtitle fifo
*/
buffer = hb_buffer_init( length + 1 );
+ buffer->s.frametype = HB_FRAME_SUBTITLE;
buffer->s.start = wb->data608->current_visible_start_ms;
buffer->s.stop = get_fts(wb);
memcpy( buffer->data, wb->subline, length + 1 );
if (wb->enc_buffer_used)
{
hb_buffer_t *buffer = hb_buffer_init( wb->enc_buffer_used + 1 );
+ buffer->s.frametype = HB_FRAME_SUBTITLE;
buffer->s.start = ms_start;
buffer->s.stop = ms_end;
memcpy( buffer->data, wb->enc_buffer, wb->enc_buffer_used + 1 );
For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
*/
-#include <mp4v2/mp4v2.h>
#include "common.h"
+#if defined(USE_MP4V2)
+#include <mp4v2/mp4v2.h>
+
static int decmp4metadata( hb_title_t *title )
{
MP4FileHandle input_file;
}
return result;
}
+#endif // USE_MP4V2
/*
* decmetadata()
return 0;
}
+#if defined(USE_MP4V2)
/*
* Hacky way of figuring out if this is an MP4, in which case read the data using libmp4v2
*/
{
return decmp4metadata( title );
}
+#endif
return 0;
}
hb_buffer_close( &pv->list_pass_buffer );
out->s = in->s;
+ out->s.frametype = HB_FRAME_SUBTITLE;
out->sequence = in->sequence;
}
out->s.start = out->s.stop = pts;
out = hb_frame_buffer_init(AV_PIX_FMT_YUVA420P,
rect->w, rect->h);
+ out->s.frametype = HB_FRAME_SUBTITLE;
out->s.id = in->s.id;
out->sequence = in->sequence;
out->s.start = pts;
{
out = hb_buffer_init( 1 );
+ out->s.frametype = HB_FRAME_SUBTITLE;
out->s.id = in->s.id;
out->s.start = pts;
out->s.stop = pts;
{
// If decoding to PICTURESUB format:
int readOrder;
+ int raw;
hb_job_t *job;
};
out->size = dst - out->data;
// Copy metadata from the input packet to the output packet
+ out->s.frametype = HB_FRAME_SUBTITLE;
out->s.start = in_start;
out->s.stop = in_stop;
out->sequence = in_sequence;
if ( parse_timing_from_ssa_packet( (char *) in_data, &in_start, &in_stop ) )
goto fail;
+ if (pv->raw)
+ {
+ out = hb_buffer_init(in_size + 3);
+ snprintf((char*)out->data, in_size + 3, "%s\r\n", in_data);
+ out->s.frametype = HB_FRAME_SUBTITLE;
+ out->s.start = in_start;
+ out->s.stop = in_stop;
+ out->sequence = in_sequence;
+ return out;
+ }
+
// Convert the SSA packet to MKV-SSA format, which is what libass expects
char *mkvIn;
int numPartsRead;
strcat( mkvIn, (char *) styleToTextFields );
out->size = strlen(mkvIn);
+ out->s.frametype = HB_FRAME_SUBTITLE;
out->s.start = in_start;
out->s.stop = in_stop;
out->sequence = in_sequence;
pv = calloc( 1, sizeof( hb_work_private_t ) );
w->private_data = pv;
pv->job = job;
+
+ if (job->mux & HB_MUX_MASK_AV)
+ {
+ pv->raw = 1;
+ }
return 0;
}
return HB_WORK_DONE;
}
- if ( w->subtitle->config.dest == PASSTHRUSUB && pv->job->mux == HB_MUX_MKV )
+ if (w->subtitle->config.dest == PASSTHRUSUB &&
+ (pv->job->mux & HB_MUX_MASK_MKV))
{
*buf_out = ssa_to_mkv_ssa(w, in);
}
out->size = dst - out->data;
// Copy metadata from the input packet to the output packet
+ out->s.frametype = HB_FRAME_SUBTITLE;
out->s.start = in->s.start;
out->s.stop = in->s.stop;
// Pass the packets through without modification
hb_buffer_t *out = *buf_in;
+ out->s.frametype = HB_FRAME_SUBTITLE;
+
// Warn if the subtitle's duration has not been passed through by the
// demuxer, which will prevent the subtitle from displaying at all
if (out->s.stop == 0)
pv->buf = hb_buffer_init( 0xFFFF );
memcpy( pv->buf->data, in->data, in->size );
pv->buf->s.id = in->s.id;
+ pv->buf->s.frametype = HB_FRAME_SUBTITLE;
pv->buf->sequence = in->sequence;
pv->size_got = in->size;
if( in->s.start >= 0 )
realheight = crop[1] - crop[0] + 1;
buf = hb_frame_buffer_init( AV_PIX_FMT_YUVA420P, realwidth, realheight );
+ buf->s.frametype = HB_FRAME_SUBTITLE;
buf->s.start = pv->pts_start;
buf->s.stop = pv->pts_stop;
buf->s.type = SUBTITLE_BUF;
struct {
int64_t start;
- int64_t stop;
- int64_t renderOffset;
+ int64_t duration;
} frame_info[FRAME_INFO_SIZE];
};
job->anamorphic.par_width, job->anamorphic.par_height );
}
- if( job->mux & HB_MUX_MP4 )
+ if( job->mux & HB_MUX_MASK_MP4 )
{
context->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
{
job->areBframes = 1;
}
- if( ( job->mux & HB_MUX_MP4 ) && job->pass != 1 )
+ if( ( job->mux & HB_MUX_MASK_MP4 ) && job->pass != 1 )
{
w->config->mpeg4.length = context->extradata_size;
memcpy( w->config->mpeg4.bytes, context->extradata,
{
int i = pv->frameno_in & FRAME_INFO_MASK;
pv->frame_info[i].start = in->s.start;
- pv->frame_info[i].stop = in->s.stop;
+ pv->frame_info[i].duration = in->s.stop - in->s.start;
}
static int64_t get_frame_start( hb_work_private_t * pv, int64_t frameno )
return pv->frame_info[i].start;
}
-static int64_t get_frame_stop( hb_work_private_t * pv, int64_t frameno )
+static int64_t get_frame_duration( hb_work_private_t * pv, int64_t frameno )
{
int i = frameno & FRAME_INFO_MASK;
- return pv->frame_info[i].stop;
+ return pv->frame_info[i].duration;
}
static void compute_dts_offset( hb_work_private_t * pv, hb_buffer_t * buf )
else
{
int64_t frameno = pkt.pts;
- buf->size = pkt.size;
- buf->s.start = get_frame_start( pv, frameno );
- buf->s.stop = get_frame_stop( pv, frameno );
- buf->s.flags &= ~HB_FRAME_REF;
+ buf->size = pkt.size;
+ buf->s.start = get_frame_start( pv, frameno );
+ buf->s.duration = get_frame_duration( pv, frameno );
+ buf->s.stop = buf->s.stop + buf->s.duration;
+ buf->s.flags &= ~HB_FRAME_REF;
switch ( pv->context->coded_frame->pict_type )
{
case AV_PICTURE_TYPE_P:
w->config->extradata.length = context->extradata_size;
}
+ audio->config.out.delay = av_rescale_q(context->delay, context->time_base,
+ (AVRational){1, 90000});
+
return 0;
}
if (got_packet && pkt.size)
{
out->size = pkt.size;
-
// The output pts from libav is in context->time_base. Convert it back
// to our timebase.
- //
- // Also account for the "delay" factor that libav seems to arbitrarily
- // subtract from the packet. Not sure WTH they think they are doing by
- // offsetting the value in a negative direction.
- out->s.start = av_rescale_q(pv->context->delay + pkt.pts,
- pv->context->time_base,
- (AVRational){1, 90000});
-
- out->s.stop = out->s.start + (90000 * pv->samples_per_frame /
- audio->config.out.samplerate);
-
- out->s.type = AUDIO_BUF;
+ out->s.start = av_rescale_q(pkt.pts, pv->context->time_base,
+ (AVRational){1, 90000});
+ out->s.duration = (double)90000 * pv->samples_per_frame /
+ audio->config.out.samplerate;
+ out->s.stop = out->s.start + out->s.duration;
+ out->s.type = AUDIO_BUF;
out->s.frametype = HB_FRAME_AUDIO;
}
else
{
hb_buffer_t * buf = hb_buffer_init( size );
memcpy( buf->data, pv->obuf, size );
- buf->size = size;
- buf->s.start = pv->pts;
- pv->pts += pv->framedur;
- buf->s.stop = pv->pts;
- buf->s.type = AUDIO_BUF;
+ buf->size = size;
+ buf->s.start = pv->pts;
+ buf->s.duration = pv->framedur;
+ buf->s.stop = buf->s.start + buf->s.duration;
+ buf->s.type = AUDIO_BUF;
buf->s.frametype = HB_FRAME_AUDIO;
+ pv->pts += pv->framedur;
return buf;
}
return NULL;
}
}
- buf = hb_buffer_init( pv->output_bytes );
- buf->s.start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate;
- buf->s.stop = buf->s.start + 90000 * 1152 / audio->config.out.samplerate;
+ buf = hb_buffer_init( pv->output_bytes );
+ buf->s.start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate;
+ buf->s.duration = (double)90000 * 1152 / audio->config.out.samplerate;
+ buf->s.stop = buf->s.start + buf->s.duration;
pv->pts = buf->s.stop;
buf->size = lame_encode_buffer_float(
pv->lame, samples[0], samples[1],
th_comment_init( &tc );
- th_encode_flushheader( pv->ctx, &tc, &op );
- memcpy(w->config->theora.headers[0], &op, sizeof(op));
- memcpy(w->config->theora.headers[0] + sizeof(op), op.packet, op.bytes );
+ ogg_packet *header;
- th_encode_flushheader( pv->ctx, &tc, &op );
- memcpy(w->config->theora.headers[1], &op, sizeof(op));
- memcpy(w->config->theora.headers[1] + sizeof(op), op.packet, op.bytes );
-
- th_encode_flushheader( pv->ctx, &tc, &op );
- memcpy(w->config->theora.headers[2], &op, sizeof(op));
- memcpy(w->config->theora.headers[2] + sizeof(op), op.packet, op.bytes );
+ int ii;
+ for (ii = 0; ii < 3; ii++)
+ {
+ th_encode_flushheader( pv->ctx, &tc, &op );
+ header = (ogg_packet*)w->config->theora.headers[ii];
+ memcpy(header, &op, sizeof(op));
+ header->packet = w->config->theora.headers[ii] + sizeof(ogg_packet);
+ memcpy(header->packet, op.packet, op.bytes );
+ }
th_comment_clear( &tc );
}
th_encode_packetout( pv->ctx, 0, &op );
- buf = hb_buffer_init( op.bytes + sizeof(op) );
- memcpy(buf->data, &op, sizeof(op));
- memcpy(buf->data + sizeof(op), op.packet, op.bytes);
+ buf = hb_buffer_init(op.bytes);
+ memcpy(buf->data, op.packet, op.bytes);
buf->f.fmt = AV_PIX_FMT_YUV420P;
buf->f.width = frame_width;
buf->f.height = frame_height;
buf->s.frametype = ( th_packet_iskeyframe(&op) ) ? HB_FRAME_KEY : HB_FRAME_REF;
- buf->s.start = in->s.start;
- buf->s.stop = in->s.stop;
+ buf->s.start = in->s.start;
+ buf->s.stop = in->s.stop;
+ buf->s.duration = in->s.stop - in->s.start;
*buf_out = buf;
/* get the 3 headers */
vorbis_analysis_headerout(&pv->vd, &pv->vc,
&header[0], &header[1], &header[2]);
+ ogg_packet *pheader;
for (i = 0; i < 3; i++)
{
- memcpy(w->config->vorbis.headers[i], &header[i], sizeof(ogg_packet));
- memcpy(w->config->vorbis.headers[i] + sizeof(ogg_packet),
- header[i].packet, header[i].bytes);
+ pheader = (ogg_packet*)w->config->theora.headers[i];
+ memcpy(pheader, &header[i], sizeof(ogg_packet));
+ pheader->packet = w->config->theora.headers[i] + sizeof(ogg_packet);
+ memcpy(pheader->packet, header[i].packet, header[i].bytes );
}
pv->input_samples = pv->out_discrete_channels * OGGVORBIS_FRAME_SIZE;
if( vorbis_bitrate_flushpacket( &pv->vd, &op ) )
{
- buf = hb_buffer_init( sizeof( ogg_packet ) + op.bytes );
- memcpy( buf->data, &op, sizeof( ogg_packet ) );
- memcpy( buf->data + sizeof( ogg_packet ), op.packet,
- op.bytes );
+ buf = hb_buffer_init( op.bytes );
+ memcpy( buf->data, op.packet, op.bytes );
blocksize = vorbis_packet_blocksize(&pv->vi, &op);
buf->s.type = AUDIO_BUF;
buf->s.start = (int64_t)(vorbis_granule_time(&pv->vd, op.granulepos) * 90000);
buf->s.stop = (int64_t)(vorbis_granule_time(&pv->vd, (pv->prev_blocksize + blocksize)/4 + op.granulepos) * 90000);
+ buf->s.duration = buf->s.stop - buf->s.start;
/* The stop time isn't accurate for the first ~3 packets, as the actual blocksize depends on the previous _and_ current packets. */
pv->prev_blocksize = blocksize;
return buf;
return 1;
}
+ /* If the PSNR or SSIM tunes are in use, enable the relevant metric */
+ if (job->x264_tune != NULL && job->x264_tune[0] != '\0')
+ {
+ char *tmp = strdup(job->x264_tune);
+ char *tok = strtok(tmp, ",./-+");
+ do
+ {
+ if (!strncasecmp(tok, "psnr", 4))
+ {
+ param.analyse.b_psnr = 1;
+ break;
+ }
+ if (!strncasecmp(tok, "ssim", 4))
+ {
+ param.analyse.b_ssim = 1;
+ break;
+ }
+ }
+ while ((tok = strtok(NULL, ",./-+")) != NULL);
+ free(tmp);
+ }
+
/* Some HandBrake-specific defaults; users can override them
* using the advanced_opts string. */
-
- /* Enable metrics */
- param.analyse.b_psnr = 1;
- param.analyse.b_ssim = 1;
-
if( job->pass == 2 && job->cfr != 1 )
{
hb_interjob_t * interjob = hb_interjob_get( job->h );
buf->s.frametype = 0;
// use the pts to get the original frame's duration.
- int64_t duration = get_frame_duration( pv, pic_out->i_pts );
- buf->s.start = pic_out->i_pts;
- buf->s.stop = pic_out->i_pts + duration;
+ buf->s.duration = get_frame_duration( pv, pic_out->i_pts );
+ buf->s.start = pic_out->i_pts;
+ buf->s.stop = buf->s.start + buf->s.duration;
buf->s.renderOffset = pic_out->i_dts;
if ( !w->config->h264.init_delay && pic_out->i_dts < 0 )
{
b->alloc = buffer_pool->buffer_size;
b->size = size;
b->data = data;
+ b->s.start = -1;
+ b->s.stop = -1;
+ b->s.renderOffset = -1;
return( b );
}
}
buffers.allocated += b->alloc;
hb_unlock(buffers.lock);
}
+ b->s.start = -1;
+ b->s.stop = -1;
+ b->s.renderOffset = -1;
return b;
}
hb_title_close( &title );
}
+ /* Print CPU info here so that it's in all scan and encode logs */
+ hb_log("hb_scan: CPU count: %i", hb_get_cpu_count());
+ if (hb_get_cpu_name() != NULL)
+ {
+ hb_log("hb_scan: CPU name: %s", hb_get_cpu_name());
+ }
+ if (hb_get_cpu_platform_name() != NULL)
+ {
+ hb_log("hb_scan: CPU type: %s", hb_get_cpu_platform_name());
+ }
+
hb_log( "hb_scan: path=%s, title_index=%d", path, title_index );
- h->scan_thread = hb_scan_init( h, &h->scan_die, path, title_index,
- &h->title_set, preview_count,
+ h->scan_thread = hb_scan_init( h, &h->scan_die, path, title_index,
+ &h->title_set, preview_count,
store_previews, min_duration );
}
uint8_t discontinuity;
int new_chap; // Video packets: if non-zero, is the index of the chapter whose boundary was crossed
- #define HB_FRAME_IDR 0x01
- #define HB_FRAME_I 0x02
- #define HB_FRAME_AUDIO 0x04
- #define HB_FRAME_P 0x10
- #define HB_FRAME_B 0x20
- #define HB_FRAME_BREF 0x40
- #define HB_FRAME_KEY 0x0F
- #define HB_FRAME_REF 0xF0
+ #define HB_FRAME_IDR 0x01
+ #define HB_FRAME_I 0x02
+ #define HB_FRAME_AUDIO 0x04
+ #define HB_FRAME_SUBTITLE 0x08
+ #define HB_FRAME_P 0x10
+ #define HB_FRAME_B 0x20
+ #define HB_FRAME_BREF 0x40
+ #define HB_FRAME_KEY 0x0F
+ #define HB_FRAME_REF 0xF0
uint8_t frametype;
uint16_t flags;
} s;
hb_mux_object_t * hb_mux_##a##_init( hb_job_t * );
DECLARE_MUX( mp4 );
-DECLARE_MUX( avi );
-DECLARE_MUX( ogm );
DECLARE_MUX( mkv );
+DECLARE_MUX( avformat );
+void hb_muxmp4_process_subtitle_style( uint8_t *input,
+ uint8_t *output,
+ uint8_t *style, uint16_t *stylesize );
{ "Zulu", "", "zu", "zul" },
{ NULL, NULL, NULL } };
+static const int lang_count = sizeof(languages) / sizeof(languages[0]);
+
iso639_lang_t * lang_for_code( int code )
{
char code_string[2];
return (iso639_lang_t*) languages;
}
+const iso639_lang_t* lang_get_next(const iso639_lang_t *last)
+{
+ if (last == NULL)
+ {
+ return (const iso639_lang_t*)languages;
+ }
+ if (last < languages || // out of bounds
+ last >= languages + lang_count - 2) // last valid language
+ {
+ return NULL;
+ }
+ return ++last;
+}
+
+
int lang_to_code(const iso639_lang_t *lang);
iso639_lang_t * lang_for_english( const char * english );
+
+/*
+ * Get the next language in the list.
+ * Returns NULL if there are no more languages.
+ * Pass NULL to get the first language in the list.
+ */
+const iso639_lang_t* lang_get_next(const iso639_lang_t *last);
+
#ifdef __cplusplus
}
#endif
ifeq (1,$(FEATURE.faac))
LIBHB.GCC.D += USE_FAAC
endif
+ifeq (1,$(FEATURE.mp4v2))
+LIBHB.GCC.D += USE_MP4V2
+endif
+ifeq (1,$(FEATURE.libmkv))
+LIBHB.GCC.D += USE_LIBMKV
+endif
+ifeq (1,$(FEATURE.avformat))
+LIBHB.GCC.D += USE_AVFORMAT
+endif
LIBHB.GCC.D += __LIBHB__ USE_PTHREAD
LIBHB.GCC.D += __LIBHB__ USE_PTHREAD HAVE_THREADS=1
LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include
LIBHB.GCC.D += SYS_MINGW PTW32_STATIC_LIB
LIBHB.GCC.args.extra.dylib++ += -Wl,--enable-auto-import -static
else ifeq ($(BUILD.system),solaris)
- LIBHB.GCC.D += SYS_SunOS _LARGEFILE_SOURCE _FILE_OFFSET_BITS=64
+ LIBHB.GCC.D += SYS_SunOS _LARGEFILE_SOURCE _FILE_OFFSET_BITS=64 _POSIX_C_SOURCE=200112L __EXTENSIONS__
else
LIBHB.platform.D = SYS_UNKNOWN
endif
LIBHB.dll.libs = $(foreach n, \
a52 ass avcodec avformat avutil avresample dvdnav dvdread \
- fontconfig freetype mkv mpeg2 mp3lame mp4v2 \
+ fontconfig freetype mpeg2 mp3lame \
ogg samplerate swscale theora vorbis vorbisenc x264 xml2 bluray, \
$(CONTRIB.build/)lib/lib$(n).a )
LIBHB.dll.libs += $(CONTRIB.build/)lib/libmfx.a
endif
+ifeq (1,$(FEATURE.mp4v2))
+LIBHB.dll.libs += $(CONTRIB.build/)lib/libmp4v2.a
+endif
+
+ifeq (1,$(FEATURE.libmkv))
+LIBHB.dll.libs += $(CONTRIB.build/)lib/libmkv.a
+endif
+
ifneq ($(HAS.iconv),1)
LIBHB.dll.libs += $(CONTRIB.build/)lib/libiconv.a
else
--- /dev/null
+/* muxavformat.c
+
+ Copyright (c) 2003-2013 HandBrake Team
+ This file is part of the HandBrake source code
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License v2.
+ For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+#if defined(USE_AVFORMAT)
+
+#include <ogg/ogg.h>
+#include "libavformat/avformat.h"
+#include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
+
+#include "hb.h"
+#include "lang.h"
+
+struct hb_mux_data_s
+{
+ enum
+ {
+ MUX_TYPE_VIDEO,
+ MUX_TYPE_AUDIO,
+ MUX_TYPE_SUBTITLE
+ } type;
+
+ AVStream *st;
+
+ int64_t duration;
+
+ hb_buffer_t * delay_buf;
+
+ int64_t prev_chapter_tc;
+ int16_t current_chapter;
+};
+
+struct hb_mux_object_s
+{
+ HB_MUX_COMMON;
+
+ hb_job_t * job;
+
+ AVFormatContext * oc;
+ AVRational time_base;
+
+ int ntracks;
+ hb_mux_data_t ** tracks;
+
+ int delay;
+};
+
+enum
+{
+ META_TITLE,
+ META_ARTIST,
+ META_DIRECTOR,
+ META_COMPOSER,
+ META_RELEASE_DATE,
+ META_COMMENT,
+ META_ALBUM,
+ META_GENRE,
+ META_DESCRIPTION,
+ META_SYNOPSIS,
+ META_LAST
+};
+
+enum
+{
+ META_MUX_MP4,
+ META_MUX_MKV,
+ META_MUX_LAST
+};
+
+const char *metadata_keys[META_LAST][META_MUX_LAST] =
+{
+ {"title", "TITLE"},
+ {"artist", "ARTIST"},
+ {"album_artist", "DIRECTOR"},
+ {"composer", "COMPOSER"},
+ {"date", "DATE_RELEASED"},
+ {"comment", "SUMMARY"},
+ {"album", NULL},
+ {"genre", "GENRE"},
+ {"description", "DESCRIPTION"},
+ {"synopsis", "SYNOPSIS"}
+};
+
+static char* lookup_lang_code(int mux, char *iso639_2)
+{
+ iso639_lang_t *lang;
+ char *out = NULL;
+
+ switch (mux)
+ {
+ case HB_MUX_AV_MP4:
+ out = iso639_2;
+ break;
+ case HB_MUX_AV_MKV:
+ // MKV lang codes should be ISO-639-2B if it exists,
+ // else ISO-639-2
+ lang = lang_for_code2( iso639_2 );
+ out = lang->iso639_2b ? lang->iso639_2b : lang->iso639_2;
+ break;
+ default:
+ break;
+ }
+ return out;
+}
+
+/**********************************************************************
+ * avformatInit
+ **********************************************************************
+ * Allocates hb_mux_data_t structures, create file and write headers
+ *********************************************************************/
+static int avformatInit( hb_mux_object_t * m )
+{
+ hb_job_t * job = m->job;
+ hb_audio_t * audio;
+ hb_mux_data_t * track;
+ int meta_mux;
+ int max_tracks;
+ int ii, ret;
+
+ const char *muxer_name = NULL;
+
+ uint8_t default_track_flag = 1;
+ uint8_t need_fonts = 0;
+ char *lang;
+
+
+ m->delay = -1;
+ max_tracks = 1 + hb_list_count( job->list_audio ) +
+ hb_list_count( job->list_subtitle );
+
+ m->tracks = calloc(max_tracks, sizeof(hb_mux_data_t*));
+
+ m->oc = avformat_alloc_context();
+ if (m->oc == NULL)
+ {
+ hb_error( "Could not initialize avformat context." );
+ goto error;
+ }
+
+ switch (job->mux)
+ {
+ case HB_MUX_AV_MP4:
+ m->time_base.num = 1;
+ m->time_base.den = 90000;
+ if( job->ipod_atom )
+ muxer_name = "ipod";
+ else
+ muxer_name = "mp4";
+ meta_mux = META_MUX_MP4;
+ break;
+
+ case HB_MUX_AV_MKV:
+ // libavformat is essentially hard coded such that it only
+ // works with a timebase of 1/1000
+ m->time_base.num = 1;
+ m->time_base.den = 1000;
+ muxer_name = "matroska";
+ meta_mux = META_MUX_MKV;
+ break;
+
+ default:
+ {
+ hb_error("Invalid Mux %x", job->mux);
+ goto error;
+ }
+ }
+ m->oc->oformat = av_guess_format(muxer_name, NULL, NULL);
+ if(m->oc->oformat == NULL)
+ {
+ hb_error("Could not guess output format %s", muxer_name);
+ goto error;
+ }
+ av_strlcpy(m->oc->filename, job->file, sizeof(m->oc->filename));
+ ret = avio_open2(&m->oc->pb, job->file, AVIO_FLAG_WRITE,
+ &m->oc->interrupt_callback, NULL);
+ if( ret < 0 )
+ {
+ hb_error( "avio_open2 failed, errno %d", ret);
+ goto error;
+ }
+
+ /* Video track */
+ track = m->tracks[m->ntracks++] = calloc(1, sizeof( hb_mux_data_t ) );
+ job->mux_data = track;
+
+ track->type = MUX_TYPE_VIDEO;
+ track->st = avformat_new_stream(m->oc, NULL);
+ if (track->st == NULL)
+ {
+ hb_error("Could not initialize video stream");
+ goto error;
+ }
+ track->st->time_base = m->time_base;
+ avcodec_get_context_defaults3(track->st->codec, NULL);
+
+ track->st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ track->st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ uint8_t *priv_data = NULL;
+ int priv_size = 0;
+ switch (job->vcodec)
+ {
+ case HB_VCODEC_X264:
+ track->st->codec->codec_id = AV_CODEC_ID_H264;
+
+ /* Taken from x264 muxers.c */
+ priv_size = 5 + 1 + 2 + job->config.h264.sps_length + 1 + 2 +
+ job->config.h264.pps_length;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+
+ priv_data[0] = 1;
+ priv_data[1] = job->config.h264.sps[1]; /* AVCProfileIndication */
+ priv_data[2] = job->config.h264.sps[2]; /* profile_compat */
+ priv_data[3] = job->config.h264.sps[3]; /* AVCLevelIndication */
+ priv_data[4] = 0xff; // nalu size length is four bytes
+ priv_data[5] = 0xe1; // one sps
+
+ priv_data[6] = job->config.h264.sps_length >> 8;
+ priv_data[7] = job->config.h264.sps_length;
+
+ memcpy(priv_data+8, job->config.h264.sps,
+ job->config.h264.sps_length);
+
+ priv_data[8+job->config.h264.sps_length] = 1; // one pps
+ priv_data[9+job->config.h264.sps_length] =
+ job->config.h264.pps_length >> 8;
+ priv_data[10+job->config.h264.sps_length] =
+ job->config.h264.pps_length;
+
+ memcpy(priv_data+11+job->config.h264.sps_length,
+ job->config.h264.pps, job->config.h264.pps_length );
+ break;
+
+ case HB_VCODEC_FFMPEG_MPEG4:
+ track->st->codec->codec_id = AV_CODEC_ID_MPEG4;
+
+ if (job->config.mpeg4.length != 0)
+ {
+ priv_size = job->config.mpeg4.length;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+ memcpy(priv_data, job->config.mpeg4.bytes, priv_size);
+ }
+ break;
+
+ case HB_VCODEC_FFMPEG_MPEG2:
+ track->st->codec->codec_id = AV_CODEC_ID_MPEG2VIDEO;
+
+ if (job->config.mpeg4.length != 0)
+ {
+ priv_size = job->config.mpeg4.length;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+ memcpy(priv_data, job->config.mpeg4.bytes, priv_size);
+ }
+ break;
+
+ case HB_VCODEC_THEORA:
+ {
+ track->st->codec->codec_id = AV_CODEC_ID_THEORA;
+
+ int size = 0;
+ ogg_packet *ogg_headers[3];
+
+ for (ii = 0; ii < 3; ii++)
+ {
+ ogg_headers[ii] = (ogg_packet *)job->config.theora.headers[ii];
+ size += ogg_headers[ii]->bytes + 2;
+ }
+
+ priv_size = size;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+
+ size = 0;
+ for(ii = 0; ii < 3; ii++)
+ {
+ AV_WB16(priv_data + size, ogg_headers[ii]->bytes);
+ size += 2;
+ memcpy(priv_data+size, ogg_headers[ii]->packet,
+ ogg_headers[ii]->bytes);
+ size += ogg_headers[ii]->bytes;
+ }
+ } break;
+
+ default:
+ hb_error("muxavformat: Unknown video codec: %x", job->vcodec);
+ goto error;
+ }
+ track->st->codec->extradata = priv_data;
+ track->st->codec->extradata_size = priv_size;
+
+ track->st->codec->width = job->width;
+ track->st->codec->height = job->height;
+ track->st->sample_aspect_ratio.num = job->anamorphic.par_width;
+ track->st->sample_aspect_ratio.den = job->anamorphic.par_height;
+ track->st->codec->sample_aspect_ratio.num = job->anamorphic.par_width;
+ track->st->codec->sample_aspect_ratio.den = job->anamorphic.par_height;
+ track->st->disposition |= AV_DISPOSITION_DEFAULT;
+
+ int vrate_base, vrate;
+ if( job->pass == 2 )
+ {
+ hb_interjob_t * interjob = hb_interjob_get( job->h );
+ vrate_base = interjob->vrate_base;
+ vrate = interjob->vrate;
+ }
+ else
+ {
+ vrate_base = job->vrate_base;
+ vrate = job->vrate;
+ }
+
+ // If the vrate is 27000000, there's a good chance this is
+ // a standard rate that we have in our hb_video_rates table.
+ // Because of rounding errors and approximations made while
+ // measuring framerate, the actual value may not be exact. So
+ // we look for rates that are "close" and make an adjustment
+ // to fps.den.
+ if (vrate == 27000000)
+ {
+ const hb_rate_t *video_framerate = NULL;
+ while ((video_framerate = hb_video_framerate_get_next(video_framerate)) != NULL)
+ {
+ if (abs(vrate_base - video_framerate->rate) < 10)
+ {
+ vrate_base = video_framerate->rate;
+ break;
+ }
+ }
+ }
+ hb_reduce(&vrate_base, &vrate, vrate_base, vrate);
+ if (job->mux == HB_MUX_AV_MP4)
+ {
+ // libavformat mp4 muxer requires that the codec time_base have the
+ // same denominator as the stream time_base, it uses it for the
+ // mdhd timescale.
+ double scale = (double)track->st->time_base.den / vrate;
+ track->st->codec->time_base.den = track->st->time_base.den;
+ track->st->codec->time_base.num = vrate_base * scale;
+ }
+ else
+ {
+ track->st->codec->time_base.num = vrate_base;
+ track->st->codec->time_base.den = vrate;
+ }
+
+ /* add the audio tracks */
+ for(ii = 0; ii < hb_list_count( job->list_audio ); ii++ )
+ {
+ audio = hb_list_item( job->list_audio, ii );
+ track = m->tracks[m->ntracks++] = calloc(1, sizeof( hb_mux_data_t ) );
+ audio->priv.mux_data = track;
+
+ track->type = MUX_TYPE_AUDIO;
+
+ track->st = avformat_new_stream(m->oc, NULL);
+ if (track->st == NULL)
+ {
+ hb_error("Could not initialize audio stream");
+ goto error;
+ }
+ avcodec_get_context_defaults3(track->st->codec, NULL);
+
+ track->st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ track->st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ if (job->mux == HB_MUX_AV_MP4)
+ {
+ track->st->codec->time_base.num = audio->config.out.samples_per_frame;
+ track->st->codec->time_base.den = audio->config.out.samplerate;
+ track->st->time_base.num = 1;
+ track->st->time_base.den = audio->config.out.samplerate;
+ }
+ else
+ {
+ track->st->codec->time_base = m->time_base;
+ }
+
+ priv_data = NULL;
+ priv_size = 0;
+ switch (audio->config.out.codec & HB_ACODEC_MASK)
+ {
+ case HB_ACODEC_DCA:
+ case HB_ACODEC_DCA_HD:
+ track->st->codec->codec_id = AV_CODEC_ID_DTS;
+ break;
+ case HB_ACODEC_AC3:
+ track->st->codec->codec_id = AV_CODEC_ID_AC3;
+ break;
+ case HB_ACODEC_LAME:
+ case HB_ACODEC_MP3:
+ track->st->codec->codec_id = AV_CODEC_ID_MP3;
+ break;
+ case HB_ACODEC_VORBIS:
+ {
+ track->st->codec->codec_id = AV_CODEC_ID_VORBIS;
+
+ int jj, size = 0;
+ ogg_packet *ogg_headers[3];
+
+ for (jj = 0; jj < 3; jj++)
+ {
+ ogg_headers[jj] = (ogg_packet *)audio->priv.config.vorbis.headers[jj];
+ size += ogg_headers[jj]->bytes + 2;
+ }
+
+ priv_size = size;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+
+ size = 0;
+ for(jj = 0; jj < 3; jj++)
+ {
+ AV_WB16(priv_data + size, ogg_headers[jj]->bytes);
+ size += 2;
+ memcpy(priv_data+size, ogg_headers[jj]->packet,
+ ogg_headers[jj]->bytes);
+ size += ogg_headers[jj]->bytes;
+ }
+ } break;
+ case HB_ACODEC_FFFLAC:
+ case HB_ACODEC_FFFLAC24:
+ track->st->codec->codec_id = AV_CODEC_ID_FLAC;
+
+ if (audio->priv.config.extradata.bytes)
+ {
+ priv_size = audio->priv.config.extradata.length;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+ memcpy(priv_data,
+ audio->priv.config.extradata.bytes,
+ audio->priv.config.extradata.length);
+ }
+ break;
+ case HB_ACODEC_FAAC:
+ case HB_ACODEC_FFAAC:
+ case HB_ACODEC_CA_AAC:
+ case HB_ACODEC_CA_HAAC:
+ case HB_ACODEC_FDK_AAC:
+ case HB_ACODEC_FDK_HAAC:
+ track->st->codec->codec_id = AV_CODEC_ID_AAC;
+
+ if (audio->priv.config.extradata.bytes)
+ {
+ priv_size = audio->priv.config.extradata.length;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+ memcpy(priv_data,
+ audio->priv.config.extradata.bytes,
+ audio->priv.config.extradata.length);
+ }
+ break;
+ default:
+ hb_error("muxavformat: Unknown audio codec: %x",
+ audio->config.out.codec);
+ goto error;
+ }
+ track->st->codec->extradata = priv_data;
+ track->st->codec->extradata_size = priv_size;
+
+ if( default_track_flag )
+ {
+ track->st->disposition |= AV_DISPOSITION_DEFAULT;
+ default_track_flag = 0;
+ }
+
+ lang = lookup_lang_code(job->mux, audio->config.lang.iso639_2 );
+ if (lang != NULL)
+ {
+ av_dict_set(&track->st->metadata, "language", lang, 0);
+ }
+ track->st->codec->sample_rate = audio->config.out.samplerate;
+ if (audio->config.out.codec & HB_ACODEC_PASS_FLAG)
+ {
+ track->st->codec->channels = av_get_channel_layout_nb_channels(audio->config.in.channel_layout);
+ track->st->codec->channel_layout = audio->config.in.channel_layout;
+ }
+ else
+ {
+ track->st->codec->channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
+ track->st->codec->channel_layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL);
+ }
+
+ char *name;
+ if (audio->config.out.name == NULL)
+ {
+ switch (track->st->codec->channels)
+ {
+ case 1:
+ name = "Mono";
+ break;
+
+ case 2:
+ name = "Stereo";
+ break;
+
+ default:
+ name = "Surround";
+ break;
+ }
+ }
+ else
+ {
+ name = audio->config.out.name;
+ }
+ av_dict_set(&track->st->metadata, "title", name, 0);
+ }
+
+ char * subidx_fmt =
+ "size: %dx%d\n"
+ "org: %d, %d\n"
+ "scale: 100%%, 100%%\n"
+ "alpha: 100%%\n"
+ "smooth: OFF\n"
+ "fadein/out: 50, 50\n"
+ "align: OFF at LEFT TOP\n"
+ "time offset: 0\n"
+ "forced subs: %s\n"
+ "palette: %06x, %06x, %06x, %06x, %06x, %06x, "
+ "%06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x\n"
+ "custom colors: OFF, tridx: 0000, "
+ "colors: 000000, 000000, 000000, 000000\n";
+
+ int subtitle_default = -1;
+ for( ii = 0; ii < hb_list_count( job->list_subtitle ); ii++ )
+ {
+ hb_subtitle_t *subtitle = hb_list_item( job->list_subtitle, ii );
+
+ if( subtitle->config.dest == PASSTHRUSUB )
+ {
+ if ( subtitle->config.default_track )
+ subtitle_default = ii;
+ }
+ }
+ // Quicktime requires that at least one subtitle is enabled,
+ // else it doesn't show any of the subtitles.
+ // So check to see if any of the subtitles are flagged to be
+ // the defualt. The default will the the enabled track, else
+ // enable the first track.
+ if (job->mux == HB_MUX_AV_MP4 && subtitle_default == -1)
+ {
+ subtitle_default = 0;
+ }
+
+ for( ii = 0; ii < hb_list_count( job->list_subtitle ); ii++ )
+ {
+ hb_subtitle_t * subtitle;
+ uint32_t rgb[16];
+ char subidx[2048];
+ int len;
+
+ subtitle = hb_list_item( job->list_subtitle, ii );
+ if (subtitle->config.dest != PASSTHRUSUB)
+ continue;
+
+ track = m->tracks[m->ntracks++] = calloc(1, sizeof( hb_mux_data_t ) );
+ subtitle->mux_data = track;
+
+ track->type = MUX_TYPE_SUBTITLE;
+ track->st = avformat_new_stream(m->oc, NULL);
+ if (track->st == NULL)
+ {
+ hb_error("Could not initialize subtitle stream");
+ goto error;
+ }
+ avcodec_get_context_defaults3(track->st->codec, NULL);
+
+ track->st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ track->st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ track->st->time_base = m->time_base;
+ track->st->codec->time_base = m->time_base;
+ track->st->codec->width = subtitle->width;
+ track->st->codec->height = subtitle->height;
+
+ priv_data = NULL;
+ priv_size = 0;
+ switch (subtitle->source)
+ {
+ case VOBSUB:
+ {
+ int jj;
+ track->st->codec->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
+
+ for (jj = 0; jj < 16; jj++)
+ rgb[jj] = hb_yuv2rgb(subtitle->palette[jj]);
+ len = snprintf(subidx, 2048, subidx_fmt,
+ subtitle->width, subtitle->height,
+ 0, 0, "OFF",
+ rgb[0], rgb[1], rgb[2], rgb[3],
+ rgb[4], rgb[5], rgb[6], rgb[7],
+ rgb[8], rgb[9], rgb[10], rgb[11],
+ rgb[12], rgb[13], rgb[14], rgb[15]);
+
+ priv_size = len + 1;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+ memcpy(priv_data, subidx, priv_size);
+ } break;
+
+ case PGSSUB:
+ {
+ track->st->codec->codec_id = AV_CODEC_ID_HDMV_PGS_SUBTITLE;
+ } break;
+
+ case SSASUB:
+ {
+ if (job->mux == HB_MUX_AV_MP4)
+ {
+ track->st->codec->codec_id = AV_CODEC_ID_MOV_TEXT;
+ }
+ else
+ {
+ track->st->codec->codec_id = AV_CODEC_ID_SSA;
+ need_fonts = 1;
+
+ if (subtitle->extradata_size)
+ {
+ priv_size = subtitle->extradata_size;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+ memcpy(priv_data, subtitle->extradata, priv_size);
+ }
+ }
+ } break;
+
+ case CC608SUB:
+ case CC708SUB:
+ case UTF8SUB:
+ case TX3GSUB:
+ case SRTSUB:
+ {
+ if (job->mux == HB_MUX_AV_MP4)
+ track->st->codec->codec_id = AV_CODEC_ID_MOV_TEXT;
+ else
+ track->st->codec->codec_id = AV_CODEC_ID_TEXT;
+ } break;
+
+ default:
+ continue;
+ }
+ if (track->st->codec->codec_id == AV_CODEC_ID_MOV_TEXT)
+ {
+ // Build codec extradata for tx3g.
+ // If we were using a libav codec to generate this data
+ // this would (or should) be done for us.
+ uint8_t properties[] = {
+ 0x00, 0x00, 0x00, 0x00, // Display Flags
+ 0x01, // Horiz. Justification
+ 0xff, // Vert. Justification
+ 0x00, 0x00, 0x00, 0xff, // Bg color
+ 0x00, 0x00, 0x00, 0x00, // Default text box
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, // Reserved
+ 0x00, 0x01, // Font ID
+ 0x00, // Font face
+ 0x18, // Font size
+ 0xff, 0xff, 0xff, 0xff, // Fg color
+ // Font table:
+ 0x00, 0x00, 0x00, 0x12, // Font table size
+ 'f','t','a','b', // Tag
+ 0x00, 0x01, // Count
+ 0x00, 0x01, // Font ID
+ 0x05, // Font name length
+ 'A','r','i','a','l' // Font name
+ };
+
+ int width, height = 60;
+ if (job->anamorphic.mode)
+ width = job->width * ((float)job->anamorphic.par_width / job->anamorphic.par_height);
+ else
+ width = job->width;
+ track->st->codec->width = width;
+ track->st->codec->height = height;
+ properties[14] = height >> 8;
+ properties[15] = height & 0xff;
+ properties[16] = width >> 8;
+ properties[17] = width & 0xff;
+
+ priv_size = sizeof(properties);
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+ memcpy(priv_data, properties, priv_size);
+ }
+ track->st->codec->extradata = priv_data;
+ track->st->codec->extradata_size = priv_size;
+
+ if ( ii == subtitle_default )
+ {
+ track->st->disposition |= AV_DISPOSITION_DEFAULT;
+ }
+
+ lang = lookup_lang_code(job->mux, subtitle->iso639_2 );
+ if (lang != NULL)
+ {
+ av_dict_set(&track->st->metadata, "language", lang, 0);
+ }
+ }
+
+ if (need_fonts)
+ {
+ hb_list_t * list_attachment = job->list_attachment;
+ int i;
+ for ( i = 0; i < hb_list_count(list_attachment); i++ )
+ {
+ hb_attachment_t * attachment = hb_list_item( list_attachment, i );
+
+ if (attachment->type == FONT_TTF_ATTACH &&
+ attachment->size > 0)
+ {
+ AVStream *st = avformat_new_stream(m->oc, NULL);
+ if (st == NULL)
+ {
+ hb_error("Could not initialize attachment stream");
+ goto error;
+ }
+ avcodec_get_context_defaults3(st->codec, NULL);
+
+ st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
+ track->st->codec->codec_id = AV_CODEC_ID_TTF;
+
+ priv_size = attachment->size;
+ priv_data = av_malloc(priv_size);
+ if (priv_data == NULL)
+ {
+ hb_error("malloc failure");
+ goto error;
+ }
+ memcpy(priv_data, attachment->data, priv_size);
+
+ track->st->codec->extradata = priv_data;
+ track->st->codec->extradata_size = priv_size;
+
+ av_dict_set(&st->metadata, "filename", attachment->name, 0);
+ }
+ }
+ }
+
+ if( job->metadata )
+ {
+ hb_metadata_t *md = job->metadata;
+
+ hb_deep_log(2, "Writing Metadata to output file...");
+ if (md->name &&
+ metadata_keys[META_TITLE][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_TITLE][meta_mux], md->name, 0);
+ }
+ if (md->artist &&
+ metadata_keys[META_ARTIST][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_ARTIST][meta_mux], md->artist, 0);
+ }
+ if (md->album_artist &&
+ metadata_keys[META_DIRECTOR][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_DIRECTOR][meta_mux],
+ md->album_artist, 0);
+ }
+ if (md->composer &&
+ metadata_keys[META_COMPOSER][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_COMPOSER][meta_mux],
+ md->composer, 0);
+ }
+ if (md->release_date &&
+ metadata_keys[META_RELEASE_DATE][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_RELEASE_DATE][meta_mux],
+ md->release_date, 0);
+ }
+ if (md->comment &&
+ metadata_keys[META_COMMENT][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_COMMENT][meta_mux], md->comment, 0);
+ }
+ if (!md->name && md->album &&
+ metadata_keys[META_ALBUM][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_ALBUM][meta_mux], md->album, 0);
+ }
+ if (md->genre &&
+ metadata_keys[META_GENRE][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_GENRE][meta_mux], md->genre, 0);
+ }
+ if (md->description &&
+ metadata_keys[META_DESCRIPTION][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_DESCRIPTION][meta_mux],
+ md->description, 0);
+ }
+ if (md->long_description &&
+ metadata_keys[META_SYNOPSIS][meta_mux] != NULL)
+ {
+ av_dict_set(&m->oc->metadata,
+ metadata_keys[META_SYNOPSIS][meta_mux],
+ md->long_description, 0);
+ }
+ }
+
+ AVDictionary * av_opts = NULL;
+ if (job->mp4_optimize && (job->mux & HB_MUX_MASK_MP4))
+ av_dict_set( &av_opts, "movflags", "faststart", 0 );
+
+ ret = avformat_write_header(m->oc, &av_opts);
+ if( ret < 0 )
+ {
+ av_dict_free( &av_opts );
+ hb_error( "muxavformat: avformat_write_header failed!");
+ goto error;
+ }
+
+ AVDictionaryEntry *t = NULL;
+ while( ( t = av_dict_get( av_opts, "", t, AV_DICT_IGNORE_SUFFIX ) ) )
+ {
+ hb_log( "muxavformat: Unknown option %s", t->key );
+ }
+ av_dict_free( &av_opts );
+
+ return 0;
+
+error:
+ free(job->mux_data);
+ job->mux_data = NULL;
+ avformat_free_context(m->oc);
+ *job->die = 1;
+ return -1;
+}
+
+static int add_chapter(hb_mux_object_t *m, int64_t start, int64_t end, char * title)
+{
+ AVChapter *chap;
+ AVChapter **chapters;
+ int nchap = m->oc->nb_chapters;
+
+ nchap++;
+ chapters = av_realloc(m->oc->chapters, nchap * sizeof(AVChapter*));
+ if (chapters == NULL)
+ {
+ hb_error("malloc failure");
+ return -1;
+ }
+
+ chap = av_mallocz(sizeof(AVChapter));
+ if (chap == NULL)
+ {
+ hb_error("malloc failure");
+ return -1;
+ }
+
+ m->oc->chapters = chapters;
+ m->oc->chapters[nchap-1] = chap;
+ m->oc->nb_chapters = nchap;
+
+ chap->id = nchap;
+ chap->time_base = m->time_base;
+ chap->start = start;
+ chap->end = end;
+ av_dict_set(&chap->metadata, "title", title, 0);
+
+ return 0;
+}
+
+// Video with b-frames and certain audio types require a lead-in delay.
+// Compute the max delay and offset all timestamps by this amount.
+//
+// For mp4, avformat will automatically put entries in the edts atom
+// to account for the offset of the first dts in each track.
+static void computeDelay(hb_mux_object_t *m)
+{
+ int ii;
+ hb_audio_t * audio;
+
+ m->delay = m->job->config.h264.init_delay;
+ for(ii = 0; ii < hb_list_count( m->job->list_audio ); ii++ )
+ {
+ audio = hb_list_item( m->job->list_audio, ii );
+ if (audio->config.out.delay > m->delay)
+ m->delay = audio->config.out.delay;
+ }
+}
+
+static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *buf)
+{
+ AVPacket pkt;
+ int64_t dts, pts, duration = -1;
+ hb_job_t *job = m->job;
+ uint8_t tx3g_out[2048];
+
+ if (m->delay == -1)
+ {
+ computeDelay(m);
+ }
+
+ if (buf != NULL)
+ {
+ if (buf->s.start != -1)
+ buf->s.start += m->delay;
+ if (buf->s.renderOffset != -1)
+ buf->s.renderOffset += m->delay;
+ }
+
+ // We only compute dts duration for MP4 files
+ if (track->type == MUX_TYPE_VIDEO && (job->mux & HB_MUX_MASK_MP4))
+ {
+ hb_buffer_t * tmp;
+
+ // delay by one frame so that we can compute duration properly.
+ tmp = track->delay_buf;
+ track->delay_buf = buf;
+ buf = tmp;
+ }
+ if (buf == NULL)
+ return 0;
+
+ if (buf->s.renderOffset == -1)
+ {
+ dts = av_rescale_q(buf->s.start, (AVRational){1,90000},
+ track->st->time_base);
+ }
+ else
+ {
+ dts = av_rescale_q(buf->s.renderOffset, (AVRational){1,90000},
+ track->st->time_base);
+ }
+
+ pts = av_rescale_q(buf->s.start, (AVRational){1,90000},
+ track->st->time_base);
+
+ if (track->type == MUX_TYPE_VIDEO && track->delay_buf != NULL)
+ {
+ int64_t delayed_dts;
+ delayed_dts = av_rescale_q(track->delay_buf->s.renderOffset,
+ (AVRational){1,90000},
+ track->st->time_base);
+ duration = delayed_dts - dts;
+ }
+ if (duration < 0 && buf->s.duration > 0)
+ {
+ duration = av_rescale_q(buf->s.duration, (AVRational){1,90000},
+ track->st->time_base);
+ }
+ if (duration < 0)
+ {
+ // There is a possiblility that some subtitles get through the pipeline
+ // without ever discovering their true duration. Make the duration
+ // 10 seconds in this case.
+ if (track->type == MUX_TYPE_SUBTITLE)
+ duration = av_rescale_q(10, (AVRational){1,1},
+ track->st->time_base);
+ else
+ duration = 0;
+ }
+
+ av_init_packet(&pkt);
+ pkt.data = buf->data;
+ pkt.size = buf->size;
+ pkt.dts = dts;
+ pkt.pts = pts;
+ pkt.duration = duration;
+
+ if (track->type == MUX_TYPE_VIDEO &&
+ (job->vcodec == HB_VCODEC_X264 || job->vcodec & HB_VCODEC_FFMPEG_MASK))
+ {
+ if (buf->s.frametype == HB_FRAME_IDR)
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ }
+ else if (buf->s.frametype & HB_FRAME_KEY)
+ {
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ }
+
+ track->duration += pkt.duration;
+
+ switch (track->type)
+ {
+ case MUX_TYPE_VIDEO:
+ {
+ if (job->chapter_markers && buf->s.new_chap)
+ {
+ hb_chapter_t *chapter;
+
+ // reached chapter N, write marker for chapter N-1
+ // we don't know the end time of chapter N-1 till we receive
+ // chapter N. So we are always writing the previous chapter
+ // mark.
+ track->current_chapter = buf->s.new_chap - 1;
+
+ // chapter numbers start at 1, but the list starts at 0
+ chapter = hb_list_item(job->list_chapter,
+ track->current_chapter - 1);
+
+ // make sure we're not writing a chapter that has 0 length
+ if (chapter != NULL && track->prev_chapter_tc < pkt.pts)
+ {
+ char title[1024];
+ if (chapter->title != NULL)
+ {
+ snprintf(title, 1023, "%s", chapter->title);
+ }
+ else
+ {
+ snprintf(title, 1023, "Chapter %d",
+ track->current_chapter);
+ }
+ add_chapter(m, track->prev_chapter_tc, pkt.pts, title);
+ }
+ track->prev_chapter_tc = pkt.pts;
+ }
+ } break;
+
+ case MUX_TYPE_SUBTITLE:
+ {
+ if (job->mux == HB_MUX_AV_MP4)
+ {
+ /* Write an empty sample */
+ if ( track->duration < pts )
+ {
+ AVPacket empty_pkt;
+ uint8_t empty[2] = {0,0};
+
+ av_init_packet(&empty_pkt);
+ empty_pkt.data = empty;
+ empty_pkt.size = 2;
+ empty_pkt.dts = track->duration;
+ empty_pkt.pts = track->duration;
+ empty_pkt.duration = pts - duration;
+ empty_pkt.convergence_duration = empty_pkt.duration;
+ empty_pkt.stream_index = track->st->index;
+ int ret = av_interleaved_write_frame(m->oc, &empty_pkt);
+ if (ret < 0)
+ {
+ hb_error("av_interleaved_write_frame failed!");
+ *job->die = 1;
+ return -1;
+ }
+ track->duration = pts;
+ }
+ uint8_t styleatom[2048];;
+ uint16_t stylesize = 0;
+ uint8_t buffer[2048];
+ uint16_t buffersize = 0;
+
+ *buffer = '\0';
+
+ /*
+ * Copy the subtitle into buffer stripping markup and creating
+ * style atoms for them.
+ */
+ hb_muxmp4_process_subtitle_style( buf->data,
+ buffer,
+ styleatom, &stylesize );
+
+ buffersize = strlen((char*)buffer);
+
+ /* Write the subtitle sample */
+ memcpy( tx3g_out + 2, buffer, buffersize );
+ memcpy( tx3g_out + 2 + buffersize, styleatom, stylesize);
+ tx3g_out[0] = ( buffersize >> 8 ) & 0xff;
+ tx3g_out[1] = buffersize & 0xff;
+ pkt.data = tx3g_out;
+ pkt.size = buffersize + stylesize + 2;
+ }
+ pkt.convergence_duration = pkt.duration;
+
+ } break;
+ case MUX_TYPE_AUDIO:
+ default:
+ break;
+ }
+
+ pkt.stream_index = track->st->index;
+ int ret = av_interleaved_write_frame(m->oc, &pkt);
+ if (ret < 0)
+ {
+ hb_error("av_interleaved_write_frame failed!");
+ *job->die = 1;
+ return -1;
+ }
+
+ hb_buffer_close( &buf );
+ return 0;
+}
+
+static int avformatEnd(hb_mux_object_t *m)
+{
+ hb_job_t *job = m->job;
+ hb_mux_data_t *track = job->mux_data;
+
+ if( !job->mux_data )
+ {
+ /*
+ * We must have failed to create the file in the first place.
+ */
+ return 0;
+ }
+
+ // Flush any delayed frames
+ int ii;
+ for (ii = 0; ii < m->ntracks; ii++)
+ {
+ avformatMux(m, m->tracks[ii], NULL);
+ }
+
+ if (job->chapter_markers)
+ {
+ hb_chapter_t *chapter;
+
+ // get the last chapter
+ chapter = hb_list_item(job->list_chapter, track->current_chapter++);
+
+ // only write the last chapter marker if it lasts at least 1.5 second
+ if (chapter != NULL && chapter->duration > 135000LL)
+ {
+ char title[1024];
+ if (chapter->title != NULL)
+ {
+ snprintf(title, 1023, "%s", chapter->title);
+ }
+ else
+ {
+ snprintf(title, 1023, "Chapter %d", track->current_chapter);
+ }
+ add_chapter(m, track->prev_chapter_tc, track->duration, title);
+ }
+ }
+
+ // Update and track private data that can change during
+ // encode.
+ for(ii = 0; ii < hb_list_count( job->list_audio ); ii++)
+ {
+ AVStream *st;
+ hb_audio_t * audio;
+
+ audio = hb_list_item(job->list_audio, ii);
+ st = audio->priv.mux_data->st;
+
+ switch (audio->config.out.codec & HB_ACODEC_MASK)
+ {
+ case HB_ACODEC_FFFLAC:
+ case HB_ACODEC_FFFLAC24:
+ if( audio->priv.config.extradata.bytes )
+ {
+ uint8_t *priv_data;
+ int priv_size;
+
+ priv_size = audio->priv.config.extradata.length;
+ priv_data = av_realloc(st->codec->extradata, priv_size);
+ if (priv_data == NULL)
+ {
+ break;
+ }
+ memcpy(priv_data,
+ audio->priv.config.extradata.bytes,
+ audio->priv.config.extradata.length);
+ st->codec->extradata = priv_data;
+ st->codec->extradata_size = priv_size;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ av_write_trailer(m->oc);
+ avio_close(m->oc->pb);
+ avformat_free_context(m->oc);
+ m->oc = NULL;
+
+ return 0;
+}
+
+hb_mux_object_t * hb_mux_avformat_init( hb_job_t * job )
+{
+ hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 );
+ m->init = avformatInit;
+ m->mux = avformatMux;
+ m->end = avformatEnd;
+ m->job = job;
+ return m;
+}
+
+#endif // USE_AVFORMAT
{
switch( job->mux )
{
- case HB_MUX_MP4:
+#ifdef USE_MP4V2
+ case HB_MUX_MP4V2:
mux->m = hb_mux_mp4_init( job );
break;
- case HB_MUX_MKV:
+#endif
+#ifdef USE_LIBMKV
+ case HB_MUX_LIBMKV:
mux->m = hb_mux_mkv_init( job );
break;
+#endif
+#ifdef USE_AVFORMAT
+ case HB_MUX_AV_MP4:
+ case HB_MUX_AV_MKV:
+ mux->m = hb_mux_avformat_init( job );
+ break;
+#endif
default:
hb_error( "No muxer selected, exiting" );
*job->die = 1;
muxClose
};
+typedef struct stylerecord_s {
+ enum style_s {ITALIC, BOLD, UNDERLINE} style;
+ uint16_t start;
+ uint16_t stop;
+ struct stylerecord_s *next;
+} stylerecord;
+
+static void hb_makestylerecord( stylerecord **stack,
+ enum style_s style, int start )
+{
+ stylerecord *record = calloc( sizeof( stylerecord ), 1 );
+
+ if( record )
+ {
+ record->style = style;
+ record->start = start;
+ record->next = *stack;
+ *stack = record;
+ }
+}
+
+static void hb_makestyleatom( stylerecord *record, uint8_t *style)
+{
+ uint8_t face = 1;
+ hb_deep_log(3, "Made style '%s' from %d to %d",
+ record->style == ITALIC ? "Italic" : record->style == BOLD ? "Bold" : "Underline", record->start, record->stop);
+
+ switch( record->style )
+ {
+ case ITALIC:
+ face = 2;
+ break;
+ case BOLD:
+ face = 1;
+ break;
+ case UNDERLINE:
+ face = 4;
+ break;
+ default:
+ face = 2;
+ break;
+ }
+
+ style[0] = (record->start >> 8) & 0xff; // startChar
+ style[1] = record->start & 0xff;
+ style[2] = (record->stop >> 8) & 0xff; // endChar
+ style[3] = record->stop & 0xff;
+ style[4] = (1 >> 8) & 0xff; // font-ID
+ style[5] = 1 & 0xff;
+ style[6] = face; // face-style-flags: 1 bold; 2 italic; 4 underline
+ style[7] = 24; // font-size
+ style[8] = 255; // r
+ style[9] = 255; // g
+ style[10] = 255; // b
+ style[11] = 255; // a
+}
+
+/*
+ * Copy the input to output removing markup and adding markup to the style
+ * atom where appropriate.
+ */
+void hb_muxmp4_process_subtitle_style( uint8_t *input,
+ uint8_t *output,
+ uint8_t *style, uint16_t *stylesize )
+{
+ uint8_t *reader = input;
+ uint8_t *writer = output;
+ uint8_t stylecount = 0;
+ uint16_t utf8_count = 0; // utf8 count from start of subtitle
+ stylerecord *stylestack = NULL;
+ stylerecord *oldrecord = NULL;
+
+ while(*reader != '\0') {
+ if( ( *reader & 0xc0 ) == 0x80 )
+ {
+ /*
+ * Track the utf8_count when doing markup so that we get the tx3g stops
+ * based on UTF8 chr counts rather than bytes.
+ */
+ utf8_count++;
+ hb_deep_log( 3, "MuxMP4: Counted %d UTF-8 chrs within subtitle so far",
+ utf8_count);
+ }
+ if (*reader == '<') {
+ /*
+ * possible markup, peek at the next chr
+ */
+ switch(*(reader+1)) {
+ case 'i':
+ if (*(reader+2) == '>') {
+ reader += 3;
+ hb_makestylerecord(&stylestack, ITALIC, (writer - output - utf8_count));
+ } else {
+ *writer++ = *reader++;
+ }
+ break;
+ case 'b':
+ if (*(reader+2) == '>') {
+ reader += 3;
+ hb_makestylerecord(&stylestack, BOLD, (writer - output - utf8_count));
+ } else {
+ *writer++ = *reader++;
+ }
+ break;
+ case 'u':
+ if (*(reader+2) == '>') {
+ reader += 3;
+ hb_makestylerecord(&stylestack, UNDERLINE, (writer - output - utf8_count));
+ } else {
+ *writer++ = *reader++;
+ }
+ break;
+ case '/':
+ switch(*(reader+2)) {
+ case 'i':
+ if (*(reader+3) == '>') {
+ /*
+ * Check whether we then immediately start more markup of the same type, if so then
+ * lets not close it now and instead continue this markup.
+ */
+ if ((*(reader+4) && *(reader+4) == '<') &&
+ (*(reader+5) && *(reader+5) == 'i') &&
+ (*(reader+6) && *(reader+6) == '>')) {
+ /*
+ * Opening italics right after, so don't close off these italics.
+ */
+ hb_deep_log(3, "Joining two sets of italics");
+ reader += (4 + 3);
+ continue;
+ }
+
+
+ if ((*(reader+4) && *(reader+4) == ' ') &&
+ (*(reader+5) && *(reader+5) == '<') &&
+ (*(reader+6) && *(reader+6) == 'i') &&
+ (*(reader+7) && *(reader+7) == '>')) {
+ /*
+ * Opening italics right after, so don't close off these italics.
+ */
+ hb_deep_log(3, "Joining two sets of italics (plus space)");
+ reader += (4 + 4);
+ *writer++ = ' ';
+ continue;
+ }
+ if (stylestack && stylestack->style == ITALIC) {
+ uint8_t style_record[12];
+ stylestack->stop = writer - output - utf8_count;
+ hb_makestyleatom(stylestack, style_record);
+
+ memcpy(style + 10 + (12 * stylecount), style_record, 12);
+ stylecount++;
+
+ oldrecord = stylestack;
+ stylestack = stylestack->next;
+ free(oldrecord);
+ } else {
+ hb_error("Mismatched Subtitle markup '%s'", input);
+ }
+ reader += 4;
+ } else {
+ *writer++ = *reader++;
+ }
+ break;
+ case 'b':
+ if (*(reader+3) == '>') {
+ if (stylestack && stylestack->style == BOLD) {
+ uint8_t style_record[12];
+ stylestack->stop = writer - output - utf8_count;
+ hb_makestyleatom(stylestack, style_record);
+
+ memcpy(style + 10 + (12 * stylecount), style_record, 12);
+ stylecount++;
+ oldrecord = stylestack;
+ stylestack = stylestack->next;
+ free(oldrecord);
+ } else {
+ hb_error("Mismatched Subtitle markup '%s'", input);
+ }
+
+ reader += 4;
+ } else {
+ *writer++ = *reader++;
+ }
+ break;
+ case 'u':
+ if (*(reader+3) == '>') {
+ if (stylestack && stylestack->style == UNDERLINE) {
+ uint8_t style_record[12];
+ stylestack->stop = writer - output - utf8_count;
+ hb_makestyleatom(stylestack, style_record);
+
+ memcpy(style + 10 + (12 * stylecount), style_record, 12);
+ stylecount++;
+
+ oldrecord = stylestack;
+ stylestack = stylestack->next;
+ free(oldrecord);
+ } else {
+ hb_error("Mismatched Subtitle markup '%s'", input);
+ }
+ reader += 4;
+ } else {
+ *writer++ = *reader++;
+ }
+ break;
+ default:
+ *writer++ = *reader++;
+ break;
+ }
+ break;
+ default:
+ *writer++ = *reader++;
+ break;
+ }
+ } else if (*reader == '\r') {
+ // skip '\r' and replace with '\n' if necessary
+ if (*(++reader) != '\n') {
+ *writer++ = '\n';
+ }
+ } else {
+ *writer++ = *reader++;
+ }
+ }
+ *writer = '\0';
+
+ if( stylecount )
+ {
+ *stylesize = 10 + ( stylecount * 12 );
+
+ memcpy( style + 4, "styl", 4);
+
+ style[0] = 0;
+ style[1] = 0;
+ style[2] = (*stylesize >> 8) & 0xff;
+ style[3] = *stylesize & 0xff;
+ style[8] = (stylecount >> 8) & 0xff;
+ style[9] = stylecount & 0xff;
+
+ }
+
+}
+
*/
/* libmkv header */
+
+#if defined(USE_LIBMKV)
+
#include "libmkv.h"
#include <ogg/ogg.h>
/* Scale factor to apply to timecodes to convert from HandBrake's
* 1/90000s to nanoseconds as expected by libmkv */
-#define TIMECODE_SCALE 1000000000 / 90000
+#define NANOSECOND_SCALE 1000000000L
+#define TIMECODE_SCALE 1000000000L / 90000
struct hb_mux_object_s
{
HB_MUX_COMMON;
- hb_job_t * job;
-
+ hb_job_t * job;
mk_Writer * file;
+ int delay;
};
struct hb_mux_data_s
mux_data = calloc(1, sizeof( hb_mux_data_t ) );
audio->priv.mux_data = mux_data;
+ if (audio->config.out.delay > m->delay)
+ m->delay = audio->config.out.delay;
+
mux_data->codec = audio->config.out.codec;
memset(track, 0, sizeof(mk_TrackConfig));
char chapter_name[1024];
hb_chapter_t *chapter_data;
uint64_t timecode = 0;
- ogg_packet *op = NULL;
hb_job_t *job = m->job;
+ // Adjust for audio preroll and scale units
+ timecode = (buf->s.start + m->delay) * TIMECODE_SCALE;
if (mux_data == job->mux_data)
{
/* Video */
- timecode = buf->s.start * TIMECODE_SCALE;
-
if (job->chapter_markers && buf->s.new_chap)
{
// reached chapter N, write marker for chapter N-1
}
mux_data->prev_chapter_tc = timecode;
}
-
- if (job->vcodec == HB_VCODEC_THEORA)
- {
- /* ughhh, theora is a pain :( */
- op = (ogg_packet *)buf->data;
- op->packet = buf->data + sizeof( ogg_packet );
- if (mk_startFrame(m->file, mux_data->track) < 0)
- {
- hb_error( "Failed to write frame to output file, Disk Full?" );
- *job->die = 1;
- }
- mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
- mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0);
- hb_buffer_close( &buf );
- return 0;
- }
}
else if (mux_data->subtitle)
{
*job->die = 1;
}
uint64_t duration;
- timecode = buf->s.start * TIMECODE_SCALE;
- if (buf->s.stop <= buf->s.start)
+ if (buf->s.duration < 0)
{
- duration = 0;
+ duration = 10 * NANOSECOND_SCALE;
}
else
{
- duration = buf->s.stop * TIMECODE_SCALE - timecode;
+ duration = buf->s.duration * TIMECODE_SCALE;
}
mk_addFrameData(m->file, mux_data->track, buf->data, buf->size);
mk_setFrameFlags(m->file, mux_data->track, timecode, 1, duration);
else
{
/* Audio */
- timecode = buf->s.start * TIMECODE_SCALE;
- if (mux_data->codec == HB_ACODEC_VORBIS)
- {
- /* ughhh, vorbis is a pain :( */
- op = (ogg_packet *)buf->data;
- op->packet = buf->data + sizeof( ogg_packet );
- if (mk_startFrame(m->file, mux_data->track))
- {
- hb_error( "Failed to write frame to output file, Disk Full?" );
- *job->die = 1;
- }
- mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
- mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0);
- hb_buffer_close( &buf );
- return 0;
- }
}
if( mk_startFrame(m->file, mux_data->track) < 0)
m->job = job;
return m;
}
+#endif // USE_LIBMKV
For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
*/
+#include "hb.h"
+
+#if defined(USE_MP4V2)
+
#include "mp4v2/mp4v2.h"
#include "a52dec/a52.h"
-#include "hb.h"
-
struct hb_mux_object_s
{
HB_MUX_COMMON;
int subtitle_default;
/* Flags for enabling/disabling tracks in an MP4. */
- typedef enum { TRACK_DISABLED = 0x0, TRACK_ENABLED = 0x1, TRACK_IN_MOVIE = 0x2, TRACK_IN_PREVIEW = 0x4, TRACK_IN_POSTER = 0x8} track_header_flags;
+ enum
+ {
+ TRACK_DISABLED = 0x0,
+ TRACK_ENABLED = 0x1,
+ TRACK_IN_MOVIE = 0x2,
+ TRACK_IN_PREVIEW = 0x4,
+ TRACK_IN_POSTER = 0x8
+ };
/* Create an empty mp4 file */
if (job->largeFileSize)
return 0;
}
-typedef struct stylerecord_s {
- enum style_s {ITALIC, BOLD, UNDERLINE} style;
- uint16_t start;
- uint16_t stop;
- struct stylerecord_s *next;
-} stylerecord;
-
-static void hb_makestylerecord( stylerecord **stack,
- enum style_s style, int start )
+static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
+ hb_buffer_t * buf )
{
- stylerecord *record = calloc( sizeof( stylerecord ), 1 );
-
- if( record )
- {
- record->style = style;
- record->start = start;
- record->next = *stack;
- *stack = record;
- }
-}
+ hb_job_t * job = m->job;
+ int64_t duration, stop = -1;
+ int64_t offset = 0;
+ hb_buffer_t *tmp;
-static void hb_makestyleatom( stylerecord *record, uint8_t *style)
-{
- uint8_t face = 1;
- hb_deep_log(3, "Made style '%s' from %d to %d",
- record->style == ITALIC ? "Italic" : record->style == BOLD ? "Bold" : "Underline", record->start, record->stop);
-
- switch( record->style )
+ if (buf != NULL)
{
- case ITALIC:
- face = 2;
- break;
- case BOLD:
- face = 1;
- break;
- case UNDERLINE:
- face = 4;
- break;
- default:
- face = 2;
- break;
- }
-
- style[0] = (record->start >> 8) & 0xff; // startChar
- style[1] = record->start & 0xff;
- style[2] = (record->stop >> 8) & 0xff; // endChar
- style[3] = record->stop & 0xff;
- style[4] = (1 >> 8) & 0xff; // font-ID
- style[5] = 1 & 0xff;
- style[6] = face; // face-style-flags: 1 bold; 2 italic; 4 underline
- style[7] = 24; // font-size
- style[8] = 255; // r
- style[9] = 255; // g
- style[10] = 255; // b
- style[11] = 255; // a
-
-}
-
-/*
- * Copy the input to output removing markup and adding markup to the style
- * atom where appropriate.
- */
-static void hb_muxmp4_process_subtitle_style( uint8_t *input,
- uint8_t *output,
- uint8_t *style, uint16_t *stylesize )
-{
- uint8_t *reader = input;
- uint8_t *writer = output;
- uint8_t stylecount = 0;
- uint16_t utf8_count = 0; // utf8 count from start of subtitle
- stylerecord *stylestack = NULL;
- stylerecord *oldrecord = NULL;
-
- while(*reader != '\0') {
- if( ( *reader & 0xc0 ) == 0x80 )
+ if (buf->s.duration >= 0)
{
- /*
- * Track the utf8_count when doing markup so that we get the tx3g stops
- * based on UTF8 chr counts rather than bytes.
- */
- utf8_count++;
- hb_deep_log( 3, "MuxMP4: Counted %d UTF-8 chrs within subtitle so far",
- utf8_count);
+ stop = buf->s.start + buf->s.duration;
}
- if (*reader == '<') {
- /*
- * possible markup, peek at the next chr
- */
- switch(*(reader+1)) {
- case 'i':
- if (*(reader+2) == '>') {
- reader += 3;
- hb_makestylerecord(&stylestack, ITALIC, (writer - output - utf8_count));
- } else {
- *writer++ = *reader++;
- }
- break;
- case 'b':
- if (*(reader+2) == '>') {
- reader += 3;
- hb_makestylerecord(&stylestack, BOLD, (writer - output - utf8_count));
- } else {
- *writer++ = *reader++;
- }
- break;
- case 'u':
- if (*(reader+2) == '>') {
- reader += 3;
- hb_makestylerecord(&stylestack, UNDERLINE, (writer - output - utf8_count));
- } else {
- *writer++ = *reader++;
- }
- break;
- case '/':
- switch(*(reader+2)) {
- case 'i':
- if (*(reader+3) == '>') {
- /*
- * Check whether we then immediately start more markup of the same type, if so then
- * lets not close it now and instead continue this markup.
- */
- if ((*(reader+4) && *(reader+4) == '<') &&
- (*(reader+5) && *(reader+5) == 'i') &&
- (*(reader+6) && *(reader+6) == '>')) {
- /*
- * Opening italics right after, so don't close off these italics.
- */
- hb_deep_log(3, "Joining two sets of italics");
- reader += (4 + 3);
- continue;
- }
-
-
- if ((*(reader+4) && *(reader+4) == ' ') &&
- (*(reader+5) && *(reader+5) == '<') &&
- (*(reader+6) && *(reader+6) == 'i') &&
- (*(reader+7) && *(reader+7) == '>')) {
- /*
- * Opening italics right after, so don't close off these italics.
- */
- hb_deep_log(3, "Joining two sets of italics (plus space)");
- reader += (4 + 4);
- *writer++ = ' ';
- continue;
- }
- if (stylestack && stylestack->style == ITALIC) {
- uint8_t style_record[12];
- stylestack->stop = writer - output - utf8_count;
- hb_makestyleatom(stylestack, style_record);
-
- memcpy(style + 10 + (12 * stylecount), style_record, 12);
- stylecount++;
-
- oldrecord = stylestack;
- stylestack = stylestack->next;
- free(oldrecord);
- } else {
- hb_error("Mismatched Subtitle markup '%s'", input);
- }
- reader += 4;
- } else {
- *writer++ = *reader++;
- }
- break;
- case 'b':
- if (*(reader+3) == '>') {
- if (stylestack && stylestack->style == BOLD) {
- uint8_t style_record[12];
- stylestack->stop = writer - output - utf8_count;
- hb_makestyleatom(stylestack, style_record);
-
- memcpy(style + 10 + (12 * stylecount), style_record, 12);
- stylecount++;
- oldrecord = stylestack;
- stylestack = stylestack->next;
- free(oldrecord);
- } else {
- hb_error("Mismatched Subtitle markup '%s'", input);
- }
-
- reader += 4;
- } else {
- *writer++ = *reader++;
- }
- break;
- case 'u':
- if (*(reader+3) == '>') {
- if (stylestack && stylestack->style == UNDERLINE) {
- uint8_t style_record[12];
- stylestack->stop = writer - output - utf8_count;
- hb_makestyleatom(stylestack, style_record);
-
- memcpy(style + 10 + (12 * stylecount), style_record, 12);
- stylecount++;
-
- oldrecord = stylestack;
- stylestack = stylestack->next;
- free(oldrecord);
- } else {
- hb_error("Mismatched Subtitle markup '%s'", input);
- }
- reader += 4;
- } else {
- *writer++ = *reader++;
- }
- break;
- default:
- *writer++ = *reader++;
- break;
- }
- break;
- default:
- *writer++ = *reader++;
- break;
- }
- } else if (*reader == '\r') {
- // skip '\r' and replace with '\n' if necessary
- if (*(++reader) != '\n') {
- *writer++ = '\n';
- }
- } else {
- *writer++ = *reader++;
+ else if (mux_data->subtitle)
+ {
+ buf->s.duration = 10 * 90000;
+ stop = buf->s.start + buf->s.duration;
}
}
- *writer = '\0';
-
- if( stylecount )
- {
- *stylesize = 10 + ( stylecount * 12 );
-
- memcpy( style + 4, "styl", 4);
-
- style[0] = 0;
- style[1] = 0;
- style[2] = (*stylesize >> 8) & 0xff;
- style[3] = *stylesize & 0xff;
- style[8] = (stylecount >> 8) & 0xff;
- style[9] = stylecount & 0xff;
-
- }
-
-}
-
-static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
- hb_buffer_t * buf )
-{
- hb_job_t * job = m->job;
- int64_t duration;
- int64_t offset = 0;
- hb_buffer_t *tmp;
if( mux_data == job->mux_data )
{
if ( !buf )
return 0;
+ stop = buf->s.start + buf->s.duration;
+
if ((job->vcodec & HB_VCODEC_H264_MASK) ||
(job->vcodec & HB_VCODEC_FFMPEG_MASK))
{
}
else
{
- duration = buf->s.stop - m->sum_dur;
+ duration = stop - m->sum_dur;
// Due to how libx264 generates DTS, it's possible for the
// above calculation to be negative.
//
// We're getting the frames in decode order but the timestamps are
// for presentation so we have to use durations and effectively
// compute a DTS.
- duration = buf->s.stop - buf->s.start;
+ duration = buf->s.duration;
}
if ( duration <= 0 )
try to fix the error so that the file will still be playable. */
hb_log("MP4Mux: illegal duration %"PRId64", start %"PRId64","
"stop %"PRId64", sum_dur %"PRId64,
- duration, buf->s.start, buf->s.stop, m->sum_dur );
+ duration, buf->s.start, stop, m->sum_dur );
/* we don't know when the next frame starts so we can't pick a
valid duration for this one. we pick something "short"
(roughly 1/3 of an NTSC frame time) to take time from
code should coalesce overlapping subtitle lines. */
if( buf->s.start < mux_data->sum_dur )
{
- if ( buf->s.stop - mux_data->sum_dur > 90*500 )
+ if ( stop - mux_data->sum_dur > 90*500 )
{
hb_log("MP4Mux: shortening overlapping subtitle, "
"start %"PRId64", stop %"PRId64", sum_dur %"PRId64,
- buf->s.start, buf->s.stop, m->sum_dur);
+ buf->s.start, stop, m->sum_dur);
buf->s.start = mux_data->sum_dur;
}
}
{
hb_log("MP4Mux: skipping overlapping subtitle, "
"start %"PRId64", stop %"PRId64", sum_dur %"PRId64,
- buf->s.start, buf->s.stop, m->sum_dur);
+ buf->s.start, stop, m->sum_dur);
}
else
{
- int64_t duration;
-
- if( buf->s.start < 0 )
- buf->s.start = mux_data->sum_dur;
-
- if( buf->s.stop < 0 )
- duration = 90000L * 10;
- else
- duration = buf->s.stop - buf->s.start;
-
/* Write an empty sample */
if ( mux_data->sum_dur < buf->s.start )
{
buffersize = strlen((char*)buffer);
- hb_deep_log(3, "MuxMP4:Sub:%fs:%"PRId64":%"PRId64":%"PRId64": %s",
- (float)buf->s.start / 90000, buf->s.start, buf->s.stop,
- duration, buffer);
+ hb_deep_log(3, "MuxMP4:Sub:%fs:%"PRId64":%"PRId64":%f: %s",
+ (float)buf->s.start / 90000, buf->s.start, stop,
+ buf->s.duration, buffer);
/* Write the subtitle sample */
memcpy( output + 2, buffer, buffersize );
mux_data->track,
output,
buffersize + stylesize + 2,
- duration,
+ buf->s.duration,
0,
1 ))
{
*job->die = 1;
}
- mux_data->sum_dur += duration;
+ mux_data->sum_dur += buf->s.duration;
}
}
else if( mux_data->sub_format == PICTURESUB )
{
- int64_t duration;
-
- if( buf->s.start < 0 )
- buf->s.start = mux_data->sum_dur;
-
- if( buf->s.stop < 0 )
- duration = 90000L * 10;
- else
- duration = buf->s.stop - buf->s.start;
-
/* Write an empty sample */
if ( mux_data->sum_dur < buf->s.start )
{
mux_data->track,
buf->data,
buf->size,
- duration,
+ buf->s.duration,
0,
1 ))
{
*job->die = 1;
}
- mux_data->sum_dur += duration;
+ mux_data->sum_dur += buf->s.duration;
}
}
else
static int MP4End( hb_mux_object_t * m )
{
hb_job_t * job = m->job;
+ int i;
if (m->file != MP4_INVALID_FILE_HANDLE)
{
if ( job->config.h264.init_delay )
{
- // Insert track edit to get A/V back in sync. The edit amount is
- // the init_delay.
- int64_t edit_amt = job->config.h264.init_delay;
- MP4AddTrackEdit(m->file, 1, MP4_INVALID_EDIT_ID, edit_amt,
- MP4GetTrackDuration(m->file, 1), 0);
- if ( m->job->chapter_markers )
- {
- // apply same edit to chapter track to keep it in sync with video
- MP4AddTrackEdit(m->file, m->chapter_track, MP4_INVALID_EDIT_ID,
- edit_amt,
- MP4GetTrackDuration(m->file, m->chapter_track), 0);
- }
- }
+ // Insert track edit to get A/V back in sync. The edit amount is
+ // the init_delay.
+ int64_t edit_amt = job->config.h264.init_delay;
+ MP4AddTrackEdit(m->file, 1, MP4_INVALID_EDIT_ID, edit_amt,
+ MP4GetTrackDuration(m->file, 1), 0);
+ if ( m->job->chapter_markers )
+ {
+ // apply same edit to chapter track to keep it in sync with video
+ MP4AddTrackEdit(m->file, m->chapter_track, MP4_INVALID_EDIT_ID,
+ edit_amt,
+ MP4GetTrackDuration(m->file, m->chapter_track), 0);
+ }
+ }
+
+ // Check for audio preroll and add edit entries for audio
+ for( i = 0; i < hb_list_count( job->list_audio ); i++ )
+ {
+ hb_audio_t *audio = hb_list_item( job->list_audio, i );
+ hb_mux_data_t *mux_data = audio->priv.mux_data;
+ if (audio->config.out.delay > 0)
+ {
+ int64_t edit_amt = audio->config.out.delay;
+ MP4AddTrackEdit(m->file, mux_data->track, MP4_INVALID_EDIT_ID,
+ edit_amt, MP4GetTrackDuration(m->file, 1), 0);
+ }
+ }
/*
* Write the MP4 iTunes metadata if we have any metadata
return m;
}
+#endif // USE_MP4V2
#include <unistd.h>
#include "hb.h"
+#include "libavutil/cpu.h"
/************************************************************************
* hb_get_date()
}
/************************************************************************
- * hb_get_cpu_count()
- ************************************************************************
- * Whenever possible, returns the number of CPUs on the current
- * computer. Returns 1 otherwise.
- * The detection is actually only performed on the first call.
+ * Get information about the CPU (number of cores, name, platform name)
************************************************************************/
+static void init_cpu_info();
+static int init_cpu_count();
+struct
+{
+ enum hb_cpu_platform platform;
+ const char *name;
+ char buf[48];
+ int count;
+} hb_cpu_info;
+
int hb_get_cpu_count()
{
- static int cpu_count = 0;
+ return hb_cpu_info.count;
+}
+
+int hb_get_cpu_platform()
+{
+ return hb_cpu_info.platform;
+}
+
+const char* hb_get_cpu_name()
+{
+ return hb_cpu_info.name;
+}
+
+const char* hb_get_cpu_platform_name()
+{
+ switch (hb_cpu_info.platform)
+ {
+ // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 3C
+ // Table 35-1: CPUID Signature Values of DisplayFamily_DisplayModel
+ case HB_CPU_PLATFORM_INTEL_SNB:
+ return "Intel microarchitecture Sandy Bridge";
+ case HB_CPU_PLATFORM_INTEL_IVB:
+ return "Intel microarchitecture Ivy Bridge";
+ case HB_CPU_PLATFORM_INTEL_HSW:
+ return "Intel microarchitecture Haswell";
+
+ default:
+ return NULL;
+ }
+}
+
+static void init_cpu_info()
+{
+ hb_cpu_info.name = NULL;
+ hb_cpu_info.count = init_cpu_count();
+ hb_cpu_info.platform = HB_CPU_PLATFORM_UNSPECIFIED;
- if( cpu_count )
+ if (av_get_cpu_flags() & AV_CPU_FLAG_SSE)
{
- return cpu_count;
+ int eax, ebx, ecx, edx, family, model;
+
+ ff_cpu_cpuid(1, &eax, &ebx, &ecx, &edx);
+ family = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
+ model = ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0);
+
+ // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 3C
+ // Table 35-1: CPUID Signature Values of DisplayFamily_DisplayModel
+ switch (family)
+ {
+ case 0x06:
+ {
+ switch (model)
+ {
+ case 0x2A:
+ case 0x2D:
+ hb_cpu_info.platform = HB_CPU_PLATFORM_INTEL_SNB;
+ break;
+ case 0x3A:
+ case 0x3E:
+ hb_cpu_info.platform = HB_CPU_PLATFORM_INTEL_IVB;
+ break;
+ case 0x3C:
+ case 0x45:
+ case 0x46:
+ hb_cpu_info.platform = HB_CPU_PLATFORM_INTEL_HSW;
+ break;
+ default:
+ break;
+ }
+ } break;
+
+ default:
+ break;
+ }
+
+ // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 2A
+ // Figure 3-8: Determination of Support for the Processor Brand String
+ // Table 3-17: Information Returned by CPUID Instruction
+ ff_cpu_cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
+ if ((eax & 0x80000004) < 0x80000004)
+ {
+ ff_cpu_cpuid(0x80000002,
+ (int*)&hb_cpu_info.buf[ 0],
+ (int*)&hb_cpu_info.buf[ 4],
+ (int*)&hb_cpu_info.buf[ 8],
+ (int*)&hb_cpu_info.buf[12]);
+ ff_cpu_cpuid(0x80000003,
+ (int*)&hb_cpu_info.buf[16],
+ (int*)&hb_cpu_info.buf[20],
+ (int*)&hb_cpu_info.buf[24],
+ (int*)&hb_cpu_info.buf[28]);
+ ff_cpu_cpuid(0x80000004,
+ (int*)&hb_cpu_info.buf[32],
+ (int*)&hb_cpu_info.buf[36],
+ (int*)&hb_cpu_info.buf[40],
+ (int*)&hb_cpu_info.buf[44]);
+
+ hb_cpu_info.name = hb_cpu_info.buf;
+ hb_cpu_info.buf[47] = '\0'; // just in case
+
+ while (isspace(*hb_cpu_info.name))
+ {
+ // skip leading whitespace to prettify
+ hb_cpu_info.name++;
+ }
+ }
}
- cpu_count = 1;
+}
+
+/*
+ * Whenever possible, returns the number of CPUs on the current computer.
+ * Returns 1 otherwise.
+ */
+static int init_cpu_count()
+{
+ int cpu_count = 1;
#if defined(SYS_CYGWIN) || defined(SYS_MINGW)
SYSTEM_INFO cpuinfo;
}
#endif
+ init_cpu_info();
+
return result;
}
#define DIR_SEP_STR "/"
#endif
+/************************************************************************
+ * CPU info utilities
+ ***********************************************************************/
+enum hb_cpu_platform
+{
+ // list of microarchitecture codenames
+ HB_CPU_PLATFORM_UNSPECIFIED = 0,
+ HB_CPU_PLATFORM_INTEL_SNB,
+ HB_CPU_PLATFORM_INTEL_IVB,
+ HB_CPU_PLATFORM_INTEL_HSW,
+};
+int hb_get_cpu_count();
+int hb_get_cpu_platform();
+const char* hb_get_cpu_name();
+const char* hb_get_cpu_platform_name();
+extern void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx);
+
/************************************************************************
* Utils
***********************************************************************/
uint64_t hb_get_time_us();
void hb_snooze( int delay );
-int hb_get_cpu_count();
int hb_platform_init();
#ifdef SYS_MINGW
char *strtok_r(char *s, const char *delim, char **save_ptr);
#endif /* __LIBHB__ */
#endif
+
* For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
*/
+#include "hb.h"
+#include "ports.h"
#include "common.h"
#include "hb_dict.h"
#include "qsv_common.h"
static mfxVersion qsv_minimum_version;
static int qsv_hardware_available = 0;
static int qsv_software_available = 0;
-static char cpu_name_buf[48];
// check available Intel Media SDK version against a minimum
#define HB_CHECK_MFX_VERSION(MFX_VERSION, MAJOR, MINOR) \
return -1;
}
- hb_qsv_info->cpu_name = NULL;
- // detect the CPU platform to check for hardware-specific capabilities
- if (av_get_cpu_flags() & AV_CPU_FLAG_SSE)
- {
- int eax, ebx, ecx, edx;
- int family = 0, model = 0;
-
- ff_cpu_cpuid(1, &eax, &ebx, &ecx, &edx);
- family = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
- model = ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0);
-
- // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 2A
- // Figure 3-8: Determination of Support for the Processor Brand String
- // Table 3-17: Information Returned by CPUID Instruction
- ff_cpu_cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
- if ((eax & 0x80000004) < 0x80000004)
- {
- ff_cpu_cpuid(0x80000002,
- (int*)&cpu_name_buf[ 0], (int*)&cpu_name_buf[ 4],
- (int*)&cpu_name_buf[ 8], (int*)&cpu_name_buf[12]);
- ff_cpu_cpuid(0x80000003,
- (int*)&cpu_name_buf[16], (int*)&cpu_name_buf[20],
- (int*)&cpu_name_buf[24], (int*)&cpu_name_buf[28]);
- ff_cpu_cpuid(0x80000004,
- (int*)&cpu_name_buf[32], (int*)&cpu_name_buf[36],
- (int*)&cpu_name_buf[40], (int*)&cpu_name_buf[44]);
-
- cpu_name_buf[47] = '\0'; // just in case
- hb_qsv_info->cpu_name = (const char*)cpu_name_buf;
- while (isspace(*hb_qsv_info->cpu_name))
- {
- // skip leading whitespace to prettify
- hb_qsv_info->cpu_name++;
- }
- }
-
- // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 3C
- // Table 35-1: CPUID Signature Values of DisplayFamily_DisplayModel
- if (family == 0x06)
- {
- switch (model)
- {
- case 0x2A:
- case 0x2D:
- hb_qsv_info->cpu_platform = HB_CPU_PLATFORM_INTEL_SNB;
- break;
- case 0x3A:
- case 0x3E:
- hb_qsv_info->cpu_platform = HB_CPU_PLATFORM_INTEL_IVB;
- break;
- case 0x3C:
- case 0x45:
- case 0x46:
- hb_qsv_info->cpu_platform = HB_CPU_PLATFORM_INTEL_HSW;
- break;
- default:
- hb_qsv_info->cpu_platform = HB_CPU_PLATFORM_UNSPECIFIED;
- break;
- }
- }
- }
-
mfxSession session;
qsv_minimum_version.Major = HB_QSV_MINVERSION_MAJOR;
qsv_minimum_version.Minor = HB_QSV_MINVERSION_MINOR;
hb_qsv_info->capabilities |= HB_QSV_CAP_OPTION2_BRC;
hb_qsv_info->capabilities |= HB_QSV_CAP_MSDK_API_1_6;
}
- if (hb_qsv_info->cpu_platform == HB_CPU_PLATFORM_INTEL_HSW)
+ if (hb_get_cpu_platform() == HB_CPU_PLATFORM_INTEL_HSW)
{
if (HB_CHECK_MFX_VERSION(qsv_hardware_version, 1, 7))
{
hb_log("Intel Quick Sync Video support: %s",
hb_qsv_available() ? "yes": "no");
- // print the hardware summary too
- hb_log(" - CPU name: %s", hb_qsv_info->cpu_name);
- switch (hb_qsv_info->cpu_platform)
- {
- // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 3C
- // Table 35-1: CPUID Signature Values of DisplayFamily_DisplayModel
- case HB_CPU_PLATFORM_INTEL_SNB:
- hb_log(" - Intel microarchitecture Sandy Bridge");
- break;
- case HB_CPU_PLATFORM_INTEL_IVB:
- hb_log(" - Intel microarchitecture Ivy Bridge");
- break;
- case HB_CPU_PLATFORM_INTEL_HSW:
- hb_log(" - Intel microarchitecture Haswell");
- break;
- default:
- break;
- }
-
// if we have Quick Sync Video support, also print the details
if (hb_qsv_available())
{
#define HB_QSV_CAP_OPTION2_LOOKAHEAD (1 << 3) // mfxExtCodingOption2: LookAhead
#define HB_QSV_CAP_OPTION2_TRELLIS (1 << 4) // mfxExtCodingOption2: Trellis
- // if a feature depends on the cpu generation
- enum
- {
- // list of microarchitecture codenames
- HB_CPU_PLATFORM_UNSPECIFIED = 0,
- HB_CPU_PLATFORM_INTEL_SNB,
- HB_CPU_PLATFORM_INTEL_IVB,
- HB_CPU_PLATFORM_INTEL_HSW,
- }
- cpu_platform;
- const char *cpu_name;
-
// TODO: add available decoders, filters, encoders,
// maximum decode and encode resolution, etc.
} hb_qsv_info_t;
else if ( buf->s.start >= r->job->pts_to_start )
{
r->job->pts_to_start = 0;
- r->start_found = 1;
}
+ r->start_found = 1;
}
}
double gain_factor;
} hb_sync_audio_t;
+typedef struct
+{
+ int link;
+ int merge;
+ hb_buffer_t * list_current;
+ hb_buffer_t * last;
+} subtitle_sanitizer_t;
+
typedef struct
{
/* Video */
int chap_mark; /* to propagate chapter mark across a drop */
hb_buffer_t * cur; /* The next picture to process */
+ subtitle_sanitizer_t *subtitle_sanitizer;
+
/* Statistics */
uint64_t st_counts[4];
uint64_t st_dates[4];
static void getPtsOffset( hb_work_object_t * w );
static int checkPtsOffset( hb_work_object_t * w );
static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i );
+static void InitSubtitle( hb_job_t * job, hb_sync_video_t * sync, int i );
static void InsertSilence( hb_work_object_t * w, int64_t d );
static void UpdateState( hb_work_object_t * w );
static void UpdateSearchState( hb_work_object_t * w, int64_t start );
for ( i = 0; i < pv->common->pts_count; i++ )
pv->common->first_pts[i] = INT64_MAX;
+ int count = hb_list_count(job->list_subtitle);
+ sync->subtitle_sanitizer = calloc(count, sizeof(subtitle_sanitizer_t));
+ for( i = 0; i < count; i++ )
+ {
+ InitSubtitle(job, sync, i);
+ }
return ret;
}
+static void InitSubtitle( hb_job_t * job, hb_sync_video_t * sync, int i )
+{
+ hb_subtitle_t * subtitle;
+
+ subtitle = hb_list_item( job->list_subtitle, i );
+ if (subtitle->format == TEXTSUB &&
+ subtitle->config.dest == PASSTHRUSUB &&
+ (job->mux & HB_MUX_MASK_MP4))
+ {
+ // Merge overlapping subtitles since mpv tx3g does not support them
+ sync->subtitle_sanitizer[i].merge = 1;
+ }
+ if (subtitle->config.dest == PASSTHRUSUB)
+ {
+ // Fill in stop time when it is missing
+ sync->subtitle_sanitizer[i].link = 1;
+ }
+}
+
/***********************************************************************
* Close Video
***********************************************************************
w->private_data = NULL;
}
+#define ABS(a) ((a) < 0 ? -(a) : (a))
+
+static hb_buffer_t * mergeSubtitles(subtitle_sanitizer_t *sanitizer, int end)
+{
+ hb_buffer_t *a, *b, *buf, *out = NULL, *last = NULL;
+
+ do
+ {
+ a = sanitizer->list_current;
+
+ buf = NULL;
+ if (a != NULL && end)
+ {
+ sanitizer->list_current = a->next;
+ if (sanitizer->list_current == NULL)
+ sanitizer->last = NULL;
+ a->next = NULL;
+ buf = a;
+ }
+ else if (a != NULL && a->s.stop != -1)
+ {
+ b = a->next;
+
+ if (b != NULL && !sanitizer->merge)
+ {
+ sanitizer->list_current = a->next;
+ if (sanitizer->list_current == NULL)
+ sanitizer->last = NULL;
+ a->next = NULL;
+ buf = a;
+ }
+ else if (b != NULL && a->s.stop > b->s.start)
+ {
+ // Overlap
+ if (ABS(a->s.start - b->s.start) <= 18000)
+ {
+ // subtitles start within 1/5 second of eachother, merge
+ sanitizer->list_current = a->next;
+ if (sanitizer->list_current == NULL)
+ sanitizer->last = NULL;
+ a->next = NULL;
+ b->s.start = a->s.stop;
+
+ buf = hb_buffer_init(a->size + b->size);
+ buf->s = a->s;
+ sprintf((char*)buf->data, "%s\n%s", a->data, b->data);
+ hb_buffer_close(&a);
+
+ if (b->s.stop != -1 && ABS(b->s.stop - b->s.start) <= 18000)
+ {
+ // b and a completely overlap, remove b
+ sanitizer->list_current = b->next;
+ if (sanitizer->list_current == NULL)
+ sanitizer->last = NULL;
+ hb_buffer_close(&b);
+ }
+ }
+ else
+ {
+ // a starts before b, output copy of a and
+ buf = hb_buffer_dup(a);
+ buf->s.stop = b->s.start;
+ a->s.start = b->s.start;
+ }
+ }
+ else if (b != NULL && a->s.stop <= b->s.start)
+ {
+ sanitizer->list_current = a->next;
+ if (sanitizer->list_current == NULL)
+ sanitizer->last = NULL;
+ a->next = NULL;
+ buf = a;
+ }
+ }
+
+ if (buf != NULL)
+ {
+ if (buf->s.stop != -1)
+ buf->s.duration = buf->s.stop - buf->s.start;
+ else
+ buf->s.duration = -1;
+ if (last == NULL)
+ {
+ out = last = buf;
+ }
+ else
+ {
+ last->next = buf;
+ last = buf;
+ }
+ }
+ } while (buf != NULL);
+
+ return out;
+}
+
+static hb_buffer_t * sanitizeSubtitle(
+ hb_work_private_t * pv,
+ int i,
+ hb_buffer_t * sub)
+{
+ hb_sync_video_t * sync;
+ subtitle_sanitizer_t * sanitizer;
+
+ sync = &pv->type.video;
+ sanitizer = &sync->subtitle_sanitizer[i];
+
+ if (!sanitizer->link && !sanitizer->merge)
+ {
+ return sub;
+ }
+
+ if (sub == NULL)
+ {
+ return mergeSubtitles(sanitizer, 1);
+ }
+
+ hb_lock( pv->common->mutex );
+ sub->s.start -= pv->common->video_pts_slip;
+ if (sub->s.stop != -1)
+ sub->s.stop -= pv->common->video_pts_slip;
+ if (sub->s.renderOffset != -1)
+ sub->s.renderOffset -= pv->common->video_pts_slip;
+ hb_unlock( pv->common->mutex );
+
+ if (sanitizer->last != NULL && sanitizer->last->s.stop == -1)
+ {
+ sanitizer->last->s.stop = sub->s.start;
+ }
+
+ if (sanitizer->last == NULL)
+ {
+ sanitizer->list_current = sanitizer->last = sub;
+ }
+ else
+ {
+ sanitizer->last->next = sub;
+ sanitizer->last = sub;
+ }
+ return mergeSubtitles(sanitizer, 0);
+}
+
/***********************************************************************
* syncVideoWork
***********************************************************************
}
}
hb_lock( pv->common->mutex );
- // Tell the audio threads what must be dropped
- pv->common->audio_pts_thresh = next_start + pv->common->video_pts_slip;
+ if (job->frame_to_start > 0)
+ {
+ // When doing frame based p-to-p we must update the audio
+ // start point with each frame skipped.
+ //
+ // Tell the audio threads what must be dropped
+ pv->common->audio_pts_thresh = next->s.start;
+ }
hb_cond_broadcast( pv->common->next_frame );
hb_unlock( pv->common->mutex );
for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
{
subtitle = hb_list_item( job->list_subtitle, i );
+ // flush out any pending subtitle buffers in the sanitizer
+ hb_buffer_t *out = sanitizeSubtitle(pv, i, NULL);
+ if (out != NULL)
+ hb_fifo_push( subtitle->fifo_out, out );
if( subtitle->config.dest == PASSTHRUSUB )
{
hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
{
subtitle = hb_list_item( job->list_subtitle, i );
+ // flush out any pending subtitle buffers in the sanitizer
+ hb_buffer_t *out = sanitizeSubtitle(pv, i, NULL);
+ if (out != NULL)
+ hb_fifo_push( subtitle->fifo_out, out );
if( subtitle->config.dest == PASSTHRUSUB )
{
hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
{
subtitle = hb_list_item( job->list_subtitle, i );
+ // flush out any pending subtitle buffers in the sanitizer
+ hb_buffer_t *out = sanitizeSubtitle(pv, i, NULL);
+ if (out != NULL)
+ hb_fifo_push( subtitle->fifo_out, out );
if( subtitle->config.dest == PASSTHRUSUB )
{
hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
{
- int64_t sub_start, sub_stop, duration;
+ hb_buffer_t *out;
subtitle = hb_list_item( job->list_subtitle, i );
// Sanitize subtitle start and stop times, then pass to
// muxer or renderer filter.
- while ( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) != NULL )
+ while ( ( sub = hb_fifo_get( subtitle->fifo_raw ) ) != NULL )
{
- hb_lock( pv->common->mutex );
- sub_start = sub->s.start - pv->common->video_pts_slip;
- hb_unlock( pv->common->mutex );
-
- if (sub->s.stop == -1)
- {
- if (subtitle->config.dest != RENDERSUB &&
- hb_fifo_size( subtitle->fifo_raw ) < 2)
- {
- // For passthru subs, we want to wait for the
- // next subtitle so that we can fill in the stop time.
- // This way the muxer can compute the duration of
- // the subtitle.
- //
- // For render subs, we need to ensure that they
- // get to the renderer before the associated video
- // that they are to be applied to. It is the
- // responsibility of the renderer to handle
- // stop == -1.
- break;
- }
- }
-
- sub = hb_fifo_get( subtitle->fifo_raw );
- if ( sub->s.stop == -1 )
+ if (sub->size > 0)
{
- hb_buffer_t *next;
- next = hb_fifo_see( subtitle->fifo_raw );
- if (next != NULL)
- sub->s.stop = next->s.start;
+ out = sanitizeSubtitle(pv, i, sub);
+ if (out != NULL)
+ hb_fifo_push( subtitle->fifo_out, out );
}
- // Need to re-write subtitle timestamps to account
- // for any slippage.
- sub_stop = -1;
- if ( sub->s.stop != -1 )
- {
- duration = sub->s.stop - sub->s.start;
- sub_stop = sub_start + duration;
- }
-
- sub->s.start = sub_start;
- sub->s.stop = sub_stop;
-
- hb_fifo_push( subtitle->fifo_out, sub );
}
}
sync->cur = cur = next;
cur->sub = NULL;
cur->s.start -= pv->common->video_pts_slip;
+ if (cur->s.renderOffset != -1)
+ cur->s.renderOffset -= pv->common->video_pts_slip;
cur->s.stop -= pv->common->video_pts_slip;
sync->pts_skip = 0;
if ( duration <= 0 )
hb_unlock( pv->common->mutex );
}
- /* Wait for start frame if doing point-to-point */
+ // Wait for start frame if doing point-to-point
+ //
+ // When doing p-to-p, video leads the way. The video thead will set
+ // start_found when we have reached the start point.
+ //
+ // When doing frame based p-to-p, as each video frame is processed
+ // it advances audio_pts_thresh which informs us how much audio must
+ // be dropped.
hb_lock( pv->common->mutex );
- start = buf->s.start - pv->common->audio_pts_slip;
while ( !pv->common->start_found && !*w->done )
{
if ( pv->common->audio_pts_thresh < 0 )
hb_unlock( pv->common->mutex );
return HB_WORK_OK;
}
+
+ // We should only get here when doing frame based p-to-p.
+ // In frame based p-to-p, the video sync thread updates
+ // audio_pts_thresh as it discards frames. So wait here
+ // until the current audio frame needs to be discarded
+ // or start point is found.
while ( !pv->common->start_found &&
buf->s.start >= pv->common->audio_pts_thresh && !*w->done )
{
}
}
}
- start = buf->s.start - pv->common->audio_pts_slip;
}
- if ( start < 0 )
+ start = buf->s.start - pv->common->audio_pts_slip;
+ hb_unlock( pv->common->mutex );
+
+ // When doing p-to-p, video determines when the start point has been
+ // found. Since audio and video are processed asynchronously, there
+ // may yet be audio packets in the pipe that are before the start point.
+ // These packets will have negative start times after applying
+ // audio_pts_slip.
+ if (start < 0)
{
- hb_buffer_close( &buf );
- hb_unlock( pv->common->mutex );
+ hb_buffer_close(&buf);
return HB_WORK_OK;
}
- hb_unlock( pv->common->mutex );
if( job->frame_to_stop && pv->common->count_frames >= job->frame_to_stop )
{
case HB_MUX_MP4V2:
if (job->largeFileSize)
hb_log(" + 64-bit chunk offsets");
+ case HB_MUX_AV_MP4:
if (job->mp4_optimize)
hb_log(" + optimized for HTTP streaming (fast start)");
if (job->ipod_atom)
hb_log(" + h264 level: %s", job->h264_level);
}
- if( job->vquality >= 0 )
+ if (job->vquality >= 0)
{
- hb_log( " + quality: %.2f %s", job->vquality, job->vcodec == HB_VCODEC_X264 ? "(RF)" : "(QP)" );
+ hb_log(" + quality: %.2f (%s)", job->vquality,
+ hb_video_quality_get_name(job->vcodec));
}
else
{
if (chapter->title != NULL)
{
[fChapterTitlesArray addObject:[NSString
- stringWithUTF8String:chapter->title]];
+ stringWithFormat:@"%s",
+ chapter->title]];
}
else
{
BOOL fRipIndicatorShown;
/* Queue File variables */
+ FSEventStreamRef QueueStream;
NSString * QueueFile;
NSMutableArray * QueueFileArray;
int currentQueueEncodeIndex; // Used to track the currently encoding queueu item
- (void) doAddAllTitlesToQueue;
/* Queue File Stuff */
+- (void) initQueueFSEvent;
+- (void) closeQueueFSEvent;
- (void) loadQueueFile;
+- (void) reloadQueue;
- (NSDictionary *)createQueueFileItem;
- (void)saveQueueFileItem;
- (void) incrementQueueItemDone:(int) queueItemDoneIndexNum;
+ (unsigned int) maximumNumberOfAllowedAudioTracks { return maximumNumberOfAllowedAudioTracks; }
+- (NSString *)appSupportPath
+{
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSString *appSupportPath = nil;
+
+ NSArray *allPaths = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory,
+ NSUserDomainMask,
+ YES );
+ if( [allPaths count] )
+ appSupportPath = [[allPaths objectAtIndex:0] stringByAppendingPathComponent:@"HandBrake"];
+
+ if( ![fileManager fileExistsAtPath:appSupportPath] )
+ [fileManager createDirectoryAtPath:appSupportPath withIntermediateDirectories:YES attributes:nil error:NULL];
+
+ return appSupportPath;
+}
+
- (id)init
{
self = [super init];
/* Check for check for the app support directory here as
* outputPanel needs it right away, as may other future methods
*/
- NSString *libraryDir = [NSSearchPathForDirectoriesInDomains( NSLibraryDirectory,
- NSUserDomainMask,
- YES ) objectAtIndex:0];
- AppSupportDirectory = [[libraryDir stringByAppendingPathComponent:@"Application Support"]
- stringByAppendingPathComponent:@"HandBrake"];
- if( ![[NSFileManager defaultManager] fileExistsAtPath:AppSupportDirectory] )
- {
- [[NSFileManager defaultManager] createDirectoryAtPath:AppSupportDirectory
- attributes:nil];
- }
+ AppSupportDirectory = [self appSupportPath];
/* Check for and create the App Support Preview directory if necessary */
NSString *PreviewDirectory = [AppSupportDirectory stringByAppendingPathComponent:@"Previews"];
if( ![[NSFileManager defaultManager] fileExistsAtPath:PreviewDirectory] )
/* Init QueueFile .plist */
[self loadQueueFile];
+ [self initQueueFSEvent];
/* Run hbInstances to get any info on other instances as well as set the
* pid number for this instance in the case of multi-instance encoding. */
hbInstanceNum = [self hbInstances];
[self setQueueEncodingItemsAsPending];
}
+ [self reloadQueue];
[self showQueueWindow:NULL];
}
}
// it's highly probable that the user throw a lot of files and just want to reset this
[[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles];
+ [self closeQueueFSEvent];
[currentQueueEncodeNameString release];
[browsedSourceDisplayName release];
[outputPanel release];
break;
}
}
-
- /* Since we can use multiple instance off of the same queue file it is imperative that we keep the QueueFileArray updated off of the QueueFile.plist
- * so we go ahead and do it in this existing timer as opposed to using a new one */
-
- NSMutableArray * tempQueueArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
- [QueueFileArray setArray:tempQueueArray];
- [tempQueueArray release];
- /* Send Fresh QueueFileArray to fQueueController to update queue window */
- [fQueueController setQueueArray: QueueFileArray];
+
[self getQueueStats];
-
+
/* Update the visibility of the Auto Passthru advanced options box */
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"ShowAdvancedOptsForAutoPassthru"] == YES)
{
{
/* User chose to override our warning and scan the physical dvd anyway, at their own peril. on an encrypted dvd this produces massive log files and fails */
cancelScanDecrypt = 0;
- [self writeToActivityLog: "User overrode copy-proteciton warning - trying to open physical dvd without decryption"];
+ [self writeToActivityLog:"User overrode copy-protection warning - trying to open physical dvd without decryption"];
}
}
- else
+ else if (dvdcss != NULL)
{
/* VLC was found in /Applications so all is well, we can carry on using vlc's libdvdcss.dylib for decrypting if needed */
[self writeToActivityLog: "libdvdcss.2.dylib found for decrypting physical dvd"];
dlclose(dvdcss);
}
+ else
+ {
+ /* User chose to override our warning and scan the physical dvd anyway, at their own peril. on an encrypted dvd this produces massive log files and fails */
+ cancelScanDecrypt = 0;
+ [self writeToActivityLog:"Copy-protection warning disabled in preferences - trying to open physical dvd without decryption"];
+ }
}
if (cancelScanDecrypt == 0)
#pragma mark -
#pragma mark Queue File
-- (void) loadQueueFile {
+static void queueFSEventStreamCallback(
+ ConstFSEventStreamRef streamRef,
+ void *clientCallBackInfo,
+ size_t numEvents,
+ void *eventPaths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[])
+{
+ HBController *hb = (HBController *)clientCallBackInfo;
+ [hb reloadQueue];
+}
+
+- (void)initQueueFSEvent
+{
+ /* Define variables and create a CFArray object containing
+ CFString objects containing paths to watch.
+ */
+ CFStringRef mypath = (CFStringRef) [[self appSupportPath] stringByAppendingPathComponent:@"Queue"];
+ CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
+
+ FSEventStreamContext callbackCtx;
+ callbackCtx.version = 0;
+ callbackCtx.info = self;
+ callbackCtx.retain = NULL;
+ callbackCtx.release = NULL;
+ callbackCtx.copyDescription = NULL;
+
+ CFAbsoluteTime latency = 0.5; /* Latency in seconds */
+
+ /* Create the stream, passing in a callback */
+ QueueStream = FSEventStreamCreate(NULL,
+ &queueFSEventStreamCallback,
+ &callbackCtx,
+ pathsToWatch,
+ kFSEventStreamEventIdSinceNow,
+ latency,
+ kFSEventStreamCreateFlagIgnoreSelf
+ );
+
+ /* Create the stream before calling this. */
+ FSEventStreamScheduleWithRunLoop(QueueStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ FSEventStreamStart(QueueStream);
+}
+
+- (void)closeQueueFSEvent
+{
+ FSEventStreamStop(QueueStream);
+ FSEventStreamInvalidate(QueueStream);
+ FSEventStreamRelease(QueueStream);
+}
+
+- (void)loadQueueFile
+{
/* We declare the default NSFileManager into fileManager */
- NSFileManager * fileManager = [NSFileManager defaultManager];
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSString *appSupportPath = [self appSupportPath];
+
/* We define the location of the user presets file */
- QueueFile = @"~/Library/Application Support/HandBrake/Queue.plist";
- QueueFile = [[QueueFile stringByExpandingTildeInPath]retain];
+ QueueFile = [[appSupportPath stringByAppendingPathComponent:@"Queue/Queue.plist"] retain];
+
/* We check for the Queue.plist */
- if ([fileManager fileExistsAtPath:QueueFile] == 0)
+ if( ![fileManager fileExistsAtPath:QueueFile] )
{
+ if( ![fileManager fileExistsAtPath:[appSupportPath stringByAppendingPathComponent:@"Queue"]] )
+ {
+ [fileManager createDirectoryAtPath:[appSupportPath stringByAppendingPathComponent:@"Queue"] withIntermediateDirectories:YES attributes:nil error:NULL];
+ }
+
[fileManager createFileAtPath:QueueFile contents:nil attributes:nil];
}
-
+
QueueFileArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
/* lets check to see if there is anything in the queue file .plist */
- if (nil == QueueFileArray)
+ if( QueueFileArray == nil )
{
/* if not, then lets initialize an empty array */
QueueFileArray = [[NSMutableArray alloc] init];
else
{
/* ONLY clear out encoded items if we are single instance */
- if (hbInstanceNum == 1)
+ if( hbInstanceNum == 1 )
{
[self clearQueueEncodedItems];
}
}
}
+- (void)reloadQueue
+{
+ [self writeToActivityLog:"Queue reloaded"];
+
+ NSMutableArray * tempQueueArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
+ [QueueFileArray setArray:tempQueueArray];
+ [tempQueueArray release];
+ /* Send Fresh QueueFileArray to fQueueController to update queue window */
+ [fQueueController setQueueArray: QueueFileArray];
+}
+
- (void)addQueueFileItem
{
[QueueFileArray addObject:[self createQueueFileItem]];
[fVidBitrateField setStringValue:[queueToApply objectForKey:@"VideoAvgBitrate"]];
- if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
+ int direction;
+ float minValue, maxValue, granularity;
+ hb_video_quality_get_limits([[fVidEncoderPopUp selectedItem] tag],
+ &minValue, &maxValue, &granularity, &direction);
+ if (!direction)
{
- /* Since theora's qp value goes up from left to right, we can just set the slider float value */
[fVidQualitySlider setFloatValue:[[queueToApply objectForKey:@"VideoQualitySlider"] floatValue]];
}
else
{
- /* Since ffmpeg and x264 use an "inverted" slider (lower qp/rf values indicate a higher quality) we invert the value on the slider */
- [fVidQualitySlider setFloatValue:([fVidQualitySlider maxValue] + [fVidQualitySlider minValue]) - [[queueToApply objectForKey:@"VideoQualitySlider"] floatValue]];
+ /*
+ * Since ffmpeg and x264 use an "inverted" slider (lower values
+ * indicate a higher quality) we invert the value on the slider
+ */
+ [fVidQualitySlider setFloatValue:([fVidQualitySlider minValue] +
+ [fVidQualitySlider maxValue] -
+ [[queueToApply objectForKey:@"VideoQualitySlider"] floatValue])];
}
[self videoMatrixChanged:nil];
//[self calculateBitrate: sender];
/* We're changing the chapter range - we may need to flip the m4v/mp4 extension */
- if ([fDstFormatPopUp indexOfSelectedItem] == 0)
- [self autoSetM4vExtension: sender];
+ if ([[fDstFormatPopUp selectedItem] tag] & HB_MUX_MASK_MP4)
+ [self autoSetM4vExtension:sender];
}
- (IBAction) startEndSecValueChanged: (id) sender
{
case HB_MUX_MP4V2:
[fDstMp4LargeFileCheck setHidden:NO];
+ case HB_MUX_AV_MP4:
[fDstMp4HttpOptFileCheck setHidden:NO];
[fDstMp4iPodFileCheck setHidden:NO];
break;
- (IBAction) autoSetM4vExtension: (id) sender
{
- if ( [fDstFormatPopUp indexOfSelectedItem] )
+ if (!([[fDstFormatPopUp selectedItem] tag] & HB_MUX_MASK_MP4))
return;
NSString * extension = @"mp4";
*/
- (void) setupQualitySlider
{
- /* Get the current slider maxValue to check for a change in slider scale later
- * so that we can choose a new similar value on the new slider scale */
- float previousMaxValue = [fVidQualitySlider maxValue];
- float previousPercentOfSliderScale = [fVidQualitySlider floatValue] / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue] + 1);
- NSString * qpRFLabelString = @"QP:";
- /* x264 0-51 */
+ /*
+ * Get the current slider maxValue to check for a change in slider scale
+ * later so that we can choose a new similar value on the new slider scale
+ */
+ float previousMaxValue = [fVidQualitySlider maxValue];
+ float previousPercentOfSliderScale = ([fVidQualitySlider floatValue] /
+ ([fVidQualitySlider maxValue] -
+ [fVidQualitySlider minValue] + 1));
+ [fVidQualityRFLabel setStringValue:[NSString stringWithFormat:@"%s",
+ hb_video_quality_get_name([[fVidEncoderPopUp
+ selectedItem] tag])]];
+ int direction;
+ float minValue, maxValue, granularity;
+ hb_video_quality_get_limits([[fVidEncoderPopUp selectedItem] tag],
+ &minValue, &maxValue, &granularity, &direction);
if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_X264)
{
- [fVidQualitySlider setMinValue:0.0];
- [fVidQualitySlider setMaxValue:51.0];
- /* As x264 allows for qp/rf values that are fractional, we get the value from the preferences */
- int fractionalGranularity = 1 / [[NSUserDefaults standardUserDefaults] floatForKey:@"x264CqSliderFractional"];
- [fVidQualitySlider setNumberOfTickMarks:(([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]) * fractionalGranularity) + 1];
- qpRFLabelString = @"RF:";
- }
- /* FFmpeg MPEG-2/4 1-31 */
- if ([[fVidEncoderPopUp selectedItem] tag] & HB_VCODEC_FFMPEG_MASK )
- {
- [fVidQualitySlider setMinValue:1.0];
- [fVidQualitySlider setMaxValue:31.0];
- [fVidQualitySlider setNumberOfTickMarks:31];
- }
- /* Theora 0-63 */
- if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
- {
- [fVidQualitySlider setMinValue:0.0];
- [fVidQualitySlider setMaxValue:63.0];
- [fVidQualitySlider setNumberOfTickMarks:64];
+ /*
+ * As x264 allows for qp/rf values that are fractional,
+ * we get the value from the preferences
+ */
+ granularity = [[NSUserDefaults standardUserDefaults]
+ floatForKey:@"x264CqSliderFractional"];
}
- [fVidQualityRFLabel setStringValue:qpRFLabelString];
+ [fVidQualitySlider setMinValue:minValue];
+ [fVidQualitySlider setMaxValue:maxValue];
+ [fVidQualitySlider setNumberOfTickMarks:((maxValue - minValue) *
+ (1. / granularity)) + 1];
/* check to see if we have changed slider scales */
- if (previousMaxValue != [fVidQualitySlider maxValue])
+ if (previousMaxValue != maxValue)
{
- /* if so, convert the old setting to the new scale as close as possible based on percentages */
- float rf = ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue] + 1) * previousPercentOfSliderScale;
- [fVidQualitySlider setFloatValue:rf];
+ /*
+ * if so, convert the old setting to the new scale as close as possible
+ * based on percentages
+ */
+ [fVidQualitySlider setFloatValue:((maxValue - minValue + 1.) *
+ (previousPercentOfSliderScale))];
}
[self qualitySliderChanged:nil];
- (IBAction) qualitySliderChanged: (id) sender
{
-
- /* Our constant quality slider is in a range based
+ /*
+ * Our constant quality slider is in a range based
* on each encoders qp/rf values. The range depends
* on the encoder. Also, the range is inverse of quality
* for all of the encoders *except* for theora
* so, the floatValue at the right for x264 would be 51
* and our rf field needs to show 0 and vice versa.
*/
-
- float sliderRfInverse = ([fVidQualitySlider maxValue] - [fVidQualitySlider floatValue]) + [fVidQualitySlider minValue];
- /* If the encoder is theora, use the float, otherwise use the inverse float*/
- //float sliderRfToPercent;
- if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
- {
- [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", [fVidQualitySlider floatValue]]];
+ int direction;
+ float minValue, maxValue, granularity;
+ float inverseValue = ([fVidQualitySlider minValue] +
+ [fVidQualitySlider maxValue] -
+ [fVidQualitySlider floatValue]);
+ hb_video_quality_get_limits([[fVidEncoderPopUp selectedItem] tag],
+ &minValue, &maxValue, &granularity, &direction);
+ if (!direction)
+ {
+ [fVidQualityRFField setStringValue:[NSString stringWithFormat:@"%.2f",
+ [fVidQualitySlider floatValue]]];
}
else
{
- [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", sliderRfInverse]];
+ [fVidQualityRFField setStringValue:[NSString stringWithFormat:@"%.2f",
+ inverseValue]];
}
/* Show a warning if x264 and rf 0 which is lossless */
- if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_X264 && sliderRfInverse == 0.0)
+ if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_X264 && inverseValue == 0.0)
{
- [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f (Warning: Lossless)", sliderRfInverse]];
+ [fVidQualityRFField setStringValue:[NSString stringWithFormat:@"%.2f (Warning: Lossless)",
+ inverseValue]];
}
[self customSettingUsed: sender];
[fVidBitrateField setStringValue:[chosenPreset objectForKey:@"VideoAvgBitrate"]];
- if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
+ int direction;
+ float minValue, maxValue, granularity;
+ hb_video_quality_get_limits([[fVidEncoderPopUp selectedItem] tag],
+ &minValue, &maxValue, &granularity, &direction);
+ if (!direction)
{
- /* Since theora's qp value goes up from left to right, we can just set the slider float value */
[fVidQualitySlider setFloatValue:[[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
}
else
{
- /* Since ffmpeg and x264 use an "inverted" slider (lower qp/rf values indicate a higher quality) we invert the value on the slider */
- [fVidQualitySlider setFloatValue:([fVidQualitySlider maxValue] + [fVidQualitySlider minValue]) - [[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
+ /*
+ * Since ffmpeg and x264 use an "inverted" slider (lower values
+ * indicate a higher quality) we invert the value on the slider
+ */
+ [fVidQualitySlider setFloatValue:([fVidQualitySlider minValue] +
+ [fVidQualitySlider maxValue] -
+ [[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue])];
}
[self videoMatrixChanged:nil];
<?xml version="1.0" encoding="UTF-8"?>
-<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
- <int key="IBDocument.SystemTarget">1050</int>
- <string key="IBDocument.SystemVersion">10F569</string>
- <string key="IBDocument.InterfaceBuilderVersion">788</string>
- <string key="IBDocument.AppKitVersion">1038.29</string>
- <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <int key="IBDocument.SystemTarget">1060</int>
+ <string key="IBDocument.SystemVersion">12F30</string>
+ <string key="IBDocument.InterfaceBuilderVersion">3084</string>
+ <string key="IBDocument.AppKitVersion">1187.39</string>
+ <string key="IBDocument.HIToolboxVersion">626.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string key="NS.object.0">788</string>
+ <string key="NS.object.0">3084</string>
</object>
- <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="2577"/>
- <integer value="2649"/>
- </object>
- <object class="NSArray" key="IBDocument.PluginDependencies">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>NSButton</string>
+ <string>NSButtonCell</string>
+ <string>NSCustomObject</string>
+ <string>NSCustomView</string>
+ <string>NSImageCell</string>
+ <string>NSMenu</string>
+ <string>NSMenuItem</string>
+ <string>NSOutlineView</string>
+ <string>NSScrollView</string>
+ <string>NSScroller</string>
+ <string>NSSlider</string>
+ <string>NSSliderCell</string>
+ <string>NSTableColumn</string>
+ <string>NSTextField</string>
+ <string>NSTextFieldCell</string>
+ <string>NSView</string>
+ <string>NSWindowTemplate</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- </object>
+ </array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys" id="0">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
</object>
- <object class="NSMutableArray" key="IBDocument.RootObjects" id="543585533">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="543585533">
<object class="NSCustomObject" id="678333032">
<string key="NSClassName">HBQueueController</string>
</object>
<object class="NSWindowTemplate" id="238545558">
<int key="NSWindowStyleMask">4111</int>
<int key="NSWindowBacking">2</int>
- <string key="NSWindowRect">{{893, 128}, {587, 432}}</string>
+ <string key="NSWindowRect">{{893, 128}, {574, 423}}</string>
<int key="NSWTFlags">1886912512</int>
<string key="NSWindowTitle">Queue - HandBrake</string>
<string key="NSWindowClass">NSWindow</string>
<object class="NSMutableString" key="NSViewClass">
<characters key="NS.bytes">View</characters>
</object>
- <string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
+ <nil key="NSUserInterfaceItemIdentifier"/>
<string key="NSWindowContentMinSize">{525, 340}</string>
<object class="NSView" key="NSWindowView" id="431299686">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
- <object class="NSMutableArray" key="NSSubviews">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="NSSubviews">
<object class="NSCustomView" id="60629844">
<reference key="NSNextResponder" ref="431299686"/>
<int key="NSvFlags">274</int>
- <object class="NSMutableArray" key="NSSubviews">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="NSSubviews">
<object class="NSScrollView" id="9160137">
<reference key="NSNextResponder" ref="60629844"/>
<int key="NSvFlags">274</int>
- <object class="NSMutableArray" key="NSSubviews">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="NSSubviews">
<object class="NSClipView" id="13598910">
<reference key="NSNextResponder" ref="9160137"/>
<int key="NSvFlags">2304</int>
- <object class="NSMutableArray" key="NSSubviews">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="NSSubviews">
<object class="NSOutlineView" id="790027174">
<reference key="NSNextResponder" ref="13598910"/>
<int key="NSvFlags">4352</int>
- <string key="NSFrameSize">{517, 329}</string>
+ <string key="NSFrameSize">{532, 336}</string>
<reference key="NSSuperview" ref="13598910"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ <bool key="NSControlAllowsExpansionToolTips">YES</bool>
<object class="_NSCornerView" key="NSCornerView">
<nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<string key="NSFrame">{{518, 0}, {16, 17}}</string>
</object>
- <object class="NSMutableArray" key="NSTableColumns">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="NSTableColumns">
<object class="NSTableColumn" id="821940358">
<string key="NSIdentifier">icon</string>
<double key="NSWidth">38</double>
<double key="NSMinWidth">38</double>
<double key="NSMaxWidth">38</double>
<object class="NSTableHeaderCell" key="NSHeaderCell">
- <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags">75497536</int>
<int key="NSCellFlags2">2048</int>
<string key="NSContents"/>
<object class="NSFont" key="NSSupport" id="26">
</object>
</object>
<object class="NSImageCell" key="NSDataCell" id="592677893">
- <int key="NSCellFlags">130560</int>
+ <int key="NSCellFlags">134217728</int>
<int key="NSCellFlags2">33554432</int>
<int key="NSAlign">3</int>
<int key="NSScale">0</int>
</object>
<object class="NSTableColumn" id="664777621">
<string key="NSIdentifier">desc</string>
- <double key="NSWidth">450</double>
+ <double key="NSWidth">465</double>
<double key="NSMinWidth">40</double>
<double key="NSMaxWidth">5000</double>
<object class="NSTableHeaderCell" key="NSHeaderCell">
- <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags">75497536</int>
<int key="NSCellFlags2">2048</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="26"/>
<reference key="NSTextColor" ref="204129071"/>
</object>
<object class="NSTextFieldCell" key="NSDataCell" id="574589932">
- <int key="NSCellFlags">337772032</int>
+ <int key="NSCellFlags">337641472</int>
<int key="NSCellFlags2">0</int>
<object class="NSFont" key="NSSupport" id="844481358">
<string key="NSName">LucidaGrande</string>
<double key="NSMinWidth">8</double>
<double key="NSMaxWidth">20</double>
<object class="NSTableHeaderCell" key="NSHeaderCell">
- <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags">75497536</int>
<int key="NSCellFlags2">134219776</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="26"/>
<reference key="NSTextColor" ref="204129071"/>
</object>
<object class="NSButtonCell" key="NSDataCell" id="620017021">
- <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="844481358"/>
<reference key="NSControlView" ref="790027174"/>
- <int key="NSButtonFlags">135020799</int>
+ <int key="NSButtonFlags">135020544</int>
<int key="NSButtonFlags2">6</int>
<object class="NSCustomResource" key="NSNormalImage">
<string key="NSClassName">NSImage</string>
</object>
<reference key="NSTableView" ref="790027174"/>
</object>
- </object>
+ </array>
<double key="NSIntercellSpacingWidth">3</double>
<double key="NSIntercellSpacingHeight">2</double>
<reference key="NSBackgroundColor" ref="983556133"/>
<int key="NSDraggingSourceMaskForNonLocal">0</int>
<bool key="NSAllowsTypeSelect">YES</bool>
<int key="NSTableViewDraggingDestinationStyle">0</int>
+ <int key="NSTableViewGroupRowStyle">1</int>
</object>
- </object>
- <string key="NSFrame">{{1, 1}, {517, 329}}</string>
+ </array>
+ <string key="NSFrame">{{1, 1}, {532, 336}}</string>
<reference key="NSSuperview" ref="9160137"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="790027174"/>
<reference key="NSDocView" ref="790027174"/>
<object class="NSColor" key="NSBGColor">
<object class="NSScroller" id="459639248">
<reference key="NSNextResponder" ref="9160137"/>
<int key="NSvFlags">256</int>
- <string key="NSFrame">{{518, 1}, {15, 329}}</string>
+ <string key="NSFrame">{{517, 1}, {16, 336}}</string>
<reference key="NSSuperview" ref="9160137"/>
+ <reference key="NSWindow"/>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<reference key="NSTarget" ref="9160137"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">0.71428570000000002</double>
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{-100, -100}, {282, 15}}</string>
<reference key="NSSuperview" ref="9160137"/>
+ <reference key="NSWindow"/>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSsFlags">1</int>
<reference key="NSTarget" ref="9160137"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">0.9656652</double>
</object>
- </object>
- <string key="NSFrame">{{20, 20}, {534, 331}}</string>
+ </array>
+ <string key="NSFrame">{{20, 20}, {534, 338}}</string>
<reference key="NSSuperview" ref="60629844"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="13598910"/>
- <int key="NSsFlags">18</int>
+ <int key="NSsFlags">133138</int>
<reference key="NSVScroller" ref="459639248"/>
<reference key="NSHScroller" ref="636348341"/>
<reference key="NSContentView" ref="13598910"/>
<bytes key="NSScrollAmts">AAAAAAAAAABBmAAAQZgAAA</bytes>
+ <double key="NSMinMagnification">0.25</double>
+ <double key="NSMaxMagnification">4</double>
+ <double key="NSMagnification">1</double>
</object>
<object class="NSSlider" id="948250828">
<reference key="NSNextResponder" ref="60629844"/>
<int key="NSvFlags">-2147483356</int>
<string key="NSFrame">{{60, 1}, {180, 16}}</string>
<reference key="NSSuperview" ref="60629844"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSSliderCell" key="NSCell" id="1016294819">
- <int key="NSCellFlags">67501824</int>
+ <int key="NSCellFlags">67371264</int>
<int key="NSCellFlags2">262144</int>
<object class="NSMutableString" key="NSContents">
<characters key="NS.bytes"/>
<bool key="NSAllowsTickMarkValuesOnly">YES</bool>
<bool key="NSVertical">NO</bool>
</object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSSlider" id="252090132">
<reference key="NSNextResponder" ref="60629844"/>
<int key="NSvFlags">-2147483356</int>
<string key="NSFrame">{{296, 2}, {80, 16}}</string>
<reference key="NSSuperview" ref="60629844"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSSliderCell" key="NSCell" id="271127179">
- <int key="NSCellFlags">67501824</int>
+ <int key="NSCellFlags">67371264</int>
<int key="NSCellFlags2">262144</int>
<object class="NSMutableString" key="NSContents">
<characters key="NS.bytes"/>
<bool key="NSAllowsTickMarkValuesOnly">YES</bool>
<bool key="NSVertical">NO</bool>
</object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSTextField" id="316422061">
<reference key="NSNextResponder" ref="60629844"/>
<int key="NSvFlags">-2147483356</int>
<string key="NSFrame">{{17, 0}, {38, 14}}</string>
<reference key="NSSuperview" ref="60629844"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="655488883">
- <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">272629760</int>
<string key="NSContents">Indent</string>
<reference key="NSSupport" ref="26"/>
</object>
<reference key="NSTextColor" ref="434514744"/>
</object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSTextField" id="891125080">
<reference key="NSNextResponder" ref="60629844"/>
<int key="NSvFlags">-2147483356</int>
<string key="NSFrame">{{245, 1}, {46, 14}}</string>
<reference key="NSSuperview" ref="60629844"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="402192242">
- <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">272629760</int>
<string key="NSContents">Spacing</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSBackgroundColor" ref="987568653"/>
<reference key="NSTextColor" ref="434514744"/>
</object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSButton" id="1065139278">
<reference key="NSNextResponder" ref="60629844"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{6, -25}, {159, 16}}</string>
<reference key="NSSuperview" ref="60629844"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="907474520">
- <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">134479872</int>
<string key="NSContents">quick way to intercept delete key</string>
<object class="NSFont" key="NSSupport">
<int key="NSfFlags">3614</int>
</object>
<reference key="NSControlView" ref="1065139278"/>
- <int key="NSButtonFlags">-2038021889</int>
+ <int key="NSButtonFlags">-2038022144</int>
<int key="NSButtonFlags2">34</int>
<object class="NSFont" key="NSAlternateImage">
<string key="NSName">LucidaGrande</string>
<int key="NSPeriodicDelay">200</int>
<int key="NSPeriodicInterval">25</int>
</object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
- </object>
- <string key="NSFrame">{{0, 9}, {574, 358}}</string>
+ </array>
+ <string key="NSFrameSize">{574, 358}</string>
<reference key="NSSuperview" ref="431299686"/>
+ <reference key="NSWindow"/>
<string key="NSClassName">NSView</string>
<string key="NSExtension">NSResponder</string>
</object>
<object class="NSTextField" id="463845363">
<reference key="NSNextResponder" ref="431299686"/>
<int key="NSvFlags">264</int>
- <string key="NSFrame">{{17, 407}, {148, 14}}</string>
+ <string key="NSFrame">{{17, 399}, {540, 14}}</string>
<reference key="NSSuperview" ref="431299686"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="617812287">
- <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">272760832</int>
<string key="NSContents">Pending Jobs</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSBackgroundColor" ref="987568653"/>
<reference key="NSTextColor" ref="434514744"/>
</object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
<object class="NSTextField" id="138063786">
<reference key="NSNextResponder" ref="431299686"/>
<int key="NSvFlags">266</int>
- <string key="NSFrame">{{17, 373}, {560, 30}}</string>
+ <string key="NSFrame">{{17, 366}, {540, 29}}</string>
<reference key="NSSuperview" ref="431299686"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="108133680">
- <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">4325376</int>
<string key="NSContents">There are no jobs currently encoding</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSBackgroundColor" ref="987568653"/>
<reference key="NSTextColor" ref="434514744"/>
</object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
- </object>
- <string key="NSFrameSize">{587, 432}</string>
+ </array>
+ <string key="NSFrameSize">{574, 423}</string>
<reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
</object>
- <string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
+ <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
<string key="NSMinSize">{525, 362}</string>
- <string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
+ <string key="NSMaxSize">{10000000000000, 10000000000000}</string>
<string key="NSFrameAutosaveName">QueueWindow</string>
+ <bool key="NSWindowIsRestorable">YES</bool>
</object>
<object class="NSMenu" id="771940260">
<string key="NSTitle"/>
- <object class="NSMutableArray" key="NSMenuItems">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="16179858">
<reference key="NSMenu" ref="771940260"/>
<string key="NSTitle">Edit</string>
<reference key="NSOnImage" ref="7190541"/>
<reference key="NSMixedImage" ref="681624584"/>
</object>
- </object>
+ </array>
</object>
- </object>
+ </array>
<object class="IBObjectContainer" key="IBDocument.Objects">
- <object class="NSMutableArray" key="connectionRecords">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">fQueuePane</string>
</object>
<int key="connectionID">2564</int>
</object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
- <string key="label">delegate</string>
- <reference key="source" ref="238545558"/>
- <reference key="destination" ref="678333032"/>
- </object>
- <int key="connectionID">2579</int>
- </object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">fOutlineView</string>
</object>
<int key="connectionID">2601</int>
</object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
- <string key="label">dataSource</string>
- <reference key="source" ref="790027174"/>
- <reference key="destination" ref="678333032"/>
- </object>
- <int key="connectionID">2602</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
- <string key="label">delegate</string>
- <reference key="source" ref="790027174"/>
- <reference key="destination" ref="678333032"/>
- </object>
- <int key="connectionID">2603</int>
- </object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">removeSelectedQueueItem:</string>
</object>
<int key="connectionID">2648</int>
</object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
- <string key="label">menu</string>
- <reference key="source" ref="574589932"/>
- <reference key="destination" ref="771940260"/>
- </object>
- <int key="connectionID">2653</int>
- </object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">editSelectedQueueItem:</string>
</object>
<int key="connectionID">2657</int>
</object>
- </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="238545558"/>
+ <reference key="destination" ref="678333032"/>
+ </object>
+ <int key="connectionID">2579</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="790027174"/>
+ <reference key="destination" ref="678333032"/>
+ </object>
+ <int key="connectionID">2602</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="790027174"/>
+ <reference key="destination" ref="678333032"/>
+ </object>
+ <int key="connectionID">2603</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">menu</string>
+ <reference key="source" ref="574589932"/>
+ <reference key="destination" ref="771940260"/>
+ </object>
+ <int key="connectionID">2653</int>
+ </object>
+ </array>
<object class="IBMutableOrderedSet" key="objectRecords">
- <object class="NSArray" key="orderedObjects">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
- <reference key="object" ref="0"/>
+ <array key="object" id="0"/>
<reference key="children" ref="543585533"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2576</int>
<reference key="object" ref="238545558"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="431299686"/>
- </object>
+ </array>
<reference key="parent" ref="0"/>
<string key="objectName">Window</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">2577</int>
<reference key="object" ref="431299686"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="60629844"/>
<reference ref="138063786"/>
<reference ref="463845363"/>
- </object>
+ </array>
<reference key="parent" ref="238545558"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2547</int>
<reference key="object" ref="60629844"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="9160137"/>
<reference ref="948250828"/>
<reference ref="252090132"/>
<reference ref="316422061"/>
<reference ref="891125080"/>
<reference ref="1065139278"/>
- </object>
+ </array>
<reference key="parent" ref="431299686"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2596</int>
<reference key="object" ref="9160137"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="790027174"/>
<reference ref="459639248"/>
<reference ref="636348341"/>
- </object>
+ </array>
<reference key="parent" ref="60629844"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2597</int>
<reference key="object" ref="790027174"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="664777621"/>
<reference ref="498008730"/>
<reference ref="821940358"/>
- </object>
+ </array>
<reference key="parent" ref="9160137"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2599</int>
<reference key="object" ref="664777621"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="574589932"/>
- </object>
+ </array>
<reference key="parent" ref="790027174"/>
</object>
<object class="IBObjectRecord">
<object class="IBObjectRecord">
<int key="objectID">2604</int>
<reference key="object" ref="498008730"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="620017021"/>
- </object>
+ </array>
<reference key="parent" ref="790027174"/>
</object>
<object class="IBObjectRecord">
<object class="IBObjectRecord">
<int key="objectID">2624</int>
<reference key="object" ref="821940358"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="592677893"/>
- </object>
+ </array>
<reference key="parent" ref="790027174"/>
</object>
<object class="IBObjectRecord">
<object class="IBObjectRecord">
<int key="objectID">2610</int>
<reference key="object" ref="948250828"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="1016294819"/>
- </object>
+ </array>
<reference key="parent" ref="60629844"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2611</int>
<reference key="object" ref="252090132"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="271127179"/>
- </object>
+ </array>
<reference key="parent" ref="60629844"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2614</int>
<reference key="object" ref="316422061"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="655488883"/>
- </object>
+ </array>
<reference key="parent" ref="60629844"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2615</int>
<reference key="object" ref="891125080"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="402192242"/>
- </object>
+ </array>
<reference key="parent" ref="60629844"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2622</int>
<reference key="object" ref="1065139278"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="907474520"/>
- </object>
+ </array>
<reference key="parent" ref="60629844"/>
</object>
<object class="IBObjectRecord">
<object class="IBObjectRecord">
<int key="objectID">2511</int>
<reference key="object" ref="463845363"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="617812287"/>
- </object>
+ </array>
<reference key="parent" ref="431299686"/>
</object>
<object class="IBObjectRecord">
<object class="IBObjectRecord">
<int key="objectID">2646</int>
<reference key="object" ref="138063786"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="108133680"/>
- </object>
+ </array>
<reference key="parent" ref="431299686"/>
</object>
<object class="IBObjectRecord">
<object class="IBObjectRecord">
<int key="objectID">2649</int>
<reference key="object" ref="771940260"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="children">
<reference ref="16179858"/>
<reference ref="60102320"/>
<reference ref="172286461"/>
- </object>
+ </array>
<reference key="parent" ref="0"/>
<string key="objectName">ContextMenu</string>
</object>
<reference key="object" ref="172286461"/>
<reference key="parent" ref="771940260"/>
</object>
- </object>
- </object>
- <object class="NSMutableDictionary" key="flattenedProperties">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>-3.IBPluginDependency</string>
- <string>2511.IBPluginDependency</string>
- <string>2511.ImportedFromIB2</string>
- <string>2547.IBPluginDependency</string>
- <string>2547.ImportedFromIB2</string>
- <string>2576.IBEditorWindowLastContentRect</string>
- <string>2576.IBPluginDependency</string>
- <string>2576.IBWindowTemplateEditedContentRect</string>
- <string>2576.ImportedFromIB2</string>
- <string>2576.windowTemplate.hasMaxSize</string>
- <string>2576.windowTemplate.hasMinSize</string>
- <string>2576.windowTemplate.maxSize</string>
- <string>2576.windowTemplate.minSize</string>
- <string>2577.IBPluginDependency</string>
- <string>2577.ImportedFromIB2</string>
- <string>2596.IBPluginDependency</string>
- <string>2596.ImportedFromIB2</string>
- <string>2597.CustomClassName</string>
- <string>2597.IBPluginDependency</string>
- <string>2597.ImportedFromIB2</string>
- <string>2599.IBPluginDependency</string>
- <string>2599.ImportedFromIB2</string>
- <string>2604.IBPluginDependency</string>
- <string>2604.ImportedFromIB2</string>
- <string>2605.IBPluginDependency</string>
- <string>2605.ImportedFromIB2</string>
- <string>2609.CustomClassName</string>
- <string>2609.IBPluginDependency</string>
- <string>2609.ImportedFromIB2</string>
- <string>2610.IBPluginDependency</string>
- <string>2610.ImportedFromIB2</string>
- <string>2611.IBPluginDependency</string>
- <string>2611.ImportedFromIB2</string>
- <string>2614.IBPluginDependency</string>
- <string>2614.ImportedFromIB2</string>
- <string>2615.IBPluginDependency</string>
- <string>2615.ImportedFromIB2</string>
- <string>2622.IBPluginDependency</string>
- <string>2622.ImportedFromIB2</string>
- <string>2624.IBPluginDependency</string>
- <string>2624.ImportedFromIB2</string>
- <string>2625.IBPluginDependency</string>
- <string>2625.ImportedFromIB2</string>
- <string>2637.IBPluginDependency</string>
- <string>2638.IBPluginDependency</string>
- <string>2639.IBPluginDependency</string>
- <string>2640.IBPluginDependency</string>
- <string>2641.IBPluginDependency</string>
- <string>2642.IBPluginDependency</string>
- <string>2643.IBPluginDependency</string>
- <string>2643.IBShouldRemoveOnLegacySave</string>
- <string>2644.IBPluginDependency</string>
- <string>2644.IBShouldRemoveOnLegacySave</string>
- <string>2646.IBPluginDependency</string>
- <string>2646.ImportedFromIB2</string>
- <string>2647.IBPluginDependency</string>
- <string>2649.IBEditorWindowLastContentRect</string>
- <string>2649.IBPluginDependency</string>
- <string>2650.IBPluginDependency</string>
- <string>2652.IBPluginDependency</string>
- <string>2655.IBPluginDependency</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>{{77, 333}, {587, 432}}</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{77, 333}, {587, 432}}</string>
- <integer value="1"/>
- <boolean value="NO"/>
- <integer value="1"/>
- <string>{3.40282e+38, 3.40282e+38}</string>
- <string>{525, 340}</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>HBQueueOutlineView</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>HBImageAndTextCell</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <integer value="1"/>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{555, 544}, {96, 63}}</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="unlocalizedProperties">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference key="dict.sortedKeys" ref="0"/>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
+ </array>
</object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2511.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2547.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2576.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2576.IBWindowTemplateEditedContentRect">{{77, 333}, {587, 432}}</string>
+ <string key="2577.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2596.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2597.CustomClassName">HBQueueOutlineView</string>
+ <string key="2597.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2599.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2604.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2605.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2609.CustomClassName">HBImageAndTextCell</string>
+ <string key="2609.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2610.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2611.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2614.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2615.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2622.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2624.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2625.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2637.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2638.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2639.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2640.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2641.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2642.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2643.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <integer value="1" key="2643.IBShouldRemoveOnLegacySave"/>
+ <string key="2644.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <integer value="1" key="2644.IBShouldRemoveOnLegacySave"/>
+ <string key="2646.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2647.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2649.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2650.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2652.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2655.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
- <object class="NSMutableDictionary" key="localizations">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference key="dict.sortedKeys" ref="0"/>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
- </object>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">2657</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
- <object class="NSMutableArray" key="referencedPartialClassDescriptions">
- <bool key="EncodedWithXMLCoder">YES</bool>
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">HBImageAndTextCell</string>
<string key="superclassName">NSTextFieldCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
- <string key="minorKey">HBImageAndTextCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">HBImageAndTextCell</string>
- <string key="superclassName">NSTextFieldCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBUserSource</string>
- <string key="minorKey"/>
+ <string key="minorKey">./Classes/HBImageAndTextCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">HBQueueController</string>
<string key="superclassName">NSWindowController</string>
- <object class="NSMutableDictionary" key="actions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>editSelectedQueueItem:</string>
- <string>imageSpacingChanged:</string>
- <string>indentChanged:</string>
- <string>removeSelectedQueueItem:</string>
- <string>revealSelectedQueueItem:</string>
- <string>showQueueWindow:</string>
+ <dictionary class="NSMutableDictionary" key="actions">
+ <string key="editSelectedQueueItem:">id</string>
+ <string key="imageSpacingChanged:">id</string>
+ <string key="indentChanged:">id</string>
+ <string key="removeSelectedQueueItem:">id</string>
+ <string key="revealSelectedQueueItem:">id</string>
+ <string key="showQueueWindow:">id</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="actionInfosByName">
+ <object class="IBActionInfo" key="editSelectedQueueItem:">
+ <string key="name">editSelectedQueueItem:</string>
+ <string key="candidateClassName">id</string>
</object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
+ <object class="IBActionInfo" key="imageSpacingChanged:">
+ <string key="name">imageSpacingChanged:</string>
+ <string key="candidateClassName">id</string>
</object>
- </object>
- <object class="NSMutableDictionary" key="actionInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>editSelectedQueueItem:</string>
- <string>imageSpacingChanged:</string>
- <string>indentChanged:</string>
- <string>removeSelectedQueueItem:</string>
- <string>revealSelectedQueueItem:</string>
- <string>showQueueWindow:</string>
+ <object class="IBActionInfo" key="indentChanged:">
+ <string key="name">indentChanged:</string>
+ <string key="candidateClassName">id</string>
</object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBActionInfo">
- <string key="name">editSelectedQueueItem:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">imageSpacingChanged:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">indentChanged:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">removeSelectedQueueItem:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">revealSelectedQueueItem:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">showQueueWindow:</string>
- <string key="candidateClassName">id</string>
- </object>
+ <object class="IBActionInfo" key="removeSelectedQueueItem:">
+ <string key="name">removeSelectedQueueItem:</string>
+ <string key="candidateClassName">id</string>
</object>
- </object>
- <object class="NSMutableDictionary" key="outlets">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>fCurrentJobPane</string>
- <string>fIndentation</string>
- <string>fJobDescTextField</string>
- <string>fJobIconView</string>
- <string>fOutlineView</string>
- <string>fProgressBar</string>
- <string>fProgressTextField</string>
- <string>fQueueCountField</string>
- <string>fQueuePane</string>
- <string>fSpacing</string>
+ <object class="IBActionInfo" key="revealSelectedQueueItem:">
+ <string key="name">revealSelectedQueueItem:</string>
+ <string key="candidateClassName">id</string>
</object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>NSView</string>
- <string>NSSlider</string>
- <string>NSTextField</string>
- <string>NSImageView</string>
- <string>HBQueueOutlineView</string>
- <string>NSProgressIndicator</string>
- <string>NSTextField</string>
- <string>NSTextField</string>
- <string>NSView</string>
- <string>NSSlider</string>
+ <object class="IBActionInfo" key="showQueueWindow:">
+ <string key="name">showQueueWindow:</string>
+ <string key="candidateClassName">id</string>
</object>
- </object>
- <object class="NSMutableDictionary" key="toOneOutletInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>fCurrentJobPane</string>
- <string>fIndentation</string>
- <string>fJobDescTextField</string>
- <string>fJobIconView</string>
- <string>fOutlineView</string>
- <string>fProgressBar</string>
- <string>fProgressTextField</string>
- <string>fQueueCountField</string>
- <string>fQueuePane</string>
- <string>fSpacing</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="fCurrentJobPane">NSView</string>
+ <string key="fIndentation">NSSlider</string>
+ <string key="fJobDescTextField">NSTextField</string>
+ <string key="fJobIconView">NSImageView</string>
+ <string key="fOutlineView">HBQueueOutlineView</string>
+ <string key="fProgressBar">NSProgressIndicator</string>
+ <string key="fProgressTextField">NSTextField</string>
+ <string key="fQueueCountField">NSTextField</string>
+ <string key="fQueuePane">NSView</string>
+ <string key="fSpacing">NSSlider</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="fCurrentJobPane">
+ <string key="name">fCurrentJobPane</string>
+ <string key="candidateClassName">NSView</string>
</object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBToOneOutletInfo">
- <string key="name">fCurrentJobPane</string>
- <string key="candidateClassName">NSView</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fIndentation</string>
- <string key="candidateClassName">NSSlider</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fJobDescTextField</string>
- <string key="candidateClassName">NSTextField</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fJobIconView</string>
- <string key="candidateClassName">NSImageView</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fOutlineView</string>
- <string key="candidateClassName">HBQueueOutlineView</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fProgressBar</string>
- <string key="candidateClassName">NSProgressIndicator</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fProgressTextField</string>
- <string key="candidateClassName">NSTextField</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fQueueCountField</string>
- <string key="candidateClassName">NSTextField</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fQueuePane</string>
- <string key="candidateClassName">NSView</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">fSpacing</string>
- <string key="candidateClassName">NSSlider</string>
- </object>
+ <object class="IBToOneOutletInfo" key="fIndentation">
+ <string key="name">fIndentation</string>
+ <string key="candidateClassName">NSSlider</string>
</object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="333889241">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">HBQueueController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">HBQueueController</string>
- <string key="superclassName">NSWindowController</string>
- <object class="NSMutableDictionary" key="actions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>cancelCurrentJob:</string>
- <string>revealSelectedJobGroups:</string>
- <string>togglePauseResume:</string>
- <string>toggleStartCancel:</string>
+ <object class="IBToOneOutletInfo" key="fJobDescTextField">
+ <string key="name">fJobDescTextField</string>
+ <string key="candidateClassName">NSTextField</string>
</object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- <string>id</string>
+ <object class="IBToOneOutletInfo" key="fJobIconView">
+ <string key="name">fJobIconView</string>
+ <string key="candidateClassName">NSImageView</string>
</object>
- </object>
- <object class="NSMutableDictionary" key="actionInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>cancelCurrentJob:</string>
- <string>revealSelectedJobGroups:</string>
- <string>togglePauseResume:</string>
- <string>toggleStartCancel:</string>
+ <object class="IBToOneOutletInfo" key="fOutlineView">
+ <string key="name">fOutlineView</string>
+ <string key="candidateClassName">HBQueueOutlineView</string>
</object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBActionInfo">
- <string key="name">cancelCurrentJob:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">revealSelectedJobGroups:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">togglePauseResume:</string>
- <string key="candidateClassName">id</string>
- </object>
- <object class="IBActionInfo">
- <string key="name">toggleStartCancel:</string>
- <string key="candidateClassName">id</string>
- </object>
+ <object class="IBToOneOutletInfo" key="fProgressBar">
+ <string key="name">fProgressBar</string>
+ <string key="candidateClassName">NSProgressIndicator</string>
</object>
- </object>
+ <object class="IBToOneOutletInfo" key="fProgressTextField">
+ <string key="name">fProgressTextField</string>
+ <string key="candidateClassName">NSTextField</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="fQueueCountField">
+ <string key="name">fQueueCountField</string>
+ <string key="candidateClassName">NSTextField</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="fQueuePane">
+ <string key="name">fQueuePane</string>
+ <string key="candidateClassName">NSView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="fSpacing">
+ <string key="name">fSpacing</string>
+ <string key="candidateClassName">NSSlider</string>
+ </object>
+ </dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBUserSource</string>
- <string key="minorKey"/>
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/HBQueueController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">HBQueueOutlineView</string>
<string key="superclassName">NSOutlineView</string>
- <reference key="sourceIdentifier" ref="333889241"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">HBQueueOutlineView</string>
- <string key="superclassName">NSOutlineView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBUserSource</string>
- <string key="minorKey"/>
- </object>
- </object>
- </object>
- <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBPartialClassDescription">
- <string key="className">NSActionCell</string>
- <string key="superclassName">NSCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSActionCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <string key="superclassName">NSResponder</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="1009815657">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSApplication.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="942825343">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSApplicationScripting.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="874636585">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSColorPanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSHelpManager.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSPageLayout.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSApplication</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSUserInterfaceItemSearching.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSButton</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSButton.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSButtonCell</string>
- <string key="superclassName">NSActionCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSButtonCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSCell</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSControl</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="596505546">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSControl.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSFormatter</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSFormatter.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSImageCell</string>
- <string key="superclassName">NSCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSImageCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSImageView</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSImageView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSMenu</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="721965304">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSMenu.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSMenuItem</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="529283491">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSMenuItem.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSAccessibility.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="1009815657"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="942825343"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="874636585"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="596505546"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSDictionaryController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSDragging.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSFontManager.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSFontPanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSKeyValueBinding.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <reference key="sourceIdentifier" ref="721965304"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSNibLoading.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="440847546">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSOutlineView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSPasteboard.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSSavePanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="415747133">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTableView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSToolbarItem.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier" id="165950663">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSArchiver.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSClassDescription.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSObjectScripting.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSPortCoder.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSScriptClassDescription.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSScriptKeyValueCoding.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSScriptObjectSpecifiers.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSScriptWhoseTests.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Growl.framework/Headers/GrowlApplicationBridge.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">ImageKit.framework/Headers/IKImageBrowserView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">ImageKit.framework/Headers/IKSaveOptions.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">ImageKit.framework/Headers/ImageKitDeprecated.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">PDFKit.framework/Headers/PDFDocument.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">PDFKit.framework/Headers/PDFView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureDecompressedAudioOutput.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureDecompressedVideoOutput.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureFileOutput.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureVideoPreviewOutput.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTCaptureView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTMovie.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QTKit.framework/Headers/QTMovieView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzComposer.framework/Headers/QCCompositionParameterView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzComposer.framework/Headers/QCCompositionPickerView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuartzFilters.framework/Headers/QuartzFilterManager.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">QuickLookUI.framework/Headers/QLPreviewPanel.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Sparkle.framework/Headers/SUAppcast.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">Sparkle.framework/Headers/SUUpdater.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSOutlineView</string>
- <string key="superclassName">NSTableView</string>
- <reference key="sourceIdentifier" ref="440847546"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSProgressIndicator</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSProgressIndicator.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSResponder</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSInterfaceStyle.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSResponder</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSResponder.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSScrollView</string>
- <string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSScrollView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSScroller</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSScroller.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSSlider</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSSlider.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSSliderCell</string>
- <string key="superclassName">NSActionCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSSliderCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTableColumn</string>
- <string key="superclassName">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTableColumn.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTableView</string>
- <string key="superclassName">NSControl</string>
- <reference key="sourceIdentifier" ref="415747133"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTextField</string>
- <string key="superclassName">NSControl</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTextField.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSTextFieldCell</string>
- <string key="superclassName">NSActionCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSTextFieldCell.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSClipView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSView</string>
- <reference key="sourceIdentifier" ref="529283491"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSRulerView.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSView</string>
- <string key="superclassName">NSResponder</string>
- <reference key="sourceIdentifier" ref="165950663"/>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSWindow</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSDrawer.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSWindow</string>
- <string key="superclassName">NSResponder</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSWindow.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSWindow</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">NSWindowController</string>
- <string key="superclassName">NSResponder</string>
- <object class="NSMutableDictionary" key="actions">
- <string key="NS.key.0">showWindow:</string>
- <string key="NS.object.0">id</string>
- </object>
- <object class="NSMutableDictionary" key="actionInfosByName">
- <string key="NS.key.0">showWindow:</string>
- <object class="IBActionInfo" key="NS.object.0">
- <string key="name">showWindow:</string>
- <string key="candidateClassName">id</string>
- </object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBFrameworkSource</string>
- <string key="minorKey">AppKit.framework/Headers/NSWindowController.h</string>
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/HBQueueOutlineView.h</string>
</object>
</object>
- </object>
+ </array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
- <integer value="1050" key="NS.object.0"/>
+ <real value="1060" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
- <integer value="3000" key="NS.object.0"/>
+ <real value="4200" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
- <string key="IBDocument.LastKnownRelativeProjectPath">../HandBrake.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
- <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>Delete</string>
- <string>NSMenuCheckmark</string>
- <string>NSMenuMixedState</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>{16, 16}</string>
- <string>{9, 8}</string>
- <string>{7, 2}</string>
- </object>
- </object>
+ <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <string key="Delete">{16, 16}</string>
+ <string key="NSMenuCheckmark">{11, 11}</string>
+ <string key="NSMenuMixedState">{10, 3}</string>
+ </dictionary>
</data>
</archive>
[super keyDown:event];
}
+- (void)scrollWheel:(NSEvent *)theEvent
+{
+ if (!fEncodeState)
+ {
+ if ([theEvent deltaY] < 0)
+ {
+ [fPictureSlider setIntegerValue:fPicture < [fPictureSlider maxValue] ? fPicture + 1 : fPicture];
+ [self pictureSliderChanged:self];
+ }
+ else if ([theEvent deltaY] > 0)
+ {
+ [fPictureSlider setIntegerValue:fPicture > [fPictureSlider minValue] ? fPicture - 1 : fPicture];
+ [self pictureSliderChanged:self];
+ }
+ }
+}
+
#pragma mark *** QTTime Utilities ***
// convert a time value (long) to a QTTime structure
{
if ([outlineView isItemExpanded: item])
{
- /* Below is the original code to accommodate a live resize,
- * however as stated in travistex's comments it's very buggy.
- * For now I will leave it here ... commented out and use
- * the code below to determine the row height based on each
- * encodes optional parameters and how they are displayed. */
+ // It is important to use a constant value when calculating the height. Querying the tableColumn width will not work, since it dynamically changes as the user resizes -- however, we don't get a notification that the user "did resize" it until after the mouse is let go. We use the latter as a hook for telling the table that the heights changed. We must return the same height from this method every time, until we tell the table the heights have changed. Not doing so will quicly cause drawing problems.
+ NSTableColumn *tableColumnToWrap = (NSTableColumn *) [[outlineView tableColumns] objectAtIndex:1];
+ NSInteger columnToWrap = [outlineView.tableColumns indexOfObject:tableColumnToWrap];
- // Short-circuit here if in a live resize primarily to fix a bug but also to
- // increase resposivness during a resize. There's a bug in NSTableView that
- // causes row heights to get messed up if you try to change them during a live
- // resize. So if in a live resize, simply return the previously calculated
- // height. The row heights will get fixed up after the resize because we have
- // implemented viewDidEndLiveResize to force all of them to be recalculated.
- // if ([outlineView inLiveResize] && [item lastDescriptionHeight] > 0)
- // return [item lastDescriptionHeight];
+ // Grab the fully prepared cell with our content filled in. Note that in IB the cell's Layout is set to Wraps.
+ NSCell *cell = [outlineView preparedCellAtColumn:columnToWrap row:[outlineView rowForItem:item]];
- // CGFloat width = [[outlineView tableColumnWithIdentifier: @"desc"] width];
- // Column width is NOT what is ultimately used. I can't quite figure out what
- // width to use for calculating text metrics. No matter how I tweak this value,
- // there are a few conditions in which the drawn text extends below the bounds
- // of the row cell. In previous versions, which ran under Tiger, I was
- // reducing width by 47 pixles.
- // width -= 2; // (?) for intercell spacing
-
- // CGFloat height = [item heightOfDescriptionForWidth: width];
- // return height;
-
- /* So, we know several rows of text that are in all queue items for display.
- * These are the title line, Preset, Format, Destination, Picture, and Video Lines
- */
- CGFloat rowHeightNonTitle = 15.0;
- /* Add the title line height, then the non title line height for Preset, Format, Destination
- * Picture and Video
- */
- CGFloat itemHeightForDisplay = HB_ROW_HEIGHT_TITLE_ONLY + (rowHeightNonTitle * 5);
-
- /* get our item row number so we an use it to calc how many lines we have to display based
- * on MP4 Options, Filter Options, X264 Options, Audio Tracks and Subtitles from our queue array */
- int itemRowNum = [outlineView rowForItem: item];
- NSMutableDictionary *queueItemToCheck = [outlineView itemAtRow: itemRowNum];
-
- /* Check to see if we need to allow for container options */
- if ([[queueItemToCheck objectForKey:@"MuxerOptionsSummary"] length])
- {
- itemHeightForDisplay += rowHeightNonTitle;
- }
-
- /* check to see if we need to allow for the Picture Filters row */
- if ([[queueItemToCheck objectForKey:@"PictureFiltersSummary"] length])
- {
- itemHeightForDisplay += rowHeightNonTitle;
- }
-
- /* check to see if we need a line to display x264/lavc options */
- if ([[queueItemToCheck objectForKey:@"VideoEncoder"] isEqualToString: @"H.264 (x264)"])
- {
- itemHeightForDisplay += rowHeightNonTitle * 2;
- }
- else if (![[queueItemToCheck objectForKey:@"VideoEncoder"] isEqualToString: @"VP3 (Theora)"])
- {
- itemHeightForDisplay += rowHeightNonTitle;
- }
-
- /* check to see how many audio track lines to allow for */
- unsigned int ourMaximumNumberOfAudioTracks = [HBController maximumNumberOfAllowedAudioTracks];
- int actualCountOfAudioTracks = 0;
- BOOL autoPassthruPresent = NO;
- for (unsigned int i = 1; i <= ourMaximumNumberOfAudioTracks; i++) {
- if (0 < [[queueItemToCheck objectForKey: [NSString stringWithFormat: @"Audio%dTrack", i]] intValue])
- {
- actualCountOfAudioTracks++;
- }
- if (HB_ACODEC_AUTO_PASS == [[queueItemToCheck objectForKey: [NSString stringWithFormat: @"JobAudio%dEncoder", i]] intValue])
- {
- autoPassthruPresent = YES;
- }
- }
- itemHeightForDisplay += (actualCountOfAudioTracks * rowHeightNonTitle * 2);
-
- if (autoPassthruPresent == YES)
- {
- itemHeightForDisplay += rowHeightNonTitle * 2;
- }
-
- /* add in subtitle lines for each subtitle in the SubtitleList array */
- itemHeightForDisplay += rowHeightNonTitle * [[queueItemToCheck objectForKey:@"SubtitleList"] count];
-
- return itemHeightForDisplay;
+ // See how tall it naturally would want to be if given a restricted with, but unbound height
+ NSRect constrainedBounds = NSMakeRect(0, 0, [tableColumnToWrap width], CGFLOAT_MAX);
+ NSSize naturalSize = [cell cellSizeForBounds:constrainedBounds];
+ // Make sure we have a minimum height -- use the table's set height as the minimum.
+ if (naturalSize.height > [outlineView rowHeight])
+ return naturalSize.height;
+ else
+ return [outlineView rowHeight];
}
else
{
}
}
-- (CGFloat) heightOfDescriptionForWidth:(CGFloat)width
-{
- // Try to return the cached value if no changes have happened since the last time
- //if ((width == fLastDescriptionWidth) && (fLastDescriptionHeight != 0) && !fNeedsDescription)
- // return fLastDescriptionHeight;
-
- //if (fNeedsDescription)
- // [self updateDescription];
-
- // Calculate the height
- //NSRect bounds = [fDescription boundingRectWithSize:NSMakeSize(width, 10000) options:NSStringDrawingUsesLineFragmentOrigin];
- //fLastDescriptionHeight = bounds.size.height + 6.0; // add some border to bottom
- //fLastDescriptionWidth = width;
- return HB_ROW_HEIGHT_FULL_DESCRIPTION;
-
-/* supposedly another way to do this, in case boundingRectWithSize isn't working
- NSTextView* tmpView = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, width, 1)];
- [[tmpView textStorage] setAttributedString:aString];
- [tmpView setHorizontallyResizable:NO];
- [tmpView setVerticallyResizable:YES];
-// [[tmpView textContainer] setHeightTracksTextView: YES];
-// [[tmpView textContainer] setContainerSize: NSMakeSize(width, 10000)];
- [tmpView sizeToFit];
- float height = [tmpView frame].size.height;
- [tmpView release];
- return height;
-*/
-}
-
-- (CGFloat) lastDescriptionHeight
-{
- return HB_ROW_HEIGHT_FULL_DESCRIPTION;
-}
-
- (id)outlineView:(NSOutlineView *)fOutlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
if ([[tableColumn identifier] isEqualToString:@"desc"])
It may be used under the terms of the GNU General Public License. */
#import "HBSubtitles.h"
+#include "lang.h"
#include "hb.h"
@implementation HBSubtitles
}
/* setup our array of languages */
+ const iso639_lang_t *lang;
languagesArray = [[NSMutableArray alloc] init];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Any",@"und",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Afar",@"aar",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Abkhazian",@"abk",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Afrikaans",@"afr",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Akan",@"ak",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Albanian",@"sqi",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Amharic",@"amh",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Arabic",@"ara",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Aragonese",@"arg",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Armenian",@"hye",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Assamese",@"asm",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Avaric",@"ava",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Avestan",@"ave",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Aymara",@"aym",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Azerbaijani",@"aze",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Bashkir",@"bak",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Bambara",@"bam",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Basque",@"eus",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Belarusian",@"bel",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Bengali",@"ben",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Bihari",@"bih",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Bislama",@"bis",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Bosnian",@"bos",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Breton",@"bre",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Bulgarian",@"bul",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Burmese",@"mya",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Catalan",@"cat",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Chamorro",@"cha",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Chechen",@"che",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Chinese",@"zho",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Church Slavic",@"chu",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Chuvash",@"chv",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Cornish",@"cor",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Corsican",@"cos",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Cree",@"cre",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Czech",@"ces",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Danish",@"dan",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Divehi",@"div",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Dutch",@"nld",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Dzongkha",@"dzo",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"English",@"eng",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Esperanto",@"epo",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Estonian",@"est",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ewe",@"ewe",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Faroese",@"fao",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Fijian",@"fij",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Finnish",@"fin",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"French",@"fra",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Western Frisian",@"fry",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Fulah",@"ful",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Georgian",@"kat",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"German",@"deu",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Gaelic (Scots)",@"gla",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Irish",@"gle",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Galician",@"glg",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Manx",@"glv",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Greek, Modern",@"ell",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Guarani",@"grn",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Gujarati",@"guj",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Haitian",@"hat",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Hausa",@"hau",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Hebrew",@"heb",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Herero",@"her",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Hindi",@"hin",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Hiri Motu",@"hmo",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Hungarian",@"hun",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Igbo",@"ibo",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Icelandic",@"isl",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ido",@"ido",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Sichuan Yi",@"iii",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Inuktitut",@"iku",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Interlingue",@"ile",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Interlingua",@"ina",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Indonesian",@"ind",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Inupiaq",@"ipk",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Italian",@"ita",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Javanese",@"jav",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Japanese",@"jpn",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kalaallisut (Greenlandic)",@"kal",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kannada",@"kan",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kashmiri",@"kas",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kanuri",@"kau",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kazakh",@"kaz",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Central Khmer",@"khm",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kikuyu",@"kik",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kinyarwanda",@"kin",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kirghiz",@"kir",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Komi",@"kom",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kongo",@"kon",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Korean",@"kor",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kuanyama",@"kua",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Kurdish",@"kur",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Lao",@"lao",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Latin",@"lat",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Latvian",@"lav",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Limburgan",@"lim",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Lingala",@"lin",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Lithuanian",@"lit",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Luxembourgish",@"ltz",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Luba-Katanga",@"lub",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ganda",@"lug",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Macedonian",@"mkd",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Marshallese",@"mah",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Malayalam",@"mal",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Maori",@"mri",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Marathi",@"mar",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Malay",@"msa",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Malagasy",@"mlg",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Maltese",@"mlt",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Moldavian",@"mol",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Mongolian",@"mon",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Nauru",@"nau",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Navajo",@"nav",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ndebele, South",@"nbl",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ndebele, North",@"nde",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ndonga",@"ndo",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Nepali",@"nep",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Norwegian Nynorsk",@"nno",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Norwegian Bokmål",@"nob",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Norwegian",@"nor",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Chichewa; Nyanja",@"nya",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Occitan (post 1500); Provençal",@"oci",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ojibwa",@"oji",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Oriya",@"ori",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Oromo",@"orm",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ossetian; Ossetic",@"und",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Panjabi",@"pan",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Persian",@"fas",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Pali",@"pli",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Portuguese",@"por",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Pushto",@"pus",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Quechua",@"que",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Romansh",@"roh",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Romanian",@"ron",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Rundi",@"run",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Russian",@"rus",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Sango",@"sag",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Sanskrit",@"san",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Serbian",@"srp",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Croatian",@"hrv",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Sinhala",@"sin",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Slovak",@"slk",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Slovenian",@"slv",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Northern Sami",@"sme",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Samoan",@"smo",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Shona",@"sna",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Sindhi",@"snd",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Somali",@"som",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Sotho, Southern",@"sot",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Spanish",@"spa",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Sardinian",@"srd",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Swati",@"ssw",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Sundanese",@"sun",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Swahili",@"swa",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Swedish",@"swe",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tahitian",@"tah",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tamil",@"tam",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tatar",@"tat",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Telugu",@"tel",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tajik",@"tgk",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tagalog",@"tgl",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Thai",@"tha",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tibetan",@"bod",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tigrinya",@"tir",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tonga (Tonga Islands)",@"ton",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tswana",@"tsn",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Tsonga",@"tso",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Turkmen",@"tuk",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Turkish",@"tur",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Twi",@"twi",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Uighur",@"uig",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Ukrainian",@"ukr",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Urdu",@"urd",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Uzbek",@"uzb",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Venda",@"ven",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Vietnamese",@"vie",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Volapük",@"vol",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Welsh",@"cym",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Walloon",@"wln",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Wolof",@"wol",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Xhosa",@"xho",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Yiddish",@"yid",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Yoruba",@"yor",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"ZhuangZhuang",@"zha",nil]];
- [languagesArray addObject:[NSArray arrayWithObjects:@"Zulu",@"zul",nil]];
-
- languagesArrayDefIndex = 40;
+ for (lang = lang_get_next(NULL); lang != NULL; lang = lang_get_next(lang))
+ {
+ [languagesArray addObject:[NSArray arrayWithObjects:
+ [NSString stringWithUTF8String:lang->eng_name],
+ [NSString stringWithUTF8String:lang->iso639_2],
+ nil]];
+ if (!strcasecmp(lang->eng_name, "English"))
+ {
+ languagesArrayDefIndex = [languagesArray count] - 1;
+ }
+ }
/* populate the charCodeArray */
charCodeArray = [[NSMutableArray alloc] init];
27D6C75814B102DA00B785E4 /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73214B102DA00B785E4 /* libfreetype.a */; };
27D6C75914B102DA00B785E4 /* libfribidi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73314B102DA00B785E4 /* libfribidi.a */; };
27D6C75A14B102DA00B785E4 /* libfribidi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73314B102DA00B785E4 /* libfribidi.a */; };
- 27D6C75B14B102DA00B785E4 /* libmkv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73414B102DA00B785E4 /* libmkv.a */; };
- 27D6C75C14B102DA00B785E4 /* libmkv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73414B102DA00B785E4 /* libmkv.a */; };
27D6C75E14B102DA00B785E4 /* libmp3lame.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73614B102DA00B785E4 /* libmp3lame.a */; };
27D6C75F14B102DA00B785E4 /* libmp3lame.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73614B102DA00B785E4 /* libmp3lame.a */; };
- 27D6C76014B102DA00B785E4 /* libmp4v2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73714B102DA00B785E4 /* libmp4v2.a */; };
- 27D6C76114B102DA00B785E4 /* libmp4v2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73714B102DA00B785E4 /* libmp4v2.a */; };
27D6C76214B102DA00B785E4 /* libmpeg2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73814B102DA00B785E4 /* libmpeg2.a */; };
27D6C76314B102DA00B785E4 /* libmpeg2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73814B102DA00B785E4 /* libmpeg2.a */; };
27D6C76414B102DA00B785E4 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D6C73914B102DA00B785E4 /* libogg.a */; };
27D6C73114B102DA00B785E4 /* libfontconfig.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfontconfig.a; path = external/contrib/lib/libfontconfig.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C73214B102DA00B785E4 /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfreetype.a; path = external/contrib/lib/libfreetype.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C73314B102DA00B785E4 /* libfribidi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfribidi.a; path = external/contrib/lib/libfribidi.a; sourceTree = BUILT_PRODUCTS_DIR; };
- 27D6C73414B102DA00B785E4 /* libmkv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmkv.a; path = external/contrib/lib/libmkv.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C73614B102DA00B785E4 /* libmp3lame.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmp3lame.a; path = external/contrib/lib/libmp3lame.a; sourceTree = BUILT_PRODUCTS_DIR; };
- 27D6C73714B102DA00B785E4 /* libmp4v2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmp4v2.a; path = external/contrib/lib/libmp4v2.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C73814B102DA00B785E4 /* libmpeg2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmpeg2.a; path = external/contrib/lib/libmpeg2.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C73914B102DA00B785E4 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = external/contrib/lib/libogg.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C73A14B102DA00B785E4 /* libsamplerate.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsamplerate.a; path = external/contrib/lib/libsamplerate.a; sourceTree = BUILT_PRODUCTS_DIR; };
27D6C75614B102DA00B785E4 /* libfontconfig.a in Frameworks */,
27D6C75814B102DA00B785E4 /* libfreetype.a in Frameworks */,
27D6C75A14B102DA00B785E4 /* libfribidi.a in Frameworks */,
- 27D6C75C14B102DA00B785E4 /* libmkv.a in Frameworks */,
27D6C75F14B102DA00B785E4 /* libmp3lame.a in Frameworks */,
- 27D6C76114B102DA00B785E4 /* libmp4v2.a in Frameworks */,
27D6C76314B102DA00B785E4 /* libmpeg2.a in Frameworks */,
27D6C76514B102DA00B785E4 /* libogg.a in Frameworks */,
27D6C76714B102DA00B785E4 /* libsamplerate.a in Frameworks */,
27D6C75514B102DA00B785E4 /* libfontconfig.a in Frameworks */,
27D6C75714B102DA00B785E4 /* libfreetype.a in Frameworks */,
27D6C75914B102DA00B785E4 /* libfribidi.a in Frameworks */,
- 27D6C75B14B102DA00B785E4 /* libmkv.a in Frameworks */,
27D6C75E14B102DA00B785E4 /* libmp3lame.a in Frameworks */,
- 27D6C76014B102DA00B785E4 /* libmp4v2.a in Frameworks */,
27D6C76214B102DA00B785E4 /* libmpeg2.a in Frameworks */,
27D6C76414B102DA00B785E4 /* libogg.a in Frameworks */,
27D6C76614B102DA00B785E4 /* libsamplerate.a in Frameworks */,
27D6C73114B102DA00B785E4 /* libfontconfig.a */,
27D6C73214B102DA00B785E4 /* libfreetype.a */,
27D6C73314B102DA00B785E4 /* libfribidi.a */,
- 27D6C73414B102DA00B785E4 /* libmkv.a */,
27D6C73614B102DA00B785E4 /* libmp3lame.a */,
- 27D6C73714B102DA00B785E4 /* libmp4v2.a */,
27D6C73814B102DA00B785E4 /* libmpeg2.a */,
27D6C73914B102DA00B785E4 /* libogg.a */,
27D6C73A14B102DA00B785E4 /* libsamplerate.a */,
ifeq (1,$(FEATURE.faac))
extra_libs += $(abspath $(BUILD))/contrib/lib/libfaac.a
endif
+
+ifeq (1,$(FEATURE.mp4v2))
+ extra_libs += $(abspath $(BUILD))/contrib/lib/libmp4v2.a
+endif
+
+ifeq (1,$(FEATURE.libmkv))
+ extra_libs += $(abspath $(BUILD))/contrib/lib/libmkv.a
+endif
MACOSX.extra_ldflags = OTHER_LDFLAGS='$(extra_libs)'
## xcconfig: must be one of macosx/xcconfig/*.xcconfig
grp.add_option( '--enable-faac', dest="enable_faac", default=False, action='store_true', help=h )
grp.add_option( '--disable-faac', dest="enable_faac", action='store_false' )
+ h = IfHost( 'enable use of mp4v2 muxer', '*-*-*', none=optparse.SUPPRESS_HELP ).value
+ grp.add_option( '--enable-mp4v2', dest="enable_mp4v2", default=True, action='store_true', help=h )
+ grp.add_option( '--disable-mp4v2', dest="enable_mp4v2", action='store_false' )
+
+ h = IfHost( 'enable use of libmkv muxer', '*-*-*', none=optparse.SUPPRESS_HELP ).value
+ grp.add_option( '--enable-libmkv', dest="enable_libmkv", default=True, action='store_true', help=h )
+ grp.add_option( '--disable-libmkv', dest="enable_libmkv", action='store_false' )
+
+ h = IfHost( 'enable use of avformat muxer', '*-*-*', none=optparse.SUPPRESS_HELP ).value
+ grp.add_option( '--enable-avformat', dest="enable_avformat", default=True, action='store_true', help=h )
+ grp.add_option( '--disable-avformat', dest="enable_avformat", action='store_false' )
+
cli.add_option_group( grp )
## add launch options
doc.add( 'FEATURE.fdk_aac', int( options.enable_fdk_aac ))
doc.add( 'FEATURE.libav_aac', int( options.enable_libav_aac ))
doc.add( 'FEATURE.faac', int( options.enable_faac ))
+ doc.add( 'FEATURE.mp4v2', int( options.enable_mp4v2 ))
+ doc.add( 'FEATURE.libmkv', int( options.enable_libmkv ))
+ doc.add( 'FEATURE.avformat', int( options.enable_avformat ))
doc.add( 'FEATURE.qsv', int( options.enable_qsv ))
doc.add( 'FEATURE.xcode', int( not (Tools.xcodebuild.fail or options.disable_xcode or options.cross) ))
MODULES += contrib/faac
endif
+ifeq (1,$(FEATURE.mp4v2))
+ MODULES += contrib/mp4v2
+endif
+
+ifeq (1,$(FEATURE.libmkv))
+ MODULES += contrib/libmkv
+endif
+
MODULES += contrib/lame
MODULES += contrib/ffmpeg
MODULES += contrib/libdvdread
MODULES += contrib/libdvdnav
MODULES += contrib/libbluray
-MODULES += contrib/libmkv
-MODULES += contrib/mp4v2
MODULES += contrib/mpeg2dec
ifneq (,$(filter $(BUILD.system),mingw))
usr/bin/ghb
usr/share/applications/*
usr/share/icons/*
+usr/share/locale/*
#DOCS#
TEST.GCC.l = \
a52 ass avcodec avformat avutil avresample dvdnav dvdread \
- fontconfig freetype fribidi mkv mpeg2 mp3lame mp4v2 ogg \
+ fontconfig freetype fribidi mpeg2 mp3lame ogg \
samplerate swscale theoraenc theoradec vorbis vorbisenc x264 \
bluray xml2 bz2 z
TEST.GCC.l += faac
endif
+ifeq (1,$(FEATURE.mp4v2))
+TEST.GCC.l += mp4v2
+endif
+
+ifeq (1,$(FEATURE.libmkv))
+TEST.GCC.l += mkv
+endif
+
TEST.install.exe = $(DESTDIR)$(PREFIX/)bin/$(notdir $(TEST.exe))
###############################################################################
TEST.GCC.l += pthread dl m
else ifeq ($(BUILD.system),solaris)
TEST.GCC.l += pthread nsl socket iconv
+ TEST.GCC.D += _POSIX_C_SOURCE=200112L __EXTENSIONS__
else ifeq (1-mingw,$(BUILD.cross)-$(BUILD.system))
ifeq ($(HAS.dlfcn),1)
TEST.GCC.l += dl
}
sub_config = subtitle->config;
- if( mux == HB_MUX_MKV || subtitle->format == TEXTSUB)
+ if ((mux & HB_MUX_MASK_MKV) || subtitle->format == TEXTSUB)
{
sub_config.dest = PASSTHRUSUB;
}