Duncan Webb wrote:
> Hans Verkuil wrote:
>> On Tuesday 31 October 2006 07:09, Duncan Webb wrote:
>>>>> Aha, need to use VIDIOC_STREAMOFF. I'll try this out in the next
>>>>> few days and let you know.
>>>> Thanks, this works quite nicely.
>>>>
>>>> There are a couple of things that I've noticed:
>> Oops, I missed the following questions in your original email.
>>
>>>> 1) If the video device is read again after VIDIOC_STREAMOFF and
>>>> reading 0 bytes, it does continue streaming. This means that it's
>>>> not possible to use VIDIOC_STREAMOFF and VIDIOC_STREAMON to pause
>>>> the recording. AFAICS Not a problem for what I'm doing but could be
>>>> a problem if anybody wants to pause the video recording.
>> STREAMOFF is not meant for pausing (there are ivtv ioctls for that).
>> STREAMON is not implemented at all currently.
>>
>>>> 2) The end of program marker is written by VIDIOC_STREAMOFF instead
>>>> of during the close.
>> That's correct. You should interpret STREAMOFF as a close() that waits
>> for the end of the GOP. You should not try to do anything after the
>> STREAMOFF.
I've done some more testing on this, attached is a tiny program to turn
off the stream.
Am I correct that to pause the stream the IVTV_IOC_PAUSE_ENCODE and
IVTV_IOC_RESUME_ENCODE should be used?
Two thing that I've noticed both cause an "Interrupted System Call" error.
1) If IVTV_IOC_S_GOP_END is not called
2) If the PAUSE and RESUME calls are made.
After the interrupted system call a reboot is required, or at least I've
not found a way to reset the driver.
I'm wondering if the calls have been made incorrectly?
Regards,
Duncan
/* streamoff-test.c
vim:expandtab:shiftwidth=4:tabstop=4:
IVTV turning off and pausing streaming test
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#define __USE_LARGEFILE64
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <inttypes.h>
#include <unistd.h>
#define __user
#include <linux/videodev2.h>
#define IVTV_INTERNAL
#include "ivtv.h"
static int doioctl(int fh, int request, void *parm, const char *name)
{
int retVal;
printf("ioctl %s ", name);
retVal = ioctl(fh, request, parm);
if (retVal < 0)
printf("failed: %s\n", strerror(errno));
else
printf("ok\n");
return retVal;
}
static unsigned char buffer_video[128*1024];
int main(int argc, char *argv[])
{
const char *device = "/dev/video0";
const char *output = "test.mpeg";
int end_gop = 1;
enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
ssize_t bytes_read;
ssize_t bytes_written;
int outfh = -1;
int infh = -1;
int i;
int streaming = -1;
outfh = open(output, O_WRONLY|O_CREAT|O_LARGEFILE,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
if (outfh == -1) {
printf("Failed to open output \"%s\": %s\n", output, strerror(errno));
return 1;
}
if ((infh = open(device, O_RDONLY|O_LARGEFILE)) < 0) {
printf("Failed to open \"%s\": %s\n", device, strerror(errno));
return 1;
}
if (doioctl(infh, IVTV_IOC_S_GOP_END, &end_gop, "IVTV_IOC_S_GOP_END") == 0)
{
printf("IVTV_IOC_S_GOP_END %d\n", end_gop);
}
streaming = 0;
for (i = 0; i < 100; i++) {
#ifdef PAUSE
if (i == 20) {
printf("\n");
if (doioctl(infh, IVTV_IOC_PAUSE_ENCODE, NULL,
"IVTV_IOC_PAUSE_ENCODE") == 0) {
printf("IVTV_IOC_PAUSE_ENCODE set\n");
streaming = 1;
}
}
if (i == 30) {
printf("\n");
if (doioctl(infh, IVTV_IOC_RESUME_ENCODE, NULL,
"IVTV_IOC_RESUME_ENCODE") == 0) {
printf("IVTV_IOC_RESUME_ENCODE set\n");
streaming = 2;
}
}
#endif
if (i == 40) {
printf("\n");
if (doioctl(infh, VIDIOC_STREAMOFF, &buf_type, "VIDIOC_STREAMOFF")
== 0) {
printf("VIDIOC_STREAMOFF set\n");
streaming = 3;
}
}
if (streaming == 1) {
usleep(250000);
printf("%c", '0'+streaming);
continue;
}
bytes_read = read(infh, buffer_video, sizeof(buffer_video));
if (bytes_read < 0) {
printf("read failed: %s\n", strerror(errno));
break;
}
if (bytes_read == 0) {
if (streaming == 3) {
printf("finished\n");
break;
} else {
printf("read no data: %s\n", strerror(errno));
}
}
bytes_written = write(outfh, buffer_video, bytes_read);
if (bytes_written != bytes_read) {
printf("write failed: %s\n", strerror(errno));
}
printf("%3d, %d, bytes_read=%d, bytes_written=%d\n", i, streaming,
bytes_read, bytes_written);
}
close(infh);
close(outfh);
return 0;
}
_______________________________________________
ivtv-devel mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-devel