omxplayer中复杂的getchar()操作
Complex getchar() operation in omxplayer
最近我一直在尝试将命名管道的输出重定向到omxplayer的运行实例中(请参阅此处以获取一个不控制omxplayer的最低工作示例,尽管它应该控制omxplayer)。我怀疑这与对管道的读写有关——也许附加了一行新行——所以我得到了一些帮助,编写了一个C程序,它向管道写入并从中读取(见此处),但事实证明这也不是读/写错误。因此,我去追踪omxplayer的代码,认为无论它有多复杂,最终都必须有一个地方有标准的C++代码来读取用户输入,感谢上帝,我找到了它。据我所知,这是一种方法,负责获得用户输入,并为Dbus做准备,让它发挥其所有的天堂般的作用:
void Keyboard::Process()
{
while(!m_bStop && conn && dbus_connection_read_write_dispatch(conn, 0))
{
int ch[8];
int chnum = 0;
while ((ch[chnum] = getchar()) != EOF) chnum++;
if (chnum > 1) ch[0] = ch[chnum - 1] | (ch[chnum - 2] << 8);
if (m_keymap[ch[0]] != 0)
send_action(m_keymap[ch[0]]);
else
Sleep(20);
}
}
据我所知,while(!m_bStop...
是一个条件,只是为了确保事情仍然有效,m_keymap
是一个密码,它将'p'
或'q'
等整数与ACTION_PAUSE
和ACTION_QUIT
等枚举值相匹配,我认为send_action()
只是开始了。
问题:
以下是我不明白的:
- 当我甚至没有按Enter-->
while ((ch[chnum] = getchar()) != EOF)
时,EOF是如何检测到的(如果您对此感到困惑,当播放电影时,我会按p暂停电影,而不是p,然后按下Enter或Ctrl+1D- 当数组
ch
的长度只有8时,为什么我们在while循环while ((ch[chnum] = getchar()) != EOF) chnum++
中循环可能超过8次迭代- 这可能是特定于实现的,但为什么当所有输入都保证为1个字符长时,大小为8的数组(我可以在映射中看到它,而且键是即时处理的)。这与箭头键和逃生键有任何关系吗
- 假设可能有一个以上的字符,不知何故,这行应该做什么
if (chnum > 1) ch[0] = ch[chnum - 1] | (ch[chnum - 2] << 8)
- 最后,知道omxplayer是如何读取用户生成的输入的,有人能告诉我为什么我的简单脚本(标记为
omxplayer_test.c
)不能成功控制播放器吗 - 当数组
getchar.c:
#include <stdio.h>
int main( int argc, char *argv[] ) {
int ch [ 8 ];
int chnum = 0;
while ( ( ch [ chnum ] = getchar() ) != EOF ) chnum++;
printf ( "You will never make it here!n" );
return 0;
}
omxplayer_test.c:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#define PIPE_PATH "testpipe"
#define VIDEO_PATH "Matrix.mkv"
#define P_MESSAGE "p"
#define Q_MESSAGE "q"
#define I_MESSAGE "."
#define VIDEO_PLAYER "omxplayer"
#define SLEEP_PERIOD 2L
int main()
{
int fd;
pid_t pid;
pid_t wpid;
int status;
char shellCmd [ 1000 ];
struct timespec time1, time2; //used for sleeping
bool parent;
char c;
parent = false;
//Make pipe BEFORE forking
mkfifo ( PIPE_PATH, 0666 );
if ( ( pid = fork () ) < 0 )
{
perror ( "Fork Failedn" );
return -1;
}
else if ( pid == 0 )
{ //first child launches the movie
sprintf ( shellCmd, "%s %s < %s >/dev/null 2>&1", VIDEO_PLAYER, VIDEO_PATH, PIPE_PATH );
if ( system ( shellCmd ) == -1 )
{
printf ( "Error: %sn", shellCmd );
fflush(stdout);
}
printf ("First child finishedn");
fflush (stdout);
}
else
{
if ( ( pid = fork () ) < 0 )
{
perror ( "Fork Failedn" );
return -1;
}
else if ( pid == 0 )
{ //second child waits x seconds then pauses/unpauses/quits movie
time1.tv_sec = SLEEP_PERIOD; //sleep for x seconds
time1.tv_nsec = 0L; //Dont worry about milli seconds
nanosleep ( &time1, &time2 );
//Suprisingly, this signal which gets ball rolling works
fd = open ( PIPE_PATH, O_WRONLY );
write ( fd, I_MESSAGE, sizeof ( I_MESSAGE ) );
nanosleep ( &time1, &time2 );
printf ( "Sleep over, pausing movien");
fflush(stdout);
write ( fd, I_MESSAGE, sizeof ( P_MESSAGE ) );
nanosleep ( &time1, &time2 );
printf ( "Sleep over, unpausing movien");
fflush(stdout);
write ( fd, P_MESSAGE, sizeof ( P_MESSAGE ) );
nanosleep ( &time1, &time2 );
printf ( "Sleep over, quiting movien");
fflush(stdout);
write ( fd, Q_MESSAGE, sizeof ( Q_MESSAGE ) );
close ( fd );
printf ("Second child finishedn");
fflush (stdout);
}
else
{
parent = true;
}
}
while ( ( wpid = wait ( &status ) ) > 0 )
{
printf ( "Exit status of %d was %d (%s)n", ( int ) wpid, status, ( status == 0 ) ? "accept" : "reject" );
fflush(stdout);
}
if ( parent == true )
{
printf ("deleting pipen");
fflush(stdout);
unlink ( PIPE_PATH );
}
return 0;
}
@puk我偶然发现了你的"老"问题,但以防你自己没有回答。
看看上面类似的东西https://github.com/popcornmix/omxplayer/issues/131.由于omxplayer
版本0.3.x来自"popcornmix
"存储库,我将在那里回答这些问题,因为它是您提出omxplayer
问题的更好地方;)
但我将在这里回答为什么您的omxplayer_test.c
不工作的问题,因为正是您的代码让omxplayer
失败:)严格来说不是真的,因为这是omxplayer
中的当前问题:(
I_MESSAGE的发送最让我惊讶,因为我不知道"上有任何键盘输入处理性格另一方面,"i"命令omxplayer转到上一章。因此,如果您没有在"上对任何内容进行键映射输入键或意味着真正的"i"操作,只需忽略它;不需要(也不应该)启动CCD_ 20。
要暂停omxplayer
,您输入的是I_MESSAGE
而不是P_MESSAGE
。
但是,使用write()和消息的sizeof()向omxplayer发送命令会产生与前面提到的问题相同的效果。x_MESSAGE
的sizeof()
返回2作为结果,而不是1(一)!CCD_ 26在(c编码的)串的CCD_ 27中计数;例如"p"
被存储为'p'' '
,因此至少有2个字符。因此,请使用strlen()
(需要#include <string.h>
),因为它只发送x_MESSAGE
字符。
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 重载操作程序时出错>>用于类中的字符串 memebr
- 对字符串进行位操作
- 我可以在 C++ 中的函数体之外进行操作吗?
- MPI突然停止了对多个核心的操作
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 对字符数组中的元素执行逐位操作
- 如何在directx/c++中进行平移/缩放操作
- 逐位操作的隐式类型转换
- 为什么一个向量上的多线程操作很慢
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 位移操作和位掩码未检测到重复字符
- 如何进行特定的位操作?
- 当我们进行一些操作时,应该使用什么'std::string'或'std::stringstream'?
- 字符串操作 - 字符计数
- 此代码中的操作流程是什么?C/C++.
- 复制和交换习惯用法与移动操作之间的交互
- 像union_这样的 Boost.Geometry 操作如何处理浮点类型的基本不精确性?
- 为什么 std::lerp 不适用于任何已实现所需操作的类型?
- omxplayer中复杂的getchar()操作