aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_av_play.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_av_play.c')
-rw-r--r--test/test_av_play.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/test/test_av_play.c b/test/test_av_play.c
new file mode 100644
index 0000000..293d6d8
--- /dev/null
+++ b/test/test_av_play.c
@@ -0,0 +1,310 @@
+/*
+ * test_av_play.c - Test playing an MPEG A+V PES (e.g. VDR recordings) from a file.
+ *
+ * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
+ * & Marcus Metzler <marcus@convergence.de>
+ * for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/video.h>
+#include <linux/dvb/audio.h>
+#include <sys/poll.h>
+
+static int audioPlay(int fd)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,AUDIO_PLAY) < 0)){
+ perror("AUDIO PLAY: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int audioSelectSource(int fd, audio_stream_source_t source)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,AUDIO_SELECT_SOURCE, source) < 0)){
+ perror("AUDIO SELECT SOURCE: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+static int audioSetMute(int fd, int state)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,AUDIO_SET_MUTE, state) < 0)){
+ perror("AUDIO SET MUTE: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int audioSetAVSync(int fd, int state)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,AUDIO_SET_AV_SYNC, state) < 0)){
+ perror("AUDIO SET AV SYNC: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int videoStop(int fd)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,VIDEO_STOP,0) < 0)){
+ perror("VIDEO STOP: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int videoPlay(int fd)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,VIDEO_PLAY) < 0)){
+ perror("VIDEO PLAY: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int videoFreeze(int fd)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,VIDEO_FREEZE) < 0)){
+ perror("VIDEO FREEZE: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int videoContinue(int fd)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,VIDEO_CONTINUE) < 0)){
+ perror("VIDEO CONTINUE: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int videoSelectSource(int fd, video_stream_source_t source)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,VIDEO_SELECT_SOURCE, source) < 0)){
+ perror("VIDEO SELECT SOURCE: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int videoFastForward(int fd,int nframes)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes) < 0)){
+ perror("VIDEO FAST FORWARD: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int videoSlowMotion(int fd,int nframes)
+{
+ int ans;
+
+ if ( (ans = ioctl(fd,VIDEO_SLOWMOTION, nframes) < 0)){
+ perror("VIDEO SLOWMOTION: ");
+ return -1;
+ }
+
+ return 0;
+}
+
+#define BUFFY 32768
+#define NFD 2
+static void play_file_av(int filefd, int vfd, int afd)
+{
+ char buf[BUFFY];
+ int count;
+ int written;
+ struct pollfd pfd[NFD];
+ int stopped = 0;
+
+ pfd[0].fd = STDIN_FILENO;
+ pfd[0].events = POLLIN;
+
+ pfd[1].fd = vfd;
+ pfd[1].events = POLLOUT;
+
+ pfd[2].fd = afd;
+ pfd[2].events = POLLOUT;
+
+ videoSelectSource(vfd,VIDEO_SOURCE_MEMORY);
+ audioSelectSource(afd,AUDIO_SOURCE_MEMORY);
+
+ // FIXME: only seems to work if starting audio first!
+ audioPlay(afd);
+ videoPlay(vfd);
+
+ count = read(filefd,buf,BUFFY);
+ write(vfd,buf,count);
+
+ while ( (count = read(filefd,buf,BUFFY)) >= 0 ){
+ written = 0;
+ while(written < count){
+ if (poll(pfd,NFD,1)){
+ if (pfd[1].revents & POLLOUT){
+ written += write(vfd,buf+written,
+ count-written);
+ }
+ if (pfd[0].revents & POLLIN){
+ int c = getchar();
+ switch(c){
+ case 'z':
+ videoFreeze(vfd);
+ printf("playback frozen\n");
+ stopped = 1;
+ break;
+
+ case 's':
+ videoStop(vfd);
+ printf("playback stopped\n");
+ stopped = 1;
+ break;
+
+ case 'c':
+ videoContinue(vfd);
+ printf("playback continued\n");
+ stopped = 0;
+ break;
+
+ case 'p':
+ videoPlay(vfd);
+ audioPlay(afd);
+ audioSetAVSync(afd, 1);
+ audioSetMute(afd, 0);
+ printf("playback started\n");
+ stopped = 0;
+ break;
+
+ case 'f':
+ audioSetAVSync(afd, 0);
+ audioSetMute(afd, 1);
+ videoFastForward(vfd,0);
+ printf("fastforward\n");
+ stopped = 0;
+ break;
+
+ case 'm':
+ audioSetAVSync(afd, 0);
+ audioSetMute(afd, 1);
+ videoSlowMotion(vfd,2);
+ printf("slowmotion\n");
+ stopped = 0;
+ break;
+
+ case 'q':
+ videoContinue(vfd);
+ exit(0);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int vfd, afd;
+ int filefd;
+ char *videodev = "/dev/dvb/adapter0/video0";
+ char *audiodev = "/dev/dvb/adapter0/audio0";
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: test_av_play mpeg_A+V_PES_file\n");
+ return 1;
+ }
+
+ if (getenv("VIDEO"))
+ videodev = getenv("VIDEO");
+ if (getenv("AUDIO"))
+ videodev = getenv("AUDIO");
+
+ printf("using video device '%s'\n", videodev);
+ printf("using audio device '%s'\n", audiodev);
+
+ if ( (filefd = open(argv[1],O_RDONLY)) < 0){
+ perror("File open:");
+ return -1;
+ }
+ if((vfd = open(videodev,O_RDWR|O_NONBLOCK)) < 0){
+ perror("VIDEO DEVICE: ");
+ return -1;
+ }
+ if((afd = open(audiodev,O_RDWR|O_NONBLOCK)) < 0){
+ perror("AUDIO DEVICE: ");
+ return -1;
+ }
+ play_file_av(filefd, vfd, afd);
+ close(vfd);
+ close(afd);
+ close(filefd);
+ return 0;
+
+
+}
+