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

Reply via email to