comparison mplayer.c @ 17911:52f95509cd05

Add the new property API and implement a couple properties. Move the volume and mute command to the command to property bridge.
author albeu
date Wed, 22 Mar 2006 00:19:02 +0000
parents 5ae29dc47c17
children f9cb6fc1608a
comparison
equal deleted inserted replaced
17910:5ae29dc47c17 17911:52f95509cd05
40 #define HELP_MP_DEFINE_STATIC 40 #define HELP_MP_DEFINE_STATIC
41 #include "help_mp.h" 41 #include "help_mp.h"
42 42
43 #include "m_option.h" 43 #include "m_option.h"
44 #include "m_config.h" 44 #include "m_config.h"
45 #include "m_property.h"
45 46
46 #include "cfg-mplayer-def.h" 47 #include "cfg-mplayer-def.h"
47 48
48 #ifdef USE_SUB 49 #ifdef USE_SUB
49 #include "subreader.h" 50 #include "subreader.h"
236 static int osd_show_percentage = 0; 237 static int osd_show_percentage = 0;
237 static int osd_duration = 1000; 238 static int osd_duration = 1000;
238 239
239 static int term_osd = 1; 240 static int term_osd = 1;
240 static char* term_osd_esc = "\x1b[A\r\x1b[K"; 241 static char* term_osd_esc = "\x1b[A\r\x1b[K";
242 static char* playing_msg = NULL;
241 // seek: 243 // seek:
242 static char *seek_to_sec=NULL; 244 static char *seek_to_sec=NULL;
243 static off_t seek_to_byte=0; 245 static off_t seek_to_byte=0;
244 static off_t step_sec=0; 246 static off_t step_sec=0;
245 static int loop_times=-1; 247 static int loop_times=-1;
1054 #define OSD_MSG_SUB_DELAY 2 1056 #define OSD_MSG_SUB_DELAY 2
1055 #define OSD_MSG_SPEED 3 1057 #define OSD_MSG_SPEED 3
1056 #define OSD_MSG_OSD_STATUS 4 1058 #define OSD_MSG_OSD_STATUS 4
1057 #define OSD_MSG_BAR 5 1059 #define OSD_MSG_BAR 5
1058 #define OSD_MSG_PAUSE 6 1060 #define OSD_MSG_PAUSE 6
1059 #define OSD_MSG_MUTE 7 1061 // Base id for the messages generated from the commmand to property bridge
1062 #define OSD_MSG_PROPERTY 0x100
1063
1060 1064
1061 // These will later be implemented via properties and removed 1065 // These will later be implemented via properties and removed
1062 #define OSD_MSG_AV_DELAY 100 1066 #define OSD_MSG_AV_DELAY 100
1063 #define OSD_MSG_FRAMEDROPPING 101 1067 #define OSD_MSG_FRAMEDROPPING 101
1064 #define OSD_MSG_ONTOP 102 1068 #define OSD_MSG_ONTOP 102
1300 printf("%s\n",term_osd_esc); 1304 printf("%s\n",term_osd_esc);
1301 } 1305 }
1302 } 1306 }
1303 1307
1304 1308
1309 // General properties
1310
1311 static int mp_property_osdlevel(m_option_t* prop,int action,void* arg) {
1312 return m_property_choice(prop,action,arg,&osd_level);
1313 }
1314
1315 static int mp_property_playback_speed(m_option_t* prop,int action,void* arg) {
1316 switch(action) {
1317 case M_PROPERTY_SET:
1318 if(!arg) return 0;
1319 M_PROPERTY_CLAMP(prop,*(float*)arg);
1320 playback_speed = *(float*)arg;
1321 build_afilter_chain(sh_audio, &ao_data);
1322 return 1;
1323 case M_PROPERTY_STEP_UP:
1324 case M_PROPERTY_STEP_DOWN:
1325 playback_speed += (arg ? *(float*)arg : 0.1) *
1326 (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
1327 M_PROPERTY_CLAMP(prop,playback_speed);
1328 build_afilter_chain(sh_audio, &ao_data);
1329 return 1;
1330 }
1331 return m_property_float_range(prop,action,arg,&playback_speed);
1332 }
1333
1334 static int mp_property_path(m_option_t* prop,int action,void* arg) {
1335 return m_property_string_ro(prop,action,arg,filename);
1336 }
1337
1338 static int mp_property_filename(m_option_t* prop,int action,void* arg) {
1339 char* f;
1340 if(!filename) return M_PROPERTY_UNAVAILABLE;
1341 if(((f = strrchr(filename,'/')) || (f = strrchr(filename,'\\'))) && f[1])
1342 f++;
1343 else
1344 f = filename;
1345 return m_property_string_ro(prop,action,arg,f);
1346 }
1347
1348
1349 static int mp_property_demuxer(m_option_t* prop,int action,void* arg) {
1350 if(!demuxer) return M_PROPERTY_UNAVAILABLE;
1351 return m_property_string_ro(prop,action,arg,(char*)demuxer->desc->name);
1352 }
1353
1354 static int mp_property_length(m_option_t* prop,int action,void* arg) {
1355 double len;
1356
1357 if(!demuxer ||
1358 !(int)(len = demuxer_get_time_length(demuxer)))
1359 return M_PROPERTY_UNAVAILABLE;
1360
1361 switch(action) {
1362 case M_PROPERTY_PRINT:
1363 if(!arg) return 0;
1364 else {
1365 int h, m, s = len;
1366 h = s/3600;
1367 s -= h*3600;
1368 m = s/60;
1369 s -= m*60;
1370 *(char**)arg = malloc(20);
1371 if(h > 0) sprintf(*(char**)arg,"%d:%02d:%02d",h,m,s);
1372 else if(m > 0) sprintf(*(char**)arg,"%d:%02d",m,s);
1373 else sprintf(*(char**)arg,"%d",s);
1374 return 1;
1375 }
1376 break;
1377 }
1378 return m_property_double_ro(prop,action,arg,len);
1379 }
1380
1381 // Audio properties
1382
1383 static int mp_property_volume(m_option_t* prop,int action,void* arg) {
1384
1385 if(!sh_audio) return M_PROPERTY_UNAVAILABLE;
1386
1387 switch(action) {
1388 case M_PROPERTY_GET:
1389 if(!arg) return 0;
1390 mixer_getbothvolume(&mixer,arg);
1391 return 1;
1392 case M_PROPERTY_PRINT:{
1393 float vol;
1394 if(!arg) return 0;
1395 mixer_getbothvolume(&mixer,&vol);
1396 return m_property_float_range(prop,action,arg,&vol);
1397 }
1398 case M_PROPERTY_STEP_UP:
1399 case M_PROPERTY_STEP_DOWN:
1400 case M_PROPERTY_SET:
1401 break;
1402 default:
1403 return M_PROPERTY_NOT_IMPLEMENTED;
1404 }
1405
1406 #ifdef USE_EDL
1407 if (edl_muted) return M_PROPERTY_DISABLED;
1408 user_muted = 0;
1409 #endif
1410
1411 switch(action) {
1412 case M_PROPERTY_SET:
1413 if(!arg) return 0;
1414 M_PROPERTY_CLAMP(prop,*(float*)arg);
1415 mixer_setvolume(&mixer,*(float*)arg,*(float*)arg);
1416 return 1;
1417 case M_PROPERTY_STEP_UP:
1418 if(arg && *(float*)arg <= 0)
1419 mixer_decvolume(&mixer);
1420 else
1421 mixer_incvolume(&mixer);
1422 return 1;
1423 case M_PROPERTY_STEP_DOWN:
1424 if(arg && *(float*)arg <= 0)
1425 mixer_incvolume(&mixer);
1426 else
1427 mixer_decvolume(&mixer);
1428 return 1;
1429 }
1430 return M_PROPERTY_NOT_IMPLEMENTED;
1431 }
1432
1433
1434 static int mp_property_mute(m_option_t* prop,int action,void* arg) {
1435
1436 if(!sh_audio) return M_PROPERTY_UNAVAILABLE;
1437
1438 switch(action) {
1439 case M_PROPERTY_SET:
1440 #ifdef USE_EDL
1441 if(edl_muted) return M_PROPERTY_DISABLED;
1442 #endif
1443 if(!arg) return 0;
1444 if((!!*(int*)arg) != mixer.muted)
1445 mixer_mute(&mixer);
1446 return 1;
1447 case M_PROPERTY_STEP_UP:
1448 case M_PROPERTY_STEP_DOWN:
1449 #ifdef USE_EDL
1450 if(edl_muted) return M_PROPERTY_DISABLED;
1451 #endif
1452 mixer_mute(&mixer);
1453 return 1;
1454 case M_PROPERTY_PRINT:
1455 if(!arg) return 0;
1456 #ifdef USE_EDL
1457 if(edl_muted) {
1458 *(char**)arg = strdup(MSGTR_EnabledEdl);
1459 return 1;
1460 }
1461 #endif
1462 default:
1463 return m_property_flag(prop,action,arg,&mixer.muted);
1464
1465 }
1466 }
1467
1468
1469 static m_option_t mp_properties[] = {
1470 // General
1471 { "osdlevel", mp_property_osdlevel, CONF_TYPE_INT,
1472 M_OPT_RANGE, 0, 3, NULL },
1473 { "speed", mp_property_playback_speed, CONF_TYPE_FLOAT,
1474 M_OPT_RANGE, 0.01, 100.0, NULL },
1475 { "filename", mp_property_filename, CONF_TYPE_STRING,
1476 0, 0, 0, NULL },
1477 { "path", mp_property_path, CONF_TYPE_STRING,
1478 0, 0, 0, NULL },
1479 { "demuxer", mp_property_demuxer, CONF_TYPE_STRING,
1480 0, 0, 0, NULL },
1481 { "length", mp_property_length, CONF_TYPE_DOUBLE,
1482 0, 0, 0, NULL },
1483
1484 // Audio
1485 { "volume", mp_property_volume, CONF_TYPE_FLOAT,
1486 M_OPT_RANGE, 0, 100, NULL },
1487 { "mute", mp_property_mute, CONF_TYPE_FLAG,
1488 M_OPT_RANGE, 0, 1, NULL },
1489 { NULL, NULL, NULL, 0, 0, 0, NULL }
1490 };
1491
1492 m_option_t* mp_property_find(char* name) {
1493 return m_option_list_find(mp_properties,name);
1494 }
1495
1496 int mp_property_do(char* name,int action, void* val) {
1497 m_option_t* p = mp_property_find(name);
1498 if(!p) return M_PROPERTY_UNAVAILABLE;
1499 return m_property_do(p,action,val);
1500 }
1501
1502
1503 /*
1504 * \brief Commands to property bridge.
1505 *
1506 * It is used to handle most commands that just set a property
1507 * and optionaly display something on the OSD.
1508 * Two kinds of commands are handled: adjust or toggle.
1509 *
1510 * Adjust commands take 1 or 2 paramter: <value> <abs>
1511 * If <abs> is none zero the property is set to the given value
1512 * otherwise it is adjusted.
1513 *
1514 * Toggle commands take 0 or 1 parameter. With no parameter
1515 * or a value less than the property minimum it just step the
1516 * property to it's next value. Otherwise it set it to the given
1517 * value.
1518 *
1519 */
1520
1521 static struct {
1522 char* name; // property name
1523 int cmd; // cmd id
1524 int toggle; // set/adjust or toggle command
1525 int osd_progbar; // progbar type
1526 int osd_id; // osd msg id if it must be shared
1527 char* osd_msg; // osd msg template
1528 } set_prop_cmd[] = {
1529 // audio
1530 { "volume", MP_CMD_VOLUME, 0, OSD_VOLUME, -1, MSGTR_Volume },
1531 { "mute", MP_CMD_MUTE, 1, 0, -1, MSGTR_MuteStatus },
1532
1533 { NULL, 0, 0, 0, -1, NULL }
1534 };
1535
1536 static int set_property_command(mp_cmd_t* cmd) {
1537 int i,r;
1538 m_option_t* prop;
1539
1540 // look for the command
1541 for(i = 0 ; set_prop_cmd[i].name ; i++)
1542 if(set_prop_cmd[i].cmd == cmd->id) break;
1543 if(!set_prop_cmd[i].name) return 0;
1544
1545 // get the property
1546 prop = mp_property_find(set_prop_cmd[i].name);
1547 if(!prop) return 0;
1548
1549 // toggle command
1550 if(set_prop_cmd[i].toggle) {
1551 // set to value
1552 if(cmd->nargs > 0 && cmd->args[0].v.i >= prop->min)
1553 r = m_property_do(prop,M_PROPERTY_SET,&cmd->args[0].v.i);
1554 else
1555 r = m_property_do(prop,M_PROPERTY_STEP_UP,NULL);
1556 } else if(cmd->args[1].v.i) //set
1557 r = m_property_do(prop,M_PROPERTY_SET,&cmd->args[0].v);
1558 else // adjust
1559 r = m_property_do(prop,M_PROPERTY_STEP_UP,&cmd->args[0].v);
1560
1561 if(r <= 0) return 1;
1562
1563 if(set_prop_cmd[i].osd_progbar) {
1564 if(prop->type == CONF_TYPE_INT) {
1565 if(m_property_do(prop,M_PROPERTY_GET,&r) > 0)
1566 set_osd_bar(set_prop_cmd[i].osd_progbar,
1567 set_prop_cmd[i].osd_msg,
1568 prop->min,prop->max,r);
1569 } else if(prop->type == CONF_TYPE_FLOAT) {
1570 float f;
1571 if(m_property_do(prop,M_PROPERTY_GET,&f) > 0)
1572 set_osd_bar(set_prop_cmd[i].osd_progbar,set_prop_cmd[i].osd_msg,
1573 prop->min,prop->max,f);
1574 } else
1575 mp_msg(MSGT_CPLAYER,MSGL_ERR, "Property use an unsupported type.\n");
1576 return 1;
1577 }
1578
1579 if(set_prop_cmd[i].osd_msg) {
1580 char* val = m_property_print(prop);
1581 if(val) {
1582 set_osd_msg(set_prop_cmd[i].osd_id >= 0 ? set_prop_cmd[i].osd_id :
1583 OSD_MSG_PROPERTY+i,1,osd_duration,
1584 set_prop_cmd[i].osd_msg,val);
1585 free(val);
1586 }
1587 }
1588 return 1;
1589 }
1590
1305 int main(int argc,char* argv[]){ 1591 int main(int argc,char* argv[]){
1306 1592
1307 1593
1308 char * mem_ptr; 1594 char * mem_ptr;
1309 1595
2419 2705
2420 //================== MAIN: ========================== 2706 //================== MAIN: ==========================
2421 main: 2707 main:
2422 current_module="main"; 2708 current_module="main";
2423 2709
2710 if(playing_msg) {
2711 char* msg = m_properties_expand_string(mp_properties,playing_msg);
2712 mp_msg(MSGT_CPLAYER,MSGL_INFO,"%s",msg);
2713 free(msg);
2714 }
2715
2716
2424 // Disable the term osd in verbose mode 2717 // Disable the term osd in verbose mode
2425 if(verbose) term_osd = 0; 2718 if(verbose) term_osd = 0;
2426 fflush(stdout); 2719 fflush(stdout);
2427 2720
2428 #ifdef HAVE_NEW_GUI 2721 #ifdef HAVE_NEW_GUI
3113 3406
3114 { 3407 {
3115 mp_cmd_t* cmd; 3408 mp_cmd_t* cmd;
3116 int brk_cmd = 0; 3409 int brk_cmd = 0;
3117 while( !brk_cmd && (cmd = mp_input_get_cmd(0,0,0)) != NULL) { 3410 while( !brk_cmd && (cmd = mp_input_get_cmd(0,0,0)) != NULL) {
3411 if(!set_property_command(cmd))
3118 switch(cmd->id) { 3412 switch(cmd->id) {
3119 case MP_CMD_SEEK : { 3413 case MP_CMD_SEEK : {
3120 float v; 3414 float v;
3121 int abs; 3415 int abs;
3122 if(sh_video) 3416 if(sh_video)
3139 rel_seek_secs+= v; 3433 rel_seek_secs+= v;
3140 osd_function= (v > 0) ? OSD_FFW : OSD_REW; 3434 osd_function= (v > 0) ? OSD_FFW : OSD_REW;
3141 } 3435 }
3142 brk_cmd = 1; 3436 brk_cmd = 1;
3143 } break; 3437 } break;
3438 case MP_CMD_SET_PROPERTY: {
3439 m_option_t* prop = mp_property_find(cmd->args[0].v.s);
3440 if(!prop) mp_msg(MSGT_CPLAYER,MSGL_WARN,"Unkown property: '%s'\n",cmd->args[0].v.s);
3441 else if(m_property_parse(prop,cmd->args[1].v.s) <= 0)
3442 mp_msg(MSGT_CPLAYER,MSGL_WARN,"Failed to set property '%s' to '%s'.\n",
3443 cmd->args[0].v.s,cmd->args[1].v.s);
3444
3445 } break;
3446 case MP_CMD_GET_PROPERTY: {
3447 m_option_t* prop;
3448 void* val;
3449 prop = mp_property_find(cmd->args[0].v.s);
3450 if(!prop) mp_msg(MSGT_CPLAYER,MSGL_WARN,"Unkown property: '%s'\n",cmd->args[0].v.s);
3451 // use m_option_print directly to get easily parsable values
3452 val = calloc(1,prop->type->size);
3453 if(m_property_do(prop,M_PROPERTY_GET,val) <= 0) {
3454 mp_msg(MSGT_CPLAYER,MSGL_WARN,"Failed to get value of property '%s'.\n",
3455 cmd->args[0].v.s);
3456 break;
3457 }
3458 tmp = m_option_print(prop,val);
3459 if(!tmp || tmp == (char*)-1) {
3460 mp_msg(MSGT_CPLAYER,MSGL_WARN,"Failed to print value of property '%s'.\n",
3461 cmd->args[0].v.s);
3462 break;
3463 }
3464 mp_msg(MSGT_GLOBAL,MSGL_INFO, "ANS_%s=%s\n",cmd->args[0].v.s,tmp);
3465 free(tmp);
3466 } break;
3144 #ifdef USE_EDL 3467 #ifdef USE_EDL
3145 case MP_CMD_EDL_MARK: 3468 case MP_CMD_EDL_MARK:
3146 if( edl_fd ) { 3469 if( edl_fd ) {
3147 float v = sh_video->pts; 3470 float v = sh_video->pts;
3148 fprintf( edl_fd, "%f %f %d\n", v-2, v, 0 ); 3471 fprintf( edl_fd, "%f %f %d\n", v-2, v, 0 );
3290 rm_osd_msg(OSD_MSG_OSD_STATUS); 3613 rm_osd_msg(OSD_MSG_OSD_STATUS);
3291 } break; 3614 } break;
3292 case MP_CMD_OSD_SHOW_TEXT : { 3615 case MP_CMD_OSD_SHOW_TEXT : {
3293 set_osd_msg(OSD_MSG_TEXT,1,osd_duration,"%64s",cmd->args[0].v.s); 3616 set_osd_msg(OSD_MSG_TEXT,1,osd_duration,"%64s",cmd->args[0].v.s);
3294 } break; 3617 } break;
3295 case MP_CMD_VOLUME : {
3296 int v = cmd->args[0].v.i;
3297
3298 // start change for absolute volume value
3299 int abs = (cmd->nargs > 1) ? cmd->args[1].v.i : 0;
3300
3301 #ifdef USE_EDL
3302 if (edl_muted) break;
3303 user_muted = 0;
3304 #endif
3305 if( abs )
3306 {
3307 mixer_setvolume(&mixer, (float)v, (float)v );
3308 } else {
3309 if(v > 0)
3310 mixer_incvolume(&mixer);
3311 else
3312 mixer_decvolume(&mixer);
3313 }
3314
3315 if(1){
3316 float vol;
3317 mixer_getbothvolume(&mixer, &vol);
3318 set_osd_bar(OSD_VOLUME,"Volume",0,100,vol);
3319 }
3320 } break;
3321 case MP_CMD_MUTE:
3322 #ifdef USE_EDL
3323 user_muted = !user_muted;
3324 if ((edl_muted | user_muted) != mixer.muted)
3325 #endif
3326 mixer_mute(&mixer);
3327 set_osd_msg(OSD_MSG_MUTE,1,osd_duration, MSGTR_OSDMute,
3328 mixer.muted ? MSGTR_OSDenabled : MSGTR_OSDdisabled);
3329 break;
3330 case MP_CMD_LOADFILE : { 3618 case MP_CMD_LOADFILE : {
3331 play_tree_t* e = play_tree_new(); 3619 play_tree_t* e = play_tree_new();
3332 play_tree_add_file(e,cmd->args[0].v.s); 3620 play_tree_add_file(e,cmd->args[0].v.s);
3333 3621
3334 if (cmd->args[1].v.i) // append 3622 if (cmd->args[1].v.i) // append