Merge branch 'upstream/13.0' into tizen 70/222570/8 accepted/tizen/unified/20200304.123924 submit/tizen/20200211.115824 submit/tizen/20200224.103343 submit/tizen/20200303.010146
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 7 Feb 2020 02:57:20 +0000 (11:57 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 7 Feb 2020 03:08:32 +0000 (12:08 +0900)
[Version] 13.0-1
[Issue Type] Upgrade

Change-Id: I252236dc28ad2be6fa4cb7f44fd942aeb83f5396
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
55 files changed:
1  2 
Makefile.am
configure.ac
packaging/pulseaudio.spec
src/Makefile.am
src/daemon/cmdline.c
src/daemon/daemon-conf.c
src/daemon/main.c
src/map-file
src/modules/alsa/90-pulseaudio.rules
src/modules/alsa/alsa-sink.c
src/modules/alsa/alsa-ucm.c
src/modules/alsa/mixer/profile-sets/default.conf
src/modules/alsa/module-alsa-card.c
src/modules/bluetooth/a2dp-codecs.h
src/modules/bluetooth/backend-ofono.c
src/modules/bluetooth/bluez5-util.c
src/modules/bluetooth/bluez5-util.h
src/modules/bluetooth/module-bluetooth-policy.c
src/modules/bluetooth/module-bluez5-device.c
src/modules/bluetooth/module-bluez5-discover.c
src/modules/module-filter-apply.c
src/modules/module-ladspa-sink.c
src/modules/module-loopback.c
src/modules/module-role-cork.c
src/modules/module-role-ducking.c
src/modules/module-switch-on-port-available.c
src/modules/module-udev-detect.c
src/modules/raop/raop-client.c
src/modules/raop/raop-sink.c
src/modules/stream-interaction.c
src/pulse/context.c
src/pulse/context.h
src/pulse/def.h
src/pulse/proplist.h
src/pulse/simple.c
src/pulse/simple.h
src/pulse/stream.c
src/pulse/thread-mainloop.c
src/pulse/volume.c
src/pulse/volume.h
src/pulsecore/cli-command.c
src/pulsecore/core-util.c
src/pulsecore/core.c
src/pulsecore/core.h
src/pulsecore/log.c
src/pulsecore/protocol-native.c
src/pulsecore/sink-input.c
src/pulsecore/sink-input.h
src/pulsecore/sink.c
src/pulsecore/sink.h
src/pulsecore/source-output.c
src/pulsecore/source-output.h
src/pulsecore/source.c
src/pulsecore/source.h
src/utils/pactl.c

diff --cc Makefile.am
Simple merge
diff --cc configure.ac
@@@ -1750,9 -1600,7 +1785,8 @@@ AS_IF([test "x$HAVE_UDEV" = "x1"], ENAB
  AS_IF([test "x$HAVE_SYSTEMD_DAEMON" = "x1"], ENABLE_SYSTEMD_DAEMON=yes, ENABLE_SYSTEMD_DAEMON=no)
  AS_IF([test "x$HAVE_SYSTEMD_LOGIN" = "x1"], ENABLE_SYSTEMD_LOGIN=yes, ENABLE_SYSTEMD_LOGIN=no)
  AS_IF([test "x$HAVE_SYSTEMD_JOURNAL" = "x1"], ENABLE_SYSTEMD_JOURNAL=yes, ENABLE_SYSTEMD_JOURNAL=no)
- AS_IF([test "x$HAVE_BLUEZ_4" = "x1"], ENABLE_BLUEZ_4=yes, ENABLE_BLUEZ_4=no)
  AS_IF([test "x$HAVE_BLUEZ_5" = "x1"], ENABLE_BLUEZ_5=yes, ENABLE_BLUEZ_5=no)
 +AS_IF([test "x$HAVE_BLUEZ_VENDOR_CODEC" = "x1"], HAVE_BLUEZ_VENDOR_CODEC=yes, HAVE_BLUEZ_VENDOR_CODEC=no)
  AS_IF([test "x$HAVE_BLUEZ_5_OFONO_HEADSET" = "x1"], ENABLE_BLUEZ_5_OFONO_HEADSET=yes, ENABLE_BLUEZ_5_OFONO_HEADSET=no)
  AS_IF([test "x$HAVE_BLUEZ_5_NATIVE_HEADSET" = "x1"], ENABLE_BLUEZ_5_NATIVE_HEADSET=yes, ENABLE_BLUEZ_5_NATIVE_HEADSET=no)
  AS_IF([test "x$HAVE_HAL_COMPAT" = "x1"], ENABLE_HAL_COMPAT=yes, ENABLE_HAL_COMPAT=no)
index b72cc0e,0000000..91ffec6
mode 100644,000000..100644
--- /dev/null
@@@ -1,459 -1,0 +1,463 @@@
- Version:          11.1
- Release:          81
 +%define udev_dir %{_prefix}/lib/udev
 +
 +Name:             pulseaudio
 +Summary:          Improved Linux sound server
++Version:          13.0
++Release:          1
 +Group:            Multimedia/Audio
 +License:          LGPL-2.1
 +URL:              http://pulseaudio.org
 +Source0:          http://www.freedesktop.org/software/pulseaudio/releases/%{name}-%{version}.tar.gz
 +Source1001:       pulseaudio.manifest
 +BuildRequires:    libtool-ltdl-devel
 +BuildRequires:    libtool
 +BuildRequires:    intltool
 +BuildRequires:    fdupes
 +BuildRequires:    pkgconfig(speexdsp)
 +BuildRequires:    pkgconfig(sndfile)
 +BuildRequires:    pkgconfig(alsa)
 +BuildRequires:    pkgconfig(glib-2.0)
 +%if "%{tizen_profile_name}" != "tv"
 +BuildRequires:    pkgconfig(sbc)
 +%endif
 +BuildRequires:    pkgconfig(dbus-1)
 +BuildRequires:    pkgconfig(libudev)
 +BuildRequires:    pkgconfig(openssl1.1)
 +BuildRequires:    pkgconfig(json-c)
 +BuildRequires:    pkgconfig(dlog)
 +BuildRequires:    pkgconfig(cynara-client)
 +BuildRequires:    pkgconfig(cynara-creds-socket)
 +BuildRequires:    pkgconfig(cynara-session)
 +BuildRequires:    systemd-devel
 +BuildRequires:    libcap-devel
 +%if "%{tizen_profile_name}" == "tv"
 +BuildRequires:    pkgconfig(lwipc)
 +%endif
 +Requires:         udev
 +Requires(post):   /sbin/ldconfig
 +Requires(postun): /sbin/ldconfig
 +
 +%description
 +PulseAudio is a sound server for Linux and other Unix like operating
 +systems. It is intended to be an improved drop-in replacement for the
 +Enlightened Sound Daemon (ESOUND).
 +
 +%package -n libpulse
 +Summary:    PulseAudio client libraries
 +Group:      Multimedia/Audio
 +
 +%description -n libpulse
 +Client libraries used by applications that access a PulseAudio sound server
 +via PulseAudio's native interface.
 +
 +%package -n libpulse-mainloop-glib
 +Summary:        GLIB  2
 +Group:          Multimedia/Audio
 +
 +%description -n libpulse-mainloop-glib
 +pulseaudio is a networked sound server for Linux and other Unix like
 +operating systems and Microsoft Windows. It is intended to be an
 +improved drop-in replacement for the Enlightened Sound Daemon (ESOUND).
 +
 +This package contains the GLIB Main Loop bindings for the PulseAudio
 +sound server.
 +
 +%package -n libpulse-devel
 +Summary:    PulseAudio client development headers and libraries
 +Group:      Multimedia/Development
 +Requires:   libpulse = %{version}
 +Requires:   libpulse-mainloop-glib = %{version}
 +
 +%description -n libpulse-devel
 +Headers and libraries for developing applications that access a PulseAudio
 +sound server via PulseAudio's native interface
 +
 +%package utils
 +Summary:    Command line tools for the PulseAudio sound server
 +Group:      Multimedia/Audio
 +Requires:   %{name} = %{version}-%{release}
 +
 +%description utils
 +These tools provide command line access to various features of the
 +PulseAudio sound server. Included tools are:
 +pabrowse - Browse available PulseAudio servers on the local network.
 +paplay - Playback a WAV file via a PulseAudio sink.
 +pacat - Cat raw audio data to a PulseAudio sink.
 +parec - Cat raw audio data from a PulseAudio source.
 +pacmd - Connect to PulseAudio's built-in command line control interface.
 +pactl - Send a control command to a PulseAudio server.
 +padsp - /dev/dsp wrapper to transparently support OSS applications.
 +pax11publish - Store/retrieve PulseAudio default server/sink/source
 +settings in the X11 root window.
 +
 +%package module-bluetooth
 +Summary:    Bluetooth module for PulseAudio sound server
 +Group:      Multimedia/Audio
 +Requires:   %{name} = %{version}-%{release}
 +
 +%description module-bluetooth
 +This module enables PulseAudio to work with bluetooth devices, like headset
 +or audio gateway
 +
 +%package config
 +Summary: PA default configuration
 +Group: System Environment/Configuration
 +
 +%description config
 +Default configuration for PulseAudio.
 +
 +%package module-raop
 +Summary: PA module-raop
 +Group:   Multimedia/Audio
 +
 +%description module-raop
 +PulseAudio module-raop.
 +
 +%package module-augment-properties
 +Summary: PA module-augment-properties
 +Group:   Multimedia/Audio
 +
 +%description module-augment-properties
 +PulseAudio module-augment-properties.
 +
 +%package module-dbus-protocol
 +Summary: PA module-dbus-protocol
 +Group:   Multimedia/Audio
 +
 +%description module-dbus-protocol
 +PulseAudio module-dbus-protocol.
 +
 +%package module-switch-on-connect
 +Summary: PA module-swich-on-connect
 +Group:   Multimedia/Audio
 +
 +%description module-switch-on-connect
 +PulseAudio module-swich-on-connect.
 +
 +%package vala-bindings
 +Summary:    PA Vala bindings
 +Group:      Multimedia/Audio
 +Requires:   %{name} = %{version}-%{release}
 +
 +%description vala-bindings
 +PulseAudio Vala bindings.
 +
 +%package realtime-scheduling
 +Summary:    PA realtime scheduling
 +Group:      Multimedia/Audio
 +Requires:   %{name} = %{version}-%{release}
 +Requires:   libcap-tools
 +
 +%description realtime-scheduling
 +PulseAudio realtime-scheduling.
 +
 +%prep
 +%setup -q -T -b0
 +echo "%{version}" > .tarball-version
 +cp %{SOURCE1001} .
 +%if "%{tizen_profile_name}" == "tv"
 +cp src/daemon/systemd/system/pulseaudio-tv.service.in src/daemon/systemd/system/pulseaudio.service.in
 +%endif
 +
 +%build
 +export CFLAGS="%{optflags} -fno-strict-aliasing -D__TIZEN__ -DTIZEN_BT_A2DP_MULTISTREAM -D__TIZEN_BT__ -D__TIZEN_LOG__ %{?asan:-ldl -fPIC }"
 +%if 0%{?sec_build_binary_debug_enable}
 +export CFLAGS+=" -DTIZEN_DEBUG_ENABLE"
 +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
 +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
 +%endif
 +
 +%if "%{tizen_profile_name}" == "mobile"
 +echo "tizen profile mobile"
 +export CFLAGS+=" -DTIZEN_PROFILE_MOBILE "
 +%endif
 +
 +%if "%{tizen_profile_name}" == "wearable"
 +echo "tizen profile wearable"
 +export CFLAGS+=" -DTIZEN_PROFILE_WEARABLE"
 +%endif
 +
 +%if "%{tizen_profile_name}" == "tv"
 +echo "tizen profile tv"
 +export CFLAGS+=" -DTIZEN_TV_PROD "
 +%endif
 +
 +export LD_AS_NEEDED=0
 +NOCONFIGURE=yes ./bootstrap.sh
 +%configure --prefix=%{_prefix} \
 +        --disable-static \
 +        --enable-alsa \
 +        --disable-ipv6 \
 +        --disable-oss-output \
 +        --disable-oss-wrapper \
 +        --disable-esound \
 +        --disable-per-user-esound-socket \
 +        --disable-x11 \
 +        --disable-hal-compat \
 +        --disable-lirc \
 +        --disable-avahi \
 +        --disable-jack \
 +        --without-fftw \
 +        --disable-bluez4 \
 +        --disable-systemd-login \
++        --disable-gconf \
++        --disable-gsettings \
 +        --with-udev-rules-dir=%{udev_dir}/rules.d \
 +        --with-system-user=pulse \
 +        --with-system-group=pulse \
 +        --with-access-group=pulse-access \
 +        --enable-dlog \
 +        --enable-buffer-attr \
 +        --enable-pcm-dump \
 +        --enable-security \
 +        --enable-udev-with-usb-only \
 +        --enable-paready \
 +        --enable-pa-simple-ext \
 +        --enable-empty-pop \
 +%{?asan: --disable-neon-opt } \
 +        --enable-filter-group \
 +        --enable-volume-ramp \
 +        --enable-individual-volume-ratio \
 +%if "%{tizen_profile_name}" == "tv"
 +        --enable-prelink \
 +        --enable-lwipc \
 +        --disable-pcm-dump \
 +%endif
 +
 +%__make %{?_smp_mflags} V=0
 +
 +%install
 +%make_install
 +%find_lang %{name}
 +
 +rm -rf  %{buildroot}%{_sysconfdir}/xdg/autostart/pulseaudio-kde.desktop
 +rm -rf  %{buildroot}%{_bindir}/start-pulseaudio-kde
 +rm -rf  %{buildroot}%{_bindir}/start-pulseaudio-x11
 +rm -rf %{buildroot}%{_libdir}/pulse-%{version}/modules/module-device-manager.so
 +mkdir -p %{buildroot}%{_includedir}/pulsecore/filter
 +cp %{buildroot}%{_includedir}/pulsecore/lfe-filter.h %{buildroot}%{_includedir}/pulsecore/filter
 +
 +%if "%{tizen_profile_name}" == "tv"
 +mkdir -p %{buildroot}%{_unitdir}/sysinit.target.wants/
 +ln -s  ../pulseaudio.service  %{buildroot}%{_unitdir}/sysinit.target.wants/pulseaudio.service
 +%else
 +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants/
 +ln -s  ../pulseaudio.service  %{buildroot}%{_unitdir}/multi-user.target.wants/pulseaudio.service
 +%endif
 +
 +fdupes  %{buildroot}%{_datadir}
 +fdupes  %{buildroot}%{_includedir}
 +
 +# get rid of *.la files
 +rm -f %{buildroot}%{_libdir}/*.la
 +rm -f %{buildroot}%{_libdir}/pulseaudio/*.la
 +
 +%post
 +/sbin/ldconfig
 +
 +%preun
 +
 +%postun -p /sbin/ldconfig
 +
 +%post   -n libpulse -p /sbin/ldconfig
 +%postun -n libpulse -p /sbin/ldconfig
 +
 +%post   -n libpulse-mainloop-glib -p /sbin/ldconfig
 +%postun -n libpulse-mainloop-glib -p /sbin/ldconfig
 +
 +%post   realtime-scheduling
 +setcap cap_sys_nice+ep /usr/bin/pulseaudio
 +
 +%postun realtime-scheduling
 +setcap -r /usr/bin/pulseaudio
 +
 +%lang_package
 +
 +%files
 +%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%license LICENSE LGPL
 +%exclude %{_bindir}/esdcompat
 +%{_bindir}/pulseaudio
 +%{_libdir}/pulseaudio/libpulsecore-%{version}.so
 +%{udev_dir}/rules.d/90-pulseaudio.rules
 +%config(noreplace) /etc/dbus-1/system.d/pulseaudio-system.conf
 +# list all modules
 +%{_libdir}/pulse-%{version}/modules/libalsa-util.so
 +%{_libdir}/pulse-%{version}/modules/libcli.so
 +%{_libdir}/pulse-%{version}/modules/libprotocol-cli.so
 +%{_libdir}/pulse-%{version}/modules/libprotocol-http.so
 +%{_libdir}/pulse-%{version}/modules/libprotocol-native.so
 +%{_libdir}/pulse-%{version}/modules/libprotocol-simple.so
 +%{_libdir}/pulse-%{version}/modules/librtp.so
 +%{_libdir}/pulse-%{version}/modules/module-allow-passthrough.so
 +%{_libdir}/pulse-%{version}/modules/module-alsa-card.so
 +%{_libdir}/pulse-%{version}/modules/module-alsa-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-alsa-source.so
 +%{_libdir}/pulse-%{version}/modules/module-always-sink.so
++%{_libdir}/pulse-%{version}/modules/module-always-source.so
 +%{_libdir}/pulse-%{version}/modules/module-card-restore.so
 +%{_libdir}/pulse-%{version}/modules/module-cli-protocol-tcp.so
 +%{_libdir}/pulse-%{version}/modules/module-cli-protocol-unix.so
 +%{_libdir}/pulse-%{version}/modules/module-cli.so
 +%{_libdir}/pulse-%{version}/modules/module-combine.so
 +%{_libdir}/pulse-%{version}/modules/module-combine-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-console-kit.so
 +%{_libdir}/pulse-%{version}/modules/module-default-device-restore.so
 +%{_libdir}/pulse-%{version}/modules/module-detect.so
 +%{_libdir}/pulse-%{version}/modules/module-device-restore.so
 +%{_libdir}/pulse-%{version}/modules/module-echo-cancel.so
 +%{_libdir}/pulse-%{version}/modules/module-filter-apply.so
 +%{_libdir}/pulse-%{version}/modules/module-filter-heuristics.so
 +%{_libdir}/pulse-%{version}/modules/module-http-protocol-tcp.so
 +%{_libdir}/pulse-%{version}/modules/module-http-protocol-unix.so
 +%{_libdir}/pulse-%{version}/modules/module-intended-roles.so
 +%{_libdir}/pulse-%{version}/modules/module-ladspa-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-loopback.so
 +%{_libdir}/pulse-%{version}/modules/module-match.so
 +%{_libdir}/pulse-%{version}/modules/module-mmkbd-evdev.so
 +%{_libdir}/pulse-%{version}/modules/module-native-protocol-fd.so
 +%{_libdir}/pulse-%{version}/modules/module-native-protocol-tcp.so
 +%{_libdir}/pulse-%{version}/modules/module-native-protocol-unix.so
 +%{_libdir}/pulse-%{version}/modules/module-null-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-null-source.so
 +%{_libdir}/pulse-%{version}/modules/module-pipe-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-pipe-source.so
 +%{_libdir}/pulse-%{version}/modules/module-position-event-sounds.so
 +%{_libdir}/pulse-%{version}/modules/module-remap-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-remap-source.so
 +%{_libdir}/pulse-%{version}/modules/module-rescue-streams.so
 +%{_libdir}/pulse-%{version}/modules/module-role-ducking.so
 +%{_libdir}/pulse-%{version}/modules/module-role-cork.so
 +%{_libdir}/pulse-%{version}/modules/module-rtp-recv.so
 +%{_libdir}/pulse-%{version}/modules/module-rtp-send.so
 +%{_libdir}/pulse-%{version}/modules/module-rygel-media-server.so
 +%{_libdir}/pulse-%{version}/modules/module-simple-protocol-tcp.so
 +%{_libdir}/pulse-%{version}/modules/module-simple-protocol-unix.so
 +%{_libdir}/pulse-%{version}/modules/module-sine.so
 +%{_libdir}/pulse-%{version}/modules/module-sine-source.so
 +%{_libdir}/pulse-%{version}/modules/module-stream-restore.so
 +%{_libdir}/pulse-%{version}/modules/module-suspend-on-idle.so
 +%{_libdir}/pulse-%{version}/modules/module-switch-on-port-available.so
 +%{_libdir}/pulse-%{version}/modules/module-tunnel-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-tunnel-sink-new.so
 +%{_libdir}/pulse-%{version}/modules/module-tunnel-source.so
 +%{_libdir}/pulse-%{version}/modules/module-tunnel-source-new.so
 +%{_libdir}/pulse-%{version}/modules/module-udev-detect.so
 +%{_libdir}/pulse-%{version}/modules/module-virtual-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-virtual-source.so
 +%{_libdir}/pulse-%{version}/modules/module-virtual-surround-sink.so
 +%{_libdir}/pulse-%{version}/modules/module-volume-restore.so
 +
 +
 +%exclude %{_unitdir_user}/pulseaudio.service
 +%exclude %{_unitdir_user}/pulseaudio.socket
 +%{_unitdir}/pulseaudio.service
 +%if "%{tizen_profile_name}" == "tv"
 +%{_unitdir}/sysinit.target.wants/pulseaudio.service
 +%else
 +%{_unitdir}/multi-user.target.wants/pulseaudio.service
 +%endif
 +%exclude /usr/share/bash-completion/completions/*
 +%exclude /usr/share/zsh/site-functions/_pulseaudio
 +
 +
 +%files -n libpulse
 +%manifest %{name}.manifest
 +%license LICENSE LGPL
 +%defattr(-,root,root,-)
 +%{_libdir}/libpulse.so.*
 +%{_libdir}/libpulse-simple.so.*
 +%{_libdir}/pulseaudio/libpulsecommon-*.so
 +
 +%files -n libpulse-devel
 +%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%{_includedir}/pulse/*
 +%{_includedir}/pulsecore/*
 +%{_includedir}/pulsecore/filter/*
 +%{_libdir}/libpulse.so
 +%{_libdir}/libpulse-simple.so
 +%{_libdir}/libpulse-mainloop-glib.so
 +%{_libdir}/pkgconfig/libpulse*.pc
 +%{_libdir}/pkgconfig/pulsecore.pc
 +%{_datadir}/vala/vapi/libpulse.vapi
 +# cmake stuff
 +%{_libdir}/cmake/PulseAudio/PulseAudioConfig.cmake
 +%{_libdir}/cmake/PulseAudio/PulseAudioConfigVersion.cmake
 +
 +%files -n libpulse-mainloop-glib
 +%manifest %{name}.manifest
 +%defattr(-,root,root)
 +%{_libdir}/libpulse-mainloop-glib.so.*
 +
 +%files utils
 +%manifest %{name}.manifest
 +%license LICENSE LGPL
 +%defattr(-,root,root,-)
 +%doc %{_mandir}/man1/*
 +%doc %{_mandir}/man5/*
 +%{_bindir}/pacat
 +%{_bindir}/pacmd
 +%{_bindir}/pactl
 +%{_bindir}/paplay
 +%{_bindir}/parec
 +%{_bindir}/pamon
 +%{_bindir}/parecord
 +%{_bindir}/pasuspender
++%{_bindir}/pa-info
 +
 +%files module-bluetooth
 +%manifest %{name}.manifest
 +%license LICENSE LGPL
 +%if "%{tizen_profile_name}" != "tv"
 +%defattr(-,root,root,-)
 +%{_libdir}/pulse-%{version}/modules/module-bluetooth-discover.so
 +%{_libdir}/pulse-%{version}/modules/module-bluetooth-policy.so
 +%{_libdir}/pulse-%{version}/modules/module-bluez5-discover.so
 +%{_libdir}/pulse-%{version}/modules/module-bluez5-device.so
 +%{_libdir}/pulse-%{version}/modules/module-a2dp-vendor-codec-aptx.so
 +%{_libdir}/pulse-%{version}/modules/libbluez5-util.so
 +%endif
 +
 +%files module-raop
 +%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%{_libdir}/pulse-%{version}/modules/libraop.so
 +%{_libdir}/pulse-%{version}/modules/module-raop*.so
 +
 +%files module-augment-properties
 +%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%{_libdir}/pulse-%{version}/modules/module-augment-properties.so
 +
 +%files module-dbus-protocol
 +%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%{_libdir}/pulse-%{version}/modules/module-dbus-protocol.so
 +
 +%files module-switch-on-connect
 +%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%{_libdir}/pulse-%{version}/modules/module-switch-on-connect.so
 +
 +%files config
 +%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%config(noreplace) %{_sysconfdir}/pulse/daemon.conf
 +%config(noreplace) %{_sysconfdir}/pulse/default.pa
 +%config(noreplace) %{_sysconfdir}/pulse/client.conf
 +%config(noreplace) %{_sysconfdir}/pulse/system.pa
 +
 +%{_datadir}/pulseaudio/alsa-mixer/paths/*
 +%{_datadir}/pulseaudio/alsa-mixer/profile-sets/*
 +
 +%files vala-bindings
 +%manifest %{name}.manifest
 +%defattr(-,root,root,-)
 +%{_datadir}/vala/vapi/*
 +
 +%files realtime-scheduling
 +%defattr(-,root,root,-)
 +
 +%docs_package
diff --cc src/Makefile.am
@@@ -1959,9 -1681,7 +1904,10 @@@ module_switch_on_port_available_la_CFLA
  module_filter_apply_la_SOURCES = modules/module-filter-apply.c
  module_filter_apply_la_LDFLAGS = $(MODULE_LDFLAGS)
  module_filter_apply_la_LIBADD = $(MODULE_LIBADD)
- module_filter_apply_la_CFLAGS = -DTIZEN_FILTER_GROUP
+ module_filter_apply_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_filter_apply
 +if TIZEN_FILTER_GROUP
++module_filter_apply_la_CFLAGS += -DTIZEN_FILTER_GROUP
 +endif
  
  module_filter_heuristics_la_SOURCES = modules/module-filter-heuristics.c
  module_filter_heuristics_la_LDFLAGS = $(MODULE_LDFLAGS)
@@@ -2114,12 -1845,8 +2071,11 @@@ module_alsa_source_la_CFLAGS = $(AM_CFL
  module_alsa_card_la_SOURCES = modules/alsa/module-alsa-card.c
  module_alsa_card_la_LDFLAGS = $(MODULE_LDFLAGS)
  module_alsa_card_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la
- module_alsa_card_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
+ module_alsa_card_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) -DPA_MODULE_NAME=module_alsa_card
 +if TIZEN_UDEV_USB_ONLY
 +module_alsa_card_la_CFLAGS += -DTIZEN_UDEV_USB_ONLY
 +endif
  
  # Solaris
  
  module_solaris_la_SOURCES = modules/module-solaris.c
@@@ -2346,10 -2081,7 +2310,10 @@@ module_hal_detect_la_LDFLAGS = $(MODULE
  module_udev_detect_la_SOURCES = modules/module-udev-detect.c
  module_udev_detect_la_LDFLAGS = $(MODULE_LDFLAGS)
  module_udev_detect_la_LIBADD = $(MODULE_LIBADD) $(UDEV_LIBS)
- module_udev_detect_la_CFLAGS = $(AM_CFLAGS) $(UDEV_CFLAGS)
+ module_udev_detect_la_CFLAGS = $(AM_CFLAGS) $(UDEV_CFLAGS) -DPA_MODULE_NAME=module_udev_detect
 +if TIZEN_UDEV_USB_ONLY
 +module_udev_detect_la_CFLAGS += -DTIZEN_UDEV_USB_ONLY
 +endif
  
  module_console_kit_la_SOURCES = modules/module-console-kit.c
  module_console_kit_la_LDFLAGS = $(MODULE_LDFLAGS)
@@@ -2407,7 -2141,11 +2373,8 @@@ module_bluetooth_discover_la_CFLAGS = $
  libbluez5_util_la_SOURCES = \
                modules/bluetooth/bluez5-util.c \
                modules/bluetooth/bluez5-util.h \
-               modules/bluetooth/a2dp-codecs.h
 -              modules/bluetooth/a2dp-codec-api.h \
 -              modules/bluetooth/a2dp-codec-util.c \
 -              modules/bluetooth/a2dp-codec-util.h \
+               modules/bluetooth/a2dp-codecs.h \
+               modules/bluetooth/rtp.h
  if HAVE_BLUEZ_5_OFONO_HEADSET
  libbluez5_util_la_SOURCES += \
                modules/bluetooth/backend-ofono.c
@@@ -2420,17 -2158,12 +2387,22 @@@ endi
  libbluez5_util_la_LDFLAGS = -avoid-version
  libbluez5_util_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS)
  libbluez5_util_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
 -libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-sbc.c
+ libbluez5_util_la_CPPFLAGS = $(AM_CPPFLAGS)
++#libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-sbc.c
+ libbluez5_util_la_LIBADD += $(SBC_LIBS)
+ libbluez5_util_la_CFLAGS += $(SBC_CFLAGS)
  
 +if HAVE_BLUEZ_VENDOR_CODEC
 +module_a2dp_vendor_codec_aptx_la_SOURCES = \
 +              modules/bluetooth/module-a2dp-vendor-codec-aptx.c \
 +              modules/bluetooth/module-a2dp-vendor-codec.h \
 +              modules/bluetooth/a2dp-codecs.h
 +module_a2dp_vendor_codec_aptx_la_LDFLAGS = $(MODULE_LDFLAGS)
 +module_a2dp_vendor_codec_aptx_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) libbluez5-util.la
 +module_a2dp_vendor_codec_aptx_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
 +endif
 +
  module_bluez5_discover_la_SOURCES = modules/bluetooth/module-bluez5-discover.c
  module_bluez5_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
  module_bluez5_discover_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) libbluez5-util.la
@@@ -329,9 -325,7 +329,10 @@@ int pa_cmdline_parse(pa_daemon_conf *co
              case ARG_LOG_TARGET:
                  if (pa_daemon_conf_set_log_target(conf, optarg) < 0) {
  #ifdef HAVE_SYSTEMD_JOURNAL
-                     pa_log(_("Invalid log target: use either 'syslog', 'journal','stderr' or 'auto' or a valid file name 'file:<path>', 'newfile:<path>'."));
++
+                     pa_log(_("Invalid log target: use either 'syslog', 'journal', 'stderr' or 'auto' or a valid file name 'file:<path>', 'newfile:<path>'."));
 +#elif defined(TIZEN_DLOG)
 +                    pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file name 'file:<path>', 'newfile:<path>' or 'dlog' or 'dlog-color'."));
  #else
                      pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file name 'file:<path>', 'newfile:<path>'."));
  #endif
Simple merge
  #include "ltdl-bind-now.h"
  #include "server-lookup.h"
  
 +#ifdef TIZEN_PA_READY
 +#include <fcntl.h>
 +#define PA_READY "/tmp/.pa_ready"
 +#endif
 +
 +#ifdef TIZEN_TV_PROD_LWIPC
 +#include <lwipc.h>
 +#define PULSEAUDIO_READY "/tmp/.pulseaudio_ready"
 +#endif
+ #ifdef DISABLE_LIBTOOL_PRELOAD
+ /* FIXME: work around a libtool bug by making sure we have 2 elements. Bug has
+  * been reported: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=29576 */
+ const lt_dlsymlist lt_preloaded_symbols[] = {
+     { "@PROGRAM@", NULL },
+     { NULL, NULL }
+ };
+ #endif
  
  #ifdef HAVE_LIBWRAP
  /* Only one instance of these variables */
diff --cc src/map-file
Simple merge
@@@ -19,10 -19,9 +19,11 @@@ SUBSYSTEM!="sound", GOTO="pulseaudio_en
  ACTION!="change", GOTO="pulseaudio_end"
  KERNEL!="card*", GOTO="pulseaudio_end"
  SUBSYSTEMS=="usb", GOTO="pulseaudio_check_usb"
+ SUBSYSTEMS=="firewire", GOTO="pulseaudio_firewire_quirk"
  
  SUBSYSTEMS=="platform", DRIVERS=="thinkpad_acpi", ENV{PULSE_IGNORE}="1"
 +# For tizen platform, we only allow usb devices from udev
 +SUBSYSTEMS!="usb", ENV{PULSE_IGNORE}="1", GOTO="pulseaudio_end"
  
  # Force enable speaker and internal mic for some laptops
  # This should only be necessary for kernels 3.3, 3.4 and 3.5 (as they are lacking the phantom jack kctls).
@@@ -1542,27 -1663,19 +1663,24 @@@ static int sink_set_port_cb(pa_sink *s
      pa_assert(u->mixer_handle);
  
      data = PA_DEVICE_PORT_DATA(p);
      pa_assert_se(u->mixer_path = data->path);
-     pa_alsa_path_select(u->mixer_path, data->setting, u->mixer_handle, s->muted);
      mixer_volume_init(u);
  
-     if (s->set_mute)
-         s->set_mute(s);
-     if (s->flags & PA_SINK_DEFERRED_VOLUME) {
-         if (s->write_volume)
-             s->write_volume(s);
-     } else {
-         if (s->set_volume)
-             s->set_volume(s);
-     }
+     if (s->flags & PA_SINK_DEFERRED_VOLUME)
+         pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_SYNC_MIXER, p, 0, NULL);
+     else
+         sync_mixer(u, p);
+     if (data->suspend_when_unavailable && p->available == PA_AVAILABLE_NO)
+         pa_sink_suspend(s, true, PA_SUSPEND_UNAVAILABLE);
+     else
+         pa_sink_suspend(s, false, PA_SUSPEND_UNAVAILABLE);
  
 +    if (data->suspend_when_unavailable && p->available == PA_AVAILABLE_NO)
 +        pa_sink_suspend(s, true, PA_SUSPEND_UNAVAILABLE);
 +    else
 +        pa_sink_suspend(s, false, PA_SUSPEND_UNAVAILABLE);
 +
      return 0;
  }
  
Simple merge
@@@ -113,16 -106,25 +106,34 @@@ device-strings = front:%
  channel-map = left,right
  paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
  paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
- priority = 10
+ priority = 15
+ # If everything else fails, try to use hw:0 as a stereo device...
+ [Mapping stereo-fallback]
+ device-strings = hw:%f
+ fallback = yes
+ channel-map = front-left,front-right
+ paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
+ paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
+ priority = 1
+ # ...and if even that fails, try to use hw:0 as a mono device.
+ [Mapping mono-fallback]
+ device-strings = hw:%f
+ fallback = yes
+ channel-map = mono
+ paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono
+ paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headset-mic
+ priority = 1
 +
 +# If everything else fails, try to use hw:0 as a stereo device.
 +[Mapping stereo-fallback]
 +device-strings = hw:%f
 +fallback = yes
 +channel-map = front-left,front-right
 +paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
 +paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
 +priority = 1
  
  [Mapping analog-surround-21]
  device-strings = surround21:%f
Simple merge
  #define A2DP_CODEC_SBC                        0x00
  #define A2DP_CODEC_MPEG12             0x01
  #define A2DP_CODEC_MPEG24             0x02
++#ifdef __TIZEN_BT_6__
+ #define A2DP_CODEC_ATRAC              0x04
+ #define A2DP_CODEC_VENDOR             0xFF
++#else
 +#define A2DP_CODEC_ATRAC              0x03
 +#ifdef __TIZEN_BT__
 +/* #define BLUETOOTH_APTX_SUPPORT             1 */
 +#define A2DP_CODEC_VENDOR               0xFF
 +#endif
 +#define A2DP_CODEC_NON_A2DP           0xFF
++#endif
  #define SBC_SAMPLING_FREQ_16000               (1 << 3)
  #define SBC_SAMPLING_FREQ_32000               (1 << 2)
  #define SBC_SAMPLING_FREQ_44100               (1 << 1)
  #define SBC_ALLOCATION_SNR            (1 << 1)
  #define SBC_ALLOCATION_LOUDNESS               1
  
++#ifdef __TIZEN_BT_6__
+ #define SBC_MIN_BITPOOL                       2
+ #define SBC_MAX_BITPOOL                       250
+ /* Other settings:
+  * Block length = 16
+  * Allocation method = Loudness
+  * Subbands = 8
+  */
+ #define SBC_BITPOOL_MQ_MONO_44100             19
+ #define SBC_BITPOOL_MQ_MONO_48000             18
+ #define SBC_BITPOOL_MQ_JOINT_STEREO_44100     35
+ #define SBC_BITPOOL_MQ_JOINT_STEREO_48000     33
+ #define SBC_BITPOOL_HQ_MONO_44100             31
+ #define SBC_BITPOOL_HQ_MONO_48000             29
+ #define SBC_BITPOOL_HQ_JOINT_STEREO_44100     53
+ #define SBC_BITPOOL_HQ_JOINT_STEREO_48000     51
++#endif
  #define MPEG_CHANNEL_MODE_MONO                (1 << 3)
  #define MPEG_CHANNEL_MODE_DUAL_CHANNEL        (1 << 2)
  #define MPEG_CHANNEL_MODE_STEREO      (1 << 1)
  #define MPEG_SAMPLING_FREQ_44100      (1 << 1)
  #define MPEG_SAMPLING_FREQ_48000      1
  
++#ifndef __TIZEN_BT_6__
 +#if defined(__TIZEN_BT__) && defined(ADJUST_ANDROID_BITPOOL)
 +#define MAX_BITPOOL 35
 +#else
 +#define MAX_BITPOOL 64
 +#endif
 +#define MIN_BITPOOL 2
 +
 +/*#define APTX_CHANNEL_MODE_STEREO                    2 */
 +/*
 + * aptX codec for Bluetooth only supports stereo mode with value 2
 + * But we do have sink devices programmed to send capabilities with other channel mode support.
 + * So to handle the case and keeping codec symmetry with SBC etc., we do define other channel mode,
 + * and we always make sure to set configuration with APTX_CHANNEL_MODE_STEREO only.
 + *
 + * */
 +
 +#define APTX_CHANNEL_MODE_MONO                        (1 << 3)
 +#define APTX_CHANNEL_MODE_DUAL_CHANNEL        (1 << 2)
 +#define APTX_CHANNEL_MODE_STEREO              (1 << 1)
 +#define APTX_CHANNEL_MODE_JOINT_STEREO        1
 +
 +#define APTX_VENDOR_ID0               0x4F /*APTX codec ID 79*/
 +#define APTX_VENDOR_ID1               0x0
 +#define APTX_VENDOR_ID2               0x0
 +#define APTX_VENDOR_ID3               0x0
 +
 +#define APTX_CODEC_ID0                0x1
 +#define APTX_CODEC_ID1                0x0
 +
 +#define APTX_SAMPLING_FREQ_16000      (1 << 3)
 +#define APTX_SAMPLING_FREQ_32000      (1 << 2)
 +#define APTX_SAMPLING_FREQ_44100      (1 << 1)
 +#define APTX_SAMPLING_FREQ_48000      1
- #if __BYTE_ORDER == __LITTLE_ENDIAN
++#endif
++
+ #define MPEG_BIT_RATE_INDEX_0         (1 << 0)
+ #define MPEG_BIT_RATE_INDEX_1         (1 << 1)
+ #define MPEG_BIT_RATE_INDEX_2         (1 << 2)
+ #define MPEG_BIT_RATE_INDEX_3         (1 << 3)
+ #define MPEG_BIT_RATE_INDEX_4         (1 << 4)
+ #define MPEG_BIT_RATE_INDEX_5         (1 << 5)
+ #define MPEG_BIT_RATE_INDEX_6         (1 << 6)
+ #define MPEG_BIT_RATE_INDEX_7         (1 << 7)
+ #define MPEG_BIT_RATE_INDEX_8         (1 << 8)
+ #define MPEG_BIT_RATE_INDEX_9         (1 << 9)
+ #define MPEG_BIT_RATE_INDEX_10                (1 << 10)
+ #define MPEG_BIT_RATE_INDEX_11                (1 << 11)
+ #define MPEG_BIT_RATE_INDEX_12                (1 << 12)
+ #define MPEG_BIT_RATE_INDEX_13                (1 << 13)
+ #define MPEG_BIT_RATE_INDEX_14                (1 << 14)
+ #define MPEG_MP1_BIT_RATE_32000               MPEG_BIT_RATE_INDEX_1
+ #define MPEG_MP1_BIT_RATE_64000               MPEG_BIT_RATE_INDEX_2
+ #define MPEG_MP1_BIT_RATE_96000               MPEG_BIT_RATE_INDEX_3
+ #define MPEG_MP1_BIT_RATE_128000      MPEG_BIT_RATE_INDEX_4
+ #define MPEG_MP1_BIT_RATE_160000      MPEG_BIT_RATE_INDEX_5
+ #define MPEG_MP1_BIT_RATE_192000      MPEG_BIT_RATE_INDEX_6
+ #define MPEG_MP1_BIT_RATE_224000      MPEG_BIT_RATE_INDEX_7
+ #define MPEG_MP1_BIT_RATE_256000      MPEG_BIT_RATE_INDEX_8
+ #define MPEG_MP1_BIT_RATE_288000      MPEG_BIT_RATE_INDEX_9
+ #define MPEG_MP1_BIT_RATE_320000      MPEG_BIT_RATE_INDEX_10
+ #define MPEG_MP1_BIT_RATE_352000      MPEG_BIT_RATE_INDEX_11
+ #define MPEG_MP1_BIT_RATE_384000      MPEG_BIT_RATE_INDEX_12
+ #define MPEG_MP1_BIT_RATE_416000      MPEG_BIT_RATE_INDEX_13
+ #define MPEG_MP1_BIT_RATE_448000      MPEG_BIT_RATE_INDEX_14
+ #define MPEG_MP2_BIT_RATE_32000               MPEG_BIT_RATE_INDEX_1
+ #define MPEG_MP2_BIT_RATE_48000               MPEG_BIT_RATE_INDEX_2
+ #define MPEG_MP2_BIT_RATE_56000               MPEG_BIT_RATE_INDEX_3
+ #define MPEG_MP2_BIT_RATE_64000               MPEG_BIT_RATE_INDEX_4
+ #define MPEG_MP2_BIT_RATE_80000               MPEG_BIT_RATE_INDEX_5
+ #define MPEG_MP2_BIT_RATE_96000               MPEG_BIT_RATE_INDEX_6
+ #define MPEG_MP2_BIT_RATE_112000      MPEG_BIT_RATE_INDEX_7
+ #define MPEG_MP2_BIT_RATE_128000      MPEG_BIT_RATE_INDEX_8
+ #define MPEG_MP2_BIT_RATE_160000      MPEG_BIT_RATE_INDEX_9
+ #define MPEG_MP2_BIT_RATE_192000      MPEG_BIT_RATE_INDEX_10
+ #define MPEG_MP2_BIT_RATE_224000      MPEG_BIT_RATE_INDEX_11
+ #define MPEG_MP2_BIT_RATE_256000      MPEG_BIT_RATE_INDEX_12
+ #define MPEG_MP2_BIT_RATE_320000      MPEG_BIT_RATE_INDEX_13
+ #define MPEG_MP2_BIT_RATE_384000      MPEG_BIT_RATE_INDEX_14
+ #define MPEG_MP3_BIT_RATE_32000               MPEG_BIT_RATE_INDEX_1
+ #define MPEG_MP3_BIT_RATE_40000               MPEG_BIT_RATE_INDEX_2
+ #define MPEG_MP3_BIT_RATE_48000               MPEG_BIT_RATE_INDEX_3
+ #define MPEG_MP3_BIT_RATE_56000               MPEG_BIT_RATE_INDEX_4
+ #define MPEG_MP3_BIT_RATE_64000               MPEG_BIT_RATE_INDEX_5
+ #define MPEG_MP3_BIT_RATE_80000               MPEG_BIT_RATE_INDEX_6
+ #define MPEG_MP3_BIT_RATE_96000               MPEG_BIT_RATE_INDEX_7
+ #define MPEG_MP3_BIT_RATE_112000      MPEG_BIT_RATE_INDEX_8
+ #define MPEG_MP3_BIT_RATE_128000      MPEG_BIT_RATE_INDEX_9
+ #define MPEG_MP3_BIT_RATE_160000      MPEG_BIT_RATE_INDEX_10
+ #define MPEG_MP3_BIT_RATE_192000      MPEG_BIT_RATE_INDEX_11
+ #define MPEG_MP3_BIT_RATE_224000      MPEG_BIT_RATE_INDEX_12
+ #define MPEG_MP3_BIT_RATE_256000      MPEG_BIT_RATE_INDEX_13
+ #define MPEG_MP3_BIT_RATE_320000      MPEG_BIT_RATE_INDEX_14
+ #define MPEG_BIT_RATE_FREE            MPEG_BIT_RATE_INDEX_0
+ #define MPEG_GET_BITRATE(a) ((uint16_t)(a).bitrate1 << 8 | (a).bitrate2)
+ #define MPEG_SET_BITRATE(a, b) \
+       do { \
+               (a).bitrate1 = ((b) >> 8) & 0x7f; \
+               (a).bitrate2 = (b) & 0xff; \
+       } while (0)
+ #define AAC_OBJECT_TYPE_MPEG2_AAC_LC  0x80
+ #define AAC_OBJECT_TYPE_MPEG4_AAC_LC  0x40
+ #define AAC_OBJECT_TYPE_MPEG4_AAC_LTP 0x20
+ #define AAC_OBJECT_TYPE_MPEG4_AAC_SCA 0x10
+ #define AAC_SAMPLING_FREQ_8000                0x0800
+ #define AAC_SAMPLING_FREQ_11025               0x0400
+ #define AAC_SAMPLING_FREQ_12000               0x0200
+ #define AAC_SAMPLING_FREQ_16000               0x0100
+ #define AAC_SAMPLING_FREQ_22050               0x0080
+ #define AAC_SAMPLING_FREQ_24000               0x0040
+ #define AAC_SAMPLING_FREQ_32000               0x0020
+ #define AAC_SAMPLING_FREQ_44100               0x0010
+ #define AAC_SAMPLING_FREQ_48000               0x0008
+ #define AAC_SAMPLING_FREQ_64000               0x0004
+ #define AAC_SAMPLING_FREQ_88200               0x0002
+ #define AAC_SAMPLING_FREQ_96000               0x0001
+ #define AAC_CHANNELS_1                        0x02
+ #define AAC_CHANNELS_2                        0x01
+ #define AAC_GET_BITRATE(a) ((a).bitrate1 << 16 | \
+                                       (a).bitrate2 << 8 | (a).bitrate3)
+ #define AAC_GET_FREQUENCY(a) ((a).frequency1 << 4 | (a).frequency2)
+ #define AAC_SET_BITRATE(a, b) \
+       do { \
+               (a).bitrate1 = (b >> 16) & 0x7f; \
+               (a).bitrate2 = (b >> 8) & 0xff; \
+               (a).bitrate3 = b & 0xff; \
+       } while (0)
+ #define AAC_SET_FREQUENCY(a, f) \
+       do { \
+               (a).frequency1 = (f >> 4) & 0xff; \
+               (a).frequency2 = f & 0x0f; \
+       } while (0)
+ #define AAC_INIT_BITRATE(b) \
+       .bitrate1 = (b >> 16) & 0x7f, \
+       .bitrate2 = (b >> 8) & 0xff, \
+       .bitrate3 = b & 0xff,
+ #define AAC_INIT_FREQUENCY(f) \
+       .frequency1 = (f >> 4) & 0xff, \
+       .frequency2 = f & 0x0f,
+ #define APTX_VENDOR_ID                        0x0000004f
+ #define APTX_CODEC_ID                 0x0001
+ #define APTX_CHANNEL_MODE_MONO                0x01
+ #define APTX_CHANNEL_MODE_STEREO      0x02
+ #define APTX_SAMPLING_FREQ_16000      0x08
+ #define APTX_SAMPLING_FREQ_32000      0x04
+ #define APTX_SAMPLING_FREQ_44100      0x02
+ #define APTX_SAMPLING_FREQ_48000      0x01
+ #define FASTSTREAM_VENDOR_ID          0x0000000a
+ #define FASTSTREAM_CODEC_ID           0x0001
+ #define FASTSTREAM_DIRECTION_SINK     0x1
+ #define FASTSTREAM_DIRECTION_SOURCE   0x2
+ #define FASTSTREAM_SINK_SAMPLING_FREQ_44100   0x2
+ #define FASTSTREAM_SINK_SAMPLING_FREQ_48000   0x1
+ #define FASTSTREAM_SOURCE_SAMPLING_FREQ_16000 0x2
+ #define APTX_LL_VENDOR_ID             0x0000000a
+ #define APTX_LL_CODEC_ID              0x0002
+ /* Default parameters for aptX Low Latency encoder */
+ /* Target codec buffer level = 180 */
+ #define APTX_LL_TARGET_LEVEL2 0xb4
+ #define APTX_LL_TARGET_LEVEL1 0x00
+ /* Initial codec buffer level = 360 */
+ #define APTX_LL_INITIAL_LEVEL2        0x68
+ #define APTX_LL_INITIAL_LEVEL1        0x01
+ /* SRA max rate 0.005 * 10000 = 50 */
+ #define APTX_LL_SRA_MAX_RATE          0x32
+ /* SRA averaging time = 1s */
+ #define APTX_LL_SRA_AVG_TIME          0x01
+ /* Good working codec buffer level = 180 */
+ #define APTX_LL_GOOD_WORKING_LEVEL2   0xB4
+ #define APTX_LL_GOOD_WORKING_LEVEL1   0x00
+ #define APTX_HD_VENDOR_ID             0x000000D7
+ #define APTX_HD_CODEC_ID              0x0024
+ #define LDAC_VENDOR_ID                        0x0000012d
+ #define LDAC_CODEC_ID                 0x00aa
+ #define LDAC_SAMPLING_FREQ_44100      0x20
+ #define LDAC_SAMPLING_FREQ_48000      0x10
+ #define LDAC_SAMPLING_FREQ_88200      0x08
+ #define LDAC_SAMPLING_FREQ_96000      0x04
+ #define LDAC_SAMPLING_FREQ_176400     0x02
+ #define LDAC_SAMPLING_FREQ_192000     0x01
+ #define LDAC_CHANNEL_MODE_MONO                0x04
+ #define LDAC_CHANNEL_MODE_DUAL                0x02
+ #define LDAC_CHANNEL_MODE_STEREO      0x01
+ typedef struct {
+       uint8_t vendor_id4;
+       uint8_t vendor_id3;
+       uint8_t vendor_id2;
+       uint8_t vendor_id1;
+       uint8_t codec_id2;
+       uint8_t codec_id1;
+ } __attribute__ ((packed)) a2dp_vendor_codec_t;
+ #define A2DP_GET_VENDOR_ID(a) ( \
+               (((uint32_t)(a).vendor_id4) <<  0) | \
+               (((uint32_t)(a).vendor_id3) <<  8) | \
+               (((uint32_t)(a).vendor_id2) << 16) | \
+               (((uint32_t)(a).vendor_id1) << 24) \
+       )
+ #define A2DP_GET_CODEC_ID(a) ((a).codec_id2 | (((uint16_t)(a).codec_id1) << 8))
+ #define A2DP_SET_VENDOR_ID_CODEC_ID(v, c) ((a2dp_vendor_codec_t){ \
+               .vendor_id4 = (((v) >>  0) & 0xff), \
+               .vendor_id3 = (((v) >>  8) & 0xff), \
+               .vendor_id2 = (((v) >> 16) & 0xff), \
+               .vendor_id1 = (((v) >> 24) & 0xff), \
+               .codec_id2 = (((c) >> 0) & 0xff), \
+               .codec_id1 = (((c) >> 8) & 0xff), \
+       })
+ typedef struct {
+       uint8_t reserved;
+       uint8_t target_level2;
+       uint8_t target_level1;
+       uint8_t initial_level2;
+       uint8_t initial_level1;
+       uint8_t sra_max_rate;
+       uint8_t sra_avg_time;
+       uint8_t good_working_level2;
+       uint8_t good_working_level1;
+ } __attribute__ ((packed)) a2dp_aptx_ll_new_caps_t;
+ typedef struct {
+       a2dp_vendor_codec_t info;
+       uint8_t frequency;
+       uint8_t channel_mode;
+ } __attribute__ ((packed)) a2dp_ldac_t;
+ #if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+       __BYTE_ORDER == __LITTLE_ENDIAN
  
  typedef struct {
        uint8_t channel_mode:4;
@@@ -120,16 -326,46 +373,59 @@@ typedef struct 
        uint8_t frequency:6;
        uint8_t mpf:1;
        uint8_t rfa:1;
++#ifdef __TIZEN_BT_6__
+       uint8_t bitrate1:7;
+       uint8_t vbr:1;
+       uint8_t bitrate2;
++#else
 +      uint16_t bitrate;
++#endif
  } __attribute__ ((packed)) a2dp_mpeg_t;
  
  typedef struct {
+       uint8_t object_type;
+       uint8_t frequency1;
+       uint8_t rfa:2;
+       uint8_t channels:2;
+       uint8_t frequency2:4;
+       uint8_t bitrate1:7;
+       uint8_t vbr:1;
+       uint8_t bitrate2;
+       uint8_t bitrate3;
+ } __attribute__ ((packed)) a2dp_aac_t;
+ typedef struct {
++#ifdef __TIZEN_BT_6__
+       a2dp_vendor_codec_t info;
+       uint8_t channel_mode:4;
+       uint8_t frequency:4;
++#else
 +      uint8_t vendor_id[4];
 +      uint8_t codec_id[2];
 +      uint8_t channel_mode:4;
 +      uint8_t frequency:4;
++#endif
  } __attribute__ ((packed)) a2dp_aptx_t;
