From 290d5987488564afa5c9fe11f709c78e4bf31ccc Mon Sep 17 00:00:00 2001 From: "Reynaldo H. Verdejo Pinochet" Date: Wed, 13 Apr 2011 15:05:15 -0400 Subject: [PATCH] Remove audioflingersink Remove audioflingersink, it's in gst-android now. --- Android.mk | 1 - sys/audioflingersink/Android.mk | 69 - sys/audioflingersink/GstAndroid.cpp | 36 - sys/audioflingersink/audioflinger_wrapper.cpp | 470 ----- sys/audioflingersink/audioflinger_wrapper.h | 85 - .../gstaudioflingerringbuffer.h | 90 - sys/audioflingersink/gstaudioflingersink.c | 1655 ----------------- sys/audioflingersink/gstaudioflingersink.h | 70 - 8 files changed, 2476 deletions(-) delete mode 100644 sys/audioflingersink/Android.mk delete mode 100644 sys/audioflingersink/GstAndroid.cpp delete mode 100644 sys/audioflingersink/audioflinger_wrapper.cpp delete mode 100644 sys/audioflingersink/audioflinger_wrapper.h delete mode 100644 sys/audioflingersink/gstaudioflingerringbuffer.h delete mode 100755 sys/audioflingersink/gstaudioflingersink.c delete mode 100644 sys/audioflingersink/gstaudioflingersink.h diff --git a/Android.mk b/Android.mk index c3a5ff3468..fb349cf057 100644 --- a/Android.mk +++ b/Android.mk @@ -111,7 +111,6 @@ CONFIGURE_TARGETS += gst-plugins-bad-configure -include $(GST_PLUGINS_BAD_TOP)/gst/asfmux/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/videoparsers/Android.mk -include $(GST_PLUGINS_BAD_TOP)/ext/faad/Android.mk --include $(GST_PLUGINS_BAD_TOP)/sys/audioflingersink/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/sdp/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/hls/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/jp2kdecimator/Android.mk diff --git a/sys/audioflingersink/Android.mk b/sys/audioflingersink/Android.mk deleted file mode 100644 index ebbf452090..0000000000 --- a/sys/audioflingersink/Android.mk +++ /dev/null @@ -1,69 +0,0 @@ -# external/gstreamer/gstplayer/Android.mk -# -# Copyright 2009 STN wireless -# -#ifeq ($(USE_HARDWARE_MM),true) - -LOCAL_PATH:= $(call my-dir) - -# ------------------------------------- -# gstaudioflinger library -# -include $(CLEAR_VARS) - -LOCAL_ARM_MODE := arm - -gstaudioflinger_FILES := \ - audioflinger_wrapper.cpp \ - gstaudioflingersink.c \ - GstAndroid.cpp - -LOCAL_SRC_FILES := $(gstaudioflinger_FILES) -LOCAL_C_INCLUDES = $(LOCAL_PATH) \ - $(LOCAL_PATH)/include \ - $(TOP)/frameworks/base - -LOCAL_CFLAGS += -DHAVE_CONFIG_H -LOCAL_CFLAGS += -Wall -Wdeclaration-after-statement -g -O2 -LOCAL_CFLAGS += -DANDROID_USE_GSTREAMER \ - $(shell $(PKG_CONFIG) gstreamer-plugins-bad-0.10 --cflags) \ - $(shell $(PKG_CONFIG) gstreamer-audio-0.10 --cflags) - -ifeq ($(USE_AUDIO_PURE_CODEC),true) -LOCAL_CFLAGS += -DAUDIO_PURE_CODEC -endif - -LOCAL_SHARED_LIBRARIES += libdl -LOCAL_SHARED_LIBRARIES += \ - libgstreamer-0.10 \ - libgstbase-0.10 \ - libglib-2.0 \ - libgthread-2.0 \ - libgmodule-2.0 \ - libgobject-2.0 \ - libgstvideo-0.10 \ - libgstaudio-0.10 - -LOCAL_LDFLAGS := -L$(SYSROOT)/usr/lib -llog - -LOCAL_SHARED_LIBRARIES += \ - libutils \ - libcutils \ - libui \ - libhardware \ - libandroid_runtime \ - libmedia - - -LOCAL_MODULE:= libgstaudioflinger -LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10 - -# -# define LOCAL_PRELINK_MODULE to false to not use pre-link map -# -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE_TAGS := eng debug - -include $(BUILD_SHARED_LIBRARY) - -#endif # USE_HARDWARE_MM == true diff --git a/sys/audioflingersink/GstAndroid.cpp b/sys/audioflingersink/GstAndroid.cpp deleted file mode 100644 index 275638b17c..0000000000 --- a/sys/audioflingersink/GstAndroid.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -/* Helper functions */ -#include - -/* Object header */ -#include "gstaudioflingersink.h" - -static gboolean plugin_init (GstPlugin * plugin) -{ - gboolean ret = TRUE; - - ret &= gst_audioflinger_sink_plugin_init (plugin); - - return ret; -} - -/* Version number of package */ -#define VERSION "0.0.1" -/* package name */ -#define PACKAGE "Android ST-ERICSSON" - - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "audioflinger", - "Android audioflinger library for gstreamer", - plugin_init, VERSION, "LGPL", "libgstaudioflinger.so", "http://www.stericsson.com") - diff --git a/sys/audioflingersink/audioflinger_wrapper.cpp b/sys/audioflingersink/audioflinger_wrapper.cpp deleted file mode 100644 index 64ad7faf0f..0000000000 --- a/sys/audioflingersink/audioflinger_wrapper.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/* GStreamer - * Copyright (C) <2009> Prajnashi S - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#define ENABLE_GST_PLAYER_LOG -#include -#include -#include -#include -#include -#include "audioflinger_wrapper.h" -#include -//#include - - -#define LOG_NDEBUG 0 - -#undef LOG_TAG -#define LOG_TAG "audioflinger_wrapper" - - -using namespace android; - - -typedef struct _AudioFlingerDevice -{ - AudioTrack* audio_track; - bool init; - sp audio_sink; - bool audio_sink_specified; -} AudioFlingerDevice; - - -/* commonly used macro */ -#define AUDIO_FLINGER_DEVICE(handle) ((AudioFlingerDevice*)handle) -#define AUDIO_FLINGER_DEVICE_TRACK(handle) \ - (AUDIO_FLINGER_DEVICE(handle)->audio_track) -#define AUDIO_FLINGER_DEVICE_SINK(handle) \ - (AUDIO_FLINGER_DEVICE(handle)->audio_sink) - - -AudioFlingerDeviceHandle audioflinger_device_create() -{ - AudioFlingerDevice* audiodev = NULL; - AudioTrack *audiotr = NULL; - - // create a new instance of AudioFlinger - audiodev = new AudioFlingerDevice; - if (audiodev == NULL) { - LOGE("Error to create AudioFlingerDevice\n"); - return NULL; - } - - // create AudioTrack - audiotr = new AudioTrack (); - if (audiotr == NULL) { - LOGE("Error to create AudioTrack\n"); - return NULL; - } - - audiodev->init = false; - audiodev->audio_track = (AudioTrack *) audiotr; - audiodev->audio_sink = 0; - audiodev->audio_sink_specified = false; - LOGD("Create AudioTrack successfully %p\n",audiodev); - - return (AudioFlingerDeviceHandle)audiodev; -} - -AudioFlingerDeviceHandle audioflinger_device_open(void* audio_sink) -{ - AudioFlingerDevice* audiodev = NULL; - - // audio_sink shall be an MediaPlayerBase::AudioSink instance - if(audio_sink == NULL) - return NULL; - - // create a new instance of AudioFlinger - audiodev = new AudioFlingerDevice; - if (audiodev == NULL) { - LOGE("Error to create AudioFlingerDevice\n"); - return NULL; - } - - // set AudioSink - - audiodev->audio_sink = (MediaPlayerBase::AudioSink*)audio_sink; - audiodev->audio_track = NULL; - audiodev->init = false; - audiodev->audio_sink_specified = true; - LOGD("Open AudioSink successfully : %p\n",audiodev); - - return (AudioFlingerDeviceHandle)audiodev; -} - -int audioflinger_device_set (AudioFlingerDeviceHandle handle, - int streamType, int channelCount, uint32_t sampleRate, int bufferCount) -{ - status_t status = NO_ERROR; -#ifndef STECONF_ANDROID_VERSION_DONUT - uint32_t channels = 0; -#endif - - int format = AudioSystem::PCM_16_BIT; - - if (handle == NULL) - return -1; - - if(AUDIO_FLINGER_DEVICE_TRACK(handle)) { - // bufferCount is not the number of internal buffer, but the internal - // buffer size -#ifdef STECONF_ANDROID_VERSION_DONUT - status = AUDIO_FLINGER_DEVICE_TRACK(handle)->set(streamType, sampleRate, - format, channelCount); - LOGD("SET : handle : %p : Set AudioTrack, status: %d, streamType: %d, sampleRate: %d, " - "channelCount: %d, bufferCount: %d\n",handle, status, streamType, sampleRate, - channelCount, bufferCount); -#else - switch (channelCount) - { - case 1: - channels = AudioSystem::CHANNEL_OUT_FRONT_LEFT; - break; - case 2: - channels = AudioSystem::CHANNEL_OUT_STEREO; - break; - case 0: - default: - channels = 0; - break; - } - status = AUDIO_FLINGER_DEVICE_TRACK(handle)->set(streamType, sampleRate, - format, channels/*, bufferCount*/); - LOGD("SET handle : %p : Set AudioTrack, status: %d, streamType: %d, sampleRate: %d, " - "channelCount: %d(%d), bufferCount: %d\n",handle, status, streamType, sampleRate, - channelCount, channels, bufferCount); -#endif - AUDIO_FLINGER_DEVICE_TRACK(handle)->setPositionUpdatePeriod(bufferCount); - - } - else if(AUDIO_FLINGER_DEVICE_SINK(handle).get()) { -#ifdef STECONF_ANDROID_VERSION_DONUT - status = AUDIO_FLINGER_DEVICE_SINK(handle)->open(sampleRate, channelCount, - format/*, bufferCount*/); //SDA - - LOGD("OPEN : handle : %p : Set AudioSink, status: %d, streamType: %d, sampleRate: %d," - "channelCount: %d, bufferCount: %d\n", handle, status, streamType, sampleRate, - channelCount, bufferCount); -#else - channels = channelCount; - status = AUDIO_FLINGER_DEVICE_SINK(handle)->open(sampleRate, channels, - format/*, bufferCount*/); - LOGD("OPEN handle : %p : Set AudioSink, status: %d, streamType: %d, sampleRate: %d," - "channelCount: %d(%d), bufferCount: %d\n", handle, status, streamType, sampleRate, - channelCount, channels, bufferCount); -#endif - AUDIO_FLINGER_DEVICE_TRACK(handle) = (AudioTrack *)(AUDIO_FLINGER_DEVICE_SINK(handle)->getTrack()); - if(AUDIO_FLINGER_DEVICE_TRACK(handle)) { - AUDIO_FLINGER_DEVICE_TRACK(handle)->setPositionUpdatePeriod(bufferCount); - } - } - - if (status != NO_ERROR) - return -1; - - AUDIO_FLINGER_DEVICE(handle)->init = true; - - return 0; -} - -void audioflinger_device_release (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL) - return; - - LOGD("Enter\n"); - if(! AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified ) { - if (AUDIO_FLINGER_DEVICE_TRACK(handle) ) { - LOGD("handle : %p Release AudioTrack\n", handle); - delete AUDIO_FLINGER_DEVICE_TRACK(handle); - } - } - if (AUDIO_FLINGER_DEVICE_SINK(handle).get()) { - LOGD("handle : %p Release AudioSink\n", handle); - AUDIO_FLINGER_DEVICE_SINK(handle).clear(); - AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified = false; - } - - delete AUDIO_FLINGER_DEVICE(handle); -} - - -void audioflinger_device_start (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return; - - LOGD("handle : %p Start Device\n", handle); - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - AUDIO_FLINGER_DEVICE_SINK(handle)->start(); - } - else { - AUDIO_FLINGER_DEVICE_TRACK(handle)->start(); - } -} - -void audioflinger_device_stop (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return; - - LOGD("handle : %p Stop Device\n", handle); - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - AUDIO_FLINGER_DEVICE_SINK(handle)->stop(); - } - else { - AUDIO_FLINGER_DEVICE_TRACK(handle)->stop(); - } - -} - -void audioflinger_device_flush (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return; - - LOGD("handle : %p Flush device\n", handle); - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - AUDIO_FLINGER_DEVICE_SINK(handle)->flush(); - } - else { - AUDIO_FLINGER_DEVICE_TRACK(handle)->flush(); - } -} - -void audioflinger_device_pause (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return; - - LOGD("handle : %p Pause Device\n", handle); - - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - AUDIO_FLINGER_DEVICE_SINK(handle)->pause(); - } - else { - AUDIO_FLINGER_DEVICE_TRACK(handle)->pause(); - } - -} - -void audioflinger_device_mute (AudioFlingerDeviceHandle handle, int mute) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return; - - LOGD("handle : %p Mute Device\n", handle); - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - // do nothing here, because the volume/mute is set in media service layer - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - AUDIO_FLINGER_DEVICE_TRACK(handle)->mute((bool)mute); - } -} - -int audioflinger_device_muted (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return -1; - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - // do nothing here, because the volume/mute is set in media service layer - return -1; - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - return (int) AUDIO_FLINGER_DEVICE_TRACK(handle)->muted (); - } - return -1; -} - - -void audioflinger_device_set_volume (AudioFlingerDeviceHandle handle, float left, - float right) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return; - - LOGD("handle : %p Set volume Device %f,%f\n", handle,left,right); - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - // do nothing here, because the volume/mute is set in media service layer - return ; - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - AUDIO_FLINGER_DEVICE_TRACK(handle)->setVolume (left, right); - } -} - -ssize_t audioflinger_device_write (AudioFlingerDeviceHandle handle, const void *buffer, - size_t size) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return -1; - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - return AUDIO_FLINGER_DEVICE_SINK(handle)->write(buffer, size); - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - return AUDIO_FLINGER_DEVICE_TRACK(handle)->write(buffer, size); - } -#ifndef STECONF_ANDROID_VERSION_DONUT - return -1; -#endif -} - -int audioflinger_device_frameCount (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return -1; - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - return (int)AUDIO_FLINGER_DEVICE_SINK(handle)->frameCount(); - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - return (int)AUDIO_FLINGER_DEVICE_TRACK(handle)->frameCount(); - } - return -1; -} - -int audioflinger_device_frameSize (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return -1; - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - return (int)AUDIO_FLINGER_DEVICE_SINK(handle)->frameSize(); - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - return (int)AUDIO_FLINGER_DEVICE_TRACK(handle)->frameSize(); - } -#ifndef STECONF_ANDROID_VERSION_DONUT - return -1; -#endif -} - -int64_t audioflinger_device_latency (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return -1; - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - return (int64_t)AUDIO_FLINGER_DEVICE_SINK(handle)->latency(); - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - return (int64_t)AUDIO_FLINGER_DEVICE_TRACK(handle)->latency(); - } - return -1; -} - -int audioflinger_device_format (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return -1; - - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - // do nothing here, MediaPlayerBase::AudioSink doesn't provide format() - // interface - return -1; - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - return (int)AUDIO_FLINGER_DEVICE_TRACK(handle)->format(); - } - return -1; -} - -int audioflinger_device_channelCount (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return -1; - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - return (int)AUDIO_FLINGER_DEVICE_SINK(handle)->channelCount(); - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - return (int)AUDIO_FLINGER_DEVICE_TRACK(handle)->channelCount(); - } - return -1; -} - -uint32_t audioflinger_device_sampleRate (AudioFlingerDeviceHandle handle) -{ - if (handle == NULL || AUDIO_FLINGER_DEVICE(handle)->init == false) - return 0; - if(AUDIO_FLINGER_DEVICE(handle)->audio_sink_specified) { - // do nothing here, MediaPlayerBase::AudioSink doesn't provide sampleRate() - // interface - return -1; - } - else if (AUDIO_FLINGER_DEVICE_TRACK(handle)) { - return (int)AUDIO_FLINGER_DEVICE_TRACK(handle)->getSampleRate(); -} - return(-1); -} - -int audioflinger_device_obtain_buffer (AudioFlingerDeviceHandle handle, - void **buffer_handle, int8_t **data, size_t *samples, uint64_t offset) -{ - AudioTrack *track = AUDIO_FLINGER_DEVICE_TRACK (handle); - status_t res; - AudioTrack::Buffer *audioBuffer; - - if(track == 0) return(-1); - audioBuffer = new AudioTrack::Buffer(); - audioBuffer->frameCount = *samples; - res = track->obtainBufferAtOffset (audioBuffer, offset, -1); - if (res < 0) { - delete audioBuffer; - - return (int) res; - } - - *samples = audioBuffer->frameCount; - *buffer_handle = static_cast (audioBuffer); - *data = audioBuffer->i8; - - return res; -} - -void audioflinger_device_release_buffer (AudioFlingerDeviceHandle handle, - void *buffer_handle) -{ - AudioTrack *track = AUDIO_FLINGER_DEVICE_TRACK (handle); - AudioTrack::Buffer *audioBuffer = static_cast(buffer_handle); - - if(track == 0) return; - - track->releaseBuffer (audioBuffer); - delete audioBuffer; -} - -uint32_t audioflinger_device_get_position (AudioFlingerDeviceHandle handle) -{ - status_t status; - uint32_t ret = -1; - AudioTrack *track = AUDIO_FLINGER_DEVICE_TRACK (handle); - - if(track == 0) return(-1); - - status = track->getPosition (&ret); - - return ret; -} diff --git a/sys/audioflingersink/audioflinger_wrapper.h b/sys/audioflingersink/audioflinger_wrapper.h deleted file mode 100644 index 07e7693312..0000000000 --- a/sys/audioflingersink/audioflinger_wrapper.h +++ /dev/null @@ -1,85 +0,0 @@ -/* GStreamer - * Copyright (C) <2009> Prajnashi S - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * This file defines APIs to convert C++ AudioFlinder/AudioTrack - * interface to C interface - */ -#ifndef __AUDIOFLINGER_WRAPPER_H__ -#define __AUDIOFLINGER_WRAPPER_H__ - -#define LATE 0x80000002 - -#ifdef __cplusplus -extern "C" { -#endif -typedef void* AudioFlingerDeviceHandle; - -AudioFlingerDeviceHandle audioflinger_device_create(); - -AudioFlingerDeviceHandle audioflinger_device_open(void* audio_sink); - -int audioflinger_device_set (AudioFlingerDeviceHandle handle, - int streamType, int channelCount, uint32_t sampleRate, int bufferCount); - -void audioflinger_device_release(AudioFlingerDeviceHandle handle); - -void audioflinger_device_start(AudioFlingerDeviceHandle handle); - -void audioflinger_device_stop(AudioFlingerDeviceHandle handle); - -ssize_t audioflinger_device_write(AudioFlingerDeviceHandle handle, - const void* buffer, size_t size); - -void audioflinger_device_flush(AudioFlingerDeviceHandle handle); - -void audioflinger_device_pause(AudioFlingerDeviceHandle handle); - -void audioflinger_device_mute(AudioFlingerDeviceHandle handle, int mute); - -int audioflinger_device_muted(AudioFlingerDeviceHandle handle); - -void audioflinger_device_set_volume(AudioFlingerDeviceHandle handle, - float left, float right); - -int audioflinger_device_frameCount(AudioFlingerDeviceHandle handle); - -int audioflinger_device_frameSize(AudioFlingerDeviceHandle handle); - -int64_t audioflinger_device_latency(AudioFlingerDeviceHandle handle); - -int audioflinger_device_format(AudioFlingerDeviceHandle handle); - -int audioflinger_device_channelCount(AudioFlingerDeviceHandle handle); - -uint32_t audioflinger_device_sampleRate(AudioFlingerDeviceHandle handle); - -int audioflinger_device_obtain_buffer (AudioFlingerDeviceHandle handle, - void **buffer_handle, int8_t **data, size_t *samples, uint64_t offset); -void audioflinger_device_release_buffer (AudioFlingerDeviceHandle handle, - void *buffer_handle); - -uint32_t audioflinger_device_get_position (AudioFlingerDeviceHandle handle); - - -#ifdef __cplusplus -} -#endif - -#endif /* __AUDIOFLINGER_WRAPPER_H__ */ diff --git a/sys/audioflingersink/gstaudioflingerringbuffer.h b/sys/audioflingersink/gstaudioflingerringbuffer.h deleted file mode 100644 index 8ccd7bbdba..0000000000 --- a/sys/audioflingersink/gstaudioflingerringbuffer.h +++ /dev/null @@ -1,90 +0,0 @@ -/* GStreamer - * Copyright (C) 2010 Alessandro Decina - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef GST_AUDIO_FLINGER_RING_BUFFER_H -#define GST_AUDIO_FLINGER_RING_BUFFER_H - -#include - -#include "gstaudiosink.h" - -GST_DEBUG_CATEGORY_STATIC (gst_audio_sink_debug); -#define GST_CAT_DEFAULT gst_audio_sink_debug - -#define GST_TYPE_AUDIORING_BUFFER \ - (gst_audioringbuffer_get_type()) -#define GST_AUDIORING_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIORING_BUFFER,GstAudioRingBuffer)) -#define GST_AUDIORING_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIORING_BUFFER,GstAudioRingBufferClass)) -#define GST_AUDIORING_BUFFER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_AUDIORING_BUFFER, GstAudioRingBufferClass)) -#define GST_AUDIORING_BUFFER_CAST(obj) \ - ((GstAudioRingBuffer *)obj) -#define GST_IS_AUDIORING_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIORING_BUFFER)) -#define GST_IS_AUDIORING_BUFFER_CLASS(klass)\ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIORING_BUFFER)) - -typedef struct _GstAudioRingBuffer GstAudioRingBuffer; -typedef struct _GstAudioRingBufferClass GstAudioRingBufferClass; - -#define GST_AUDIORING_BUFFER_GET_COND(buf) (((GstAudioRingBuffer *)buf)->cond) -#define GST_AUDIORING_BUFFER_WAIT(buf) (g_cond_wait (GST_AUDIORING_BUFFER_GET_COND (buf), GST_OBJECT_GET_LOCK (buf))) -#define GST_AUDIORING_BUFFER_SIGNAL(buf) (g_cond_signal (GST_AUDIORING_BUFFER_GET_COND (buf))) -#define GST_AUDIORING_BUFFER_BROADCAST(buf)(g_cond_broadcast (GST_AUDIORING_BUFFER_GET_COND (buf))) - -struct _GstAudioRingBuffer -{ - GstRingBuffer object; - - gboolean running; - gint queuedseg; - - GCond *cond; -}; - -struct _GstAudioRingBufferClass -{ - GstRingBufferClass parent_class; -}; - -static void gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass); -static void gst_audioringbuffer_init (GstAudioRingBuffer * ringbuffer, - GstAudioRingBufferClass * klass); -static void gst_audioringbuffer_dispose (GObject * object); -static void gst_audioringbuffer_finalize (GObject * object); - -static GstRingBufferClass *ring_parent_class = NULL; - -static gboolean gst_audioringbuffer_open_device (GstRingBuffer * buf); -static gboolean gst_audioringbuffer_close_device (GstRingBuffer * buf); -static gboolean gst_audioringbuffer_acquire (GstRingBuffer * buf, - GstRingBufferSpec * spec); -static gboolean gst_audioringbuffer_release (GstRingBuffer * buf); -static gboolean gst_audioringbuffer_start (GstRingBuffer * buf); -static gboolean gst_audioringbuffer_pause (GstRingBuffer * buf); -static gboolean gst_audioringbuffer_stop (GstRingBuffer * buf); -static guint gst_audioringbuffer_delay (GstRingBuffer * buf); -static gboolean gst_audioringbuffer_activate (GstRingBuffer * buf, - gboolean active); - -GType gst_audioringbuffer_get_type (void); - -#endif /* GST_AUDIO_FLINGER_RING_BUFFER_H */ diff --git a/sys/audioflingersink/gstaudioflingersink.c b/sys/audioflingersink/gstaudioflingersink.c deleted file mode 100755 index df1256ceb5..0000000000 --- a/sys/audioflingersink/gstaudioflingersink.c +++ /dev/null @@ -1,1655 +0,0 @@ -/* GStreamer - * Copyright (C) <2009> Prajnashi S - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-audioflindersink - * - * This element lets you output sound using the Audio Flinger system in Android - * - * Note that you should almost always use generic audio conversion elements - * like audioconvert and audioresample in front of an audiosink to make sure - * your pipeline works under all circumstances (those conversion elements will - * act in passthrough-mode if no conversion is necessary). - */ - -#ifdef HAVE_CONFIG_H -//#include "config.h" -#endif -#include "gstaudioflingersink.h" -#include - - - -#define LOG_NDEBUG 0 - -#undef LOG_TAG -#define LOG_TAG "GstAudioFlingerSink" - - -#define DEFAULT_BUFFERTIME (500*GST_MSECOND) / (GST_USECOND) -#define DEFAULT_LATENCYTIME (50*GST_MSECOND) / (GST_USECOND) -#define DEFAULT_VOLUME 10.0 -#define DEFAULT_MUTE FALSE -#define DEFAULT_EXPORT_SYSTEM_AUDIO_CLOCK TRUE - -/* - * PROPERTY_ID - */ -enum -{ - PROP_NULL, - PROP_VOLUME, - PROP_MUTE, - PROP_AUDIO_SINK, -}; - -GST_DEBUG_CATEGORY_STATIC (audioflinger_debug); -#define GST_CAT_DEFAULT audioflinger_debug - -/* elementfactory information */ -static const GstElementDetails gst_audioflinger_sink_details = -GST_ELEMENT_DETAILS ("Audio Sink (AudioFlinger)", - "Sink/Audio", - "Output to android's AudioFlinger", - "Prajnashi S , " - "Alessandro Decina "); - -#define GST_TYPE_ANDROID_AUDIORING_BUFFER \ - (gst_android_audioringbuffer_get_type()) -#define GST_ANDROID_AUDIORING_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ANDROID_AUDIORING_BUFFER,GstAndroidAudioRingBuffer)) -#define GST_ANDROID_AUDIORING_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ANDROID_AUDIORING_BUFFER,GstAndroidAudioRingBufferClass)) -#define GST_ANDROID_AUDIORING_BUFFER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ANDROID_AUDIORING_BUFFER, GstAndroidAudioRingBufferClass)) -#define GST_ANDROID_AUDIORING_BUFFER_CAST(obj) \ - ((GstAndroidAudioRingBuffer *)obj) -#define GST_IS_ANDROID_AUDIORING_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ANDROID_AUDIORING_BUFFER)) -#define GST_IS_ANDROID_AUDIORING_BUFFER_CLASS(klass)\ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ANDROID_AUDIORING_BUFFER)) - -typedef struct _GstAndroidAudioRingBuffer GstAndroidAudioRingBuffer; -typedef struct _GstAndroidAudioRingBufferClass GstAndroidAudioRingBufferClass; - -#define GST_ANDROID_AUDIORING_BUFFER_GET_COND(buf) (((GstAndroidAudioRingBuffer *)buf)->cond) -#define GST_ANDROID_AUDIORING_BUFFER_WAIT(buf) (g_cond_wait (GST_ANDROID_ANDROID_AUDIORING_BUFFER_GET_COND (buf), GST_OBJECT_GET_LOCK (buf))) -#define GST_ANDROID_AUDIORING_BUFFER_SIGNAL(buf) (g_cond_signal (GST_ANDROID_ANDROID_AUDIORING_BUFFER_GET_COND (buf))) -#define GST_ANDROID_AUDIORING_BUFFER_BROADCAST(buf)(g_cond_broadcast (GST_ANDROID_ANDROID_AUDIORING_BUFFER_GET_COND (buf))) - -struct _GstAndroidAudioRingBuffer -{ - GstRingBuffer object; - - gboolean running; - gint queuedseg; - - GCond *cond; -}; - -struct _GstAndroidAudioRingBufferClass -{ - GstRingBufferClass parent_class; -}; - -static void -gst_android_audioringbuffer_class_init (GstAndroidAudioRingBufferClass * klass); -static void gst_android_audioringbuffer_init (GstAndroidAudioRingBuffer * - ringbuffer, GstAndroidAudioRingBufferClass * klass); -static void gst_android_audioringbuffer_dispose (GObject * object); -static void gst_android_audioringbuffer_finalize (GObject * object); - -static GstRingBufferClass *ring_parent_class = NULL; - -static gboolean gst_android_audioringbuffer_open_device (GstRingBuffer * buf); -static gboolean gst_android_audioringbuffer_close_device (GstRingBuffer * buf); -static gboolean gst_android_audioringbuffer_acquire (GstRingBuffer * buf, - GstRingBufferSpec * spec); -static gboolean gst_android_audioringbuffer_release (GstRingBuffer * buf); -static gboolean gst_android_audioringbuffer_start (GstRingBuffer * buf); -static gboolean gst_android_audioringbuffer_pause (GstRingBuffer * buf); -static gboolean gst_android_audioringbuffer_stop (GstRingBuffer * buf); -static gboolean gst_android_audioringbuffer_activate (GstRingBuffer * buf, - gboolean active); -static void gst_android_audioringbuffer_clear (GstRingBuffer * buf); -static guint gst_android_audioringbuffer_commit (GstRingBuffer * buf, - guint64 * sample, guchar * data, gint in_samples, gint out_samples, - gint * accum); - -static void gst_audioflinger_sink_base_init (gpointer g_class); -static void gst_audioflinger_sink_class_init (GstAudioFlingerSinkClass * klass); -static void gst_audioflinger_sink_init (GstAudioFlingerSink * - audioflinger_sink); - -static void gst_audioflinger_sink_dispose (GObject * object); -static void gst_audioflinger_sink_finalise (GObject * object); - -static void gst_audioflinger_sink_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); -static void gst_audioflinger_sink_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static GstCaps *gst_audioflinger_sink_getcaps (GstBaseSink * bsink); - -static gboolean gst_audioflinger_sink_open (GstAudioFlingerSink * asink); -static gboolean gst_audioflinger_sink_close (GstAudioFlingerSink * asink); -static gboolean gst_audioflinger_sink_prepare (GstAudioFlingerSink * asink, - GstRingBufferSpec * spec); -static gboolean gst_audioflinger_sink_unprepare (GstAudioFlingerSink * asink); -static void gst_audioflinger_sink_reset (GstAudioFlingerSink * asink, - gboolean create_clock); -static void gst_audioflinger_sink_set_mute (GstAudioFlingerSink * - audioflinger_sink, gboolean mute); -static void gst_audioflinger_sink_set_volume (GstAudioFlingerSink * - audioflinger_sink, float volume); -static gboolean gst_audioflinger_sink_event (GstBaseSink * bsink, - GstEvent * event); -static GstRingBuffer *gst_audioflinger_sink_create_ringbuffer (GstBaseAudioSink - * sink); -static GstClockTime gst_audioflinger_sink_get_time (GstClock * clock, - gpointer user_data); -static GstFlowReturn gst_audioflinger_sink_preroll (GstBaseSink * bsink, - GstBuffer * buffer); -static GstClockTime gst_audioflinger_sink_system_audio_clock_get_time (GstClock - * clock, gpointer user_data); -static GstClock *gst_audioflinger_sink_provide_clock (GstElement * elem); -static GstStateChangeReturn gst_audioflinger_sink_change_state (GstElement * - element, GstStateChange transition); - -static GstStaticPadTemplate audioflingersink_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " - "endianness = (int) { " G_STRINGIFY (G_BYTE_ORDER) " }, " - "signed = (boolean) { TRUE }, " - "width = (int) 16, " - "depth = (int) 16, " - "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; ") - ); - -static GType -gst_android_audioringbuffer_get_type (void) -{ - static GType ringbuffer_type = 0; - - if (!ringbuffer_type) { - static const GTypeInfo ringbuffer_info = { - sizeof (GstAndroidAudioRingBufferClass), - NULL, - NULL, - (GClassInitFunc) gst_android_audioringbuffer_class_init, - NULL, - NULL, - sizeof (GstAndroidAudioRingBuffer), - 0, - (GInstanceInitFunc) gst_android_audioringbuffer_init, - NULL - }; - - ringbuffer_type = - g_type_register_static (GST_TYPE_RING_BUFFER, - "GstAndroidAudioSinkRingBuffer", &ringbuffer_info, 0); - } - return ringbuffer_type; -} - -static void -gst_android_audioringbuffer_class_init (GstAndroidAudioRingBufferClass * klass) -{ - GObjectClass *gobject_class; - GstRingBufferClass *gstringbuffer_class; - - gobject_class = G_OBJECT_CLASS (klass); - gstringbuffer_class = GST_RING_BUFFER_CLASS (klass); - - ring_parent_class = g_type_class_peek_parent (klass); - - gobject_class->dispose = gst_android_audioringbuffer_dispose; - gobject_class->finalize = gst_android_audioringbuffer_finalize; - - gstringbuffer_class->open_device = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_open_device); - gstringbuffer_class->close_device = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_close_device); - gstringbuffer_class->acquire = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_acquire); - gstringbuffer_class->release = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_release); - gstringbuffer_class->start = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_start); - gstringbuffer_class->pause = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_pause); - gstringbuffer_class->resume = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_start); - gstringbuffer_class->stop = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_stop); - gstringbuffer_class->clear_all = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_clear); - gstringbuffer_class->commit = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_commit); - -#if 0 - gstringbuffer_class->delay = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_delay); -#endif - gstringbuffer_class->activate = - GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_activate); -} - -static void -gst_android_audioringbuffer_init (G_GNUC_UNUSED GstAndroidAudioRingBuffer * - ringbuffer, G_GNUC_UNUSED GstAndroidAudioRingBufferClass * g_class) -{ -} - -static void -gst_android_audioringbuffer_dispose (GObject * object) -{ - G_OBJECT_CLASS (ring_parent_class)->dispose (object); -} - -static void -gst_android_audioringbuffer_finalize (GObject * object) -{ - G_OBJECT_CLASS (ring_parent_class)->finalize (object); -} - -static gboolean -gst_android_audioringbuffer_open_device (GstRingBuffer * buf) -{ - GstAudioFlingerSink *sink; - gboolean result = TRUE; - LOGD (">gst_android_audioringbuffer_open_device"); - sink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (buf)); - result = gst_audioflinger_sink_open (sink); - - if (!result) - goto could_not_open; - - return result; - -could_not_open: - { - GST_DEBUG_OBJECT (sink, "could not open device"); - LOGE ("could not open device"); - return FALSE; - } -} - -static gboolean -gst_android_audioringbuffer_close_device (GstRingBuffer * buf) -{ - GstAudioFlingerSink *sink; - gboolean result = TRUE; - - LOGD (">gst_android_audioringbuffer_close_device"); - - sink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (buf)); - - result = gst_audioflinger_sink_close (sink); - - if (!result) - goto could_not_close; - - return result; - -could_not_close: - { - GST_DEBUG_OBJECT (sink, "could not close device"); - LOGE ("could not close device"); - return FALSE; - } -} - -static gboolean -gst_android_audioringbuffer_acquire (GstRingBuffer * buf, - GstRingBufferSpec * spec) -{ - GstAudioFlingerSink *sink; - gboolean result = FALSE; - - LOGD (">gst_android_audioringbuffer_acquire"); - - sink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (buf)); - - result = gst_audioflinger_sink_prepare (sink, spec); - - if (!result) - goto could_not_prepare; - - return TRUE; - - /* ERRORS */ -could_not_prepare: - { - GST_DEBUG_OBJECT (sink, "could not prepare device"); - LOGE ("could not close device"); - return FALSE; - } -} - -static gboolean -gst_android_audioringbuffer_activate (G_GNUC_UNUSED GstRingBuffer * buf, - G_GNUC_UNUSED gboolean active) -{ - return TRUE; -} - -/* function is called with LOCK */ -static gboolean -gst_android_audioringbuffer_release (GstRingBuffer * buf) -{ - GstAudioFlingerSink *sink; - gboolean result = FALSE; - LOGD (">gst_android_audioringbuffer_release"); - - sink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (buf)); - - result = gst_audioflinger_sink_unprepare (sink); - - if (!result) - goto could_not_unprepare; - - GST_DEBUG_OBJECT (sink, "unprepared"); - LOGD ("unprepared"); - - return result; - -could_not_unprepare: - { - GST_DEBUG_OBJECT (sink, "could not unprepare device"); - LOGE ("could not unprepare device"); - return FALSE; - } -} - -static gboolean -gst_android_audioringbuffer_start (GstRingBuffer * buf) -{ - GstAudioFlingerSink *asink; - GstAndroidAudioRingBuffer *abuf; - - abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf); - asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf)); - - GST_INFO_OBJECT (buf, "starting ringbuffer"); - LOGD ("starting ringbuffer"); - - audioflinger_device_start (asink->audioflinger_device); - - return TRUE; -} - -static gboolean -gst_android_audioringbuffer_pause (GstRingBuffer * buf) -{ - GstAudioFlingerSink *asink; - GstAndroidAudioRingBuffer *abuf; - - abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf); - asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf)); - - GST_INFO_OBJECT (buf, "pausing ringbuffer"); - LOGD ("pausing ringbuffer"); - - audioflinger_device_pause (asink->audioflinger_device); - - return TRUE; -} - -static gboolean -gst_android_audioringbuffer_stop (GstRingBuffer * buf) -{ - GstAudioFlingerSink *asink; - GstAndroidAudioRingBuffer *abuf; - - abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf); - asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf)); - - GST_INFO_OBJECT (buf, "stopping ringbuffer"); - LOGD ("stopping ringbuffer"); - - audioflinger_device_stop (asink->audioflinger_device); - - return TRUE; -} - -#if 0 -static guint -gst_android_audioringbuffer_delay (GstRingBuffer * buf) -{ - return 0; -} -#endif - -static void -gst_android_audioringbuffer_clear (GstRingBuffer * buf) -{ - GstAudioFlingerSink *asink; - GstAndroidAudioRingBuffer *abuf; - - abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf); - asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf)); - - GST_INFO_OBJECT (buf, "clearing ringbuffer"); - LOGD ("clearing ringbuffer"); - - if (asink->audioflinger_device == NULL) - return; - - GST_INFO_OBJECT (asink, "resetting clock"); - gst_audio_clock_reset (GST_AUDIO_CLOCK (asink->audio_clock), 0); - - audioflinger_device_flush (asink->audioflinger_device); -} - -#define FWD_SAMPLES(s,se,d,de) \ -G_STMT_START { \ - /* no rate conversion */ \ - guint towrite = MIN (se + bps - s, de - d); \ - /* simple copy */ \ - if (!skip) \ - memcpy (d, s, towrite); \ - in_samples -= towrite / bps; \ - out_samples -= towrite / bps; \ - s += towrite; \ - GST_LOG ("copy %u bytes", towrite); \ -} G_STMT_END - -/* in_samples >= out_samples, rate > 1.0 */ -#define FWD_UP_SAMPLES(s,se,d,de) \ -G_STMT_START { \ - guint8 *sb = s, *db = d; \ - while (s <= se && d < de) { \ - if (!skip) \ - memcpy (d, s, bps); \ - s += bps; \ - *accum += outr; \ - if ((*accum << 1) >= inr) { \ - *accum -= inr; \ - d += bps; \ - } \ - } \ - in_samples -= (s - sb)/bps; \ - out_samples -= (d - db)/bps; \ - GST_DEBUG ("fwd_up end %d/%d",*accum,*toprocess); \ -} G_STMT_END - -/* out_samples > in_samples, for rates smaller than 1.0 */ -#define FWD_DOWN_SAMPLES(s,se,d,de) \ -G_STMT_START { \ - guint8 *sb = s, *db = d; \ - while (s <= se && d < de) { \ - if (!skip) \ - memcpy (d, s, bps); \ - d += bps; \ - *accum += inr; \ - if ((*accum << 1) >= outr) { \ - *accum -= outr; \ - s += bps; \ - } \ - } \ - in_samples -= (s - sb)/bps; \ - out_samples -= (d - db)/bps; \ - GST_DEBUG ("fwd_down end %d/%d",*accum,*toprocess); \ -} G_STMT_END - -#define REV_UP_SAMPLES(s,se,d,de) \ -G_STMT_START { \ - guint8 *sb = se, *db = d; \ - while (s <= se && d < de) { \ - if (!skip) \ - memcpy (d, se, bps); \ - se -= bps; \ - *accum += outr; \ - while (d < de && (*accum << 1) >= inr) { \ - *accum -= inr; \ - d += bps; \ - } \ - } \ - in_samples -= (sb - se)/bps; \ - out_samples -= (d - db)/bps; \ - GST_DEBUG ("rev_up end %d/%d",*accum,*toprocess); \ -} G_STMT_END - -#define REV_DOWN_SAMPLES(s,se,d,de) \ -G_STMT_START { \ - guint8 *sb = se, *db = d; \ - while (s <= se && d < de) { \ - if (!skip) \ - memcpy (d, se, bps); \ - d += bps; \ - *accum += inr; \ - while (s <= se && (*accum << 1) >= outr) { \ - *accum -= outr; \ - se -= bps; \ - } \ - } \ - in_samples -= (sb - se)/bps; \ - out_samples -= (d - db)/bps; \ - GST_DEBUG ("rev_down end %d/%d",*accum,*toprocess); \ -} G_STMT_END - -static guint -gst_android_audioringbuffer_commit (GstRingBuffer * buf, guint64 * sample, - guchar * data, gint in_samples, gint out_samples, gint * accum) -{ - GstBaseAudioSink *baseaudiosink; - GstAudioFlingerSink *asink; - GstAndroidAudioRingBuffer *abuf; - guint result; - guint8 *data_end; - gboolean reverse; - gint *toprocess; - gint inr, outr, bps; - guint bufsize; - gboolean skip = FALSE; - guint32 position; - gboolean slaved; - guint64 corrected_sample; - gboolean sync; - - abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf); - asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf)); - baseaudiosink = GST_BASE_AUDIO_SINK (asink); - sync = gst_base_sink_get_sync (GST_BASE_SINK_CAST (asink)); - - GST_LOG_OBJECT (asink, "entering commit"); - - /* make sure the ringbuffer is started */ - if (G_UNLIKELY (g_atomic_int_get (&buf->state) != - GST_RING_BUFFER_STATE_STARTED)) { - /* see if we are allowed to start it */ - if (G_UNLIKELY (g_atomic_int_get (&buf->abidata.ABI.may_start) == FALSE)) - goto no_start; - - GST_LOG_OBJECT (buf, "start!"); - LOGD ("start!"); - if (!gst_ring_buffer_start (buf)) - goto start_failed; - } - - slaved = GST_ELEMENT_CLOCK (baseaudiosink) != asink->exported_clock; - if (asink->last_resync_sample == -1 || - (gint64) baseaudiosink->next_sample == -1) { - if (slaved) { - /* we're writing a discont buffer. Disable slaving for a while in order to - * fill the initial buffer needed by the audio mixer thread. This avoids - * some cases where audioflinger removes us from the list of active tracks - * because we aren't writing enough data. - */ - GST_INFO_OBJECT (asink, "no previous sample, now %" G_GINT64_FORMAT - " disabling slaving", *sample); - LOGD ("no previous sample, now %ld disabling slaving", *sample); - - asink->last_resync_sample = *sample; - g_object_set (asink, "slave-method", GST_BASE_AUDIO_SINK_SLAVE_NONE, - NULL); - asink->slaving_disabled = TRUE; - } else { -/* Trace displayed too much time : remove it - GST_INFO_OBJECT (asink, "no previous sample but not slaved"); - LOGD("no previous sample but not slaved"); -*/ - } - } - - if (slaved && asink->slaving_disabled) { - guint64 threshold; - - threshold = gst_util_uint64_scale_int (buf->spec.rate, 5, 1); - threshold += asink->last_resync_sample; - - if (*sample >= threshold) { - GST_INFO_OBJECT (asink, "last sync %" G_GINT64_FORMAT - " reached sample %" G_GINT64_FORMAT ", enabling slaving", - asink->last_resync_sample, *sample); - g_object_set (asink, "slave-method", GST_BASE_AUDIO_SINK_SLAVE_SKEW, - NULL); - asink->slaving_disabled = FALSE; - } - } - - bps = buf->spec.bytes_per_sample; - bufsize = buf->spec.segsize * buf->spec.segtotal; - - /* our toy resampler for trick modes */ - reverse = out_samples < 0; - out_samples = ABS (out_samples); - - if (in_samples >= out_samples) - toprocess = &in_samples; - else - toprocess = &out_samples; - - inr = in_samples - 1; - outr = out_samples - 1; - - GST_LOG_OBJECT (asink, "in %d, out %d reverse %d sync %d", inr, outr, - reverse, sync); - - /* data_end points to the last sample we have to write, not past it. This is - * needed to properly handle reverse playback: it points to the last sample. */ - data_end = data + (bps * inr); - - while (*toprocess > 0) { - if (sync) { - size_t avail; - guint towrite; - gint err; - guint8 *d, *d_end; - gpointer buffer_handle; - - position = audioflinger_device_get_position (asink->audioflinger_device); - avail = out_samples; - buffer_handle = NULL; - GST_LOG_OBJECT (asink, "calling obtain buffer, position %d" - " offset %" G_GINT64_FORMAT " samples %" G_GSSIZE_FORMAT, - position, *sample, avail); - err = audioflinger_device_obtain_buffer (asink->audioflinger_device, - &buffer_handle, (int8_t **) & d, &avail, *sample); - GST_LOG_OBJECT (asink, "obtain buffer returned"); - if (err < 0) { - GST_LOG_OBJECT (asink, "obtain buffer error %d, state %d", - err, buf->state); - LOGD ("obtain buffer error 0x%x, state %d", err, buf->state); - - if (err == LATE) - skip = TRUE; - else if (buf->state != GST_RING_BUFFER_STATE_STARTED) - goto done; - else - goto obtain_buffer_failed; - } - - towrite = avail * bps; - d_end = d + towrite; - - GST_LOG_OBJECT (asink, "writing %u samples at offset %" G_GUINT64_FORMAT, - (guint) avail, *sample); - - if (G_LIKELY (inr == outr && !reverse)) { - FWD_SAMPLES (data, data_end, d, d_end); - } else if (!reverse) { - if (inr >= outr) { - /* forward speed up */ - FWD_UP_SAMPLES (data, data_end, d, d_end); - } else { - /* forward slow down */ - FWD_DOWN_SAMPLES (data, data_end, d, d_end); - } - } else { - if (inr >= outr) - /* reverse speed up */ - REV_UP_SAMPLES (data, data_end, d, d_end); - else - /* reverse slow down */ - REV_DOWN_SAMPLES (data, data_end, d, d_end); - } - - *sample += avail; - - if (buffer_handle) - audioflinger_device_release_buffer (asink->audioflinger_device, - buffer_handle); - } else { - gint written; - - written = audioflinger_device_write (asink->audioflinger_device, data, - *toprocess * bps); - if (written > 0) { - *toprocess -= written / bps; - data += written; - } else { - LOGE ("Error to write buffer(error=%d)", written); - GST_LOG_OBJECT (asink, "Error to write buffer(error=%d)", written); - goto start_failed; - } - } - } -skip: - /* we consumed all samples here */ - data = data_end + bps; - -done: - result = inr - ((data_end - data) / bps); - GST_LOG_OBJECT (asink, "wrote %d samples", result); - - return result; - - /* ERRORS */ -no_start: - { - GST_LOG_OBJECT (asink, "we can not start"); - LOGE ("we can not start"); - return 0; - } -start_failed: - { - GST_LOG_OBJECT (asink, "failed to start the ringbuffer"); - LOGE ("failed to start the ringbuffer"); - return 0; - } -obtain_buffer_failed: - { - GST_ELEMENT_ERROR (asink, RESOURCE, FAILED, - ("obtain_buffer failed"), (NULL)); - LOGE ("obtain_buffer failed"); - return -1; - } -} - -static GstElementClass *parent_class = NULL; - -GType -gst_audioflinger_sink_get_type (void) -{ - static GType audioflingersink_type = 0; - - if (!audioflingersink_type) { - static const GTypeInfo audioflingersink_info = { - sizeof (GstAudioFlingerSinkClass), - gst_audioflinger_sink_base_init, - NULL, - (GClassInitFunc) gst_audioflinger_sink_class_init, - NULL, - NULL, - sizeof (GstAudioFlingerSink), - 0, - (GInstanceInitFunc) gst_audioflinger_sink_init, - }; - - audioflingersink_type = - g_type_register_static (GST_TYPE_AUDIO_SINK, "GstAudioFlingerSink", - &audioflingersink_info, 0); - } - - return audioflingersink_type; -} - -static void -gst_audioflinger_sink_dispose (GObject * object) -{ - GstAudioFlingerSink *audioflinger_sink = GST_AUDIOFLINGERSINK (object); - - if (audioflinger_sink->probed_caps) { - gst_caps_unref (audioflinger_sink->probed_caps); - audioflinger_sink->probed_caps = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -gst_audioflinger_sink_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details (element_class, &gst_audioflinger_sink_details); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&audioflingersink_sink_factory)); - GST_DEBUG_CATEGORY_INIT (audioflinger_debug, "audioflingersink", 0, - "audioflinger sink trace"); -} - -static void -gst_audioflinger_sink_class_init (GstAudioFlingerSinkClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSinkClass *gstbasesink_class; - GstBaseAudioSinkClass *gstbaseaudiosink_class; - GstAudioSinkClass *gstaudiosink_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesink_class = (GstBaseSinkClass *) klass; - gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass; - gstaudiosink_class = (GstAudioSinkClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_audioflinger_sink_dispose); - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_audioflinger_sink_finalise); - gobject_class->get_property = - GST_DEBUG_FUNCPTR (gst_audioflinger_sink_get_property); - gobject_class->set_property = - GST_DEBUG_FUNCPTR (gst_audioflinger_sink_set_property); - - gstelement_class->provide_clock = - GST_DEBUG_FUNCPTR (gst_audioflinger_sink_provide_clock); - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_audioflinger_sink_change_state); - - gstbasesink_class->get_caps = - GST_DEBUG_FUNCPTR (gst_audioflinger_sink_getcaps); - - gstbaseaudiosink_class->create_ringbuffer = - GST_DEBUG_FUNCPTR (gst_audioflinger_sink_create_ringbuffer); - - gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_audioflinger_sink_event); - gstbasesink_class->preroll = - GST_DEBUG_FUNCPTR (gst_audioflinger_sink_preroll); - - /* Install properties */ - g_object_class_install_property (gobject_class, PROP_MUTE, - g_param_spec_boolean ("mute", "Mute", - "Mute output", DEFAULT_MUTE, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, PROP_VOLUME, - g_param_spec_double ("volume", "Volume", - "control volume size", 0.0, 10.0, DEFAULT_VOLUME, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, PROP_AUDIO_SINK, - g_param_spec_pointer ("audiosink", "AudioSink", - "The pointer of MediaPlayerBase::AudioSink", G_PARAM_WRITABLE)); -} - -static void -gst_audioflinger_sink_init (GstAudioFlingerSink * audioflinger_sink) -{ - GST_DEBUG_OBJECT (audioflinger_sink, "initializing audioflinger_sink"); - LOGD ("initializing audioflinger_sink"); - - audioflinger_sink->audio_clock = NULL; - audioflinger_sink->system_clock = NULL; - audioflinger_sink->system_audio_clock = NULL; - audioflinger_sink->exported_clock = NULL; - audioflinger_sink->export_system_audio_clock = - DEFAULT_EXPORT_SYSTEM_AUDIO_CLOCK; - gst_audioflinger_sink_reset (audioflinger_sink, TRUE); -} - -static void -gst_audioflinger_sink_reset (GstAudioFlingerSink * sink, gboolean create_clocks) -{ - - if (sink->audioflinger_device != NULL) { - audioflinger_device_release (sink->audioflinger_device); - sink->audioflinger_device = NULL; - } - - sink->audioflinger_device = NULL; - sink->m_volume = DEFAULT_VOLUME; - sink->m_mute = DEFAULT_MUTE; - sink->m_init = FALSE; - sink->m_audiosink = NULL; - sink->eos = FALSE; - sink->may_provide_clock = TRUE; - sink->last_resync_sample = -1; - - if (sink->system_clock) { - GstClock *clock = sink->system_clock; - - GST_INFO_OBJECT (sink, "destroying system_clock %d", - GST_OBJECT_REFCOUNT (sink->system_clock)); - gst_clock_set_master (sink->system_clock, NULL); - gst_object_replace ((GstObject **) & sink->system_clock, NULL); - GST_INFO_OBJECT (sink, "destroyed system_clock"); - GST_INFO_OBJECT (sink, "destroying system_audio_clock %d", - GST_OBJECT_REFCOUNT (sink->system_audio_clock)); - gst_object_replace ((GstObject **) & sink->system_audio_clock, NULL); - GST_INFO_OBJECT (sink, "destroyed system_audio_clock"); - } - - if (sink->audio_clock) { - GST_INFO_OBJECT (sink, "destroying audio clock %d", - GST_OBJECT_REFCOUNT (sink->audio_clock)); - - gst_object_replace ((GstObject **) & sink->audio_clock, NULL); - } - - if (sink->exported_clock) { - GST_INFO_OBJECT (sink, "destroying exported clock %d", - GST_OBJECT_REFCOUNT (sink->exported_clock)); - gst_object_replace ((GstObject **) & sink->exported_clock, NULL); - GST_INFO_OBJECT (sink, "destroyed exported clock"); - } - - if (create_clocks) { - GstClockTime external, internal; - - /* create the audio clock that uses the ringbuffer as its audio source */ - sink->audio_clock = gst_audio_clock_new ("GstAudioFlingerSinkClock", - gst_audioflinger_sink_get_time, sink); - - /* always set audio_clock as baseaudiosink's provided_clock */ - gst_object_replace ((GstObject **) & - GST_BASE_AUDIO_SINK (sink)->provided_clock, - GST_OBJECT (sink->audio_clock)); - - /* create the system_audio_clock, which is an *audio clock* that uses an - * instance of the system clock as its time source */ - sink->system_audio_clock = - gst_audio_clock_new ("GstAudioFlingerSystemAudioClock", - gst_audioflinger_sink_system_audio_clock_get_time, sink); - - /* create an instance of the system clock, that we slave to - * sink->audio_clock to have an audio clock with an higher resolution than - * the segment size (50ms) */ - sink->system_clock = g_object_new (GST_TYPE_SYSTEM_CLOCK, - "name", "GstAudioFlingerSystemClock", NULL); - - /* calibrate the clocks */ - external = gst_clock_get_time (sink->audio_clock); - internal = gst_clock_get_internal_time (sink->system_clock); - gst_clock_set_calibration (sink->system_clock, internal, external, 1, 1); - - /* slave the system clock to the audio clock */ - GST_OBJECT_FLAG_SET (sink->system_clock, GST_CLOCK_FLAG_CAN_SET_MASTER); - g_object_set (sink->system_clock, "timeout", 50 * GST_MSECOND, NULL); - gst_clock_set_master (sink->system_clock, sink->audio_clock); - } - -} - -static void -gst_audioflinger_sink_finalise (GObject * object) -{ - GstAudioFlingerSink *audioflinger_sink = GST_AUDIOFLINGERSINK (object); - - GST_INFO_OBJECT (object, "finalize"); - - gst_audioflinger_sink_reset (audioflinger_sink, FALSE); - - G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (object)); -} - -static GstRingBuffer * -gst_audioflinger_sink_create_ringbuffer (GstBaseAudioSink * sink) -{ - GstRingBuffer *buffer; - - GST_DEBUG_OBJECT (sink, "creating ringbuffer"); - LOGD ("creating ringbuffer"); - buffer = g_object_new (GST_TYPE_ANDROID_AUDIORING_BUFFER, NULL); - GST_DEBUG_OBJECT (sink, "created ringbuffer @%p", buffer); - LOGD ("created ringbuffer @%p", buffer); - - return buffer; -} - -static void -gst_audioflinger_sink_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstAudioFlingerSink *audioflinger_sink; - - audioflinger_sink = GST_AUDIOFLINGERSINK (object); - g_return_if_fail (audioflinger_sink != NULL); - - switch (prop_id) { - case PROP_MUTE: - g_value_set_boolean (value, audioflinger_sink->m_mute); - GST_DEBUG_OBJECT (audioflinger_sink, "get mute: %d", - audioflinger_sink->m_mute); - LOGD ("get mute: %d", audioflinger_sink->m_mute); - break; - case PROP_VOLUME: - g_value_set_double (value, audioflinger_sink->m_volume); - GST_DEBUG_OBJECT (audioflinger_sink, "get volume: %f", - audioflinger_sink->m_volume); - LOGD ("get volume: %f", audioflinger_sink->m_volume); - break; - case PROP_AUDIO_SINK: - GST_ERROR_OBJECT (audioflinger_sink, "Shall not go here!"); - LOGD ("Shall not go here!"); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_audioflinger_sink_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstAudioFlingerSink *audioflinger_sink; - audioflinger_sink = GST_AUDIOFLINGERSINK (object); - - g_return_if_fail (audioflinger_sink != NULL); - GST_OBJECT_LOCK (audioflinger_sink); - switch (prop_id) { - case PROP_MUTE: - audioflinger_sink->m_mute = g_value_get_boolean (value); - GST_DEBUG_OBJECT (audioflinger_sink, "set mute: %d", - audioflinger_sink->m_mute); - LOGD ("set mute: %d", audioflinger_sink->m_mute); - /* set device if it's initialized */ - if (audioflinger_sink->audioflinger_device && audioflinger_sink->m_init) - gst_audioflinger_sink_set_mute (audioflinger_sink, - (int) (audioflinger_sink->m_mute)); - break; - case PROP_VOLUME: - audioflinger_sink->m_volume = g_value_get_double (value); - GST_DEBUG_OBJECT (audioflinger_sink, "set volume: %f", - audioflinger_sink->m_volume); - LOGD ("set volume: %f", audioflinger_sink->m_volume); - /* set device if it's initialized */ - if (audioflinger_sink->audioflinger_device && audioflinger_sink->m_init) - gst_audioflinger_sink_set_volume (audioflinger_sink, - (float) audioflinger_sink->m_volume); - break; - case PROP_AUDIO_SINK: - audioflinger_sink->m_audiosink = g_value_get_pointer (value); - GST_DEBUG_OBJECT (audioflinger_sink, "set audiosink: %p", - audioflinger_sink->m_audiosink); - LOGD ("set audiosink: %p", audioflinger_sink->m_audiosink); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - GST_OBJECT_UNLOCK (audioflinger_sink); -} - -static GstCaps * -gst_audioflinger_sink_getcaps (GstBaseSink * bsink) -{ - GstAudioFlingerSink *audioflinger_sink; - GstCaps *caps; - - audioflinger_sink = GST_AUDIOFLINGERSINK (bsink); - GST_DEBUG_OBJECT (audioflinger_sink, "enter,%p", - audioflinger_sink->audioflinger_device); - LOGD ("gst_audioflinger_sink_getcaps,%p", - audioflinger_sink->audioflinger_device); - if (audioflinger_sink->audioflinger_device == NULL - || audioflinger_sink->m_init == FALSE) { - caps = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD - (bsink))); - } else if (audioflinger_sink->probed_caps) { - caps = gst_caps_copy (audioflinger_sink->probed_caps); - } else { - caps = gst_caps_new_any (); - if (caps && !gst_caps_is_empty (caps)) { - audioflinger_sink->probed_caps = gst_caps_copy (caps); - } - } - - return caps; -} - -static gboolean -gst_audioflinger_sink_open (GstAudioFlingerSink * audioflinger) -{ - GstBaseAudioSink *baseaudiosink = (GstBaseAudioSink *) audioflinger; - - GST_DEBUG_OBJECT (audioflinger, "enter"); - LOGD ("gst_audioflinger_sink_open"); - g_return_val_if_fail (audioflinger != NULL, FALSE); - - baseaudiosink->buffer_time = DEFAULT_BUFFERTIME; - baseaudiosink->latency_time = DEFAULT_LATENCYTIME; - - if (audioflinger->audioflinger_device == NULL) { - if (audioflinger->m_audiosink) { - if (!(audioflinger->audioflinger_device = - audioflinger_device_open (audioflinger->m_audiosink))) - goto failed_creation; - GST_DEBUG_OBJECT (audioflinger, "open an existed flinger, %p", - audioflinger->audioflinger_device); - LOGD ("open an existed flinger, %p", audioflinger->audioflinger_device); - } else { - if (!(audioflinger->audioflinger_device = audioflinger_device_create ())) - goto failed_creation; - GST_DEBUG_OBJECT (audioflinger, "create a new flinger, %p", - audioflinger->audioflinger_device); - LOGD ("create a new flinger, %p", audioflinger->audioflinger_device); - } - } - return TRUE; - - /* ERRORS */ -failed_creation: - { - GST_ELEMENT_ERROR (audioflinger, RESOURCE, SETTINGS, (NULL), - ("Failed to create AudioFlinger")); - LOGE ("Failed to create AudioFlinger"); - return FALSE; - } -} - -static gboolean -gst_audioflinger_sink_close (GstAudioFlingerSink * audioflinger) -{ - GST_DEBUG_OBJECT (audioflinger, "enter"); - LOGD ("gst_audioflinger_sink_close"); - - if (audioflinger->audioflinger_device != NULL) { - GST_DEBUG_OBJECT (audioflinger, "release flinger device"); - LOGD ("release flinger device"); - audioflinger_device_stop (audioflinger->audioflinger_device); - audioflinger_device_release (audioflinger->audioflinger_device); - audioflinger->audioflinger_device = NULL; - } - return TRUE; -} - -static gboolean -gst_audioflinger_sink_prepare (GstAudioFlingerSink * audioflinger, - GstRingBufferSpec * spec) -{ - GST_DEBUG_OBJECT (audioflinger, "enter"); - LOGD ("gst_audioflinger_sink_prepare"); - - /* FIXME: - * - * Pipeline crashes in audioflinger_device_set(), after releasing audio - * flinger device and creating it again. In most cases, it will happen when - * playing the same audio again. - * - * It seems the root cause is we create and release audio flinger sink in - * different thread in playbin2. Till now, I haven't found way to - * create/release device in the same thread. Fortunately, it will not effect - * the gst-launch usage - */ - if (audioflinger_device_set (audioflinger->audioflinger_device, - 3, spec->channels, spec->rate, spec->segsize) == -1) - goto failed_creation; - - audioflinger->m_init = TRUE; -// gst_audioflinger_sink_set_volume (audioflinger, audioflinger->m_volume); -// gst_audioflinger_sink_set_mute (audioflinger, audioflinger->m_mute); - spec->bytes_per_sample = (spec->width / 8) * spec->channels; - audioflinger->bytes_per_sample = spec->bytes_per_sample; - - spec->segsize = - audioflinger_device_frameCount (audioflinger->audioflinger_device); - - GST_DEBUG_OBJECT (audioflinger, - "channels: %d, rate: %d, width: %d, got segsize: %d, segtotal: %d, " - "frame count: %d, frame size: %d", - spec->channels, spec->rate, spec->width, spec->segsize, spec->segtotal, - audioflinger_device_frameCount (audioflinger->audioflinger_device), - audioflinger_device_frameSize (audioflinger->audioflinger_device) - ); - LOGD ("channels: %d, rate: %d, width: %d, got segsize: %d, segtotal: %d, " - "frame count: %d, frame size: %d", - spec->channels, spec->rate, spec->width, spec->segsize, spec->segtotal, - audioflinger_device_frameCount (audioflinger->audioflinger_device), - audioflinger_device_frameSize (audioflinger->audioflinger_device) - ); - -#if 0 - GST_DEBUG_OBJECT (audioflinger, "pause device"); - LOGD ("pause device"); - audioflinger_device_pause (audioflinger->audioflinger_device); -#endif - - return TRUE; - - /* ERRORS */ -failed_creation: - { - GST_ELEMENT_ERROR (audioflinger, RESOURCE, SETTINGS, (NULL), - ("Failed to create AudioFlinger for format %d", spec->format)); - LOGE ("Failed to create AudioFlinger for format %d", spec->format); - return FALSE; - } -dodgy_width: - { - GST_ELEMENT_ERROR (audioflinger, RESOURCE, SETTINGS, (NULL), - ("Unhandled width %d", spec->width)); - LOGE ("Unhandled width %d", spec->width); - return FALSE; - } -} - -static gboolean -gst_audioflinger_sink_unprepare (GstAudioFlingerSink * audioflinger) -{ - GST_DEBUG_OBJECT (audioflinger, "enter"); - LOGD ("gst_audioflinger_sink_unprepare"); - - if (audioflinger->audioflinger_device != NULL) { - GST_DEBUG_OBJECT (audioflinger, "release flinger device"); - LOGD ("release flinger device"); - audioflinger_device_stop (audioflinger->audioflinger_device); - audioflinger->m_init = FALSE; - } - - return TRUE; -} - -static void -gst_audioflinger_sink_set_mute (GstAudioFlingerSink * audioflinger_sink, - gboolean mute) -{ - GST_DEBUG_OBJECT (audioflinger_sink, "set PROP_MUTE = %d\n", mute); - LOGD ("set PROP_MUTE = %d\n", mute); - - if (audioflinger_sink->audioflinger_device) - audioflinger_device_mute (audioflinger_sink->audioflinger_device, mute); - audioflinger_sink->m_mute = mute; -} - -static void -gst_audioflinger_sink_set_volume (GstAudioFlingerSink * audioflinger_sink, - float volume) -{ - GST_DEBUG_OBJECT (audioflinger_sink, "set PROP_VOLUME = %f\n", volume); - LOGD ("set PROP_VOLUME = %f\n", volume); - - if (audioflinger_sink->audioflinger_device != NULL) { - audioflinger_device_set_volume (audioflinger_sink->audioflinger_device, - volume, volume); - } -} - -gboolean -gst_audioflinger_sink_plugin_init (GstPlugin * plugin) -{ - return gst_element_register (plugin, "audioflingersink", GST_RANK_PRIMARY, - GST_TYPE_AUDIOFLINGERSINK); -} - -/* -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "audioflingersink", - "audioflinger sink audio", plugin_init, VERSION, "LGPL", "GStreamer", - "http://gstreamer.net/") - */ - -static GstClock * -gst_audioflinger_sink_provide_clock (GstElement * elem) -{ - GstBaseAudioSink *sink; - GstAudioFlingerSink *asink; - GstClock *clock; - - sink = GST_BASE_AUDIO_SINK (elem); - asink = GST_AUDIOFLINGERSINK (elem); - - /* we have no ringbuffer (must be NULL state) */ - if (sink->ringbuffer == NULL) - goto wrong_state; - - if (!gst_ring_buffer_is_acquired (sink->ringbuffer)) - goto wrong_state; - - GST_OBJECT_LOCK (sink); - if (!asink->may_provide_clock) - goto already_playing; - - if (!sink->provide_clock) - goto clock_disabled; - - clock = GST_CLOCK_CAST (gst_object_ref (asink->exported_clock)); - GST_INFO_OBJECT (asink, "providing clock %p %s", clock, - clock == NULL ? NULL : GST_OBJECT_NAME (clock)); - GST_OBJECT_UNLOCK (sink); - - return clock; - - /* ERRORS */ -wrong_state: - { - GST_DEBUG_OBJECT (sink, "ringbuffer not acquired"); - LOGD ("ringbuffer not acquired"); - return NULL; - } -already_playing: - { - GST_INFO_OBJECT (sink, "we went to playing already"); - GST_OBJECT_UNLOCK (sink); - return NULL; - } -clock_disabled: - { - GST_DEBUG_OBJECT (sink, "clock provide disabled"); - LOGD ("clock provide disabled"); - GST_OBJECT_UNLOCK (sink); - return NULL; - } -} - -static GstStateChangeReturn -gst_audioflinger_sink_change_state (GstElement * element, - GstStateChange transition) -{ - GstStateChangeReturn ret; - GstClockTime time; - GstAudioFlingerSink *sink = GST_AUDIOFLINGERSINK (element); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - sink->may_provide_clock = FALSE; - if (sink->exported_clock == sink->system_audio_clock) { - GstClockTime cinternal, cexternal, crate_num, crate_denom; - - /* take the slave lock to make sure that the slave_callback doesn't run - * while we're moving sink->audio_clock forward, causing - * sink->system_clock to jump as well */ - GST_CLOCK_SLAVE_LOCK (sink->system_clock); - gst_clock_get_calibration (sink->audio_clock, NULL, NULL, - &crate_num, &crate_denom); - cinternal = gst_clock_get_internal_time (sink->audio_clock); - cexternal = gst_clock_get_time (GST_ELEMENT_CLOCK (sink)); - gst_clock_set_calibration (sink->audio_clock, cinternal, cexternal, - crate_num, crate_denom); - /* reset observations */ - sink->system_clock->filling = TRUE; - sink->system_clock->time_index = 0; - GST_CLOCK_SLAVE_UNLOCK (sink->system_clock); - - time = gst_clock_get_time (sink->audio_clock); - GST_INFO_OBJECT (sink, "PAUSED_TO_PLAYING," - " base_time %" GST_TIME_FORMAT - " after %" GST_TIME_FORMAT - " internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_ELEMENT (sink)->base_time), - GST_TIME_ARGS (time), - GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal)); - } - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - default: - break; - } - return ret; -} - -static GstFlowReturn -gst_audioflinger_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer) -{ - GstFlowReturn ret; - gboolean us_live = FALSE; - GstQuery *query; - GstAudioFlingerSink *asink = GST_AUDIOFLINGERSINK (bsink); - GstBaseAudioSink *baseaudiosink = GST_BASE_AUDIO_SINK (bsink); - GstClock *clock; - - GST_INFO_OBJECT (bsink, "preroll"); - - ret = GST_BASE_SINK_CLASS (parent_class)->preroll (bsink, buffer); - if (ret != GST_FLOW_OK) - goto done; - - if (asink->exported_clock != NULL) { - GST_INFO_OBJECT (bsink, "clock already exported"); - goto done; - } - - query = gst_query_new_latency (); - - /* ask the peer for the latency */ - if (gst_pad_peer_query (bsink->sinkpad, query)) { - /* get upstream min and max latency */ - gst_query_parse_latency (query, &us_live, NULL, NULL); - GST_INFO_OBJECT (bsink, "query result live: %d", us_live); - } else { - GST_WARNING_OBJECT (bsink, "latency query failed"); - } - gst_query_unref (query); - - if (!us_live && asink->export_system_audio_clock) { - clock = asink->system_audio_clock; - /* set SLAVE_NONE so that baseaudiosink doesn't try to slave audio_clock to - * system_audio_clock - */ - g_object_set (asink, "slave-method", GST_BASE_AUDIO_SINK_SLAVE_NONE, NULL); - } else { - clock = asink->audio_clock; - } - - GST_INFO_OBJECT (bsink, "using %s clock", - clock == asink->audio_clock ? "audio" : "system_audio"); - gst_object_replace ((GstObject **) & asink->exported_clock, - GST_OBJECT (clock)); - GST_OBJECT_UNLOCK (asink); - -done: - return ret; -} - -static gboolean -gst_audioflinger_sink_event (GstBaseSink * bsink, GstEvent * event) -{ - GstAudioFlingerSink *asink = GST_AUDIOFLINGERSINK (bsink); - GstBaseAudioSink *baseaudiosink = GST_BASE_AUDIO_SINK (bsink); - GstRingBuffer *ringbuf = baseaudiosink->ringbuffer; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - GST_INFO_OBJECT (asink, "got EOS"); - asink->eos = TRUE; - - if (baseaudiosink->next_sample) { - guint64 next_sample, sample; - gint sps; - GstFlowReturn ret; - GstBuffer *buf; - - sps = ringbuf->spec.segsize / ringbuf->spec.bytes_per_sample; - sample = baseaudiosink->next_sample; - next_sample = baseaudiosink->next_sample / sps; - if (next_sample < ringbuf->spec.segsize) { - gint samples, out_samples, accum, size; - GstClockTime timestamp, before, after; - guchar *data, *data_start; - gint64 drift_tolerance; - guint written; - gint64 offset; - - samples = (ringbuf->spec.segsize - next_sample) * 4; - - size = samples * ringbuf->spec.bytes_per_sample; - - timestamp = gst_util_uint64_scale_int (baseaudiosink->next_sample, - GST_SECOND, ringbuf->spec.rate); - - before = gst_clock_get_internal_time (asink->audio_clock); - GST_INFO_OBJECT (asink, "%" G_GINT64_FORMAT " < %d, " - "padding with silence, samples %d size %d ts %" GST_TIME_FORMAT, - next_sample, ringbuf->spec.segsize, samples, size, - GST_TIME_ARGS (timestamp)); - LOGD ("PADDING"); - - data_start = data = g_malloc0 (size); - offset = baseaudiosink->next_sample; - out_samples = samples; - - GST_STATE_LOCK (bsink); - do { - written = - gst_ring_buffer_commit_full (ringbuf, &offset, data, samples, - out_samples, &accum); - - GST_DEBUG_OBJECT (bsink, "wrote %u of %u", written, samples); - /* if we wrote all, we're done */ - if (written == samples) - break; - - /* else something interrupted us and we wait for preroll. */ - if ((ret = gst_base_sink_wait_preroll (bsink)) != GST_FLOW_OK) - break; - - /* update the output samples. FIXME, this will just skip them when pausing - * during trick mode */ - if (out_samples > written) { - out_samples -= written; - accum = 0; - } else - break; - - samples -= written; - data += written * ringbuf->spec.bytes_per_sample; - } while (TRUE); - - - GST_STATE_UNLOCK (bsink); - - g_free (data_start); - after = gst_clock_get_internal_time (asink->audio_clock); - - GST_INFO_OBJECT (asink, "padded, left %d before %" GST_TIME_FORMAT - " after %" GST_TIME_FORMAT, samples, - GST_TIME_ARGS (before), GST_TIME_ARGS (after)); - - - } else { - LOGD ("NOT PADDING 1"); - } - } else { - LOGD ("NOT PADDING 2"); - } - - break; - case GST_EVENT_BUFFERING_START: - GST_INFO_OBJECT (asink, "buffering start"); - break; - case GST_EVENT_BUFFERING_STOP: - { - gboolean slaved; - GstClockTime cinternal, cexternal, crate_num, crate_denom; - GstClockTime before, after; - - gst_clock_get_calibration (asink->audio_clock, &cinternal, &cexternal, - &crate_num, &crate_denom); - - before = gst_clock_get_time (asink->audio_clock); - - cinternal = gst_clock_get_internal_time (asink->audio_clock); - cexternal = gst_clock_get_time (GST_ELEMENT_CLOCK (asink)); - gst_clock_set_calibration (asink->audio_clock, cinternal, - cexternal, crate_num, crate_denom); - - after = gst_clock_get_time (asink->audio_clock); - - GST_INFO_OBJECT (asink, "buffering stopped, clock recalibrated" - " before %" GST_TIME_FORMAT " after %" GST_TIME_FORMAT, - GST_TIME_ARGS (before), GST_TIME_ARGS (after)); - - /* force baseaudiosink to resync from the next buffer */ - GST_BASE_AUDIO_SINK (asink)->next_sample = -1; - - /* reset this so we allow some time before enabling slaving again */ - asink->last_resync_sample = -1; - slaved = GST_ELEMENT_CLOCK (asink) != asink->exported_clock; - if (slaved) { - GST_INFO_OBJECT (asink, "disabling slaving"); - g_object_set (asink, "slave-method", GST_BASE_AUDIO_SINK_SLAVE_NONE, - NULL); - asink->slaving_disabled = TRUE; - } - - g_object_set (asink, "drift-tolerance", 200 * GST_MSECOND, NULL); - break; - } - default: - break; - } - - return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event); -} - -static GstClockTime -gst_audioflinger_sink_get_time (GstClock * clock, gpointer user_data) -{ - GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (user_data); - uint32_t position = -1; - GstAudioFlingerSink *asink = GST_AUDIOFLINGERSINK (sink); - GstClockTime time = GST_CLOCK_TIME_NONE; - GstClockTime ptime = GST_CLOCK_TIME_NONE; - GstClockTime system_audio_clock_time = GST_CLOCK_TIME_NONE; - GstClockTime offset = GST_CLOCK_TIME_NONE; - GstClockTime adjusted_time = GST_CLOCK_TIME_NONE; - GstClockTime cinternal, cexternal, crate_num, crate_denom; - - gst_clock_get_calibration (clock, &cinternal, &cexternal, - &crate_num, &crate_denom); - - if (!asink->audioflinger_device || !asink->m_init) { - GST_DEBUG_OBJECT (sink, "device not created yet"); - - goto out; - } - - if (!asink->audioflinger_device || !asink->m_init) { - GST_DEBUG_OBJECT (sink, "device not created yet"); - - goto out; - } - - if (!sink->ringbuffer) { - GST_DEBUG_OBJECT (sink, "NULL ringbuffer"); - - goto out; - } - - if (!sink->ringbuffer->acquired) { - GST_DEBUG_OBJECT (sink, "ringbuffer not acquired"); - - goto out; - } - - position = audioflinger_device_get_position (asink->audioflinger_device); - if (position == -1) - goto out; - - time = gst_util_uint64_scale_int (position, GST_SECOND, - sink->ringbuffer->spec.rate); - - offset = gst_audio_clock_adjust (GST_CLOCK (clock), 0); - adjusted_time = gst_audio_clock_adjust (GST_CLOCK (clock), time); - - if (asink->system_audio_clock) - system_audio_clock_time = gst_clock_get_time (asink->system_audio_clock); - - if (GST_ELEMENT_CLOCK (asink) - && asink->audio_clock != GST_ELEMENT_CLOCK (asink)) - ptime = gst_clock_get_time (GST_ELEMENT_CLOCK (asink)); - -out: - GST_DEBUG_OBJECT (sink, - "clock %s processed samples %" G_GINT32_FORMAT " offset %" GST_TIME_FORMAT - " time %" GST_TIME_FORMAT " pipeline time %" GST_TIME_FORMAT - " system audio clock %" GST_TIME_FORMAT " adjusted_time %" GST_TIME_FORMAT - " cinternal %" GST_TIME_FORMAT " cexternal %" GST_TIME_FORMAT, - GST_OBJECT_NAME (clock), position, GST_TIME_ARGS (offset), - GST_TIME_ARGS (time), GST_TIME_ARGS (ptime), - GST_TIME_ARGS (system_audio_clock_time), GST_TIME_ARGS (adjusted_time), - GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal)); - - return time; -} - -static GstClockTime -gst_audioflinger_sink_system_audio_clock_get_time (GstClock * clock, - gpointer user_data) -{ - GstClockTime time, offset; - GstAudioFlingerSink *sink = GST_AUDIOFLINGERSINK (user_data); - - time = gst_clock_get_time (sink->system_clock); - offset = gst_audio_clock_adjust (clock, (GstClockTime) 0); - time -= offset; - - return time; -} diff --git a/sys/audioflingersink/gstaudioflingersink.h b/sys/audioflingersink/gstaudioflingersink.h deleted file mode 100644 index 02e6a928ed..0000000000 --- a/sys/audioflingersink/gstaudioflingersink.h +++ /dev/null @@ -1,70 +0,0 @@ -/* GStreamer - * Copyright (C) <2009> Prajnashi S - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifndef __GST_AUDIOFLINGERSINK_H__ -#define __GST_AUDIOFLINGERSINK_H__ - - -#include -#include "gstaudiosink.h" -#include "audioflinger_wrapper.h" - - -G_BEGIN_DECLS - -#define GST_TYPE_AUDIOFLINGERSINK (gst_audioflinger_sink_get_type()) -#define GST_AUDIOFLINGERSINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIOFLINGERSINK,GstAudioFlingerSink)) -#define GST_AUDIOFLINGERSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOFLINGERSINK,GstAudioFlingerSinkClass)) -#define GST_IS_AUDIOFLINGERSINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIOFLINGERSINK)) -#define GST_IS_AUDIOFLINGERSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOFLINGERSINK)) - -typedef struct _GstAudioFlingerSink GstAudioFlingerSink; -typedef struct _GstAudioFlingerSinkClass GstAudioFlingerSinkClass; - -struct _GstAudioFlingerSink { - GstAudioSink sink; - - AudioFlingerDeviceHandle audioflinger_device; - gboolean m_init; - gint bytes_per_sample; - gdouble m_volume; - gboolean m_mute; - gpointer m_audiosink; - GstCaps *probed_caps; - gboolean eos; - GstClock *audio_clock; - GstClock *system_clock; - GstClock *system_audio_clock; - GstClock *exported_clock; - gboolean export_system_audio_clock; - gboolean may_provide_clock; - gboolean slaving_disabled; - guint64 last_resync_sample; -}; - -struct _GstAudioFlingerSinkClass { - GstAudioSinkClass parent_class; -}; - -GType gst_audioflinger_sink_get_type(void); - - gboolean gst_audioflinger_sink_plugin_init (GstPlugin * plugin); - -G_END_DECLS - -#endif /* __GST_AUDIOFLINGERSINK_H__ */ -- 2.34.1