#include <sys/time.h>
#include <stdlib.h>
#include <dlog.h>
+#include <gio/gio.h>
#include <mm_error.h>
#include <mm_attrs.h>
+#include <mm_sound.h>
#include "mm_player_priv.h"
#include "mm_player_ini.h"
#define FAKE_SINK_MAX_LATENESS G_GINT64_CONSTANT(20000000) /* set 20ms as waylandsink */
+#define DEFAULT_PCM_OUT_FORMAT "F32LE"
+#define DEFAULT_PCM_OUT_SAMPLERATE 44100
+#define DEFAULT_PCM_OUT_CHANNEL 2
+
/*---------------------------------------------------------------------------
| LOCAL CONSTANT DEFINITIONS: |
---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
| LOCAL FUNCTION PROTOTYPES: |
---------------------------------------------------------------------------*/
-static int __mmplayer_gst_create_pipeline(mm_player_t *player);
-static int __mmplayer_gst_destroy_pipeline(mm_player_t *player);
-static int __mmplayer_gst_create_text_pipeline(mm_player_t *player);
-static int __mmplayer_gst_create_video_sink_bin(mm_player_t *player, GstCaps *caps, MMDisplaySurfaceType surface_type);
-static int __mmplayer_gst_create_audio_sink_bin(mm_player_t *player);
-static int __mmplayer_gst_create_text_sink_bin(mm_player_t *player);
+static int __mmplayer_gst_create_pipeline(mmplayer_t *player);
+static int __mmplayer_gst_destroy_pipeline(mmplayer_t *player);
+static int __mmplayer_gst_create_text_pipeline(mmplayer_t *player);
+static int __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDisplaySurfaceType surface_type);
+static int __mmplayer_gst_create_audio_sink_bin(mmplayer_t *player);
+static int __mmplayer_gst_create_text_sink_bin(mmplayer_t *player);
static GstPadProbeReturn __mmplayer_gst_selector_blocked(GstPad *pad, GstPadProbeInfo *info, gpointer data);
static void __mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data);
static void __mmplayer_pipeline_complete(GstElement *decodebin, gpointer data);
static gboolean __mmplayer_is_midi_type(gchar *str_caps);
static gboolean __mmplayer_is_only_mp3_type(gchar *str_caps);
-static void __mmplayer_set_audio_attrs(mm_player_t *player, GstCaps *caps);
+static void __mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps);
static gboolean __mmplayer_update_subtitle(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data);
-static void __mmplayer_release_misc(mm_player_t *player);
-static void __mmplayer_release_misc_post(mm_player_t *player);
-static gboolean __mmplayer_init_gstreamer(mm_player_t *player);
+static void __mmplayer_release_misc(mmplayer_t *player);
+static void __mmplayer_release_misc_post(mmplayer_t *player);
+static gboolean __mmplayer_init_gstreamer(mmplayer_t *player);
static void __mmplayer_video_stream_decoded_preroll_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data);
static void __mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data);
static GstPadProbeReturn __mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
-static int __mmplayer_change_selector_pad(mm_player_t *player, MMPlayerTrackType type, int index);
-
-static gboolean __mmplayer_check_subtitle(mm_player_t *player);
-static int __mmplayer_handle_missed_plugin(mm_player_t *player);
-static int __mmplayer_check_not_supported_codec(mm_player_t *player, const gchar *factory_class, const gchar *mime);
-static void __mmplayer_add_sink(mm_player_t *player, GstElement *sink);
-static void __mmplayer_del_sink(mm_player_t *player, GstElement *sink);
-static void __mmplayer_release_signal_connection(mm_player_t *player, MMPlayerSignalType type);
+static int __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, int index);
+
+static gboolean __mmplayer_check_subtitle(mmplayer_t *player);
+static int __mmplayer_handle_missed_plugin(mmplayer_t *player);
+static int __mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime);
+static void __mmplayer_add_sink(mmplayer_t *player, GstElement *sink);
+static void __mmplayer_del_sink(mmplayer_t *player, GstElement *sink);
+static void __mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e type);
static gpointer __mmplayer_gapless_play_thread(gpointer data);
-static gboolean __mmplayer_add_dump_buffer_probe(mm_player_t *player, GstElement *element);
+static gboolean __mmplayer_add_dump_buffer_probe(mmplayer_t *player, GstElement *element);
static GstPadProbeReturn __mmplayer_dump_buffer_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
static void __mmplayer_release_dump_list(GList *dump_list);
-static int __mmplayer_gst_realize(mm_player_t *player);
-static int __mmplayer_gst_unrealize(mm_player_t *player);
-static int __mmplayer_gst_adjust_subtitle_position(mm_player_t *player, int format, int position);
-static int __mmplayer_gst_set_message_callback(mm_player_t *player, MMMessageCallback callback, gpointer user_param);
+static int __mmplayer_gst_realize(mmplayer_t *player);
+static int __mmplayer_gst_unrealize(mmplayer_t *player);
+static int __mmplayer_gst_adjust_subtitle_position(mmplayer_t *player, int position);
+static int __mmplayer_gst_set_message_callback(mmplayer_t *player, MMMessageCallback callback, gpointer user_param);
/* util */
-static gboolean __mmplayer_verify_gapless_play_path(mm_player_t *player);
-static void __mmplayer_activate_next_source(mm_player_t *player, GstState target);
-static void __mmplayer_check_pipeline(mm_player_t *player);
-static gboolean __mmplayer_deactivate_selector(mm_player_t *player, MMPlayerTrackType type);
-static void __mmplayer_deactivate_old_path(mm_player_t *player);
-static int __mmplayer_gst_create_plain_text_elements(mm_player_t *player);
+static gboolean __mmplayer_verify_gapless_play_path(mmplayer_t *player);
+static void __mmplayer_activate_next_source(mmplayer_t *player, GstState target);
+static void __mmplayer_check_pipeline(mmplayer_t *player);
+static gboolean __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type);
+static void __mmplayer_deactivate_old_path(mmplayer_t *player);
+static int __mmplayer_gst_create_plain_text_elements(mmplayer_t *player);
static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar *format_name);
static void __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data);
-static void __mmplayer_audio_stream_send_data(mm_player_t *player, mm_player_audio_stream_buff_t *a_buffer);
-static void __mmplayer_initialize_storage_info(mm_player_t *player, MMPlayerPathType path_type);
+static void __mmplayer_audio_stream_send_data(mmplayer_t *player, mmplayer_audio_stream_buff_t *a_buffer);
+static void __mmplayer_initialize_storage_info(mmplayer_t *player, mmplayer_path_type_e path_type);
static int __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res, void *user_data);
-static gboolean __mmplayer_update_duration_value(mm_player_t *player);
-static gboolean __mmplayer_update_audio_attrs(mm_player_t *player, MMHandleType attrs);
-static gboolean __mmplayer_update_video_attrs(mm_player_t *player, MMHandleType attrs);
-static gboolean __mmplayer_update_bitrate_attrs(mm_player_t *player, MMHandleType attrs);
-
-static void __mmplayer_copy_uri_and_set_type(MMPlayerParseProfile *data, const char *uri, int uri_type);
-static int __mmplayer_set_mem_uri(MMPlayerParseProfile *data, char *path, void *param);
-static int __mmplayer_set_file_uri(MMPlayerParseProfile *data, const char *uri);
-
-static MMPlayerVideoStreamDataType *__mmplayer_create_stream_from_pad(GstPad *pad);
-static void __mmplayer_zerocopy_set_stride_elevation_bo(MMPlayerVideoStreamDataType *stream, GstMemory *mem);
-static gboolean __mmplayer_swcodec_set_stride_elevation(MMPlayerVideoStreamDataType *stream);
-static gboolean __mmplayer_swcodec_set_bo(mm_player_t *player, MMPlayerVideoStreamDataType *stream, GstMemory *mem);
-
-static void __mmplayer_set_pause_state(mm_player_t *player);
-static void __mmplayer_set_playing_state(mm_player_t *player);
+static gboolean __mmplayer_update_duration_value(mmplayer_t *player);
+static gboolean __mmplayer_update_audio_attrs(mmplayer_t *player, MMHandleType attrs);
+static gboolean __mmplayer_update_video_attrs(mmplayer_t *player, MMHandleType attrs);
+static gboolean __mmplayer_update_bitrate_attrs(mmplayer_t *player, MMHandleType attrs);
+
+static void __mmplayer_copy_uri_and_set_type(mmplayer_parse_profile_t *data, const char *uri, int uri_type);
+static int __mmplayer_set_mem_uri(mmplayer_parse_profile_t *data, char *path, void *param);
+static int __mmplayer_set_file_uri(mmplayer_parse_profile_t *data, const char *uri);
+
+static mmplayer_video_decoded_data_info_t *__mmplayer_create_stream_from_pad(GstPad *pad);
+static void __mmplayer_zerocopy_set_stride_elevation_bo(mmplayer_video_decoded_data_info_t *stream, GstMemory *mem);
+static gboolean __mmplayer_swcodec_set_stride_elevation(mmplayer_video_decoded_data_info_t *stream);
+static gboolean __mmplayer_swcodec_set_bo(mmplayer_t *player, mmplayer_video_decoded_data_info_t *stream, GstMemory *mem);
+
+static void __mmplayer_set_pause_state(mmplayer_t *player);
+static void __mmplayer_set_playing_state(mmplayer_t *player);
/*===========================================================================================
| |
| FUNCTION DEFINITIONS |
/* This function should be called after the pipeline goes PAUSED or higher
state. */
gboolean
-__mmplayer_update_content_attrs(mm_player_t *player, enum content_attr_flag flag)
+__mmplayer_update_content_attrs(mmplayer_t *player, enum content_attr_flag flag)
{
static gboolean has_duration = FALSE;
static gboolean has_video_attrs = FALSE;
}
MMStreamingType
-__mmplayer_get_stream_service_type(mm_player_t *player)
+__mmplayer_get_stream_service_type(mmplayer_t *player)
{
MMStreamingType streaming_type = STREAMING_SERVICE_NONE;
* it to applicaton by calling callback function
*/
void
-__mmplayer_set_state(mm_player_t *player, int state)
+__mmplayer_set_state(mmplayer_t *player, int state)
{
MMMessageParamType msg = {0, };
}
int
-__mmplayer_check_state(mm_player_t *player, enum PlayerCommandState command)
+__mmplayer_check_state(mmplayer_t *player, mmplayer_command_state_e command)
{
- MMPlayerStateType current_state = MM_PLAYER_STATE_NUM;
- MMPlayerStateType pending_state = MM_PLAYER_STATE_NUM;
+ mmplayer_state_e current_state = MM_PLAYER_STATE_NUM;
+ mmplayer_state_e pending_state = MM_PLAYER_STATE_NUM;
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
static gpointer
__mmplayer_gapless_play_thread(gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
- MMPlayerGstElement *mainbin = NULL;
+ mmplayer_t *player = (mmplayer_t *)data;
+ mmplayer_gst_element_t *mainbin = NULL;
MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
void
__mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
GstMessage *msg = NULL;
GQueue *queue = NULL;
}
gboolean
-__mmplayer_gst_remove_fakesink(mm_player_t *player, MMPlayerGstElement *fakesink)
+__mmplayer_gst_remove_fakesink(mmplayer_t *player, mmplayer_gst_element_t *fakesink)
{
GstElement *parent = NULL;
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
-
- /* if we have no fakesink. this meas we are using decodebin which doesn'
- t need to add extra fakesink */
- MMPLAYER_RETURN_VAL_IF_FAIL(fakesink, TRUE);
+ MMPLAYER_RETURN_VAL_IF_FAIL(fakesink && fakesink->gst, TRUE);
/* lock */
MMPLAYER_FSINK_LOCK(player);
- if (!fakesink->gst)
- goto ERROR;
-
/* get parent of fakesink */
parent = (GstElement *)gst_object_get_parent((GstObject *)fakesink->gst);
if (!parent) {
}
static void
-__mmplayer_gst_selector_update_start_time(mm_player_t *player, MMPlayerTrackType stream_type)
+__mmplayer_gst_selector_update_start_time(mmplayer_t *player, mmplayer_track_type_e stream_type)
{
gint64 stop_running_time = 0;
gint64 position_running_time = 0;
{
GstPadProbeReturn ret = GST_PAD_PROBE_OK;
GstEvent *event = GST_PAD_PROBE_INFO_DATA(info);
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
GstCaps *caps = NULL;
GstStructure *str = NULL;
const gchar *name = NULL;
- MMPlayerTrackType stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
+ mmplayer_track_type_e stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
gboolean caps_ret = TRUE;
if (GST_EVENT_IS_DOWNSTREAM(event) &&
/* create fakesink for audio or video path witout audiobin or videobin */
static void
-__mmplayer_gst_make_fakesink(mm_player_t *player, GstPad *pad, const gchar *name)
+__mmplayer_gst_make_fakesink(mmplayer_t *player, GstPad *pad, const gchar *name)
{
GstElement *pipeline = NULL;
GstElement *fakesink = NULL;
}
static GstElement *
-__mmplayer_gst_make_selector(mm_player_t *player, enum MainElementID elem_idx, MMPlayerTrackType stream_type)
+__mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmplayer_track_type_e stream_type)
{
GstElement *pipeline = NULL;
GstElement *selector = NULL;
pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
gst_bin_add(GST_BIN(pipeline), selector);
+ gst_object_unref(GST_OBJECT(srcpad));
+
MMPLAYER_FLEAVE();
return selector;
}
void
__mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
GstElement *selector = NULL;
GstCaps *caps = NULL;
GstStructure *str = NULL;
gboolean first_track = FALSE;
gboolean caps_ret = TRUE;
- enum MainElementID elem_idx = MMPLAYER_M_NUM;
- MMPlayerTrackType stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
+ main_element_id_e elem_idx = MMPLAYER_M_NUM;
+ mmplayer_track_type_e stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(elem && pad);
/* in case of exporting video frame, it requires the 360 video filter.
* it will be handled in _no_more_pads(). */
- if ((stype == MM_DISPLAY_SURFACE_NULL) && (!player->set_mode.media_packet_video_stream)) {
+ if ((stype == MM_DISPLAY_SURFACE_NULL) && (!player->set_mode.video_export)) {
__mmplayer_gst_make_fakesink(player, pad, name);
goto DONE;
}
}
static gboolean
-__mmplayer_create_sink_path(mm_player_t *player, GstElement *selector, MMPlayerTrackType type)
+__mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_track_type_e type)
{
GstPad *srcpad = NULL;
}
static void
-__mmplayer_set_decode_track_info(mm_player_t *player, MMPlayerTrackType type)
+__mmplayer_set_decode_track_info(mmplayer_t *player, mmplayer_track_type_e type)
{
MMHandleType attrs = 0;
gint active_index = 0;
}
static gboolean
-__mmplayer_create_audio_sink_path(mm_player_t *player, GstElement *audio_selector)
+__mmplayer_create_audio_sink_path(mmplayer_t *player, GstElement *audio_selector)
{
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
}
static gboolean
-__mmplayer_create_text_sink_path(mm_player_t *player, GstElement *text_selector)
+__mmplayer_create_text_sink_path(mmplayer_t *player, GstElement *text_selector)
{
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && text_selector, FALSE);
}
static gboolean
-__mmplayer_gst_set_queue2_buffering(mm_player_t *player)
+__mmplayer_gst_set_queue2_buffering(mmplayer_t *player)
{
gint64 dur_bytes = 0L;
static void
__mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
{
- mm_player_t *player = NULL;
+ mmplayer_t *player = NULL;
GstElement *video_selector = NULL;
GstElement *audio_selector = NULL;
GstElement *text_selector = NULL;
MMPLAYER_FENTER();
- player = (mm_player_t *)data;
+ player = (mmplayer_t *)data;
LOGD("no-more-pad signal handling");
}
static gboolean
-__mmplayer_gst_add_sinkbin_to_pipeline(mm_player_t *player, GstElement *sinkbin, GstPad *pad, gboolean reusing, gchar *sink_pad_name)
+__mmplayer_gst_add_sinkbin_to_pipeline(mmplayer_t *player, GstElement *sinkbin, GstPad *pad, gboolean reusing, gchar *sink_pad_name)
{
gboolean ret = FALSE;
GstElement *pipeline = NULL;
static void
__mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
{
- mm_player_t *player = NULL;
+ mmplayer_t *player = NULL;
GstCaps *caps = NULL;
gchar *caps_str = NULL;
GstStructure *str = NULL;
gchar *sink_pad_name = "sink";
/* check handles */
- player = (mm_player_t *)data;
+ player = (mmplayer_t *)data;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(elem && pad);
/* LOGD("detected mimetype : %s", name); */
if (strstr(name, "audio")) {
if (player->pipeline->audiobin == NULL) {
+ const gchar *audio_format = gst_structure_get_string(str, "format");
+ if (audio_format) {
+ LOGD("original audio format %s", audio_format);
+ mm_attrs_set_string_by_name(player->attrs, "content_audio_format", audio_format);
+ }
+
if (__mmplayer_gst_create_audio_sink_bin(player) != MM_ERROR_NONE) {
LOGE("failed to create audiobin. continuing without audio");
goto ERROR;
}
static gboolean
-__mmplayer_get_property_value_for_rotation(mm_player_t *player, int display_angle, int orientation, int *value)
+__mmplayer_get_property_value_for_rotation(mmplayer_t *player, int display_angle, int orientation, int *value)
{
int required_angle = 0; /* Angle required for straight view */
int rotation_angle = 0;
}
int
-__mmplayer_video_param_check_video_sink_bin(mm_player_t *player)
+__mmplayer_video_param_check_video_sink_bin(mmplayer_t *player)
{
/* check video sinkbin is created */
MMPLAYER_RETURN_VAL_IF_FAIL(player &&
}
int
-__mmplayer_get_video_angle(mm_player_t *player, int *display_angle, int *orientation)
+__mmplayer_get_video_angle(mmplayer_t *player, int *display_angle, int *orientation)
{
int display_rotation = 0;
gchar *org_orient = NULL;
}
void
-__mmplayer_video_param_set_display_rotation(mm_player_t *player)
+__mmplayer_video_param_set_display_rotation(mmplayer_t *player)
{
int rotation_value = 0;
int orientations = 0; // current supported angle values are 0, 90, 180, 270
}
void
-__mmplayer_video_param_set_display_visible(mm_player_t *player)
+__mmplayer_video_param_set_display_visible(mmplayer_t *player)
{
MMHandleType attrs = 0;
int visible = 0;
}
void
-__mmplayer_video_param_set_display_method(mm_player_t *player)
+__mmplayer_video_param_set_display_method(mmplayer_t *player)
{
MMHandleType attrs = 0;
int display_method = 0;
}
void
-__mmplayer_video_param_set_video_roi_area(mm_player_t *player)
+__mmplayer_video_param_set_video_roi_area(mmplayer_t *player)
{
MMHandleType attrs = 0;
void *handle = NULL;
}
void
-__mmplayer_video_param_set_roi_area(mm_player_t *player)
+__mmplayer_video_param_set_roi_area(mmplayer_t *player)
{
MMHandleType attrs = 0;
void *handle = NULL;
}
void
-__mmplayer_video_param_set_display_overlay(mm_player_t *player)
+__mmplayer_video_param_set_display_overlay(mmplayer_t *player)
{
MMHandleType attrs = 0;
void *handle = NULL;
}
int
-__mmplayer_update_wayland_videosink_video_param(mm_player_t *player, char *param_name)
+__mmplayer_update_wayland_videosink_video_param(mmplayer_t *player, char *param_name)
{
gboolean update_all_param = FALSE;
MMPLAYER_FENTER();
}
int
-_mmplayer_update_video_param(mm_player_t *player, char *param_name)
+_mmplayer_update_video_param(mmplayer_t *player, char *param_name)
{
MMHandleType attrs = 0;
int surface_type = 0;
_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
{
gboolean disable_overlay = FALSE;
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_FENTER();
int
_mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
gboolean disable_overlay = FALSE;
MMPLAYER_FENTER();
__mmplayer_gst_element_link_bucket(GList *element_bucket)
{
GList *bucket = element_bucket;
- MMPlayerGstElement *element = NULL;
- MMPlayerGstElement *prv_element = NULL;
+ mmplayer_gst_element_t *element = NULL;
+ mmplayer_gst_element_t *prv_element = NULL;
+ GstElement *tee_element = NULL;
gint successful_link_count = 0;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(element_bucket, -1);
- prv_element = (MMPlayerGstElement *)bucket->data;
+ prv_element = (mmplayer_gst_element_t *)bucket->data;
bucket = bucket->next;
for (; bucket; bucket = bucket->next) {
- element = (MMPlayerGstElement *)bucket->data;
+ element = (mmplayer_gst_element_t *)bucket->data;
if (element && element->gst) {
if (prv_element && prv_element->gst) {
+ if (strstr(GST_ELEMENT_NAME(element->gst), "audio-tee-queue") && strcmp(GST_ELEMENT_NAME(prv_element->gst), "audio-tee")) {
+ if (tee_element) {
+ prv_element->gst = tee_element;
+ } else {
+ LOGD("failed to make new audio branch - linking [%s] to [%s] is not supported",
+ GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
+ GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
+ return -1;
+ }
+ }
if (gst_element_link(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst))) {
LOGD("linking [%s] to [%s] success",
GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
successful_link_count++;
+ if (!strcmp(GST_ELEMENT_NAME(prv_element->gst), "audio-tee")) {
+ LOGD("keep audio-tee element for next audio pipeline branch");
+ tee_element = prv_element->gst;
+ }
} else {
LOGD("linking [%s] to [%s] failed",
GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
__mmplayer_gst_element_add_bucket_to_bin(GstBin *bin, GList *element_bucket)
{
GList *bucket = element_bucket;
- MMPlayerGstElement *element = NULL;
+ mmplayer_gst_element_t *element = NULL;
int successful_add_count = 0;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(bin, 0);
for (; bucket; bucket = bucket->next) {
- element = (MMPlayerGstElement *)bucket->data;
+ element = (mmplayer_gst_element_t *)bucket->data;
if (element && element->gst) {
if (!gst_bin_add(bin, GST_ELEMENT(element->gst))) {
static void
__mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
GstCaps *caps = NULL;
GstStructure *str = NULL;
const char *name;
return;
}
-/**
- * This function is to create audio pipeline for playing.
- *
- * @param player [in] handle of player
- *
- * @return This function returns zero on success.
- * @remark
- * @see __mmplayer_gst_create_midi_pipeline, __mmplayer_gst_create_video_sink_bin
- */
-/* macro for code readability. just for sinkbin-creation functions */
-#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket, x_player) \
- do {\
- x_bin[x_id].id = x_id;\
- x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
- if (!x_bin[x_id].gst) {\
- LOGE("failed to create %s", x_factory);\
- goto ERROR;\
- } else {\
- if (x_player->ini.set_dump_element_flag)\
- __mmplayer_add_dump_buffer_probe(x_player, x_bin[x_id].gst);\
- } \
- if (x_add_bucket)\
- element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
- } while (0);
-
void
-__mmplayer_audio_stream_clear_buffer(mm_player_t *player, gboolean send_all)
+__mmplayer_audio_stream_clear_buffer(mmplayer_t *player, gboolean send_all)
{
GList *l = NULL;
if (player->audio_stream_buff_list) {
for (l = g_list_first(player->audio_stream_buff_list); l; l = g_list_next(l)) {
- mm_player_audio_stream_buff_t *tmp = (mm_player_audio_stream_buff_t *)l->data;
+ mmplayer_audio_stream_buff_t *tmp = (mmplayer_audio_stream_buff_t *)l->data;
if (tmp) {
if (send_all) {
LOGD("[%"G_GUINT64_FORMAT"] send remained data.", tmp->channel_mask);
}
static void
-__mmplayer_audio_stream_send_data(mm_player_t *player, mm_player_audio_stream_buff_t *a_buffer)
+__mmplayer_audio_stream_send_data(mmplayer_t *player, mmplayer_audio_stream_buff_t *a_buffer)
{
- MMPlayerAudioStreamDataType audio_stream = { 0, };
+ mmplayer_audio_decoded_data_info_t audio_stream = { 0, };
MMPLAYER_FENTER();
- MMPLAYER_RETURN_IF_FAIL(player && player->audio_stream_render_cb);
+ MMPLAYER_RETURN_IF_FAIL(player && player->audio_decoded_cb);
audio_stream.bitrate = a_buffer->bitrate;
audio_stream.channel = a_buffer->channel;
audio_stream.channel_mask = a_buffer->channel_mask;
audio_stream.data_size = a_buffer->data_size;
audio_stream.data = a_buffer->pcm_data;
+ audio_stream.pcm_format = a_buffer->pcm_format;
- /* LOGD("[%"G_GUINT64_FORMAT"] send data size:%d, %p", audio_stream.channel_mask, audio_stream.data_size, player->audio_stream_cb_user_param); */
- player->audio_stream_render_cb(&audio_stream, player->audio_stream_cb_user_param);
+ /* LOGD("[%"G_GUINT64_FORMAT"] send data size:%d, %p", audio_stream.channel_mask, audio_stream.data_size, player->audio_decoded_cb_user_param); */
+ player->audio_decoded_cb(&audio_stream, player->audio_decoded_cb_user_param);
MMPLAYER_FLEAVE();
}
static void
__mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
+ const gchar *pcm_format = NULL;
gint channel = 0;
gint rate = 0;
gint depth = 0;
guint64 channel_mask = 0;
void *a_data = NULL;
gint a_size = 0;
- mm_player_audio_stream_buff_t *a_buffer = NULL;
+ mmplayer_audio_stream_buff_t *a_buffer = NULL;
GstMapInfo mapinfo = GST_MAP_INFO_INIT;
GList *l = NULL;
MMPLAYER_FENTER();
- MMPLAYER_RETURN_IF_FAIL(player && player->audio_stream_render_cb);
+ MMPLAYER_RETURN_IF_FAIL(player && player->audio_decoded_cb);
gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
a_data = mapinfo.data;
GstStructure *structure = gst_caps_get_structure(caps, 0);
/* MMPLAYER_LOG_GST_CAPS_TYPE(caps); */
+ pcm_format = gst_structure_get_string(structure, "format");
gst_structure_get_int(structure, "rate", &rate);
gst_structure_get_int(structure, "channels", &channel);
gst_structure_get_int(structure, "depth", &depth);
* The num of buffer list depends on the num of audio channels */
if (player->audio_stream_buff_list) {
for (l = g_list_first(player->audio_stream_buff_list); l; l = g_list_next(l)) {
- mm_player_audio_stream_buff_t *tmp = (mm_player_audio_stream_buff_t *)l->data;
+ mmplayer_audio_stream_buff_t *tmp = (mmplayer_audio_stream_buff_t *)l->data;
if (tmp) {
if (channel_mask == tmp->channel_mask) {
/* LOGD("[%"G_GUINT64_FORMAT"] total: %d, data: %d, buffer: %d", channel_mask, tmp->data_size, a_size, tmp->buff_size); */
}
}
- /* create new audio stream data */
- a_buffer = (mm_player_audio_stream_buff_t *)g_try_malloc0(sizeof(mm_player_audio_stream_buff_t));
+ /* create new audio stream data for newly found audio channel */
+ a_buffer = (mmplayer_audio_stream_buff_t *)g_try_malloc0(sizeof(mmplayer_audio_stream_buff_t));
if (a_buffer == NULL) {
LOGE("failed to alloc data.");
goto DONE;
a_buffer->is_little_endian = (endianness == 1234 ? true : false);
a_buffer->channel_mask = channel_mask;
a_buffer->data_size = a_size;
+ a_buffer->pcm_format = util_convert_audio_pcm_str_to_media_format_mime(pcm_format);
- if (!player->audio_stream_sink_sync) {
+ if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK) {
/* If sync is FALSE, use buffer list to reduce the IPC. */
a_buffer->buff_size = (a_size > player->ini.pcm_buffer_size) ? (a_size) : (player->ini.pcm_buffer_size);
a_buffer->pcm_data = g_try_malloc(a_buffer->buff_size);
static void
__mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
- MMPlayerGstElement *audiobin = player->pipeline->audiobin;
+ mmplayer_t *player = (mmplayer_t *)data;
+ mmplayer_gst_element_t *audiobin = player->pipeline->audiobin;
GstPad *sinkpad = NULL;
GstElement *queue = NULL, *sink = NULL;
goto ERROR;
}
- LOGE("player->audio_stream_sink_sync: %d", player->audio_stream_sink_sync);
+ LOGE("audio_extract_opt : 0x%X", player->audio_extract_opt);
gst_object_unref(sinkpad);
- g_object_set(sink, "sync", player->audio_stream_sink_sync, NULL);
+ if (!(player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK))
+ g_object_set(sink, "sync", TRUE, NULL);
g_object_set(sink, "signal-handoffs", TRUE, NULL);
+ /* keep the first sink reference only */
+ if (!audiobin[MMPLAYER_A_SINK].gst) {
+ audiobin[MMPLAYER_A_SINK].id = MMPLAYER_A_SINK;
+ audiobin[MMPLAYER_A_SINK].gst = sink;
+ }
+
gst_element_set_state(sink, GST_STATE_PAUSED);
gst_element_set_state(queue, GST_STATE_PAUSED);
G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
(gpointer)player);
+ __mmplayer_add_sink(player, sink);
+
MMPLAYER_FLEAVE();
return;
}
void
-__mmplayer_gst_set_pulsesink_property(mm_player_t *player, MMHandleType attrs)
+__mmplayer_gst_set_pulsesink_property(mmplayer_t *player)
{
#define MAX_PROPS_LEN 128
gint latency_mode = 0;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->audiobin);
- mm_attrs_get_int_by_name(attrs, "sound_stream_index", &stream_id);
- mm_attrs_get_string_by_name(attrs, "sound_stream_type", &stream_type);
+ mm_attrs_get_int_by_name(player->attrs, "sound_stream_index", &stream_id);
+ mm_attrs_get_string_by_name(player->attrs, "sound_stream_type", &stream_type);
if (!stream_type) {
LOGE("stream_type is null.");
} else {
- if (player->sound.focus_id)
- snprintf(stream_props, sizeof(stream_props) - 1, "props,media.role=%s, media.parent_id=%d, media.focus_id=%d",
- stream_type, stream_id, player->sound.focus_id);
- else
- snprintf(stream_props, sizeof(stream_props) - 1, "props,media.role=%s, media.parent_id=%d",
- stream_type, stream_id);
+ snprintf(stream_props, sizeof(stream_props) - 1, "props,media.role=%s, media.parent_id=%d",
+ stream_type, stream_id);
props = gst_structure_from_string(stream_props, NULL);
g_object_set(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "stream-properties", props, NULL);
- LOGI("stream_type[%s], stream_id[%d], focus_id[%d], result[%s].",
- stream_type, stream_id, player->sound.focus_id, stream_props);
+ LOGI("stream_type[%s], stream_id[%d], result[%s].", stream_type, stream_id, stream_props);
gst_structure_free(props);
}
- mm_attrs_get_int_by_name(attrs, "sound_latency_mode", &latency_mode);
+ mm_attrs_get_int_by_name(player->attrs, "sound_latency_mode", &latency_mode);
switch (latency_mode) {
case AUDIO_LATENCY_MODE_LOW:
}
void
-__mmplayer_gst_set_openalsink_property(mm_player_t *player)
+__mmplayer_gst_set_openalsink_property(mmplayer_t *player)
{
- MMPlayerGstElement *audiobin = NULL;
+ mmplayer_gst_element_t *audiobin = NULL;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->audiobin);
}
static int
-__mmplayer_gst_fill_audio_bucket(mm_player_t *player, GList **bucket)
+__mmplayer_gst_make_audio_playback_sink(mmplayer_t *player, GList **bucket)
{
- MMPlayerGstElement *audiobin = NULL;
- MMHandleType attrs = 0;
- GList *element_bucket = NULL;
- GstCaps *acaps = NULL;
+ mmplayer_gst_element_t *audiobin = NULL;
GstPad *sink_pad = NULL;
+ GstCaps *acaps = NULL;
+ gint channels = 0;
int pitch_control = 0;
double pitch_value = 1.0;
player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
audiobin = player->pipeline->audiobin;
- attrs = MMPLAYER_GET_ATTRS(player);
- if (player->build_audio_offload) { /* skip all the audio filters */
- LOGD("create audio offload sink : %s", player->ini.audio_offload_sink_element);
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audio_offload_sink_element, "audiosink", TRUE, player);
- g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE, NULL);
- __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
- goto DONE;
- }
+ LOGD("make element for normal audio playback");
+
+ /* audio bin structure for playback. {} means optional.
+ optional : pitch, audioeq, custom audioeq, openalsink for 360 audio content
- /* pitch */
+ * src - ... - {aconv - pitch} - aconv - rgvolume - resample - volume -
+ {audioeq} - {custom audioeq} - pulsesink or {aconv - capsfilter - openalsink}
+ */
+
+ /* for pitch control */
mm_attrs_multiple_get(player->attrs, NULL,
MM_PLAYER_PITCH_CONTROL, &pitch_control,
MM_PLAYER_PITCH_VALUE, &pitch_value,
gst_object_unref(factory);
/* converter */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_PITCH, "audioconvert", "audio convert pitch", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_PITCH, "audioconvert", "audio convert pitch", *bucket, player);
/* pitch */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_PITCH, "pitch", "audio pitch", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_PITCH, "pitch", "audio pitch", *bucket, player);
g_object_set(G_OBJECT(audiobin[MMPLAYER_A_PITCH].gst), "pitch", (gdouble)pitch_value, NULL);
} else {
LOGW("there is no pitch element");
}
/* converter */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audio converter", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audio converter", *bucket, player);
/* replaygain volume */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RGVOL, "rgvolume", "audio rgvolume", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RGVOL, "rgvolume", "audio rgvolume", *bucket, player);
if (player->sound.rg_enable)
g_object_set(G_OBJECT(audiobin[MMPLAYER_A_RGVOL].gst), "enable-rgvolume", TRUE, NULL);
else
g_object_set(G_OBJECT(audiobin[MMPLAYER_A_RGVOL].gst), "enable-rgvolume", FALSE, NULL);
/* resampler */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER, player->ini.audioresampler_element, "audio resampler", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER, player->ini.audioresampler_element, "audio resampler", *bucket, player);
- if (player->audio_stream_render_cb) { /* pcm extraction only, no sound output */
- gchar *dst_format = NULL;
- int dst_len = 0;
- int dst_samplerate = 0;
- int dst_channels = 0;
- GstCaps *caps = NULL;
- char *caps_str = NULL;
+ /* for logical volume control */
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", *bucket, player);
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
- /* get conf. values */
- mm_attrs_multiple_get(player->attrs, NULL,
- "pcm_audioformat", &dst_format, &dst_len,
- "pcm_extraction_samplerate", &dst_samplerate,
- "pcm_extraction_channels", &dst_channels,
- NULL);
+ if (player->sound.mute) {
+ LOGD("mute enabled");
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
+ }
- LOGD("pcm info - format: %s(%d), samplerate : %d, channel: %d", dst_format, dst_len, dst_samplerate, dst_channels);
+ mm_attrs_get_int_by_name(player->attrs, "content_audio_channels", &channels);
- /* capsfilter */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audio capsfilter", TRUE, player);
- caps = gst_caps_new_simple("audio/x-raw",
- "format", G_TYPE_STRING, dst_format,
- "rate", G_TYPE_INT, dst_samplerate,
- "channels", G_TYPE_INT, dst_channels,
- NULL);
+ /* audio effect element. if audio effect is enabled */
+ if ((strcmp(player->ini.audioeffect_element, ""))
+ && (channels <= 2)
+ && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, player->ini.audioeffect_element, "audio effect filter", *bucket, player);
- caps_str = gst_caps_to_string(caps);
- LOGD("new caps : %s", caps_str);
+ LOGD("audio effect config. bypass = %d, effect type = %d", player->bypass_audio_effect, player->audio_effect_info.effect_type);
- g_object_set(GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL);
+ if ((!player->bypass_audio_effect)
+ && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
+ if (player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM) {
+ if (!_mmplayer_audio_effect_custom_apply(player))
+ LOGI("apply audio effect(custom) setting success");
+ }
+ }
- /* clean */
- gst_caps_unref(caps);
- MMPLAYER_FREEIF(caps_str);
+ if ((strcmp(player->ini.audioeffect_element_custom, ""))
+ && (player->set_mode.rich_audio)) {
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER_SEC, player->ini.audioeffect_element_custom, "audio effect filter custom", *bucket, player);
+ }
+ }
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_DEINTERLEAVE, "deinterleave", "deinterleave", TRUE, player);
+ /* create audio sink */
+ LOGD("spherical %d, channels %d, ambisonic type %d, format %d, order %d",
+ player->is_content_spherical, channels, player->video360_metadata.ambisonic_type,
+ player->video360_metadata.ambisonic_format, player->video360_metadata.ambisonic_order);
- g_object_set(G_OBJECT(audiobin[MMPLAYER_A_DEINTERLEAVE].gst), "keep-positions", TRUE, NULL);
+ /* Note: qtdemux converts audio metadata defaults to openalsink defaults. */
+ if (player->is_360_feature_enabled &&
+ player->is_content_spherical &&
+ channels == 4 &&
+ player->video360_metadata.ambisonic_type == MMFILE_AMBISONIC_TYPE_PERIPHONIC &&
+ player->video360_metadata.ambisonic_format == MMFILE_AMBISONIC_FORMAT_AMB &&
+ player->video360_metadata.ambisonic_order == MMFILE_AMBISONIC_ORDER_FOA) {
- /* raw pad handling signal, audiosink will be added after getting signal */
- __mmplayer_add_signal_connection(player, G_OBJECT(audiobin[MMPLAYER_A_DEINTERLEAVE].gst),
- MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(__mmplayer_gst_audio_deinterleave_pad_added), (gpointer)player);
+ strncpy(player->ini.audiosink_element, "openalsink", PLAYER_INI_MAX_STRLEN - 1);
+
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_BFORMAT, "audioconvert", "audio-converter-bformat", *bucket, player);
+
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_360, "capsfilter", "audio-caps-filter", *bucket, player);
+ acaps = gst_caps_from_string(SPATIAL_AUDIO_CAPS);
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_CAPS_360].gst), "caps", acaps, NULL);
+ gst_caps_unref(acaps);
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "openalsink", "audiosink", *bucket, player);
+
+ player->is_openal_plugin_used = TRUE;
} else {
+ if (player->is_360_feature_enabled && player->is_content_spherical)
+ LOGW("Audio track isn't of the ambisonic type and can't be played back as a spatial sound.");
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audiosink_element, "audiosink", *bucket, player);
+ }
- /* normal playback */
- gint channels = 0;
+ if ((MMPLAYER_IS_RTSP_STREAMING(player)) ||
+ (player->videodec_linked && player->ini.use_system_clock)) {
+ LOGD("system clock will be used.");
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "provide-clock", FALSE, NULL);
+ }
- /* for logical volume control */
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", TRUE, player);
- g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
+ if (g_strrstr(player->ini.audiosink_element, "pulsesink"))
+ __mmplayer_gst_set_pulsesink_property(player);
+ else if (g_strrstr(player->ini.audiosink_element, "openalsink"))
+ __mmplayer_gst_set_openalsink_property(player);
- if (player->sound.mute) {
- LOGD("mute enabled");
- g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
- }
+ /* qos on */
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL); /* qos on */
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "slave-method", GST_AUDIO_BASE_SINK_SLAVE_NONE, NULL);
- mm_attrs_get_int_by_name(player->attrs, "content_audio_channels", &channels);
+ sink_pad = gst_element_get_static_pad(audiobin[MMPLAYER_A_SINK].gst, "sink");
+ __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+ "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
+ gst_object_unref(GST_OBJECT(sink_pad));
- /* audio effect element. if audio effect is enabled */
- if ((strcmp(player->ini.audioeffect_element, ""))
- && (channels <= 2)
- && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, player->ini.audioeffect_element, "audio effect filter", TRUE, player);
+ __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
- LOGD("audio effect config. bypass = %d, effect type = %d", player->bypass_audio_effect, player->audio_effect_info.effect_type);
+ MMPLAYER_FLEAVE();
+ return MM_ERROR_NONE;
- if ((!player->bypass_audio_effect)
- && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
- if (player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM) {
- if (!_mmplayer_audio_effect_custom_apply(player))
- LOGI("apply audio effect(custom) setting success");
- }
- }
+ERROR: /* MMPLAYER_CREATE_ELEMENT */
+ MMPLAYER_FLEAVE();
+ return MM_ERROR_PLAYER_INTERNAL;
+}
- if ((strcmp(player->ini.audioeffect_element_custom, ""))
- && (player->set_mode.rich_audio))
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER_SEC, player->ini.audioeffect_element_custom, "audio effect filter custom", TRUE, player);
- }
+static int
+__mmplayer_gst_make_audio_extract_sink(mmplayer_t *player, GList **bucket)
+{
+ mmplayer_gst_element_t *audiobin = NULL;
+ enum audio_element_id extract_sink_id = MMPLAYER_A_SINK;
- /* create audio sink */
- LOGD("360 spherical %d, channels %d, ambisonic type %d, format %d, order %d",
- player->is_content_spherical, channels, player->video360_metadata.ambisonic_type,
- player->video360_metadata.ambisonic_format, player->video360_metadata.ambisonic_order);
+ gchar *dst_format = NULL;
+ int dst_len = 0;
+ int dst_samplerate = 0;
+ int dst_channels = 0;
+ GstCaps *caps = NULL;
+ char *caps_str = NULL;
- /* Note: qtdemux converts audio metadata defaults to openalsink defaults. */
- if (player->is_360_feature_enabled &&
- player->is_content_spherical &&
- channels == 4 &&
- player->video360_metadata.ambisonic_type == MMFILE_AMBISONIC_TYPE_PERIPHONIC &&
- player->video360_metadata.ambisonic_format == MMFILE_AMBISONIC_FORMAT_AMB &&
- player->video360_metadata.ambisonic_order == MMFILE_AMBISONIC_ORDER_FOA) {
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+ player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
- strncpy(player->ini.audiosink_element, "openalsink", PLAYER_INI_MAX_STRLEN - 1);
+ audiobin = player->pipeline->audiobin;
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_BFORMAT, "audioconvert", "audio-converter-bformat", TRUE, player);
+ LOGD("make element for audio extract, option = 0x%X", player->audio_extract_opt);
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_360, "capsfilter", "audio-caps-filter", TRUE, player);
- acaps = gst_caps_from_string(SPATIAL_AUDIO_CAPS);
- g_object_set(G_OBJECT(audiobin[MMPLAYER_A_CAPS_360].gst), "caps", acaps, NULL);
- gst_caps_unref(acaps);
+ /* audio bin structure according to the mmplayer_audio_extract_opt_e.
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "openalsink", "audiosink", TRUE, player);
+ [case 1] extract interleave audio pcm without playback
+ : MM_PLAYER_AUDIO_EXTRACT_DEFAULT (sync)
+ MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK (non sync)
- player->is_openal_plugin_used = TRUE;
- } else {
- if (player->is_360_feature_enabled && player->is_content_spherical)
- LOGW("Audio track isn't of the ambisonic type and can't be played back as a spatial sound.");
- MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audiosink_element, "audiosink", TRUE, player);
- }
+ * src - ... - aconv - resample - capsfilter - fakesink (sync or not)
+
+ [case 2] deinterleave for each channel without playback
+ : MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE (sync)
+ MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_AND_DEINTERLEAVE (non sync)
+
+ * src - ... - aconv - resample - capsfilter - deinterleave - fakesink (sync or not)
+ - fakesink (sync or not)
+ - ... (sync or not)
+
+ [case 3] [case 1(sync only)] + playback
+ : MM_PLAYER_AUDIO_EXTRACT_WITH_PLAYBACK
+
+ * src - ... - tee - queue1 - playback path
+ - queue2 - [case1 pipeline with sync]
+
+ [case 4] [case 2(sync only)] + playback
+ : MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE_WITH_PLAYBACK
+
+ * src - ... - tee - queue1 - playback path
+ - queue2 - [case2 pipeline with sync]
+
+ */
+
+ /* 1. create tee and playback path
+ 'tee' should be added at first to copy the decoded stream
+ */
+ if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_WITH_PLAYBACK) {
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE, "tee", "audio-tee", *bucket, player);
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_TEE].gst), "num-src-pads", 2, NULL);
- if ((MMPLAYER_IS_RTSP_STREAMING(player)) ||
- (player->videodec_linked && player->ini.use_system_clock)) {
- LOGD("system clock will be used.");
- g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "provide-clock", FALSE, NULL);
+ /* tee - path 1 : for playback path */
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE_Q1, "queue", "audio-tee-queue1", *bucket, player);
+ __mmplayer_gst_make_audio_playback_sink(player, bucket);
+
+ /* tee - path 2 : for extract path */
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE_Q2, "queue", "audio-tee-queue2", *bucket, player);
+ extract_sink_id = MMPLAYER_A_EXTRACT_SINK; /* there is another playback sink */
+ }
+
+ /* if there is tee, 'tee - path 2' is linked here */
+ /* converter */
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_CONV, "audioconvert", "audio-ext-conv", *bucket, player);
+
+ /* resampler */
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_RESAMPLER, player->ini.audioresampler_element, "audio-ext-resampler", *bucket, player);
+
+ /* 2. decide the extract pcm format */
+ mm_attrs_multiple_get(player->attrs, NULL,
+ "pcm_audioformat", &dst_format, &dst_len,
+ "pcm_extraction_samplerate", &dst_samplerate,
+ "pcm_extraction_channels", &dst_channels,
+ NULL);
+
+ LOGD("required extract pcm format - format: %s(%d), samplerate : %d, channel: %d",
+ dst_format, dst_len, dst_samplerate, dst_channels);
+
+ if (dst_format == NULL || dst_len == 0 || dst_samplerate == 0 || dst_channels == 0) {
+ mm_attrs_multiple_get(player->attrs, NULL,
+ "content_audio_format", &dst_format, &dst_len, /* get string and len */
+ "content_audio_samplerate", &dst_samplerate,
+ "content_audio_channels", &dst_channels,
+ NULL);
+
+ LOGD("apply the decoded pcm format - format: %s(%d), samplerate : %d, channel: %d",
+ dst_format, dst_len, dst_samplerate, dst_channels);
+
+ /* If there is no enough information, set it to platform default value. */
+ if (dst_format == NULL || util_convert_audio_pcm_str_to_media_format_mime(dst_format) == MEDIA_FORMAT_MAX) {
+ LOGD("set platform default format");
+ dst_format = DEFAULT_PCM_OUT_FORMAT;
}
+ if (dst_samplerate <= 0) dst_samplerate = DEFAULT_PCM_OUT_SAMPLERATE;
+ if (dst_channels <= 0) dst_channels = DEFAULT_PCM_OUT_CHANNEL;
+ }
- if (g_strrstr(player->ini.audiosink_element, "pulsesink"))
- __mmplayer_gst_set_pulsesink_property(player, attrs);
- else if (g_strrstr(player->ini.audiosink_element, "openalsink"))
- __mmplayer_gst_set_openalsink_property(player);
+ /* 3. create capsfilter */
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_CAPS, "capsfilter", "audio-ext-caps", *bucket, player);
+ caps = gst_caps_new_simple("audio/x-raw",
+ "format", G_TYPE_STRING, dst_format,
+ "rate", G_TYPE_INT, dst_samplerate,
+ "channels", G_TYPE_INT, dst_channels,
+ NULL);
- /* qos on */
- g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL); /* qos on */
- g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "slave-method", GST_AUDIO_BASE_SINK_SLAVE_NONE, NULL);
+ caps_str = gst_caps_to_string(caps);
+ LOGD("new caps : %s", caps_str);
- sink_pad = gst_element_get_static_pad(audiobin[MMPLAYER_A_SINK].gst, "sink");
- __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
- "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
- gst_object_unref(GST_OBJECT(sink_pad));
+ g_object_set(GST_ELEMENT(audiobin[MMPLAYER_A_EXTRACT_CAPS].gst), "caps", caps, NULL);
+
+ /* clean */
+ gst_caps_unref(caps);
+ MMPLAYER_FREEIF(caps_str);
+
+ /* 4-1. create deinterleave to extract pcm for each channel */
+ if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE) {
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_DEINTERLEAVE, "deinterleave", "deinterleave", *bucket, player);
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_EXTRACT_DEINTERLEAVE].gst), "keep-positions", TRUE, NULL);
+
+ /* audiosink will be added after getting signal for each channel */
+ __mmplayer_add_signal_connection(player, G_OBJECT(audiobin[MMPLAYER_A_EXTRACT_DEINTERLEAVE].gst),
+ MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(__mmplayer_gst_audio_deinterleave_pad_added), (gpointer)player);
+ } else {
+ /* 4-2. create fakesink to extract interlevaed pcm */
+ LOGD("add audio fakesink for interleaved audio");
+ MMPLAYER_CREATE_ELEMENT(audiobin, extract_sink_id, "fakesink", "fakeaudiosink", *bucket, player);
+ if (!(player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK))
+ g_object_set(G_OBJECT(audiobin[extract_sink_id].gst), "sync", TRUE, NULL);
+ g_object_set(G_OBJECT(audiobin[extract_sink_id].gst), "signal-handoffs", TRUE, NULL);
+
+ __mmplayer_add_signal_connection(player,
+ G_OBJECT(audiobin[extract_sink_id].gst),
+ MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+ "handoff",
+ G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
+ (gpointer)player);
+
+ __mmplayer_add_sink(player, audiobin[extract_sink_id].gst);
+ }
+
+ MMPLAYER_FLEAVE();
+ return MM_ERROR_NONE;
+
+ERROR: /* MMPLAYER_CREATE_ELEMENT */
+ MMPLAYER_FLEAVE();
+ return MM_ERROR_PLAYER_INTERNAL;
+}
+
+static int
+__mmplayer_gst_make_audio_bin_element(mmplayer_t *player, GList **bucket)
+{
+ int ret = MM_ERROR_NONE;
+ mmplayer_gst_element_t *audiobin = NULL;
+ GList *element_bucket = NULL;
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+ player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+ audiobin = player->pipeline->audiobin;
+
+ if (player->build_audio_offload) { /* skip all the audio filters */
+ LOGD("create audio offload sink : %s", player->ini.audio_offload_sink_element);
+
+ MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audio_offload_sink_element, "audiosink", element_bucket, player);
+ g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE,
+ "volume", player->sound.volume, "mute", player->sound.mute, NULL);
__mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
+ goto DONE;
}
+ /* FIXME: need to mention the supportable condition at API reference */
+ if (player->audio_decoded_cb && (!MMPLAYER_IS_RTSP_STREAMING(player)))
+ ret = __mmplayer_gst_make_audio_extract_sink(player, &element_bucket);
+ else
+ ret = __mmplayer_gst_make_audio_playback_sink(player, &element_bucket);
+
+ if (ret != MM_ERROR_NONE)
+ goto ERROR;
DONE:
+ LOGD("success to make audio bin element");
*bucket = element_bucket;
MMPLAYER_FLEAVE();
return MM_ERROR_NONE;
ERROR:
+ LOGE("failed to make audio bin element");
g_list_free(element_bucket);
*bucket = NULL;
}
static int
-__mmplayer_gst_create_audio_sink_bin(mm_player_t *player)
+__mmplayer_gst_create_audio_sink_bin(mmplayer_t *player)
{
- MMPlayerGstElement *first_element = NULL;
- MMPlayerGstElement *audiobin = NULL;
+ mmplayer_gst_element_t *first_element = NULL;
+ mmplayer_gst_element_t *audiobin = NULL;
GstPad *pad = NULL;
GstPad *ghostpad = NULL;
GList *element_bucket = NULL;
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
/* alloc handles */
- audiobin = (MMPlayerGstElement *)g_try_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_A_NUM);
+ audiobin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_A_NUM);
if (!audiobin) {
LOGE("failed to allocate memory for audiobin");
return MM_ERROR_PLAYER_NO_FREE_SPACE;
player->pipeline->audiobin = audiobin;
/* create audio filters and audiosink */
- if (__mmplayer_gst_fill_audio_bucket(player, &element_bucket) != MM_ERROR_NONE)
+ if (__mmplayer_gst_make_audio_bin_element(player, &element_bucket) != MM_ERROR_NONE)
goto ERROR;
/* adding created elements to bin */
goto ERROR;
/* get first element's sinkpad for creating ghostpad */
- first_element = (MMPlayerGstElement *)element_bucket->data;
+ first_element = (mmplayer_gst_element_t *)element_bucket->data;
if (!first_element) {
LOGE("failed to get first elem");
goto ERROR;
}
int
-_mmplayer_video_stream_release_bo(mm_player_t *player, void *bo)
+_mmplayer_video_stream_release_bo(mmplayer_t *player, void *bo)
{
int ret = MM_ERROR_NONE;
GList *l = NULL;
if (player->video_bo_list) {
for (l = g_list_first(player->video_bo_list); l; l = g_list_next(l)) {
- mm_player_video_bo_info_t *tmp = (mm_player_video_bo_info_t *)l->data;
+ mmplayer_video_bo_info_t *tmp = (mmplayer_video_bo_info_t *)l->data;
if (tmp && tmp->bo == bo) {
tmp->used = FALSE;
LOGD("release bo %p", bo);
}
static void
-__mmplayer_video_stream_destroy_bo_list(mm_player_t *player)
+__mmplayer_video_stream_destroy_bo_list(mmplayer_t *player)
{
GList *l = NULL;
if (player->video_bo_list) {
LOGD("destroy video_bo_list : %d", g_list_length(player->video_bo_list));
for (l = g_list_first(player->video_bo_list); l; l = g_list_next(l)) {
- mm_player_video_bo_info_t *tmp = (mm_player_video_bo_info_t *)l->data;
+ mmplayer_video_bo_info_t *tmp = (mmplayer_video_bo_info_t *)l->data;
if (tmp) {
if (tmp->bo)
tbm_bo_unref(tmp->bo);
}
static void *
-__mmplayer_video_stream_get_bo(mm_player_t *player, int size)
+__mmplayer_video_stream_get_bo(mmplayer_t *player, int size)
{
GList *l = NULL;
MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
}
for (; idx < player->ini.num_of_video_bo; idx++) {
- mm_player_video_bo_info_t *bo_info = g_new(mm_player_video_bo_info_t, 1);
+ mmplayer_video_bo_info_t *bo_info = g_new(mmplayer_video_bo_info_t, 1);
if (!bo_info) {
LOGE("Fail to alloc bo_info.");
break;
while (TRUE) {
/* get bo from list*/
for (l = g_list_first(player->video_bo_list); l; l = g_list_next(l)) {
- mm_player_video_bo_info_t *tmp = (mm_player_video_bo_info_t *)l->data;
+ mmplayer_video_bo_info_t *tmp = (mmplayer_video_bo_info_t *)l->data;
if (tmp && (tmp->used == FALSE)) {
LOGD("found bo %p to use", tmp->bo);
tmp->used = TRUE;
static void
__mmplayer_video_stream_decoded_preroll_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
MMPLAYER_FENTER();
- MMPLAYER_RETURN_IF_FAIL(player && player->video_stream_cb);
+ MMPLAYER_RETURN_IF_FAIL(player && player->video_decoded_cb);
/* send prerolled pkt */
player->video_stream_prerolled = false;
static void
__mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
- MMPlayerVideoStreamDataType *stream = NULL;
+ mmplayer_t *player = (mmplayer_t *)data;
+ mmplayer_video_decoded_data_info_t *stream = NULL;
GstMemory *mem = NULL;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player);
- MMPLAYER_RETURN_IF_FAIL(player->video_stream_cb);
+ MMPLAYER_RETURN_IF_FAIL(player->video_decoded_cb);
if (player->video_stream_prerolled) {
player->video_stream_prerolled = false;
/* check zero-copy */
if (player->set_mode.video_zc &&
- player->set_mode.media_packet_video_stream &&
+ player->set_mode.video_export &&
gst_is_tizen_memory(mem)) {
__mmplayer_zerocopy_set_stride_elevation_bo(stream, mem);
stream->internal_buffer = gst_buffer_ref(buffer);
goto ERROR;
}
- if (!player->video_stream_cb(stream, player->video_stream_cb_user_param)) {
- LOGE("failed to send video stream data.");
+ if (!player->video_decoded_cb(stream, player->video_decoded_cb_user_param)) {
+ LOGE("failed to send video decoded data.");
goto ERROR;
}
}
static void
-__mmplayer_gst_set_video360_property(mm_player_t *player)
+__mmplayer_gst_set_video360_property(mmplayer_t *player)
{
- MMPlayerGstElement *videobin = NULL;
+ mmplayer_gst_element_t *videobin = NULL;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->videobin);
}
static int
-__mmplayer_gst_create_video_filters(mm_player_t *player, MMDisplaySurfaceType surface_type, GList **bucket)
+__mmplayer_gst_create_video_filters(mmplayer_t *player, MMDisplaySurfaceType surface_type, GList **bucket)
{
gchar *video_csc = "videoconvert"; /* default colorspace converter */
GList *element_bucket = NULL;
/* create video360 filter */
if (player->is_360_feature_enabled && player->is_content_spherical) {
LOGD("create video360 element");
- MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_360, "video360", "video-360", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_360, "video360", "video-360", element_bucket, player);
__mmplayer_gst_set_video360_property(player);
goto EXIT;
}
/* in case of sw codec & overlay surface type, except 360 playback.
* if libav video decoder is selected, videoconvert is required to render the shm wl-buffer which support RGB only via tizenwlsink. */
LOGD("create video converter: %s", video_csc);
- MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", element_bucket, player);
EXIT:
*bucket = element_bucket;
}
static gchar *
-__mmplayer_get_videosink_factory_name(mm_player_t *player, MMDisplaySurfaceType surface_type)
+__mmplayer_get_videosink_factory_name(mmplayer_t *player, MMDisplaySurfaceType surface_type)
{
gchar *factory_name = NULL;
}
static int
-__mmplayer_gst_set_videosink_property(mm_player_t *player, MMDisplaySurfaceType surface_type)
+__mmplayer_gst_set_videosink_property(mmplayer_t *player, MMDisplaySurfaceType surface_type)
{
gchar *factory_name = NULL;
- MMPlayerGstElement *videobin = NULL;
+ mmplayer_gst_element_t *videobin = NULL;
MMHandleType attrs;
int gapless = 0;
g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "enable-last-sample", FALSE, NULL);
}
- if (player->set_mode.media_packet_video_stream) {
+ if (player->set_mode.video_export) {
int enable = 0;
mm_attrs_get_int_by_name(player->attrs, "enable_video_decoded_cb", &enable);
if (enable || (surface_type == MM_DISPLAY_SURFACE_REMOTE) || (surface_type == MM_DISPLAY_SURFACE_NULL))
* - video overlay surface(arm/x86) : tizenwlsink
*/
static int
-__mmplayer_gst_create_video_sink_bin(mm_player_t *player, GstCaps *caps, MMDisplaySurfaceType surface_type)
+__mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDisplaySurfaceType surface_type)
{
GstPad *pad = NULL;
GList *element_bucket = NULL;
- MMPlayerGstElement *first_element = NULL;
- MMPlayerGstElement *videobin = NULL;
+ mmplayer_gst_element_t *first_element = NULL;
+ mmplayer_gst_element_t *videobin = NULL;
gchar *videosink_factory_name = NULL;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
/* alloc handles */
- videobin = (MMPlayerGstElement *)g_try_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM);
+ videobin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_V_NUM);
if (!videobin)
return MM_ERROR_PLAYER_NO_FREE_SPACE;
goto ERROR;
videosink_factory_name = __mmplayer_get_videosink_factory_name(player, surface_type);
- MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_factory_name, "videosink", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_factory_name, "videosink", element_bucket, player);
/* additional setting for sink plug-in */
if (__mmplayer_gst_set_videosink_property(player, surface_type) != MM_ERROR_NONE) {
}
/* get first element's sinkpad for creating ghostpad */
- first_element = (MMPlayerGstElement *)element_bucket->data;
+ first_element = (mmplayer_gst_element_t *)element_bucket->data;
if (!first_element) {
LOGE("failed to get first element from bucket");
goto ERROR;
}
static int
-__mmplayer_gst_create_plain_text_elements(mm_player_t *player)
+__mmplayer_gst_create_plain_text_elements(mmplayer_t *player)
{
GList *element_bucket = NULL;
- MMPlayerGstElement *textbin = player->pipeline->textbin;
+ mmplayer_gst_element_t *textbin = player->pipeline->textbin;
- MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_QUEUE, "queue", "text_queue", TRUE, player);
- MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_IDENTITY, "identity", "text_identity", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_QUEUE, "queue", "text_queue", element_bucket, player);
+ MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_IDENTITY, "identity", "text_identity", element_bucket, player);
g_object_set(G_OBJECT(textbin[MMPLAYER_T_IDENTITY].gst),
"signal-handoffs", FALSE,
NULL);
- MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", TRUE, player);
+ MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", element_bucket, player);
__mmplayer_add_signal_connection(player,
G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst),
MM_PLAYER_SIGNAL_TYPE_TEXTBIN,
}
static int
-__mmplayer_gst_create_text_sink_bin(mm_player_t *player)
+__mmplayer_gst_create_text_sink_bin(mmplayer_t *player)
{
- MMPlayerGstElement *textbin = NULL;
+ mmplayer_gst_element_t *textbin = NULL;
GList *element_bucket = NULL;
int surface_type = 0;
gint i = 0;
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
/* alloc handles */
- textbin = (MMPlayerGstElement *)g_try_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_T_NUM);
+ textbin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_T_NUM);
if (!textbin) {
LOGE("failed to allocate memory for textbin");
return MM_ERROR_PLAYER_NO_FREE_SPACE;
}
static int
-__mmplayer_gst_create_text_pipeline(mm_player_t *player)
+__mmplayer_gst_create_text_pipeline(mmplayer_t *player)
{
- MMPlayerGstElement *mainbin = NULL;
- MMPlayerGstElement *textbin = NULL;
+ mmplayer_gst_element_t *mainbin = NULL;
+ mmplayer_gst_element_t *textbin = NULL;
MMHandleType attrs = 0;
GstElement *subsrc = NULL;
GstElement *subparse = NULL;
gboolean
__mmplayer_update_subtitle(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
MMMessageParamType msg = {0, };
GstClockTime duration = 0;
gpointer text = NULL;
gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
text = mapinfo.data;
text_size = mapinfo.size;
- duration = GST_BUFFER_DURATION(buffer);
if (player->set_mode.subtitle_off) {
LOGD("subtitle is OFF.");
}
msg.data = (void *)text;
+
+ duration = GST_BUFFER_DURATION(buffer);
+
+ if (!GST_CLOCK_TIME_IS_VALID(duration)) {
+ if (player->duration > GST_BUFFER_PTS(buffer))
+ duration = player->duration - GST_BUFFER_PTS(buffer);
+ else
+ duration = 0;
+ LOGI("subtitle duration is invalid, subtitle duration change "
+ "GST_CLOCK_TIME_NONE -> %" GST_TIME_FORMAT, GST_TIME_ARGS(duration));
+ }
msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
LOGD("update subtitle : [%ld msec] %s", msg.subtitle.duration, (char *)msg.data);
static GstPadProbeReturn
__mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
{
- mm_player_t *player = (mm_player_t *)u_data;
+ mmplayer_t *player = (mmplayer_t *)u_data;
GstClockTime cur_timestamp = 0;
gint64 adjusted_timestamp = 0;
GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
}
static int
-__mmplayer_gst_adjust_subtitle_position(mm_player_t *player, int format, int position)
+__mmplayer_gst_adjust_subtitle_position(mmplayer_t *player, int position)
{
MMPLAYER_FENTER();
return MM_ERROR_NONE;
}
- switch (format) {
- case MM_PLAYER_POS_FORMAT_TIME:
- {
- /* check current postion */
- player->adjust_subtitle_pos = position;
+ /* check current postion */
+ player->adjust_subtitle_pos = position;
- LOGD("save adjust_subtitle_pos in player") ;
- }
- break;
-
- default:
- {
- LOGW("invalid format.");
- MMPLAYER_FLEAVE();
- return MM_ERROR_INVALID_ARGUMENT;
- }
- }
+ LOGD("save adjust_subtitle_pos in player");
MMPLAYER_FLEAVE();
* @see
*/
static int
-__mmplayer_gst_create_pipeline(mm_player_t *player)
+__mmplayer_gst_create_pipeline(mmplayer_t *player)
{
int ret = MM_ERROR_NONE;
- MMPlayerGstElement *mainbin = NULL;
+ mmplayer_gst_element_t *mainbin = NULL;
MMHandleType attrs = 0;
MMPLAYER_FENTER();
goto INIT_ERROR;
}
- player->pipeline = (MMPlayerGstPipelineInfo *)g_malloc0(sizeof(MMPlayerGstPipelineInfo));
+ player->pipeline = (mmplayer_pipeline_info_t *)g_malloc0(sizeof(mmplayer_pipeline_info_t));
if (player->pipeline == NULL)
goto INIT_ERROR;
/* create mainbin */
- mainbin = (MMPlayerGstElement *)g_try_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
+ mainbin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_M_NUM);
if (mainbin == NULL)
goto INIT_ERROR;
}
static void
-__mmplayer_reset_gapless_state(mm_player_t *player)
+__mmplayer_reset_gapless_state(mmplayer_t *player)
{
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player
&& player->pipeline->audiobin
&& player->pipeline->audiobin[MMPLAYER_A_BIN].gst);
- memset(&player->gapless, 0, sizeof(mm_player_gapless_t));
+ memset(&player->gapless, 0, sizeof(mmplayer_gapless_t));
MMPLAYER_FLEAVE();
return;
}
static int
-__mmplayer_gst_destroy_pipeline(mm_player_t *player)
+__mmplayer_gst_destroy_pipeline(mmplayer_t *player)
{
gint timeout = 0;
int ret = MM_ERROR_NONE;
/* cleanup gst stuffs */
if (player->pipeline) {
- MMPlayerGstElement *mainbin = player->pipeline->mainbin;
+ mmplayer_gst_element_t *mainbin = player->pipeline->mainbin;
GstTagList *tag_list = player->pipeline->tag_list;
/* first we need to disconnect all signal hander */
__mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_ALL);
if (mainbin) {
- MMPlayerGstElement *audiobin = player->pipeline->audiobin;
- MMPlayerGstElement *videobin = player->pipeline->videobin;
- MMPlayerGstElement *textbin = player->pipeline->textbin;
+ mmplayer_gst_element_t *audiobin = player->pipeline->audiobin;
+ mmplayer_gst_element_t *videobin = player->pipeline->videobin;
+ mmplayer_gst_element_t *textbin = player->pipeline->textbin;
GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
gst_bus_set_sync_handler(bus, NULL, NULL, NULL);
gst_object_unref(bus);
}
static int
-__mmplayer_gst_realize(mm_player_t *player)
+__mmplayer_gst_realize(mmplayer_t *player)
{
gint timeout = 0;
int ret = MM_ERROR_NONE;
}
static int
-__mmplayer_gst_unrealize(mm_player_t *player)
+__mmplayer_gst_unrealize(mmplayer_t *player)
{
int ret = MM_ERROR_NONE;
}
static int
-__mmplayer_gst_set_message_callback(mm_player_t *player, MMMessageCallback callback, gpointer user_param)
+__mmplayer_gst_set_message_callback(mmplayer_t *player, MMMessageCallback callback, gpointer user_param)
{
MMPLAYER_FENTER();
}
int
-__mmplayer_parse_profile(const char *uri, void *param, MMPlayerParseProfile *data)
+__mmplayer_parse_profile(const char *uri, void *param, mmplayer_parse_profile_t *data)
{
int ret = MM_ERROR_NONE;
char *path = NULL;
MMPLAYER_RETURN_VAL_IF_FAIL(data, MM_ERROR_PLAYER_INTERNAL);
MMPLAYER_RETURN_VAL_IF_FAIL((strlen(uri) <= MM_MAX_URL_LEN), MM_ERROR_PLAYER_INVALID_URI);
- memset(data, 0, sizeof(MMPlayerParseProfile));
+ memset(data, 0, sizeof(mmplayer_parse_profile_t));
if (strstr(uri, "es_buff://")) {
__mmplayer_copy_uri_and_set_type(data, uri, MM_PLAYER_URI_TYPE_MS_BUFF);
}
static gboolean
-__mmplayer_can_do_interrupt(mm_player_t *player)
+__mmplayer_can_do_interrupt(mmplayer_t *player)
{
if (!player || !player->pipeline || !player->attrs) {
LOGW("not initialized");
goto FAILED;
}
- if (player->audio_stream_render_cb) {
+ if (player->audio_decoded_cb) {
LOGW("not support in pcm extraction mode");
goto FAILED;
}
__resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
void *user_data)
{
- mm_player_t *player = NULL;
+ mmplayer_t *player = NULL;
MMPLAYER_FENTER();
LOGE("- user_data is null");
return FALSE;
}
- player = (mm_player_t *)user_data;
+ player = (mmplayer_t *)user_data;
/* do something to release resource here.
* player stop and interrupt forwarding */
}
static void
-__mmplayer_initialize_video_roi(mm_player_t *player)
+__mmplayer_initialize_video_roi(mmplayer_t *player)
{
player->video_roi.scale_x = 0.0;
player->video_roi.scale_y = 0.0;
int ret = MM_ERROR_PLAYER_INTERNAL;
bool enabled = false;
- mm_player_t *player = MM_PLAYER_CAST(handle);
+ mmplayer_t *player = MM_PLAYER_CAST(handle);
MMPLAYER_FENTER();
}
static gboolean
-__mmplayer_init_gstreamer(mm_player_t *player)
+__mmplayer_init_gstreamer(mmplayer_t *player)
{
static gboolean initialized = FALSE;
static const int max_argc = 50;
}
static void
-__mmplayer_check_async_state_transition(mm_player_t *player)
+__mmplayer_check_async_state_transition(mmplayer_t *player)
{
GstState element_state = GST_STATE_VOID_PENDING;
GstState element_pending_state = GST_STATE_VOID_PENDING;
int
_mmplayer_destroy(MMHandleType handle)
{
- mm_player_t *player = MM_PLAYER_CAST(handle);
+ mmplayer_t *player = MM_PLAYER_CAST(handle);
MMPLAYER_FENTER();
int
_mmplayer_realize(MMHandleType hplayer)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
char *uri = NULL;
void *param = NULL;
MMHandleType attrs = 0;
player->demux_pad_index = 0;
player->subtitle_language_list = NULL;
player->is_subtitle_force_drop = FALSE;
- player->last_multiwin_status = FALSE;
__mmplayer_track_initialize(player);
__mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
int
_mmplayer_unrealize(MMHandleType hplayer)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_FENTER();
int
_mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback, gpointer user_param)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
int
_mmplayer_get_state(MMHandleType hplayer, int *state)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_RETURN_VAL_IF_FAIL(state, MM_ERROR_INVALID_ARGUMENT);
return MM_ERROR_NONE;
}
-
-int
-_mmplayer_set_volume(MMHandleType hplayer, MMPlayerVolumeType volume)
+static int
+__mmplayer_gst_set_volume_property(mmplayer_t *player, const char *prop_name)
{
- mm_player_t *player = (mm_player_t *)hplayer;
GstElement *vol_element = NULL;
- int i = 0;
+ enum audio_element_id volume_elem_id = MMPLAYER_A_VOL;
MMPLAYER_FENTER();
-
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
- LOGD("volume [L]=%f:[R]=%f",
- volume.level[MM_VOLUME_CHANNEL_LEFT], volume.level[MM_VOLUME_CHANNEL_RIGHT]);
-
- /* invalid factor range or not */
- for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++) {
- if (volume.level[i] < MM_VOLUME_FACTOR_MIN || volume.level[i] > MM_VOLUME_FACTOR_MAX) {
- LOGE("Invalid factor!(valid factor:0~1.0)");
- return MM_ERROR_INVALID_ARGUMENT;
- }
- }
-
- /* not support to set other value into each channel */
- if ((volume.level[MM_VOLUME_CHANNEL_LEFT] != volume.level[MM_VOLUME_CHANNEL_RIGHT]))
- return MM_ERROR_INVALID_ARGUMENT;
-
- /* Save volume to handle. Currently the first array element will be saved. */
- player->sound.volume = volume.level[MM_VOLUME_CHANNEL_LEFT];
+ MMPLAYER_RETURN_VAL_IF_FAIL(prop_name, MM_ERROR_INVALID_ARGUMENT);
/* check pipeline handle */
if (!player->pipeline || !player->pipeline->audiobin) {
- LOGD("audiobin is not created yet");
- LOGD("but, current stored volume will be set when it's created.");
+ LOGD("'%s' will be applied when audiobin is created", prop_name);
- /* NOTE : stored volume will be used in create_audiobin
+ /* NOTE : stored value will be used in create_audiobin
* returning MM_ERROR_NONE here makes application to able to
- * set volume at anytime.
+ * set audio volume or mute at anytime.
*/
return MM_ERROR_NONE;
}
- /* setting volume to volume element */
- vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+ if (player->build_audio_offload) {
+ LOGD("offload pipeline");
+ volume_elem_id = MMPLAYER_A_SINK;
+ }
- if (vol_element) {
- LOGD("volume is set [%f]", player->sound.volume);
- g_object_set(vol_element, "volume", player->sound.volume, NULL);
+ vol_element = player->pipeline->audiobin[volume_elem_id].gst;
+ if (!vol_element) {
+ LOGE("failed to get vol element %d", volume_elem_id);
+ return MM_ERROR_PLAYER_INTERNAL;
}
- MMPLAYER_FLEAVE();
+ LOGD("set '%s' property to element[%s]", prop_name, GST_ELEMENT_NAME(vol_element));
+
+ if (!g_object_class_find_property(G_OBJECT_GET_CLASS(vol_element), prop_name)) {
+ LOGE("there is no '%s' property", prop_name);
+ return MM_ERROR_PLAYER_INTERNAL;
+ }
+
+ if (!strcmp(prop_name, "volume")) {
+ g_object_set(vol_element, "volume", player->sound.volume, NULL);
+ } else if (!strcmp(prop_name, "mute")) {
+ g_object_set(vol_element, "mute", player->sound.mute, NULL);
+ } else {
+ LOGE("invalid property %s", prop_name);
+ return MM_ERROR_PLAYER_INTERNAL;
+ }
return MM_ERROR_NONE;
}
int
-_mmplayer_get_volume(MMHandleType hplayer, MMPlayerVolumeType *volume)
+_mmplayer_set_volume(MMHandleType hplayer, float volume)
{
- mm_player_t *player = (mm_player_t *)hplayer;
- int i = 0;
+ int ret = MM_ERROR_NONE;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
-
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL(volume, MM_ERROR_INVALID_ARGUMENT);
- /* returning stored volume */
- for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
- volume->level[i] = player->sound.volume;
+ LOGD("volume = %f", volume);
- MMPLAYER_FLEAVE();
+ /* invalid factor range or not */
+ if (volume < MM_VOLUME_FACTOR_MIN || volume > MM_VOLUME_FACTOR_MAX) {
+ LOGE("Invalid volume value");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
- return MM_ERROR_NONE;
+ player->sound.volume = volume;
+
+ ret = __mmplayer_gst_set_volume_property(player, "volume");
+
+ MMPLAYER_FLEAVE();
+ return ret;
}
int
-_mmplayer_set_mute(MMHandleType hplayer, int mute)
+_mmplayer_get_volume(MMHandleType hplayer, float *volume)
{
- mm_player_t *player = (mm_player_t *)hplayer;
- GstElement *vol_element = NULL;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+ MMPLAYER_RETURN_VAL_IF_FAIL(volume, MM_ERROR_INVALID_ARGUMENT);
- /* mute value shoud 0 or 1 */
- if (mute != 0 && mute != 1) {
- LOGE("bad mute value");
+ *volume = player->sound.volume;
- /* FIXIT : definitly, we need _BAD_PARAM error code */
- return MM_ERROR_INVALID_ARGUMENT;
- }
+ LOGD("current vol = %f", *volume);
- player->sound.mute = mute;
+ MMPLAYER_FLEAVE();
+ return MM_ERROR_NONE;
+}
- /* just hold mute value if pipeline is not ready */
- if (!player->pipeline || !player->pipeline->audiobin) {
- LOGD("pipeline is not ready. holding mute value");
- return MM_ERROR_NONE;
- }
+int
+_mmplayer_set_mute(MMHandleType hplayer, bool mute)
+{
+ int ret = MM_ERROR_NONE;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
+
+ MMPLAYER_FENTER();
+ MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+ LOGD("mute = %d", mute);
- /* NOTE : volume will only created when the bt is enabled */
- if (vol_element) {
- LOGD("mute : %d", mute);
- g_object_set(vol_element, "mute", mute, NULL);
- } else
- LOGD("volume elemnet is not created. using volume in audiosink");
+ player->sound.mute = mute;
- MMPLAYER_FLEAVE();
+ ret = __mmplayer_gst_set_volume_property(player, "mute");
- return MM_ERROR_NONE;
+ MMPLAYER_FLEAVE();
+ return ret;
}
int
-_mmplayer_get_mute(MMHandleType hplayer, int *pmute)
+_mmplayer_get_mute(MMHandleType hplayer, bool *mute)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- MMPLAYER_RETURN_VAL_IF_FAIL(pmute, MM_ERROR_INVALID_ARGUMENT);
+ MMPLAYER_RETURN_VAL_IF_FAIL(mute, MM_ERROR_INVALID_ARGUMENT);
- /* just hold mute value if pipeline is not ready */
- if (!player->pipeline || !player->pipeline->audiobin) {
- LOGD("pipeline is not ready. returning stored value");
- *pmute = player->sound.mute;
- return MM_ERROR_NONE;
- }
+ *mute = player->sound.mute;
- *pmute = player->sound.mute;
+ LOGD("current mute = %d", *mute);
MMPLAYER_FLEAVE();
int
_mmplayer_set_videostream_changed_cb(MMHandleType hplayer, mm_player_stream_changed_callback callback, void *user_param)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
int
_mmplayer_set_audiostream_changed_cb(MMHandleType hplayer, mm_player_stream_changed_callback callback, void *user_param)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
}
int
-_mmplayer_set_audiostream_cb(MMHandleType hplayer, bool sync, mm_player_audio_stream_callback callback, void *user_param)
+_mmplayer_set_audio_decoded_cb(MMHandleType hplayer, mmplayer_audio_extract_opt_e opt, mm_player_audio_decoded_callback callback, void *user_param)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- player->audio_stream_render_cb = callback;
- player->audio_stream_cb_user_param = user_param;
- player->audio_stream_sink_sync = sync;
- LOGD("handle: %p, cb: %p, sync: %d", player, player->audio_stream_render_cb, player->audio_stream_sink_sync);
+ player->audio_decoded_cb = callback;
+ player->audio_decoded_cb_user_param = user_param;
+ player->audio_extract_opt = opt;
+ LOGD("handle: %p, cb: %p, opt: 0x%X", player, player->audio_decoded_cb, player->audio_extract_opt);
MMPLAYER_FLEAVE();
}
int
-_mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callback callback, void *user_param)
+_mmplayer_set_video_decoded_cb(MMHandleType hplayer, mm_player_video_decoded_callback callback, void *user_param)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
if (callback && !player->bufmgr)
player->bufmgr = tbm_bufmgr_init(-1);
- player->set_mode.media_packet_video_stream = (callback) ? true : false;
- player->video_stream_cb = callback;
- player->video_stream_cb_user_param = user_param;
+ player->set_mode.video_export = (callback) ? true : false;
+ player->video_decoded_cb = callback;
+ player->video_decoded_cb_user_param = user_param;
- LOGD("Stream cb Handle value is %p : %p, enable:%d", player, player->video_stream_cb, player->set_mode.media_packet_video_stream);
+ LOGD("Stream cb Handle value is %p : %p, enable:%d", player, player->video_decoded_cb, player->set_mode.video_export);
MMPLAYER_FLEAVE();
int
_mmplayer_start(MMHandleType hplayer)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
gint ret = MM_ERROR_NONE;
MMPLAYER_FENTER();
* Because GST_ERROR_MESSAGE is posted by other plugin internally.
*/
int
-__mmplayer_handle_missed_plugin(mm_player_t *player)
+__mmplayer_handle_missed_plugin(mmplayer_t *player)
{
MMMessageParamType msg_param;
memset(&msg_param, 0, sizeof(MMMessageParamType));
}
static void
-__mmplayer_check_pipeline(mm_player_t *player)
+__mmplayer_check_pipeline(mmplayer_t *player)
{
GstState element_state = GST_STATE_VOID_PENDING;
GstState element_pending_state = GST_STATE_VOID_PENDING;
int
_mmplayer_stop(MMHandleType hplayer)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_FENTER();
int
_mmplayer_pause(MMHandleType hplayer)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
gint64 pos_nsec = 0;
gboolean async = FALSE;
gint ret = MM_ERROR_NONE;
int
_mmplayer_abort_pause(MMHandleType hplayer)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_FENTER();
int
_mmplayer_resume(MMHandleType hplayer)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
gboolean async = FALSE;
int
_mmplayer_set_playspeed(MMHandleType hplayer, float rate, bool streaming)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
gint64 pos_nsec = 0;
int ret = MM_ERROR_NONE;
- int mute = FALSE;
+ bool mute = false;
signed long long start = 0, stop = 0;
- MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+ mmplayer_state_e current_state = MM_PLAYER_STATE_NONE;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
/* The sound of video is not supported under 0.0 and over 2.0. */
if (rate >= TRICK_PLAY_MUTE_THRESHOLD_MAX || rate < TRICK_PLAY_MUTE_THRESHOLD_MIN) {
if (player->can_support_codec & FOUND_PLUGIN_VIDEO)
- mute = TRUE;
+ mute = true;
}
_mmplayer_set_mute(hplayer, mute);
int
_mmplayer_set_position(MMHandleType hplayer, gint64 position)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_FENTER();
int
_mmplayer_get_position(MMHandleType hplayer, gint64 *position)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
int
_mmplayer_get_duration(MMHandleType hplayer, gint64 *duration)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
int
_mmplayer_get_buffer_position(MMHandleType hplayer, int *start_pos, int *end_pos)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
}
int
-_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int format, int position)
+_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int position)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
- ret = __mmplayer_gst_adjust_subtitle_position(player, format, position);
+ ret = __mmplayer_gst_adjust_subtitle_position(player, position);
MMPLAYER_FLEAVE();
__mmplayer_is_only_mp3_type(gchar *str_caps)
{
if (g_strrstr(str_caps, "application/x-id3") ||
- (g_strrstr(str_caps, "audio/mpeg") && g_strrstr(str_caps, "mpegversion= (int)1")))
+ (g_strrstr(str_caps, "audio/mpeg") && g_strrstr(str_caps, "mpegversion=(int)1")))
return TRUE;
return FALSE;
}
static void
-__mmplayer_set_audio_attrs(mm_player_t *player, GstCaps *caps)
+__mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps)
{
GstStructure *caps_structure = NULL;
gint samplerate = 0;
}
static void
-__mmplayer_update_content_type_info(mm_player_t *player)
+__mmplayer_update_content_type_info(mmplayer_t *player)
{
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player && player->type);
__mmplayer_typefind_have_type(GstElement *tf, guint probability,
GstCaps *caps, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
GstPad *pad = NULL;
MMPLAYER_FENTER();
if (async && player->msg_posted == FALSE)
__mmplayer_handle_missed_plugin(player);
- goto DONE;
}
-DONE:
gst_object_unref(GST_OBJECT(pad));
MMPLAYER_FLEAVE();
}
GstElement *
-__mmplayer_gst_make_decodebin(mm_player_t *player)
+__mmplayer_gst_make_decodebin(mmplayer_t *player)
{
GstElement *decodebin = NULL;
}
static GstElement *
-__mmplayer_gst_make_queue2(mm_player_t *player)
+__mmplayer_gst_make_queue2(mmplayer_t *player)
{
GstElement *queue2 = NULL;
gint64 dur_bytes = 0L;
- MMPlayerGstElement *mainbin = NULL;
- MuxedBufferType type = MUXED_BUFFER_TYPE_MEM_QUEUE;
+ mmplayer_gst_element_t *mainbin = NULL;
+ muxed_buffer_type_e type = MUXED_BUFFER_TYPE_MEM_QUEUE;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, NULL);
}
gboolean
-__mmplayer_gst_create_decoder(mm_player_t *player, GstPad *srcpad, const GstCaps *caps)
+__mmplayer_gst_create_decoder(mmplayer_t *player, GstPad *srcpad, const GstCaps *caps)
{
- MMPlayerGstElement *mainbin = NULL;
+ mmplayer_gst_element_t *mainbin = NULL;
GstElement *decodebin = NULL;
GstElement *queue2 = NULL;
GstPad *sinkpad = NULL;
gst_object_unref(GST_OBJECT(sinkpad));
sinkpad = NULL;
+ gst_object_unref(GST_OBJECT(qsrcpad));
+ qsrcpad = NULL;
mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
mainbin[MMPLAYER_M_AUTOPLUG].gst = decodebin;
if (sinkpad)
gst_object_unref(GST_OBJECT(sinkpad));
+ if (qsrcpad)
+ gst_object_unref(GST_OBJECT(qsrcpad));
+
if (queue2) {
/* NOTE : Trying to dispose element queue0, but it is in READY instead of the NULL state.
* You need to explicitly set elements to the NULL state before
}
static int
-__mmplayer_check_not_supported_codec(mm_player_t *player, const gchar *factory_class, const gchar *mime)
+__mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime)
{
MMPLAYER_FENTER();
static void
__mmplayer_pipeline_complete(GstElement *decodebin, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
MMPLAYER_FENTER();
}
static gboolean
-__mmplayer_get_next_uri(mm_player_t *player)
+__mmplayer_get_next_uri(mmplayer_t *player)
{
- MMPlayerParseProfile profile;
+ mmplayer_parse_profile_t profile;
gint uri_idx = 0;
guint num_of_list = 0;
char *uri = NULL;
}
static gboolean
-__mmplayer_verify_gapless_play_path(mm_player_t *player)
+__mmplayer_verify_gapless_play_path(mmplayer_t *player)
{
#define REPEAT_COUNT_INFINITELY -1
#define REPEAT_COUNT_MIN 2
}
static void
-__mmplayer_initialize_gapless_play(mm_player_t *player)
+__mmplayer_initialize_gapless_play(mmplayer_t *player)
{
int i;
mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
- /* clean found parsers */
- if (player->parsers) {
- GList *parsers = player->parsers;
- for (; parsers; parsers = g_list_next(parsers)) {
- gchar *name = parsers->data;
- MMPLAYER_FREEIF(name);
- }
- g_list_free(player->parsers);
- player->parsers = NULL;
- }
-
/* clean found audio decoders */
if (player->audio_decoders) {
GList *a_dec = player->audio_decoders;
}
static void
-__mmplayer_activate_next_source(mm_player_t *player, GstState target)
+__mmplayer_activate_next_source(mmplayer_t *player, GstState target)
{
- MMPlayerGstElement *mainbin = NULL;
+ mmplayer_gst_element_t *mainbin = NULL;
MMMessageParamType msg_param = {0,};
GstElement *element = NULL;
MMHandleType attrs = 0;
char *uri = NULL;
- enum MainElementID elem_idx = MMPLAYER_M_NUM;
+ main_element_id_e elem_idx = MMPLAYER_M_NUM;
MMPLAYER_FENTER();
}
static gboolean
-__mmplayer_deactivate_selector(mm_player_t *player, MMPlayerTrackType type)
+__mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type)
{
- mm_player_selector_t *selector = &player->selector[type];
- MMPlayerGstElement *sinkbin = NULL;
- enum MainElementID selectorId = MMPLAYER_M_NUM;
- enum MainElementID sinkId = MMPLAYER_M_NUM;
+ mmplayer_selector_t *selector = &player->selector[type];
+ mmplayer_gst_element_t *sinkbin = NULL;
+ main_element_id_e selectorId = MMPLAYER_M_NUM;
+ main_element_id_e sinkId = MMPLAYER_M_NUM;
GstPad *srcpad = NULL;
GstPad *sinkpad = NULL;
gboolean send_notice = FALSE;
}
static void
-__mmplayer_deactivate_old_path(mm_player_t *player)
+__mmplayer_deactivate_old_path(mmplayer_t *player)
{
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player);
_mmplayer_set_uri(MMHandleType hplayer, const char *uri)
{
int result = MM_ERROR_NONE;
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
int
_mmplayer_set_next_uri(MMHandleType hplayer, const char *uri, bool is_first_path)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
guint num_of_list = 0;
MMPLAYER_FENTER();
if (is_first_path) {
if (num_of_list == 0) {
player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
- LOGD("add original path : %s", uri);
+ SECURE_LOGD("add original path : %s", uri);
} else {
player->uri_info.uri_list = g_list_delete_link(player->uri_info.uri_list, g_list_nth(player->uri_info.uri_list, 0));
player->uri_info.uri_list = g_list_insert(player->uri_info.uri_list, g_strdup(uri), 0);
- LOGD("change original path : %s", uri);
+ SECURE_LOGD("change original path : %s", uri);
}
} else {
MMHandleType attrs = 0;
player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(original_uri));
player->uri_info.uri_idx = 0;
- LOGD("add original path at first : %s", original_uri);
+ SECURE_LOGD("add original path at first : %s", original_uri);
}
}
player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
- LOGD("add new path : %s(total num of list = %d)", uri, g_list_length(player->uri_info.uri_list));
+ SECURE_LOGD("add new path : %s(total num of list = %d)", uri, g_list_length(player->uri_info.uri_list));
}
MMPLAYER_FLEAVE();
int
_mmplayer_get_next_uri(MMHandleType hplayer, char **uri)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
char *next_uri = NULL;
guint num_of_list = 0;
__mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad,
GstCaps *caps, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
const gchar *klass = NULL;
const gchar *mime = NULL;
gchar *caps_str = NULL;
__mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad,
GstCaps *caps, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
const char *mime = NULL;
gboolean ret = TRUE;
}
static gboolean
-__mmplayer_check_offload_path(mm_player_t *player)
+__mmplayer_is_audio_offload_device_type(mmplayer_t *player)
+{
+ gboolean ret = TRUE;
+ GDBusConnection *conn = NULL;
+ GError *err = NULL;
+ GVariant *result = NULL;
+ const gchar *dbus_device_type = NULL;
+ const gchar *dbus_ret = NULL;
+ gint idx = 0;
+
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (!conn || err) {
+ LOGE("failed g_bus_get_sync() (%s)", err ? err->message : NULL);
+ g_error_free(err);
+ ret = FALSE;
+ goto DONE;
+ }
+
+ result = g_dbus_connection_call_sync(conn,
+ "org.pulseaudio.Server",
+ "/org/pulseaudio/StreamManager",
+ "org.pulseaudio.StreamManager",
+ "GetCurrentMediaRoutingPath",
+ g_variant_new("(s)", "out"),
+ G_VARIANT_TYPE("(ss)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ 2000,
+ NULL,
+ &err);
+ if (!result || err) {
+ LOGE("failed g_dbus_connection_call_sync() (%s)", err ? err->message : NULL);
+ g_error_free(err);
+ ret = FALSE;
+ goto DONE;
+ }
+
+ /* device type is listed in stream-map.json at mmfw-sysconf */
+ g_variant_get(result, "(&s&s)", &dbus_device_type, &dbus_ret);
+
+ LOGI("g_dbus_connection_call_sync() success (%s, %s)", dbus_device_type, dbus_ret);
+ if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
+ ret = FALSE;
+ goto DONE;
+ }
+
+ /* the device type is listed in ini file among audio-jack, bt-a2dp, usb-audio, builtin-speaker */
+ for (idx = 0; player->ini.audio_offload_device_type[idx][0] != '\0'; idx++) {
+ if (strstr(dbus_device_type, player->ini.audio_offload_device_type[idx])) {
+ LOGD("audio offload is supportable");
+ ret = TRUE;
+ goto DONE;
+ }
+ }
+
+ LOGD("audio offload is not supportable");
+ ret = FALSE;
+
+DONE:
+ g_variant_unref(result);
+ g_object_unref(conn);
+
+ return ret;
+}
+
+static void __mmplayer_rebuild_audio_pipeline(mmplayer_t *player)
+{
+ mmplayer_state_e current_state = MM_PLAYER_STATE_NONE;
+ gint64 position = 0;
+
+ MMPLAYER_RETURN_IF_FAIL(player && player->attrs &&
+ player->pipeline && player->pipeline->mainbin);
+
+ MMPLAYER_CMD_LOCK(player);
+ current_state = MMPLAYER_CURRENT_STATE(player);
+
+ if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &position))
+ LOGW("getting current position failed in paused");
+
+ _mmplayer_unrealize((MMHandleType)player);
+ _mmplayer_realize((MMHandleType)player);
+
+ _mmplayer_set_position((MMHandleType)player, position);
+
+ /* async not to be blocked in streaming case */
+ mm_attrs_set_int_by_name(player->attrs, "profile_prepare_async", TRUE);
+ if (mm_attrs_commit_all(player->attrs))
+ LOGE("failed to commit");
+
+ _mmplayer_pause((MMHandleType)player);
+
+ if (current_state == MM_PLAYER_STATE_PLAYING)
+ _mmplayer_start((MMHandleType)player);
+ MMPLAYER_CMD_UNLOCK(player);
+
+ LOGD("rebuilding audio pipeline is completed.");
+}
+
+void __mmplayer_audio_device_connected_cb(MMSoundDevice_t device_h, bool is_connected, void *user_data)
+{
+ mmplayer_t *player = (mmplayer_t *)user_data;
+ mm_sound_device_type_e dev_type = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER;
+ gboolean is_supportable = FALSE;
+
+ if (mm_sound_get_device_type(device_h, &dev_type) != MM_ERROR_NONE)
+ LOGW("failed to get device type");
+ else
+ LOGD("dev type (%d), connected (%d)", dev_type, is_connected);
+
+ if ((dev_type != MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP) &&
+ (dev_type != MM_SOUND_DEVICE_TYPE_AUDIOJACK) &&
+ (dev_type != MM_SOUND_DEVICE_TYPE_USB_AUDIO)) {
+ LOGD("ignore this dev connected info");
+ return;
+ }
+
+ is_supportable = __mmplayer_is_audio_offload_device_type(player);
+ if (player->build_audio_offload == is_supportable) {
+ LOGD("keep current pipeline without re-building");
+ return;
+ }
+
+ /* rebuild pipeline */
+ LOGD("re-build pipeline - offload: %d", is_supportable);
+ player->build_audio_offload = FALSE;
+ __mmplayer_rebuild_audio_pipeline(player);
+
+ return;
+}
+
+static gboolean
+__mmplayer_add_audio_device_connected_cb(mmplayer_t *player)
+{
+ unsigned int id = 0;
+
+ if (player->audio_device_cb_id != 0) {
+ LOGW("audio device connected cb was already added (%u)", player->audio_device_cb_id);
+ return TRUE;
+ }
+
+ if (mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_IO_DIRECTION_OUT_FLAG,
+ __mmplayer_audio_device_connected_cb, player, &id) == MM_ERROR_NONE) {
+ LOGD("added device connected cb (%u)", id);
+ player->audio_device_cb_id = id;
+ } else {
+ LOGW("failed to add device connected cb");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+__mmplayer_can_build_audio_offload_path(mmplayer_t *player)
{
gboolean ret = FALSE;
GstElementFactory *factory = NULL;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->attrs, FALSE);
- if (strcmp(player->ini.audio_offload_sink_element, "")) {
- /* FIXME : 1. need to consider the current audio output path and
- player have to know whether it support offload or not.
- 2. could be added new condition about content length */
- LOGD("current stream : %s, sink: %s", player->type, player->ini.audio_offload_sink_element);
- if (!__mmplayer_is_only_mp3_type(player->type))
- goto DONE;
+ LOGD("current stream : %s, sink: %s", player->type, player->ini.audio_offload_sink_element);
+ if (!__mmplayer_is_only_mp3_type(player->type))
+ goto DONE;
- factory = gst_element_factory_find(player->ini.audio_offload_sink_element);
- if (!factory)
- goto DONE;
+ if (!strcmp(player->ini.audio_offload_sink_element, "")) {
+ LOGD("there is no audio offload sink");
+ goto DONE;
+ }
- LOGD("can setup the audio offload path");
- gst_object_unref(factory);
- ret = TRUE;
+ if (player->ini.audio_offload_device_type[0][0] == '\0') {
+ LOGW("there is no audio device type to support offload");
+ goto DONE;
+ }
+
+ factory = gst_element_factory_find(player->ini.audio_offload_sink_element);
+ if (!factory) {
+ LOGW("there is no installed audio offload sink element");
+ goto DONE;
}
+ gst_object_unref(factory);
+
+ if (!__mmplayer_add_audio_device_connected_cb(player))
+ goto DONE;
+
+ if (!__mmplayer_is_audio_offload_device_type(player))
+ goto DONE;
+
+ LOGD("audio offload can be built");
+ ret = TRUE;
DONE:
MMPLAYER_FLEAVE();
}
static GstAutoplugSelectResult
-__mmplayer_check_codec_info(mm_player_t *player, const char *klass, GstCaps *caps, char *factory_name)
+__mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps, char *factory_name)
{
GstAutoplugSelectResult ret = GST_AUTOPLUG_SELECT_TRY;
int idx = 0;
int audio_offload = 0;
if ((g_strrstr(klass, "Codec/Decoder/Audio"))) {
- mm_attrs_get_int_by_name(player->attrs, "audio_offload", &audio_offload); /* user setting */
+ mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_OFFLOAD, &audio_offload); /* user requirement */
- if (audio_offload && __mmplayer_check_offload_path(player)) {
- LOGD("expose audio path to build offload path");
+ if (audio_offload && __mmplayer_can_build_audio_offload_path(player)) {
+ LOGD("expose audio path to build offload output path");
player->build_audio_offload = TRUE;
/* update codec info */
player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
GstCaps *caps, GstElementFactory *factory, gpointer data)
{
GstAutoplugSelectResult result = GST_AUTOPLUG_SELECT_TRY;
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
gchar *factory_name = NULL;
gchar *caps_str = NULL;
/* don't make video because of not required */
if ((stype == MM_DISPLAY_SURFACE_NULL) &&
- (!player->set_mode.media_packet_video_stream)) {
+ (!player->set_mode.video_export)) {
LOGD("no need video decoding, expose pad");
result = GST_AUTOPLUG_SELECT_EXPOSE;
goto DONE;
__mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad,
gpointer data)
{
- //mm_player_t *player = (mm_player_t *)data;
+ //mmplayer_t *player = (mmplayer_t *)data;
GstCaps *caps = NULL;
LOGD("[Decodebin2] pad-removed signal");
static void
__mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
GstIterator *iter = NULL;
GValue item = { 0, };
GstPad *pad = NULL;
void
__mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data)
{
- mm_player_t *player = (mm_player_t *)data;
+ mmplayer_t *player = (mmplayer_t *)data;
const gchar *klass = NULL;
gchar *factory_name = NULL;
if (__mmplayer_add_dump_buffer_probe(player, element))
LOGD("add buffer probe");
- //<-
if (g_strrstr(klass, "Codec/Decoder/Audio")) {
gchar *selected = NULL;
selected = g_strdup(GST_ELEMENT_NAME(element));
player->audio_decoders = g_list_append(player->audio_decoders, selected);
}
- //-> temp code
-
- if (g_strrstr(klass, "Parser")) {
- gchar *selected = NULL;
-
- selected = g_strdup(factory_name);
- player->parsers = g_list_append(player->parsers, selected);
- }
if (g_strrstr(klass, "Demuxer/Adaptive")) {
player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].id = MMPLAYER_M_ADAPTIVE_DEMUX;
}
static void
-__mmplayer_release_misc(mm_player_t *player)
+__mmplayer_release_misc(mmplayer_t *player)
{
int i;
bool cur_mode = player->set_mode.rich_audio;
MMPLAYER_RETURN_IF_FAIL(player);
- player->video_stream_cb = NULL;
- player->video_stream_cb_user_param = NULL;
+ player->video_decoded_cb = NULL;
+ player->video_decoded_cb_user_param = NULL;
player->video_stream_prerolled = false;
- player->audio_stream_render_cb = NULL;
- player->audio_stream_cb_user_param = NULL;
- player->audio_stream_sink_sync = false;
+ player->audio_decoded_cb = NULL;
+ player->audio_decoded_cb_user_param = NULL;
+ player->audio_extract_opt = MM_PLAYER_AUDIO_EXTRACT_DEFAULT;
player->video_stream_changed_cb = NULL;
player->video_stream_changed_cb_user_param = NULL;
player->is_subtitle_force_drop = FALSE;
player->play_subtitle = FALSE;
player->adjust_subtitle_pos = 0;
- player->last_multiwin_status = FALSE;
player->has_closed_caption = FALSE;
- player->set_mode.media_packet_video_stream = false;
+ player->set_mode.video_export = false;
player->profile.uri_type = MM_PLAYER_URI_TYPE_NONE;
- memset(&player->set_mode, 0, sizeof(MMPlayerSetMode));
+ memset(&player->set_mode, 0, sizeof(mmplayer_setting_mode_t));
/* recover mode */
player->set_mode.rich_audio = cur_mode;
+ if (player->audio_device_cb_id > 0 &&
+ mm_sound_remove_device_connected_callback(player->audio_device_cb_id) != MM_ERROR_NONE)
+ LOGW("failed to remove audio device_connected_callback");
+ player->audio_device_cb_id = 0;
+
for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) {
player->bitrate[i] = 0;
player->maximum_bitrate[i] = 0;
}
static void
-__mmplayer_release_misc_post(mm_player_t *player)
+__mmplayer_release_misc_post(mmplayer_t *player)
{
char *original_uri = NULL;
MMPLAYER_FENTER();
mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
- /* clean found parsers */
- if (player->parsers) {
- GList *parsers = player->parsers;
- for (; parsers; parsers = g_list_next(parsers)) {
- gchar *name = parsers->data;
- MMPLAYER_FREEIF(name);
- }
- g_list_free(player->parsers);
- player->parsers = NULL;
- }
-
/* clean found audio decoders */
if (player->audio_decoders) {
GList *a_dec = player->audio_decoders;
}
gboolean
-__mmplayer_check_subtitle(mm_player_t *player)
+__mmplayer_check_subtitle(mmplayer_t *player)
{
MMHandleType attrs = 0;
char *subtitle_uri = NULL;
}
void
-__mmplayer_cancel_eos_timer(mm_player_t *player)
+__mmplayer_cancel_eos_timer(mmplayer_t *player)
{
MMPLAYER_RETURN_IF_FAIL(player);
}
static void
-__mmplayer_add_sink(mm_player_t *player, GstElement *sink)
+__mmplayer_add_sink(mmplayer_t *player, GstElement *sink)
{
MMPLAYER_FENTER();
}
static void
-__mmplayer_del_sink(mm_player_t *player, GstElement *sink)
+__mmplayer_del_sink(mmplayer_t *player, GstElement *sink)
{
MMPLAYER_FENTER();
}
void
-__mmplayer_add_signal_connection(mm_player_t *player, GObject *object,
- MMPlayerSignalType type, const gchar *signal, GCallback cb_funct, gpointer u_data)
+__mmplayer_add_signal_connection(mmplayer_t *player, GObject *object,
+ mmplayer_signal_type_e type, const gchar *signal, GCallback cb_funct, gpointer u_data)
{
- MMPlayerSignalItem *item = NULL;
+ mmplayer_signal_item_t *item = NULL;
MMPLAYER_FENTER();
MMPLAYER_RETURN_IF_FAIL(player);
return;
}
- item = (MMPlayerSignalItem *)g_try_malloc(sizeof(MMPlayerSignalItem));
+ item = (mmplayer_signal_item_t *)g_try_malloc(sizeof(mmplayer_signal_item_t));
if (!item) {
LOGE("cannot connect signal [%s]", signal);
return;
* g_signal_handler_disconnect(instance, id);
*/
static void
-__mmplayer_release_signal_connection(mm_player_t *player, MMPlayerSignalType type)
+__mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e type)
{
GList *sig_list = NULL;
- MMPlayerSignalItem *item = NULL;
+ mmplayer_signal_item_t *item = NULL;
MMPLAYER_FENTER();
int
_mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_type, void *display_overlay)
{
- mm_player_t *player = 0;
+ mmplayer_t *player = 0;
int prev_display_surface_type = 0;
void *prev_display_overlay = NULL;
int
_mmplayer_set_subtitle_silent(MMHandleType hplayer, int silent)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
}
int
-_mmplayer_sync_subtitle_pipeline(mm_player_t *player)
+_mmplayer_sync_subtitle_pipeline(mmplayer_t *player)
{
- MMPlayerGstElement *mainbin = NULL;
- MMPlayerGstElement *textbin = NULL;
+ mmplayer_gst_element_t *mainbin = NULL;
+ mmplayer_gst_element_t *textbin = NULL;
GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
GstState current_state = GST_STATE_VOID_PENDING;
GstState element_state = GST_STATE_VOID_PENDING;
}
static int
-__mmplayer_change_external_subtitle_language(mm_player_t *player, const char *filepath)
+__mmplayer_change_external_subtitle_language(mmplayer_t *player, const char *filepath)
{
GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
GstState current_state = GST_STATE_VOID_PENDING;
MMHandleType attrs = 0;
- MMPlayerGstElement *mainbin = NULL;
- MMPlayerGstElement *textbin = NULL;
+ mmplayer_gst_element_t *mainbin = NULL;
+ mmplayer_gst_element_t *textbin = NULL;
gchar *subtitle_uri = NULL;
int result = MM_ERROR_NONE;
_mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char *filepath)
{
int result = MM_ERROR_NONE;
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
char *path = NULL;
MMPLAYER_FENTER();
}
static int
-__mmplayer_change_selector_pad(mm_player_t *player, MMPlayerTrackType type, int index)
+__mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, int index)
{
int result = MM_ERROR_NONE;
gchar *change_pad_name = NULL;
GstPad *sinkpad = NULL;
- MMPlayerGstElement *mainbin = NULL;
- enum MainElementID elem_idx = MMPLAYER_M_NUM;
+ mmplayer_gst_element_t *mainbin = NULL;
+ main_element_id_e elem_idx = MMPLAYER_M_NUM;
GstCaps *caps = NULL;
gint total_track_num = 0;
}
int
-_mmplayer_change_track_language(MMHandleType hplayer, MMPlayerTrackType type, int index)
+_mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type, int index)
{
int result = MM_ERROR_NONE;
- mm_player_t *player = NULL;
- MMPlayerGstElement *mainbin = NULL;
+ mmplayer_t *player = NULL;
+ mmplayer_gst_element_t *mainbin = NULL;
gint current_active_index = 0;
MMPLAYER_FENTER();
- player = (mm_player_t *)hplayer;
+ player = (mmplayer_t *)hplayer;
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
if (!player->pipeline) {
int
_mmplayer_get_subtitle_silent(MMHandleType hplayer, int *silent)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
}
static gboolean
-__mmplayer_add_dump_buffer_probe(mm_player_t *player, GstElement *element)
+__mmplayer_add_dump_buffer_probe(mmplayer_t *player, GstElement *element)
{
MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
MMPLAYER_RETURN_VAL_IF_FAIL(element, FALSE);
for (idx = 0; player->ini.dump_element_keyword[idx][0] != '\0'; idx++) {
if (g_strrstr(factory_name, player->ini.dump_element_keyword[idx])) {
LOGD("dump [%s] sink pad", player->ini.dump_element_keyword[idx]);
- mm_player_dump_t *dump_s;
- dump_s = g_try_malloc(sizeof(mm_player_dump_t));
+ mmplayer_dump_t *dump_s;
+ dump_s = g_try_malloc(sizeof(mmplayer_dump_t));
if (dump_s == NULL) {
LOGE("malloc fail");
return FALSE;
fwrite(probe_info.data, 1, probe_info.size , dump_data);
+ gst_buffer_unmap(buffer, &probe_info);
+
return GST_PAD_PROBE_OK;
}
return;
for (; d_list; d_list = g_list_next(d_list)) {
- mm_player_dump_t *dump_s = d_list->data;
+ mmplayer_dump_t *dump_s = d_list->data;
if (dump_s->dump_pad) {
if (dump_s->probe_handle_id)
gst_pad_remove_probe(dump_s->dump_pad, dump_s->probe_handle_id);
+ gst_object_unref(GST_OBJECT(dump_s->dump_pad));
}
if (dump_s->dump_element_file) {
fclose(dump_s->dump_element_file);
int
_mmplayer_has_closed_caption(MMHandleType hplayer, bool *exist)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
int
_mmplayer_get_timeout(MMHandleType hplayer, int *timeout)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
int
_mmplayer_get_num_of_video_out_buffers(MMHandleType hplayer, int *num, int *extra_num)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
}
static void
-__mmplayer_initialize_storage_info(mm_player_t *player, MMPlayerPathType path_type)
+__mmplayer_initialize_storage_info(mmplayer_t *player, mmplayer_path_type_e path_type)
{
int i = 0;
MMPLAYER_FENTER();
_mmplayer_manage_external_storage_state(MMHandleType hplayer, int id, int state)
{
int ret = MM_ERROR_NONE;
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMMessageParamType msg_param = {0, };
MMPLAYER_FENTER();
_mmplayer_get_adaptive_variant_info(MMHandleType hplayer, int *num, char **var_info)
{
int ret = MM_ERROR_NONE;
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int idx = 0, total = 0;
gchar *result = NULL, *tmp = NULL;
result = g_strdup("");
for (idx = 0 ; idx < total ; idx++) {
- VariantData *v_data = NULL;
+ stream_variant_t *v_data = NULL;
v_data = g_list_nth_data(player->adaptive_info.var_list, idx);
if (v_data) {
_mmplayer_set_max_adaptive_variant_limit(MMHandleType hplayer, int bandwidth, int width, int height)
{
int ret = MM_ERROR_NONE;
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
_mmplayer_get_max_adaptive_variant_limit(MMHandleType hplayer, int *bandwidth, int *width, int *height)
{
int ret = MM_ERROR_NONE;
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
_mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *prebuffer_ms, int *rebuffer_ms)
{
int ret = MM_ERROR_NONE;
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMPLAYER_FENTER();
MMPLAYER_RETURN_VAL_IF_FAIL(player && player->streamer, MM_ERROR_PLAYER_NOT_INITIALIZED);
}
int
-_mmplayer_set_codec_type(MMHandleType hplayer, MMPlayerStreamType stream_type, MMPlayerVideoCodecType codec_type)
+_mmplayer_set_codec_type(MMHandleType hplayer, mmplayer_stream_type_e stream_type, mmplayer_video_codec_type_e codec_type)
{
#define IDX_FIRST_SW_CODEC 0
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
const char *attr_name = (stream_type == MM_PLAYER_STREAM_TYPE_AUDIO) ? (MM_PLAYER_AUDIO_CODEC_TYPE) : (MM_PLAYER_VIDEO_CODEC_TYPE);
MMHandleType attrs = 0;
int
_mmplayer_set_replaygain_enabled(MMHandleType hplayer, bool enabled)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
GstElement *rg_vol_element = NULL;
MMPLAYER_FENTER();
int
_mmplayer_is_replaygain_enabled(MMHandleType hplayer, bool *enabled)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
GstElement *rg_vol_element = NULL;
gboolean enable = FALSE;
int
_mmplayer_set_video_roi_area(MMHandleType hplayer, double scale_x, double scale_y, double scale_width, double scale_height)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
MMHandleType attrs = 0;
void *handle = NULL;
int ret = MM_ERROR_NONE;
int
_mmplayer_get_video_roi_area(MMHandleType hplayer, double *scale_x, double *scale_y, double *scale_width, double *scale_height)
{
- mm_player_t *player = (mm_player_t *)hplayer;
+ mmplayer_t *player = (mmplayer_t *)hplayer;
int ret = MM_ERROR_NONE;
MMPLAYER_FENTER();
}
static gboolean
-__mmplayer_update_duration_value(mm_player_t *player)
+__mmplayer_update_duration_value(mmplayer_t *player)
{
gboolean ret = FALSE;
gint64 dur_nsec = 0;
}
static gboolean
-__mmplayer_update_audio_attrs(mm_player_t *player, MMHandleType attrs)
+__mmplayer_update_audio_attrs(mmplayer_t *player, MMHandleType attrs)
{
/* update audio params
NOTE : We need original audio params and it can be only obtained from src pad of audio
GstPad *pad = NULL;
gint samplerate = 0, channels = 0;
GstStructure *p = NULL;
+ GstElement *aconv = NULL;
LOGD("try to update audio attrs");
MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->audiobin, FALSE);
- MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, FALSE);
- pad = gst_element_get_static_pad(
- player->pipeline->audiobin[MMPLAYER_A_CONV].gst, "sink");
+ if (player->pipeline->audiobin[MMPLAYER_A_CONV].gst) {
+ aconv = player->pipeline->audiobin[MMPLAYER_A_CONV].gst;
+ } else if (player->pipeline->audiobin[MMPLAYER_A_EXTRACT_CONV].gst) {
+ aconv = player->pipeline->audiobin[MMPLAYER_A_EXTRACT_CONV].gst;
+ } else {
+ LOGE("there is no audio converter");
+ return FALSE;
+ }
+
+ pad = gst_element_get_static_pad(aconv, "sink");
if (!pad) {
- LOGW("failed to get pad from audiosink");
+ LOGW("failed to get pad from audio converter");
return FALSE;
}
}
static gboolean
-__mmplayer_update_video_attrs(mm_player_t *player, MMHandleType attrs)
+__mmplayer_update_video_attrs(mmplayer_t *player, MMHandleType attrs)
{
LOGD("try to update video attrs");
}
static gboolean
-__mmplayer_update_bitrate_attrs(mm_player_t *player, MMHandleType attrs)
+__mmplayer_update_bitrate_attrs(mmplayer_t *player, MMHandleType attrs)
{
gboolean ret = FALSE;
guint64 data_size = 0;
}
static void
-__mmplayer_copy_uri_and_set_type(MMPlayerParseProfile *data, const char *uri, int uri_type)
+__mmplayer_copy_uri_and_set_type(mmplayer_parse_profile_t *data, const char *uri, int uri_type)
{
strncpy(data->uri, uri, MM_MAX_URL_LEN - 1);
data->uri_type = uri_type;
}
static int
-__mmplayer_set_mem_uri(MMPlayerParseProfile *data, char *path, void *param)
+__mmplayer_set_mem_uri(mmplayer_parse_profile_t *data, char *path, void *param)
{
int ret = MM_ERROR_PLAYER_INVALID_URI;
int mem_size = 0;
}
static int
-__mmplayer_set_file_uri(MMPlayerParseProfile *data, const char *uri)
+__mmplayer_set_file_uri(mmplayer_parse_profile_t *data, const char *uri)
{
gchar *location = NULL;
GError *err = NULL;
return ret;
}
-static MMPlayerVideoStreamDataType *
+static mmplayer_video_decoded_data_info_t *
__mmplayer_create_stream_from_pad(GstPad *pad)
{
GstCaps *caps = NULL;
GstStructure *structure = NULL;
unsigned int fourcc = 0;
const gchar *string_format = NULL;
- MMPlayerVideoStreamDataType *stream = NULL;
+ mmplayer_video_decoded_data_info_t *stream = NULL;
gint width, height;
MMPixelFormatType format;
+ GstVideoInfo info;
caps = gst_pad_get_current_caps(pad);
if (!caps) {
gst_structure_get_int(structure, "width", &width);
gst_structure_get_int(structure, "height", &height);
string_format = gst_structure_get_string(structure, "format");
+
if (string_format)
fourcc = _mmplayer_convert_fourcc_string_to_value(string_format);
format = util_get_pixtype(fourcc);
+ gst_video_info_from_caps(&info, caps);
gst_caps_unref(caps);
/* moved here */
return NULL;
}
- stream = (MMPlayerVideoStreamDataType *)g_try_malloc0(sizeof(MMPlayerVideoStreamDataType));
+ stream = (mmplayer_video_decoded_data_info_t *)g_try_malloc0(sizeof(mmplayer_video_decoded_data_info_t));
if (!stream) {
LOGE("failed to alloc mem for video data");
return NULL;
stream->width = width;
stream->height = height;
stream->format = format;
+ stream->plane_num = GST_VIDEO_INFO_N_PLANES(&info);
return stream;
}
static void
-__mmplayer_zerocopy_set_stride_elevation_bo(MMPlayerVideoStreamDataType *stream, GstMemory *mem)
+__mmplayer_zerocopy_set_stride_elevation_bo(mmplayer_video_decoded_data_info_t *stream, GstMemory *mem)
{
unsigned int pitch = 0;
+ unsigned int size = 0;
int index = 0;
tbm_surface_h surface = gst_tizen_memory_get_surface(mem);
+ tbm_bo bo = NULL;
for (index = 0; index < gst_tizen_memory_get_num_bos(mem); index++) {
- tbm_surface_internal_get_plane_data(surface, index, NULL, NULL, &pitch);
- stream->bo[index] = tbm_bo_ref(gst_tizen_memory_get_bos(mem, index));
+ bo = gst_tizen_memory_get_bos(mem, index);
+ if (bo)
+ stream->bo[index] = tbm_bo_ref(bo);
+ else
+ LOGE("failed to get bo for index %d", index);
+ }
+
+ for (index = 0; index < stream->plane_num; index++) {
+ tbm_surface_internal_get_plane_data(surface, index, &size, NULL, &pitch);
stream->stride[index] = pitch;
- stream->elevation[index] = stream->height;
+ if (pitch)
+ stream->elevation[index] = size / pitch;
+ else
+ stream->elevation[index] = stream->height;
}
}
static gboolean
-__mmplayer_swcodec_set_stride_elevation(MMPlayerVideoStreamDataType *stream)
+__mmplayer_swcodec_set_stride_elevation(mmplayer_video_decoded_data_info_t *stream)
{
if (stream->format == MM_PIXEL_FORMAT_I420) {
int ret = TBM_SURFACE_ERROR_NONE;
}
static gboolean
-__mmplayer_swcodec_set_bo(mm_player_t *player, MMPlayerVideoStreamDataType *stream, GstMemory *mem)
+__mmplayer_swcodec_set_bo(mmplayer_t *player, mmplayer_video_decoded_data_info_t *stream, GstMemory *mem)
{
tbm_bo_handle thandle;
gboolean is_mapped;
}
static void
-__mmplayer_set_pause_state(mm_player_t *player)
+__mmplayer_set_pause_state(mmplayer_t *player)
{
if (player->sent_bos)
return;
}
static void
-__mmplayer_set_playing_state(mm_player_t *player)
+__mmplayer_set_playing_state(mmplayer_t *player)
{
gchar *audio_codec = NULL;
else if (g_strrstr(player->type, "audio/x-amr"))
audio_codec = "AMR";
else if (g_strrstr(player->type, "audio/mpeg")
- && !g_strrstr(player->type, "mpegversion= (int)1"))
+ && !g_strrstr(player->type, "mpegversion=(int)1"))
audio_codec = "AAC";
else
audio_codec = "unknown";