- #elif __BYTE_ORDER == __BIG_ENDIAN
++#ifdef __TIZEN_BT_6__
+ typedef struct {
+       a2dp_vendor_codec_t info;
+       uint8_t direction;
+       uint8_t sink_frequency:4;
+       uint8_t source_frequency:4;
+ } __attribute__ ((packed)) a2dp_faststream_t;
+ typedef struct {
+       a2dp_aptx_t aptx;
+       uint8_t bidirect_link:1;
+       uint8_t has_new_caps:1;
+       uint8_t reserved:6;
+       a2dp_aptx_ll_new_caps_t new_caps[0];
+ } __attribute__ ((packed)) a2dp_aptx_ll_t;
++#endif
+ #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
+       __BYTE_ORDER == __BIG_ENDIAN
  
  typedef struct {
        uint8_t frequency:4;
@@@ -148,16 -384,44 +444,55 @@@ typedef struct 
        uint8_t rfa:1;
        uint8_t mpf:1;
        uint8_t frequency:6;
++#ifdef __TIZEN_BT_6__
+       uint8_t vbr:1;
+       uint8_t bitrate1:7;
+       uint8_t bitrate2;
++#else
 +      uint16_t bitrate;
++#endif
  } __attribute__ ((packed)) a2dp_mpeg_t;
  
  typedef struct {
+       uint8_t object_type;
+       uint8_t frequency1;
+       uint8_t frequency2:4;
+       uint8_t channels:2;
+       uint8_t rfa:2;
+       uint8_t vbr:1;
+       uint8_t bitrate1:7;
+       uint8_t bitrate2;
+       uint8_t bitrate3;
+ } __attribute__ ((packed)) a2dp_aac_t;
+ typedef struct {
++#ifdef __TIZEN_BT_6__
+       a2dp_vendor_codec_t info;
+       uint8_t frequency:4;
+       uint8_t channel_mode:4;
++#else
 +      uint8_t vendor_id[4];
 +      uint8_t codec_id[2];
 +      uint8_t frequency:4;
 +      uint8_t channel_mode:4;
++#endif
  } __attribute__ ((packed)) a2dp_aptx_t;
  
+ typedef struct {
+       a2dp_vendor_codec_t info;
+       uint8_t direction;
+       uint8_t source_frequency:4;
+       uint8_t sink_frequency:4;
+ } __attribute__ ((packed)) a2dp_faststream_t;
+ typedef struct {
+       a2dp_aptx_t aptx;
+       uint8_t reserved:6;
+       uint8_t has_new_caps:1;
+       uint8_t bidirect_link:1;
+       a2dp_aptx_ll_new_caps_t new_caps[0];
+ } __attribute__ ((packed)) a2dp_aptx_ll_t;
  #else
  #error "Unknown byte order"
  #endif
Simple merge
@@@ -930,75 -889,33 +935,105 @@@ finish
      pa_xfree(endpoint);
  }
  
++#ifdef __TIZEN_BT_6__
+ static void register_endpoint(pa_bluetooth_discovery *y, const pa_a2dp_codec *a2dp_codec, const char *path, const char *endpoint, const char *uuid) {
+     DBusMessage *m;
+     DBusMessageIter i, d;
+     uint8_t capabilities[MAX_A2DP_CAPS_SIZE];
+     size_t capabilities_size;
+     uint8_t codec_id;
+     pa_log_debug("Registering %s on adapter %s", endpoint, path);
+     codec_id = a2dp_codec->id.codec_id;
+     capabilities_size = a2dp_codec->fill_capabilities(capabilities);
+     pa_assert(capabilities_size != 0);
+     pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, path, BLUEZ_MEDIA_INTERFACE, "RegisterEndpoint"));
+     dbus_message_iter_init_append(m, &i);
+     pa_assert_se(dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &endpoint));
+     dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
+                                          DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &d);
+     pa_dbus_append_basic_variant_dict_entry(&d, "UUID", DBUS_TYPE_STRING, &uuid);
+     pa_dbus_append_basic_variant_dict_entry(&d, "Codec", DBUS_TYPE_BYTE, &codec_id);
+     pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, capabilities_size);
+     dbus_message_iter_close_container(&i, &d);
+     send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint));
+ }
++#else
 +static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const char *endpoint, const char *uuid) {
 +    DBusMessage *m;
 +    DBusMessageIter i, d;
 +    uint8_t codec = 0;
 +
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +    if(pa_streq(endpoint,A2DP_APTX_SOURCE_ENDPOINT))
 +        codec = A2DP_CODEC_VENDOR;
 +#endif
 +    pa_log_debug("Registering %s on adapter %s", endpoint, path);
 +
 +    pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, path, BLUEZ_MEDIA_INTERFACE, "RegisterEndpoint"));
 +
 +    dbus_message_iter_init_append(m, &i);
 +    pa_assert_se(dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &endpoint));
 +    dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
 +                                         DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &d);
 +    pa_dbus_append_basic_variant_dict_entry(&d, "UUID", DBUS_TYPE_STRING, &uuid);
 +    pa_dbus_append_basic_variant_dict_entry(&d, "Codec", DBUS_TYPE_BYTE, &codec);
 +
 +    if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE) || pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK)) {
 +#ifdef __TIZEN_BT__
 +    if (codec == A2DP_CODEC_SBC) {
 +        a2dp_sbc_t capabilities;
 +        capabilities.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO |
 +                                    SBC_CHANNEL_MODE_JOINT_STEREO;
 +        capabilities.frequency = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_32000 | SBC_SAMPLING_FREQ_44100 |
 +                                 SBC_SAMPLING_FREQ_48000;
 +        capabilities.allocation_method = SBC_ALLOCATION_SNR | SBC_ALLOCATION_LOUDNESS;
 +        capabilities.subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8;
 +        capabilities.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 | SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16;
 +        capabilities.min_bitpool = MIN_BITPOOL;
 +        capabilities.max_bitpool = MAX_BITPOOL;
 +        pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
 +    }
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +    if (codec == A2DP_CODEC_VENDOR ) {
 +        /* aptx */
 +        a2dp_aptx_t capabilities;
 +        capabilities.vendor_id[0] = APTX_VENDOR_ID0;
 +        capabilities.vendor_id[1] = APTX_VENDOR_ID1;
 +        capabilities.vendor_id[2] = APTX_VENDOR_ID2;
 +        capabilities.vendor_id[3] = APTX_VENDOR_ID3;
 +        capabilities.codec_id[0] = APTX_CODEC_ID0;
 +        capabilities.codec_id[1] = APTX_CODEC_ID1;
 +        capabilities.channel_mode= APTX_CHANNEL_MODE_STEREO;
 +        capabilities.frequency= APTX_SAMPLING_FREQ_44100;
 +        pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
 +    }
 +#endif /* BLUETOOTH_APTX_SUPPORT */
 +#else
 +        a2dp_sbc_t capabilities;
 +        capabilities.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO |
 +                                    SBC_CHANNEL_MODE_JOINT_STEREO;
 +        capabilities.frequency = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_32000 | SBC_SAMPLING_FREQ_44100 |
 +                                 SBC_SAMPLING_FREQ_48000;
 +        capabilities.allocation_method = SBC_ALLOCATION_SNR | SBC_ALLOCATION_LOUDNESS;
 +        capabilities.subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8;
 +        capabilities.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 | SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16;
 +        capabilities.min_bitpool = MIN_BITPOOL;
 +        capabilities.max_bitpool = MAX_BITPOOL;
 +        pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
 +#endif /* __TIZEN_BT__ */
 +    }
 +
 +    dbus_message_iter_close_container(&i, &d);
 +
 +    send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint));
 +}
++#endif
  
  static void parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessageIter *dict_i) {
      DBusMessageIter element_i;
  
          if (pa_streq(interface, BLUEZ_ADAPTER_INTERFACE)) {
              pa_bluetooth_adapter *a;
++#ifdef __TIZEN_BT_6__
+             unsigned a2dp_codec_i;
++#endif
  
              if ((a = pa_hashmap_get(y->adapters, path))) {
                  pa_log_error("Found duplicated D-Bus path for adapter %s", path);
              if (!a->valid)
                  return;
  
++#ifdef __TIZEN_BT_6__
+             /* Order is important. bluez prefers endpoints registered earlier.
+              * And codec with higher number has higher priority. So iterate in reverse order. */
+             for (a2dp_codec_i = pa_bluetooth_a2dp_codec_count(); a2dp_codec_i > 0; a2dp_codec_i--) {
+                 const pa_a2dp_codec *a2dp_codec = pa_bluetooth_a2dp_codec_iter(a2dp_codec_i-1);
+                 char *endpoint;
+                 endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
+                 register_endpoint(y, a2dp_codec, path, endpoint, PA_BLUETOOTH_UUID_A2DP_SINK);
+                 pa_xfree(endpoint);
+                 endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name);
+                 register_endpoint(y, a2dp_codec, path, endpoint, PA_BLUETOOTH_UUID_A2DP_SOURCE);
+                 pa_xfree(endpoint);
+             }
++#else
 +            register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, PA_BLUETOOTH_UUID_A2DP_SOURCE);
 +            register_endpoint(y, path, A2DP_SINK_ENDPOINT, PA_BLUETOOTH_UUID_A2DP_SINK);
 +#ifdef TIZEN_BT_A2DP_MULTISTREAM
 +            register_endpoint(y, path, A2DP_SINK_ENDPOINT2, PA_BLUETOOTH_UUID_A2DP_SINK);
 +#endif
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +            register_endpoint(y, path, A2DP_APTX_SOURCE_ENDPOINT, PA_BLUETOOTH_UUID_A2DP_SOURCE);
 +#endif
++#endif
          } else if (pa_streq(interface, BLUEZ_DEVICE_INTERFACE)) {
  
              if ((d = pa_hashmap_get(y->devices, path))) {
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }
  
++#ifndef __TIZEN_BT_6__
 +static uint8_t a2dp_default_bitpool(uint8_t freq, uint8_t mode) {
 +    /* These bitpool values were chosen based on the A2DP spec recommendation */
 +    switch (freq) {
 +        case SBC_SAMPLING_FREQ_16000:
 +        case SBC_SAMPLING_FREQ_32000:
 +            return 53;
 +
 +        case SBC_SAMPLING_FREQ_44100:
 +
 +            switch (mode) {
 +                case SBC_CHANNEL_MODE_MONO:
 +                case SBC_CHANNEL_MODE_DUAL_CHANNEL:
 +                    return 31;
 +
 +                case SBC_CHANNEL_MODE_STEREO:
 +                case SBC_CHANNEL_MODE_JOINT_STEREO:
 +#if defined(__TIZEN_BT__) && defined(ADJUST_ANDROID_BITPOOL)
 +                    return 35;
 +#else
 +                    return 53;
 +#endif
 +            }
 +
 +            pa_log_warn("Invalid channel mode %u", mode);
 +            return 53;
 +
 +        case SBC_SAMPLING_FREQ_48000:
 +
 +            switch (mode) {
 +                case SBC_CHANNEL_MODE_MONO:
 +                case SBC_CHANNEL_MODE_DUAL_CHANNEL:
 +                    return 29;
 +
 +                case SBC_CHANNEL_MODE_STEREO:
 +                case SBC_CHANNEL_MODE_JOINT_STEREO:
 +                    return 51;
 +            }
 +
 +            pa_log_warn("Invalid channel mode %u", mode);
 +            return 51;
 +    }
 +
 +    pa_log_warn("Invalid sampling freq %u", freq);
 +    return 53;
 +}
 +
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +static DBusMessage *endpoint_select_configuration_for_aptx(DBusConnection *c, DBusMessage *m, void *userdata) {
 +    a2dp_aptx_t *cap;
 +    a2dp_aptx_t config;
 +    uint8_t *pconf = (uint8_t *) &config;
 +    int size;
 +    DBusMessage *r;
 +    DBusError e;
 +
 +    dbus_error_init(&e);
 +
 +    if (!dbus_message_get_args(m, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &cap, &size, DBUS_TYPE_INVALID)) {
 +        pa_log("org.bluez.MediaEndpoint.SelectConfiguration: %s", e.message);
 +        dbus_error_free(&e);
 +        goto fail;
 +    }
 +
 +    pa_assert(size == sizeof(config));
 +
 +    memset(&config, 0, sizeof(config));
 +
 +    if (cap->vendor_id[0] == APTX_VENDOR_ID0 &&
 +        cap->vendor_id[1] == APTX_VENDOR_ID1 &&
 +        cap->vendor_id[2] == APTX_VENDOR_ID2 &&
 +        cap->vendor_id[3] == APTX_VENDOR_ID3 &&
 +         cap->codec_id[0] == APTX_CODEC_ID0  &&
 +         cap->codec_id[1] == APTX_CODEC_ID1  )
 +        pa_log_debug("A2DP_CODEC_NON_A2DP and this is APTX Codec");
 +    else {
 +        pa_log_debug("A2DP_CODEC_NON_A2DP but this is not APTX Codec");
 +        goto fail;
 +    }
 +
 +    memcpy(&config,cap, sizeof(config));
 +
 +/* The below code shuld be re-written by aptx */
 +/* And we should configure pulseaudio freq */
 +
 +    if (cap->frequency & APTX_SAMPLING_FREQ_44100)
 +        config.frequency = APTX_SAMPLING_FREQ_44100;
 +    else if (cap->frequency & APTX_SAMPLING_FREQ_48000)
 +        config.frequency = APTX_SAMPLING_FREQ_48000;
 +    else if (cap->frequency & APTX_SAMPLING_FREQ_32000)
 +        config.frequency = APTX_SAMPLING_FREQ_32000;
 +    else if (cap->frequency & APTX_SAMPLING_FREQ_16000)
 +        config.frequency = APTX_SAMPLING_FREQ_16000;
 +    else {
 +        pa_log_error("No aptx supported frequencies");
 +        goto fail;
 +    }
 +
 +    if (cap->channel_mode & APTX_CHANNEL_MODE_JOINT_STEREO)
 +        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
 +    else if (cap->channel_mode & APTX_CHANNEL_MODE_STEREO)
 +        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
 +    else if (cap->channel_mode & APTX_CHANNEL_MODE_DUAL_CHANNEL)
 +        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
 +    else {
 +        pa_log_error("No aptx supported channel modes");
 +        goto fail;
 +    }
 +
 +    pa_assert_se(r = dbus_message_new_method_return(m));
 +
 +    pa_assert_se(dbus_message_append_args(
 +                                     r,
 +                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pconf, size,
 +                                     DBUS_TYPE_INVALID));
 +
 +    return r;
 +
 +fail:
 +    pa_assert_se(r = (dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
 +                                                        "Unable to select configuration")));
 +    return r;
 +}
 +#endif
