mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	Merge branch 'revert-fccb4bd2' into 'master'
alsa-mixer: Recognize rear mic jack mixer of USB audio See merge request pulseaudio/pulseaudio!821
This commit is contained in:
		
						commit
						78281d21e5
					
				
					 107 changed files with 51641 additions and 35 deletions
				
			
		| 
						 | 
				
			
			@ -19,8 +19,13 @@ variables:
 | 
			
		|||
  # CI runs, for example when adding new packages to FDO_DISTRIBUTION_PACKAGES.
 | 
			
		||||
  # The tag is an arbitrary string that identifies the exact container
 | 
			
		||||
  # contents.
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  FDO_DISTRIBUTION_TAG: '2021-03-01-02'
 | 
			
		||||
  FDO_DISTRIBUTION_VERSION: '18.04'
 | 
			
		||||
=======
 | 
			
		||||
  FDO_DISTRIBUTION_TAG: '2023-08-13-00'
 | 
			
		||||
  FDO_DISTRIBUTION_VERSION: '20.04'
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  FDO_UPSTREAM_REPO: 'pulseaudio/pulseaudio'
 | 
			
		||||
 | 
			
		||||
include:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								NEWS
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								NEWS
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
PulseAudio 17.0
 | 
			
		||||
 | 
			
		||||
Changes at a glance:
 | 
			
		||||
| 
						 | 
				
			
			@ -184,6 +186,7 @@ tensorknower69
 | 
			
		|||
김인수
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
PulseAudio 15.0
 | 
			
		||||
 | 
			
		||||
Changes at a glance:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,13 @@ if get_option('daemon')
 | 
			
		|||
  ]
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
manpages += [
 | 
			
		||||
  ['pacat', '1', ['paplay', 'parec', 'parecord', 'pamon']],
 | 
			
		||||
  ['pactl', '1'],
 | 
			
		||||
  ['pulse-client.conf', '5'],
 | 
			
		||||
]
 | 
			
		||||
=======
 | 
			
		||||
if get_option('client')
 | 
			
		||||
  manpages += [
 | 
			
		||||
    ['pacat', '1', ['paplay', 'parec', 'parecord', 'pamon']],
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +40,19 @@ if get_option('client')
 | 
			
		|||
    ]
 | 
			
		||||
  endif
 | 
			
		||||
endif
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
if cdata.has('HAVE_OSS_WRAPPER')
 | 
			
		||||
  manpages += [
 | 
			
		||||
    ['padsp', '1'],
 | 
			
		||||
  ]
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if x11_dep.found()
 | 
			
		||||
  manpages += [
 | 
			
		||||
    ['pax11publish', '1'],
 | 
			
		||||
  ]
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# FIXME: Add esdcompat if HAVE_ESOUND
 | 
			
		||||
#manpages += ['esdcompat', '1'],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -174,9 +174,13 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
    <option>
 | 
			
		||||
      <p><opt>set-default-sink</opt> <arg>SINK</arg></p>
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
      <optdesc><p>Make the specified sink (identified by its symbolic name or numerical index) the default sink.</p></optdesc>
 | 
			
		||||
=======
 | 
			
		||||
      <optdesc><p>Make the specified sink (identified by its symbolic name or numerical index) the default sink.
 | 
			
		||||
         Use the special name \@NONE@ to unset the user defined default sink. This will make pulseaudio return to the default
 | 
			
		||||
         sink selection based on sink priority.</p></optdesc>
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    </option>
 | 
			
		||||
 | 
			
		||||
    <option>
 | 
			
		||||
| 
						 | 
				
			
			@ -191,9 +195,13 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
    <option>
 | 
			
		||||
      <p><opt>set-default-source</opt> <arg>SOURCE</arg></p>
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
      <optdesc><p>Make the specified source (identified by its symbolic name or numerical index) the default source.</p></optdesc>
 | 
			
		||||
