blob: 378f1f4cd59bec9990ee1a3566e439d01ec84dd2 [file] [log] [blame]
/*
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All rights reserved.
*
*/
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your pconfigion) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Description: New gplay application use new playengine
* Author: Haihua Hu
* Create Data: 2015/06/24
* Modify By: Haihua Hu
* Modify Data: 2015/08/03
* Change log:
*/
#include <termio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include "playengine.h"
#include "playlist.h"
/* version information of gplay */
#define FSL_PLAYENGINE_VERSION "FSL_GPLAY_01.00"
#define OS_NAME "_LINUX"
#define SEPARATOR " "
#define FSL_PLAYENGINE_VERSION_STR \
(FSL_PLAYENGINE_VERSION OS_NAME SEPARATOR "build on" \
SEPARATOR __DATE__ SEPARATOR __TIME__)
typedef enum{
PLAYER_REPEAT_NONE = 0,
PLAYER_REPEAT_PLAYLIST = 1,
PLAYER_REPEAT_CURRENT = 2,
} repeat_mode;
typedef struct{
gchar *video_sink_name;
gchar *audio_sink_name;
gchar *text_sink_name;
gchar *suburi;
PlayListHandle pl;
const gchar *current;
repeat_mode repeat;
gint play_times;
gint timeout;
gint display_refresh_frq;
gboolean no_auto_next;
gboolean handle_buffering;
}gplay_pconfigions;
/* used by display thread and event callback */
typedef struct{
PlayEngine *engine;
gplay_pconfigions *options;
}CustomData;
static volatile gboolean gexit_main = FALSE;
static volatile gboolean gexit_display_thread = FALSE;
static volatile gboolean gDisable_display = FALSE;
void
alarm_signal(int signum)
{
}
void
set_alarm(guint seconds)
{
struct sigaction act;
/* Register alarm handler for alarm */
act.sa_handler = &alarm_signal;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGALRM, &act, NULL);
/* Set timer for seconds */
alarm(seconds);
}
PlayEngineResult
playlist_next(PlayEngine *engine,
gplay_pconfigions *options)
{
if(options->repeat > PLAYER_REPEAT_CURRENT || options->repeat < PLAYER_REPEAT_NONE)
{
g_print("Unknown repeat mode\n");
return PLAYENGINE_FAILURE;
}
switch( options->repeat )
{
case PLAYER_REPEAT_NONE:
{
options->current = getNextItem(options->pl);
if(options->current)
{
g_print("Now Playing: %s\n", options->current);
engine->set_file((PlayEngineHandle)engine, options->current);
engine->play((PlayEngineHandle)engine);
}
else
{
gboolean islast = FALSE;
isLastItem(options->pl, &islast);
if(islast)
{
g_print("No more media file, exit gplay!\n");
}else
{
g_print("playlist unknown error\n");
}
return PLAYENGINE_FAILURE;
}
}
break;
case PLAYER_REPEAT_PLAYLIST:
{
options->current = getNextItem(options->pl);
if(options->current)
{
printf("Now Playing: %s\n", options->current);
engine->set_file((PlayEngineHandle)engine, options->current);
engine->play((PlayEngineHandle)engine);
}
else
{
gboolean islast = FALSE;
isLastItem(options->pl, &islast);
if(islast)
{
if (options->play_times>0){
options->play_times--;
if (options->play_times == 0) {
g_print("Repeat mode finished\n");
return PLAYENGINE_FAILURE;
}
}
options->current = getFirstItem(options->pl);
if(options->current)
{
printf("Now Playing: %s\n", options->current);
engine->set_file((PlayEngineHandle)engine, options->current);
engine->play((PlayEngineHandle)engine);
}
}else
{
g_print("playlist unknown error\n");
return PLAYENGINE_FAILURE;
}
}
}
break;
case PLAYER_REPEAT_CURRENT:
{
engine->play((PlayEngineHandle)engine);
}
break;
default:
break;
}
return PLAYENGINE_SUCCESS;
}
PlayEngineResult
playlist_previous(PlayEngine *engine,
gplay_pconfigions * options)
{
gchar iName[1024];
if(options->repeat > PLAYER_REPEAT_CURRENT || options->repeat < PLAYER_REPEAT_NONE)
{
g_print("Unknown repeat mode\n");
return PLAYENGINE_FAILURE;
}
switch( options->repeat )
{
case PLAYER_REPEAT_NONE:
{
options->current = getPrevItem(options->pl);
if(options->current)
{
g_print("Now Playing: %s\n", options->current);
engine->set_file((PlayEngineHandle)engine, options->current);
engine->play((PlayEngineHandle)engine);
}
else
{
gboolean isFirst = FALSE;
isFirstItem(options->pl, &isFirst);
if(isFirst)
{
g_print("No more media file, exit gplay!\n");
}else
{
g_print("playlist unknown error\n");
}
return PLAYENGINE_FAILURE;
}
}
break;
case PLAYER_REPEAT_PLAYLIST:
{
options->current = getPrevItem(options->pl);
if(options->current)
{
printf("Now Playing: %s\n", options->current);
engine->set_file((PlayEngineHandle)engine, options->current);
engine->play((PlayEngineHandle)engine);
}
else
{
gboolean isFirst = FALSE;
isFirstItem(options->pl, &isFirst);
if(isFirst)
{
if (options->play_times>0){
options->play_times--;
if (options->play_times == 0) {
g_print("Repeat mode finished\n");
return PLAYENGINE_FAILURE;
}
}
options->current = getLastItem(options->pl);
if(options->current)
{
printf("Now Playing: %s\n", options->current);
engine->set_file((PlayEngineHandle)engine, options->current);
engine->play((PlayEngineHandle)engine);
}
}else
{
g_print("playlist unknown error\n");
return PLAYENGINE_FAILURE;
}
}
}
break;
case PLAYER_REPEAT_CURRENT:
{
engine->play((PlayEngineHandle)engine);
}
break;
default:
break;
}
return PLAYENGINE_SUCCESS;
}
void
event_callback(void *context,
EventType EventID,
void *Eventpayload)
{
CustomData * PlayData = (CustomData *)context;
if(!PlayData || !PlayData->engine || !PlayData->options)
{
g_print("player pointer is invalid!\n");
gexit_main = TRUE;
gexit_display_thread = TRUE;
set_alarm(1);
return;
}
gplay_pconfigions *options = PlayData->options;
PlayEngine *engine = PlayData->engine;
switch(EventID)
{
case EVENT_ID_EOS:
{
/* for auto test script */
g_print("EOS Found\n");
engine->stop((PlayEngineHandle)engine);
if(!options->no_auto_next)
{
if(playlist_next(engine, options) != PLAYENGINE_SUCCESS)
{
gexit_main = TRUE;
gexit_display_thread = TRUE;
set_alarm(1);
}else{
g_print("play next item successfully\n");
}
}else{
g_print("no auto next is on\n");
gexit_main = TRUE;
gexit_display_thread = TRUE;
set_alarm(1);
}
}
break;
case EVENT_ID_ERROR:
{
const gchar * errstr = (gchar *)Eventpayload;
if(errstr)
g_print("gplay meet internal error: %s\n",errstr);
engine->stop((PlayEngineHandle)engine);
gexit_main = TRUE;
gexit_display_thread = TRUE;
set_alarm(1);
}
break;
case EVENT_ID_STATE_CHANGE:
{
/* to do here to process state change */
PlayEngineState *state = (PlayEngineState *)Eventpayload;
if(state)
g_print("State change from %s to %s\n",gst_element_state_get_name(state->old_st),
gst_element_state_get_name(state->new_st));
}
break;
case EVENT_ID_BUFFERING:
{
/* to do here to process buffering */
const gint *percent = (gint *)Eventpayload;
if(options->handle_buffering){
if(percent){
g_print("\r\t\t\t\t\t\t%s %d%%", "buffering...", *percent);
if(*percent == 0)
{
engine->pause((PlayEngineHandle)engine);
}else if(*percent >= 100)
{
engine->play((PlayEngineHandle)engine);
}
}
}
}
break;
default:
break;
}
}
void
print_help()
{
g_print ("options :\n");
g_print (" --quiet Disable playback status display updating\n\n");
g_print (" --repeat Set gplay to playlist repeat mode.\n");
g_print (" Use below option to specify your repeat times\n");
g_print (" --repeat=PlayTimes\n\n");
g_print (" --video-sink Specify the video sink instead of default sink\n");
g_print (" Use below option to input your video sink name\n");
g_print (" --video-sink=video_sink_name\n\n");
g_print (" --audio-sink Specify the audio sink instead of default sink\n");
g_print (" Use below option to input your audio sink name\n");
g_print (" --audio-sink=audio_sink_name\n\n");
g_print (" --text-sink Specify the text sink instead of default sink\n");
g_print (" Use below option to input your text sink name\n");
g_print (" --text-sink=text_sink_name\n\n");
g_print (" --suburi Set subtitle path\n");
g_print (" Use below option to input your pathname\n");
g_print (" --suburi=pathname\n\n");
}
PlayEngineResult
parse_pconfigions(gplay_pconfigions *pconfig,
gint32 argc,
gchar* argv[])
{
gint32 i;
pconfig->pl = createPlayList();
if ((void *)pconfig->pl == NULL){
printf("Can not create Playlist!!\n");
return PLAYENGINE_FAILURE;
}
pconfig->play_times = -1;
for (i=1;i<argc;i++){
if (strlen(argv[i])) {
if (argv[i][0]=='-'){
if ((strcmp(argv[i], "-h")==0)||(strcmp(argv[i], "--help")==0)){
g_print ("Usage: gplay-1.0 [OPTIONS] PATH [PATH...]\n");
print_help();
goto err;
}
if (strcmp(argv[i], "--quiet")==0){
pconfig->display_refresh_frq = 0;
continue;
}
if (strncmp(argv[i], "--repeat", 8)==0){
if (argv[i][8]=='='){
pconfig->play_times = atoi(&(argv[i][9]));
}
pconfig->repeat = PLAYER_REPEAT_PLAYLIST;
continue;
}
if ((strncmp(argv[i], "--video-sink", 12)==0)){
if (argv[i][12]=='='){
pconfig->video_sink_name = &(argv[i][13]);
}
continue;
}
if ((strncmp(argv[i], "--audio-sink", 12)==0)){
if (argv[i][12]=='='){
pconfig->audio_sink_name = &(argv[i][13]);
}
continue;
}
if ((strncmp(argv[i], "--text-sink", 11)==0)) {
if (argv[i][11]=='=') {
pconfig->text_sink_name = &(argv[i][12]);
}
continue;
}
if ((strncmp(argv[i], "--suburi", 8)==0)) {
if (argv[i][8]=='=') {
pconfig->suburi = &(argv[i][9]);
}
continue;
}
if (strncmp(argv[i], "--timeout", 9)==0){
if (argv[i][9]=='='){
pconfig->timeout = atoi(&(argv[i][10]));
}
continue;
}
if ((strncmp(argv[i], "--info-interval", 14)==0)){
if (argv[i][14]=='='){
pconfig->display_refresh_frq = atoi(&(argv[i][15]));
}
continue;
}
if ((strcmp(argv[i], "--noautonext") == 0)) {
pconfig->no_auto_next = TRUE;
continue;
}
if ((strcmp(argv[i], "--handle-buffering")==0)){
pconfig->handle_buffering = TRUE;
continue;
}
continue;
}else{
if(addItemAtTail(pconfig->pl, argv[i]) != PLAYENGINE_SUCCESS)
goto err;
continue;
}
}
}
pconfig->current = getFirstItem(pconfig->pl);
if(pconfig->current == NULL)
{
g_print("NO File specified!!\n");
goto err;
}
return PLAYENGINE_SUCCESS;
err:
if (pconfig->pl){
destroyPlayList(pconfig->pl);
pconfig->pl=NULL;
}
return PLAYENGINE_FAILURE;
}
void
display_thread_fun(gpointer data)
{
CustomData * PlayData = (CustomData *)data;
gchar str_repeated_mode[3][20] = {"(No Repeated)", "(List Repeated)", "(Current Repeated)"};
if(!PlayData || !PlayData->engine || !PlayData->options)
{
g_print("Invalid Custom Data pointer\n");
return;
}
PlayEngine * engine = PlayData->engine;
gplay_pconfigions *options = PlayData->options;
while(1)
{
if( TRUE == gexit_display_thread )
{
g_print("Exit display thread\n");
engine->stop_wait_state_change((PlayEngineHandle)engine);
return;
}
if( FALSE == gDisable_display )
{
gchar str_player_state_rate[16];
gchar str_volume[16];
gchar* prepeated_mode = &(str_repeated_mode[options->repeat][0]);
guint64 hour, minute, second;
guint64 hour_d, minute_d, second_d;
guint64 duration=0;
guint64 elapsed=0;
GstState player_state = GST_STATE_NULL;
gdouble playback_rate = 0.0;
gboolean bmute = 0;
gdouble volume = 0.0;
engine->get_duration((PlayEngineHandle)engine, &duration);
engine->get_position((PlayEngineHandle)engine, &elapsed);
engine->get_state((PlayEngineHandle)engine, &player_state);
engine->get_play_rate((PlayEngineHandle)engine, &playback_rate);
engine->get_mute((PlayEngineHandle)engine, &bmute);
engine->get_volume((PlayEngineHandle)engine, &volume);
if(duration == GST_CLOCK_TIME_NONE || elapsed == GST_CLOCK_TIME_NONE)
continue;
hour = (elapsed/ (gint64)3600000000000);
minute = (elapsed / (guint64)60000000000) - (hour * 60);
second = (elapsed / 1000000000) - (hour * 3600) - (minute * 60);
hour_d = (duration/ (guint64)3600000000000);
minute_d = (duration / (guint64)60000000000) - (hour_d * 60);
second_d = (duration / 1000000000) - (hour_d * 3600) - (minute_d * 60);
switch(player_state)
{
case GST_STATE_PLAYING:
{
if( playback_rate > 1.0 && playback_rate <= 8.0 )
{
sprintf(str_player_state_rate, "%s(%1.1fX)", "FF ", playback_rate);
}
if( playback_rate > 0.0 && playback_rate < 1.0 )
{
sprintf(str_player_state_rate, "%s(%1.1fX)", "SF ", playback_rate);
}
if( playback_rate >= -8.0 && playback_rate <= -0.0 )
{
sprintf(str_player_state_rate, "%s(%1.1fX)", "FB ", playback_rate);
}
if( playback_rate == 1.0 )
{
sprintf(str_player_state_rate, "%s", "Playing ");
}
}
break;
case GST_STATE_PAUSED:
sprintf(str_player_state_rate, "%s", "Pause ");
break;
case GST_STATE_READY:
sprintf(str_player_state_rate, "%s", "Ready ");
case GST_STATE_NULL:
sprintf(str_player_state_rate, "%s", "Stop ");
break;
default:
sprintf(str_player_state_rate, "%s", "Unknown ");
break;
}
if( bmute )
{
sprintf(str_volume, "%s", "MUTE ");
}
else
{
sprintf(str_volume, "Vol=%.1lf", volume);
}
g_print("\r[%s%s][%s][%02d:%02d:%02d/%02d:%02d:%02d]",
str_player_state_rate, prepeated_mode, str_volume,
(gint32)hour, (gint32)minute, (gint32)second,
(gint32)hour_d, (gint32)minute_d, (gint32)second_d);
fflush (stdout);
}
sleep(1);
}
}
void
print_metadata(PlayEngine *engine)
{
gint64 duration=0;
imx_metadata metadata;
gint32 i;
if(!engine)
{
g_print("PlayEngine pointer invalid, print metadata failed\n");
return;
}
engine->get_metadata((PlayEngineHandle)engine, &metadata);
engine->get_duration((PlayEngineHandle)engine, &duration);
/* g_print not support Chinese, should use printf when show metadata */
printf("\nMedia URI: %s\n", metadata.pathname);
printf("\tContainer: %s\n", metadata.container);
printf("\tDuration: %d seconds\n", (gint32)(duration/1000000000));
printf("\tTitle: %s\n", metadata.title);
printf("\tAritist: %s\n", metadata.artist);
printf("\tAlbum: %s\n", metadata.album);
printf("\tCreationDate: %s\n", metadata.year);
printf("\tGenre: %s\n", metadata.genre);
printf("\tAlbumartist: %s\n", metadata.albumartist);
printf("\tComposer: %s\n", metadata.composer);
printf("\tCopyright: %s\n", metadata.copyright);
printf("\tDescription: %s\n", metadata.description);
printf("\tPerformer: %s\n", metadata.performer);
printf("\tKeywords: %s\n", metadata.keywords);
printf("\tComment: %s\n", metadata.comment);
printf("\tTool: %s\n", metadata.tool);
printf("\tLocation latitude: %s\n", metadata.location_latitude);
printf("\tLocation longtitude: %s\n", metadata.location_longtitude);
printf("\tTrackCount: %d\n", metadata.track_count);
printf("\tTrackNumber: %d\n", metadata.track_number);
printf("\tDiscNumber: %d\n", metadata.disc_number);
printf("\tRating: %d\n", metadata.rating);
for (i=0; i<metadata.n_audio; i++) {
printf("Audio%d:\n", i);
printf("\tCodec: %s\n", metadata.audio_info[i].codec_type);
printf("\tSample Rate: %d\n", metadata.audio_info[i].samplerate);
printf("\tChannels: %d\n", metadata.audio_info[i].channels);
printf("\tBitrate: %d\n", metadata.audio_info[i].bitrate);
printf("\tLanguage Code: %s\n", metadata.audio_info[i].language);
}
for (i=0; i<metadata.n_video; i++) {
printf("Video%d:\n", i);
printf("\tCodec: %s\n", metadata.video_info[i].codec_type);
printf("\tWidth: %d\n", metadata.video_info[i].width);
printf("\tHeight: %d\n", metadata.video_info[i].height);
printf("\tFrame Rate: %f\n", (float)metadata.video_info[i].framerate_numerator / (float)metadata.video_info[i].framerate_denominator);
printf("\tBitrate: %d\n", metadata.video_info[i].bitrate);
printf("\tLanguage Code: %s\n", metadata.video_info[i].language);
}
for (i=0; i<metadata.n_subtitle; i++) {
printf("subtitle%d:\n", i);
printf("\tCodec: %s\n", metadata.subtitle_info[i].codec_type);
printf("\tLanguage Code: %s\n", metadata.subtitle_info[i].language);
}
}
void
print_menu()
{
g_print("\n%s\n", FSL_PLAYENGINE_VERSION_STR);
g_print("\t[h]display the operation Help\n");
g_print("\t[p]Play\n");
g_print("\t[s]Stop\n");
g_print("\t[e]Seek\n");
g_print("\t[a]Pause when playing, play when paused\n");
g_print("\t[v]Volume\n");
g_print("\t[m]Switch to mute or not\n");
g_print("\t[>]Play next file\n");
g_print("\t[<]Play previous file\n");
g_print("\t[r]Switch to repeated mode or not\n");
g_print("\t[u]Select the video track\n");
g_print("\t[d]Select the audio track\n");
g_print("\t[b]Select the subtitle track\n");
g_print("\t[f]Set full screen\n");
g_print("\t[z]resize the width and height\n");
g_print("\t[t]Rotate\n");
g_print("\t[c]Setting play rate\n");
g_print("\t[i]Display the metadata\n");
g_print("\t[x]eXit\n");
}
static void
signal_handler(int sig)
{
switch(sig)
{
case SIGINT:
g_print(" Aborted by signal[%d] Interrupt...\n", sig);
gexit_main = TRUE;
gexit_display_thread = TRUE;
break;
case SIGTTIN:
/* Nothing need do */
break;
default:
break;
}
}
static void
reset_signal(int sig, void *handler)
{
if(!handler)
return;
struct sigaction act;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(sig, &act, NULL);
}
int
main(int argc,char *argv[])
{
gchar sCommand[256];
PlayEngine * playengine = NULL;
gplay_pconfigions options;
GThread * display_thread = NULL;
CustomData PlayData;
reset_signal(SIGINT, signal_handler);
/* support gplay to run in backend */
reset_signal(SIGTTIN, signal_handler);
if( argc < 2 )
{
g_print ("Use -h or --help to see help message.\n");
g_print ("Usage: gplay-1.0 [OPTIONS] PATH [PATH...]\n");
print_help();
return PLAYENGINE_FAILURE;
}
memset(&options, 0, sizeof(gplay_pconfigions));
options.play_times = 0;
options.repeat = PLAYER_REPEAT_NONE;
options.no_auto_next = FALSE;
options.handle_buffering = FALSE;
options.display_refresh_frq = 1;
//strcpy(options.text_sink_name,"fakesink");
if(parse_pconfigions(&options, argc, argv) != PLAYENGINE_SUCCESS)
{
return PLAYENGINE_FAILURE;
}
/* create playback engine */
playengine = play_engine_create();
/* check if the play engine is created successfully */
if(!playengine)
{
g_print("Create play engine failed!\n");
return PLAYENGINE_FAILURE;
}
PlayData.engine = playengine;
PlayData.options = &options;
if(options.timeout != 0)
{
playengine->set_state_change_timeout((PlayEngineHandle)playengine, options.timeout);
}
if (!options.video_sink_name)
if(play_engine_checkfeature(PLAYENGINE_G2D)) {
options.video_sink_name = "overlaysink";
}else {
options.video_sink_name = "imxv4l2sink";
}
g_print("Set VideoSink %s\n", options.video_sink_name);
playengine->set_video_sink((PlayEngineHandle)playengine, options.video_sink_name);
if (options.audio_sink_name){
g_print("Set AudioSink %s\n", options.audio_sink_name);
playengine->set_audio_sink((PlayEngineHandle)playengine, options.audio_sink_name);
}
if (options.text_sink_name) {
g_print("Set TextSink %s\n", options.text_sink_name);
playengine->set_text_sink((PlayEngineHandle)playengine, options.text_sink_name);
}
if (options.suburi)
{
/* load usr define subtitle uri */
g_print("Load subtitle: %s\n",options.suburi);
playengine->set_subtitle_uri((PlayEngineHandle)playengine, options.suburi);
}else
{
/* if there is dafault subtitle file, try to load - not support now*/
}
playengine->reg_event_handler((PlayEngineHandle)playengine, &PlayData, event_callback);
if(playengine->set_file(playengine,options.current) != PLAYENGINE_SUCCESS)
{
g_print("set file failed\n");
if(options.pl)
destroyPlayList(options.pl);
options.pl = NULL;
if(playengine)
play_engine_destroy(playengine);
playengine = NULL;
return PLAYENGINE_FAILURE;
}
if(options.display_refresh_frq != 0)
{
display_thread = g_thread_new("display_thread", (GThreadFunc)display_thread_fun, &PlayData);
}
if(playengine->play((PlayEngineHandle)playengine) !=PLAYENGINE_SUCCESS)
{
g_print("try to play failed\n");
if(options.pl)
destroyPlayList(options.pl);
options.pl = NULL;
if(playengine)
play_engine_destroy(playengine);
playengine = NULL;
gexit_display_thread = TRUE;
if(display_thread)
g_thread_join(display_thread);
return PLAYENGINE_FAILURE;
}
/* for auto test script */
g_print("%s\n","fsl_player_play()");
fflush(stdout);
print_menu();
while(gexit_main == FALSE){
sCommand[0] = ' ';
errno = 0;
if(scanf("%256s", sCommand) != 1){
continue;
}
switch( sCommand[0] )
{
case 'h': // display the operation Help.
print_menu();
break;
case 'p': // Play.
{
GstState player_state = GST_STATE_NULL;
playengine->get_state((PlayEngineHandle)playengine,&player_state);
if (player_state == GST_STATE_NULL) {
playengine->set_file(playengine, options.current);
playengine->play(playengine);
}
}
break;
case 's': // Stop
{
playengine->stop((PlayEngineHandle)playengine);
}
break;
case 'a': // pAuse
{
GstState player_state = GST_STATE_NULL;
playengine->get_state((PlayEngineHandle)playengine, &player_state);
if (player_state == GST_STATE_NULL) {
playengine->set_file(playengine, options.current);
playengine->play(playengine);
}else if(player_state == GST_STATE_PLAYING)
playengine->pause((PlayEngineHandle)playengine);
else if(player_state == GST_STATE_PAUSED)
playengine->play((PlayEngineHandle)playengine);
}
break;
case 'e': // sEek
{
guint32 seek_point_sec = 0;
guint64 duration_ns = 0;
guint64 duration_sec = 0;
guint32 seek_portion = 0;
gboolean accurate_seek = FALSE;//
gint input_mode = -1;
gboolean seekable = FALSE;
gDisable_display = TRUE;
playengine->get_seekable((PlayEngineHandle)playengine, &seekable);
if(!seekable){
g_print("file is not seekable!\n");
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
break;
}
playengine->get_duration((PlayEngineHandle)playengine, &duration_ns);
duration_sec = duration_ns / 1000000000;
//kb_restore_term(STDIN_FILENO);
g_print("Select seek mode[Fast seek:0,Accurate seek:1]:");
if(scanf("%d",&input_mode) != 1)
{
gDisable_display = FALSE;
break;
}
if( input_mode != 0 && input_mode != 1 )
{
g_print("Invalid seek mode!\n");
gDisable_display = FALSE;
break;
}else{
accurate_seek = (gboolean)input_mode;
}
g_print("%s seek to percentage[0:100] or second [t?]:", accurate_seek?"Accurate":"Normal");
if(scanf("%256s",sCommand) != 1)
{
gDisable_display = FALSE;
break;
}
if (sCommand[0]=='t'){
seek_point_sec = atoi(&sCommand[1]);
}else{
seek_portion = atoi(sCommand);
if( seek_portion>100 )
{
g_print("Invalid seek point!\n");
gDisable_display = FALSE;
break;
}
seek_point_sec = (guint64)(seek_portion * duration_sec / 100);
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
playengine->seek((PlayEngineHandle)playengine, seek_point_sec, accurate_seek);
}
break;
case 'v': //Volume
{
gdouble volume;
g_print("Set volume[0-1.0]:");
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%lf",&volume) != 1)
{
gDisable_display = FALSE;
break;
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
playengine->set_volume((PlayEngineHandle)playengine, volume);
}
break;
case 'm':
{
gboolean mute_status = FALSE;
playengine->get_mute((PlayEngineHandle)playengine, &mute_status);
if(mute_status == FALSE)
{
playengine->set_mute((PlayEngineHandle)playengine, TRUE);
}else
{
playengine->set_mute((PlayEngineHandle)playengine, FALSE);
}
}
break;
case 'c': // playing direction and speed Control.
{
gdouble playback_rate;
g_print("Set playing speed[-8,-4,-2,0.125,0.25,0.5,1,2,4,8]:");
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%lf",&playback_rate) != 1)
{
gDisable_display = FALSE;
break;
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
playengine->set_play_rate((PlayEngineHandle)playengine, playback_rate);
}
break;
case 'i':
print_metadata((PlayEngineHandle)playengine);
break;
case 'x':// eXit
{
playengine->stop((PlayEngineHandle)playengine);
g_print("Ready to exit this app!\n");
gexit_main = TRUE;
gexit_display_thread = TRUE;
}
break;
case 'r': // Switch to repeated mode or not
{
gint setrepeat;
g_print("input repeated mode[0 for no repeated,1 for play list repeated, 2 for current file repeated]:");
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%d",&setrepeat) != 1)
{
gDisable_display = FALSE;
break;
}
if( setrepeat<0 || setrepeat>2 )
{
g_print("Invalid repeated mode!\n");
}
else
{
options.repeat = setrepeat;
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
}
break;
case '>': // Play next file
g_print("next\n");
playengine->stop((PlayEngineHandle)playengine);
if (playlist_next(playengine, &options) != PLAYENGINE_SUCCESS)
{
gexit_main = TRUE;
gexit_display_thread = TRUE;
set_alarm(1);
}
break;
case '<': // Play previous file
g_print("previous\n");
playengine->stop((PlayEngineHandle)playengine);
if(playlist_previous(playengine, &options) != PLAYENGINE_SUCCESS)
{
gexit_main = TRUE;
gexit_display_thread = TRUE;
set_alarm(1);
}
break;
case 't': // Rotate 90 degree every time
{
gint rotate_value;
g_print("Set rotation between 0, 90, 180, 270: ");
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%d",&rotate_value) != 1)
{
gDisable_display = FALSE;
break;
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
if(rotate_value != 0 && rotate_value != 90 && rotate_value != 180 && rotate_value != 270 )
{
g_print("Invalid rotation value=%d, should input [0, 90, 180, 270]\n", rotate_value);
break;
}
playengine->set_rotate((PlayEngineHandle)playengine, rotate_value);
}
break;
case 'z': // resize the width and height
{
DisplayArea area;
guint x = 0;
guint y = 0;
guint width = 0;
guint height = 0;
g_print("Input [x y width height]:");
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%d %d %d %d", &x, &y, &width, &height) != 4)
{
gDisable_display = FALSE;
break;
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
area.offsetx = x;
area.offsety = y;
area.width = width;
area.height = height;
playengine->set_render_rect((PlayEngineHandle)playengine, area);
playengine->expose_video((PlayEngineHandle)playengine);
}
break;
case 'f':
{
playengine->set_fullscreen((PlayEngineHandle)playengine);
playengine->expose_video((PlayEngineHandle)playengine);
}
break;
case 'u': // Select the video track
{
gint32 video_track_no = 0;
gint32 total_video_no = 0;
guint64 elapsed=0;
playengine->get_video_num((PlayEngineHandle)playengine, &total_video_no);
g_print("input video track number[0,%d]:",total_video_no-1);
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%d",&video_track_no) != 1)
{
gDisable_display = FALSE;
break;
}
if( video_track_no < 0 || video_track_no > total_video_no-1 )
{
g_print("Invalid video track!\n");
}
else
{
playengine->select_video((PlayEngineHandle)playengine, video_track_no);
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
}
break;
case 'd': // Select the audio track
{
gint32 audio_track_no = 0;
gint32 total_audio_no = 0;
guint64 elapsed=0;
playengine->get_audio_num((PlayEngineHandle)playengine, &total_audio_no);
g_print("input audio track number[0,%d]:",total_audio_no-1);
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%d",&audio_track_no) != 1)
{
gDisable_display = FALSE;
break;
}
if( audio_track_no < 0 || audio_track_no > total_audio_no-1 )
{
g_print("Invalid audio track!\n");
}
else
{
playengine->select_audio((PlayEngineHandle)playengine, audio_track_no);
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
}
break;
case 'b': // Select the subtitle
{
gint32 subtitle_no = 0;
gint32 total_subtitle_no = 0;
playengine->get_subtitle_num((PlayEngineHandle)playengine, &total_subtitle_no);
g_print("input subtitle number[0,%d]:",total_subtitle_no-1);
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%d",&subtitle_no) != 1)
{
gDisable_display = FALSE;
break;
}
if( subtitle_no < 0 || subtitle_no > total_subtitle_no-1 )
{
g_print("Invalid subtitle track!\n");
}
else
{
playengine->select_subtitle((PlayEngineHandle)playengine, subtitle_no);
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
}
break;
case '*':// sleep 1 second
{
sleep(1);
}
break;
case '#':// sleep 10 seconds
{
sleep(10);
}
break;
case 'q': // Query information
{
g_print("Input query type[v:has video?, e:seekable?, s:state, p:position, u:duration, z:size, t:rotation, c:play rate]:\n");
//kb_restore_term(STDIN_FILENO);
gDisable_display = TRUE;
if(scanf("%256s",sCommand) != 1)
{
gDisable_display = FALSE;
break;
}
gDisable_display = FALSE;
//kb_set_raw_term(STDIN_FILENO);
switch(sCommand[0])
{
case 'v':
{
gint video_num = 0;
playengine->get_video_num((PlayEngineHandle)playengine, &video_num);
g_print("Number of Video Streams : %d\n", video_num);
}
break;
case 'e':
{
gboolean seekable = FALSE;
playengine->get_seekable((PlayEngineHandle)playengine, &seekable);
g_print("Seekable : %s\n", seekable ? "Yes" : "No");
}
break;
case 's':
{
GstState player_state = GST_STATE_NULL;
gdouble playback_rate = 0.0;
playengine->get_state((PlayEngineHandle)playengine, &player_state);
playengine->get_play_rate((PlayEngineHandle)playengine, &playback_rate);
switch(player_state)
{
case GST_STATE_PLAYING:
{
if( playback_rate > 1.0 && playback_rate <= 8.0 )
{
g_print("Current State : Fast Forward\n");
}
if( playback_rate > 0.0 && playback_rate < 1.0 )
{
g_print("Current State : Slow Forward\n");
}
if( playback_rate >= -8.0 && playback_rate <= -0.0 )
{
g_print("Current State : Fast Backward\n");
}
if( playback_rate == 1.0 )
{
g_print("Current State : Playing\n");
}
}
break;
case GST_STATE_PAUSED:
g_print("Current State : Paused\n");
break;
case GST_STATE_READY:
g_print("Current State : Ready\n");
break;
case GST_STATE_NULL:
g_print("Current State : Stopped\n");
break;
default:
g_print("Current State : Unknown\n");
break;
}
}
break;
case 'p':
{
gint64 pos = 0;
playengine->get_position((PlayEngineHandle)playengine, &pos);
g_print("Current playing position : %lld\n", pos);
}
break;
case 'u':
{
gint64 duration = 0;
playengine->get_duration((PlayEngineHandle)playengine, &duration);
g_print("Duration : %lld\n", duration);
}
break;
case 'z':
{
DisplayArea area = {0};
playengine->get_display_area((PlayEngineHandle)playengine, &area);
g_print("Current video display area : %d %d %d %d\n", area.offsetx, area.offsety, area.width, area.height);
}
break;
case 't':
{
gint32 rotation = 0;
playengine->get_rotate((PlayEngineHandle)playengine, &rotation);
g_print("Current rotation : %d\n", rotation);
}
break;
case 'c':
{
gdouble playback_rate = 0.0;
playengine->get_play_rate((PlayEngineHandle)playengine, &playback_rate);
g_print("Current play rate : %1.1f\n", playback_rate);
}
break;
default:
break;
}
}
break;
default:
break;
}
fflush(stdout);
fflush(stdin);
}
gboolean ismute = FALSE;
playengine->get_mute((PlayEngineHandle)playengine, &ismute);
if(ismute)
{
playengine->pause((PlayEngineHandle)playengine);
playengine->set_mute((PlayEngineHandle)playengine, FALSE);
}
playengine->set_volume((PlayEngineHandle)playengine, 1.0);
/* for auto test script */
g_print("FSL_PLAYENGINE_UI_MSG_EXIT\n");
if(options.pl)
destroyPlayList(options.pl);
options.pl = NULL;
if(playengine)
play_engine_destroy(playengine);
playengine = NULL;
if(display_thread)
g_thread_join(display_thread);
/* for auto test script */
g_print("fsl_player_deinit\n");
return PLAYENGINE_SUCCESS;
}