++#endif
 +
  const char *pa_bluetooth_profile_to_string(pa_bluetooth_profile_t profile) {
      switch(profile) {
          case PA_BLUETOOTH_PROFILE_A2DP_SINK:
      return NULL;
  }
  
++#ifdef __TIZEN_BT_6__
+ static const pa_a2dp_codec *a2dp_endpoint_to_a2dp_codec(const char *endpoint) {
+     const char *codec_name;
+     if (pa_startswith(endpoint, A2DP_SINK_ENDPOINT "/"))
+         codec_name = endpoint + strlen(A2DP_SINK_ENDPOINT "/");
+     else if (pa_startswith(endpoint, A2DP_SOURCE_ENDPOINT "/"))
+         codec_name = endpoint + strlen(A2DP_SOURCE_ENDPOINT "/");
+     else
+         return NULL;
+     return pa_bluetooth_get_a2dp_codec(codec_name);
+ }
++#endif
  static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
++#ifdef __TIZEN_BT_6__
+     pa_bluetooth_discovery *y = userdata;
+     pa_bluetooth_device *d;
+     pa_bluetooth_transport *t;
+     const pa_a2dp_codec *a2dp_codec = NULL;
+     const char *sender, *path, *endpoint_path, *dev_path = NULL, *uuid = NULL;
+     const uint8_t *config = NULL;
+     int size = 0;
+     pa_bluetooth_profile_t p = PA_BLUETOOTH_PROFILE_OFF;
+     DBusMessageIter args, props;
+     DBusMessage *r;
+     if (!dbus_message_iter_init(m, &args) || !pa_streq(dbus_message_get_signature(m), "oa{sv}")) {
+         pa_log_error("Invalid signature for method SetConfiguration()");
+         goto fail2;
+     }
+     dbus_message_iter_get_basic(&args, &path);
+     if (pa_hashmap_get(y->transports, path)) {
+         pa_log_error("Endpoint SetConfiguration(): Transport %s is already configured.", path);
+         goto fail2;
+     }
+     pa_assert_se(dbus_message_iter_next(&args));
+     dbus_message_iter_recurse(&args, &props);
+     if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
+         goto fail;
+     endpoint_path = dbus_message_get_path(m);
+     /* Read transport properties */
+     while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
+         const char *key;
+         DBusMessageIter value, entry;
+         int var;
+         dbus_message_iter_recurse(&props, &entry);
+         dbus_message_iter_get_basic(&entry, &key);
+         dbus_message_iter_next(&entry);
+         dbus_message_iter_recurse(&entry, &value);
+         var = dbus_message_iter_get_arg_type(&value);
+         if (pa_streq(key, "UUID")) {
+             if (var != DBUS_TYPE_STRING) {
+                 pa_log_error("Property %s of wrong type %c", key, (char)var);
+                 goto fail;
+             }
+             dbus_message_iter_get_basic(&value, &uuid);
+             if (pa_startswith(endpoint_path, A2DP_SINK_ENDPOINT "/"))
+                 p = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
+             else if (pa_startswith(endpoint_path, A2DP_SOURCE_ENDPOINT "/"))
+                 p = PA_BLUETOOTH_PROFILE_A2DP_SINK;
+             if ((pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE) && p != PA_BLUETOOTH_PROFILE_A2DP_SINK) ||
+                 (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK) && p != PA_BLUETOOTH_PROFILE_A2DP_SOURCE)) {
+                 pa_log_error("UUID %s of transport %s incompatible with endpoint %s", uuid, path, endpoint_path);
+                 goto fail;
+             }
+         } else if (pa_streq(key, "Device")) {
+             if (var != DBUS_TYPE_OBJECT_PATH) {
+                 pa_log_error("Property %s of wrong type %c", key, (char)var);
+                 goto fail;
+             }
+             dbus_message_iter_get_basic(&value, &dev_path);
+         } else if (pa_streq(key, "Configuration")) {
+             DBusMessageIter array;
+             if (var != DBUS_TYPE_ARRAY) {
+                 pa_log_error("Property %s of wrong type %c", key, (char)var);
+                 goto fail;
+             }
+             dbus_message_iter_recurse(&value, &array);
+             var = dbus_message_iter_get_arg_type(&array);
+             if (var != DBUS_TYPE_BYTE) {
+                 pa_log_error("%s is an array of wrong type %c", key, (char)var);
+                 goto fail;
+             }
+             dbus_message_iter_get_fixed_array(&array, &config, &size);
+             a2dp_codec = a2dp_endpoint_to_a2dp_codec(endpoint_path);
+             pa_assert(a2dp_codec);
+             if (!a2dp_codec->is_configuration_valid(config, size))
+                 goto fail;
+         }
+         dbus_message_iter_next(&props);
+     }
+     if (!a2dp_codec)
+         goto fail2;
+     if ((d = pa_hashmap_get(y->devices, dev_path))) {
+         if (!d->valid) {
+             pa_log_error("Information about device %s is invalid", dev_path);
+             goto fail2;
+         }
+     } else {
+         /* InterfacesAdded signal is probably on its way, device_info_valid is kept as 0. */
+         pa_log_warn("SetConfiguration() received for unknown device %s", dev_path);
+         d = device_create(y, dev_path);
+     }
+     if (d->transports[p] != NULL) {
+         pa_log_error("Cannot configure transport %s because profile %s is already used", path, pa_bluetooth_profile_to_string(p));
+         goto fail2;
+     }
+     sender = dbus_message_get_sender(m);
+     pa_assert_se(r = dbus_message_new_method_return(m));
+     pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL));
+     dbus_message_unref(r);
+     t = pa_bluetooth_transport_new(d, sender, path, p, config, size);
+     t->a2dp_codec = a2dp_codec;
+     t->acquire = bluez5_transport_acquire_cb;
+     t->release = bluez5_transport_release_cb;
+     pa_bluetooth_transport_put(t);
+     pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
+     return NULL;
+ fail:
+     pa_log_error("Endpoint SetConfiguration(): invalid arguments");
+ fail2:
+     pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to set configuration"));
+     return r;
++#else
 +    pa_bluetooth_discovery *y = userdata;
 +    pa_bluetooth_device *d;
 +    pa_bluetooth_transport *t;
 +    const char *sender, *path, *endpoint_path, *dev_path = NULL, *uuid = NULL;
 +#ifdef __TIZEN_BT__
 +    uint8_t codec = 0;
 +#endif
 +    const uint8_t *config = NULL;
 +    int size = 0;
 +    pa_bluetooth_profile_t p = PA_BLUETOOTH_PROFILE_OFF;
 +    DBusMessageIter args, props;
 +    DBusMessage *r;
 +
 +    if (!dbus_message_iter_init(m, &args) || !pa_streq(dbus_message_get_signature(m), "oa{sv}")) {
 +        pa_log_error("Invalid signature for method SetConfiguration()");
 +        goto fail2;
 +    }
 +
 +    dbus_message_iter_get_basic(&args, &path);
 +
 +    if (pa_hashmap_get(y->transports, path)) {
 +        pa_log_error("Endpoint SetConfiguration(): Transport %s is already configured.", path);
 +        goto fail2;
 +    }
 +
 +    pa_assert_se(dbus_message_iter_next(&args));
 +
 +    dbus_message_iter_recurse(&args, &props);
 +    if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
 +        goto fail;
 +
 +    /* Read transport properties */
 +    while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
 +        const char *key;
 +        DBusMessageIter value, entry;
 +        int var;
 +
 +        dbus_message_iter_recurse(&props, &entry);
 +        dbus_message_iter_get_basic(&entry, &key);
 +
 +        dbus_message_iter_next(&entry);
 +        dbus_message_iter_recurse(&entry, &value);
 +
 +        var = dbus_message_iter_get_arg_type(&value);
 +
 +        if (pa_streq(key, "UUID")) {
 +            if (var != DBUS_TYPE_STRING) {
 +                pa_log_error("Property %s of wrong type %c", key, (char)var);
 +                goto fail;
 +            }
 +
 +            dbus_message_iter_get_basic(&value, &uuid);
 +
 +            endpoint_path = dbus_message_get_path(m);
 +#ifdef __TIZEN_BT__
 +            pa_assert_se(endpoint_path);
 +#endif
 +
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +            if (pa_streq(endpoint_path, A2DP_SOURCE_ENDPOINT) ||
 +                pa_streq(endpoint_path, A2DP_APTX_SOURCE_ENDPOINT)) {
 +                if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE))
 +                    p = PA_BLUETOOTH_PROFILE_A2DP_SINK;
 +            }
 +#else
 +            if (pa_streq(endpoint_path, A2DP_SOURCE_ENDPOINT)) {
 +                if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE))
 +                    p = PA_BLUETOOTH_PROFILE_A2DP_SINK;
 +            }
 +#endif
 +            else if (pa_streq(endpoint_path, A2DP_SINK_ENDPOINT)) {
 +                if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK))
 +                    p = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
 +            }
 +#ifdef TIZEN_BT_A2DP_MULTISTREAM
 +            else if (pa_streq(endpoint_path, A2DP_SINK_ENDPOINT2)) {
 +                if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK))
 +                    p = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
 +            }
 +#endif
 +
 +            if (p == PA_BLUETOOTH_PROFILE_OFF) {
 +                pa_log_error("UUID %s of transport %s incompatible with endpoint %s", uuid, path, endpoint_path);
 +                goto fail;
 +            }
 +#ifdef __TIZEN_BT__
 +        } else if (pa_streq(key, "Codec")) {
 +            if (var != DBUS_TYPE_BYTE) {
 +                pa_log_error("Property %s of wrong type %c", key, (char)var);
 +                goto fail;
 +            }
 +
 +            dbus_message_iter_get_basic(&value, &codec);
 +#endif
 +        } else if (pa_streq(key, "Device")) {
 +            if (var != DBUS_TYPE_OBJECT_PATH) {
 +                pa_log_error("Property %s of wrong type %c", key, (char)var);
 +                goto fail;
 +            }
 +
 +            dbus_message_iter_get_basic(&value, &dev_path);
 +        } else if (pa_streq(key, "Configuration")) {
 +            DBusMessageIter array;
 +#ifndef BLUETOOTH_APTX_SUPPORT
 +            a2dp_sbc_t *c;
 +#endif
 +
 +            if (var != DBUS_TYPE_ARRAY) {
 +                pa_log_error("Property %s of wrong type %c", key, (char)var);
 +                goto fail;
 +            }
 +
 +            dbus_message_iter_recurse(&value, &array);
 +            var = dbus_message_iter_get_arg_type(&array);
 +            if (var != DBUS_TYPE_BYTE) {
 +                pa_log_error("%s is an array of wrong type %c", key, (char)var);
 +                goto fail;
 +            }
 +
 +            dbus_message_iter_get_fixed_array(&array, &config, &size);
 +#ifndef BLUETOOTH_APTX_SUPPORT
 +            if (size != sizeof(a2dp_sbc_t)) {
 +                pa_log_error("Configuration array of invalid size");
 +                goto fail;
 +            }
 +
 +            c = (a2dp_sbc_t *) config;
 +
 +            if (c->frequency != SBC_SAMPLING_FREQ_16000 && c->frequency != SBC_SAMPLING_FREQ_32000 &&
 +                c->frequency != SBC_SAMPLING_FREQ_44100 && c->frequency != SBC_SAMPLING_FREQ_48000) {
 +                pa_log_error("Invalid sampling frequency in configuration");
 +                goto fail;
 +            }
 +
 +            if (c->channel_mode != SBC_CHANNEL_MODE_MONO && c->channel_mode != SBC_CHANNEL_MODE_DUAL_CHANNEL &&
 +                c->channel_mode != SBC_CHANNEL_MODE_STEREO && c->channel_mode != SBC_CHANNEL_MODE_JOINT_STEREO) {
 +                pa_log_error("Invalid channel mode in configuration");
 +                goto fail;
 +            }
 +
 +            if (c->allocation_method != SBC_ALLOCATION_SNR && c->allocation_method != SBC_ALLOCATION_LOUDNESS) {
 +                pa_log_error("Invalid allocation method in configuration");
 +                goto fail;
 +            }
 +
 +            if (c->subbands != SBC_SUBBANDS_4 && c->subbands != SBC_SUBBANDS_8) {
 +                pa_log_error("Invalid SBC subbands in configuration");
 +                goto fail;
 +            }
 +
 +            if (c->block_length != SBC_BLOCK_LENGTH_4 && c->block_length != SBC_BLOCK_LENGTH_8 &&
 +                c->block_length != SBC_BLOCK_LENGTH_12 && c->block_length != SBC_BLOCK_LENGTH_16) {
 +                pa_log_error("Invalid block length in configuration");
 +                goto fail;
 +            }
 +#endif
 +        }
 +
 +        dbus_message_iter_next(&props);
 +    }
 +
 +    if ((d = pa_hashmap_get(y->devices, dev_path))) {
 +        if (!d->valid) {
 +            pa_log_error("Information about device %s is invalid", dev_path);
 +            goto fail2;
 +        }
 +    } else {
 +        /* InterfacesAdded signal is probably on its way, device_info_valid is kept as 0. */
 +        pa_log_warn("SetConfiguration() received for unknown device %s", dev_path);
 +        d = device_create(y, dev_path);
 +    }
 +
 +    if (d->transports[p] != NULL) {
 +        pa_log_error("Cannot configure transport %s because profile %s is already used", path, pa_bluetooth_profile_to_string(p));
 +        goto fail2;
 +    }
 +
 +    sender = dbus_message_get_sender(m);
 +
 +    pa_assert_se(r = dbus_message_new_method_return(m));
 +    pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL));
 +    dbus_message_unref(r);
 +
 +    t = pa_bluetooth_transport_new(d, sender, path, p, config, size);
 +#ifdef __TIZEN_BT__
 +    t->codec = codec;
 +    d->transports[p] = t;
 +#endif
 +    t->acquire = bluez5_transport_acquire_cb;
 +    t->release = bluez5_transport_release_cb;
 +    pa_bluetooth_transport_put(t);
 +
 +    pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
 +
 +    return NULL;
 +
 +fail:
 +    pa_log_error("Endpoint SetConfiguration(): invalid arguments");
 +
 +fail2:
 +    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to set configuration"));
 +    return r;
++#endif
  }
  
  static DBusMessage *endpoint_select_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
      pa_bluetooth_discovery *y = userdata;
++#ifndef __TIZEN_BT_6__
 +    a2dp_sbc_t *cap, config;
 +    uint8_t *pconf = (uint8_t *) &config;
 +    int i, size;
 +    DBusMessage *r;
 +    DBusError err;
 +
 +    static const struct {
 +        uint32_t rate;
 +        uint8_t cap;
 +    } freq_table[] = {
 +        { 16000U, SBC_SAMPLING_FREQ_16000 },
 +        { 32000U, SBC_SAMPLING_FREQ_32000 },
 +        { 44100U, SBC_SAMPLING_FREQ_44100 },
 +        { 48000U, SBC_SAMPLING_FREQ_48000 }
 +    };
++#else
+     const char *endpoint_path;
+     uint8_t *cap;
+     int size;
+     const pa_a2dp_codec *a2dp_codec;
+     uint8_t config[MAX_A2DP_CAPS_SIZE];
+     uint8_t *config_ptr = config;
+     size_t config_size;
+     DBusMessage *r;
+     DBusError err;
+     endpoint_path = dbus_message_get_path(m);
++#endif
 +
++#ifndef __TIZEN_BT_6__
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +    if (dbus_message_has_path(m, A2DP_APTX_SOURCE_ENDPOINT))
 +        return endpoint_select_configuration_for_aptx(conn ,m ,userdata);
 +#endif
++#endif
  
      dbus_error_init(&err);
  
          goto fail;
      }
  
++#ifndef __TIZEN_BT_6__
 +    if (size != sizeof(config)) {
 +        pa_log_error("Capabilities array has invalid size");
 +        goto fail;
 +    }
 +
 +    pa_zero(config);
 +
 +    /* Find the lowest freq that is at least as high as the requested sampling rate */
 +    for (i = 0; (unsigned) i < PA_ELEMENTSOF(freq_table); i++)
 +        if (freq_table[i].rate >= y->core->default_sample_spec.rate && (cap->frequency & freq_table[i].cap)) {
 +            config.frequency = freq_table[i].cap;
 +            break;
 +        }
 +
 +    if ((unsigned) i == PA_ELEMENTSOF(freq_table)) {
 +        for (--i; i >= 0; i--) {
 +            if (cap->frequency & freq_table[i].cap) {
 +                config.frequency = freq_table[i].cap;
 +                break;
 +            }
 +        }
 +
 +        if (i < 0) {
 +            pa_log_error("Not suitable sample rate");
 +            goto fail;
 +        }
 +    }
 +
 +    pa_assert((unsigned) i < PA_ELEMENTSOF(freq_table));
 +
 +    if (y->core->default_sample_spec.channels <= 1) {
 +        if (cap->channel_mode & SBC_CHANNEL_MODE_MONO)
 +            config.channel_mode = SBC_CHANNEL_MODE_MONO;
 +        else if (cap->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
 +            config.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
 +        else if (cap->channel_mode & SBC_CHANNEL_MODE_STEREO)
 +            config.channel_mode = SBC_CHANNEL_MODE_STEREO;
 +        else if (cap->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
 +            config.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
 +        else {
 +            pa_log_error("No supported channel modes");
 +            goto fail;
 +        }
 +    }
 +
 +    if (y->core->default_sample_spec.channels >= 2) {
 +        if (cap->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
 +            config.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
 +        else if (cap->channel_mode & SBC_CHANNEL_MODE_STEREO)
 +            config.channel_mode = SBC_CHANNEL_MODE_STEREO;
 +        else if (cap->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
 +            config.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
 +        else if (cap->channel_mode & SBC_CHANNEL_MODE_MONO)
 +            config.channel_mode = SBC_CHANNEL_MODE_MONO;
 +        else {
 +            pa_log_error("No supported channel modes");
 +            goto fail;
 +        }
 +    }
 +
 +    if (cap->block_length & SBC_BLOCK_LENGTH_16)
 +        config.block_length = SBC_BLOCK_LENGTH_16;
 +    else if (cap->block_length & SBC_BLOCK_LENGTH_12)
 +        config.block_length = SBC_BLOCK_LENGTH_12;
 +    else if (cap->block_length & SBC_BLOCK_LENGTH_8)
 +        config.block_length = SBC_BLOCK_LENGTH_8;
 +    else if (cap->block_length & SBC_BLOCK_LENGTH_4)
 +        config.block_length = SBC_BLOCK_LENGTH_4;
 +    else {
 +        pa_log_error("No supported block lengths");
 +        goto fail;
 +    }
 +
 +    if (cap->subbands & SBC_SUBBANDS_8)
 +        config.subbands = SBC_SUBBANDS_8;
 +    else if (cap->subbands & SBC_SUBBANDS_4)
 +        config.subbands = SBC_SUBBANDS_4;
 +    else {
 +        pa_log_error("No supported subbands");
 +        goto fail;
 +    }
 +
 +    if (cap->allocation_method & SBC_ALLOCATION_LOUDNESS)
 +        config.allocation_method = SBC_ALLOCATION_LOUDNESS;
 +    else if (cap->allocation_method & SBC_ALLOCATION_SNR)
 +        config.allocation_method = SBC_ALLOCATION_SNR;
 +
 +    config.min_bitpool = (uint8_t) PA_MAX(MIN_BITPOOL, cap->min_bitpool);
 +    config.max_bitpool = (uint8_t) PA_MIN(a2dp_default_bitpool(config.frequency, config.channel_mode), cap->max_bitpool);
 +
 +    if (config.min_bitpool > config.max_bitpool)
 +        goto fail;
 +
 +    pa_assert_se(r = dbus_message_new_method_return(m));
 +    pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pconf, size, DBUS_TYPE_INVALID));
++#else
+     a2dp_codec = a2dp_endpoint_to_a2dp_codec(endpoint_path);
+     pa_assert(a2dp_codec);
+     config_size = a2dp_codec->fill_preferred_configuration(&y->core->default_sample_spec, cap, size, config);
+     if (config_size == 0)
+         goto fail;
+     pa_assert_se(r = dbus_message_new_method_return(m));
+     pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &config_ptr, config_size, DBUS_TYPE_INVALID));
++#endif
  
      return r;
  
@@@ -1866,36 -1505,29 +2107,60 @@@ fail
  }
  
  static DBusMessage *endpoint_release(DBusConnection *conn, DBusMessage *m, void *userdata) {
++#ifndef __TIZEN_BT_6__
 +    DBusMessage *r;
 +
 +    pa_assert_se(r = dbus_message_new_error(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE ".Error.NotImplemented",
 +                                            "Method not implemented"));
++#else
+     DBusMessage *r = NULL;
+     /* From doc/media-api.txt in bluez:
+      *
+      *    This method gets called when the service daemon
+      *    unregisters the endpoint. An endpoint can use it to do
+      *    cleanup tasks. There is no need to unregister the
+      *    endpoint, because when this method gets called it has
+      *    already been unregistered.
+      *
+      * We don't have any cleanup to do. */
+     /* Reply only if requested. Generally bluetoothd doesn't request a reply
+      * to the Release() call. Sending replies when not requested on the system
+      * bus tends to cause errors in syslog from dbus-daemon, because it
+      * doesn't let unexpected replies through, so it's important to have this
+      * check here. */
+     if (!dbus_message_get_no_reply(m))
+         pa_assert_se(r = dbus_message_new_method_return(m));
++#endif
  
      return r;
  }
  
++#ifndef __TIZEN_BT_6__
 +#ifdef __TIZEN_BT__
 +static DBusMessage *endpoint_suspend_media(DBusConnection *conn, DBusMessage *m, void *userdata) {
 +    pa_bluetooth_discovery *y = userdata;
 +    pa_bluetooth_transport *t;
 +    DBusMessage *r;
 +
 +    pa_log_debug("dbus Call from to Suspend Media");
 +    if (!(t = pa_hashmap_first(y->transports)))
 +        goto fail;
 +
 +    pa_hook_fire(&t->device->discovery->hooks[PA_BLUETOOTH_HOOK_SCO_STATE_CHANGED], t);
 +
 +    pa_assert_se(r = dbus_message_new_method_return(m));
 +
 +    return r;
 +
 +fail:
 +    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to clear configuration"));
 +    return r;
 +}
 +#endif
++#endif
 +
  static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, void *userdata) {
      struct pa_bluetooth_discovery *y = userdata;
      DBusMessage *r = NULL;
  
      pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
  
++#ifndef __TIZEN_BT_6__
 +#ifdef __TIZEN_BT__
 +    pa_assert_se(path);
 +#endif
 +
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +#ifdef TIZEN_BT_A2DP_MULTISTREAM
 +    if (!pa_streq(path, A2DP_SOURCE_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT2)
 +         && !pa_streq(path,A2DP_APTX_SOURCE_ENDPOINT))
 +        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 +#else
 +     if (!pa_streq(path, A2DP_SOURCE_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT) && !pa_streq(path,A2DP_APTX_SOURCE_ENDPOINT))
 +        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 +#endif
 +#else
 +#ifdef TIZEN_BT_A2DP_MULTISTREAM
 +    if (!pa_streq(path, A2DP_SOURCE_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT2))
 +        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 +#else
 +    if (!pa_streq(path, A2DP_SOURCE_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT))
 +        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 +#endif
 +#endif /* BLUETOOTH_APTX_SUPPORT */
++#endif
++
++#ifdef __TIZEN_BT_6__
+     if (!a2dp_endpoint_to_a2dp_codec(path))
+         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++#endif
  
      if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
          const char *xml = ENDPOINT_INTROSPECT_XML;
          r = endpoint_clear_configuration(c, m, userdata);
      else if (dbus_message_is_method_call(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "Release"))
          r = endpoint_release(c, m, userdata);
++#ifndef __TIZEN_BT_6__
 +#ifdef __TIZEN_BT__
 +    else if (dbus_message_is_method_call(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SuspendMedia"))
 +        endpoint_suspend_media(c, m, userdata);
 +#endif
++#endif
      else
          return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  
      return DBUS_HANDLER_RESULT_HANDLED;
  }
  
++#ifndef __TIZEN_BT_6__
 +static void endpoint_init(pa_bluetooth_discovery *y, pa_bluetooth_profile_t profile) {
 +    static const DBusObjectPathVTable vtable_endpoint = {
 +        .message_function = endpoint_handler,
 +    };
 +
 +    pa_assert(y);
 +
 +    switch(profile) {
 +        case PA_BLUETOOTH_PROFILE_A2DP_SINK:
 +            pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_SOURCE_ENDPOINT,
 +                                                              &vtable_endpoint, y));
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +            pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_APTX_SOURCE_ENDPOINT,
 +                                                              &vtable_endpoint, y));
 +#endif
 +            break;
 +        case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
 +            pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_SINK_ENDPOINT,
 +                                                              &vtable_endpoint, y));
 +#ifdef TIZEN_BT_A2DP_MULTISTREAM
 +            pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_SINK_ENDPOINT2,
 +                                                            &vtable_endpoint, y));
 +#endif
 +            break;
 +        default:
 +            pa_assert_not_reached();
 +            break;
 +    }
 +}
++#else
+ static void endpoint_init(pa_bluetooth_discovery *y, const char *endpoint) {
+     static const DBusObjectPathVTable vtable_endpoint = {
+         .message_function = endpoint_handler,
+     };
+     pa_assert(y);
+     pa_assert(endpoint);
+     pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), endpoint,
+                                                       &vtable_endpoint, y));
+ }
++#endif
  
++#ifndef __TIZEN_BT_6__
 +static void endpoint_done(pa_bluetooth_discovery *y, pa_bluetooth_profile_t profile) {
 +    pa_assert(y);
 +
 +    switch(profile) {
 +        case PA_BLUETOOTH_PROFILE_A2DP_SINK:
 +            dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_SOURCE_ENDPOINT);
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +            dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_APTX_SOURCE_ENDPOINT);
 +#endif
 +            break;
 +        case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
 +            dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_SINK_ENDPOINT);
 +#ifdef TIZEN_BT_A2DP_MULTISTREAM
 +            dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_SINK_ENDPOINT2);
 +            break;
 +#endif
 +        default:
 +            pa_assert_not_reached();
 +            break;
 +    }
 +}
++#else
+ static void endpoint_done(pa_bluetooth_discovery *y, const char *endpoint) {
+     pa_assert(y);
+     pa_assert(endpoint);
+     dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), endpoint);
+ }
++#endif
  
  pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backend) {
      pa_bluetooth_discovery *y;
      DBusError err;
      DBusConnection *conn;
++#ifdef __TIZEN_BT_6__
 +    unsigned i;
++#else
+     unsigned i, count;
+     const pa_a2dp_codec *a2dp_codec;
+     char *endpoint;
++#endif
  
      y = pa_xnew0(pa_bluetooth_discovery, 1);
      PA_REFCNT_INIT(y);
      }
      y->matches_added = true;
  
++#ifdef __TIZEN_BT_6__
+     count = pa_bluetooth_a2dp_codec_count();
+     for (i = 0; i < count; i++) {
+         a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
+         endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
+         endpoint_init(y, endpoint);
+         pa_xfree(endpoint);
+         endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name);
+         endpoint_init(y, endpoint);
+         pa_xfree(endpoint);
+     }
++#else
 +    endpoint_init(y, PA_BLUETOOTH_PROFILE_A2DP_SINK);
 +    endpoint_init(y, PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
++#endif
 +
 +#ifndef __TIZEN_BT__
 +    y->hf_audio_agent = hf_audio_agent_init(c);
 +#endif
  
      get_managed_objects(y);
  
@@@ -2153,8 -1729,18 +2475,23 @@@ void pa_bluetooth_discovery_unref(pa_bl
          if (y->filter_added)
              dbus_connection_remove_filter(pa_dbus_connection_get(y->connection), filter_cb, y);
  
++#ifdef __TIZEN_BT_6__
+         count = pa_bluetooth_a2dp_codec_count();
+         for (i = 0; i < count; i++) {
+             a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
+             endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name);
+             endpoint_done(y, endpoint);
+             pa_xfree(endpoint);
+             endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name);
+             endpoint_done(y, endpoint);
+             pa_xfree(endpoint);
+         }
++#else
 +        endpoint_done(y, PA_BLUETOOTH_PROFILE_A2DP_SINK);
 +        endpoint_done(y, PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
++#endif
  
          pa_dbus_connection_unref(y->connection);
      }
@@@ -44,10 -47,8 +54,11 @@@ typedef struct pa_bluetooth_backend pa_
  
  typedef enum pa_bluetooth_hook {
      PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED,          /* Call data: pa_bluetooth_device */
+     PA_BLUETOOTH_HOOK_DEVICE_UNLINK,                      /* Call data: pa_bluetooth_device */
      PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED,            /* Call data: pa_bluetooth_transport */
 +#ifdef __TIZEN_BT__
 +    PA_BLUETOOTH_HOOK_SCO_STATE_CHANGED,            /* Call data: pa_bluetooth_transport */
 +#endif
      PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED,  /* Call data: pa_bluetooth_transport */
      PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED,     /* Call data: pa_bluetooth_transport */
      PA_BLUETOOTH_HOOK_MAX
@@@ -88,13 -86,8 +86,12 @@@ static pa_hook_result_t source_put_hook
          return PA_HOOK_OK;
  
      if (u->enable_a2dp_source && pa_streq(s, "a2dp_source"))
 +#ifdef __TIZEN__
 +        role = "media";
 +#else
          role = "music";
-     /* TODO: remove hfgw when we remove BlueZ 4 support */
-     else if (u->enable_ag && (pa_streq(s, "hfgw") || pa_streq(s, "headset_audio_gateway")))
 +#endif
+     else if (u->enable_ag && pa_streq(s, "headset_audio_gateway"))
          role = "phone";
      else {
          pa_log_debug("Profile %s cannot be selected for loopback", s);
@@@ -25,7 -26,6 +26,9 @@@
  #include <errno.h>
  
  #include <arpa/inet.h>
++#ifndef __TIZEN_BT_6__
 +#include <sbc/sbc.h>
++#endif
  
  #include <pulse/rtclock.h>
  #include <pulse/timeval.h>
  #include <pulsecore/thread-mq.h>
  #include <pulsecore/time-smoother.h>
  
 +#ifdef __TIZEN_BT__
 +#include <pulsecore/sink.h>
 +#include <pulsecore/namereg.h>
 +#include <dirent.h>
 +#include <dlfcn.h>
 +#endif
 +
  #include "a2dp-codecs.h"
+ #include "a2dp-codec-util.h"
  #include "bluez5-util.h"
- #include "module-bluez5-device-symdef.h"
++#ifndef __TIZEN_BT_6__
 +#include "rtp.h"
++#endif
 +
 +#ifdef BLUETOOTH_APTX_SUPPORT
 +#include <dlfcn.h>
 +#endif
  
  PA_MODULE_AUTHOR("João Paulo Rechi Vita");
  PA_MODULE_DESCRIPTION("BlueZ 5 Bluetooth audio sink and source");
@@@ -69,15 -57,12 +74,23 @@@ PA_MODULE_LOAD_ONCE(false)
  PA_MODULE_USAGE("path=<device object path>"
                  "autodetect_mtu=<boolean>");
  
++#ifndef __TIZEN_BT_6__
 +#define MAX_PLAYBACK_CATCH_UP_USEC (100 * PA_USEC_PER_MSEC)
++#endif
  #define FIXED_LATENCY_PLAYBACK_A2DP (25 * PA_USEC_PER_MSEC)
++#ifdef __TIZEN_BT_6__
+ #define FIXED_LATENCY_PLAYBACK_SCO  (25 * PA_USEC_PER_MSEC)
++#else
 +#define FIXED_LATENCY_PLAYBACK_SCO (125 * PA_USEC_PER_MSEC)
++#endif
  #define FIXED_LATENCY_RECORD_A2DP   (25 * PA_USEC_PER_MSEC)
  #define FIXED_LATENCY_RECORD_SCO    (25 * PA_USEC_PER_MSEC)
  
++#ifndef __TIZEN_BT_6__
 +#define BITPOOL_DEC_LIMIT 32
 +#define BITPOOL_DEC_STEP 5
  #define HSP_MAX_GAIN 15
++#endif
  
  static const char* const valid_modargs[] = {
      "path",
@@@ -166,15 -131,18 +180,27 @@@ struct userdata 
      pa_usec_t started_at;
      pa_smoother *read_smoother;
      pa_memchunk write_memchunk;
 +    pa_sample_spec sample_spec;
 +    struct sbc_info sbc_info;
 +
 +#ifdef __TIZEN_BT__
 +    pa_modargs *modargs;
 +    struct pa_bluetooth_vendor_codec_ops *selected_ops;
 +    pa_proplist *vendor_codec_list;
 +    bool is_aptx_supported;
 +#endif
+     const pa_a2dp_codec *a2dp_codec;
+     void *encoder_info;
+     pa_sample_spec encoder_sample_spec;
+     void *encoder_buffer;                        /* Codec transfer buffer */
+     size_t encoder_buffer_size;                  /* Size of the buffer */
+     void *decoder_info;
+     pa_sample_spec decoder_sample_spec;
+     void *decoder_buffer;                        /* Codec transfer buffer */
+     size_t decoder_buffer_size;                  /* Size of the buffer */
  };
  
  typedef enum pa_bluetooth_form_factor {
@@@ -397,7 -376,7 +434,11 @@@ static int sco_process_push(struct user
       * issues in our Bluetooth adapter. In these cases, in order to avoid
       * an assertion failure due to unaligned data, just discard the whole
       * packet */
++#ifdef __TIZEN_BT_6__
+     if (!pa_frame_aligned(l, &u->decoder_sample_spec)) {
++#else
 +    if (!pa_frame_aligned(l, &u->sample_spec)) {
++#endif
          pa_log_warn("SCO packet received of unaligned size: %zu", l);
          pa_memblock_unref(memchunk.memblock);
          return -1;
          tstamp = pa_rtclock_now();
      }
  
++#ifdef __TIZEN_BT_6__
+     pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->decoder_sample_spec));
++#else
 +    pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->sample_spec));
++#endif
      pa_smoother_resume(u->read_smoother, tstamp, true);
  
      pa_source_post(u->source, &memchunk);
  }
  
  /* Run from IO thread */
++#ifdef __TIZEN_BT_6__
+ static void a2dp_prepare_encoder_buffer(struct userdata *u) {
+     pa_assert(u);
+     if (u->encoder_buffer_size < u->write_link_mtu) {
+         pa_xfree(u->encoder_buffer);
+         u->encoder_buffer = pa_xmalloc(u->write_link_mtu);
+     }
+     /* Encoder buffer cannot be larger then link MTU, otherwise
+      * encode method would produce larger packets then link MTU */
+     u->encoder_buffer_size = u->write_link_mtu;
+ }
++#else
 +static void a2dp_prepare_buffer(struct userdata *u) {
 +    size_t min_buffer_size = PA_MAX(u->read_link_mtu, u->write_link_mtu);
 +
 +    pa_assert(u);
 +
 +    if (u->sbc_info.buffer_size >= min_buffer_size)
 +        return;
 +
 +    u->sbc_info.buffer_size = 2 * min_buffer_size;
 +    pa_xfree(u->sbc_info.buffer);
 +    u->sbc_info.buffer = pa_xmalloc(u->sbc_info.buffer_size);
 +}
++#endif
+ /* Run from IO thread */
+ static void a2dp_prepare_decoder_buffer(struct userdata *u) {
+     pa_assert(u);
+     if (u->decoder_buffer_size < u->read_link_mtu) {
+         pa_xfree(u->decoder_buffer);
+         u->decoder_buffer = pa_xmalloc(u->read_link_mtu);
+     }
+     /* Decoder buffer cannot be larger then link MTU, otherwise
+      * decode method would produce larger output then read_block_size */
+     u->decoder_buffer_size = u->read_link_mtu;
+ }
+ /* Run from IO thread */
+ static int a2dp_write_buffer(struct userdata *u, size_t nbytes) {
+     int ret = 0;
+     /* Encoder function of A2DP codec may provide empty buffer, in this case do
+      * not post any empty buffer via A2DP socket. It may be because of codec
+      * internal state, e.g. encoder is waiting for more samples so it can
+      * provide encoded data. */
+     if (PA_UNLIKELY(!nbytes)) {
+         u->write_index += (uint64_t) u->write_memchunk.length;
+         pa_memblock_unref(u->write_memchunk.memblock);
+         pa_memchunk_reset(&u->write_memchunk);
+         return 0;
+     }
+     for (;;) {
+         ssize_t l;
+         l = pa_write(u->stream_fd, u->encoder_buffer, nbytes, &u->stream_write_type);
+         pa_assert(l != 0);
+         if (l < 0) {
+             if (errno == EINTR)
+                 /* Retry right away if we got interrupted */
+                 continue;
+             else if (errno == EAGAIN) {
+                 /* Hmm, apparently the socket was not writable, give up for now */
+                 pa_log_debug("Got EAGAIN on write() after POLLOUT, probably there is a temporary connection loss.");
+                 break;
+             }
+             pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno));
+             ret = -1;
+             break;
+         }
+         pa_assert((size_t) l <= nbytes);
+         if ((size_t) l != nbytes) {
+             pa_log_warn("Wrote memory block to socket only partially! %llu written, wanted to write %llu.",
+                         (unsigned long long) l,
+                         (unsigned long long) nbytes);
+             ret = -1;
+             break;
+         }
+         u->write_index += (uint64_t) u->write_memchunk.length;
+         pa_memblock_unref(u->write_memchunk.memblock);
+         pa_memchunk_reset(&u->write_memchunk);
+         ret = 1;
+         break;
+     }
+     return ret;
+ }
  
  /* Run from IO thread */
  static int a2dp_process_render(struct userdata *u) {
-     struct rtp_payload *payload;
++#ifdef __TIZEN_BT_6__
+     const uint8_t *ptr;
+     size_t processed;
+     size_t length;
+     pa_assert(u);
+     pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK);
+     pa_assert(u->sink);
+     pa_assert(u->a2dp_codec);
+     /* First, render some data */
+     if (!u->write_memchunk.memblock)
+         pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
+     pa_assert(u->write_memchunk.length == u->write_block_size);
+     a2dp_prepare_encoder_buffer(u);
+     /* Try to create a packet of the full MTU */
+     ptr = (const uint8_t *) pa_memblock_acquire_chunk(&u->write_memchunk);
+     length = u->a2dp_codec->encode_buffer(u->encoder_info, u->write_index / pa_frame_size(&u->encoder_sample_spec), ptr, u->write_memchunk.length, u->encoder_buffer, u->encoder_buffer_size, &processed);
+     pa_memblock_release(u->write_memchunk.memblock);
+     if (processed != u->write_memchunk.length) {
+         pa_log_error("Encoding error");
+         return -1;
+     }
+     return a2dp_write_buffer(u, length);
++#else
 +    struct sbc_info *sbc_info;
 +    struct rtp_header *header;
-     payload = (struct rtp_payload*) ((uint8_t*) sbc_info->buffer + sizeof(*header));
++    struct rtp_sbc_payload *payload;
 +    size_t nbytes;
 +    void *d;
 +    const void *p;
 +    size_t to_write, to_encode;
 +    unsigned frame_count;
 +    int ret = 0;
 +
 +    pa_assert(u);
 +    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK);
 +    pa_assert(u->sink);
 +
 +    /* First, render some data */
 +    if (!u->write_memchunk.memblock)
 +        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
 +
 +    pa_assert(u->write_memchunk.length == u->write_block_size);
 +
 +    a2dp_prepare_buffer(u);
 +
 +    sbc_info = &u->sbc_info;
 +    header = sbc_info->buffer;
++    payload = (struct rtp_sbc_payload*) ((uint8_t*) sbc_info->buffer + sizeof(*header));
 +
 +    frame_count = 0;
 +
 +    /* Try to create a packet of the full MTU */
 +
 +    p = (const uint8_t *) pa_memblock_acquire_chunk(&u->write_memchunk);
 +    to_encode = u->write_memchunk.length;
 +
 +    d = (uint8_t*) sbc_info->buffer + sizeof(*header) + sizeof(*payload);
 +    to_write = sbc_info->buffer_size - sizeof(*header) - sizeof(*payload);
 +
 +    while (PA_LIKELY(to_encode > 0 && to_write > 0)) {
 +        ssize_t written;
 +        ssize_t encoded;
 +
 +        encoded = sbc_encode(&sbc_info->sbc,
 +                             p, to_encode,
 +                             d, to_write,
 +                             &written);
 +
 +        if (PA_UNLIKELY(encoded <= 0)) {
 +            pa_log_error("SBC encoding error (%li)", (long) encoded);
 +            pa_memblock_release(u->write_memchunk.memblock);
 +            return -1;
 +        }
 +
 +        pa_assert_fp((size_t) encoded <= to_encode);
 +        pa_assert_fp((size_t) encoded == sbc_info->codesize);
 +
 +        pa_assert_fp((size_t) written <= to_write);
 +        pa_assert_fp((size_t) written == sbc_info->frame_length);
 +
 +        p = (const uint8_t*) p + encoded;
 +        to_encode -= encoded;
 +
 +        d = (uint8_t*) d + written;
 +        to_write -= written;
 +
 +        frame_count++;
 +    }
 +
 +    pa_memblock_release(u->write_memchunk.memblock);
 +
 +    pa_assert(to_encode == 0);
 +
 +    PA_ONCE_BEGIN {
 +        pa_log_debug("Using SBC encoder implementation: %s", pa_strnull(sbc_get_implementation_info(&sbc_info->sbc)));
 +    } PA_ONCE_END;
 +
 +    /* write it to the fifo */
 +    memset(sbc_info->buffer, 0, sizeof(*header) + sizeof(*payload));
 +    header->v = 2;
 +    header->pt = 1;
 +    header->sequence_number = htons(sbc_info->seq_num++);
 +    header->timestamp = htonl(u->write_index / pa_frame_size(&u->sample_spec));
 +    header->ssrc = htonl(1);
 +    payload->frame_count = frame_count;
 +
 +    nbytes = (uint8_t*) d - (uint8_t*) sbc_info->buffer;
 +
 +    for (;;) {
 +        ssize_t l;
 +
 +        l = pa_write(u->stream_fd, sbc_info->buffer, nbytes, &u->stream_write_type);
 +
 +        pa_assert(l != 0);
 +
 +        if (l < 0) {
 +
 +            if (errno == EINTR)
 +                /* Retry right away if we got interrupted */
 +                continue;
 +
 +            else if (errno == EAGAIN)
 +                /* Hmm, apparently the socket was not writable, give up for now */
 +                break;
 +
 +            pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno));
 +            ret = -1;
 +            break;
 +        }
 +
 +        pa_assert((size_t) l <= nbytes);
 +
 +        if ((size_t) l != nbytes) {
 +            pa_log_warn("Wrote memory block to socket only partially! %llu written, wanted to write %llu.",
 +                        (unsigned long long) l,
 +                        (unsigned long long) nbytes);
 +            ret = -1;
 +            break;
 +        }
 +
 +        u->write_index += (uint64_t) u->write_memchunk.length;
 +        pa_memblock_unref(u->write_memchunk.memblock);
 +        pa_memchunk_reset(&u->write_memchunk);
 +
 +        ret = 1;
 +
 +        break;
 +    }
 +
 +    return ret;
++#endif
  }
  
 +#ifdef __TIZEN_BT__
 +/* Run from IO thread */
 +static int a2dp_process_null_render(struct userdata *u) {
 +    pa_assert(u);
 +    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK);
 +    pa_assert(u->sink);
 +
 +    /* First, render some data */
 +    if (!u->write_memchunk.memblock)
 +        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
 +
 +    pa_assert(u->write_memchunk.length == u->write_block_size);
 +
 +    u->write_index += (uint64_t) u->write_memchunk.length;
 +    pa_memblock_unref(u->write_memchunk.memblock);
 +    pa_memchunk_reset(&u->write_memchunk);
 +
 +    return 1;
 +}
 +#endif
 +
  /* Run from IO thread */
  static int a2dp_process_push(struct userdata *u) {
-         struct rtp_payload *payload;
++#ifdef __TIZEN_BT_6__
+     int ret = 0;
+     pa_memchunk memchunk;
+     pa_assert(u);
+     pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
+     pa_assert(u->source);
+     pa_assert(u->read_smoother);
+     pa_assert(u->a2dp_codec);
+     memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
+     memchunk.index = memchunk.length = 0;
+     a2dp_prepare_decoder_buffer(u);
+     for (;;) {
+         bool found_tstamp = false;
+         pa_usec_t tstamp;
+         uint8_t *ptr;
+         ssize_t l;
+         size_t processed;
+         l = pa_read(u->stream_fd, u->decoder_buffer, u->decoder_buffer_size, &u->stream_write_type);
+         if (l <= 0) {
+             if (l < 0 && errno == EINTR)
+                 /* Retry right away if we got interrupted */
+                 continue;
+             else if (l < 0 && errno == EAGAIN)
+                 /* Hmm, apparently the socket was not readable, give up for now. */
+                 break;
+             pa_log_error("Failed to read data from socket: %s", l < 0 ? pa_cstrerror(errno) : "EOF");
+             ret = -1;
+             break;
+         }
+         pa_assert((size_t) l <= u->decoder_buffer_size);
+         /* TODO: get timestamp from rtp */
+         if (!found_tstamp) {
+             /* pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!"); */
+             tstamp = pa_rtclock_now();
+         }
+         ptr = pa_memblock_acquire(memchunk.memblock);
+         memchunk.length = pa_memblock_get_length(memchunk.memblock);
+         memchunk.length = u->a2dp_codec->decode_buffer(u->decoder_info, u->decoder_buffer, l, ptr, memchunk.length, &processed);
+         pa_memblock_release(memchunk.memblock);
+         if (processed != (size_t) l) {
+             pa_log_error("Decoding error");
+             ret = -1;
+             break;
+         }
+         u->read_index += (uint64_t) memchunk.length;
+         pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->decoder_sample_spec));
+         pa_smoother_resume(u->read_smoother, tstamp, true);
+         /* Decoding of A2DP codec data may result in empty buffer, in this case
+          * do not post empty audio samples. It may happen due to algorithmic
+          * delay of audio codec. */
+         if (PA_LIKELY(memchunk.length))
+             pa_source_post(u->source, &memchunk);
+         ret = l;
+         break;
+     }
+     pa_memblock_unref(memchunk.memblock);
+     return ret;
++#else
 +    int ret = 0;
 +    pa_memchunk memchunk;
 +
 +    pa_assert(u);
 +    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
 +    pa_assert(u->source);
 +    pa_assert(u->read_smoother);
 +
 +    memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
 +    memchunk.index = memchunk.length = 0;
 +
 +    for (;;) {
 +        bool found_tstamp = false;
 +        pa_usec_t tstamp;
 +        struct sbc_info *sbc_info;
 +        struct rtp_header *header;
-         payload = (struct rtp_payload*) ((uint8_t*) sbc_info->buffer + sizeof(*header));
++        struct rtp_sbc_payload *payload;
 +        const void *p;
 +        void *d;
 +        ssize_t l;
 +        size_t to_write, to_decode;
 +        size_t total_written = 0;
 +
 +        a2dp_prepare_buffer(u);
 +
 +        sbc_info = &u->sbc_info;
 +        header = sbc_info->buffer;
-         (u->read_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
++        payload = (struct rtp_sbc_payload*) ((uint8_t*) sbc_info->buffer + sizeof(*header));
 +
 +        l = pa_read(u->stream_fd, sbc_info->buffer, sbc_info->buffer_size, &u->stream_write_type);
 +
 +        if (l <= 0) {
 +
 +            if (l < 0 && errno == EINTR)
 +                /* Retry right away if we got interrupted */
 +                continue;
 +
 +            else if (l < 0 && errno == EAGAIN)
 +                /* Hmm, apparently the socket was not readable, give up for now. */
 +                break;
 +
 +            pa_log_error("Failed to read data from socket: %s", l < 0 ? pa_cstrerror(errno) : "EOF");
 +            ret = -1;
 +            break;
 +        }
 +
 +        pa_assert((size_t) l <= sbc_info->buffer_size);
 +
 +        /* TODO: get timestamp from rtp */
 +        if (!found_tstamp) {
 +            /* pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!"); */
 +            tstamp = pa_rtclock_now();
 +        }
 +
 +        p = (uint8_t*) sbc_info->buffer + sizeof(*header) + sizeof(*payload);
 +        to_decode = l - sizeof(*header) - sizeof(*payload);
 +
 +        d = pa_memblock_acquire(memchunk.memblock);
 +        to_write = memchunk.length = pa_memblock_get_length(memchunk.memblock);
 +
 +        while (PA_LIKELY(to_decode > 0)) {
 +            size_t written;
 +            ssize_t decoded;
 +
 +            decoded = sbc_decode(&sbc_info->sbc,
 +                                 p, to_decode,
 +                                 d, to_write,
 +                                 &written);
 +
 +            if (PA_UNLIKELY(decoded <= 0)) {
 +                pa_log_error("SBC decoding error (%li)", (long) decoded);
 +                pa_memblock_release(memchunk.memblock);
 +                pa_memblock_unref(memchunk.memblock);
 +                return 0;
 +            }
 +
 +            total_written += written;
 +
 +            /* Reset frame length, it can be changed due to bitpool change */
 +            sbc_info->frame_length = sbc_get_frame_length(&sbc_info->sbc);
 +
 +            pa_assert_fp((size_t) decoded <= to_decode);
 +            pa_assert_fp((size_t) decoded == sbc_info->frame_length);
 +
 +            pa_assert_fp((size_t) written == sbc_info->codesize);
 +
 +            p = (const uint8_t*) p + decoded;
 +            to_decode -= decoded;
 +
 +            d = (uint8_t*) d + written;
 +            to_write -= written;
 +        }
 +
 +        u->read_index += (uint64_t) total_written;
 +        pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->sample_spec));
 +        pa_smoother_resume(u->read_smoother, tstamp, true);
 +
 +        memchunk.length -= to_write;
 +
 +        pa_memblock_release(memchunk.memblock);
 +
 +        pa_source_post(u->source, &memchunk);
 +
 +        ret = l;
 +        break;
 +    }
 +
 +    pa_memblock_unref(memchunk.memblock);
 +
 +    return ret;
++#endif
 +}
 +
++#ifndef __TIZEN_BT_6__
 +/* Run from I/O thread */
 +static void a2dp_set_bitpool(struct userdata *u, uint8_t bitpool) {
 +    struct sbc_info *sbc_info;
 +
 +    pa_assert(u);
 +
 +    sbc_info = &u->sbc_info;
 +
 +    if (sbc_info->sbc.bitpool == bitpool)
 +        return;
 +
 +    if (bitpool > sbc_info->max_bitpool)
 +        bitpool = sbc_info->max_bitpool;
 +    else if (bitpool < sbc_info->min_bitpool)
 +        bitpool = sbc_info->min_bitpool;
 +
 +    sbc_info->sbc.bitpool = bitpool;
 +
 +    sbc_info->codesize = sbc_get_codesize(&sbc_info->sbc);
 +    sbc_info->frame_length = sbc_get_frame_length(&sbc_info->sbc);
 +
 +    pa_log_debug("Bitpool has changed to %u", sbc_info->sbc.bitpool);
 +
 +    u->read_block_size =
-         (u->write_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
++        (u->read_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_sbc_payload))
 +        / sbc_info->frame_length * sbc_info->codesize;
 +
 +    u->write_block_size =
++        (u->write_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_sbc_payload))
 +        / sbc_info->frame_length * sbc_info->codesize;
 +
 +    pa_sink_set_max_request_within_thread(u->sink, u->write_block_size);
 +    pa_sink_set_fixed_latency_within_thread(u->sink,
 +            FIXED_LATENCY_PLAYBACK_A2DP + pa_bytes_to_usec(u->write_block_size, &u->sample_spec));
 +}
 +
 +/* Run from I/O thread */
 +static void a2dp_reduce_bitpool(struct userdata *u) {
 +    struct sbc_info *sbc_info;
 +    uint8_t bitpool;
 +
 +    pa_assert(u);
 +
 +    sbc_info = &u->sbc_info;
 +
 +    /* Check if bitpool is already at its limit */
 +    if (sbc_info->sbc.bitpool <= BITPOOL_DEC_LIMIT)
 +        return;
 +
 +    bitpool = sbc_info->sbc.bitpool - BITPOOL_DEC_STEP;
 +
 +    if (bitpool < BITPOOL_DEC_LIMIT)
 +        bitpool = BITPOOL_DEC_LIMIT;
 +
 +    a2dp_set_bitpool(u, bitpool);
  }
++#endif
+ static void update_sink_buffer_size(struct userdata *u) {
+     int old_bufsize;
+     socklen_t len = sizeof(int);
+     int ret;
+     ret = getsockopt(u->stream_fd, SOL_SOCKET, SO_SNDBUF, &old_bufsize, &len);
+     if (ret == -1) {
+         pa_log_warn("Changing bluetooth buffer size: Failed to getsockopt(SO_SNDBUF): %s", pa_cstrerror(errno));
+     } else {
+         int new_bufsize;
+         /* Set send buffer size as small as possible. The minimum value is 1024 according to the
+          * socket man page. The data is written to the socket in chunks of write_block_size, so
+          * there should at least be room for two chunks in the buffer. Generally, write_block_size
+          * is larger than 512. If not, use the next multiple of write_block_size which is larger
+          * than 1024. */
+         new_bufsize = 2 * u->write_block_size;
+         if (new_bufsize < 1024)
+             new_bufsize = (1024 / u->write_block_size + 1) * u->write_block_size;
+         /* The kernel internally doubles the buffer size that was set by setsockopt and getsockopt
+          * returns the doubled value. */
+         if (new_bufsize != old_bufsize / 2) {
+             ret = setsockopt(u->stream_fd, SOL_SOCKET, SO_SNDBUF, &new_bufsize, len);
+             if (ret == -1)
+                 pa_log_warn("Changing bluetooth buffer size: Failed to change from %d to %d: %s", old_bufsize / 2, new_bufsize, pa_cstrerror(errno));
+             else
+                 pa_log_info("Changing bluetooth buffer size: Changed from %d to %d", old_bufsize / 2, new_bufsize);
+         }
+     }
+ }
  
  static void teardown_stream(struct userdata *u) {
      if (u->rtpoll_item) {
@@@ -803,13 -680,18 +1084,24 @@@ static int transport_acquire(struct use
      if (u->stream_fd < 0)
          return u->stream_fd;
  
+     /* transport_acquired must be set before calling
+      * pa_bluetooth_transport_set_state() */
      u->transport_acquired = true;
 +
 +#ifdef __TIZEN_BT__
 +    u->transport_suspended_by_remote = false;
 +#endif
      pa_log_info("Transport %s acquired: fd %d", u->transport->path, u->stream_fd);
  
++#ifdef __TIZEN_BT_6__
+     if (u->transport->state == PA_BLUETOOTH_TRANSPORT_STATE_IDLE) {
+         if (pa_thread_mq_get() != NULL)
+             pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->msg), BLUETOOTH_MESSAGE_SET_TRANSPORT_PLAYING, NULL, 0, NULL, NULL);
+         else
+             pa_bluetooth_transport_set_state(u->transport, PA_BLUETOOTH_TRANSPORT_STATE_PLAYING);
+     }
++#endif
      return 0;
  }
  
@@@ -856,41 -746,26 +1166,59 @@@ static void transport_config_mtu(struc
          }
  
          if (!pa_frame_aligned(u->write_block_size, &u->sink->sample_spec)) {
 +#ifdef __TIZEN__
 +            pa_log_debug("Got invalid write MTU: %zu, rounding down", u->write_block_size);
 +#else
              pa_log_debug("Got invalid write MTU: %lu, rounding down", u->write_block_size);
 +#endif
              u->write_block_size = pa_frame_align(u->write_block_size, &u->sink->sample_spec);
          }
 +#ifdef __TIZEN_BT__
 +    } else if(u->sbc_info.sbc_initialized) {
 +#else
      } else {
-             (u->read_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
 +#endif
++#ifdef __TIZEN_BT_6__
+         pa_assert(u->a2dp_codec);
+         if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) {
+             u->write_block_size = u->a2dp_codec->get_write_block_size(u->encoder_info, u->write_link_mtu);
+         } else {
+             u->read_block_size = u->a2dp_codec->get_read_block_size(u->decoder_info, u->read_link_mtu);
+         }
+     }
+     if (u->sink)
+         handle_sink_block_size_change(u);
+     if (u->source)
+         pa_source_set_fixed_latency_within_thread(u->source,
+                                                   (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE ?
+                                                    FIXED_LATENCY_RECORD_A2DP : FIXED_LATENCY_RECORD_SCO) +
+                                                   pa_bytes_to_usec(u->read_block_size, &u->decoder_sample_spec));
++#else
 +        u->read_block_size =
-             (u->write_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
++            (u->read_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_sbc_payload))
 +            / u->sbc_info.frame_length * u->sbc_info.codesize;
 +
 +        u->write_block_size =
++            (u->write_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_sbc_payload))
 +            / u->sbc_info.frame_length * u->sbc_info.codesize;
 +    }
 +
 +    if (u->sink) {
 +        pa_sink_set_max_request_within_thread(u->sink, u->write_block_size);
 +        pa_sink_set_fixed_latency_within_thread(u->sink,
 +                                                (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK ?
 +                                                 FIXED_LATENCY_PLAYBACK_A2DP : FIXED_LATENCY_PLAYBACK_SCO) +
 +                                                pa_bytes_to_usec(u->write_block_size, &u->sample_spec));
 +    }
 +
 +    if (u->source)
 +        pa_source_set_fixed_latency_within_thread(u->source,
 +                                                  (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE ?
 +                                                   FIXED_LATENCY_RECORD_A2DP : FIXED_LATENCY_RECORD_SCO) +
 +                                                  pa_bytes_to_usec(u->read_block_size, &u->sample_spec));
++#endif
  }
  
  /* Run from I/O thread */
@@@ -904,19 -781,26 +1234,42 @@@ static int setup_stream(struct userdat
  
      pa_log_info("Transport %s resuming", u->transport->path);
  
++#ifdef __TIZEN_BT_6__
+     if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) {
+         pa_assert(u->a2dp_codec);
+         if (u->a2dp_codec->reset(u->encoder_info) < 0)
+             return -1;
+     } else if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE) {
+         pa_assert(u->a2dp_codec);
+         if (u->a2dp_codec->reset(u->decoder_info) < 0)
+             return -1;
+     }
+     transport_config_mtu(u);
+     pa_make_fd_nonblock(u->stream_fd);
+     pa_make_socket_low_delay(u->stream_fd);
+     one = 1;
+     if (setsockopt(u->stream_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)) < 0)
+         pa_log_warn("Failed to enable SO_TIMESTAMP: %s", pa_cstrerror(errno));
+     pa_log_debug("Stream properly set up, we're ready to roll!");
++#else
 +    transport_config_mtu(u);
 +
 +    pa_make_fd_nonblock(u->stream_fd);
 +    pa_make_socket_low_delay(u->stream_fd);
 +
 +    one = 1;
 +    if (setsockopt(u->stream_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)) < 0)
 +        pa_log_warn("Failed to enable SO_TIMESTAMP: %s", pa_cstrerror(errno));
 +
 +    pa_log_debug("Stream properly set up, we're ready to roll!");
 +
 +    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK)
 +        a2dp_set_bitpool(u, u->sbc_info.max_bitpool);
++#endif
  
      u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
      pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
@@@ -940,85 -826,100 +1295,179 @@@ static bool setup_transport_and_stream(
      if (transport_error < 0) {
          if (transport_error != -EAGAIN)
              return false;
-     } else
+     } else {
++#ifdef __TIZEN_BT_6__
+         if (setup_stream(u) < 0)
+             return false;
++#else
 +        setup_stream(u);
++#endif
+     }
      return true;
  }
  
  /* Run from IO thread */
  static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
++#ifdef __TIZEN_BT_6__
+     struct userdata *u = PA_SOURCE(o)->userdata;
+     pa_assert(u->source == PA_SOURCE(o));
+     pa_assert(u->transport);
+     switch (code) {
+         case PA_SOURCE_MESSAGE_GET_LATENCY: {
+             int64_t wi, ri;
+             if (u->read_smoother) {
+                 wi = pa_smoother_get(u->read_smoother, pa_rtclock_now());
+                 ri = pa_bytes_to_usec(u->read_index, &u->decoder_sample_spec);
+                 *((int64_t*) data) = u->source->thread_info.fixed_latency + wi - ri;
+             } else
+                 *((int64_t*) data) = 0;
+             return 0;
+         }
+         case PA_SOURCE_MESSAGE_SETUP_STREAM:
+             /* Skip stream setup if stream_fd has been invalidated.
+                This can occur if the stream has already been set up and
+                then immediately received POLLHUP. If the stream has
+                already been set up earlier, then this setup_stream()
+                call is redundant anyway, but currently the code
+                is such that this kind of unnecessary setup_stream()
+                calls can happen. */
+             if (u->stream_fd < 0)
+                 pa_log_debug("Skip source stream setup while closing");
+             else
+                 setup_stream(u);
+             return 0;
+     }
+     return pa_source_process_msg(o, code, data, offset, chunk);
++#else
 +    struct userdata *u = PA_SOURCE(o)->userdata;
 +    bool failed = false;
 +    int r;
 +
 +    pa_assert(u->source == PA_SOURCE(o));
 +    pa_assert(u->transport);
 +
 +    switch (code) {
 +
 +        case PA_SOURCE_MESSAGE_SET_STATE:
 +
 +            switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
 +
 +                case PA_SOURCE_SUSPENDED:
 +                    /* Ignore if transition is PA_SOURCE_INIT->PA_SOURCE_SUSPENDED */
 +                    if (!PA_SOURCE_IS_OPENED(u->source->thread_info.state))
 +                        break;
 +
 +                    /* Stop the device if the sink is suspended as well */
 +                    if (!u->sink || u->sink->state == PA_SINK_SUSPENDED)
 +                        transport_release(u);
 +
 +                    if (u->read_smoother)
 +                        pa_smoother_pause(u->read_smoother, pa_rtclock_now());
 +
 +                    break;
 +
 +                case PA_SOURCE_IDLE:
 +                case PA_SOURCE_RUNNING:
 +                    if (u->source->thread_info.state != PA_SOURCE_SUSPENDED)
 +                        break;
 +
 +                    /* Resume the device if the sink was suspended as well */
 +                    if (!u->sink || !PA_SINK_IS_OPENED(u->sink->thread_info.state))
 +                        failed = !setup_transport_and_stream(u);
 +
 +                    /* We don't resume the smoother here. Instead we
 +                     * wait until the first packet arrives */
 +
 +                    break;
 +
 +                case PA_SOURCE_UNLINKED:
 +                case PA_SOURCE_INIT:
 +                case PA_SOURCE_INVALID_STATE:
 +                    break;
 +            }
 +
 +            break;
 +
 +        case PA_SOURCE_MESSAGE_GET_LATENCY: {
 +            int64_t wi, ri;
 +
 +            if (u->read_smoother) {
 +                wi = pa_smoother_get(u->read_smoother, pa_rtclock_now());
 +                ri = pa_bytes_to_usec(u->read_index, &u->sample_spec);
 +
 +                *((int64_t*) data) = u->source->thread_info.fixed_latency + wi - ri;
 +            } else
 +                *((int64_t*) data) = 0;
 +
 +            return 0;
 +        }
 +
 +        case PA_SOURCE_MESSAGE_SETUP_STREAM:
 +            setup_stream(u);
 +            return 0;
 +
 +    }
 +
 +    r = pa_source_process_msg(o, code, data, offset, chunk);
 +
 +    return (r < 0 || !failed) ? r : -1;
++#endif
+ }
+ /* Called from the IO thread. */
+ static int source_set_state_in_io_thread_cb(pa_source *s, pa_source_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
+     struct userdata *u;
+     pa_assert(s);
+     pa_assert_se(u = s->userdata);
+     switch (new_state) {
+         case PA_SOURCE_SUSPENDED:
+             /* Ignore if transition is PA_SOURCE_INIT->PA_SOURCE_SUSPENDED */
+             if (!PA_SOURCE_IS_OPENED(s->thread_info.state))
+                 break;
+             /* Stop the device if the sink is suspended as well */
+             if (!u->sink || u->sink->state == PA_SINK_SUSPENDED)
+                 transport_release(u);
+             if (u->read_smoother)
+                 pa_smoother_pause(u->read_smoother, pa_rtclock_now());
+             break;
+         case PA_SOURCE_IDLE:
+         case PA_SOURCE_RUNNING:
+             if (s->thread_info.state != PA_SOURCE_SUSPENDED)
+                 break;
+             /* Resume the device if the sink was suspended as well */
+             if (!u->sink || !PA_SINK_IS_OPENED(u->sink->thread_info.state))
+                 if (!setup_transport_and_stream(u))
+                     return -1;
+             /* We don't resume the smoother here. Instead we
+              * wait until the first packet arrives */
+             break;
+         case PA_SOURCE_UNLINKED:
+         case PA_SOURCE_INIT:
+         case PA_SOURCE_INVALID_STATE:
+             break;
+     }
+     return 0;
  }
  
  /* Run from main thread */
@@@ -1049,11 -950,11 +1498,19 @@@ static void source_set_volume_cb(pa_sou
      if (volume < PA_VOLUME_NORM)
          volume++;
  
++#ifdef __TIZEN_BT_6__
+     pa_cvolume_set(&s->real_volume, u->decoder_sample_spec.channels, volume);
++#else
 +    pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume);
++#endif
  
      /* Set soft volume when in headset role */
      if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
++#ifdef __TIZEN_BT_6__
+         pa_cvolume_set(&s->soft_volume, u->decoder_sample_spec.channels, volume);
++#else
 +        pa_cvolume_set(&s->soft_volume, u->sample_spec.channels, volume);
++#endif
  
      /* If we are in the AG role, we send a command to the head set to change
       * the microphone gain. In the HS role, source and sink are swapped, so
@@@ -1074,7 -975,7 +1531,11 @@@ static int add_source(struct userdata *
      data.name = pa_sprintf_malloc("bluez_source.%s.%s", u->device->address, pa_bluetooth_profile_to_string(u->profile));
      data.namereg_fail = false;
      pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
++#ifdef __TIZEN_BT_6__
+     pa_source_new_data_set_sample_spec(&data, &u->decoder_sample_spec);
++#else
 +    pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
++#endif
      if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
          pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
  
  
  /* Run from IO thread */
  static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
++#ifdef __TIZEN_BT_6__
++    struct userdata *u = PA_SINK(o)->userdata;
++
++    pa_assert(u->sink == PA_SINK(o));
++    pa_assert(u->transport);
++
++    switch (code) {
++
++        case PA_SINK_MESSAGE_GET_LATENCY: {
++            int64_t wi = 0, ri = 0;
++
++            if (u->read_smoother) {
++                ri = pa_smoother_get(u->read_smoother, pa_rtclock_now());
++                wi = pa_bytes_to_usec(u->write_index + u->write_block_size, &u->encoder_sample_spec);
++            } else if (u->started_at) {
++                ri = pa_rtclock_now() - u->started_at;
++                wi = pa_bytes_to_usec(u->write_index, &u->encoder_sample_spec);
++            }
++
++            *((int64_t*) data) = u->sink->thread_info.fixed_latency + wi - ri;
++
++            return 0;
++        }
++
++        case PA_SINK_MESSAGE_SETUP_STREAM:
++            /* Skip stream setup if stream_fd has been invalidated.
++               This can occur if the stream has already been set up and
++               then immediately received POLLHUP. If the stream has
++               already been set up earlier, then this setup_stream()
++               call is redundant anyway, but currently the code
++               is such that this kind of unnecessary setup_stream()
++               calls can happen. */
++            if (u->stream_fd < 0)
++                pa_log_debug("Skip sink stream setup while closing");
++            else
++                setup_stream(u);
++            return 0;
++    }
++
++    return pa_sink_process_msg(o, code, data, offset, chunk);
++#else
      struct userdata *u = PA_SINK(o)->userdata;
 +    bool failed = false;
 +    int r;
  
      pa_assert(u->sink == PA_SINK(o));
      pa_assert(u->transport);
              return 0;
      }
  
 -    return pa_sink_process_msg(o, code, data, offset, chunk);
 +    r = pa_sink_process_msg(o, code, data, offset, chunk);
 +
 +    return (r < 0 || !failed) ? r : -1;
++#endif
+ }
+ /* Called from the IO thread. */
+ static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
+     struct userdata *u;
+     pa_assert(s);
+     pa_assert_se(u = s->userdata);
+     switch (new_state) {
+         case PA_SINK_SUSPENDED:
+             /* Ignore if transition is PA_SINK_INIT->PA_SINK_SUSPENDED */
+             if (!PA_SINK_IS_OPENED(s->thread_info.state))
+                 break;
+             /* Stop the device if the source is suspended as well */
+             if (!u->source || u->source->state == PA_SOURCE_SUSPENDED)
+                 /* We deliberately ignore whether stopping
+                  * actually worked. Since the stream_fd is
+                  * closed it doesn't really matter */
+                 transport_release(u);
+             break;
+         case PA_SINK_IDLE:
+         case PA_SINK_RUNNING:
+             if (s->thread_info.state != PA_SINK_SUSPENDED)
+                 break;
+             /* Resume the device if the source was suspended as well */
+             if (!u->source || !PA_SOURCE_IS_OPENED(u->source->thread_info.state))
+                 if (!setup_transport_and_stream(u))
+                     return -1;
+             break;
+         case PA_SINK_UNLINKED:
+         case PA_SINK_INIT:
+         case PA_SINK_INVALID_STATE:
+             break;
+     }
+     return 0;
  }
  
  /* Run from main thread */
@@@ -1227,11 -1134,11 +1775,19 @@@ static void sink_set_volume_cb(pa_sink 
      if (volume < PA_VOLUME_NORM)
          volume++;
  
++#ifdef __TIZEN_BT_6__
+     pa_cvolume_set(&s->real_volume, u->encoder_sample_spec.channels, volume);
++#else
 +    pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume);
++#endif
  
      /* Set soft volume when in headset role */
      if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
++#ifdef __TIZEN_BT_6__
+         pa_cvolume_set(&s->soft_volume, u->encoder_sample_spec.channels, volume);
++#else
 +        pa_cvolume_set(&s->soft_volume, u->sample_spec.channels, volume);
++#endif
  
      /* If we are in the AG role, we send a command to the head set to change
       * the speaker gain. In the HS role, source and sink are swapped, so
@@@ -1252,7 -1159,7 +1808,11 @@@ static int add_sink(struct userdata *u
      data.name = pa_sprintf_malloc("bluez_sink.%s.%s", u->device->address, pa_bluetooth_profile_to_string(u->profile));
      data.namereg_fail = false;
      pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
++#ifdef __TIZEN_BT_6__
+     pa_sink_new_data_set_sample_spec(&data, &u->encoder_sample_spec);
++#else
 +    pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
++#endif
      if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
          pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
  
  }
  
  /* Run from main thread */