=======
 | 
			
		||||
      <optdesc><p>Make the specified source (identified by its symbolic name or numerical index) the default source.
 | 
			
		||||
         Use the special name \@NONE@ to unset the user defined default source. This will make pulseaudio return to the default
 | 
			
		||||
         source selection based on source priority.</p></optdesc>
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    </option>
 | 
			
		||||
 | 
			
		||||
    <option>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										186
									
								
								meson.build
									
										
									
									
									
								
							
							
						
						
									
										186
									
								
								meson.build
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -4,9 +4,13 @@ project('pulseaudio', 'c',
 | 
			
		|||
        default_options : [ 'c_std=gnu11', 'cpp_std=c++17' ]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
meson.add_dist_script('scripts/save-tarball-version.sh', meson.project_version())
 | 
			
		||||
=======
 | 
			
		||||
if not meson.is_subproject()
 | 
			
		||||
  meson.add_dist_script('scripts/save-tarball-version.sh', meson.project_version())
 | 
			
		||||
endif
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
pa_version_str = meson.project_version()
 | 
			
		||||
# For tarballs, the first split will do nothing, but for builds in git, we
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +31,11 @@ pa_protocol_version = 35
 | 
			
		|||
 | 
			
		||||
# The stable ABI for client applications, for the version info x:y:z
 | 
			
		||||
# always will hold x=z
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
libpulse_version_info = [24, 0, 24]
 | 
			
		||||
=======
 | 
			
		||||
libpulse_version_info = [24, 3, 24]
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
# A simplified, synchronous, ABI-stable interface for client
 | 
			
		||||
# applications, for the version info x:y:z always will hold x=z
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +80,10 @@ localedir = join_paths(prefix, get_option('localedir'))
 | 
			
		|||
localstatedir = join_paths(prefix, get_option('localstatedir'))
 | 
			
		||||
sysconfdir = join_paths(prefix, get_option('sysconfdir'))
 | 
			
		||||
privlibdir = join_paths(libdir, 'pulseaudio')
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
po_dir = join_paths(meson.current_source_dir(), 'po')
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
if host_machine.system() == 'windows'
 | 
			
		||||
  # Windows only supports loading libraries from the same dir as the executable
 | 
			
		||||
| 
						 | 
				
			
			@ -430,7 +441,11 @@ cdata.set('MESON_BUILD', 1)
 | 
			
		|||
# so we request the nodelete flag to be enabled.
 | 
			
		||||
# On other systems, we don't really know how to do that, but it's welcome if somebody can tell.
 | 
			
		||||
# Windows doesn't support this flag.
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
if host_machine.system() != 'windows'
 | 
			
		||||
=======
 | 
			
		||||
if host_machine.system() != 'windows' and host_machine.system() != 'darwin'
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  nodelete_link_args = ['-Wl,-z,nodelete']
 | 
			
		||||
else
 | 
			
		||||
  nodelete_link_args = []
 | 
			
		||||
| 
						 | 
				
			
			@ -594,7 +609,26 @@ if host_machine.cpu_family() == 'arm'
 | 
			
		|||
endif
 | 
			
		||||
# NEON checks are automatically done by the unstable-simd module
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
if get_option('daemon')
 | 
			
		||||
  # FIXME: make sure it's >= 2.2
 | 
			
		||||
  ltdl_dep = cc.find_library('ltdl', required : true)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# FIXME: can meson support libtool -dlopen/-dlpreopen things?
 | 
			
		||||
#        and do we still want to support this at all?
 | 
			
		||||
cdata.set('DISABLE_LIBTOOL_PRELOAD', 1)
 | 
			
		||||
 | 
			
		||||
if get_option('database') == 'tdb'
 | 
			
		||||
  database_dep = dependency('tdb')
 | 
			
		||||
elif get_option('database') == 'gdbm'
 | 
			
		||||
  database_dep = cc.find_library('gdbm', required : true)
 | 
			
		||||
else
 | 
			
		||||
  database_dep = dependency('', required: false)
 | 
			
		||||
endif
 | 
			
		||||
=======
 | 
			
		||||
# Dependencies common to client, daemon and modules
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
if get_option('ipv6')
 | 
			
		||||
  cdata.set('HAVE_IPV6', 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -605,6 +639,17 @@ if dbus_dep.found()
 | 
			
		|||
  cdata.set('HAVE_DBUS', 1)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
gio_dep = dependency('gio-2.0', version : '>= 2.26.0')
 | 
			
		||||
if get_option('gsettings').enabled()
 | 
			
		||||
  assert(gio_dep.found(), 'GSettings support needs glib I/O library (GIO)')
 | 
			
		||||
  cdata.set('HAVE_GSETTINGS', 1)
 | 
			
		||||
else
 | 
			
		||||
  cdata.set('HAVE_GSETTINGS', 0)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
glib_dep = dependency('glib-2.0', version : '>= 2.28.0', required: get_option('glib'))
 | 
			
		||||
if glib_dep.found()
 | 
			
		||||
  cdata.set('HAVE_GLIB', 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -620,11 +665,37 @@ if libsystemd_dep.found()
 | 
			
		|||
  cdata.set('HAVE_SYSTEMD_JOURNAL', 1)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
libelogind_dep = dependency('libelogind', required : get_option('elogind'))
 | 
			
		||||
if libelogind_dep.found()
 | 
			
		||||
  cdata.set('HAVE_SYSTEMD_LOGIN', 1)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
tcpwrap_dep = cc.find_library('wrap', required: get_option('tcpwrap'))
 | 
			
		||||
if cc.has_header('tcpd.h') and cc.has_function('hosts_access', dependencies : tcpwrap_dep)
 | 
			
		||||
  cdata.set('HAVE_LIBWRAP', 1)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
x11_dep = dependency('x11-xcb', required : get_option('x11'))
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
if x11_dep.found()
 | 
			
		||||
  xcb_dep  = dependency('xcb',  required : true, version : '>= 1.6')
 | 
			
		||||
  ice_dep  = dependency('ice',  required : get_option('daemon'))
 | 
			
		||||
  sm_dep   = dependency('sm',   required : get_option('daemon'))
 | 
			
		||||
  xtst_dep = dependency('xtst', required : get_option('daemon'))
 | 
			
		||||
  cdata.set('HAVE_X11', 1)
 | 
			
		||||
  if cc.has_function('XSetIOErrorExitHandler', dependencies: x11_dep)
 | 
			
		||||
    cdata.set('HAVE_XSETIOERROREXITHANDLER', 1)
 | 
			
		||||
  endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Module dependencies
 | 
			
		||||
if cc.has_header('sys/soundcard.h', required: get_option('oss-output'))
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
# OSS support
 | 
			
		||||
if cc.has_header('sys/soundcard.h', required: get_option('oss-output'))
 | 
			
		||||
  # OSS output via daemon module-detect
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  cdata.set('HAVE_OSS_OUTPUT', 1)
 | 
			
		||||
  # OSS wrapper
 | 
			
		||||
  cdata.set('HAVE_OSS_WRAPPER', 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -636,12 +707,34 @@ if fftw_dep.found()
 | 
			
		|||
  cdata.set('HAVE_FFTW', 1)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
avahi_dep = dependency('avahi-client', version : '>= 0.6.0', required : get_option('avahi'), disabler : true)
 | 
			
		||||
if avahi_dep.found()
 | 
			
		||||
  cdata.set('HAVE_AVAHI', 1)
 | 
			
		||||
else
 | 
			
		||||
  cdata.set('HAVE_AVAHI', 0)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
sbc_dep = dependency('sbc', version : '>= 1.0', required : false)
 | 
			
		||||
 | 
			
		||||
bluez_dep = dependency('bluez', required : get_option('bluez5'))
 | 
			
		||||
 | 
			
		||||
if bluez_dep.found()
 | 
			
		||||
  assert(dbus_dep.found(), 'BlueZ requires D-Bus support')
 | 
			
		||||
  assert(sbc_dep.found(), 'BlueZ requires SBC support')
 | 
			
		||||
  cdata.set('HAVE_SBC', 1)
 | 
			
		||||
  cdata.set('HAVE_BLUEZ', 1)
 | 
			
		||||
  cdata.set('HAVE_BLUEZ_5', 1)
 | 
			
		||||
  if get_option('bluez5-native-headset')
 | 
			
		||||
    cdata.set('HAVE_BLUEZ_5_NATIVE_HEADSET', 1)
 | 
			
		||||
=======
 | 
			
		||||
# Client library dependencies
 | 
			
		||||
 | 
			
		||||
if get_option('client')
 | 
			
		||||
  asyncns_dep = dependency('libasyncns', version : '>= 0.1', required : get_option('asyncns'))
 | 
			
		||||
  if asyncns_dep.found()
 | 
			
		||||
    cdata.set('HAVE_LIBASYNCNS', 1)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  gtk_dep = dependency('gtk+-3.0', required : get_option('gtk'))
 | 
			
		||||
| 
						 | 
				
			
			@ -806,6 +899,16 @@ if get_option('daemon')
 | 
			
		|||
    cdata.set('HAVE_UDEV', 1)
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('gstreamer'))
 | 
			
		||||
gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('gstreamer'))
 | 
			
		||||
gstrtp_dep = dependency('gstreamer-rtp-1.0', required : get_option('gstreamer'))
 | 
			
		||||
 | 
			
		||||
have_gstreamer = false
 | 
			
		||||
if gst_dep.found() and gstapp_dep.found() and gstrtp_dep.found()
 | 
			
		||||
  assert(gio_dep.found(), 'GStreamer-based RTP needs glib I/O library (GIO)')
 | 
			
		||||
  have_gstreamer = true
 | 
			
		||||
=======
 | 
			
		||||
  if get_option('hal-compat')
 | 
			
		||||
    cdata.set('HAVE_HAL_COMPAT', 1)
 | 
			
		||||
  endif
 | 
			
		||||
| 
						 | 
				
			
			@ -828,6 +931,16 @@ if get_option('daemon')
 | 
			
		|||
    cdata.set('HAVE_GSTLDAC', 1)
 | 
			
		||||
    cdata.set('HAVE_GSTAPTX', 1)
 | 
			
		||||
  endif
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
bluez5_gst_dep = dependency('gstreamer-1.0', version : '>= 1.14', required : get_option('bluez5-gstreamer'))
 | 
			
		||||
bluez5_gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('bluez5-gstreamer'))
 | 
			
		||||
have_bluez5_gstreamer = false
 | 
			
		||||
if bluez5_gst_dep.found() and bluez5_gstapp_dep.found()
 | 
			
		||||
  have_bluez5_gstreamer = true
 | 
			
		||||
  cdata.set('HAVE_GSTLDAC', 1)
 | 
			
		||||
  cdata.set('HAVE_GSTAPTX', 1)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# These are required for the CMake file generation
 | 
			
		||||
| 
						 | 
				
			
			@ -843,9 +956,13 @@ check_dep = dependency('check', version : '>= 0.9.10', required : get_option('te
 | 
			
		|||
if get_option('doxygen')
 | 
			
		||||
  subdir('doxygen')
 | 
			
		||||
endif
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
subdir('po')
 | 
			
		||||
=======
 | 
			
		||||
if get_option('client')
 | 
			
		||||
  subdir('po')
 | 
			
		||||
endif
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
if get_option('man')
 | 
			
		||||
  subdir('man')
 | 
			
		||||
endif
 | 
			
		||||
| 
						 | 
				
			
			@ -956,6 +1073,14 @@ summary = [
 | 
			
		|||
#  'LIBS:                          @0@'.format(${LIBS}),
 | 
			
		||||
  '',
 | 
			
		||||
  'Enable pulseaudio daemon:      @0@'.format(get_option('daemon')),
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  '',
 | 
			
		||||
  'Enable memfd shared memory:    @0@'.format(cdata.has('HAVE_MEMFD')),
 | 
			
		||||
  'Enable X11:                    @0@'.format(x11_dep.found()),
 | 
			
		||||
  '  Safe X11 I/O errors:         @0@'.format(cdata.has('HAVE_XSETIOERROREXITHANDLER')),
 | 
			
		||||
  'Enable OSS Output:             @0@'.format(cdata.has('HAVE_OSS_OUTPUT')),
 | 
			
		||||
  'Enable OSS Wrapper:            @0@'.format(cdata.has('HAVE_OSS_WRAPPER')),
 | 
			
		||||
=======
 | 
			
		||||
  'Enable pulseaudio client:      @0@'.format(get_option('client')),
 | 
			
		||||
  '',
 | 
			
		||||
  'Enable memfd shared memory:    @0@'.format(cdata.has('HAVE_MEMFD')),
 | 
			
		||||
| 
						 | 
				
			
			@ -990,6 +1115,7 @@ summary += [
 | 
			
		|||
  'Safe X11 I/O errors:           @0@'.format(cdata.has('HAVE_XSETIOERROREXITHANDLER')),
 | 
			
		||||
  'Enable Avahi:                  @0@'.format(avahi_dep.found()),
 | 
			
		||||
  'Enable OSS Output:             @0@'.format(cdata.has('HAVE_OSS_OUTPUT')),
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
#  'Enable EsounD:                 @0@'.format(${ENABLE_ESOUND}),
 | 
			
		||||
  'Enable Alsa:                   @0@'.format(alsa_dep.found()),
 | 
			
		||||
  'Enable Jack:                   @0@'.format(jack_dep.found()),
 | 
			
		||||
| 
						 | 
				
			
			@ -997,18 +1123,45 @@ summary += [
 | 
			
		|||
#  'Enable CoreAudio:              @0@'.format(${ENABLE_COREAUDIO}),
 | 
			
		||||
#  'Enable Solaris:                @0@'.format(${ENABLE_SOLARIS}),
 | 
			
		||||
#  'Enable WaveOut:                @0@'.format(${ENABLE_WAVEOUT}),
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  'Enable GLib 2:                 @0@'.format(glib_dep.found()),
 | 
			
		||||
  'Enable GSettings:              @0@'.format(gio_dep.found()),
 | 
			
		||||
  'Enable Gtk+ 3:                 @0@'.format(gtk_dep.found()),
 | 
			
		||||
  'Enable Avahi:                  @0@'.format(avahi_dep.found()),
 | 
			
		||||
  'Enable Jack:                   @0@'.format(jack_dep.found()),
 | 
			
		||||
  'Enable Async DNS:              @0@'.format(asyncns_dep.found()),
 | 
			
		||||
  'Enable LIRC:                   @0@'.format(lirc_dep.found()),
 | 
			
		||||
  'Enable D-Bus:                  @0@'.format(dbus_dep.found()),
 | 
			
		||||
  '  Enable BlueZ 5:              @0@'.format(cdata.has('HAVE_BLUEZ_5')),
 | 
			
		||||
  '    Enable native headsets:    @0@'.format(cdata.has('HAVE_BLUEZ_5_NATIVE_HEADSET')),
 | 
			
		||||
  '    Enable  ofono headsets:    @0@'.format(cdata.has('HAVE_BLUEZ_5_OFONO_HEADSET')),
 | 
			
		||||
  '    Enable GStreamer based codecs: @0@'.format(have_bluez5_gstreamer),
 | 
			
		||||
  'Enable udev:                   @0@'.format(udev_dep.found()),
 | 
			
		||||
  '  Enable HAL->udev compat:     @0@'.format(get_option('hal-compat')),
 | 
			
		||||
  'Enable systemd:                @0@'.format(libsystemd_dep.found()),
 | 
			
		||||
  'Enable elogind:                @0@'.format(libelogind_dep.found()),
 | 
			
		||||
  'Enable TCP Wrappers:           @0@'.format(tcpwrap_dep.found()),
 | 
			
		||||
=======
 | 
			
		||||
  'Enable GSettings:              @0@'.format(gio_dep.found()),
 | 
			
		||||
  'Enable BlueZ 5:              @0@'.format(cdata.has('HAVE_BLUEZ_5')),
 | 
			
		||||
  '  Enable native headsets:    @0@'.format(cdata.has('HAVE_BLUEZ_5_NATIVE_HEADSET')),
 | 
			
		||||
  '  Enable  ofono headsets:    @0@'.format(cdata.has('HAVE_BLUEZ_5_OFONO_HEADSET')),
 | 
			
		||||
  '  Enable GStreamer based codecs: @0@'.format(have_bluez5_gstreamer),
 | 
			
		||||
  'Enable GStreamer:              @0@'.format(have_gstreamer),
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  'Enable libsamplerate:          @0@'.format(samplerate_dep.found()),
 | 
			
		||||
  'Enable ORC:                    @0@'.format(have_orcc),
 | 
			
		||||
  'Enable Adrian echo canceller:  @0@'.format(get_option('adrian-aec')),
 | 
			
		||||
  'Enable Speex (resampler, AEC): @0@'.format(speex_dep.found()),
 | 
			
		||||
  'Enable SoXR (resampler):       @0@'.format(soxr_dep.found()),
 | 
			
		||||
  'Enable WebRTC echo canceller:  @0@'.format(webrtc_dep.found()),
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  'Enable Gcov coverage:          @0@'.format(get_option('gcov')),
 | 
			
		||||
  'Enable Valgrind:               @0@'.format(cdata.has('HAVE_VALGRIND_MEMCHECK_H')),
 | 
			
		||||
  'Enable man pages:              @0@'.format(get_option('man')),
 | 
			
		||||
  'Enable unit tests:             @0@'.format(get_option('tests')),
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  '',
 | 
			
		||||
  'Enable udev:                   @0@'.format(udev_dep.found()),
 | 
			
		||||
  '  Enable HAL->udev compat:     @0@'.format(get_option('hal-compat')),
 | 
			
		||||
| 
						 | 
				
			
			@ -1043,6 +1196,38 @@ if get_option('daemon') and samplerate_dep.found()
 | 
			
		|||
  warning('Support for libsamplerate is DEPRECATED')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
if host_machine.system() != 'windows'
 | 
			
		||||
  if not dbus_dep.found()
 | 
			
		||||
    message = [
 | 
			
		||||
      'You do not have D-Bus support enabled. It is strongly recommended',
 | 
			
		||||
      'that you enable D-Bus support if your platform supports it.',
 | 
			
		||||
      'Many parts of PulseAudio use D-Bus, from ConsoleKit interaction',
 | 
			
		||||
      'to the Device Reservation Protocol to speak to JACK, Bluetooth',
 | 
			
		||||
      'support and even a native control protocol for communicating and',
 | 
			
		||||
      'controlling the PulseAudio daemon itself.',
 | 
			
		||||
    ]
 | 
			
		||||
    warning('\n' + '\n'.join(message))
 | 
			
		||||
  endif
 | 
			
		||||
  if host_machine.system() == 'linux' and not udev_dep.found()
 | 
			
		||||
    message = [
 | 
			
		||||
      'You do not have udev support enabled. It is strongly recommended',
 | 
			
		||||
      'that you enable udev support if your platform supports it as it is',
 | 
			
		||||
      'the primary method used to detect hardware audio devices (on Linux)',
 | 
			
		||||
      'and is thus a critical part of PulseAudio on that platform.',
 | 
			
		||||
    ]
 | 
			
		||||
    warning('\n' + '\n'.join(message))
 | 
			
		||||
  endif
 | 
			
		||||
  if not speex_dep.found()
 | 
			
		||||
    message = [
 | 
			
		||||
      'You do not have speex support enabled. It is strongly recommended',
 | 
			
		||||
      'that you enable speex support if your platform supports it as it is',
 | 
			
		||||
      'the primary method used for audio resampling and is thus a critical',
 | 
			
		||||
      'part of PulseAudio on that platform.',
 | 
			
		||||
    ]
 | 
			
		||||
    warning('\n' + '\n'.join(message))
 | 
			
		||||
  endif
 | 
			
		||||
=======
 | 
			
		||||
if host_machine.system() != 'windows' and not dbus_dep.found()
 | 
			
		||||
  message = [
 | 
			
		||||
    'You do not have D-Bus support enabled. It is strongly recommended',
 | 
			
		||||
| 
						 | 
				
			
			@ -1073,4 +1258,5 @@ if get_option('daemon') and host_machine.system() != 'windows' and not speex_dep
 | 
			
		|||
    'part of PulseAudio on that platform.',
 | 
			
		||||
  ]
 | 
			
		||||
  warning('\n' + '\n'.join(message))
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,12 @@
 | 
			
		|||
option('daemon',
 | 
			
		||||
       type : 'boolean', value : true,
 | 
			
		||||
       description : 'Enable building and installation of pulseaudio daemon and supporting configuration files')
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
option('client',
 | 
			
		||||
       type : 'boolean', value : true,
 | 
			
		||||
       description : 'Build and install pulseaudio client libraries and utilities')
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
option('doxygen',
 | 
			
		||||
       type : 'boolean', value : true,
 | 
			
		||||
       description : 'Enable building and installation of documentation generated with doxygen')
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +121,7 @@ option('gsettings',
 | 
			
		|||
       type : 'feature', value : 'auto',
 | 
			
		||||
       description : 'Optional GSettings support')
 | 
			
		||||
option('gstreamer',
 | 
			
		||||
       type : 'feature', value : 'auto',
 | 
			
		||||
       type : 'feature', value : 'disabled',
 | 
			
		||||
       description : 'Optional GStreamer dependency for media-related functionality')
 | 
			
		||||
option('gtk',
 | 
			
		||||
       type : 'feature', value : 'auto',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,5 +48,8 @@ zh_CN
 | 
			
		|||
zh_TW
 | 
			
		||||
eo
 | 
			
		||||
si
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
ka
 | 
			
		||||
eu
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										967
									
								
								po/bn_IN.po
									
										
									
									
									
								
							
							
						
						
									
										967
									
								
								po/bn_IN.po
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										829
									
								
								po/de_CH.po
									
										
									
									
									
								
							
							
						
						
									
										829
									
								
								po/de_CH.po
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										820
									
								
								po/pt_BR.po
									
										
									
									
									
								
							
							
						
						
									
										820
									
								
								po/pt_BR.po
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										939
									
								
								po/sr@latin.po
									
										
									
									
									
								
							
							
						
						
									
										939
									
								
								po/sr@latin.po
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										920
									
								
								po/zh_CN.po
									
										
									
									
									
								
							
							
						
						
									
										920
									
								
								po/zh_CN.po
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										734
									
								
								po/zh_TW.po
									
										
									
									
									
								
							
							
						
						
									
										734
									
								
								po/zh_TW.po
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -17,6 +17,12 @@ print_map_file() {
 | 
			
		|||
    echo "};"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
TARGET_FILE=$1
 | 
			
		||||
shift
 | 
			
		||||
 | 
			
		||||
cd "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}" && print_map_file "$@" > ${TARGET_FILE}
 | 
			
		||||
=======
 | 
			
		||||
print_def_file() {
 | 
			
		||||
    echo "EXPORTS"
 | 
			
		||||
    ctags -I ${CTAGS_IDENTIFIER_LIST} -f - --c-kinds=p "$@" | awk '/^pa_/ && !/(^pa_glib_|^pa_simple_)/ { print $1 }' | sort
 | 
			
		||||
| 
						 | 
				
			
			@ -28,3 +34,4 @@ shift 2
 | 
			
		|||
 | 
			
		||||
cd "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}" && print_map_file "$@" > ${MAP_FILE}
 | 
			
		||||
cd "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}" && print_def_file "$@" > ${DEF_FILE}
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,24 @@
 | 
			
		|||
if bashcompletiondir != 'no'
 | 
			
		||||
  aliases = []
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
  if get_option('daemon')
 | 
			
		||||
    aliases += [
 | 
			
		||||
      'pacmd',
 | 
			
		||||
      'pasuspender',
 | 
			
		||||
    ]
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  aliases += [
 | 
			
		||||
    'pacat',
 | 
			
		||||
    'pactl',
 | 
			
		||||
    'padsp',
 | 
			
		||||
    'paplay',
 | 
			
		||||
    'parec',
 | 
			
		||||
    'parecord',
 | 
			
		||||
  ]
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
  if get_option('daemon')
 | 
			
		||||
    aliases += [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,9 +120,15 @@ _pactl() {
 | 
			
		|||
                    set-default-sink set-sink-port get-default-source set-default-source
 | 
			
		||||
                    set-source-port get-sink-volume set-sink-volume get-source-volume
 | 
			
		||||
                    set-source-volume set-sink-input-volume set-source-output-volume
 | 
			
		||||
<<<<<<< HEAD:shell-completion/bash/pulseaudio
 | 
			
		||||
                    set-sink-mute set-source-mute set-sink-input-mute
 | 
			
		||||
                    set-source-output-mute set-sink-formats set-port-latency-offset
 | 
			
		||||
                    subscribe send-message help)
 | 
			
		||||
=======
 | 
			
		||||
                    get-sink-mute set-sink-mute get-source-mute set-source-mute
 | 
			
		||||
                    set-sink-input-mute set-source-output-mute set-sink-formats
 | 
			
		||||
                    set-port-latency-offset subscribe send-message help)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336:shell-completion/bash/pactl
 | 
			
		||||
 | 
			
		||||
    _init_completion -n = || return
 | 
			
		||||
    preprev=${words[$cword-2]}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -171,6 +171,9 @@ load-module module-filter-apply
 | 
			
		|||
 | 
			
		||||
### Allow including a default.pa.d directory, which if present, can be used
 | 
			
		||||
### for additional configuration snippets.
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
### Note that those snippet files must have a .pa file extension, not .conf
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
.nofail
 | 
			
		||||
.include @PA_DEFAULT_CONFIG_DIR_UNQUOTED@/default.pa.d
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,8 +30,13 @@ executable('pulseaudio',
 | 
			
		|||
  install_rpath : privlibdir,
 | 
			
		||||
  include_directories : [configinc, topinc],
 | 
			
		||||
  link_args : ['-ffast-math'],
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  link_with : [libpulsecore, libpulsecommon, libpulse],
 | 
			
		||||
  dependencies : [ltdl_dep, cap_dep, dbus_dep, libsystemd_dep, dl_dep, libintl_dep, platform_dep, platform_socket_dep],
 | 
			
		||||
=======
 | 
			
		||||
  link_with : [libpulsecore],
 | 
			
		||||
  dependencies : [ltdl_dep, cap_dep, dbus_dep, libsystemd_dep, dl_dep, libintl_dep, platform_dep, platform_socket_dep, libpulsecommon_dep, libpulse_dep],
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  c_args : pa_c_args,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,6 +69,9 @@ load-module module-position-event-sounds
 | 
			
		|||
 | 
			
		||||
### Allow including a system.pa.d directory, which if present, can be used
 | 
			
		||||
### for additional configuration snippets.
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
### Note that those snippet files must have a .pa file extension, not .conf
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
.nofail
 | 
			
		||||
.include @PA_DEFAULT_CONFIG_DIR_UNQUOTED@/system.pa.d
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -182,6 +182,29 @@ if host_machine.system() == 'windows'
 | 
			
		|||
else
 | 
			
		||||
  libpulsecommon_sources += [
 | 
			
		||||
    'pulsecore/mutex-posix.c',
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    'pulsecore/semaphore-posix.c',
 | 
			
		||||
    'pulsecore/thread-posix.c'
 | 
			
		||||
  ]
 | 
			
		||||
endif
 | 
			
		||||
# FIXME: Do SIMD things
 | 
			
		||||
 | 
			
		||||
libpulsecommon = shared_library('pulsecommon-' + pa_version_major_minor,
 | 
			
		||||
  libpulsecommon_sources,
 | 
			
		||||
  libpulsecommon_headers,
 | 
			
		||||
  include_directories : [configinc, topinc],
 | 
			
		||||
  c_args : [pa_c_args],
 | 
			
		||||
  link_args : [nodelete_link_args],
 | 
			
		||||
  install : true,
 | 
			
		||||
  install_dir : privlibdir,
 | 
			
		||||
  dependencies : [
 | 
			
		||||
    libm_dep, thread_dep, dl_dep, shm_dep, iconv_dep, sndfile_dep, dbus_dep,
 | 
			
		||||
    x11_dep, libsystemd_dep, glib_dep.partial_dependency(compile_args: true),
 | 
			
		||||
    gtk_dep.partial_dependency(compile_args: true), asyncns_dep, libintl_dep,
 | 
			
		||||
    platform_dep, tcpwrap_dep, platform_socket_dep, execinfo_dep,
 | 
			
		||||
  ],
 | 
			
		||||
  implicit_include_directories : false)
 | 
			
		||||
=======
 | 
			
		||||
    'pulsecore/poll-posix.c',
 | 
			
		||||
    'pulsecore/thread-posix.c',
 | 
			
		||||
  ]
 | 
			
		||||
| 
						 | 
				
			
			@ -215,10 +238,15 @@ else
 | 
			
		|||
    implicit_include_directories : false)
 | 
			
		||||
 | 
			
		||||
  libpulsecommon_dep = declare_dependency(link_with: libpulsecommon)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
  subdir('pulse')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
subdir('pulse')
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
if get_option('daemon')
 | 
			
		||||
  subdir('pulsecore')
 | 
			
		||||
  subdir('daemon')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,15 +107,22 @@ ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1011", ENV{PULSE_PROFILE_SET}="nativ
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1001", ENV{PULSE_PROFILE_SET}="native-instruments-komplete-audio6.conf"
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
# This entry is for the Komplete Audio 6 MK2, which has a different ID, but is functionally identical to the Komplete Audio 6.
 | 
			
		||||
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1870", ENV{PULSE_PROFILE_SET}="native-instruments-komplete-audio6.conf"
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1021", ENV{PULSE_PROFILE_SET}="native-instruments-traktor-audio10.conf"
 | 
			
		||||
ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudio-fasttrack-pro.conf"
 | 
			
		||||
ATTRS{idVendor}=="045e", ATTRS{idProduct}=="02bb", ENV{PULSE_PROFILE_SET}="kinect-audio.conf"
 | 
			
		||||
ATTRS{idVendor}=="041e", ATTRS{idProduct}=="322c", ENV{PULSE_PROFILE_SET}="sb-omni-surround-5.1.conf"
 | 
			
		||||
ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4014", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf"
 | 
			
		||||
ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="402e", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf"
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2902", ENV{PULSE_PROFILE_SET}="behringer-umc22.conf"
 | 
			
		||||
=======
 | 
			
		||||
ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2902", ENV{PULSE_PROFILE_SET}="texas-instruments-pcm2902.conf"
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="0269", ENV{PULSE_PROFILE_SET}="hp-tbt-dock-120w-g2.conf"
 | 
			
		||||
ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="0567", ENV{PULSE_PROFILE_SET}="hp-tbt-dock-audio-module.conf"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,8 +132,11 @@ ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1260", ENV{PULSE_PROFILE_SET}="usb-g
 | 
			
		|||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12ad", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
 | 
			
		||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
 | 
			
		||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
# ID 1038:1282 is for SteelSeries GameDAC
 | 
			
		||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1282", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
# ID 1038:12c4 is for Arctis 9
 | 
			
		||||
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12c4", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
 | 
			
		||||
# Lucidsound LS31
 | 
			
		||||
| 
						 | 
				
			
			@ -168,6 +178,8 @@ ATTRS{idVendor}=="1395", ATTRS{idProduct}=="00a0", ENV{PULSE_PROFILE_SET}="sennh
 | 
			
		|||
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="005f", ENV{PULSE_PROFILE_SET}="sennheiser-gsx.conf"
 | 
			
		||||
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="00a1", ENV{PULSE_PROFILE_SET}="sennheiser-gsx.conf"
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
# Sennheiser GSA 70 wireless USB dongle for GSP 670
 | 
			
		||||
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="0089", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
 | 
			
		||||
# EPOS GSA 70 wireless USB dongle for GSP 670 (Sennheiser GSA 70 with updated firmware)
 | 
			
		||||
| 
						 | 
				
			
			@ -178,6 +190,7 @@ ATTRS{idVendor}=="1395", ATTRS{idProduct}=="008a", ENV{PULSE_PROFILE_SET}="usb-g
 | 
			
		|||
# Asus Xonar SE
 | 
			
		||||
ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="189d", ENV{PULSE_PROFILE_SET}="asus-xonar-se.conf"
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
GOTO="pulseaudio_end"
 | 
			
		||||
 | 
			
		||||
LABEL="pulseaudio_check_pci"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2851,22 +2851,43 @@ static int path_verify(pa_alsa_path *p) {
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static char *get_path_config_path(const char *paths_dir, const char *fname) {
 | 
			
		||||
    char *path_config_path;
 | 
			
		||||
=======
 | 
			
		||||
static char *get_data_path(const char *data_dir, const char *data_type, const char *fname) {
 | 
			
		||||
    char *result;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    char *dir;
 | 
			
		||||
    char *data_home;
 | 
			
		||||
    pa_dynarray *data_dirs;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    if (paths_dir) {
 | 
			
		||||
        path_config_path = pa_maybe_prefix_path(fname, paths_dir);
 | 
			
		||||
        if (access(path_config_path, R_OK) == 0)
 | 
			
		||||
            return path_config_path;
 | 
			
		||||
        else
 | 
			
		||||
            pa_xfree(path_config_path);
 | 
			
		||||
=======
 | 
			
		||||
    if (data_dir) {
 | 
			
		||||
        result = pa_maybe_prefix_path(fname, data_dir);
 | 
			
		||||
        if (access(result, R_OK) == 0)
 | 
			
		||||
            return result;
 | 
			
		||||
        else
 | 
			
		||||
            pa_xfree(result);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_RUNNING_FROM_BUILD_TREE
 | 
			
		||||
    if (pa_run_from_build_tree()) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        path_config_path = pa_maybe_prefix_path(fname, PA_SRCDIR "/modules/alsa/mixer/paths/");
 | 
			
		||||
        if (access(path_config_path, R_OK) == 0)
 | 
			
		||||
            return path_config_path;
 | 
			
		||||
        else
 | 
			
		||||
            pa_xfree(path_config_path);
 | 
			
		||||
=======
 | 
			
		||||
        dir = pa_sprintf_malloc(PA_SRCDIR "/modules/alsa/mixer/%s/", data_type);
 | 
			
		||||
        result = pa_maybe_prefix_path(fname, dir);
 | 
			
		||||
        pa_xfree(dir);
 | 
			
		||||
| 
						 | 
				
			
			@ -2875,10 +2896,23 @@ static char *get_data_path(const char *data_dir, const char *data_type, const ch
 | 
			
		|||
            return result;
 | 
			
		||||
        else
 | 
			
		||||
            pa_xfree(result);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (pa_get_data_home_dir(&data_home) == 0) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "paths", data_home);
 | 
			
		||||
        pa_xfree(data_home);
 | 
			
		||||
 | 
			
		||||
        path_config_path = pa_maybe_prefix_path(fname, dir);
 | 
			
		||||
        pa_xfree(dir);
 | 
			
		||||
 | 
			
		||||
        if (access(path_config_path, R_OK) == 0)
 | 
			
		||||
            return path_config_path;
 | 
			
		||||
        else
 | 
			
		||||
            pa_xfree(path_config_path);
 | 
			
		||||
=======
 | 
			
		||||
        dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "%s", data_home, data_type);
 | 
			
		||||
        pa_xfree(data_home);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2889,6 +2923,7 @@ static char *get_data_path(const char *data_dir, const char *data_type, const ch
 | 
			
		|||
            return result;
 | 
			
		||||
        else
 | 
			
		||||
            pa_xfree(result);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pa_get_data_dirs(&data_dirs) == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2896,6 +2931,18 @@ static char *get_data_path(const char *data_dir, const char *data_type, const ch
 | 
			
		|||
        const char *n;
 | 
			
		||||
 | 
			
		||||
        PA_DYNARRAY_FOREACH(n, data_dirs, idx) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "paths", n);
 | 
			
		||||
            path_config_path = pa_maybe_prefix_path(fname, dir);
 | 
			
		||||
            pa_xfree(dir);
 | 
			
		||||
 | 
			
		||||
            if (access(path_config_path, R_OK) == 0) {
 | 
			
		||||
                pa_dynarray_free(data_dirs);
 | 
			
		||||
                return path_config_path;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                pa_xfree(path_config_path);
 | 
			
		||||
=======
 | 
			
		||||
            dir = pa_sprintf_malloc("%s" PA_PATH_SEP "alsa-mixer" PA_PATH_SEP "%s", n, data_type);
 | 
			
		||||
            result = pa_maybe_prefix_path(fname, dir);
 | 
			
		||||
            pa_xfree(dir);
 | 
			
		||||
| 
						 | 
				
			
			@ -2906,17 +2953,23 @@ static char *get_data_path(const char *data_dir, const char *data_type, const ch
 | 
			
		|||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                pa_xfree(result);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pa_dynarray_free(data_dirs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    path_config_path = pa_maybe_prefix_path(fname, PA_ALSA_PATHS_DIR);
 | 
			
		||||
    return path_config_path;
 | 
			
		||||
=======
 | 
			
		||||
    dir = pa_sprintf_malloc(PA_ALSA_DATA_DIR PA_PATH_SEP "%s", data_type);
 | 
			
		||||
    result = pa_maybe_prefix_path(fname, dir);
 | 
			
		||||
    pa_xfree(dir);
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2983,7 +3036,11 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
 | 
			
		|||
    items[2].data = &p->description;
 | 
			
		||||
    items[3].data = &mute_during_activation;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    fn = get_path_config_path(paths_dir, fname);
 | 
			
		||||
=======
 | 
			
		||||
    fn = get_data_path(paths_dir, "paths", fname);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_log_info("Loading path config: %s", fn);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2350,11 +2350,15 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
 | 
			
		|||
    bool volume_is_set;
 | 
			
		||||
    bool mute_is_set;
 | 
			
		||||
    pa_alsa_profile_set *profile_set = NULL;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    void *state;
 | 
			
		||||
=======
 | 
			
		||||
    void *state = NULL;
 | 
			
		||||
#ifdef USE_SMOOTHER_2
 | 
			
		||||
    snd_pcm_info_t* pcm_info;
 | 
			
		||||
    const char *id;
 | 
			
		||||
#endif
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_assert(m);
 | 
			
		||||
    pa_assert(ma);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1085,10 +1085,17 @@ static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle,
 | 
			
		|||
        PA_HASHMAP_FOREACH_KV(verb_name, path, data->paths, state2) {
 | 
			
		||||
            if (pa_alsa_path_probe(path, NULL, mixer_handle, ignore_dB) < 0) {
 | 
			
		||||
                pa_log_warn("Could not probe path: %s, using s/w volume", path->name);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
                pa_hashmap_remove(data->paths, profile);
 | 
			
		||||
            } else if (!path->has_volume) {
 | 
			
		||||
                pa_log_warn("Path %s is not a volume control", path->name);
 | 
			
		||||
                pa_hashmap_remove(data->paths, profile);
 | 
			
		||||
=======
 | 
			
		||||
                pa_hashmap_remove(data->paths, verb_name);
 | 
			
		||||
            } else if (!path->has_volume && !path->has_mute) {
 | 
			
		||||
                pa_log_warn("Path %s is not a volume or mute control", path->name);
 | 
			
		||||
                pa_hashmap_remove(data->paths, verb_name);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            } else
 | 
			
		||||
                pa_log_debug("Set up h/w %s using '%s' for %s:%s", path->has_volume ? "volume" : "mute",
 | 
			
		||||
                                path->name, verb_name, port->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -1706,11 +1713,29 @@ static void alsa_mapping_add_ucm_modifier(pa_alsa_mapping *m, pa_alsa_ucm_modifi
 | 
			
		|||
        pa_channel_map_init(&m->channel_map);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static pa_alsa_mapping* ucm_alsa_mapping_get(pa_alsa_ucm_config *ucm, pa_alsa_profile_set *ps, const char *verb_name, const char *device_str, bool is_sink) {
 | 
			
		||||
    pa_alsa_mapping *m;
 | 
			
		||||
    char *mapping_name;
 | 
			
		||||
    size_t ucm_alibpref_len = 0;
 | 
			
		||||
    const char *value;
 | 
			
		||||
 | 
			
		||||
    /* find private alsa-lib's configuration device prefix */
 | 
			
		||||
    if (snd_use_case_get(ucm->ucm_mgr, "_alibpref", &value) == 0) {
 | 
			
		||||
        if (value[0] && pa_startswith(device_str, value))
 | 
			
		||||
            ucm_alibpref_len = strlen(value);
 | 
			
		||||
 | 
			
		||||
        free((void *)value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mapping_name = pa_sprintf_malloc("Mapping %s: %s: %s", verb_name, device_str + ucm_alibpref_len, is_sink ? "sink" : "source");
 | 
			
		||||
=======
 | 
			
		||||
static pa_alsa_mapping* ucm_alsa_mapping_get(pa_alsa_ucm_config *ucm, pa_alsa_profile_set *ps, const char *verb_name, const char *ucm_name, bool is_sink) {
 | 
			
		||||
    pa_alsa_mapping *m;
 | 
			
		||||
    char *mapping_name;
 | 
			
		||||
 | 
			
		||||
    mapping_name = pa_sprintf_malloc("Mapping %s: %s: %s", verb_name, ucm_name, is_sink ? "sink" : "source");
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    m = pa_alsa_mapping_get(ps, mapping_name);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1734,7 +1759,11 @@ static int ucm_create_mapping_direction(
 | 
			
		|||
    pa_alsa_mapping *m;
 | 
			
		||||
    unsigned priority, rate, channels;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    m = ucm_alsa_mapping_get(ucm, ps, verb_name, device_str, is_sink);
 | 
			
		||||
=======
 | 
			
		||||
    m = ucm_alsa_mapping_get(ucm, ps, verb_name, device_name, is_sink);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    if (!m)
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -1782,10 +1811,19 @@ static int ucm_create_mapping_for_modifier(
 | 
			
		|||
 | 
			
		||||
    pa_alsa_mapping *m;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    m = ucm_alsa_mapping_get(ucm, ps, verb_name, device_str, is_sink);
 | 
			
		||||
 | 
			
		||||
    if (!m)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    pa_log_info("UCM mapping: %s modifier %s", m->name, mod_name);
 | 
			
		||||
=======
 | 
			
		||||
    m = ucm_alsa_mapping_get(ucm, ps, verb_name, mod_name, is_sink);
 | 
			
		||||
 | 
			
		||||
    if (!m)
 | 
			
		||||
        return -1;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_log_info("UCM mapping: %s modifier %s", m->name, mod_name);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2196,10 +2234,16 @@ static void ucm_mapping_jack_probe(pa_alsa_mapping *m, pa_hashmap *mixers) {
 | 
			
		|||
    if (!dev->jack || !dev->jack->mixer_device_name)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        has_control = pa_alsa_mixer_find_card(mixer_handle, &dev->jack->alsa_id, 0) != NULL;
 | 
			
		||||
        pa_alsa_jack_set_has_control(dev->jack, has_control);
 | 
			
		||||
        pa_log_info("UCM jack %s has_control=%d", dev->jack->name, dev->jack->has_control);
 | 
			
		||||
=======
 | 
			
		||||
    mixer_handle = pa_alsa_open_mixer_by_name(mixers, dev->jack->mixer_device_name, true);
 | 
			
		||||
    if (!mixer_handle) {
 | 
			
		||||
        pa_log_error("Unable to determine open mixer device '%s' for jack %s", dev->jack->mixer_device_name, dev->jack->name);
 | 
			
		||||
        return;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    has_control = pa_alsa_mixer_find_card(mixer_handle, &dev->jack->alsa_id, 0) != NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1684,7 +1684,11 @@ static snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, struct pa_alsa_mixer_id *alsa_id, unsigned int device) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, alsa_id->name, alsa_id->index, device);
 | 
			
		||||
=======
 | 
			
		||||
    return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, alsa_id->name, alsa_id->index, device, 0);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1852,6 +1856,29 @@ snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, boo
 | 
			
		|||
    pa_assert(dev);
 | 
			
		||||
 | 
			
		||||
    pm = pa_hashmap_get(mixers, dev);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    /* The quick card number/index lookup (hw:#)
 | 
			
		||||
     * We already know the card number/index, thus use the mixer
 | 
			
		||||
     * from the cache at first.
 | 
			
		||||
     */
 | 
			
		||||
    if (!pm && pa_strneq(dev, "hw:", 3)) {
 | 
			
		||||
        const char *s = dev + 3;
 | 
			
		||||
        int card_index;
 | 
			
		||||
        while (*s && *s >= '0' && *s <= '9') s++;
 | 
			
		||||
        if (*s == '\0' && pa_atoi(dev + 3, &card_index) >= 0) {
 | 
			
		||||
            PA_HASHMAP_FOREACH_KV(dev2, pm, mixers, state) {
 | 
			
		||||
                if (pm->card_index == card_index) {
 | 
			
		||||
                    dev = dev2;
 | 
			
		||||
                    pm = pa_hashmap_get(mixers, dev);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (pm) {
 | 
			
		||||
        if (!probe)
 | 
			
		||||
            pm->used_for_probe_only = false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										68
									
								
								src/modules/alsa/mixer/profile-sets/behringer-umc22.conf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/modules/alsa/mixer/profile-sets/behringer-umc22.conf
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
# This file is part of PulseAudio.
 | 
			
		||||
#
 | 
			
		||||
# PulseAudio is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU Lesser General Public License as
 | 
			
		||||
# published by the Free Software Foundation; either version 2.1 of the
 | 
			
		||||
# License, or (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# PulseAudio is distributed in the hope that it will be useful, but
 | 
			
		||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 | 
			
		||||
# General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
; Behringer U-Phoria UMC22
 | 
			
		||||
;
 | 
			
		||||
; Default mapping only allows to use stereo input and sound card has two
 | 
			
		||||
; physical input channels.
 | 
			
		||||
;
 | 
			
		||||
; However in case of only using a single input channel (like condenser
 | 
			
		||||
; microphone) only one channel will have any sound, which is often
 | 
			
		||||
; inconvenient for casual use.
 | 
			
		||||
;
 | 
			
		||||
; This config includes mono input options which makes it much more
 | 
			
		||||
; friendly in single input configuration.
 | 
			
		||||
;
 | 
			
		||||
; This config also removes default digital input/output mappings that do
 | 
			
		||||
; not physically exist on this card.
 | 
			
		||||
;
 | 
			
		||||
; Added by Nazar Mokrynskyi <nazar@mokrynskyi.com>
 | 
			
		||||
 | 
			
		||||
[General]
 | 
			
		||||
auto-profiles = yes
 | 
			
		||||
 | 
			
		||||
[Mapping analog-stereo-input]
 | 
			
		||||
device-strings = hw:%f
 | 
			
		||||
channel-map = left,right
 | 
			
		||||
paths-input = analog-input-mic
 | 
			
		||||
direction = input
 | 
			
		||||
priority = 4
 | 
			
		||||
 | 
			
		||||
[Mapping analog-mono]
 | 
			
		||||
device-strings = hw:%f
 | 
			
		||||
channel-map = mono,mono
 | 
			
		||||
paths-input = analog-input-mic
 | 
			
		||||
direction = input
 | 
			
		||||
priority = 3
 | 
			
		||||
 | 
			
		||||
[Mapping analog-mono-left]
 | 
			
		||||
device-strings = hw:%f
 | 
			
		||||
channel-map = mono,aux1
 | 
			
		||||
paths-input = analog-input-mic
 | 
			
		||||
direction = input
 | 
			
		||||
priority = 2
 | 
			
		||||
 | 
			
		||||
[Mapping analog-mono-right]
 | 
			
		||||
device-strings = hw:%f
 | 
			
		||||
channel-map = aux1,mono
 | 
			
		||||
paths-input = analog-input-mic
 | 
			
		||||
direction = input
 | 
			
		||||
priority = 1
 | 
			
		||||
 | 
			
		||||
[Mapping analog-stereo-output]
 | 
			
		||||
device-strings = front:%f
 | 
			
		||||
channel-map = left,right
 | 
			
		||||
paths-output = analog-output
 | 
			
		||||
direction = output
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,11 @@ channel-map = aux0,aux1,left,right,aux2,aux3
 | 
			
		|||
direction = output
 | 
			
		||||
 | 
			
		||||
[Mapping stereo-out-ef]
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
description = Analog Stereo 5/6
 | 
			
		||||
=======
 | 
			
		||||
description = Stereo 5/6 (S/PDIF)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
device-strings = hw:%f,0,0
 | 
			
		||||
channel-map = aux0,aux1,aux2,aux3,left,right
 | 
			
		||||
direction = output
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +55,11 @@ channel-map = mono,aux0,aux1,aux2,aux3,aux4
 | 
			
		|||
direction = input
 | 
			
		||||
 | 
			
		||||
[Mapping analog-mono-in-b]
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
description = Anlog Mono Input 2
 | 
			
		||||
=======
 | 
			
		||||
description = Analog Mono Input 2
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
device-strings = hw:%f,0,0
 | 
			
		||||
channel-map = aux0,mono,aux1,aux2,aux3,aux4
 | 
			
		||||
direction = input
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +77,11 @@ channel-map = aux0,aux1,left,right,aux2,aux3
 | 
			
		|||
direction = input
 | 
			
		||||
 | 
			
		||||
[Mapping stereo-in-ef]
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
description = Stereo Input 5/6
 | 
			
		||||
=======
 | 
			
		||||
description = Stereo Input 5/6 (S/PDIF)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
device-strings = hw:%f,0,0
 | 
			
		||||
channel-map = aux0,aux1,aux2,aux3,left,right
 | 
			
		||||
direction = input
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,9 @@ typedef struct pa_a2dp_endpoint_conf {
 | 
			
		|||
    /* Returns true if the codec can be supported on the system */
 | 
			
		||||
    bool (*can_be_supported)(bool for_encoding);
 | 
			
		||||
 | 
			
		||||
    /* Returns true if the codec can be supported on the system */
 | 
			
		||||
    bool (*can_be_supported)(bool for_encoding);
 | 
			
		||||
 | 
			
		||||
    /* Returns true if codec accepts capabilities, for_encoding is true when
 | 
			
		||||
     * capabilities are used for encoding */
 | 
			
		||||
    bool (*can_accept_capabilities)(const uint8_t *capabilities_buffer, uint8_t capabilities_size, bool for_encoding);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -490,7 +490,11 @@ static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
 | 
			
		|||
static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
 | 
			
		||||
    size_t written;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
 | 
			
		||||
=======
 | 
			
		||||
    written = gst_transcode_buffer(codec_info, timestamp, input_buffer, input_size, output_buffer, output_size, processed);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (PA_UNLIKELY(*processed == 0 || *processed != input_size))
 | 
			
		||||
        pa_log_error("aptX encoding error");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -526,7 +530,11 @@ static size_t encode_buffer_hd(void *codec_info, uint32_t timestamp, const uint8
 | 
			
		|||
static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
 | 
			
		||||
    size_t written;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
 | 
			
		||||
=======
 | 
			
		||||
    written = gst_transcode_buffer(codec_info, -1, input_buffer, input_size, output_buffer, output_size, processed);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    /* Due to aptX latency, aptx_decode starts filling output buffer after 90 input samples.
 | 
			
		||||
     * If input buffer contains less than 90 samples, aptx_decode returns zero (=no output)
 | 
			
		||||
| 
						 | 
				
			
			@ -556,6 +564,10 @@ static size_t decode_buffer_hd(void *codec_info, const uint8_t *input_buffer, si
 | 
			
		|||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx = {
 | 
			
		||||
    .id = { A2DP_CODEC_VENDOR, APTX_VENDOR_ID, APTX_CODEC_ID },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint,
 | 
			
		||||
| 
						 | 
				
			
			@ -579,6 +591,10 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx = {
 | 
			
		|||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_aptx_hd = {
 | 
			
		||||
    .id = { A2DP_CODEC_VENDOR, APTX_HD_VENDOR_ID, APTX_HD_CODEC_ID },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities_hd,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint_hd,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,14 +22,20 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
#include <pulsecore/log.h>
 | 
			
		||||
#include <pulsecore/macro.h>
 | 
			
		||||
#include <pulsecore/once.h>
 | 
			
		||||
#include <pulsecore/core-util.h>
 | 
			
		||||
#include <pulse/sample.h>
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
#include <pulse/timeval.h>
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
#include <pulse/util.h>
 | 
			
		||||
 | 
			
		||||
#include "a2dp-codecs.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +47,85 @@ static void app_sink_eos(GstAppSink *appsink, gpointer userdata) {
 | 
			
		|||
    pa_log_debug("Sink got EOS");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
/* Called from the GStreamer streaming thread */
 | 
			
		||||
static GstFlowReturn app_sink_new_sample(GstAppSink *appsink, gpointer userdata) {
 | 
			
		||||
    struct gst_info *info = (struct gst_info *) userdata;
 | 
			
		||||
    GstSample *sample = NULL;
 | 
			
		||||
    GstBuffer *buf;
 | 
			
		||||
 | 
			
		||||
    sample = gst_app_sink_pull_sample(GST_APP_SINK(info->app_sink));
 | 
			
		||||
    if (!sample)
 | 
			
		||||
        return GST_FLOW_OK;
 | 
			
		||||
 | 
			
		||||
    buf = gst_sample_get_buffer(sample);
 | 
			
		||||
    gst_buffer_ref(buf);
 | 
			
		||||
    gst_adapter_push(info->sink_adapter, buf);
 | 
			
		||||
    gst_sample_unref(sample);
 | 
			
		||||
    pa_fdsem_post(info->sample_ready_fdsem);
 | 
			
		||||
 | 
			
		||||
    return GST_FLOW_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gst_deinit_common(struct gst_info *info) {
 | 
			
		||||
    if (!info)
 | 
			
		||||
        return;
 | 
			
		||||
    if (info->sample_ready_fdsem)
 | 
			
		||||
        pa_fdsem_free(info->sample_ready_fdsem);
 | 
			
		||||
    if (info->app_src)
 | 
			
		||||
        gst_object_unref(info->app_src);
 | 
			
		||||
    if (info->app_sink)
 | 
			
		||||
        gst_object_unref(info->app_sink);
 | 
			
		||||
    if (info->sink_adapter)
 | 
			
		||||
        g_object_unref(info->sink_adapter);
 | 
			
		||||
    if (info->pipeline)
 | 
			
		||||
        gst_object_unref(info->pipeline);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GstBusSyncReply sync_bus_handler (GstBus *bus, GstMessage *message, struct gst_info *info) {
 | 
			
		||||
    GstStreamStatusType type;
 | 
			
		||||
    GstElement *owner;
 | 
			
		||||
 | 
			
		||||
    switch (GST_MESSAGE_TYPE (message)) {
 | 
			
		||||
        case GST_MESSAGE_STREAM_STATUS:
 | 
			
		||||
 | 
			
		||||
            gst_message_parse_stream_status (message, &type, &owner);
 | 
			
		||||
 | 
			
		||||
            switch (type) {
 | 
			
		||||
            case GST_STREAM_STATUS_TYPE_ENTER:
 | 
			
		||||
                pa_log_debug("GStreamer pipeline thread starting up");
 | 
			
		||||
                if (info->core->realtime_scheduling)
 | 
			
		||||
                    pa_thread_make_realtime(info->core->realtime_priority);
 | 
			
		||||
                break;
 | 
			
		||||
            case GST_STREAM_STATUS_TYPE_LEAVE:
 | 
			
		||||
                pa_log_debug("GStreamer pipeline thread shutting down");
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* pass all messages on the async queue */
 | 
			
		||||
    return GST_BUS_PASS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool gst_init_common(struct gst_info *info) {
 | 
			
		||||
    GstElement *pipeline = NULL;
 | 
			
		||||
    GstElement *appsrc = NULL, *appsink = NULL;
 | 
			
		||||
    GstAdapter *adapter;
 | 
			
		||||
    GstAppSinkCallbacks callbacks = { 0, };
 | 
			
		||||
    GstBus *bus;
 | 
			
		||||
 | 
			
		||||
    appsrc = gst_element_factory_make("appsrc", "app_source");
 | 
			
		||||
    if (!appsrc) {
 | 
			
		||||
        pa_log_error("Could not create appsrc element");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
    g_object_set(appsrc, "is-live", FALSE, "format", GST_FORMAT_TIME, "stream-type", 0, "max-bytes", 0, NULL);
 | 
			
		||||
=======
 | 
			
		||||
static void gst_deinit_common(struct gst_info *info) {
 | 
			
		||||
    if (!info)
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +139,7 @@ bool gst_init_common(struct gst_info *info) {
 | 
			
		|||
    GstElement *bin = NULL;
 | 
			
		||||
    GstElement *appsink = NULL;
 | 
			
		||||
    GstAppSinkCallbacks callbacks = { 0, };
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    appsink = gst_element_factory_make("appsink", "app_sink");
 | 
			
		||||
    if (!appsink) {
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +149,26 @@ bool gst_init_common(struct gst_info *info) {
 | 
			
		|||
    g_object_set(appsink, "sync", FALSE, "async", FALSE, "enable-last-sample", FALSE, NULL);
 | 
			
		||||
 | 
			
		||||
    callbacks.eos = app_sink_eos;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    callbacks.new_sample = app_sink_new_sample;
 | 
			
		||||
    gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, info, NULL);
 | 
			
		||||
 | 
			
		||||
    adapter = gst_adapter_new();
 | 
			
		||||
    pa_assert(adapter);
 | 
			
		||||
 | 
			
		||||
    pipeline = gst_pipeline_new(NULL);
 | 
			
		||||
    pa_assert(pipeline);
 | 
			
		||||
 | 
			
		||||
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
 | 
			
		||||
    gst_bus_set_sync_handler (bus, (GstBusSyncHandler) sync_bus_handler, info, NULL);
 | 
			
		||||
    gst_object_unref (bus);
 | 
			
		||||
 | 
			
		||||
    info->app_src = appsrc;
 | 
			
		||||
    info->app_sink = appsink;
 | 
			
		||||
    info->sink_adapter = adapter;
 | 
			
		||||
    info->pipeline = pipeline;
 | 
			
		||||
    info->sample_ready_fdsem = pa_fdsem_new();
 | 
			
		||||
=======
 | 
			
		||||
    gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, info, NULL);
 | 
			
		||||
 | 
			
		||||
    bin = gst_bin_new(NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -70,20 +176,68 @@ bool gst_init_common(struct gst_info *info) {
 | 
			
		|||
 | 
			
		||||
    info->app_sink = appsink;
 | 
			
		||||
    info->bin = bin;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    if (appsrc)
 | 
			
		||||
        gst_object_unref(appsrc);
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (appsink)
 | 
			
		||||
        gst_object_unref(appsink);
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
/*
 | 
			
		||||
 * The idea of using buffer probes is as follows. We set a buffer probe on the
 | 
			
		||||
 * encoder sink pad. In the buffer probe, we set an idle probe on the upstream
 | 
			
		||||
 * source pad. In encode_buffer, we wait on the fdsem. The fdsem gets posted
 | 
			
		||||
 * when either new_sample or idle probe gets called. We do this, to make the
 | 
			
		||||
 * appsink behave synchronously.
 | 
			
		||||
 *
 | 
			
		||||
 * For buffer probes, see
 | 
			
		||||
 * https://gstreamer.freedesktop.org/documentation/additional/design/probes.html?gi-language=c
 | 
			
		||||
 */
 | 
			
		||||
static GstPadProbeReturn gst_sink_buffer_idle_probe(GstPad *pad, GstPadProbeInfo *probe_info, gpointer userdata)
 | 
			
		||||
{
 | 
			
		||||
    struct gst_info *info = (struct gst_info *)userdata;
 | 
			
		||||
 | 
			
		||||
    pa_assert(probe_info->type & GST_PAD_PROBE_TYPE_IDLE);
 | 
			
		||||
 | 
			
		||||
    pa_fdsem_post(info->sample_ready_fdsem);
 | 
			
		||||
 | 
			
		||||
    return GST_PAD_PROBE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GstPadProbeReturn gst_sink_buffer_probe(GstPad *pad, GstPadProbeInfo *probe_info, gpointer userdata)
 | 
			
		||||
{
 | 
			
		||||
    struct gst_info *info = (struct gst_info *)userdata;
 | 
			
		||||
    GstPad *peer_pad;
 | 
			
		||||
 | 
			
		||||
    pa_assert(probe_info->type & GST_PAD_PROBE_TYPE_BUFFER);
 | 
			
		||||
 | 
			
		||||
    peer_pad = gst_pad_get_peer(pad);
 | 
			
		||||
    gst_pad_add_probe(peer_pad, GST_PAD_PROBE_TYPE_IDLE, gst_sink_buffer_idle_probe, info, NULL);
 | 
			
		||||
    gst_object_unref(peer_pad);
 | 
			
		||||
 | 
			
		||||
    return GST_PAD_PROBE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) {
 | 
			
		||||
    gchar *sample_format;
 | 
			
		||||
    GstCaps *caps;
 | 
			
		||||
    int channel_mask;
 | 
			
		||||
=======
 | 
			
		||||
static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) {
 | 
			
		||||
    gchar *sample_format;
 | 
			
		||||
    GstCaps *caps;
 | 
			
		||||
    uint64_t channel_mask;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    switch (ss->format) {
 | 
			
		||||
        case PA_SAMPLE_S16LE:
 | 
			
		||||
| 
						 | 
				
			
			@ -130,10 +284,13 @@ static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) {
 | 
			
		|||
bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transcoder) {
 | 
			
		||||
    GstPad *pad;
 | 
			
		||||
    GstCaps *caps;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    GstEvent *event;
 | 
			
		||||
    GstSegment segment;
 | 
			
		||||
    GstEvent *stream_start;
 | 
			
		||||
    guint group_id;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_assert(transcoder);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -142,13 +299,30 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transc
 | 
			
		|||
    if (!gst_init_common(info))
 | 
			
		||||
        goto common_fail;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    caps = gst_create_caps_from_sample_spec(info->ss);
 | 
			
		||||
    if (for_encoding)
 | 
			
		||||
        g_object_set(info->app_src, "caps", caps, NULL);
 | 
			
		||||
    else
 | 
			
		||||
        g_object_set(info->app_sink, "caps", caps, NULL);
 | 
			
		||||
    gst_caps_unref(caps);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    gst_bin_add_many(GST_BIN(info->pipeline), info->app_src, transcoder, info->app_sink, NULL);
 | 
			
		||||
 | 
			
		||||
    if (!gst_element_link_many(info->app_src, transcoder, info->app_sink, NULL)) {
 | 
			
		||||
=======
 | 
			
		||||
    gst_bin_add_many(GST_BIN(info->bin), transcoder, info->app_sink, NULL);
 | 
			
		||||
 | 
			
		||||
    if (!gst_element_link_many(transcoder, info->app_sink, NULL)) {
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        pa_log_error("Failed to link codec elements into pipeline");
 | 
			
		||||
        goto pipeline_fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    if (gst_element_set_state(info->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
 | 
			
		||||
=======
 | 
			
		||||
    pad = gst_element_get_static_pad(transcoder, "sink");
 | 
			
		||||
    pa_assert_se(gst_element_add_pad(info->bin, gst_ghost_pad_new("sink", pad)));
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -159,10 +333,17 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transc
 | 
			
		|||
    info->pad_sink = pad;
 | 
			
		||||
 | 
			
		||||
    if (gst_element_set_state(info->bin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        pa_log_error("Could not start pipeline");
 | 
			
		||||
        goto pipeline_fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    /* See the comment on buffer probe functions */
 | 
			
		||||
    pad = gst_element_get_static_pad(transcoder, "sink");
 | 
			
		||||
    gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, gst_sink_buffer_probe, info, NULL);
 | 
			
		||||
    gst_object_unref(pad);
 | 
			
		||||
=======
 | 
			
		||||
    /* First, send stream-start sticky event */
 | 
			
		||||
    group_id = gst_util_group_id_next();
 | 
			
		||||
    stream_start = gst_event_new_stream_start("gst-codec-pa");
 | 
			
		||||
| 
						 | 
				
			
			@ -185,6 +366,7 @@ bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transc
 | 
			
		|||
    gst_segment_init(&segment, GST_FORMAT_TIME);
 | 
			
		||||
    event = gst_event_new_segment(&segment);
 | 
			
		||||
    gst_pad_send_event(info->pad_sink, event);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_log_info("GStreamer pipeline initialisation succeeded");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -208,6 +390,24 @@ common_fail:
 | 
			
		|||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
size_t gst_transcode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
 | 
			
		||||
    struct gst_info *info = (struct gst_info *) codec_info;
 | 
			
		||||
    gsize available, transcoded;
 | 
			
		||||
    GstBuffer *in_buf;
 | 
			
		||||
    GstMapInfo map_info;
 | 
			
		||||
    GstFlowReturn ret;
 | 
			
		||||
    size_t written = 0;
 | 
			
		||||
 | 
			
		||||
    in_buf = gst_buffer_new_allocate(NULL, input_size, NULL);
 | 
			
		||||
    pa_assert(in_buf);
 | 
			
		||||
 | 
			
		||||
    pa_assert_se(gst_buffer_map(in_buf, &map_info, GST_MAP_WRITE));
 | 
			
		||||
    memcpy(map_info.data, input_buffer, input_size);
 | 
			
		||||
    gst_buffer_unmap(in_buf, &map_info);
 | 
			
		||||
 | 
			
		||||
    ret = gst_app_src_push_buffer(GST_APP_SRC(info->app_src), in_buf);
 | 
			
		||||
=======
 | 
			
		||||
size_t gst_transcode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
 | 
			
		||||
    struct gst_info *info = (struct gst_info *) codec_info;
 | 
			
		||||
    gsize transcoded;
 | 
			
		||||
| 
						 | 
				
			
			@ -242,11 +442,27 @@ size_t gst_transcode_buffer(void *codec_info, uint32_t timestamp, const uint8_t
 | 
			
		|||
    pa_assert(GST_MINI_OBJECT_REFCOUNT_VALUE(in_buf) == 1);
 | 
			
		||||
    gst_mini_object_unref(GST_MINI_OBJECT_CAST(in_buf));
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (ret != GST_FLOW_OK) {
 | 
			
		||||
        pa_log_error("failed to push buffer for transcoding %d", ret);
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    pa_fdsem_wait(info->sample_ready_fdsem);
 | 
			
		||||
 | 
			
		||||
    available = gst_adapter_available(info->sink_adapter);
 | 
			
		||||
 | 
			
		||||
    if (available) {
 | 
			
		||||
        transcoded = PA_MIN(available, output_size);
 | 
			
		||||
 | 
			
		||||
        gst_adapter_copy(info->sink_adapter, output_buffer, 0, transcoded);
 | 
			
		||||
        gst_adapter_flush(info->sink_adapter, transcoded);
 | 
			
		||||
 | 
			
		||||
        written += transcoded;
 | 
			
		||||
    } else
 | 
			
		||||
        pa_log_debug("No transcoded data available in adapter");
 | 
			
		||||
=======
 | 
			
		||||
    while ((sample = gst_app_sink_try_pull_sample(GST_APP_SINK(info->app_sink), 0))) {
 | 
			
		||||
        in_buf = gst_sample_get_buffer(sample);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -260,6 +476,7 @@ size_t gst_transcode_buffer(void *codec_info, uint32_t timestamp, const uint8_t
 | 
			
		|||
        gst_buffer_unmap(in_buf, &map_info);
 | 
			
		||||
        gst_sample_unref(sample);
 | 
			
		||||
    }
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    *processed = input_size;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -274,6 +491,19 @@ fail:
 | 
			
		|||
void gst_codec_deinit(void *codec_info) {
 | 
			
		||||
    struct gst_info *info = (struct gst_info *) codec_info;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    if (info->sample_ready_fdsem)
 | 
			
		||||
        pa_fdsem_free(info->sample_ready_fdsem);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (info->pipeline) {
 | 
			
		||||
        gst_element_set_state(info->pipeline, GST_STATE_NULL);
 | 
			
		||||
        gst_object_unref(info->pipeline);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (info->sink_adapter)
 | 
			
		||||
        g_object_unref(info->sink_adapter);
 | 
			
		||||
=======
 | 
			
		||||
    if (info->bin) {
 | 
			
		||||
        gst_element_set_state(info->bin, GST_STATE_NULL);
 | 
			
		||||
        gst_object_unref(info->bin);
 | 
			
		||||
| 
						 | 
				
			
			@ -281,6 +511,7 @@ void gst_codec_deinit(void *codec_info) {
 | 
			
		|||
 | 
			
		||||
    if (info->pad_sink)
 | 
			
		||||
        gst_object_unref(GST_OBJECT(info->pad_sink));
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_xfree(info);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,15 +43,27 @@ struct gst_info {
 | 
			
		|||
        const a2dp_ldac_t *ldac_config;
 | 
			
		||||
    } a2dp_codec_t;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    GstElement *app_src, *app_sink;
 | 
			
		||||
    GstElement *pipeline;
 | 
			
		||||
    GstAdapter *sink_adapter;
 | 
			
		||||
 | 
			
		||||
    pa_fdsem *sample_ready_fdsem;
 | 
			
		||||
=======
 | 
			
		||||
    /* The appsink element that accumulates encoded/decoded buffers */
 | 
			
		||||
    GstElement *app_sink;
 | 
			
		||||
    GstElement *bin;
 | 
			
		||||
    /* The sink pad to push to-be-encoded/decoded buffers into */
 | 
			
		||||
    GstPad *pad_sink;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    uint16_t seq_num;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool gst_codec_init(struct gst_info *info, bool for_encoding, GstElement *transcoder);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
size_t gst_transcode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed);
 | 
			
		||||
=======
 | 
			
		||||
size_t gst_transcode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
void gst_codec_deinit(void *codec_info);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,16 @@ static bool can_be_supported(bool for_encoding) {
 | 
			
		|||
    }
 | 
			
		||||
    gst_object_unref(element_factory);
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    element_factory = gst_element_factory_find("rtpldacpay");
 | 
			
		||||
    if (element_factory == NULL) {
 | 
			
		||||
        pa_log_info("LDAC RTP payloader element `rtpldacpay` not found");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    gst_object_unref(element_factory);
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -199,6 +209,10 @@ static uint8_t fill_preferred_configuration(const pa_sample_spec *default_sample
 | 
			
		|||
 | 
			
		||||
GstElement *gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_encoding) {
 | 
			
		||||
    GstElement *bin;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    GstElement *rtpldacpay;
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    GstElement *enc;
 | 
			
		||||
    GstPad *pad;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -262,16 +276,39 @@ GstElement *gst_init_ldac(struct gst_info *info, pa_sample_spec *ss, bool for_en
 | 
			
		|||
            goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    rtpldacpay = gst_element_factory_make("rtpldacpay", "rtp_ldac_pay");
 | 
			
		||||
    if (!rtpldacpay) {
 | 
			
		||||
        pa_log_error("Could not create RTP LDAC payloader element");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bin = gst_bin_new("ldac_enc_bin");
 | 
			
		||||
    pa_assert(bin);
 | 
			
		||||
 | 
			
		||||
    gst_bin_add_many(GST_BIN(bin), enc, rtpldacpay, NULL);
 | 
			
		||||
 | 
			
		||||
    if (!gst_element_link(enc, rtpldacpay)) {
 | 
			
		||||
        pa_log_error("Failed to link LDAC encoder to LDAC RTP payloader");
 | 
			
		||||
        gst_object_unref(bin);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
=======
 | 
			
		||||
    bin = gst_bin_new("ldac_enc_bin");
 | 
			
		||||
    pa_assert(bin);
 | 
			
		||||
 | 
			
		||||
    gst_bin_add_many(GST_BIN(bin), enc, NULL);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pad = gst_element_get_static_pad(enc, "sink");
 | 
			
		||||
    pa_assert_se(gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad)));
 | 
			
		||||
    gst_object_unref(GST_OBJECT(pad));
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    pad = gst_element_get_static_pad(rtpldacpay, "src");
 | 
			
		||||
=======
 | 
			
		||||
    pad = gst_element_get_static_pad(enc, "src");
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    pa_assert_se(gst_element_add_pad(bin, gst_ghost_pad_new("src", pad)));
 | 
			
		||||
    gst_object_unref(GST_OBJECT(pad));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -401,6 +438,14 @@ static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    size_t written;
 | 
			
		||||
 | 
			
		||||
    written = gst_transcode_buffer(codec_info, input_buffer, input_size, output_buffer, output_size, processed);
 | 
			
		||||
    if (PA_UNLIKELY(*processed != input_size))
 | 
			
		||||
        pa_log_error("LDAC encoding error");
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
    struct gst_info *info = (struct gst_info *) codec_info;
 | 
			
		||||
    struct rtp_header *header;
 | 
			
		||||
    struct rtp_payload *payload;
 | 
			
		||||
| 
						 | 
				
			
			@ -428,11 +473,16 @@ static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t
 | 
			
		|||
        written += sizeof(*header) + sizeof(*payload);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    return written;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq = {
 | 
			
		||||
    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint,
 | 
			
		||||
| 
						 | 
				
			
			@ -455,6 +505,10 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq = {
 | 
			
		|||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq = {
 | 
			
		||||
    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint,
 | 
			
		||||
| 
						 | 
				
			
			@ -477,6 +531,10 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq = {
 | 
			
		|||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_mq = {
 | 
			
		||||
    .id = { A2DP_CODEC_VENDOR, LDAC_VENDOR_ID, LDAC_CODEC_ID },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,8 +38,11 @@
 | 
			
		|||
 | 
			
		||||
#define SBC_BITPOOL_DEC_STEP 5
 | 
			
		||||
#define SBC_BITPOOL_INC_STEP 1
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
#define SBC_SYNCWORD    0x9C
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
struct sbc_info {
 | 
			
		||||
    sbc_t sbc;                           /* Codec data */
 | 
			
		||||
| 
						 | 
				
			
			@ -56,12 +59,15 @@ struct sbc_info {
 | 
			
		|||
 | 
			
		||||
    uint8_t nr_blocks;
 | 
			
		||||
    uint8_t nr_subbands;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    bool boost_source_volume;
 | 
			
		||||
    /* Size of SBC frame fragment left over from previous decoding iteration */
 | 
			
		||||
    size_t frame_fragment_size;
 | 
			
		||||
    /* Maximum SBC frame size is 512 bytes when SBC compression ratio > 1 */
 | 
			
		||||
    uint8_t frame_fragment[512];
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool can_be_supported(bool for_encoding) {
 | 
			
		||||
| 
						 | 
				
			
			@ -116,6 +122,8 @@ static bool can_accept_capabilities_xq(const uint8_t *capabilities_buffer, uint8
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
static bool can_accept_capabilities_faststream(const uint8_t *capabilities_buffer, uint8_t capabilities_size, bool for_encoding) {
 | 
			
		||||
    const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) capabilities_buffer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +142,7 @@ static bool can_accept_capabilities_faststream(const uint8_t *capabilities_buffe
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static const char *choose_remote_endpoint(const pa_hashmap *capabilities_hashmap, const pa_sample_spec *default_sample_spec, bool for_encoding) {
 | 
			
		||||
    const pa_a2dp_codec_capabilities *a2dp_capabilities;
 | 
			
		||||
    const char *key;
 | 
			
		||||
| 
						 | 
				
			
			@ -162,6 +171,8 @@ static const char *choose_remote_endpoint_xq(const pa_hashmap *capabilities_hash
 | 
			
		|||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
static const char *choose_remote_endpoint_faststream(const pa_hashmap *capabilities_hashmap, const pa_sample_spec *default_sample_spec, bool for_encoding) {
 | 
			
		||||
    const pa_a2dp_codec_capabilities *a2dp_capabilities;
 | 
			
		||||
    const char *key;
 | 
			
		||||
| 
						 | 
				
			
			@ -179,6 +190,7 @@ static const char *choose_remote_endpoint_faststream(const pa_hashmap *capabilit
 | 
			
		|||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static uint8_t fill_capabilities(uint8_t capabilities_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
    a2dp_sbc_t *capabilities = (a2dp_sbc_t *) capabilities_buffer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -197,6 +209,8 @@ static uint8_t fill_capabilities(uint8_t capabilities_buffer[MAX_A2DP_CAPS_SIZE]
 | 
			
		|||
    return sizeof(*capabilities);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
static void set_info_and_sample_spec_from_sbc_config(struct sbc_info *sbc_info, pa_sample_spec *sample_spec, const a2dp_sbc_t *config) {
 | 
			
		||||
    switch (config->frequency) {
 | 
			
		||||
        case SBC_SAMPLING_FREQ_16000:
 | 
			
		||||
| 
						 | 
				
			
			@ -338,6 +352,7 @@ static uint8_t sbc_get_max_bitpool_below_rate(a2dp_sbc_t *config, uint8_t lower_
 | 
			
		|||
    return lower_bound;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
/* SBC XQ
 | 
			
		||||
 *
 | 
			
		||||
 * References:
 | 
			
		||||
| 
						 | 
				
			
			@ -345,19 +360,31 @@ static uint8_t sbc_get_max_bitpool_below_rate(a2dp_sbc_t *config, uint8_t lower_
 | 
			
		|||
 *   http://soundexpert.org/articles/-/blogs/audio-quality-of-sbc-xq-bluetooth-audio-codec
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static uint8_t fill_capabilities_xq(uint8_t capabilities_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
=======
 | 
			
		||||
static uint8_t fill_capabilities_xq(uint8_t capabilities_buffer[MAX_A2DP_CAPS_SIZE], uint32_t bitrate_cap) {
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    a2dp_sbc_t *capabilities = (a2dp_sbc_t *) capabilities_buffer;
 | 
			
		||||
 | 
			
		||||
    pa_zero(*capabilities);
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    capabilities->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
 | 
			
		||||
    capabilities->frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000;
 | 
			
		||||
=======
 | 
			
		||||
    /* Bitpool value increases with sample rate. Prepare to calculate maximum viable
 | 
			
		||||
     * bitpool value at specified bitrate_cap, with rest of SBC parameters fixed. */
 | 
			
		||||
    capabilities->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
 | 
			
		||||
    capabilities->frequency = SBC_SAMPLING_FREQ_48000;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    capabilities->allocation_method = SBC_ALLOCATION_LOUDNESS;
 | 
			
		||||
    capabilities->subbands = SBC_SUBBANDS_8;
 | 
			
		||||
    capabilities->block_length = SBC_BLOCK_LENGTH_16;
 | 
			
		||||
    capabilities->min_bitpool = SBC_MIN_BITPOOL;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    capabilities->max_bitpool = SBC_MAX_BITPOOL;
 | 
			
		||||
=======
 | 
			
		||||
    capabilities->max_bitpool = SBC_MAX_BITPOOL; /* Upper boundary in calculation below. */
 | 
			
		||||
 | 
			
		||||
    /* Now calculate and write it back to be exposed through endpoint capabilities. */
 | 
			
		||||
| 
						 | 
				
			
			@ -379,10 +406,13 @@ static uint8_t fill_capabilities_faststream(uint8_t capabilities_buffer[MAX_A2DP
 | 
			
		|||
    capabilities->direction = FASTSTREAM_DIRECTION_SINK | FASTSTREAM_DIRECTION_SOURCE;
 | 
			
		||||
    capabilities->sink_frequency = FASTSTREAM_SINK_SAMPLING_FREQ_44100 | FASTSTREAM_SINK_SAMPLING_FREQ_48000;
 | 
			
		||||
    capabilities->source_frequency = FASTSTREAM_SOURCE_SAMPLING_FREQ_16000;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    return sizeof(*capabilities);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
static bool is_configuration_valid_faststream(const uint8_t *config_buffer, uint8_t config_size) {
 | 
			
		||||
    const a2dp_faststream_t *config = (const a2dp_faststream_t *) config_buffer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -409,6 +439,7 @@ static bool is_configuration_valid_faststream(const uint8_t *config_buffer, uint
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static bool is_configuration_valid(const uint8_t *config_buffer, uint8_t config_size) {
 | 
			
		||||
    const a2dp_sbc_t *config = (const a2dp_sbc_t *) config_buffer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -610,6 +641,13 @@ static uint8_t fill_preferred_configuration(const pa_sample_spec *default_sample
 | 
			
		|||
    return sizeof(*config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static void set_info_and_sample_spec_from_sbc_config(struct sbc_info *sbc_info, pa_sample_spec *sample_spec, const a2dp_sbc_t *config) {
 | 
			
		||||
    switch (config->frequency) {
 | 
			
		||||
        case SBC_SAMPLING_FREQ_16000:
 | 
			
		||||
            sbc_info->frequency = SBC_FREQ_16000;
 | 
			
		||||
            sample_spec->rate = 16000U;
 | 
			
		||||
=======
 | 
			
		||||
static uint8_t fill_preferred_configuration_faststream(const pa_sample_spec *default_sample_spec, const uint8_t *capabilities_buffer, uint8_t capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
    a2dp_faststream_t *config = (a2dp_faststream_t *) config_buffer;
 | 
			
		||||
    const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) capabilities_buffer;
 | 
			
		||||
| 
						 | 
				
			
			@ -641,6 +679,7 @@ static uint8_t fill_preferred_configuration_faststream(const pa_sample_spec *def
 | 
			
		|||
    for (i = 0; (unsigned) i < PA_ELEMENTSOF(sink_freq_table); i++)
 | 
			
		||||
        if (sink_freq_table[i].rate >= default_sample_spec->rate && (capabilities->sink_frequency & sink_freq_table[i].cap)) {
 | 
			
		||||
            config->sink_frequency = sink_freq_table[i].cap;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -689,6 +728,135 @@ static uint8_t fill_preferred_configuration_faststream(const pa_sample_spec *def
 | 
			
		|||
    return sizeof(*config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8_t fill_preferred_configuration_xq(const pa_sample_spec *default_sample_spec, const uint8_t *capabilities_buffer, uint8_t capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE], uint32_t bitrate_cap) {
 | 
			
		||||
    a2dp_sbc_t *config = (a2dp_sbc_t *) config_buffer;
 | 
			
		||||
    const a2dp_sbc_t *capabilities = (const a2dp_sbc_t *) capabilities_buffer;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    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 }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (capabilities_size != sizeof(*capabilities)) {
 | 
			
		||||
        pa_log_error("Invalid size of capabilities buffer");
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    switch (config->subbands) {
 | 
			
		||||
        case SBC_SUBBANDS_4:
 | 
			
		||||
            sbc_info->subbands = SBC_SB_4;
 | 
			
		||||
            sbc_info->nr_subbands = 4;
 | 
			
		||||
            break;
 | 
			
		||||
        case SBC_SUBBANDS_8:
 | 
			
		||||
            sbc_info->subbands = SBC_SB_8;
 | 
			
		||||
            sbc_info->nr_subbands = 8;
 | 
			
		||||
=======
 | 
			
		||||
    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 >= default_sample_spec->rate && (capabilities->frequency & freq_table[i].cap)) {
 | 
			
		||||
            config->frequency = freq_table[i].cap;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    if ((unsigned) i == PA_ELEMENTSOF(freq_table)) {
 | 
			
		||||
        for (--i; i >= 0; i--) {
 | 
			
		||||
            if (capabilities->frequency & freq_table[i].cap) {
 | 
			
		||||
                config->frequency = freq_table[i].cap;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (i < 0) {
 | 
			
		||||
            pa_log_error("Not suitable sample rate");
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    switch (config->block_length) {
 | 
			
		||||
        case SBC_BLOCK_LENGTH_4:
 | 
			
		||||
            sbc_info->blocks = SBC_BLK_4;
 | 
			
		||||
            sbc_info->nr_blocks = 4;
 | 
			
		||||
            break;
 | 
			
		||||
        case SBC_BLOCK_LENGTH_8:
 | 
			
		||||
            sbc_info->blocks = SBC_BLK_8;
 | 
			
		||||
            sbc_info->nr_blocks = 8;
 | 
			
		||||
            break;
 | 
			
		||||
        case SBC_BLOCK_LENGTH_12:
 | 
			
		||||
            sbc_info->blocks = SBC_BLK_12;
 | 
			
		||||
            sbc_info->nr_blocks = 12;
 | 
			
		||||
            break;
 | 
			
		||||
        case SBC_BLOCK_LENGTH_16:
 | 
			
		||||
            sbc_info->blocks = SBC_BLK_16;
 | 
			
		||||
            sbc_info->nr_blocks = 16;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            pa_assert_not_reached();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sbc_info->min_bitpool = config->min_bitpool;
 | 
			
		||||
    sbc_info->max_bitpool = config->max_bitpool;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_params(struct sbc_info *sbc_info) {
 | 
			
		||||
    sbc_info->sbc.frequency = sbc_info->frequency;
 | 
			
		||||
    sbc_info->sbc.blocks = sbc_info->blocks;
 | 
			
		||||
    sbc_info->sbc.subbands = sbc_info->subbands;
 | 
			
		||||
    sbc_info->sbc.mode = sbc_info->mode;
 | 
			
		||||
    sbc_info->sbc.allocation = sbc_info->allocation;
 | 
			
		||||
    sbc_info->sbc.bitpool = sbc_info->initial_bitpool;
 | 
			
		||||
    sbc_info->sbc.endian = SBC_LE;
 | 
			
		||||
 | 
			
		||||
    sbc_info->codesize = sbc_get_codesize(&sbc_info->sbc);
 | 
			
		||||
    sbc_info->frame_length = sbc_get_frame_length(&sbc_info->sbc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t sbc_get_max_bitpool_below_rate(a2dp_sbc_t *config, uint8_t lower_bound, uint8_t upper_bound, uint32_t bitrate_cap) {
 | 
			
		||||
    pa_sample_spec sample_spec;
 | 
			
		||||
    struct sbc_info sbc_info;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    pa_assert(config);
 | 
			
		||||
 | 
			
		||||
    ret = sbc_init(&sbc_info.sbc, 0);
 | 
			
		||||
    if (ret != 0) {
 | 
			
		||||
        pa_log_error("SBC initialization failed: %d", ret);
 | 
			
		||||
        return lower_bound;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_info_and_sample_spec_from_sbc_config(&sbc_info, &sample_spec, config);
 | 
			
		||||
 | 
			
		||||
    while (upper_bound - lower_bound > 1) {
 | 
			
		||||
        size_t midpoint = (upper_bound + lower_bound) / 2;
 | 
			
		||||
 | 
			
		||||
        sbc_info.initial_bitpool = midpoint;
 | 
			
		||||
        set_params(&sbc_info);
 | 
			
		||||
 | 
			
		||||
        size_t bitrate = sbc_info.frame_length * 8 * sample_spec.rate / (sbc_info.nr_subbands * sbc_info.nr_blocks);
 | 
			
		||||
 | 
			
		||||
        if (bitrate > bitrate_cap)
 | 
			
		||||
            upper_bound = midpoint;
 | 
			
		||||
        else
 | 
			
		||||
            lower_bound = midpoint;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sbc_finish(&sbc_info.sbc);
 | 
			
		||||
 | 
			
		||||
    pa_log_debug("SBC target bitrate %u bitpool %u sample rate %u", bitrate_cap, lower_bound, sample_spec.rate);
 | 
			
		||||
 | 
			
		||||
    return lower_bound;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8_t fill_preferred_configuration_xq(const pa_sample_spec *default_sample_spec, const uint8_t *capabilities_buffer, uint8_t capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE], uint32_t bitrate_cap) {
 | 
			
		||||
    a2dp_sbc_t *config = (a2dp_sbc_t *) config_buffer;
 | 
			
		||||
    const a2dp_sbc_t *capabilities = (const a2dp_sbc_t *) capabilities_buffer;
 | 
			
		||||
| 
						 | 
				
			
			@ -750,6 +918,26 @@ static uint8_t fill_preferred_configuration_xq(const pa_sample_spec *default_sam
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
    pa_assert((unsigned) i < PA_ELEMENTSOF(freq_table));
 | 
			
		||||
 | 
			
		||||
    if (default_sample_spec->channels <= 1) {
 | 
			
		||||
        if (capabilities->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
 | 
			
		||||
            config->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
 | 
			
		||||
        else {
 | 
			
		||||
            pa_log_error("No supported channel modes");
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if (capabilities->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
 | 
			
		||||
            config->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
 | 
			
		||||
        else {
 | 
			
		||||
            pa_log_error("No supported channel modes");
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (capabilities->block_length & SBC_BLOCK_LENGTH_16)
 | 
			
		||||
        config->block_length = SBC_BLOCK_LENGTH_16;
 | 
			
		||||
    else {
 | 
			
		||||
| 
						 | 
				
			
			@ -782,26 +970,35 @@ static uint8_t fill_preferred_configuration_xq(const pa_sample_spec *default_sam
 | 
			
		|||
    return sizeof(*config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
static uint8_t fill_capabilities_xq_453kbps(uint8_t capabilities_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
    return fill_capabilities_xq(capabilities_buffer, 453000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static uint8_t fill_preferred_configuration_xq_453kbps(const pa_sample_spec *default_sample_spec, const uint8_t *capabilities_buffer, uint8_t capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
    return fill_preferred_configuration_xq(default_sample_spec, capabilities_buffer, capabilities_size, config_buffer, 453000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
static uint8_t fill_capabilities_xq_512kbps(uint8_t capabilities_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
    return fill_capabilities_xq(capabilities_buffer, 512000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static uint8_t fill_preferred_configuration_xq_512kbps(const pa_sample_spec *default_sample_spec, const uint8_t *capabilities_buffer, uint8_t capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
    return fill_preferred_configuration_xq(default_sample_spec, capabilities_buffer, capabilities_size, config_buffer, 512000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
static uint8_t fill_capabilities_xq_552kbps(uint8_t capabilities_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
    return fill_capabilities_xq(capabilities_buffer, 552000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static uint8_t fill_preferred_configuration_xq_552kbps(const pa_sample_spec *default_sample_spec, const uint8_t *capabilities_buffer, uint8_t capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {
 | 
			
		||||
    return fill_preferred_configuration_xq(default_sample_spec, capabilities_buffer, capabilities_size, config_buffer, 552000);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1002,6 +1199,11 @@ static size_t get_block_size(void *codec_info, size_t link_mtu) {
 | 
			
		|||
    return frame_count * sbc_info->codesize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static size_t get_encoded_block_size(void *codec_info, size_t input_size) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
    size_t rtp_size = sizeof(struct rtp_header) + sizeof(struct rtp_sbc_payload);
 | 
			
		||||
=======
 | 
			
		||||
static size_t get_write_block_size_faststream(void *codec_info, size_t link_mtu) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
    size_t frame_count = link_mtu / sbc_info->frame_length;
 | 
			
		||||
| 
						 | 
				
			
			@ -1027,6 +1229,7 @@ static size_t get_read_block_size_faststream(void *codec_info, size_t link_mtu)
 | 
			
		|||
static size_t get_encoded_block_size(void *codec_info, size_t input_size) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
    size_t rtp_size = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    /* input size should be aligned to codec input block size */
 | 
			
		||||
    pa_assert_fp(input_size % sbc_info->codesize == 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,6 +1237,8 @@ static size_t get_encoded_block_size(void *codec_info, size_t input_size) {
 | 
			
		|||
    return (input_size / sbc_info->codesize) * sbc_info->frame_length + rtp_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
static size_t get_encoded_block_size_faststream(void *codec_info, size_t input_size) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1043,6 +1248,7 @@ static size_t get_encoded_block_size_faststream(void *codec_info, size_t input_s
 | 
			
		|||
    return (input_size / sbc_info->codesize) * sbc_info->frame_length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
    uint8_t bitpool;
 | 
			
		||||
| 
						 | 
				
			
			@ -1055,11 +1261,19 @@ static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
 | 
			
		|||
    set_bitpool(sbc_info, bitpool);
 | 
			
		||||
    return get_block_size(codec_info, write_link_mtu);
 | 
			
		||||
}
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
static size_t increase_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
    uint8_t bitpool;
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
static size_t increase_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
    uint8_t bitpool;
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    bitpool = PA_MIN(sbc_info->sbc.bitpool + SBC_BITPOOL_INC_STEP, sbc_info->max_bitpool);
 | 
			
		||||
 | 
			
		||||
    if (sbc_info->sbc.bitpool == bitpool)
 | 
			
		||||
| 
						 | 
				
			
			@ -1281,6 +1495,11 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_
 | 
			
		|||
    return d - output_buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc = {
 | 
			
		||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
=======
 | 
			
		||||
static size_t decode_buffer_faststream(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1421,6 +1640,7 @@ double get_source_output_volume_factor_dB_faststream(void *codec_info) {
 | 
			
		|||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc = {
 | 
			
		||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint,
 | 
			
		||||
| 
						 | 
				
			
			@ -1458,10 +1678,18 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc = {
 | 
			
		|||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_453 = {
 | 
			
		||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities_xq,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint_xq,
 | 
			
		||||
    .fill_capabilities = fill_capabilities_xq,
 | 
			
		||||
=======
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities_xq,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint_xq,
 | 
			
		||||
    .fill_capabilities = fill_capabilities_xq_453kbps,
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .is_configuration_valid = is_configuration_valid,
 | 
			
		||||
    .fill_preferred_configuration = fill_preferred_configuration_xq_453kbps,
 | 
			
		||||
    .bt_codec = {
 | 
			
		||||
| 
						 | 
				
			
			@ -1482,10 +1710,18 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_453 = {
 | 
			
		|||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_512 = {
 | 
			
		||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities_xq,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint_xq,
 | 
			
		||||
    .fill_capabilities = fill_capabilities_xq,
 | 
			
		||||
=======
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities_xq,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint_xq,
 | 
			
		||||
    .fill_capabilities = fill_capabilities_xq_512kbps,
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .is_configuration_valid = is_configuration_valid,
 | 
			
		||||
    .fill_preferred_configuration = fill_preferred_configuration_xq_512kbps,
 | 
			
		||||
    .bt_codec = {
 | 
			
		||||
| 
						 | 
				
			
			@ -1506,10 +1742,18 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_512 = {
 | 
			
		|||
 | 
			
		||||
const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_552 = {
 | 
			
		||||
    .id = { A2DP_CODEC_SBC, 0, 0 },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    .support_backchannel = false,
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities_xq,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint_xq,
 | 
			
		||||
    .fill_capabilities = fill_capabilities_xq,
 | 
			
		||||
=======
 | 
			
		||||
    .can_be_supported = can_be_supported,
 | 
			
		||||
    .can_accept_capabilities = can_accept_capabilities_xq,
 | 
			
		||||
    .choose_remote_endpoint = choose_remote_endpoint_xq,
 | 
			
		||||
    .fill_capabilities = fill_capabilities_xq_552kbps,
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    .is_configuration_valid = is_configuration_valid,
 | 
			
		||||
    .fill_preferred_configuration = fill_preferred_configuration_xq_552kbps,
 | 
			
		||||
    .bt_codec = {
 | 
			
		||||
| 
						 | 
				
			
			@ -1526,6 +1770,8 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_sbc_xq_552 = {
 | 
			
		|||
        .encode_buffer = encode_buffer,
 | 
			
		||||
        .decode_buffer = decode_buffer,
 | 
			
		||||
    },
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* FastStream codec is just SBC codec with fixed parameters.
 | 
			
		||||
| 
						 | 
				
			
			@ -1572,4 +1818,5 @@ const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_faststream = {
 | 
			
		|||
        .decode_buffer = decode_buffer_faststream,
 | 
			
		||||
        .get_source_output_volume_factor_dB = get_source_output_volume_factor_dB_faststream,
 | 
			
		||||
    },
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,10 @@ extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_hq;
 | 
			
		|||
extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_sq;
 | 
			
		||||
extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_ldac_eqmid_mq;
 | 
			
		||||
#endif
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
extern const pa_a2dp_endpoint_conf pa_a2dp_endpoint_conf_faststream;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
/* This is list of supported codecs. Their order is important.
 | 
			
		||||
 * Codec with lower index has higher priority. */
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +73,10 @@ static const pa_a2dp_endpoint_conf *pa_a2dp_endpoint_configurations[] = {
 | 
			
		|||
    &pa_a2dp_endpoint_conf_sbc_xq_453,
 | 
			
		||||
    &pa_a2dp_endpoint_conf_sbc_xq_512,
 | 
			
		||||
    &pa_a2dp_endpoint_conf_sbc_xq_552,
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    &pa_a2dp_endpoint_conf_faststream,
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned int pa_bluetooth_a2dp_endpoint_conf_count(void) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,18 +38,26 @@
 | 
			
		|||
 | 
			
		||||
#include "bluez5-util.h"
 | 
			
		||||
#include "bt-codec-msbc.h"
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
#include "upower.h"
 | 
			
		||||
 | 
			
		||||
#define MANDATORY_CALL_INDICATORS \
 | 
			
		||||
        "(\"call\",(0-1))," \
 | 
			
		||||
        "(\"callsetup\",(0-3))," \
 | 
			
		||||
        "(\"callheld\",(0-2))" \
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
struct pa_bluetooth_backend {
 | 
			
		||||
  pa_core *core;
 | 
			
		||||
  pa_dbus_connection *connection;
 | 
			
		||||
  pa_bluetooth_discovery *discovery;
 | 
			
		||||
  pa_hook_slot *adapter_uuids_changed_slot;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  bool enable_shared_profiles;
 | 
			
		||||
  bool enable_hsp_hs;
 | 
			
		||||
  bool enable_hfp_hf;
 | 
			
		||||
=======
 | 
			
		||||
  pa_hook_slot *host_battery_level_changed_slot;
 | 
			
		||||
  pa_upower_backend *upower;
 | 
			
		||||
  bool enable_shared_profiles;
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +65,7 @@ struct pa_bluetooth_backend {
 | 
			
		|||
  bool enable_hfp_hf;
 | 
			
		||||
  bool cmer_indicator_reporting_enabled;
 | 
			
		||||
  uint32_t cind_enabled_indicators;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
  PA_LLIST_HEAD(pa_dbus_pending, pending);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +87,37 @@ struct hfp_config {
 | 
			
		|||
    bool supports_indicators;
 | 
			
		||||
    int selected_codec;
 | 
			
		||||
};
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * the separate hansfree headset (HF) and Audio Gateway (AG) features
 | 
			
		||||
 */
 | 
			
		||||
enum hfp_hf_features {
 | 
			
		||||
    HFP_HF_EC_NR = 0,
 | 
			
		||||
    HFP_HF_CALL_WAITING = 1,
 | 
			
		||||
    HFP_HF_CLI = 2,
 | 
			
		||||
    HFP_HF_VR = 3,
 | 
			
		||||
    HFP_HF_RVOL = 4,
 | 
			
		||||
    HFP_HF_ESTATUS = 5,
 | 
			
		||||
    HFP_HF_ECALL = 6,
 | 
			
		||||
    HFP_HF_CODECS = 7,
 | 
			
		||||
    HFP_HF_INDICATORS = 8,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum hfp_ag_features {
 | 
			
		||||
    HFP_AG_THREE_WAY = 0,
 | 
			
		||||
    HFP_AG_EC_NR = 1,
 | 
			
		||||
    HFP_AG_VR = 2,
 | 
			
		||||
    HFP_AG_RING = 3,
 | 
			
		||||
    HFP_AG_NUM_TAG = 4,
 | 
			
		||||
    HFP_AG_REJECT = 5,
 | 
			
		||||
    HFP_AG_ESTATUS = 6,
 | 
			
		||||
    HFP_AG_ECALL = 7,
 | 
			
		||||
    HFP_AG_EERR = 8,
 | 
			
		||||
    HFP_AG_CODECS = 9,
 | 
			
		||||
    HFP_AG_INDICATORS = 10,
 | 
			
		||||
};
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * the separate hansfree headset (HF) and Audio Gateway (AG) features
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +161,7 @@ typedef enum pa_bluetooth_ag_to_hf_indicators {
 | 
			
		|||
    CIND_BATT_CHG_INDICATOR = 5,
 | 
			
		||||
    CIND_INDICATOR_MAX = 6
 | 
			
		||||
} pa_bluetooth_ag_to_hf_indicators_t;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
/* gateway features we support, which is as little as we can get away with */
 | 
			
		||||
static uint32_t hfp_features =
 | 
			
		||||
| 
						 | 
				
			
			@ -370,6 +411,10 @@ static int sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu
 | 
			
		|||
    if (sock < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    if (imtu) *imtu = 60;
 | 
			
		||||
    if (omtu) *omtu = 60;
 | 
			
		||||
=======
 | 
			
		||||
    /* The correct block size should take into account the SCO MTU from
 | 
			
		||||
     * the Bluetooth adapter and (for adapters in the USB bus) the MxPS
 | 
			
		||||
     * value from the Isoc USB endpoint in use by btusb and should be
 | 
			
		||||
| 
						 | 
				
			
			@ -382,6 +427,7 @@ static int sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu
 | 
			
		|||
     */
 | 
			
		||||
    if (imtu) *imtu = 144;
 | 
			
		||||
    if (omtu) *omtu = 144;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    if (t->device->autodetect_mtu) {
 | 
			
		||||
        struct sco_options sco_opt;
 | 
			
		||||
| 
						 | 
				
			
			@ -398,6 +444,11 @@ static int sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* read/decode machinery only works if we get at most one MSBC encoded packet at a time
 | 
			
		||||
     * when it is fixed to process stream of packets, lift this assertion */
 | 
			
		||||
    pa_assert(*imtu <= MSBC_PACKET_SIZE);
 | 
			
		||||
    pa_assert(*omtu <= MSBC_PACKET_SIZE);
 | 
			
		||||
 | 
			
		||||
    return sock;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
| 
						 | 
				
			
			@ -614,6 +665,13 @@ static pa_volume_t set_source_volume(pa_bluetooth_transport *t, pa_volume_t volu
 | 
			
		|||
static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf)
 | 
			
		||||
{
 | 
			
		||||
    struct hfp_config *c = t->config;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    int indicator, val;
 | 
			
		||||
    char str[5];
 | 
			
		||||
    const char *r;
 | 
			
		||||
    size_t len;
 | 
			
		||||
    const char *state;
 | 
			
		||||
=======
 | 
			
		||||
    struct transport_data *trd = t->userdata;
 | 
			
		||||
    pa_bluetooth_backend *b = trd->backend;
 | 
			
		||||
    int indicator, mode, val;
 | 
			
		||||
| 
						 | 
				
			
			@ -621,6 +679,7 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
 | 
			
		|||
    const char *r;
 | 
			
		||||
    size_t len;
 | 
			
		||||
    const char *state = NULL;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    /* first-time initialize selected codec to CVSD */
 | 
			
		||||
    if (c->selected_codec == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -635,6 +694,15 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
 | 
			
		|||
        c->state = 1;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    } else if (sscanf(buf, "AT+BAC=%3s", str) == 1) {
 | 
			
		||||
        c->support_msbc = false;
 | 
			
		||||
 | 
			
		||||
        state = NULL;
 | 
			
		||||
 | 
			
		||||
        /* check if codec id 2 (mSBC) is in the list of supported codecs */
 | 
			
		||||
        while ((r = pa_split_in_place(str, ",", &len, &state))) {
 | 
			
		||||
=======
 | 
			
		||||
    } else if (pa_startswith(buf, "AT+BIA=")) {
 | 
			
		||||
        /* Indicators start with index 1 and follow the order of the AT+CIND=? response */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -670,12 +738,16 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
 | 
			
		|||
        /* check if codec id 2 (mSBC) is in the list of supported codecs */
 | 
			
		||||
        str = pa_xstrdup(buf + 7);
 | 
			
		||||
        while ((r = pa_split_in_place(str, ",\r\n", &len, &state))) {
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            if (len == 1 && r[0] == '2') {
 | 
			
		||||
                c->support_msbc = true;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
        pa_xfree(str);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
        c->support_codec_negotiation = true;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -689,6 +761,16 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
 | 
			
		|||
 | 
			
		||||
        return true;
 | 
			
		||||
    } else if (c->state == 1 && pa_startswith(buf, "AT+CIND=?")) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        /* we declare minimal no indicators */
 | 
			
		||||
        rfcomm_write_response(fd, "+CIND: "
 | 
			
		||||
                     /* many indicators can be supported, only call and
 | 
			
		||||
                      * callheld are mandatory, so that's all we reply */
 | 
			
		||||
                     "(\"service\",(0-1)),"
 | 
			
		||||
                     "(\"call\",(0-1)),"
 | 
			
		||||
                     "(\"callsetup\",(0-3)),"
 | 
			
		||||
                     "(\"callheld\",(0-2))");
 | 
			
		||||
=======
 | 
			
		||||
        /* UPower backend available, declare support for more indicators */
 | 
			
		||||
        if (b->upower) {
 | 
			
		||||
            rfcomm_write_response(fd, "+CIND: "
 | 
			
		||||
| 
						 | 
				
			
			@ -702,18 +784,26 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
 | 
			
		|||
                    MANDATORY_CALL_INDICATORS ","
 | 
			
		||||
                    "(\"service\",(0-1))");
 | 
			
		||||
        }
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        c->state = 2;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    } else if (c->state == 2 && pa_startswith(buf, "AT+CIND?")) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        rfcomm_write_response(fd, "+CIND: 0,0,0,0");
 | 
			
		||||
=======
 | 
			
		||||
        if (b->upower)
 | 
			
		||||
            rfcomm_write_response(fd, "+CIND: 0,0,0,0,%u", pa_upower_get_battery_level(b->upower));
 | 
			
		||||
        else
 | 
			
		||||
            rfcomm_write_response(fd, "+CIND: 0,0,0,0");
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        c->state = 3;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    } else if ((c->state == 2 || c->state == 3) && pa_startswith(buf, "AT+CMER=")) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        rfcomm_write_response(fd, "OK");
 | 
			
		||||
=======
 | 
			
		||||
        if (sscanf(buf, "AT+CMER=%d,%*d,%*d,%d", &mode, &val) == 2) {
 | 
			
		||||
            /* Bluetooth HFP spec only defines mode == 3 */
 | 
			
		||||
            if (mode != 3)
 | 
			
		||||
| 
						 | 
				
			
			@ -731,6 +821,7 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
 | 
			
		|||
            rfcomm_write_response(fd, "ERROR");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
        if (c->support_codec_negotiation) {
 | 
			
		||||
            if (c->support_msbc && pa_bluetooth_discovery_get_enable_msbc(t->device->discovery)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -816,6 +907,8 @@ static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf
 | 
			
		|||
     * update, but we process only the ones we care about
 | 
			
		||||
     */
 | 
			
		||||
    return true;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int get_rfcomm_fd(pa_bluetooth_discovery *discovery) {
 | 
			
		||||
| 
						 | 
				
			
			@ -867,6 +960,7 @@ static pa_hook_result_t host_battery_level_changed_cb(pa_bluetooth_discovery *y,
 | 
			
		|||
        pa_log_debug("Battery level change indicator disabled, skipping notification");
 | 
			
		||||
 | 
			
		||||
    return PA_HOOK_OK;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
 | 
			
		||||
| 
						 | 
				
			
			@ -894,7 +988,10 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i
 | 
			
		|||
        int gain, dummy;
 | 
			
		||||
        bool do_reply = false;
 | 
			
		||||
        int vendor, product, version, features;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
        char *buf = rbuf;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        int num;
 | 
			
		||||
 | 
			
		||||
        len = pa_read(fd, rbuf, 511, NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -902,6 +999,96 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i
 | 
			
		|||
            pa_log_error("RFCOMM read error: %s", pa_cstrerror(errno));
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        buf[len] = 0;
 | 
			
		||||
        pa_log_debug("RFCOMM << %s", buf);
 | 
			
		||||
 | 
			
		||||
        /* There are only four HSP AT commands:
 | 
			
		||||
         * AT+VGS=value: value between 0 and 15, sent by the HS to AG to set the speaker gain.
 | 
			
		||||
         * +VGS=value is sent by AG to HS as a response to an AT+VGS command or when the gain
 | 
			
		||||
         * is changed on the AG side.
 | 
			
		||||
         * AT+VGM=value: value between 0 and 15, sent by the HS to AG to set the microphone gain.
 | 
			
		||||
         * +VGM=value is sent by AG to HS as a response to an AT+VGM command or when the gain
 | 
			
		||||
         * is changed on the AG side.
 | 
			
		||||
         * AT+CKPD=200: Sent by HS when headset button is pressed.
 | 
			
		||||
         * RING: Sent by AG to HS to notify of an incoming call. It can safely be ignored because
 | 
			
		||||
         * it does not expect a reply. */
 | 
			
		||||
        if (sscanf(buf, "AT+VGS=%d", &gain) == 1 || sscanf(buf, "\r\n+VGM%*[=:]%d\r\n", &gain) == 1) {
 | 
			
		||||
            if (!t->set_sink_volume) {
 | 
			
		||||
                pa_log_debug("HS/HF peer supports speaker gain control");
 | 
			
		||||
                t->set_sink_volume = set_sink_volume;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            t->sink_volume = hsp_gain_to_volume(gain);
 | 
			
		||||
            pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SINK_VOLUME_CHANGED), t);
 | 
			
		||||
            do_reply = true;
 | 
			
		||||
 | 
			
		||||
        } else if (sscanf(buf, "AT+VGM=%d", &gain) == 1 || sscanf(buf, "\r\n+VGS%*[=:]%d\r\n", &gain) == 1) {
 | 
			
		||||
            if (!t->set_source_volume) {
 | 
			
		||||
                pa_log_debug("HS/HF peer supports microphone gain control");
 | 
			
		||||
                t->set_source_volume = set_source_volume;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            t->source_volume = hsp_gain_to_volume(gain);
 | 
			
		||||
            pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SOURCE_VOLUME_CHANGED), t);
 | 
			
		||||
            do_reply = true;
 | 
			
		||||
        } else if (sscanf(buf, "AT+CKPD=%d", &dummy) == 1) {
 | 
			
		||||
            do_reply = true;
 | 
			
		||||
        } else if (sscanf(buf, "AT+XAPL=%04x-%04x-%04x,%d", &vendor, &product, &version, &features) == 4) {
 | 
			
		||||
            if (features & 0x2)
 | 
			
		||||
                /* claim, that we support battery status reports */
 | 
			
		||||
                rfcomm_write_response(fd, "+XAPL=iPhone,6");
 | 
			
		||||
            do_reply = true;
 | 
			
		||||
        } else if (sscanf(buf, "AT+IPHONEACCEV=%d", &num) == 1) {
 | 
			
		||||
            char *substr = buf, *keystr;
 | 
			
		||||
            int key, val, i;
 | 
			
		||||
 | 
			
		||||
            do_reply = true;
 | 
			
		||||
 | 
			
		||||
            for (i = 0; i < num; ++i) {
 | 
			
		||||
                keystr = strchr(substr, ',');
 | 
			
		||||
                if (!keystr) {
 | 
			
		||||
                    pa_log_warn("%s misses key for argument #%d", buf, i);
 | 
			
		||||
                    do_reply = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                keystr++;
 | 
			
		||||
                substr = strchr(keystr, ',');
 | 
			
		||||
                if (!substr) {
 | 
			
		||||
                    pa_log_warn("%s misses value for argument #%d", buf, i);
 | 
			
		||||
                    do_reply = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                substr++;
 | 
			
		||||
 | 
			
		||||
                key = atoi(keystr);
 | 
			
		||||
                val = atoi(substr);
 | 
			
		||||
 | 
			
		||||
                switch (key) {
 | 
			
		||||
                    case 1:
 | 
			
		||||
                        pa_log_notice("Battery Level: %d0%%", val + 1);
 | 
			
		||||
                        pa_bluetooth_device_report_battery_level(t->device, (val + 1) * 10, "Apple accessory indication");
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 2:
 | 
			
		||||
                        pa_log_notice("Dock Status: %s", val ? "docked" : "undocked");
 | 
			
		||||
                        break;
 | 
			
		||||
                    default:
 | 
			
		||||
                        pa_log_debug("Unexpected IPHONEACCEV key %#x", key);
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (!do_reply)
 | 
			
		||||
                rfcomm_write_response(fd, "ERROR");
 | 
			
		||||
        } else if (t->config) { /* t->config is only non-null for hfp profile */
 | 
			
		||||
            do_reply = hfp_rfcomm_handle(fd, t, buf);
 | 
			
		||||
        } else {
 | 
			
		||||
            rfcomm_write_response(fd, "ERROR");
 | 
			
		||||
            do_reply = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (do_reply)
 | 
			
		||||
            rfcomm_write_response(fd, "OK");
 | 
			
		||||
=======
 | 
			
		||||
        rbuf[len] = 0;
 | 
			
		||||
        pa_log_debug("RFCOMM << %s", rbuf);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1003,6 +1190,7 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i
 | 
			
		|||
            else
 | 
			
		||||
                buf = buf + 1; /* skip \r */
 | 
			
		||||
        }
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
| 
						 | 
				
			
			@ -1036,6 +1224,7 @@ static void transport_destroy(pa_bluetooth_transport *t) {
 | 
			
		|||
static pa_volume_t set_sink_volume(pa_bluetooth_transport *t, pa_volume_t volume) {
 | 
			
		||||
    struct transport_data *trd = t->userdata;
 | 
			
		||||
    uint16_t gain = volume_to_hsp_gain(volume);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    /* Propagate rounding and bound checks */
 | 
			
		||||
    volume = hsp_gain_to_volume(gain);
 | 
			
		||||
| 
						 | 
				
			
			@ -1045,6 +1234,17 @@ static pa_volume_t set_sink_volume(pa_bluetooth_transport *t, pa_volume_t volume
 | 
			
		|||
 | 
			
		||||
    t->sink_volume = volume;
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    /* Propagate rounding and bound checks */
 | 
			
		||||
    volume = hsp_gain_to_volume(gain);
 | 
			
		||||
 | 
			
		||||
    if (t->sink_volume == volume)
 | 
			
		||||
        return volume;
 | 
			
		||||
 | 
			
		||||
    t->sink_volume = volume;
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    /* If we are in the AG role, we send an unsolicited result-code to the headset
 | 
			
		||||
     * to change the speaker gain. In the HS role, source and sink are swapped,
 | 
			
		||||
     * so in this case we notify the AG that the microphone gain has changed
 | 
			
		||||
| 
						 | 
				
			
			@ -1061,6 +1261,7 @@ static pa_volume_t set_sink_volume(pa_bluetooth_transport *t, pa_volume_t volume
 | 
			
		|||
static pa_volume_t set_source_volume(pa_bluetooth_transport *t, pa_volume_t volume) {
 | 
			
		||||
    struct transport_data *trd = t->userdata;
 | 
			
		||||
    uint16_t gain = volume_to_hsp_gain(volume);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    /* Propagate rounding and bound checks */
 | 
			
		||||
    volume = hsp_gain_to_volume(gain);
 | 
			
		||||
| 
						 | 
				
			
			@ -1070,6 +1271,17 @@ static pa_volume_t set_source_volume(pa_bluetooth_transport *t, pa_volume_t volu
 | 
			
		|||
 | 
			
		||||
    t->source_volume = volume;
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    /* Propagate rounding and bound checks */
 | 
			
		||||
    volume = hsp_gain_to_volume(gain);
 | 
			
		||||
 | 
			
		||||
    if (t->source_volume == volume)
 | 
			
		||||
        return volume;
 | 
			
		||||
 | 
			
		||||
    t->source_volume = volume;
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    /* If we are in the AG role, we send an unsolicited result-code to the headset
 | 
			
		||||
     * to change the microphone gain. In the HS role, source and sink are swapped,
 | 
			
		||||
     * so in this case we notify the AG that the speaker gain has changed
 | 
			
		||||
| 
						 | 
				
			
			@ -1328,9 +1540,15 @@ static void native_backend_apply_profile_registration_change(pa_bluetooth_backen
 | 
			
		|||
            profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *native_backend, bool enable) {
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *native_backend, bool enable) {
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
   if (enable == native_backend->enable_shared_profiles)
 | 
			
		||||
       return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1365,6 +1583,17 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
 | 
			
		|||
    backend->adapter_uuids_changed_slot =
 | 
			
		||||
        pa_hook_connect(pa_bluetooth_discovery_hook(y, PA_BLUETOOTH_HOOK_ADAPTER_UUIDS_CHANGED), PA_HOOK_NORMAL,
 | 
			
		||||
                        (pa_hook_cb_t) adapter_uuids_changed_cb, backend);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    if (!backend->enable_hsp_hs && !backend->enable_hfp_hf)
 | 
			
		||||
        pa_log_warn("Both HSP HS and HFP HF bluetooth profiles disabled in native backend. Native backend will not register for headset connections.");
 | 
			
		||||
 | 
			
		||||
    if (backend->enable_hsp_hs)
 | 
			
		||||
        profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
 | 
			
		||||
 | 
			
		||||
    if (backend->enable_shared_profiles)
 | 
			
		||||
        native_backend_apply_profile_registration_change(backend, true);
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    backend->host_battery_level_changed_slot =
 | 
			
		||||
        pa_hook_connect(pa_bluetooth_discovery_hook(y, PA_BLUETOOTH_HOOK_HOST_BATTERY_LEVEL_CHANGED), PA_HOOK_NORMAL,
 | 
			
		||||
| 
						 | 
				
			
			@ -1388,6 +1617,7 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
 | 
			
		|||
    /* While all CIND indicators are enabled, event reporting is not enabled by default */
 | 
			
		||||
    backend->cmer_indicator_reporting_enabled = false;
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    return backend;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1400,17 +1630,23 @@ void pa_bluetooth_native_backend_free(pa_bluetooth_backend *backend) {
 | 
			
		|||
    if (backend->adapter_uuids_changed_slot)
 | 
			
		||||
        pa_hook_slot_free(backend->adapter_uuids_changed_slot);
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    if (backend->host_battery_level_changed_slot)
 | 
			
		||||
        pa_hook_slot_free(backend->host_battery_level_changed_slot);
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (backend->enable_shared_profiles)
 | 
			
		||||
        native_backend_apply_profile_registration_change(backend, false);
 | 
			
		||||
 | 
			
		||||
    if (backend->enable_hsp_hs)
 | 
			
		||||
        profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    if (backend->upower)
 | 
			
		||||
        pa_upower_backend_free(backend->upower);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_dbus_connection_unref(backend->connection);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -333,6 +333,15 @@ static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool opti
 | 
			
		|||
     * value from the Isoc USB endpoint in use by btusb and should be
 | 
			
		||||
     * made available to userspace by the Bluetooth kernel subsystem.
 | 
			
		||||
     *
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
     * Set initial MTU to max size which is reported to be working (60 bytes)
 | 
			
		||||
     * See also pa_bluetooth_transport::last_read_size handling.
 | 
			
		||||
     */
 | 
			
		||||
    if (imtu)
 | 
			
		||||
        *imtu = 60;
 | 
			
		||||
    if (omtu)
 | 
			
		||||
        *omtu = 60;
 | 
			
		||||
=======
 | 
			
		||||
     * Set initial MTU to max known payload length of HCI packet
 | 
			
		||||
     * in USB Alternate Setting 5 (144 bytes)
 | 
			
		||||
     * See also pa_bluetooth_transport::last_read_size handling
 | 
			
		||||
| 
						 | 
				
			
			@ -342,6 +351,7 @@ static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool opti
 | 
			
		|||
        *imtu = 144;
 | 
			
		||||
    if (omtu)
 | 
			
		||||
        *omtu = 144;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    err = socket_accept(card->fd);
 | 
			
		||||
    if (err < 0) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -254,6 +254,10 @@ static const char *transport_state_to_string(pa_bluetooth_transport_state_t stat
 | 
			
		|||
    return "invalid";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
 | 
			
		||||
    bool show_hfp, show_hsp;
 | 
			
		||||
=======
 | 
			
		||||
bool pa_bluetooth_device_supports_profile(const pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
 | 
			
		||||
    bool show_hfp, show_hsp, r;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -267,6 +271,7 @@ bool pa_bluetooth_device_supports_profile(const pa_bluetooth_device *device, pa_
 | 
			
		|||
                device->alias, device->address, pa_bluetooth_profile_to_string(profile));
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    if (device->enable_hfp_hf) {
 | 
			
		||||
        show_hfp = pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
 | 
			
		||||
| 
						 | 
				
			
			@ -282,6 +287,19 @@ bool pa_bluetooth_device_supports_profile(const pa_bluetooth_device *device, pa_
 | 
			
		|||
                      pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE));
 | 
			
		||||
            break;
 | 
			
		||||
        case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE);
 | 
			
		||||
        case PA_BLUETOOTH_PROFILE_HSP_HS:
 | 
			
		||||
            return show_hsp
 | 
			
		||||
                && ( !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
 | 
			
		||||
                  || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT));
 | 
			
		||||
        case PA_BLUETOOTH_PROFILE_HSP_AG:
 | 
			
		||||
            return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG);
 | 
			
		||||
        case PA_BLUETOOTH_PROFILE_HFP_HF:
 | 
			
		||||
            return show_hfp && !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
 | 
			
		||||
        case PA_BLUETOOTH_PROFILE_HFP_AG:
 | 
			
		||||
            return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
 | 
			
		||||
=======
 | 
			
		||||
            r = !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE) &&
 | 
			
		||||
                      pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_A2DP_SINK));
 | 
			
		||||
            break;
 | 
			
		||||
| 
						 | 
				
			
			@ -307,6 +325,7 @@ bool pa_bluetooth_device_supports_profile(const pa_bluetooth_device *device, pa_
 | 
			
		|||
            r = !!(pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG) &&
 | 
			
		||||
                      pa_hashmap_get(device->adapter->uuids, PA_BLUETOOTH_UUID_HFP_HF));
 | 
			
		||||
            break;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        case PA_BLUETOOTH_PROFILE_OFF:
 | 
			
		||||
        default:
 | 
			
		||||
            pa_assert_not_reached();
 | 
			
		||||
| 
						 | 
				
			
			@ -788,7 +807,10 @@ static void get_volume_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
    pa_bluetooth_transport *t;
 | 
			
		||||
    uint16_t gain;
 | 
			
		||||
    pa_volume_t volume;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    const char *error_name, *error_message;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_assert(pending);
 | 
			
		||||
    pa_assert_se(p = userdata);
 | 
			
		||||
| 
						 | 
				
			
			@ -797,6 +819,12 @@ static void get_volume_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
 | 
			
		||||
 | 
			
		||||
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        pa_log_error(DBUS_INTERFACE_PROPERTIES ".Get %s Volume failed: %s: %s",
 | 
			
		||||
                     dbus_message_get_path(p->message),
 | 
			
		||||
                     dbus_message_get_error_name(r),
 | 
			
		||||
                     pa_dbus_get_error_message(r));
 | 
			
		||||
=======
 | 
			
		||||
        error_name = dbus_message_get_error_name(r);
 | 
			
		||||
        error_message = pa_dbus_get_error_message(r);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -809,6 +837,7 @@ static void get_volume_reply(DBusPendingCall *pending, void *userdata) {
 | 
			
		|||
                         error_name,
 | 
			
		||||
                         error_message);
 | 
			
		||||
        }
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        goto finish;
 | 
			
		||||
    }
 | 
			
		||||
    dbus_message_iter_init(r, &iter);
 | 
			
		||||
| 
						 | 
				
			
			@ -1202,6 +1231,8 @@ bool pa_bluetooth_discovery_get_enable_msbc(pa_bluetooth_discovery *y)
 | 
			
		|||
    return y->enable_msbc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
pa_hashmap* pa_bluetooth_discovery_get_transports(pa_bluetooth_discovery *y) {
 | 
			
		||||
    pa_assert(y);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(y) > 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -1209,6 +1240,7 @@ pa_hashmap* pa_bluetooth_discovery_get_transports(pa_bluetooth_discovery *y) {
 | 
			
		|||
    return y->transports;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local) {
 | 
			
		||||
    pa_bluetooth_device *d;
 | 
			
		||||
    void *state = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -2130,7 +2162,11 @@ void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is
 | 
			
		|||
        pa_bluetooth_device *d;
 | 
			
		||||
 | 
			
		||||
        PA_HASHMAP_FOREACH(d, y->devices, state) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG) || device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_HF)) {
 | 
			
		||||
=======
 | 
			
		||||
            if (pa_bluetooth_device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG) || pa_bluetooth_device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_HF)) {
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
                DBusMessage *m;
 | 
			
		||||
 | 
			
		||||
                pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, d->path, BLUEZ_DEVICE_INTERFACE, "Disconnect"));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,7 +69,10 @@ 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_DEVICE_BATTERY_LEVEL_CHANGED,     /* Call data: pa_bluetooth_device */
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    PA_BLUETOOTH_HOOK_HOST_BATTERY_LEVEL_CHANGED,       /* Call data: pa_upower_backend */
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED,          /* Call data: pa_bluetooth_transport */
 | 
			
		||||
    PA_BLUETOOTH_HOOK_TRANSPORT_SOURCE_VOLUME_CHANGED,  /* Call data: pa_bluetooth_transport */
 | 
			
		||||
    PA_BLUETOOTH_HOOK_TRANSPORT_SINK_VOLUME_CHANGED,    /* Call data: pa_bluetooth_transport */
 | 
			
		||||
| 
						 | 
				
			
			@ -247,5 +250,8 @@ void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is
 | 
			
		|||
bool pa_bluetooth_discovery_get_enable_native_hsp_hs(pa_bluetooth_discovery *y);
 | 
			
		||||
bool pa_bluetooth_discovery_get_enable_native_hfp_hf(pa_bluetooth_discovery *y);
 | 
			
		||||
bool pa_bluetooth_discovery_get_enable_msbc(pa_bluetooth_discovery *y);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
pa_hashmap* pa_bluetooth_discovery_get_transports(pa_bluetooth_discovery *y);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,9 +26,12 @@ typedef struct pa_bt_codec {
 | 
			
		|||
    /* Human readable codec description */
 | 
			
		||||
    const char *description;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    /* True if codec is bi-directional and supports backchannel */
 | 
			
		||||
    bool support_backchannel;
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    /* Initialize codec, returns codec info data and set sample_spec,
 | 
			
		||||
     * for_encoding is true when codec_info is used for encoding,
 | 
			
		||||
     * for_backchannel is true when codec_info is used for backchannel */
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +70,10 @@ typedef struct pa_bt_codec {
 | 
			
		|||
     * returns size of filled ouput_buffer and set processed to size of
 | 
			
		||||
     * processed input_buffer */
 | 
			
		||||
    size_t (*decode_buffer)(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    /* Get volume factor which needs to be applied to output samples */
 | 
			
		||||
    double (*get_source_output_volume_factor_dB)(void *codec_info);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
} pa_bt_codec;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -112,6 +112,9 @@ static size_t get_read_block_size(void *codec_info, size_t link_mtu) {
 | 
			
		|||
        block_size = pa_frame_align(block_size, &info->sample_spec);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    return block_size;
 | 
			
		||||
=======
 | 
			
		||||
    /* If MTU exceeds mSBC frame size there could be up to 1 + MTU / (mSBC frame size)
 | 
			
		||||
     * frames decoded for single incoming packet.
 | 
			
		||||
     * See also pa_bluetooth_transport::last_read_size handling
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +124,7 @@ static size_t get_read_block_size(void *codec_info, size_t link_mtu) {
 | 
			
		|||
        return block_size;
 | 
			
		||||
 | 
			
		||||
    return block_size * (1 + link_mtu / MSBC_PACKET_SIZE);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static size_t get_write_block_size(void *codec_info, size_t link_mtu) {
 | 
			
		||||
| 
						 | 
				
			
			@ -212,10 +216,17 @@ static inline bool is_all_zero(const uint8_t *ptr, size_t len) {
 | 
			
		|||
/*
 | 
			
		||||
 * We build a msbc frame up in the sbc_info buffer until we have a whole one
 | 
			
		||||
 */
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static struct msbc_frame *msbc_find_frame(struct sbc_info *si, ssize_t *len,
 | 
			
		||||
                                          const uint8_t *buf, int *pseq)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
=======
 | 
			
		||||
static struct msbc_frame *msbc_find_frame(struct sbc_info *si, size_t *len,
 | 
			
		||||
                                          const uint8_t *buf, int *pseq)
 | 
			
		||||
{
 | 
			
		||||
    size_t i;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    uint8_t *p = si->input_buffer;
 | 
			
		||||
 | 
			
		||||
    /* skip input if it has all zero bytes
 | 
			
		||||
| 
						 | 
				
			
			@ -249,7 +260,11 @@ static struct msbc_frame *msbc_find_frame(struct sbc_info *si, size_t *len,
 | 
			
		|||
            id1.b = p[1];
 | 
			
		||||
            *pseq = (id1.s.sn0 & 0x1) | (id1.s.sn1 & 0x2);
 | 
			
		||||
            si->msbc_push_offset = 0;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            *len = *len - i;
 | 
			
		||||
=======
 | 
			
		||||
            *len -= i + 1;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            return (struct msbc_frame *)p;
 | 
			
		||||
        }
 | 
			
		||||
        continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -263,6 +278,51 @@ static struct msbc_frame *msbc_find_frame(struct sbc_info *si, size_t *len,
 | 
			
		|||
 | 
			
		||||
static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
 | 
			
		||||
    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    ssize_t remaining;
 | 
			
		||||
    ssize_t decoded;
 | 
			
		||||
    size_t written = 0;
 | 
			
		||||
    struct msbc_frame *frame;
 | 
			
		||||
    int seq;
 | 
			
		||||
 | 
			
		||||
    remaining = input_size;
 | 
			
		||||
    frame = msbc_find_frame(sbc_info, &remaining, input_buffer, &seq);
 | 
			
		||||
 | 
			
		||||
    /* only process when we have a full frame */
 | 
			
		||||
    if (!frame) {
 | 
			
		||||
        *processed = input_size - remaining;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t lost_packets = (4 + seq - sbc_info->msbc_seq++) % 4;
 | 
			
		||||
 | 
			
		||||
    if (lost_packets) {
 | 
			
		||||
        pa_log_debug("Lost %d input audio packet(s)", lost_packets);
 | 
			
		||||
        sbc_info->msbc_seq = seq + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    decoded = sbc_decode(&sbc_info->sbc, frame->payload, MSBC_FRAME_SIZE, output_buffer, output_size, &written);
 | 
			
		||||
 | 
			
		||||
    /* now we've consumed the sbc_info buffer, start a new one with
 | 
			
		||||
     * the partial frame we have */
 | 
			
		||||
    if (remaining > 0)
 | 
			
		||||
        msbc_find_frame(sbc_info, &remaining, input_buffer + input_size - remaining, &seq);
 | 
			
		||||
 | 
			
		||||
    pa_assert_fp(remaining == 0);
 | 
			
		||||
 | 
			
		||||
    if (PA_UNLIKELY(decoded <= 0)) {
 | 
			
		||||
        pa_log_error("mSBC decoding error (%li)", (long) decoded);
 | 
			
		||||
        pa_silence_memory(output_buffer, sbc_info->codesize, &sbc_info->sample_spec);
 | 
			
		||||
        decoded = sbc_info->frame_length;
 | 
			
		||||
        written = sbc_info->codesize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pa_assert_fp((size_t)decoded == sbc_info->frame_length);
 | 
			
		||||
    pa_assert_fp((size_t)written == sbc_info->codesize);
 | 
			
		||||
 | 
			
		||||
    *processed = input_size - remaining;
 | 
			
		||||
    return written;
 | 
			
		||||
=======
 | 
			
		||||
    size_t save_input_size;
 | 
			
		||||
    ssize_t decoded;
 | 
			
		||||
    size_t written = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -312,6 +372,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_
 | 
			
		|||
 | 
			
		||||
    *processed = total_processed;
 | 
			
		||||
    return total_written;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Modified SBC codec for HFP Wideband Speech*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,11 @@ libbluez5_util = shared_library('bluez5-util',
 | 
			
		|||
  c_args : [pa_c_args, server_c_args],
 | 
			
		||||
  link_args : [nodelete_link_args],
 | 
			
		||||
  include_directories : [configinc, topinc],
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, bluez_dep, dbus_dep, sbc_dep, libintl_dep, bluez5_gst_dep, bluez5_gstapp_dep],
 | 
			
		||||
=======
 | 
			
		||||
  dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, bluez_dep, dbus_dep, sbc_dep, libintl_dep, bluez5_gst_dep, bluez5_gstapp_dep, libm_dep],
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  install : true,
 | 
			
		||||
  install_rpath : privlibdir,
 | 
			
		||||
  install_dir : modlibexecdir,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,8 +115,11 @@ struct userdata {
 | 
			
		|||
 | 
			
		||||
    pa_hook_slot *sink_volume_changed_slot;
 | 
			
		||||
    pa_hook_slot *source_volume_changed_slot;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    pa_hook_slot *source_output_new_hook_slot;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_bluetooth_discovery *discovery;
 | 
			
		||||
    pa_bluetooth_device *device;
 | 
			
		||||
| 
						 | 
				
			
			@ -273,18 +276,29 @@ static void connect_ports(struct userdata *u, void *new_data, pa_direction_t dir
 | 
			
		|||
 | 
			
		||||
static bool bt_prepare_encoder_buffer(struct userdata *u)
 | 
			
		||||
{
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    size_t encoded_size, reserved_size;
 | 
			
		||||
=======
 | 
			
		||||
    size_t encoded_size, reserved_size, encoded_frames;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    pa_assert(u);
 | 
			
		||||
    pa_assert(u->bt_codec);
 | 
			
		||||
 | 
			
		||||
    /* If socket write MTU is less than encoded frame size, there could be
 | 
			
		||||
     * up to one write MTU of data left in encoder buffer from previous round.
 | 
			
		||||
     *
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
     * Reserve space for 2 encoded frames to cover that.
 | 
			
		||||
=======
 | 
			
		||||
     * Reserve space for at least 2 encoded frames to cover that.
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
     *
 | 
			
		||||
     * Note for A2DP codecs it is expected that size of encoded frame is less
 | 
			
		||||
     * than write link MTU. Therefore each encoded frame is sent out completely
 | 
			
		||||
     * and there is no used space in encoder buffer before next encoder call.
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
     */
 | 
			
		||||
=======
 | 
			
		||||
     *
 | 
			
		||||
     * For SCO socket all writes will be of MTU size to match payload length
 | 
			
		||||
     * of HCI packet. Depending on selected USB Alternate Setting the payload
 | 
			
		||||
| 
						 | 
				
			
			@ -304,10 +318,15 @@ static bool bt_prepare_encoder_buffer(struct userdata *u)
 | 
			
		|||
     * See also https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/254#note_779802
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (u->bt_codec->get_encoded_block_size)
 | 
			
		||||
        encoded_size = u->bt_codec->get_encoded_block_size(u->encoder_info, u->write_block_size);
 | 
			
		||||
    else
 | 
			
		||||
        encoded_size = u->write_block_size;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    reserved_size = 2 * encoded_size;
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    encoded_frames = u->write_link_mtu / u->write_block_size + 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -315,6 +334,7 @@ static bool bt_prepare_encoder_buffer(struct userdata *u)
 | 
			
		|||
        encoded_frames = 2;
 | 
			
		||||
 | 
			
		||||
    reserved_size = encoded_frames * encoded_size;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    if (u->encoder_buffer_size < reserved_size) {
 | 
			
		||||
        u->encoder_buffer = pa_xrealloc(u->encoder_buffer, reserved_size);
 | 
			
		||||
| 
						 | 
				
			
			@ -324,11 +344,19 @@ static bool bt_prepare_encoder_buffer(struct userdata *u)
 | 
			
		|||
            u->encoder_buffer_used = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    /* Report if there is still not enough space for new block */
 | 
			
		||||
    if (u->encoder_buffer_size < u->encoder_buffer_used + encoded_size)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    /* Report if there is still not enough space for new block */
 | 
			
		||||
    if (u->encoder_buffer_size < u->encoder_buffer_used + encoded_size)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -413,10 +441,17 @@ static int bt_process_render(struct userdata *u) {
 | 
			
		|||
    u->write_index += (uint64_t) u->write_memchunk.length;
 | 
			
		||||
    pa_memblock_unref(u->write_memchunk.memblock);
 | 
			
		||||
    pa_memchunk_reset(&u->write_memchunk);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static void bt_prepare_decoder_buffer(struct userdata *u) {
 | 
			
		||||
    pa_assert(u);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -429,11 +464,19 @@ static void bt_prepare_decoder_buffer(struct userdata *u) {
 | 
			
		|||
     * decode method would produce larger output then read_block_size */
 | 
			
		||||
    u->decoder_buffer_size = u->read_link_mtu;
 | 
			
		||||
}
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
/* Run from IO thread */
 | 
			
		||||
static ssize_t bt_transport_read(pa_bluetooth_transport *t, int fd, void *buffer, size_t size, pa_usec_t *p_timestamp) {
 | 
			
		||||
    ssize_t received = 0;
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
/* Run from IO thread */
 | 
			
		||||
static ssize_t bt_transport_read(pa_bluetooth_transport *t, int fd, void *buffer, size_t size, pa_usec_t *p_timestamp) {
 | 
			
		||||
    ssize_t received = 0;
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    pa_assert(t);
 | 
			
		||||
    for (;;) {
 | 
			
		||||
        uint8_t aux[1024];
 | 
			
		||||
| 
						 | 
				
			
			@ -516,6 +559,16 @@ static int bt_process_push(struct userdata *u) {
 | 
			
		|||
    pa_assert(u->read_smoother);
 | 
			
		||||
    pa_assert(u->bt_codec);
 | 
			
		||||
    pa_assert(u->transport);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    bt_prepare_decoder_buffer(u);
 | 
			
		||||
 | 
			
		||||
    received = bt_transport_read(u->transport, u->stream_fd, u->decoder_buffer, u->decoder_buffer_size, &tstamp);
 | 
			
		||||
 | 
			
		||||
    if (received <= 0) {
 | 
			
		||||
        return received;
 | 
			
		||||
    }
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    bt_prepare_decoder_buffer(u);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -560,6 +613,37 @@ static int bt_process_push(struct userdata *u) {
 | 
			
		|||
 | 
			
		||||
    /* report decoded size */
 | 
			
		||||
    received = memchunk.length;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_memchunk memchunk;
 | 
			
		||||
 | 
			
		||||
    memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
 | 
			
		||||
    memchunk.index = memchunk.length = 0;
 | 
			
		||||
 | 
			
		||||
    ptr = pa_memblock_acquire(memchunk.memblock);
 | 
			
		||||
    memchunk.length = pa_memblock_get_length(memchunk.memblock);
 | 
			
		||||
 | 
			
		||||
    memchunk.length = u->bt_codec->decode_buffer(u->decoder_info, u->decoder_buffer, received, ptr, memchunk.length, &processed);
 | 
			
		||||
 | 
			
		||||
    pa_memblock_release(memchunk.memblock);
 | 
			
		||||
 | 
			
		||||
    if (processed != (size_t) received) {
 | 
			
		||||
        pa_log_error("Decoding error");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 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);
 | 
			
		||||
 | 
			
		||||
    /* report decoded size */
 | 
			
		||||
    received = memchunk.length;
 | 
			
		||||
 | 
			
		||||
    pa_memblock_unref(memchunk.memblock);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -950,6 +1034,45 @@ static void source_set_volume_cb(pa_source *s) {
 | 
			
		|||
 | 
			
		||||
    pa_cvolume_set(&s->real_volume, u->decoder_sample_spec.channels, volume);
 | 
			
		||||
}
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
/* Run from main thread */
 | 
			
		||||
static void source_setup_volume_callback(pa_source *s) {
 | 
			
		||||
    struct userdata *u;
 | 
			
		||||
 | 
			
		||||
    pa_assert(s);
 | 
			
		||||
    pa_assert(s->core);
 | 
			
		||||
 | 
			
		||||
    u = s->userdata;
 | 
			
		||||
    pa_assert(u);
 | 
			
		||||
    pa_assert(u->source == s);
 | 
			
		||||
    pa_assert(u->transport);
 | 
			
		||||
 | 
			
		||||
    if (pa_bluetooth_profile_is_a2dp(u->profile) && !u->transport->device->avrcp_absolute_volume)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    /* Remote volume control has to be supported for the callback to make sense,
 | 
			
		||||
     * otherwise this source should continue performing attenuation in software
 | 
			
		||||
     * without HW_VOLUME_CTL.
 | 
			
		||||
     * If the peer is an AG however backend-native unconditionally provides this
 | 
			
		||||
     * function, PA in the role of HS/HF is responsible for signalling support
 | 
			
		||||
     * by emitting an initial volume command.
 | 
			
		||||
     * For A2DP bluez-util also unconditionally provides this function to keep
 | 
			
		||||
     * the peer informed about volume changes.
 | 
			
		||||
     */
 | 
			
		||||
    if (!u->transport->set_source_volume)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (pa_bluetooth_profile_should_attenuate_volume(u->profile)) {
 | 
			
		||||
        if (u->source_volume_changed_slot)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        pa_log_debug("%s: Attaching volume hook to notify peer of changes", s->name);
 | 
			
		||||
 | 
			
		||||
        u->source_volume_changed_slot = pa_hook_connect(&s->core->hooks[PA_CORE_HOOK_SOURCE_VOLUME_CHANGED],
 | 
			
		||||
                                                        PA_HOOK_NORMAL, sink_source_volume_changed_cb, u);
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
/* Run from main thread */
 | 
			
		||||
static void source_setup_volume_callback(pa_source *s) {
 | 
			
		||||
| 
						 | 
				
			
			@ -993,6 +1116,7 @@ static void source_setup_volume_callback(pa_source *s) {
 | 
			
		|||
        u->source_volume_changed_slot = pa_hook_connect(&s->core->hooks[PA_CORE_HOOK_SOURCE_VOLUME_CHANGED],
 | 
			
		||||
                                                        PA_HOOK_NORMAL, sink_source_volume_changed_cb, u);
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        /* Send initial volume to peer, signalling support for volume control */
 | 
			
		||||
        u->transport->set_source_volume(u->transport, pa_cvolume_max(&s->real_volume));
 | 
			
		||||
    } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -1180,6 +1304,7 @@ static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state,
 | 
			
		|||
/* Run from main thread */
 | 
			
		||||
static void sink_set_volume_cb(pa_sink *s) {
 | 
			
		||||
    pa_volume_t volume;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    struct userdata *u;
 | 
			
		||||
 | 
			
		||||
    pa_assert(s);
 | 
			
		||||
| 
						 | 
				
			
			@ -1199,6 +1324,72 @@ static void sink_set_volume_cb(pa_sink *s) {
 | 
			
		|||
    pa_cvolume_set(&s->real_volume, u->encoder_sample_spec.channels, volume);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Run from main thread */
 | 
			
		||||
static void sink_setup_volume_callback(pa_sink *s) {
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    struct userdata *u;
 | 
			
		||||
 | 
			
		||||
    pa_assert(s);
 | 
			
		||||
    pa_assert(s->core);
 | 
			
		||||
 | 
			
		||||
    u = s->userdata;
 | 
			
		||||
    pa_assert(u);
 | 
			
		||||
    pa_assert(u->sink == s);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    pa_assert(u->transport);
 | 
			
		||||
 | 
			
		||||
    if (pa_bluetooth_profile_is_a2dp(u->profile) && !u->transport->device->avrcp_absolute_volume)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    /* Remote volume control has to be supported for the callback to make sense,
 | 
			
		||||
     * otherwise this sink should continue performing attenuation in software
 | 
			
		||||
     * without HW_VOLUME_CTL.
 | 
			
		||||
     * If the peer is an AG however backend-native unconditionally provides this
 | 
			
		||||
     * function, PA in the role of HS/HF is responsible for signalling support
 | 
			
		||||
     * by emitting an initial volume command.
 | 
			
		||||
     */
 | 
			
		||||
    if (!u->transport->set_sink_volume)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (pa_bluetooth_profile_should_attenuate_volume(u->profile)) {
 | 
			
		||||
        /* It is yet unknown how (if at all) volume is synchronized for bidirectional
 | 
			
		||||
         * A2DP codecs.  Disallow attaching hooks to a pa_sink if the peer is in
 | 
			
		||||
         * A2DP_SOURCE role.  This assert should be replaced with the proper logic
 | 
			
		||||
         * when bidirectional codecs are implemented.
 | 
			
		||||
         */
 | 
			
		||||
        pa_assert(u->profile != PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
 | 
			
		||||
 | 
			
		||||
        if (u->sink_volume_changed_slot)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        pa_log_debug("%s: Attaching volume hook to notify peer of changes", s->name);
 | 
			
		||||
 | 
			
		||||
        u->sink_volume_changed_slot = pa_hook_connect(&s->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED],
 | 
			
		||||
                                                      PA_HOOK_NORMAL, sink_source_volume_changed_cb, u);
 | 
			
		||||
 | 
			
		||||
        /* Send initial volume to peer, signalling support for volume control */
 | 
			
		||||
        u->transport->set_sink_volume(u->transport, pa_cvolume_max(&s->real_volume));
 | 
			
		||||
    } else {
 | 
			
		||||
        if (s->set_volume == sink_set_volume_cb)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        pa_log_debug("%s: Resetting software volume for hardware attenuation by peer", s->name);
 | 
			
		||||
 | 
			
		||||
        /* Reset local attenuation */
 | 
			
		||||
        pa_sink_set_soft_volume(s, NULL);
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
    pa_assert(!pa_bluetooth_profile_should_attenuate_volume(u->profile));
 | 
			
		||||
    pa_assert(u->transport);
 | 
			
		||||
    pa_assert(u->transport->set_sink_volume);
 | 
			
		||||
 | 
			
		||||
    /* In the AG role, send a command to change speaker gain on the HS/HF */
 | 
			
		||||
    volume = u->transport->set_sink_volume(u->transport, pa_cvolume_max(&s->real_volume));
 | 
			
		||||
 | 
			
		||||
    pa_cvolume_set(&s->real_volume, u->encoder_sample_spec.channels, volume);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Run from main thread */
 | 
			
		||||
static void sink_setup_volume_callback(pa_sink *s) {
 | 
			
		||||
    struct userdata *u;
 | 
			
		||||
| 
						 | 
				
			
			@ -1257,6 +1448,7 @@ static void sink_setup_volume_callback(pa_sink *s) {
 | 
			
		|||
        /* Reset local attenuation */
 | 
			
		||||
        pa_sink_set_soft_volume(s, NULL);
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        pa_sink_set_set_volume_callback(s, sink_set_volume_cb);
 | 
			
		||||
 | 
			
		||||
        if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK)
 | 
			
		||||
| 
						 | 
				
			
			@ -1341,6 +1533,25 @@ static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
 | 
			
		|||
 | 
			
		||||
    return profile_direction[p];
 | 
			
		||||
}
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
/* Run from main thread */
 | 
			
		||||
static int transport_config(struct userdata *u) {
 | 
			
		||||
    pa_assert(u);
 | 
			
		||||
    pa_assert(u->transport);
 | 
			
		||||
    pa_assert(!u->bt_codec);
 | 
			
		||||
    pa_assert(!u->encoder_info);
 | 
			
		||||
    pa_assert(!u->decoder_info);
 | 
			
		||||
 | 
			
		||||
    u->bt_codec = u->transport->bt_codec;
 | 
			
		||||
    pa_assert(u->bt_codec);
 | 
			
		||||
 | 
			
		||||
    /* reset encoder buffer contents */
 | 
			
		||||
    u->encoder_buffer_used = 0;
 | 
			
		||||
 | 
			
		||||
    if (get_profile_direction(u->profile) & PA_DIRECTION_OUTPUT) {
 | 
			
		||||
        u->encoder_info = u->bt_codec->init(true, false, u->transport->config, u->transport->config_size, &u->encoder_sample_spec, u->core);
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
/* Run from main thread */
 | 
			
		||||
static int transport_config(struct userdata *u) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1362,13 +1573,19 @@ static int transport_config(struct userdata *u) {
 | 
			
		|||
 | 
			
		||||
    if ((get_profile_direction(u->profile) & PA_DIRECTION_OUTPUT) || u->bt_codec->support_backchannel) {
 | 
			
		||||
        u->encoder_info = u->bt_codec->init(true, reverse_backchannel, u->transport->config, u->transport->config_size, &u->encoder_sample_spec, u->core);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
        if (!u->encoder_info)
 | 
			
		||||
            return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    if (get_profile_direction(u->profile) & PA_DIRECTION_INPUT) {
 | 
			
		||||
        u->decoder_info = u->bt_codec->init(false, false, u->transport->config, u->transport->config_size, &u->decoder_sample_spec, u->core);
 | 
			
		||||
=======
 | 
			
		||||
    if ((get_profile_direction(u->profile) & PA_DIRECTION_INPUT) || u->bt_codec->support_backchannel) {
 | 
			
		||||
        u->decoder_info = u->bt_codec->init(false, reverse_backchannel, u->transport->config, u->transport->config_size, &u->decoder_sample_spec, u->core);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
        if (!u->decoder_info) {
 | 
			
		||||
            if (u->encoder_info) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1631,6 +1848,13 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                                skip_bytes -= bytes_to_render;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
                            if (u->write_index > 0 && (get_profile_direction(u->profile) & PA_DIRECTION_OUTPUT)) {
 | 
			
		||||
                                size_t new_write_block_size = u->bt_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);
 | 
			
		||||
=======
 | 
			
		||||
                            if (u->write_index > 0 && (get_profile_direction(u->profile) & PA_DIRECTION_OUTPUT || u->bt_codec->support_backchannel)) {
 | 
			
		||||
                                if (u->bt_codec->reduce_encoder_bitrate) {
 | 
			
		||||
                                    size_t new_write_block_size = u->bt_codec->reduce_encoder_bitrate(u->encoder_info, u->write_link_mtu);
 | 
			
		||||
| 
						 | 
				
			
			@ -1639,7 +1863,9 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                                        handle_sink_block_size_change(u);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    pa_gettimeofday(&tv_last_output_rate_change);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
                                }
 | 
			
		||||
                                pa_gettimeofday(&tv_last_output_rate_change);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1663,12 +1889,15 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                            goto fail;
 | 
			
		||||
 | 
			
		||||
                        if (result) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
                            if (have_source && u->read_index <= 0) {
 | 
			
		||||
                                /* We have a source but peer has not sent any data yet, log this */
 | 
			
		||||
                                if (pa_log_ratelimit(PA_LOG_DEBUG))
 | 
			
		||||
                                    pa_log_debug("Still no data received from source, sent one more block to sink");
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
                            writable = false;
 | 
			
		||||
                            have_written = true;
 | 
			
		||||
                        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1688,7 +1917,11 @@ static void thread_func(void *userdata) {
 | 
			
		|||
                            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); */
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
                            if ((get_profile_direction(u->profile) & PA_DIRECTION_OUTPUT) && u->write_memchunk.memblock == NULL) {
 | 
			
		||||
=======
 | 
			
		||||
                            if ((get_profile_direction(u->profile) & PA_DIRECTION_OUTPUT || u->bt_codec->support_backchannel) && u->write_memchunk.memblock == NULL) {
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
                                /* bt_write_buffer() is keeping up with input, try increasing bitrate */
 | 
			
		||||
                                if (u->bt_codec->increase_encoder_bitrate
 | 
			
		||||
                                    && pa_timeval_age(&tv_last_output_rate_change) >= u->device->output_rate_refresh_interval_ms * PA_USEC_PER_MSEC) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2603,10 +2836,17 @@ static int bluez5_device_message_handler(const char *object_path, const char *me
 | 
			
		|||
    pa_bluetooth_profile_t profile;
 | 
			
		||||
    const pa_a2dp_endpoint_conf *endpoint_conf;
 | 
			
		||||
    const char *codec_name;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    struct userdata *u;
 | 
			
		||||
    bool is_a2dp_sink;
 | 
			
		||||
 | 
			
		||||
    pa_assert(u = (struct userdata *)userdata);
 | 
			
		||||
=======
 | 
			
		||||
    struct userdata *u = userdata;
 | 
			
		||||
    bool is_a2dp_sink;
 | 
			
		||||
 | 
			
		||||
    pa_assert(u);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    pa_assert(message);
 | 
			
		||||
    pa_assert(response);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2867,8 +3107,11 @@ int pa__init(pa_module* m) {
 | 
			
		|||
 | 
			
		||||
    u->transport_source_volume_changed_slot =
 | 
			
		||||
        pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SOURCE_VOLUME_CHANGED), PA_HOOK_NORMAL, (pa_hook_cb_t) transport_source_volume_changed_cb, u);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    u->source_output_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) a2dp_source_output_fixate_hook_callback, u);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    if (add_card(u) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,38 @@ static const char* const valid_modargs[] = {
 | 
			
		|||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static int routing_mode_from_string(const char *rmode) {
 | 
			
		||||
    if (pa_streq(rmode, "quiet-earpiece-or-headset"))
 | 
			
		||||
        return webrtc::EchoControlMobile::kQuietEarpieceOrHeadset;
 | 
			
		||||
    else if (pa_streq(rmode, "earpiece"))
 | 
			
		||||
        return webrtc::EchoControlMobile::kEarpiece;
 | 
			
		||||
    else if (pa_streq(rmode, "loud-earpiece"))
 | 
			
		||||
        return webrtc::EchoControlMobile::kLoudEarpiece;
 | 
			
		||||
    else if (pa_streq(rmode, "speakerphone"))
 | 
			
		||||
        return webrtc::EchoControlMobile::kSpeakerphone;
 | 
			
		||||
    else if (pa_streq(rmode, "loud-speakerphone"))
 | 
			
		||||
        return webrtc::EchoControlMobile::kLoudSpeakerphone;
 | 
			
		||||
    else
 | 
			
		||||
        return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class PaWebrtcTraceCallback : public webrtc::TraceCallback {
 | 
			
		||||
    void Print(webrtc::TraceLevel level, const char *message, int length)
 | 
			
		||||
    {
 | 
			
		||||
        if (level & webrtc::kTraceError || level & webrtc::kTraceCritical)
 | 
			
		||||
            pa_log("%s", message);
 | 
			
		||||
        else if (level & webrtc::kTraceWarning)
 | 
			
		||||
            pa_log_warn("%s", message);
 | 
			
		||||
        else if (level & webrtc::kTraceInfo)
 | 
			
		||||
            pa_log_info("%s", message);
 | 
			
		||||
        else
 | 
			
		||||
            pa_log_debug("%s", message);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static int webrtc_volume_from_pa(pa_volume_t v)
 | 
			
		||||
{
 | 
			
		||||
    return (v * WEBRTC_AGC_MAX_VOLUME) / PA_VOLUME_NORM;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,13 +71,19 @@ PA_MODULE_USAGE(
 | 
			
		|||
 | 
			
		||||
static const char* const valid_modargs[] = {
 | 
			
		||||
    "channels",
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    "sink_enabled",
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    "sink_name",
 | 
			
		||||
    "sink_properties",
 | 
			
		||||
    "sink_client_name",
 | 
			
		||||
    "sink_channels",
 | 
			
		||||
    "sink_channel_map",
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    "source_enabled",
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    "source_name",
 | 
			
		||||
    "source_properties",
 | 
			
		||||
    "source_client_name",
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +108,10 @@ static const char* const modtypes[JACK_SS_COUNT] = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
struct moddata {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
    bool enabled;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    char *name;
 | 
			
		||||
    pa_proplist *proplist;
 | 
			
		||||
    char *client_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +190,11 @@ static void ensure_ports_started(struct userdata* u) {
 | 
			
		|||
    pa_assert(u);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < JACK_SS_COUNT; i++)
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        if (!u->jack_module_index[i]) {
 | 
			
		||||
=======
 | 
			
		||||
        if (u->mod_args[i].enabled && !u->jack_module_index[i]) {
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            pa_strbuf *args_buf = pa_strbuf_new();
 | 
			
		||||
            char *args;
 | 
			
		||||
            pa_module *m;
 | 
			
		||||
| 
						 | 
				
			
			@ -190,6 +203,7 @@ static void ensure_ports_started(struct userdata* u) {
 | 
			
		|||
                escaped = pa_escape(u->mod_args[i].name, "'");
 | 
			
		||||
                pa_strbuf_printf(args_buf, " %s_name='%s'", modtypes[i], escaped);
 | 
			
		||||
                pa_xfree(escaped);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            }
 | 
			
		||||
            if (!pa_proplist_isempty(u->mod_args[i].proplist)) {
 | 
			
		||||
                escaped = proplist_to_arg(u->mod_args[i].proplist);
 | 
			
		||||
| 
						 | 
				
			
			@ -208,6 +222,26 @@ static void ensure_ports_started(struct userdata* u) {
 | 
			
		|||
                pa_channel_map_snprint(cm, sizeof(cm), &u->mod_args[i].channel_map);
 | 
			
		||||
                pa_strbuf_printf(args_buf, " channel_map='%s'", cm);
 | 
			
		||||
            }
 | 
			
		||||
=======
 | 
			
		||||
            }
 | 
			
		||||
            if (!pa_proplist_isempty(u->mod_args[i].proplist)) {
 | 
			
		||||
                escaped = proplist_to_arg(u->mod_args[i].proplist);
 | 
			
		||||
                pa_strbuf_printf(args_buf, " %s_properties='%s'", modtypes[i], escaped);
 | 
			
		||||
                pa_xfree(escaped);
 | 
			
		||||
            }
 | 
			
		||||
            if (u->mod_args[i].client_name) {
 | 
			
		||||
                escaped = pa_escape(u->mod_args[i].client_name, "'");
 | 
			
		||||
                pa_strbuf_printf(args_buf, " client_name='%s'", escaped);
 | 
			
		||||
                pa_xfree(escaped);
 | 
			
		||||
            }
 | 
			
		||||
            if (u->mod_args[i].channels > 0)
 | 
			
		||||
                pa_strbuf_printf(args_buf, " channels=%" PRIu32, u->mod_args[i].channels);
 | 
			
		||||
            if (u->mod_args[i].channel_map.channels > 0) {
 | 
			
		||||
                char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
 | 
			
		||||
                pa_channel_map_snprint(cm, sizeof(cm), &u->mod_args[i].channel_map);
 | 
			
		||||
                pa_strbuf_printf(args_buf, " channel_map='%s'", cm);
 | 
			
		||||
            }
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            args = pa_strbuf_to_string_free(args_buf);
 | 
			
		||||
            pa_module_load(&m, u->core, modnames[i], args);
 | 
			
		||||
            pa_xfree(args);
 | 
			
		||||
| 
						 | 
				
			
			@ -343,6 +377,23 @@ int pa__init(pa_module *m) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < JACK_SS_COUNT; i++) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        pa_snprintf(argname, sizeof(argname), "%s_name", modtypes[i]);
 | 
			
		||||
        name = pa_modargs_get_value(ma, argname, NULL);
 | 
			
		||||
        u->mod_args[i].name = pa_xstrdup(name);
 | 
			
		||||
 | 
			
		||||
        u->mod_args[i].proplist = pa_proplist_new();
 | 
			
		||||
        pa_snprintf(argname, sizeof(argname), "%s_properties", modtypes[i]);
 | 
			
		||||
        if (pa_modargs_get_proplist(ma, argname, u->mod_args[i].proplist, PA_UPDATE_REPLACE) < 0) {
 | 
			
		||||
            pa_log("Invalid %s properties", modtypes[i]);
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pa_snprintf(argname, sizeof(argname), "%s_client_name", modtypes[i]);
 | 
			
		||||
        name = pa_modargs_get_value(ma, argname, NULL);
 | 
			
		||||
        u->mod_args[i].client_name = pa_xstrdup(name);
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
        u->mod_args[i].enabled = true;
 | 
			
		||||
        pa_snprintf(argname, sizeof(argname), "%s_enabled", modtypes[i]);
 | 
			
		||||
        if (pa_modargs_get_value_boolean(ma, argname, &u->mod_args[i].enabled) < 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -365,6 +416,7 @@ int pa__init(pa_module *m) {
 | 
			
		|||
        name = pa_modargs_get_value(ma, argname, NULL);
 | 
			
		||||
        u->mod_args[i].client_name = pa_xstrdup(name);
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        u->mod_args[i].channels = channels;
 | 
			
		||||
        pa_snprintf(argname, sizeof(argname), "%s_channels", modtypes[i]);
 | 
			
		||||
        if (pa_modargs_get_value_u32(ma, argname, &u->mod_args[i].channels) < 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,11 +70,17 @@ endif
 | 
			
		|||
 | 
			
		||||
if host_machine.system() != 'windows'
 | 
			
		||||
  all_modules += [
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    [ 'module-rtp-recv', 'rtp/module-rtp-recv.c', [], [], [], librtp ],
 | 
			
		||||
=======
 | 
			
		||||
    [ 'module-rtp-recv', 'rtp/module-rtp-recv.c', [], [], [libatomic_ops_dep], librtp ],
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    [ 'module-rtp-send', 'rtp/module-rtp-send.c' , [], [], [], librtp ],
 | 
			
		||||
  ]
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
if host_machine.system() == 'darwin'
 | 
			
		||||
  bonjour_dep = dependency('appleframeworks', modules : ['CoreFoundation'])
 | 
			
		||||
  coreaudio_dep = dependency('appleframeworks', modules : ['CoreAudio'])
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +91,7 @@ if host_machine.system() == 'darwin'
 | 
			
		|||
  ]
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
# Modules enabled by headers
 | 
			
		||||
 | 
			
		||||
if cc.has_header('linux/input.h')
 | 
			
		||||
| 
						 | 
				
			
			@ -167,13 +174,23 @@ if fftw_dep.found()
 | 
			
		|||
  ]
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if fftw_dep.found()
 | 
			
		||||
  all_modules += [
 | 
			
		||||
    [ 'module-virtual-surround-sink', 'module-virtual-surround-sink.c', [], [], [fftw_dep, libm_dep] ],
 | 
			
		||||
  ]
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if dbus_dep.found() and fftw_dep.found()
 | 
			
		||||
  all_modules += [
 | 
			
		||||
    [ 'module-equalizer-sink', 'module-equalizer-sink.c', [], [], [dbus_dep, fftw_dep, libm_dep] ],
 | 
			
		||||
  ]
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
if get_option('gsettings').enabled() and gio_dep.found()
 | 
			
		||||
=======
 | 
			
		||||
if get_option('gsettings').enabled() and glib_dep.found() and gio_dep.found()
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  subdir('gsettings')
 | 
			
		||||
  all_modules += [
 | 
			
		||||
    [ 'module-gsettings',
 | 
			
		||||
| 
						 | 
				
			
			@ -334,7 +351,11 @@ foreach m : all_modules
 | 
			
		|||
    install_rpath : rpath_dirs,
 | 
			
		||||
    install_dir : modlibexecdir,
 | 
			
		||||
    dependencies : [thread_dep, libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libintl_dep, platform_dep, platform_socket_dep] + extra_deps,
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    link_args : [nodelete_link_args, '-Wl,--no-undefined' ],
 | 
			
		||||
=======
 | 
			
		||||
    link_args : [nodelete_link_args, no_undefined_args],
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    link_with : extra_libs,
 | 
			
		||||
    name_prefix : '',
 | 
			
		||||
    name_suffix : module_suffix,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -345,6 +345,8 @@ static void stream_overflow_callback(pa_stream *stream, void *userdata) {
 | 
			
		|||
    pa_log_info("Server signalled buffer overrun.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
/* Do a reinit of the module.  Note that u will be freed as a result of this
 | 
			
		||||
 * call. */
 | 
			
		||||
static void maybe_restart(struct module_restart_data *rd) {
 | 
			
		||||
| 
						 | 
				
			
			@ -426,6 +428,7 @@ static void on_sink_created(struct userdata *u) {
 | 
			
		|||
    u->connected = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
static void context_state_cb(pa_context *c, void *userdata) {
 | 
			
		||||
    struct userdata *u = userdata;
 | 
			
		||||
    pa_assert(u);
 | 
			
		||||
| 
						 | 
				
			
			@ -445,8 +448,49 @@ static void context_state_cb(pa_context *c, void *userdata) {
 | 
			
		|||
            pa_assert(!u->stream);
 | 
			
		||||
            pa_assert(!u->sink);
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            proplist = tunnel_new_proplist(u);
 | 
			
		||||
            u->stream = pa_stream_new_with_proplist(u->context,
 | 
			
		||||
                                                    stream_name,
 | 
			
		||||
                                                    &u->sink->sample_spec,
 | 
			
		||||
                                                    &u->sink->channel_map,
 | 
			
		||||
                                                    proplist);
 | 
			
		||||
            pa_proplist_free(proplist);
 | 
			
		||||
            pa_xfree(stream_name);
 | 
			
		||||
 | 
			
		||||
            if (!u->stream) {
 | 
			
		||||
                pa_log_error("Could not create a stream.");
 | 
			
		||||
                u->thread_mainloop_api->quit(u->thread_mainloop_api, TUNNEL_THREAD_FAILED_MAINLOOP);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            requested_latency = pa_sink_get_requested_latency_within_thread(u->sink);
 | 
			
		||||
            if (requested_latency == (pa_usec_t) -1)
 | 
			
		||||
                requested_latency = u->sink->thread_info.max_latency;
 | 
			
		||||
 | 
			
		||||
            reset_bufferattr(&bufferattr);
 | 
			
		||||
            bufferattr.tlength = pa_usec_to_bytes(requested_latency, &u->sink->sample_spec);
 | 
			
		||||
 | 
			
		||||
            pa_log_debug("tlength requested at %lu.", (unsigned long) bufferattr.tlength);
 | 
			
		||||
 | 
			
		||||
            pa_stream_set_state_callback(u->stream, stream_state_cb, userdata);
 | 
			
		||||
            pa_stream_set_buffer_attr_callback(u->stream, stream_changed_buffer_attr_cb, userdata);
 | 
			
		||||
            pa_stream_set_underflow_callback(u->stream, stream_underflow_callback, userdata);
 | 
			
		||||
            pa_stream_set_overflow_callback(u->stream, stream_overflow_callback, userdata);
 | 
			
		||||
            if (pa_stream_connect_playback(u->stream,
 | 
			
		||||
                                           u->remote_sink_name,
 | 
			
		||||
                                           &bufferattr,
 | 
			
		||||
                                           PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_DONT_MOVE | PA_STREAM_START_CORKED | PA_STREAM_AUTO_TIMING_UPDATE,
 | 
			
		||||
                                           NULL,
 | 
			
		||||
                                           NULL) < 0) {
 | 
			
		||||
                pa_log_error("Could not connect stream.");
 | 
			
		||||
                u->thread_mainloop_api->quit(u->thread_mainloop_api, TUNNEL_THREAD_FAILED_MAINLOOP);
 | 
			
		||||
            }
 | 
			
		||||
            u->connected = true;
 | 
			
		||||
=======
 | 
			
		||||
            pa_log_debug("Asking ctl thread to create sink.");
 | 
			
		||||
            pa_asyncmsgq_post(u->thread_mq->outq, PA_MSGOBJECT(u->msg), TUNNEL_MESSAGE_CREATE_SINK_REQUEST, u, 0, NULL, NULL);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            break;
 | 
			
		||||
        case PA_CONTEXT_FAILED:
 | 
			
		||||
            pa_log_debug("Context failed: %s.", pa_strerror(pa_context_errno(u->context)));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -449,6 +449,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes_input, pa_memchunk
 | 
			
		|||
 | 
			
		||||
    pa_memzero(u->outspace[0], BLOCK_SIZE * 4);
 | 
			
		||||
    pa_memzero(u->outspace[1], BLOCK_SIZE * 4);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    for (c = 0; c < u->inputs; c++) {
 | 
			
		||||
        fftwf_complex *f_in = u->f_in;
 | 
			
		||||
| 
						 | 
				
			
			@ -460,6 +461,19 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes_input, pa_memchunk
 | 
			
		|||
            fftwf_complex *f_ir = u->f_ir[c * 2 + ear];
 | 
			
		||||
            float *outspace = u->outspace[ear];
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    for (c = 0; c < u->inputs; c++) {
 | 
			
		||||
        fftwf_complex *f_in = u->f_in;
 | 
			
		||||
        fftwf_complex *f_out = u->f_out;
 | 
			
		||||
 | 
			
		||||
        fftwf_execute(u->p_fw[c]);
 | 
			
		||||
 | 
			
		||||
        for (ear = 0; ear < 2; ear++) {
 | 
			
		||||
            fftwf_complex *f_ir = u->f_ir[c * 2 + ear];
 | 
			
		||||
            float *outspace = u->outspace[ear];
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
            for (s = 0, fftlen = u->fftlen / 2 + 1; s < fftlen; s++) {
 | 
			
		||||
                float re = f_ir[s][0] * f_in[s][0] - f_ir[s][1] * f_in[s][1];
 | 
			
		||||
                float im = f_ir[s][1] * f_in[s][0] + f_ir[s][0] * f_in[s][1];
 | 
			
		||||
| 
						 | 
				
			
			@ -479,6 +493,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes_input, pa_memchunk
 | 
			
		|||
    for (s = 0, fftlen = BLOCK_SIZE; s < fftlen; s++) {
 | 
			
		||||
        float output;
 | 
			
		||||
        float *outspace = u->outspace[0];
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
        output = outspace[s];
 | 
			
		||||
        if (output < -1.0) output = -1.0;
 | 
			
		||||
| 
						 | 
				
			
			@ -487,6 +502,16 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes_input, pa_memchunk
 | 
			
		|||
 | 
			
		||||
        outspace = u->outspace[1];
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
        output = outspace[s];
 | 
			
		||||
        if (output < -1.0) output = -1.0;
 | 
			
		||||
        if (output > 1.0) output = 1.0;
 | 
			
		||||
        dst[s * 2 + 0] = output;
 | 
			
		||||
 | 
			
		||||
        outspace = u->outspace[1];
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        output = outspace[s];
 | 
			
		||||
        if (output < -1.0) output = -1.0;
 | 
			
		||||
        if (output > 1.0) output = 1.0;
 | 
			
		||||
| 
						 | 
				
			
			@ -724,6 +749,7 @@ int pa__init(pa_module*m) {
 | 
			
		|||
    size_t hrir_copied_length, hrir_total_length;
 | 
			
		||||
    int hrir_channels;
 | 
			
		||||
    int fftlen;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    float *impulse_temp=NULL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -732,6 +758,16 @@ int pa__init(pa_module*m) {
 | 
			
		|||
 | 
			
		||||
    fftwf_plan p;
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    float *impulse_temp=NULL;
 | 
			
		||||
 | 
			
		||||
    unsigned *mapping_left=NULL;
 | 
			
		||||
    unsigned *mapping_right=NULL;
 | 
			
		||||
 | 
			
		||||
    fftwf_plan p;
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    pa_channel_map hrir_map, hrir_right_map;
 | 
			
		||||
 | 
			
		||||
    pa_sample_spec hrir_left_temp_ss;
 | 
			
		||||
| 
						 | 
				
			
			@ -1150,10 +1186,17 @@ fail:
 | 
			
		|||
 | 
			
		||||
    if (mapping_right)
 | 
			
		||||
        pa_xfree(mapping_right);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    if (hrir_data)
 | 
			
		||||
        pa_xfree(hrir_data);
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    if (hrir_data)
 | 
			
		||||
        pa_xfree(hrir_data);
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (hrir_right_data)
 | 
			
		||||
        pa_xfree(hrir_right_data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1212,6 +1255,7 @@ void pa__done(pa_module*m) {
 | 
			
		|||
 | 
			
		||||
    if (u->memblockq_sink)
 | 
			
		||||
        pa_memblockq_free(u->memblockq_sink);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
    if (u->p_fw) {
 | 
			
		||||
        for (i = 0, j = u->inputs; i < j; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1246,6 +1290,42 @@ void pa__done(pa_module*m) {
 | 
			
		|||
    if (u->outspace[1])
 | 
			
		||||
        fftwf_free(u->outspace[1]);
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    if (u->p_fw) {
 | 
			
		||||
        for (i = 0, j = u->inputs; i < j; i++) {
 | 
			
		||||
            if (u->p_fw[i])
 | 
			
		||||
                fftwf_destroy_plan(u->p_fw[i]);
 | 
			
		||||
        }
 | 
			
		||||
        fftwf_free(u->p_fw);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (u->p_bw)
 | 
			
		||||
        fftwf_destroy_plan(u->p_bw);
 | 
			
		||||
 | 
			
		||||
    if (u->f_ir) {
 | 
			
		||||
        for (i = 0, j = u->inputs * 2; i < j; i++) {
 | 
			
		||||
            if (u->f_ir[i])
 | 
			
		||||
                fftwf_free(u->f_ir[i]);
 | 
			
		||||
        }
 | 
			
		||||
        fftwf_free(u->f_ir);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (u->f_out)
 | 
			
		||||
        fftwf_free(u->f_out);
 | 
			
		||||
 | 
			
		||||
    if (u->f_in)
 | 
			
		||||
        fftwf_free(u->f_in);
 | 
			
		||||
 | 
			
		||||
    if (u->revspace)
 | 
			
		||||
        fftwf_free(u->revspace);
 | 
			
		||||
 | 
			
		||||
    if (u->outspace[0])
 | 
			
		||||
        fftwf_free(u->outspace[0]);
 | 
			
		||||
    if (u->outspace[1])
 | 
			
		||||
        fftwf_free(u->outspace[1]);
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (u->inspace) {
 | 
			
		||||
        for (i = 0, j = u->inputs; i < j; i++) {
 | 
			
		||||
            if (u->inspace[i])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,26 +60,7 @@ struct userdata {
 | 
			
		|||
    pa_x11_client *x11_client;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    IceConn connection;
 | 
			
		||||
    struct userdata *userdata;
 | 
			
		||||
} ice_io_callback_data;
 | 
			
		||||
 | 
			
		||||
static void* ice_io_cb_data_new(IceConn connection, struct userdata *userdata) {
 | 
			
		||||
    ice_io_callback_data *data = pa_xnew(ice_io_callback_data, 1);
 | 
			
		||||
 | 
			
		||||
    data->connection = connection;
 | 
			
		||||
    data->userdata = userdata;
 | 
			
		||||
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ice_io_cb_data_destroy(pa_mainloop_api*a, pa_io_event *e, void *userdata) {
 | 
			
		||||
    pa_assert(userdata);
 | 
			
		||||
 | 
			
		||||
    pa_xfree(userdata);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) {
 | 
			
		||||
    struct userdata *u = userdata;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +88,60 @@ static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) {
 | 
			
		|||
    pa_module_unload_request(u->module, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void die_cb(SmcConn connection, SmPointer client_data) {
 | 
			
		||||
    struct userdata *u = client_data;
 | 
			
		||||
=======
 | 
			
		||||
typedef struct {
 | 
			
		||||
    IceConn connection;
 | 
			
		||||
    struct userdata *userdata;
 | 
			
		||||
} ice_io_callback_data;
 | 
			
		||||
 | 
			
		||||
static void* ice_io_cb_data_new(IceConn connection, struct userdata *userdata) {
 | 
			
		||||
    ice_io_callback_data *data = pa_xnew(ice_io_callback_data, 1);
 | 
			
		||||
 | 
			
		||||
    data->connection = connection;
 | 
			
		||||
    data->userdata = userdata;
 | 
			
		||||
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ice_io_cb_data_destroy(pa_mainloop_api*a, pa_io_event *e, void *userdata) {
 | 
			
		||||
    pa_assert(userdata);
 | 
			
		||||
 | 
			
		||||
    pa_xfree(userdata);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) {
 | 
			
		||||
    struct userdata *u = userdata;
 | 
			
		||||
 | 
			
		||||
    pa_assert(w);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    pa_assert(u);
 | 
			
		||||
    pa_assert(u->x11_wrapper == w);
 | 
			
		||||
 | 
			
		||||
    pa_log_debug("X11 client kill callback called");
 | 
			
		||||
 | 
			
		||||
    if (u->connection) {
 | 
			
		||||
        SmcCloseConnection(u->connection, 0, NULL);
 | 
			
		||||
        u->connection = NULL;
 | 
			
		||||
    }
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    if (u->x11_client) {
 | 
			
		||||
        pa_x11_client_free(u->x11_client);
 | 
			
		||||
        u->x11_client = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (u->x11_wrapper) {
 | 
			
		||||
        pa_x11_wrapper_unref(u->x11_wrapper);
 | 
			
		||||
        u->x11_wrapper = NULL;
 | 
			
		||||
    }
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    pa_x11_wrapper_kill_deferred(u->x11_wrapper);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void close_xsmp_connection(struct userdata *userdata) {
 | 
			
		||||
    pa_assert(userdata);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,8 +184,15 @@ static void ice_io_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_fla
 | 
			
		|||
 | 
			
		||||
        IceSetShutdownNegotiation(io_data->connection, False);
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    if (IceProcessMessages(connection, NULL, NULL) == IceProcessMessagesIOError) {
 | 
			
		||||
        pa_log_debug("IceProcessMessages: I/O error, closing ICE connection");
 | 
			
		||||
        IceSetShutdownNegotiation(connection, False);
 | 
			
		||||
        IceCloseConnection(connection);
 | 
			
		||||
=======
 | 
			
		||||
        /* SM owns this connection, close via SmcCloseConnection() */
 | 
			
		||||
        close_xsmp_connection(io_data->userdata);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -183,6 +225,17 @@ static void ice_io_error_handler(IceConn iceConn) {
 | 
			
		|||
      (*ice_installed_handler) (iceConn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static IceIOErrorHandler ice_installed_handler;
 | 
			
		||||
 | 
			
		||||
/* We call any handler installed before (or after) module is loaded but
 | 
			
		||||
   avoid calling the default libICE handler which does an exit() */
 | 
			
		||||
 | 
			
		||||
static void ice_io_error_handler(IceConn iceConn) {
 | 
			
		||||
    pa_log_warn("ICE I/O error handler called");
 | 
			
		||||
    if (ice_installed_handler)
 | 
			
		||||
      (*ice_installed_handler) (iceConn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa__init(pa_module*m) {
 | 
			
		||||
 | 
			
		||||
    pa_modargs *ma = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -202,14 +255,27 @@ int pa__init(pa_module*m) {
 | 
			
		|||
        return -1;
 | 
			
		||||
    } else {
 | 
			
		||||
        IceIOErrorHandler default_handler;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
        ice_installed_handler = IceSetIOErrorHandler (NULL);
 | 
			
		||||
        default_handler = IceSetIOErrorHandler (ice_io_error_handler);
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
        ice_installed_handler = IceSetIOErrorHandler (NULL);
 | 
			
		||||
        default_handler = IceSetIOErrorHandler (ice_io_error_handler);
 | 
			
		||||
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
        if (ice_installed_handler == default_handler)
 | 
			
		||||
            ice_installed_handler = NULL;
 | 
			
		||||
 | 
			
		||||
        IceSetIOErrorHandler(ice_io_error_handler);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
        IceAddConnectionWatch(new_ice_connection, m->core);
 | 
			
		||||
        ice_in_use = true;
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -218,9 +284,12 @@ int pa__init(pa_module*m) {
 | 
			
		|||
    u->client = NULL;
 | 
			
		||||
    u->connection = NULL;
 | 
			
		||||
    u->x11_wrapper = NULL;
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    IceAddConnectionWatch(new_ice_connection, u);
 | 
			
		||||
    ice_in_use = true;
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
 | 
			
		||||
        pa_log("Failed to parse module arguments");
 | 
			
		||||
| 
						 | 
				
			
			@ -348,6 +417,12 @@ void pa__done(pa_module*m) {
 | 
			
		|||
 | 
			
		||||
        if (u->x11_client)
 | 
			
		||||
            pa_x11_client_free(u->x11_client);
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
        if (u->x11_wrapper)
 | 
			
		||||
            pa_x11_wrapper_unref(u->x11_wrapper);
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
        if (u->x11_wrapper)
 | 
			
		||||
            pa_x11_wrapper_unref(u->x11_wrapper);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,6 +70,13 @@ if glib_dep.found()
 | 
			
		|||
  libpulse_headers += 'glib-mainloop.h'
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
run_target('update-map-file',
 | 
			
		||||
  command : [ join_paths(meson.source_root(), 'scripts/generate-map-file.sh'), 'map-file',
 | 
			
		||||
              [ libpulse_headers, 'simple.h', join_paths(meson.build_root(), 'src', 'pulse', 'version.h') ] ])
 | 
			
		||||
 | 
			
		||||
versioning_link_args = '-Wl,-version-script=' + join_paths(meson.source_root(), 'src', 'pulse', 'map-file')
 | 
			
		||||
=======
 | 
			
		||||
if host_machine.system() != 'windows' and host_machine.system() != 'darwin'
 | 
			
		||||
  run_target('update-map-file',
 | 
			
		||||
    command : [ join_paths(meson.source_root(), 'scripts/generate-map-file.sh'), 'map-file', 'libpulse.def',
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +86,7 @@ if host_machine.system() != 'windows' and host_machine.system() != 'darwin'
 | 
			
		|||
else
 | 
			
		||||
  versioning_link_args = []
 | 
			
		||||
endif
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
libpulse = shared_library('pulse',
 | 
			
		||||
  libpulse_sources,
 | 
			
		||||
| 
						 | 
				
			
			@ -89,10 +97,15 @@ libpulse = shared_library('pulse',
 | 
			
		|||
  link_args : [nodelete_link_args, versioning_link_args],
 | 
			
		||||
  install : true,
 | 
			
		||||
  install_rpath : privlibdir,
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  dependencies : [libm_dep, thread_dep, libpulsecommon_dep, dbus_dep, dl_dep, iconv_dep, libintl_dep, platform_dep, platform_socket_dep],
 | 
			
		||||
  implicit_include_directories : false)
 | 
			
		||||
=======
 | 
			
		||||
  dependencies : [libm_dep, thread_dep, libpulsecommon_dep, dbus_dep, dl_dep, iconv_dep, libintl_dep, platform_dep, platform_socket_dep, libatomic_ops_dep],
 | 
			
		||||
  implicit_include_directories : false,
 | 
			
		||||
  vs_module_defs : 'libpulse.def',
 | 
			
		||||
)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
libpulse_dep = declare_dependency(link_with: libpulse)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -228,7 +228,11 @@ char *pa_get_binary_name(char *s, size_t l) {
 | 
			
		|||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
#if defined(__linux__) || (defined(__FreeBSD_kernel__) && !defined(__FreeBSD__))
 | 
			
		||||
=======
 | 
			
		||||
#if defined(__linux__) || (defined(__FreeBSD_kernel__) && !defined(__FreeBSD__)) || defined(__GNU__)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    {
 | 
			
		||||
        char *rp;
 | 
			
		||||
        /* This works on Linux and Debian/kFreeBSD */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -467,10 +467,17 @@ int pa_card_suspend(pa_card *c, bool suspend, pa_suspend_cause_t cause) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static int card_message_handler(const char *object_path, const char *message, const pa_json_object *parameters, char **response, void *userdata) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    pa_card *c;
 | 
			
		||||
    char *message_handler_path;
 | 
			
		||||
 | 
			
		||||
    pa_assert(c = (pa_card *) userdata);
 | 
			
		||||
=======
 | 
			
		||||
    pa_card *c = userdata;
 | 
			
		||||
    char *message_handler_path;
 | 
			
		||||
 | 
			
		||||
    pa_assert(c);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    pa_assert(message);
 | 
			
		||||
    pa_assert(response);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,10 @@
 | 
			
		|||
#include <pulsecore/log.h>
 | 
			
		||||
#include <pulsecore/macro.h>
 | 
			
		||||
#include <pulsecore/strbuf.h>
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
=======
 | 
			
		||||
#include <pulsecore/namereg.h>
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
#include "core.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -87,9 +90,15 @@ static char *message_handler_list(pa_core *c) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static int core_message_handler(const char *object_path, const char *message, const pa_json_object *parameters, char **response, void *userdata) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    pa_core *c;
 | 
			
		||||
 | 
			
		||||
    pa_assert(c = (pa_core *) userdata);
 | 
			
		||||
=======
 | 
			
		||||
    pa_core *c = userdata;
 | 
			
		||||
 | 
			
		||||
    pa_assert(c);
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    pa_assert(message);
 | 
			
		||||
    pa_assert(response);
 | 
			
		||||
    pa_assert(pa_safe_streq(object_path, "/core"));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,11 @@
 | 
			
		|||
typedef struct pa_creds pa_creds;
 | 
			
		||||
typedef struct pa_cmsg_ancil_data pa_cmsg_ancil_data;
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
#if defined(SCM_CREDENTIALS) || defined(SCM_CREDS)
 | 
			
		||||
=======
 | 
			
		||||
#if (defined(SCM_CREDENTIALS) || defined(SCM_CREDS)) && !defined(OS_IS_DARWIN)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
 | 
			
		||||
#define HAVE_CREDS 1
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -261,7 +261,11 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) {
 | 
			
		|||
 | 
			
		||||
#ifdef HAVE_CREDS
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 | 
			
		||||
=======
 | 
			
		||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
typedef struct cmsgcred pa_ucred_t;
 | 
			
		||||
#define SCM_CREDENTIALS SCM_CREDS
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			@ -291,14 +295,22 @@ bool pa_iochannel_creds_supported(pa_iochannel *io) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
int pa_iochannel_creds_enable(pa_iochannel *io) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
 | 
			
		||||
=======
 | 
			
		||||
#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    int t = 1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    pa_assert(io);
 | 
			
		||||
    pa_assert(io->ifd >= 0);
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
 | 
			
		||||
=======
 | 
			
		||||
#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    if (setsockopt(io->ifd, SOL_SOCKET, SO_PASSCRED, &t, sizeof(t)) < 0) {
 | 
			
		||||
        pa_log_error("setsockopt(SOL_SOCKET, SO_PASSCRED): %s", pa_cstrerror(errno));
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -334,7 +346,11 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l
 | 
			
		|||
 | 
			
		||||
    u = (pa_ucred_t*) CMSG_DATA(&cmsg.hdr);
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 | 
			
		||||
=======
 | 
			
		||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
    // the kernel fills everything
 | 
			
		||||
#else
 | 
			
		||||
    u->pid = getpid();
 | 
			
		||||
| 
						 | 
				
			
			@ -457,7 +473,11 @@ ssize_t pa_iochannel_read_with_ancil_data(pa_iochannel*io, void*data, size_t l,
 | 
			
		|||
                pa_ucred_t u;
 | 
			
		||||
                pa_assert(cmh->cmsg_len == CMSG_LEN(sizeof(pa_ucred_t)));
 | 
			
		||||
                memcpy(&u, CMSG_DATA(cmh), sizeof(pa_ucred_t));
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 | 
			
		||||
=======
 | 
			
		||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
                ancil_data->creds.gid = u.cmcred_gid;
 | 
			
		||||
                ancil_data->creds.uid = u.cmcred_uid;
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -224,7 +224,11 @@ libpulsecore = shared_library('pulsecore-' + pa_version_major_minor,
 | 
			
		|||
  install_rpath : privlibdir,
 | 
			
		||||
  install_dir : privlibdir,
 | 
			
		||||
  link_with : libpulsecore_simd_lib,
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  dependencies : [libm_dep, libpulsecommon_dep, ltdl_dep, shm_dep, sndfile_dep, database_dep, dbus_dep, libatomic_ops_dep, orc_dep, samplerate_dep, soxr_dep, speex_dep, x11_dep, libintl_dep, platform_dep, platform_socket_dep,],
 | 
			
		||||
=======
 | 
			
		||||
  dependencies : [libm_dep, libpulsecommon_dep, ltdl_dep, shm_dep, sndfile_dep, database_dep, dbus_dep, libatomic_ops_dep, orc_dep, samplerate_dep, soxr_dep, speex_dep, x11_dep, libsystemd_dep, libintl_dep, platform_dep, tcpwrap_dep, platform_socket_dep,],
 | 
			
		||||
>>>>>>> c1990dd02647405b0c13aab59f75d05cbb202336
 | 
			
		||||
  implicit_include_directories : false)
 | 
			
		||||
 | 
			
		||||
libpulsecore_dep = declare_dependency(link_with: libpulsecore)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue