blob: 15fd22797273184fbbac56fdca0a9d8002556dc9 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include "lynq_medial.h"
#include <syslog.h>
#include <gst/gst.h>
#include <pthread.h>
#include <cutils/properties.h>
//#include "modem_afe_ctrl.h"
#include <log/log.h>
#define LOG_TAG "MEDIA_API"
#define NV_VOLUME_NAME "ro.spk.volume.level"
#define NV_MIC_VOLUME_NAME "ro.mic.volume.level"
//static char *volume_rcv = "/tmp/libmodem-afe-ctrl/server_rcv";
static const int VOLUME_LEVEL_1 = 1;//0;
static const int VOLUME_LEVEL_2 = 10923;//200;
static const int VOLUME_LEVEL_3 = 21845;//209;
static const int VOLUME_LEVEL_4 = 32767;//220;
static const int VOLUME_LEVEL_5 = 43960;//234;
static const int VOLUME_LEVEL_6 = 54612;//245;
static const int VOLUME_LEVEL_7 = 65535;//255;
static const int MIC_VOLUME_LEVEL_1 = 9;
static const int MIC_VOLUME_LEVEL_2 = 19;
static const int MIC_VOLUME_LEVEL_3 = 28;
static const int MIC_VOLUME_LEVEL_4 = 37;
static const int MIC_VOLUME_LEVEL_5 = 46;
static const int MIC_VOLUME_LEVEL_6 = 55;
static const int MIC_VOLUME_LEVEL_7 = 63;
typedef void *MEDIA_HANDLE;
static MEDIA_HANDLE g_media_handle=NULL;
typedef struct {
MEDIA_HANDLE handle;
gint mute;
gdouble volume;
pthread_t thread;
GMainLoop *loop;
GstElement *playbin;
guint bus_watch_id;
GstState gst_cur_state;
} MEDIA_PARAM_T;
static gboolean
bus_call (GstBus * bus, GstMessage * msg, gpointer datas)
{
GstState oldstate, newstate, pending;
MEDIA_PARAM_T *param = (MEDIA_PARAM_T *)datas;
GMainLoop *loop = param->loop;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:{
RLOGD ("End-of-stream\n");
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_STATE_CHANGED:
gst_message_parse_state_changed (msg, &oldstate, &newstate, &pending);
param->gst_cur_state = newstate;
break;
case GST_MESSAGE_ERROR:{
gchar *debug;
GError *err;
gst_message_parse_error (msg, &err, &debug);
g_printerr ("Debugging info: %s\n", (debug) ? debug : "none");
g_free (debug);
RLOGD ("Error: %s\n", err->message);
g_error_free (err);
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
int lynq_get_mic_current_volume()
{
char cvolume_levle[5]= {0};
property_get(NV_MIC_VOLUME_NAME, cvolume_levle, "5");
printf("lynq_media_get_current_volume end :%s\n" ,cvolume_levle);
return atoi(cvolume_levle);
}
static void lynq_set_mic_volume_to_nvram(const int volume_levle )
{
char buf[5];
sprintf(buf, "%d", volume_levle);
property_set(NV_MIC_VOLUME_NAME, buf);
}
static int lynq_set_mic_real_volume(const int real_volume)
{
char cmd[256];
RLOGD("mic real volume: %d \n", real_volume);
sprintf(cmd, "amixer -c0 cset name=\"PGA Volume\" %d", real_volume);
system(cmd);
return 0;
}
static int get_mic_real_volume(const int volume_levle)
{
int real_volume;
switch (volume_levle) {
case MIC_VOLUME_LEVEL1:
real_volume = MIC_VOLUME_LEVEL_1;
break;
case MIC_VOLUME_LEVEL2:
real_volume = MIC_VOLUME_LEVEL_2;
break;
case MIC_VOLUME_LEVEL3:
real_volume = MIC_VOLUME_LEVEL_3;
break;
case MIC_VOLUME_LEVEL4:
real_volume = MIC_VOLUME_LEVEL_4;
break;
case MIC_VOLUME_LEVEL5:
real_volume = MIC_VOLUME_LEVEL_5;
break;
case MIC_VOLUME_LEVEL6:
real_volume = MIC_VOLUME_LEVEL_6;
break;
case MIC_VOLUME_LEVEL7:
real_volume = MIC_VOLUME_LEVEL_7;
break;
default:
syslog(LOG_ERR, "Not the correct parameter");
return 0;
}
return real_volume;
}
int lynq_set_mic_volume(const int volume) {
int real_volume;
if((volume>MIC_VOLUME_LEVEL7)||(volume<MIC_VOLUME_LEVEL1))
return 1;
lynq_set_mic_volume_to_nvram(volume);
real_volume = get_mic_real_volume(volume);
lynq_set_mic_real_volume(real_volume);
return 0;
}
int lynq_get_mic_volume(int* volume) {
if(volume==NULL)
{
return 1;
}
(*volume) = lynq_get_mic_current_volume();
return 0;
}
int lynq_get_spk_current_volume()
{
char cvolume_levle[5] = {0};
property_get(NV_VOLUME_NAME, cvolume_levle, "5");
printf("lynq_media_get_current_volume end :%s\n" ,cvolume_levle);
return atoi(cvolume_levle);
}
static void lynq_set_spk_volume_to_nvram(const int volume_levle )
{
char buf[5] = {0};
sprintf(buf, "%d", volume_levle);
property_set(NV_VOLUME_NAME, buf);
}
static int lynq_set_spk_real_volume(const int volume)
{
char cmd[256];
RLOGD("spk real volume: %d \n", volume);
// sprintf(cmd, "amixer -c0 cset name=\"Playback Volume\" %d", volume);
sprintf(cmd, "amixer cset name=\"Master Playback Volume\" %d", volume);
system(cmd);
return 0;
}
static int get_spk_real_volume(const int volume_levle)
{
int real_volume;
switch (volume_levle) {
case VOLUME_LEVEL1:
real_volume = VOLUME_LEVEL_1;
break;
case VOLUME_LEVEL2:
real_volume = VOLUME_LEVEL_2;
break;
case VOLUME_LEVEL3:
real_volume = VOLUME_LEVEL_3;
break;
case VOLUME_LEVEL4:
real_volume = VOLUME_LEVEL_4;
break;
case VOLUME_LEVEL5:
real_volume = VOLUME_LEVEL_5;
break;
case VOLUME_LEVEL6:
real_volume = VOLUME_LEVEL_6;
break;
case VOLUME_LEVEL7:
real_volume = VOLUME_LEVEL_7;
break;
default:
syslog(LOG_ERR, "Not the correct parameter");
return 0;
}
return real_volume;
}
int lynq_spk_volume_up()
{
int real_volume,current_volume;
current_volume = lynq_get_spk_current_volume();
if(VOLUME_LEVEL7 == current_volume)
{
return 1;
}
else
{
lynq_set_spk_volume_to_nvram(current_volume+1);
real_volume = get_spk_real_volume(current_volume+1);
lynq_set_spk_real_volume(real_volume);
return 0;
}
}
int lynq_spk_volume_down()
{
int real_volume,current_volume;
current_volume = lynq_get_spk_current_volume();
if(VOLUME_LEVEL1 == current_volume)
{
return 1;
}
else
{
lynq_set_spk_volume_to_nvram(current_volume-1);
real_volume = get_spk_real_volume(current_volume-1);
lynq_set_spk_real_volume(real_volume);
return 0;
}
}
int lynq_set_spk_volume(const int volume)
{
if((volume>VOLUME_LEVEL7)||(volume<VOLUME_LEVEL1))
return 1;
lynq_set_spk_volume_to_nvram(volume);
int real_volume = get_spk_real_volume(volume);
lynq_set_spk_real_volume(real_volume);
return 0;
}
int lynq_get_spk_volume(int* volume) {
if(volume==NULL)
{
return 1;
}
(*volume) = lynq_get_spk_current_volume();
return 0;
}
static int media_stop_full(MEDIA_PARAM_T *param)
{
GMainLoop *loop = param->loop;
GstElement *playbin = param->playbin;
guint bus_watch_id = param->bus_watch_id;
GstEvent *event_stop = NULL;
if (param != param->handle) {
RLOGE("invalid handle: %p \n", param->handle);
return 1;
}
param->handle = NULL;
gst_element_set_state (playbin, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (playbin));
g_source_remove (bus_watch_id);
g_main_loop_unref (loop);
free(param);
param = NULL;
g_media_handle=NULL;
return 0;
}
void* media_thread_func(void *arg)
{
MEDIA_PARAM_T *param = (MEDIA_PARAM_T *)arg;
RLOGD("%s start \n", __FUNCTION__);
g_main_loop_run (param->loop);
RLOGD("g_main_loop_run end \n");
media_stop_full(param);
return ((void *)0);
}
static void start_main_loop(const MEDIA_PARAM_T *param)
{
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&(param->thread), &attr, (void *)media_thread_func, param);
}
int lynq_media_play_audio(const char *path)
{
GstBus *bus;
GstMessage *msg;
GMainLoop *loop;
GstElement *playbin;
gchar *uri;
guint bus_watch_id;
int ret;
pthread_t thread;
int cnt;
MEDIA_HANDLE handle = NULL;
MEDIA_PARAM_T *param;
if(g_media_handle!=NULL)
{
RLOGE ("media is running.\n");
return 1;
}
param = malloc(sizeof(MEDIA_PARAM_T));
if (param == NULL) {
RLOGE ("malloc MEDIA_PARAM_T fail \n");
return 1;
}
memset(param, 0, sizeof(MEDIA_PARAM_T));
handle = (MEDIA_HANDLE)param;
g_media_handle=handle;
param->mute = 0;
param->volume = 1.0;
gst_init (NULL, NULL);
loop = g_main_loop_new (NULL, FALSE);
playbin = gst_element_factory_make ("playbin", "playbin");
RLOGD ("main start.\n");
if (!playbin) {
g_printerr ("Not all elements could be created.\n");
free(param);
g_media_handle=NULL;
return 1;
}
if (gst_uri_is_valid (path))
uri = g_strdup (path);
else
uri = gst_filename_to_uri (path, NULL);
g_object_set (playbin, "uri", uri, NULL);
g_object_set (playbin, "flags",0x42,NULL);
g_object_set (playbin, "volume",param->volume,NULL);
g_object_set (playbin, "mute",param->mute,NULL);
bus = gst_element_get_bus (playbin);
bus_watch_id = gst_bus_add_watch (bus, bus_call, (gpointer)param);
g_object_unref (bus);
param->playbin = playbin;
param->bus_watch_id = bus_watch_id;
param->thread = thread;
param->loop = loop;
param->handle = handle;
start_main_loop(param);
RLOGD ("gst_bus_add_watch.\n");
gst_element_set_state (playbin, GST_STATE_PLAYING);
cnt=0;
do {
if (param->gst_cur_state == GST_STATE_PLAYING)
{
break;
}
else
{
if (cnt==6){
RLOGD ("After 6s, not enter playing state.\n");
lynq_media_stop_audio();
return 1;
}
cnt++;
sleep(1);
}
} while (1);
RLOGD ("lynq_media_play_audio end, handle is %p\n",handle);
return 0;
}
void lynq_media_stop_audio()
{
if (g_media_handle == NULL) {
RLOGE ("%s, g_media_handle is NULL\n", __FUNCTION__);
return;
}
MEDIA_PARAM_T *param = (MEDIA_PARAM_T *)g_media_handle;
if (g_media_handle != param->handle) {
RLOGE("invalid handle: %p \n", g_media_handle);
}
g_main_loop_quit (param->loop);
pthread_join(param->thread, NULL);
RLOGD ("lynq_media_stop_audio end\n");
return;
}