- static void transport_config(struct userdata *u) {
+ static int transport_config(struct userdata *u) {
      if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
++#ifdef __TIZEN_BT_6__
+         u->encoder_sample_spec.format = PA_SAMPLE_S16LE;
+         u->encoder_sample_spec.channels = 1;
+         u->encoder_sample_spec.rate = 8000;
+         u->decoder_sample_spec.format = PA_SAMPLE_S16LE;
+         u->decoder_sample_spec.channels = 1;
+         u->decoder_sample_spec.rate = 8000;
+         return 0;
++#else
 +        u->sample_spec.format = PA_SAMPLE_S16LE;
 +        u->sample_spec.channels = 1;
 +        u->sample_spec.rate = 8000;
++              return 0;
++#endif
      } else {
-                     return;
 +        sbc_info_t *sbc_info = &u->sbc_info;
 +        a2dp_sbc_t *config;
 +        const pa_bluetooth_transport *t;
 +        a2dp_aptx_t *aptx_config;
 +
 +        pa_assert(u->transport);
 +
 +#ifdef __TIZEN_BT__
 +        if (u->is_aptx_supported) {
 +            t = u->transport;
 +            if (t->codec == A2DP_CODEC_VENDOR) {
 +                aptx_config = (a2dp_aptx_t *) t->config;
 +                if (aptx_config->vendor_id[0] == APTX_VENDOR_ID0 &&
 +                        aptx_config->vendor_id[1] == APTX_VENDOR_ID1 &&
 +                        aptx_config->vendor_id[2] == APTX_VENDOR_ID2 &&
 +                        aptx_config->vendor_id[3] == APTX_VENDOR_ID3 &&
 +                        aptx_config->codec_id[0] == APTX_CODEC_ID0 &&
 +                        aptx_config->codec_id[1] == APTX_CODEC_ID1) {
 +                    struct pa_bluetooth_vendor_codec_ops *ops = NULL;
 +                    size_t size;
 +                    pa_log("A2DP_CODEC_NON_A2DP and this is APTX Codec");
 +                    pa_proplist_get(u->vendor_codec_list, "APTX", &ops, &size);
 +                    if (ops) {
 +                        ops->transport_config(u);
 +                        u->selected_ops = ops;
 +                    } else {
 +                        pa_log_error("APTX ops is NULL");
 +                    }
-                     return;
 +                } else {
 +                    pa_log("A2DP_CODEC_NON_A2DP but this is not APTX Codec");
 +                }
 +            }
 +        }
 +#endif
 +
 +        u->sample_spec.format = PA_SAMPLE_S16LE;
 +        config = (a2dp_sbc_t *) u->transport->config;
 +
 +        if (sbc_info->sbc_initialized)
 +            sbc_reinit(&sbc_info->sbc, 0);
 +        else
 +            sbc_init(&sbc_info->sbc, 0);
 +        sbc_info->sbc_initialized = true;
 +
 +        switch (config->frequency) {
 +            case SBC_SAMPLING_FREQ_16000:
 +                sbc_info->sbc.frequency = SBC_FREQ_16000;
 +                u->sample_spec.rate = 16000U;
 +                break;
 +            case SBC_SAMPLING_FREQ_32000:
 +                sbc_info->sbc.frequency = SBC_FREQ_32000;
 +                u->sample_spec.rate = 32000U;
 +                break;
 +            case SBC_SAMPLING_FREQ_44100:
 +                sbc_info->sbc.frequency = SBC_FREQ_44100;
 +                u->sample_spec.rate = 44100U;
 +                break;
 +            case SBC_SAMPLING_FREQ_48000:
 +                sbc_info->sbc.frequency = SBC_FREQ_48000;
 +                u->sample_spec.rate = 48000U;
 +                break;
 +            default:
 +                pa_assert_not_reached();
 +        }
 +
 +        switch (config->channel_mode) {
 +            case SBC_CHANNEL_MODE_MONO:
 +                sbc_info->sbc.mode = SBC_MODE_MONO;
 +                u->sample_spec.channels = 1;
 +                break;
 +            case SBC_CHANNEL_MODE_DUAL_CHANNEL:
 +                sbc_info->sbc.mode = SBC_MODE_DUAL_CHANNEL;
 +                u->sample_spec.channels = 2;
 +                break;
 +            case SBC_CHANNEL_MODE_STEREO:
 +                sbc_info->sbc.mode = SBC_MODE_STEREO;
 +                u->sample_spec.channels = 2;
 +                break;
 +            case SBC_CHANNEL_MODE_JOINT_STEREO:
 +                sbc_info->sbc.mode = SBC_MODE_JOINT_STEREO;
 +                u->sample_spec.channels = 2;
 +                break;
 +            default:
 +                pa_assert_not_reached();
 +        }
 +
 +        switch (config->allocation_method) {
 +            case SBC_ALLOCATION_SNR:
 +                sbc_info->sbc.allocation = SBC_AM_SNR;
 +                break;
 +            case SBC_ALLOCATION_LOUDNESS:
 +                sbc_info->sbc.allocation = SBC_AM_LOUDNESS;
 +                break;
 +            default:
 +                pa_assert_not_reached();
 +        }
 +
 +        switch (config->subbands) {
 +            case SBC_SUBBANDS_4:
 +                sbc_info->sbc.subbands = SBC_SB_4;
 +                break;
 +            case SBC_SUBBANDS_8:
 +                sbc_info->sbc.subbands = SBC_SB_8;
 +                break;
 +            default:
 +                pa_assert_not_reached();
 +        }
 +
 +        switch (config->block_length) {
 +            case SBC_BLOCK_LENGTH_4:
 +                sbc_info->sbc.blocks = SBC_BLK_4;
 +                break;
 +            case SBC_BLOCK_LENGTH_8:
 +                sbc_info->sbc.blocks = SBC_BLK_8;
 +                break;
 +            case SBC_BLOCK_LENGTH_12:
 +                sbc_info->sbc.blocks = SBC_BLK_12;
 +                break;
 +            case SBC_BLOCK_LENGTH_16:
 +                sbc_info->sbc.blocks = SBC_BLK_16;
 +                break;
 +            default:
 +                pa_assert_not_reached();
 +        }
 +
 +        sbc_info->min_bitpool = config->min_bitpool;
 +        sbc_info->max_bitpool = config->max_bitpool;
 +
 +        /* Set minimum bitpool for source to get the maximum possible block_size */
 +        sbc_info->sbc.bitpool = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK ? sbc_info->max_bitpool : sbc_info->min_bitpool;
 +        sbc_info->codesize = sbc_get_codesize(&sbc_info->sbc);
 +        sbc_info->frame_length = sbc_get_frame_length(&sbc_info->sbc);
 +
 +        pa_log_info("SBC parameters: allocation=%u, subbands=%u, blocks=%u, bitpool=%u",
 +                    sbc_info->sbc.allocation, sbc_info->sbc.subbands ? 8 : 4, sbc_info->sbc.blocks, sbc_info->sbc.bitpool);
++#ifdef __TIZEN_BT_6__
+         bool is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
+         void *info;
+         pa_assert(u->transport);
+         pa_assert(!u->a2dp_codec);
+         pa_assert(!u->encoder_info);
+         pa_assert(!u->decoder_info);
+         u->a2dp_codec = u->transport->a2dp_codec;
+         pa_assert(u->a2dp_codec);
+         info = u->a2dp_codec->init(is_a2dp_sink, false, u->transport->config, u->transport->config_size, is_a2dp_sink ? &u->encoder_sample_spec : &u->decoder_sample_spec);
+         if (is_a2dp_sink)
+             u->encoder_info = info;
+         else
+             u->decoder_info = info;
+         if (!info)
+             return -1;
++#endif
+         return 0;
      }
  }
  
@@@ -1510,209 -1305,255 +2102,459 @@@ static int init_profile(struct userdat
      return r;
  }
  
+ static int write_block(struct userdata *u) {
+     int n_written;
+     if (u->write_index <= 0)
+         u->started_at = pa_rtclock_now();
+     if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) {
+         if ((n_written = a2dp_process_render(u)) < 0)
+             return -1;
+     } else {
+         if ((n_written = sco_process_render(u)) < 0)
+             return -1;
+     }
+     return n_written;
+ }
  /* I/O thread function */
  static void thread_func(void *userdata) {
++#ifndef __TIZEN_BT_6__
 +    struct userdata *u = userdata;
 +    unsigned do_write = 0;
 +    unsigned pending_read_bytes = 0;
 +    bool writable = false;
 +
 +    pa_assert(u);
 +    pa_assert(u->transport);
 +
 +    pa_log_debug("IO Thread starting up");
 +
 +    if (u->core->realtime_scheduling)
 +        pa_make_realtime(u->core->realtime_priority);
 +
 +    pa_thread_mq_install(&u->thread_mq);
 +
 +    /* Setup the stream only if the transport was already acquired */
 +    if (u->transport_acquired)
 +        setup_stream(u);
 +
 +    for (;;) {
 +        struct pollfd *pollfd;
 +        int ret;
 +        bool disable_timer = true;
 +
 +        pollfd = u->rtpoll_item ? pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL) : NULL;
 +
 +        if (pollfd && (pollfd->revents & ~(POLLOUT|POLLIN))) {
 +            pa_log_info("FD error: %s%s%s%s",
 +                        pollfd->revents & POLLERR ? "POLLERR " :"",
 +                        pollfd->revents & POLLHUP ? "POLLHUP " :"",
 +                        pollfd->revents & POLLPRI ? "POLLPRI " :"",
 +                        pollfd->revents & POLLNVAL ? "POLLNVAL " :"");
 +
 +            if (pollfd->revents & POLLHUP) {
 +                pollfd = NULL;
 +                teardown_stream(u);
 +                do_write = 0;
 +                pending_read_bytes = 0;
 +                writable = false;
 +                pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->msg), BLUETOOTH_MESSAGE_STREAM_FD_HUP, NULL, 0, NULL, NULL);
 +            } else
 +                goto fail;
 +        }
 +
 +        if (u->source && PA_SOURCE_IS_LINKED(u->source->thread_info.state)) {
 +
 +            /* We should send two blocks to the device before we expect
 +             * a response. */
 +
 +            if (u->write_index == 0 && u->read_index <= 0)
 +                do_write = 2;
 +
 +            if (pollfd && (pollfd->revents & POLLIN)) {
 +                int n_read;
 +
 +                if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
 +                    n_read = a2dp_process_push(u);
 +                else
 +                    n_read = sco_process_push(u);
 +
 +                if (n_read < 0)
 +                    goto fail;
 +
 +                if (n_read > 0) {
 +                    /* We just read something, so we are supposed to write something, too */
 +                    pending_read_bytes += n_read;
 +                    do_write += pending_read_bytes / u->write_block_size;
 +                    pending_read_bytes = pending_read_bytes % u->write_block_size;
 +                }
 +            }
 +        }
 +
 +        if (u->sink && PA_SINK_IS_LINKED(u->sink->thread_info.state)) {
 +
 +            if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
 +                pa_sink_process_rewind(u->sink, 0);
 +
 +            if (pollfd) {
 +                if (pollfd->revents & POLLOUT)
 +                    writable = true;
 +
 +                if ((!u->source || !PA_SOURCE_IS_LINKED(u->source->thread_info.state)) && do_write <= 0 && writable) {
 +                    pa_usec_t time_passed;
 +                    pa_usec_t audio_sent;
 +
 +                    /* Hmm, there is no input stream we could synchronize
 +                     * to. So let's do things by time */
 +
 +                    time_passed = pa_rtclock_now() - u->started_at;
 +                    audio_sent = pa_bytes_to_usec(u->write_index, &u->sample_spec);
 +
 +                    if (audio_sent <= time_passed) {
 +                        pa_usec_t audio_to_send = time_passed - audio_sent;
 +
 +                        /* Never try to catch up for more than 100ms */
 +                        if (u->write_index > 0 && audio_to_send > MAX_PLAYBACK_CATCH_UP_USEC) {
 +                            pa_usec_t skip_usec;
 +                            uint64_t skip_bytes;
 +
 +                            skip_usec = audio_to_send - MAX_PLAYBACK_CATCH_UP_USEC;
 +                            skip_bytes = pa_usec_to_bytes(skip_usec, &u->sample_spec);
 +
 +                            if (skip_bytes > 0) {
 +                                pa_memchunk tmp;
 +
 +                                pa_log_warn("Skipping %llu us (= %llu bytes) in audio stream",
 +                                            (unsigned long long) skip_usec,
 +                                            (unsigned long long) skip_bytes);
 +
 +                                pa_sink_render_full(u->sink, skip_bytes, &tmp);
 +                                pa_memblock_unref(tmp.memblock);
 +                                u->write_index += skip_bytes;
 +
 +                                if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK)
 +                                    a2dp_reduce_bitpool(u);
 +                            }
 +                        }
 +
 +                        do_write = 1;
 +                        pending_read_bytes = 0;
 +                    }
 +                }
 +
 +                if (writable && do_write > 0) {
 +                    int n_written = 0;
 +
 +                    if (u->write_index <= 0)
 +                        u->started_at = pa_rtclock_now();
 +#ifdef __TIZEN_BT__
 +                    if ((u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) &&
 +                                           !u->transport_suspended_by_remote) {
 +                        if(u->sbc_info.sbc_initialized) {
 +                            if ((n_written = a2dp_process_render(u)) < 0)
 +                                goto fail;
 +                        } else {
 +                            if (u->selected_ops)
 +                                if ((n_written = u->selected_ops->process_render(u)) < 0)
 +                                    goto fail;
 +                            else
 +                                goto fail;
 +                        }
 +                    } else if ((u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) &&
 +                                           u->transport_suspended_by_remote) {
 +                        if ((n_written = a2dp_process_null_render(u)) < 0)
 +                            goto fail;
 +#else
 +                    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) {
 +                        if ((n_written = a2dp_process_render(u)) < 0)
 +                            goto fail;
 +#endif
 +                    } else {
 +                        if ((n_written = sco_process_render(u)) < 0)
 +                            goto fail;
 +                    }
 +
 +                    if (n_written == 0)
 +                        pa_log("Broken kernel: we got EAGAIN on write() after POLLOUT!");
 +
 +                    do_write -= n_written;
 +                    writable = false;
 +                }
 +
 +                if ((!u->source || !PA_SOURCE_IS_LINKED(u->source->thread_info.state)) && do_write <= 0) {
 +                    pa_usec_t sleep_for;
 +                    pa_usec_t time_passed, next_write_at;
 +
 +                    if (writable) {
 +                        /* Hmm, there is no input stream we could synchronize
 +                         * to. So let's estimate when we need to wake up the latest */
 +                        time_passed = pa_rtclock_now() - u->started_at;
 +                        next_write_at = pa_bytes_to_usec(u->write_index, &u->sample_spec);
 +                        sleep_for = time_passed < next_write_at ? next_write_at - time_passed : 0;
 +                        /* pa_log("Sleeping for %lu; time passed %lu, next write at %lu", (unsigned long) sleep_for, (unsigned long) time_passed, (unsigned long)next_write_at); */
 +                    } else
 +                        /* drop stream every 500 ms */
 +                        sleep_for = PA_USEC_PER_MSEC * 500;
 +
 +                    pa_rtpoll_set_timer_relative(u->rtpoll, sleep_for);
 +                    disable_timer = false;
 +                }
 +            }
 +        }
 +
 +        if (disable_timer)
 +            pa_rtpoll_set_timer_disabled(u->rtpoll);
 +
 +        /* Hmm, nothing to do. Let's sleep */
 +        if (pollfd)
 +            pollfd->events = (short) (((u->sink && PA_SINK_IS_LINKED(u->sink->thread_info.state) && !writable) ? POLLOUT : 0) |
 +                                      (u->source && PA_SOURCE_IS_LINKED(u->source->thread_info.state) ? POLLIN : 0));
 +
 +        if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) {
 +            pa_log_debug("pa_rtpoll_run failed with: %d", ret);
 +            goto fail;
 +        }
 +        if (ret == 0) {
 +            pa_log_debug("IO thread shutdown requested, stopping cleanly");
 +            transport_release(u);
 +            goto finish;
 +        }
 +    }
++#else
+     struct userdata *u = userdata;
+     unsigned blocks_to_write = 0;
+     unsigned bytes_to_write = 0;
+     pa_assert(u);
+     pa_assert(u->transport);
+     pa_log_debug("IO Thread starting up");
+     if (u->core->realtime_scheduling)
+         pa_thread_make_realtime(u->core->realtime_priority);
+     pa_thread_mq_install(&u->thread_mq);
+     /* Setup the stream only if the transport was already acquired */
+     if (u->transport_acquired)
+         setup_stream(u);
+     for (;;) {
+         struct pollfd *pollfd;
+         int ret;
+         bool disable_timer = true;
+         bool writable = false;
+         bool have_source = u->source ? PA_SOURCE_IS_LINKED(u->source->thread_info.state) : false;
+         bool have_sink = u->sink ? PA_SINK_IS_LINKED(u->sink->thread_info.state) : false;
+         pollfd = u->rtpoll_item ? pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL) : NULL;
+         /* Check for stream error or close */
+         if (pollfd && (pollfd->revents & ~(POLLOUT|POLLIN))) {
+             pa_log_info("FD error: %s%s%s%s",
+                         pollfd->revents & POLLERR ? "POLLERR " :"",
+                         pollfd->revents & POLLHUP ? "POLLHUP " :"",
+                         pollfd->revents & POLLPRI ? "POLLPRI " :"",
+                         pollfd->revents & POLLNVAL ? "POLLNVAL " :"");
+             if (pollfd->revents & POLLHUP) {
+                 pollfd = NULL;
+                 teardown_stream(u);
+                 blocks_to_write = 0;
+                 bytes_to_write = 0;
+                 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->msg), BLUETOOTH_MESSAGE_STREAM_FD_HUP, NULL, 0, NULL, NULL);
+             } else
+                 goto fail;
+         }
+         /* If there is a pollfd, the stream is set up and we need to do something */
+         if (pollfd) {
+             /* Handle source if present */
+             if (have_source) {
+                 /* We should send two blocks to the device before we expect a response. */
+                 if (have_sink && u->write_index == 0 && u->read_index <= 0)
+                     blocks_to_write = 2;
+                 /* If we got woken up by POLLIN let's do some reading */
+                 if (pollfd->revents & POLLIN) {
+                     int n_read;
+                     if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
+                         n_read = a2dp_process_push(u);
+                     else
+                         n_read = sco_process_push(u);
+                     if (n_read < 0)
+                         goto fail;
+                     if (have_sink && n_read > 0) {
+                         /* We just read something, so we are supposed to write something, too */
+                         bytes_to_write += n_read;
+                         blocks_to_write += bytes_to_write / u->write_block_size;
+                         bytes_to_write = bytes_to_write % u->write_block_size;
+                     }
+                 }
+             }
+             /* Handle sink if present */
+             if (have_sink) {
+                 /* Process rewinds */
+                 if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+                     pa_sink_process_rewind(u->sink, 0);
+                 /* Test if the stream is writable */
+                 if (pollfd->revents & POLLOUT)
+                     writable = true;
+                 /* If we have a source, we let the source determine the timing
+                  * for the sink */
+                 if (have_source) {
+                     if (writable && blocks_to_write > 0) {
+                         int result;
+                         if ((result = write_block(u)) < 0)
+                             goto fail;
+                         blocks_to_write -= result;
+                         /* writable controls whether we set POLLOUT when polling - we set it to
+                          * false to enable POLLOUT. If there are more blocks to write, we want to
+                          * be woken up immediately when the socket becomes writable. If there
+                          * aren't currently any more blocks to write, then we'll have to wait
+                          * until we've received more data, so in that case we only want to set
+                          * POLLIN. Note that when we are woken up the next time, POLLOUT won't be
+                          * set in revents even if the socket has meanwhile become writable, which
+                          * may seem bad, but in that case we'll set POLLOUT in the subsequent
+                          * poll, and the poll will return immediately, so our writes won't be
+                          * delayed. */
+                         if (blocks_to_write > 0)
+                             writable = false;
+                     }
+                 /* There is no source, we have to use the system clock for timing */
+                 } else {
+                     bool have_written = false;
+                     pa_usec_t time_passed = 0;
+                     pa_usec_t audio_sent = 0;
+                     if (u->started_at) {
+                         time_passed = pa_rtclock_now() - u->started_at;
+                         audio_sent = pa_bytes_to_usec(u->write_index, &u->encoder_sample_spec);
+                     }
+                     /* A new block needs to be sent. */
+                     if (audio_sent <= time_passed) {
+                         size_t bytes_to_send = pa_usec_to_bytes(time_passed - audio_sent, &u->encoder_sample_spec);
+                         /* There are more than two blocks that need to be written. It seems that
+                          * the socket has not been accepting data fast enough (could be due to
+                          * hiccups in the wireless transmission). We need to discard everything
+                          * older than two block sizes to keep the latency from growing. */
+                         if (bytes_to_send > 2 * u->write_block_size) {
+                             uint64_t skip_bytes;
+                             pa_memchunk tmp;
+                             size_t mempool_max_block_size = pa_mempool_block_size_max(u->core->mempool);
+                             pa_usec_t skip_usec;
+                             skip_bytes = bytes_to_send - 2 * u->write_block_size;
+                             skip_usec = pa_bytes_to_usec(skip_bytes, &u->encoder_sample_spec);
+                             pa_log_debug("Skipping %llu us (= %llu bytes) in audio stream",
+                                         (unsigned long long) skip_usec,
+                                         (unsigned long long) skip_bytes);
+                             while (skip_bytes > 0) {
+                                 size_t bytes_to_render;
+                                 if (skip_bytes > mempool_max_block_size)
+                                     bytes_to_render = mempool_max_block_size;
+                                 else
+                                     bytes_to_render = skip_bytes;
+                                 pa_sink_render_full(u->sink, bytes_to_render, &tmp);
+                                 pa_memblock_unref(tmp.memblock);
+                                 u->write_index += bytes_to_render;
+                                 skip_bytes -= bytes_to_render;
+                             }
+                             if (u->write_index > 0 && u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) {
+                                 size_t new_write_block_size = u->a2dp_codec->reduce_encoder_bitrate(u->encoder_info, u->write_link_mtu);
+                                 if (new_write_block_size) {
+                                     u->write_block_size = new_write_block_size;
+                                     handle_sink_block_size_change(u);
+                                 }
+                             }
+                         }
+                         blocks_to_write = 1;
+                     }
+                     /* If the stream is writable, send some data if necessary */
+                     if (writable && blocks_to_write > 0) {
+                         int result;
+                         if ((result = write_block(u)) < 0)
+                             goto fail;
+                         blocks_to_write -= result;
+                         writable = false;
+                         if (result)
+                             have_written = true;
+                     }
+                     /* If nothing was written during this iteration, either the stream
+                      * is not writable or there was no write pending. Set up a timer that
+                      * will wake up the thread when the next data needs to be written. */
+                     if (!have_written) {
+                         pa_usec_t sleep_for;
+                         pa_usec_t next_write_at;
+                         if (writable) {
+                             /* There was no write pending on this iteration of the loop.
+                              * Let's estimate when we need to wake up next */
+                             next_write_at = pa_bytes_to_usec(u->write_index, &u->encoder_sample_spec);
+                             sleep_for = time_passed < next_write_at ? next_write_at - time_passed : 0;
+                             /* pa_log("Sleeping for %lu; time passed %lu, next write at %lu", (unsigned long) sleep_for, (unsigned long) time_passed, (unsigned long)next_write_at); */
+                         } else
+                             /* We could not write because the stream was not ready. Let's try
+                              * again in 500 ms and drop audio if we still can't write. The
+                              * thread will also be woken up when we can write again. */
+                             sleep_for = PA_USEC_PER_MSEC * 500;
+                         pa_rtpoll_set_timer_relative(u->rtpoll, sleep_for);
+                         disable_timer = false;
+                     }
+                 }
+             }
+             /* Set events to wake up the thread */
+             pollfd->events = (short) (((have_sink && !writable) ? POLLOUT : 0) | (have_source ? POLLIN : 0));
+         }
+         if (disable_timer)
+             pa_rtpoll_set_timer_disabled(u->rtpoll);
+         if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) {
+             pa_log_debug("pa_rtpoll_run failed with: %d", ret);
+             goto fail;
+         }
+         if (ret == 0) {
+             pa_log_debug("IO thread shutdown requested, stopping cleanly");
+             transport_release(u);
+             goto finish;
+         }
+     }
++#endif
  
  fail:
      /* If this was no regular exit from the loop we have to continue processing messages until we receive PA_MESSAGE_SHUTDOWN */
@@@ -2001,9 -1856,10 +2857,9 @@@ static pa_card_profile *create_card_pro
  
          p = PA_CARD_PROFILE_DATA(cp);
          break;
 -
      case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
          cp = pa_card_profile_new(name, _("Headset Head Unit (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
-         cp->priority = 20;
+         cp->priority = 30;
          cp->n_sinks = 1;
          cp->n_sources = 1;
          cp->max_sink_channels = 1;
@@@ -2366,7 -2157,7 +3222,11 @@@ static pa_hook_result_t transport_speak
      if (volume < PA_VOLUME_NORM)
          volume++;
  
++#ifdef __TIZEN_BT_6__
+     pa_cvolume_set(&v, u->encoder_sample_spec.channels, volume);
++#else
 +    pa_cvolume_set(&v, u->sample_spec.channels, volume);
++#endif
      if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
          pa_sink_volume_changed(u->sink, &v);
      else
@@@ -2393,7 -2184,7 +3253,11 @@@ static pa_hook_result_t transport_micro
      if (volume < PA_VOLUME_NORM)
          volume++;
  
++#ifdef __TIZEN_BT_6__
+     pa_cvolume_set(&v, u->decoder_sample_spec.channels, volume);
++#else
 +    pa_cvolume_set(&v, u->sample_spec.channels, volume);
++#endif
  
      if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
          pa_source_volume_changed(u->source, &v);
@@@ -2641,11 -2345,11 +3515,19 @@@ void pa__done(pa_module *m) 
      if (u->transport_microphone_gain_changed_slot)
          pa_hook_slot_free(u->transport_microphone_gain_changed_slot);
  
++#ifdef __TIZEN_BT_6__
+     if (u->encoder_buffer)
+         pa_xfree(u->encoder_buffer);
+     if (u->decoder_buffer)
+         pa_xfree(u->decoder_buffer);
++#else
 +    if (u->sbc_info.buffer)
 +        pa_xfree(u->sbc_info.buffer);
 +
 +    if (u->sbc_info.sbc_initialized)
 +        sbc_finish(&u->sbc_info.sbc);
++#endif
  
      if (u->msg)
          pa_xfree(u->msg);
  #include <pulsecore/module.h>
  #include <pulsecore/modargs.h>
  #include <pulsecore/shared.h>
 -
  #include "bluez5-util.h"
  
- #include "module-bluez5-discover-symdef.h"
  PA_MODULE_AUTHOR("João Paulo Rechi Vita");
  PA_MODULE_DESCRIPTION("Detect available BlueZ 5 Bluetooth audio devices and load BlueZ 5 Bluetooth audio drivers");
  PA_MODULE_VERSION(PACKAGE_VERSION);
 -PA_MODULE_LOAD_ONCE(true);
 +#ifdef __TIZEN_BT__
 +#define HAVE_BLUEZ_5_NATIVE_HEADSET
 +
 +PA_MODULE_USAGE("sco_sink=<name of sink> "
 +        "sco_source=<name of source> "
 +        "headset=ofono|native|auto"
 +);
 +#else
  PA_MODULE_USAGE(
      "headset=ofono|native|auto"
+     "autodetect_mtu=<boolean>"
  );
 +#endif
 +PA_MODULE_LOAD_ONCE(true);
  
 +#ifdef __TIZEN_BT__
 +static const char* const valid_modargs[] = {
 +    "headset",
 +    "autodetect_mtu",
 +    "sco_sink",
 +    "sco_source",
 +    NULL
 +};
 +#else
  static const char* const valid_modargs[] = {
      "headset",
      "autodetect_mtu",
@@@ -91,22 -72,10 +90,22 @@@ static pa_hook_result_t device_connecti
      if (!module_loaded && pa_bluetooth_device_any_transport_connected(d)) {
          /* a new device has been connected */
          pa_module *m;
 +#ifdef __TIZEN_BT__
 +        char *args = pa_sprintf_malloc("address=\"%s\" path=\"%s\" autodetect_mtu=%i", d->address, d->path, (int)u->autodetect_mtu);
 +#else
          char *args = pa_sprintf_malloc("path=%s autodetect_mtu=%i", d->path, (int)u->autodetect_mtu);
 +#endif
 +
 +#ifdef __TIZEN_BT__
 +        if (pa_bluetooth_device_sink_transport_connected(d) == true)
 +            args = pa_sprintf_malloc("%s profile=\"a2dp_sink\"", args);
 +
 +        if (pa_bluetooth_device_source_transport_connected(d) == true)
 +            args = pa_sprintf_malloc("%s profile=\"a2dp_source\"", args);
 +#endif
  
          pa_log_debug("Loading module-bluez5-device %s", args);
-         m = pa_module_load(u->module->core, "module-bluez5-device", args);
+         pa_module_load(&m, u->module->core, "module-bluez5-device", args);
          pa_xfree(args);
  
          if (m)
  #include <pulsecore/modargs.h>
  #include <pulsecore/proplist-util.h>
  
- #include "module-filter-apply-symdef.h"
 +#ifdef TIZEN_FILTER_GROUP
 +#define PA_PROP_FILTER_APPLY_GROUP      PA_PROP_FILTER_APPLY".%s.group"
 +#endif
  #define PA_PROP_FILTER_APPLY_PARAMETERS PA_PROP_FILTER_APPLY".%s.parameters"
  #define PA_PROP_FILTER_APPLY_MOVING     "filter.apply.moving"
  #define PA_PROP_FILTER_APPLY_SET_BY_MFA "filter.apply.set_by_mfa"
@@@ -203,28 -160,9 +201,28 @@@ static const char* get_filter_parameter
      return parameters;
  }
  
 +#ifdef TIZEN_FILTER_GROUP
 +static const char* get_filter_group(pa_object *o, const char *want, bool is_sink_input) {
 +    const char *group;
 +    char *prop_group;
 +    pa_proplist *pl;
 +
 +    if (is_sink_input)
 +        pl = PA_SINK_INPUT(o)->proplist;
 +    else
 +        pl = PA_SOURCE_OUTPUT(o)->proplist;
 +
 +    prop_group = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_GROUP, want);
 +    group = pa_proplist_gets(pl, prop_group);
 +    pa_xfree(prop_group);
 +
 +    return group;
 +}
 +#endif
 +
  /* This function is used to set or unset the filter related stream properties. This is necessary
   * if a stream does not have filter.apply set and is manually moved to a filter sink or source.
-  * In this case, the properies must be temporarily set and removed when the stream is moved away
+  * In this case, the properties must be temporarily set and removed when the stream is moved away
   * from the filter. */
  static void set_filter_properties(pa_proplist *pl, struct filter *filter, bool set_properties) {
      char *prop_parameters;
@@@ -674,12 -578,8 +678,12 @@@ static pa_hook_result_t process(struct 
  
              pa_log_debug("Loading %s with arguments '%s'", module_name, args);
  
-             if ((m = pa_module_load(u->core, module_name, args))) {
+             if (pa_module_load(&m, u->core, module_name, args) >= 0) {
 +#ifdef TIZEN_FILTER_GROUP
 +                find_filters_for_module(u, m, want, group, parameters);
 +#else
                  find_filters_for_module(u, m, want, parameters);
 +#endif
                  filter = pa_hashmap_get(u->filters, fltr);
                  done_something = true;
              }
Simple merge
Simple merge
@@@ -36,10 -34,7 +34,10 @@@ PA_MODULE_USAGE
          "cork_roles=<Comma separated list of roles which will be corked> "
          "global=<Should we operate globally or only inside the same device?>"
          "use_source_trigger=<Do we trigger a cork by a role of source-output as well as sink-input's? Default: false>"
- );
 +#ifdef __TIZEN__
 +        "skip_sinks=<Comma separated list of sink names which will skip corking>"
 +#endif
+         );
  
  static const char* const valid_modargs[] = {
      "trigger_roles",
Simple merge
Simple merge
Simple merge
@@@ -575,11 -678,29 +681,33 @@@ pa_sink* pa_raop_sink_new(pa_module *m
          goto fail;
      }
  
+     port = raop_create_port(u, server);
+     if (port == NULL) {
+         pa_log("Failed to create port object");
+         goto fail;
+     }
+     profile = raop_create_profile();
+     pa_hashmap_put(port->profiles, profile->name, profile);
+     description = pa_proplist_gets(data.proplist, PA_PROP_DEVICE_DESCRIPTION);
+     if (description == NULL)
+         description = server;
+     u->card = raop_create_card(m, port, profile, server, description);
+     if (u->card == NULL) {
+         pa_log("Failed to create card object");
+         goto fail;
+     }
+     data.card = u->card;
+     pa_hashmap_put(data.ports, port->name, port);
 +#ifdef __TIZEN__
 +    u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY | PA_SINK_NETWORK | PA_SINK_FLAT_VOLUME);
 +#else
      u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY | PA_SINK_NETWORK);
 +#endif
      pa_sink_new_data_done(&data);
  
      if (!(u->sink)) {
@@@ -238,40 -155,6 +238,40 @@@ static const char *find_global_trigger_
  static void cork_or_duck(struct userdata *u, pa_sink_input *i, const char *interaction_role,  const char *trigger_role, bool interaction_applied, struct group *g) {
  
      if (u->duck && !interaction_applied) {
-             if (!g->fade_needed || (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)) {
 +#ifdef __TIZEN__
 +        if (g->fade_durs.in || g->fade_durs.out) {
 +            pa_cvolume_ramp vol_ramp;
 +
 +            pa_cvolume_ramp_set(&vol_ramp, i->volume.channels, PA_VOLUME_RAMP_TYPE_LINEAR, g->fade_durs.out, g->volume);
-                 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_RUNNING) {
++            if (!g->fade_needed || i->state == PA_SINK_INPUT_CORKED) {
 +                pa_cvolume vol;
 +                vol.channels = 1;
 +                vol.values[0] = g->volume;
 +
 +                pa_log_debug("Found a '%s' stream(%u) that should be ducked by '%s'.", interaction_role, i->index, g->name);
 +
 +                pa_sink_input_add_volume_factor(i, g->name, &vol);
 +                pa_sink_input_add_volume_ramp_factor(i, g->name, &vol_ramp, false);
 +            } else {
 +                pa_log_debug("Found a '%s' stream(%u) that should be ducked with fade-out(%lums) by '%s'.", interaction_role, i->index, g->fade_durs.out, g->name);
 +                pa_sink_input_add_volume_ramp_factor(i, g->name, &vol_ramp, true);
 +
++                if (i->state == PA_SINK_INPUT_RUNNING) {
 +                    if (pa_idxset_size(g->triggered_streams) == 1) {
 +                        pa_sink_input *si = pa_idxset_first(g->triggered_streams, NULL);
 +                        pa_sink_input_set_silence_to_first_peek(si, true, g->fade_durs.out * 1000);
 +                    }
 +                }
 +            }
 +        } else {
 +            pa_cvolume vol;
 +            vol.channels = 1;
 +            vol.values[0] = g->volume;
 +
 +            pa_log_debug("Found a '%s' stream of '%s' that ducks a '%s' stream(%u).", trigger_role, g->name, interaction_role, i->index);
 +            pa_sink_input_add_volume_factor(i, g->name, &vol);
 +        }
 +#else
          pa_cvolume vol;
          vol.channels = 1;
          vol.values[0] = g->volume;
@@@ -490,16 -309,8 +490,16 @@@ static pa_hook_result_t sink_input_put_
  }
  
  static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
-     int j;
 +#ifdef __TIZEN__
++    uint32_t j;
 +    pa_core_assert_ref(core);
 +#endif
      pa_sink_input_assert_ref(i);
  
 +#ifdef __TIZEN__
 +    for (j = 0; j < u->n_groups; j++)
 +        pa_idxset_remove_by_data(u->groups[j]->interacted_inputs, (void*)i, NULL);
 +#endif
      return process(u, PA_OBJECT(i), false, false);
  }
  
Simple merge
Simple merge
diff --cc src/pulse/def.h
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -428,57 -434,9 +434,57 @@@ pa_cvolume* pa_cvolume_inc_clamp(pa_cvo
  pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
  
  /** Decrease the volume passed in by 'dec'. The proportions between
-  * the channels are kept. \since 0.9.16 */
+  * the channels are kept. Returns \a v, or NULL on error. \since 0.9.16 */
  pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec);
  
 +#ifdef __TIZEN__
 +/** Volume ramp type
 +*/
 +typedef enum pa_volume_ramp_type {
 +    PA_VOLUME_RAMP_TYPE_LINEAR = 0,        /**< linear */
 +    PA_VOLUME_RAMP_TYPE_LOGARITHMIC = 1,   /**< logarithmic */
 +    PA_VOLUME_RAMP_TYPE_CUBIC = 2,
 +} pa_volume_ramp_type_t;
 +
 +/** A structure encapsulating a volume ramp */
 +typedef struct pa_volume_ramp_t {
 +    pa_volume_ramp_type_t type;
 +    long length;
 +    pa_volume_t target;
 +} pa_volume_ramp;
 +
 +/** A structure encapsulating a multichannel volume ramp */
 +typedef struct pa_cvolume_ramp {
 +    uint8_t channels;
 +    pa_volume_ramp ramps[PA_CHANNELS_MAX];
 +} pa_cvolume_ramp;
 +
 +/** Return non-zero when *a == *b */
 +int pa_cvolume_ramp_equal(const pa_cvolume_ramp *a, const pa_cvolume_ramp *b);
 +
 +/** Init volume ramp struct */
 +pa_cvolume_ramp* pa_cvolume_ramp_init(pa_cvolume_ramp *ramp);
 +
 +/** Set the volume ramp of the first n channels to PA_VOLUME_NORM */
 +#define pa_cvolume_ramp_reset(a, n, d, l) pa_cvolume_ramp_set((a), (n), (d), (l), PA_VOLUME_NORM)
 +
 +/** Set first n channels of ramp struct to certain value */
 +pa_cvolume_ramp* pa_cvolume_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
 +
 +/** Set individual channel in the channel struct */
 +pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
 +
 +/** Return non-zero if the specified volume ramp is compatible with the
 + * specified sample spec. */
 +int pa_cvolume_ramp_compatible(const pa_cvolume_ramp *ramp, const pa_sample_spec *ss);
 +
 +/** Return non-zero when the passed volume ramp structure is valid */
 +int pa_cvolume_ramp_valid(const pa_cvolume_ramp *ramp);
 +
 +/** Multiply two per-channel ramp target volumes and return the result in
 + * dest. */
 +pa_cvolume_ramp *pa_sw_cvolume_ramp_multiply(pa_cvolume_ramp *dest, const pa_cvolume_ramp *a, const pa_cvolume_ramp *b);
 +#endif
  PA_C_DECL_END
  
  #endif
Simple merge
  #endif
  #endif
  
++#ifndef __TIZEN_BT_6__
 +#ifdef HAVE_SCHED_H
 +#include <sched.h>
 +
 +#if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
 +#define SCHED_RESET_ON_FORK 0x40000000
 +#endif
 +#endif
++#endif
 +
  #ifdef HAVE_SYS_RESOURCE_H
  #include <sys/resource.h>
  #endif
@@@ -694,158 -682,6 +692,160 @@@ char *pa_strlcpy(char *b, const char *s
      return b;
  }
  
++#ifndef __TIZEN_BT_6__
 +#ifdef _POSIX_PRIORITY_SCHEDULING
 +static int set_scheduler(int rtprio) {
 +#ifdef HAVE_SCHED_H
 +    struct sched_param sp;
 +#ifdef HAVE_DBUS
 +    int r;
 +    long long rttime;
 +#ifdef RLIMIT_RTTIME
 +    struct rlimit rl;
 +#endif
 +    DBusError error;
 +    DBusConnection *bus;
 +
 +    dbus_error_init(&error);
 +#endif
 +
 +    pa_zero(sp);
 +    sp.sched_priority = rtprio;
 +
 +#ifdef SCHED_RESET_ON_FORK
 +    if (pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, &sp) == 0) {
 +        pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
 +        return 0;
 +    }
 +#endif
 +
 +    if (pthread_setschedparam(pthread_self(), SCHED_RR, &sp) == 0) {
 +        pa_log_debug("SCHED_RR worked.");
 +        return 0;
 +    }
 +#endif  /* HAVE_SCHED_H */
 +
 +#ifdef HAVE_DBUS
 +    /* Try to talk to RealtimeKit */
 +
 +    if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
 +        pa_log("Failed to connect to system bus: %s", error.message);
 +        dbus_error_free(&error);
 +        errno = -EIO;
 +        return -1;
 +    }
 +
 +    /* We need to disable exit on disconnect because otherwise
 +     * dbus_shutdown will kill us. See
 +     * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
 +    dbus_connection_set_exit_on_disconnect(bus, FALSE);
 +
 +    rttime = rtkit_get_rttime_usec_max(bus);
 +    if (rttime >= 0) {
 +#ifdef RLIMIT_RTTIME
 +        r = getrlimit(RLIMIT_RTTIME, &rl);
 +
 +        if (r >= 0 && (long long) rl.rlim_max > rttime) {
 +            pa_log_info("Clamping rlimit-rttime to %lld for RealtimeKit", rttime);
 +            rl.rlim_cur = rl.rlim_max = rttime;
 +            r = setrlimit(RLIMIT_RTTIME, &rl);
 +
 +            if (r < 0)
 +                pa_log("setrlimit() failed: %s", pa_cstrerror(errno));
 +        }
 +#endif
 +        r = rtkit_make_realtime(bus, 0, rtprio);
 +        dbus_connection_close(bus);
 +        dbus_connection_unref(bus);
 +
 +        if (r >= 0) {
 +            pa_log_debug("RealtimeKit worked.");
 +            return 0;
 +        }
 +
 +        errno = -r;
 +    } else {
 +        dbus_connection_close(bus);
 +        dbus_connection_unref(bus);
 +        errno = -rttime;
 +    }
 +
 +#else
 +    errno = 0;
 +#endif
 +
 +    return -1;
 +}
 +#endif
 +
 +/* Make the current thread a realtime thread, and acquire the highest
 + * rtprio we can get that is less or equal the specified parameter. If
 + * the thread is already realtime, don't do anything. */
 +int pa_make_realtime(int rtprio) {
 +
 +#if defined(OS_IS_DARWIN)
 +    struct thread_time_constraint_policy ttcpolicy;
 +    uint64_t freq = 0;
 +    size_t size = sizeof(freq);
 +    int ret;
 +
 +    ret = sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0);
 +    if (ret < 0) {
 +        pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
 +        return -1;
 +    }
 +
 +    pa_log_debug("sysctl for hw.cpufrequency: %llu", freq);
 +
 +    /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
 +    ttcpolicy.period = freq / 160;
 +    ttcpolicy.computation = freq / 3300;
 +    ttcpolicy.constraint = freq / 2200;
 +    ttcpolicy.preemptible = 1;
 +
 +    ret = thread_policy_set(mach_thread_self(),
 +                            THREAD_TIME_CONSTRAINT_POLICY,
 +                            (thread_policy_t) &ttcpolicy,
 +                            THREAD_TIME_CONSTRAINT_POLICY_COUNT);
 +    if (ret) {
 +        pa_log_info("Unable to set real-time thread priority (%08x).", ret);
 +        return -1;
 +    }
 +
 +    pa_log_info("Successfully acquired real-time thread priority.");
 +    return 0;
 +
 +#elif defined(_POSIX_PRIORITY_SCHEDULING)
 +    int p;
 +
 +    if (set_scheduler(rtprio) >= 0) {
 +        pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio);
 +        return 0;
 +    }
 +
 +    for (p = rtprio-1; p >= 1; p--)
 +        if (set_scheduler(p) >= 0) {
 +            pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p, rtprio);
 +            return 0;
 +        }
 +#elif defined(OS_IS_WIN32)
 +    /* Windows only allows realtime scheduling to be set on a per process basis.
 +     * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
 +    if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) {
 +        pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
 +        return 0;
 +    }
 +
 +    pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
 +    errno = EPERM;
 +#else
 +    errno = ENOTSUP;
 +#endif
 +    pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno));
 +    return -1;
 +}
++#endif
 +
  #ifdef HAVE_SYS_RESOURCE_H
  static int set_nice(int nice_level) {
  #ifdef HAVE_DBUS
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -449,11 -331,7 +451,11 @@@ int pa_sink_input_new
      if (!data->sink) {
          pa_sink *sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
          pa_return_val_if_fail(sink, -PA_ERR_NOENTITY);
-         pa_sink_input_new_data_set_sink(data, sink, false);
+         pa_sink_input_new_data_set_sink(data, sink, false, false);
 +#ifdef __TIZEN__
 +    } else {
-         pa_sink_input_new_data_set_sink(data, data->sink, false);
++        pa_sink_input_new_data_set_sink(data, data->sink, false, false);
 +#endif
      }
  
      /* If something didn't pick a format for us, pick the top-most format since
@@@ -2363,15 -2006,6 +2366,10 @@@ void pa_sink_input_set_state_within_thr
      if (state == i->thread_info.state)
          return;
  
-     if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
-         !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
-         pa_atomic_store(&i->thread_info.drained, 1);
 +#ifdef TIZEN_EMPTY_POP
 +    if (state != PA_SINK_INPUT_RUNNING && _empty_pop_is_started(i))
 +        _empty_pop_reset(i);
 +#endif
      corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
      uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
  
Simple merge
@@@ -510,19 -454,25 +529,34 @@@ static int sink_set_state(pa_sink *s, p
              /* SET_STATE is allowed to fail only when resuming. */
              pa_assert(resuming);
  
-             if (s->set_state)
-                 s->set_state(s, PA_SINK_SUSPENDED);
+             if (s->set_state_in_main_thread)
+                 s->set_state_in_main_thread(s, PA_SINK_SUSPENDED, 0);
+             /* If resuming fails, we set the state to SUSPENDED and
+              * suspend_cause to 0. */
+             state = PA_SINK_SUSPENDED;
+             suspend_cause = 0;
+             state_changed = false;
+             suspend_cause_changed = suspend_cause != s->suspend_cause;
+             resuming = false;
+             /* We know the state isn't changing. If the suspend cause isn't
+              * changing either, then there's nothing more to do. */
+             if (!suspend_cause_changed)
+                 return ret;
          }
+     }
  
 +#ifdef TIZEN_PCM_DUMP
 +    /* close file for dump pcm */
 +    if (s->pcm_dump_fp && (s->core->pcm_dump_option & PA_PCM_DUMP_OPTION_SEPARATED) && suspending) {
 +        fclose(s->pcm_dump_fp);
 +        pa_log_info("%s closed", s->dump_path);
 +        pa_xfree(s->dump_path);
 +        s->pcm_dump_fp = NULL;
 +    }
 +#endif
+     old_suspend_cause = s->suspend_cause;
      if (suspend_cause_changed) {
          char old_cause_buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE];
          char new_cause_buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE];
Simple merge
@@@ -343,12 -275,8 +347,14 @@@ int pa_source_output_new
              pa_return_val_if_fail(source, -PA_ERR_NOENTITY);
          }
  
-         pa_source_output_new_data_set_source(data, source, false);
+         pa_source_output_new_data_set_source(data, source, false, false);
+     }
 +#ifdef __TIZEN__
-     } else {
-         pa_source_output_new_data_set_source(data, data->source, false);
- #endif
++    else {
++        pa_source_output_new_data_set_source(data, data->source, false, false);
 +    }
++#endif
++
  
      /* If something didn't pick a format for us, pick the top-most format since
       * we assume this is sorted in priority order */
Simple merge
@@@ -459,19 -407,25 +477,34 @@@ static int source_set_state(pa_source *
              /* SET_STATE is allowed to fail only when resuming. */
              pa_assert(resuming);
  
-             if (s->set_state)
-                 s->set_state(s, PA_SOURCE_SUSPENDED);
+             if (s->set_state_in_main_thread)
+                 s->set_state_in_main_thread(s, PA_SOURCE_SUSPENDED, 0);
+             /* If resuming fails, we set the state to SUSPENDED and
+              * suspend_cause to 0. */
+             state = PA_SOURCE_SUSPENDED;
+             suspend_cause = 0;
+             state_changed = false;
+             suspend_cause_changed = suspend_cause != s->suspend_cause;
+             resuming = false;
+             /* We know the state isn't changing. If the suspend cause isn't
+              * changing either, then there's nothing more to do. */
+             if (!suspend_cause_changed)
+                 return ret;
          }
+     }
  
 +#ifdef TIZEN_PCM_DUMP
 +    /* close file for dump pcm */
 +    if (s->pcm_dump_fp && (s->core->pcm_dump_option & PA_PCM_DUMP_OPTION_SEPARATED) && suspending) {
 +        fclose(s->pcm_dump_fp);
 +        pa_log_info("%s closed", s->dump_path);
 +        pa_xfree(s->dump_path);
 +        s->pcm_dump_fp = NULL;
 +    }
 +#endif
+     old_suspend_cause = s->suspend_cause;
      if (suspend_cause_changed) {
          char old_cause_buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE];
          char new_cause_buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE];
Simple merge
Simple merge