/* * Copyright (C) 2008 Ole André Vadla Ravnås * Copyright (C) 2018 Centricular Ltd. * Author: Nirbheek Chauhan * Copyright (C) 2020 Seungha Yang * * 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., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include "gstwasapi2util.h" #include GST_DEBUG_CATEGORY_EXTERN (gst_wasapi2_debug); #define GST_CAT_DEFAULT gst_wasapi2_debug /* *INDENT-OFF* */ static struct { guint64 wasapi_pos; GstAudioChannelPosition gst_pos; } wasapi_to_gst_pos[] = { {SPEAKER_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {SPEAKER_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {SPEAKER_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {SPEAKER_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, {SPEAKER_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {SPEAKER_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {SPEAKER_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {SPEAKER_FRONT_RIGHT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {SPEAKER_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, /* Enum values diverge from this point onwards */ {SPEAKER_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {SPEAKER_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {SPEAKER_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER}, {SPEAKER_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT}, {SPEAKER_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER}, {SPEAKER_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {SPEAKER_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT}, {SPEAKER_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER}, {SPEAKER_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT} }; /* *INDENT-ON* */ static const gchar * hresult_to_string_fallback (HRESULT hr) { const gchar *s = "unknown error"; switch (hr) { case AUDCLNT_E_NOT_INITIALIZED: s = "AUDCLNT_E_NOT_INITIALIZED"; break; case AUDCLNT_E_ALREADY_INITIALIZED: s = "AUDCLNT_E_ALREADY_INITIALIZED"; break; case AUDCLNT_E_WRONG_ENDPOINT_TYPE: s = "AUDCLNT_E_WRONG_ENDPOINT_TYPE"; break; case AUDCLNT_E_DEVICE_INVALIDATED: s = "AUDCLNT_E_DEVICE_INVALIDATED"; break; case AUDCLNT_E_NOT_STOPPED: s = "AUDCLNT_E_NOT_STOPPED"; break; case AUDCLNT_E_BUFFER_TOO_LARGE: s = "AUDCLNT_E_BUFFER_TOO_LARGE"; break; case AUDCLNT_E_OUT_OF_ORDER: s = "AUDCLNT_E_OUT_OF_ORDER"; break; case AUDCLNT_E_UNSUPPORTED_FORMAT: s = "AUDCLNT_E_UNSUPPORTED_FORMAT"; break; case AUDCLNT_E_INVALID_DEVICE_PERIOD: s = "AUDCLNT_E_INVALID_DEVICE_PERIOD"; break; case AUDCLNT_E_INVALID_SIZE: s = "AUDCLNT_E_INVALID_SIZE"; break; case AUDCLNT_E_DEVICE_IN_USE: s = "AUDCLNT_E_DEVICE_IN_USE"; break; case AUDCLNT_E_BUFFER_OPERATION_PENDING: s = "AUDCLNT_E_BUFFER_OPERATION_PENDING"; break; case AUDCLNT_E_BUFFER_SIZE_ERROR: s = "AUDCLNT_E_BUFFER_SIZE_ERROR"; break; case AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED: s = "AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED"; break; case AUDCLNT_E_THREAD_NOT_REGISTERED: s = "AUDCLNT_E_THREAD_NOT_REGISTERED"; break; case AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED: s = "AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED"; break; case AUDCLNT_E_ENDPOINT_CREATE_FAILED: s = "AUDCLNT_E_ENDPOINT_CREATE_FAILED"; break; case AUDCLNT_E_SERVICE_NOT_RUNNING: s = "AUDCLNT_E_SERVICE_NOT_RUNNING"; break; case AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED: s = "AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED"; break; case AUDCLNT_E_EXCLUSIVE_MODE_ONLY: s = "AUDCLNT_E_EXCLUSIVE_MODE_ONLY"; break; case AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL: s = "AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL"; break; case AUDCLNT_E_EVENTHANDLE_NOT_SET: s = "AUDCLNT_E_EVENTHANDLE_NOT_SET"; break; case AUDCLNT_E_INCORRECT_BUFFER_SIZE: s = "AUDCLNT_E_INCORRECT_BUFFER_SIZE"; break; case AUDCLNT_E_CPUUSAGE_EXCEEDED: s = "AUDCLNT_E_CPUUSAGE_EXCEEDED"; break; case AUDCLNT_S_BUFFER_EMPTY: s = "AUDCLNT_S_BUFFER_EMPTY"; break; case AUDCLNT_S_THREAD_ALREADY_REGISTERED: s = "AUDCLNT_S_THREAD_ALREADY_REGISTERED"; break; case AUDCLNT_S_POSITION_STALLED: s = "AUDCLNT_S_POSITION_STALLED"; break; case E_POINTER: s = "E_POINTER"; break; case E_INVALIDARG: s = "E_INVALIDARG"; break; } return s; } gboolean _gst_wasapi2_result (HRESULT hr, GstDebugCategory * cat, const gchar * file, const gchar * function, gint line) { #ifndef GST_DISABLE_GST_DEBUG gboolean ret = TRUE; if (FAILED (hr)) { gchar *error_text = NULL; gboolean free_string = TRUE; error_text = g_win32_error_message ((gint) hr); /* g_win32_error_message() seems to be returning empty string for * AUDCLNT_* cases */ if (!error_text || strlen (error_text) == 0) { g_free (error_text); error_text = (gchar *) hresult_to_string_fallback (hr); free_string = FALSE; } gst_debug_log (cat, GST_LEVEL_WARNING, file, function, line, NULL, "WASAPI call failed: 0x%x, %s", (guint) hr, error_text); if (free_string) g_free (error_text); ret = FALSE; } return ret; #else return SUCCEEDED (hr); #endif }