Hans Verkuil wrote:
> On Saturday 20 October 2007 11:31:27 Duncan Webb wrote:
>> Hans Verkuil wrote:
>>> On Friday 19 October 2007 21:52:15 Duncan Webb wrote:
>>>> Hans Verkuil wrote:
>>>>> On Friday 19 October 2007 19:30:59 Duncan Webb wrote:
>>>>>> Hans Verkuil wrote:
>>> The old IVTV_IOC_S_GOP_END has been removed. Instead use the new
>>> VIDIOC_ENCODER_CMD and VIDIOC_TRY_ENCODER_CMD ioctls if you want
>>> this feature. See the v4l2 spec for more details.
>> Still having a little bit of a problem with VIDIOC_ENCODER_CMD, does
>> this need to be called just before the stream off command, replace it
>> (as I think is correct) or as with IVTV_IOC_S_GOP_END before reading
>> begins?
> 
> It replaces STREAMOFF. STREAMOFF was always a half-baked implementation 
> at best and was replaced with this command. The STREAMON/OFF command 
> are really meant for the V4L2 stream I/O API. Since ivtv doesn't 
> support stream I/O the driver's VIDIOC_STREAMOFF support was removed.

Sorry to bug you Hans,

I can't seem to get VIDIOC_ENCODER_CMD to work, I written a little test
program (attached)

I would expect that after having sent the VIDIOC_ENCODER_CMD to stop,
that a read would return 0 bytes, but it seems that the buffer is always
full.

Cheers,
Duncan
/* encodercmd-test.c
vim:expandtab:shiftwidth=4:tabstop=4:

    PVR-350 IVTV streaming test

*/

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#define __USE_LARGEFILE64
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <linux/types.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>


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];

enum streaming_state { Undefined, Running, Paused, Resumed, Off };

const char *streaming2name (enum streaming_state streaming)
{
    return streaming == Undefined ? "Undefined"
         : streaming == Running   ? "Running"
         : streaming == Paused    ? "Paused"
         : streaming == Resumed   ? "Resumed"
         : streaming == Off       ? "Off"
         :                          "?";
}

char streaming2char(enum streaming_state streaming)
{
    return streaming == Undefined ? 'U'
         : streaming == Running   ? 'N'
         : streaming == Paused    ? 'P'
         : streaming == Resumed   ? 'R'
         : streaming == Off       ? 'O'
         :                          '?';
}

int main(int argc, char *argv[])
{
    const char *device = "/dev/video0";
    const char output[100] = "test";
    long int bytes_read;
    long int bytes_written;
    int outfh = -1;
    int infh = -1;
    int i;
    enum streaming_state streaming = Undefined;

    if (argc > 1) {
        device = argv[1];
    }
    printf("Running using \"%s\"", device);
#ifdef PAUSE
    printf(", PAUSE");
    strcat((char *)output, "-p");
#endif
#ifdef VERBOSE
    printf(", VERBOSE");
#endif
    strcat((char *)output, ".mpeg");
    printf(" to \"%s\"\n", output);

    printf("Press enter to run test:");
    fflush(stdout);
    getchar();

    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;
    }
    printf("Opened output \"%s\"\n", output);

    if ((infh = open(device, O_RDONLY|O_LARGEFILE)) < 0) {
        printf("Failed to open input \"%s\": %s\n", device, strerror(errno));
        return 1;
    }
    printf("Opened input \"%s\"\n", device);

    struct v4l2_capability capability;
    memset(&capability, 0, sizeof(capability));
    if (doioctl(infh, VIDIOC_QUERYCAP, &capability, "VIDIOC_QUERYCAP") == 0) {
        printf("VIDIOC_QUERYCAP %X\n", capability.version);
    } else {
        return 1;
    }

    struct v4l2_encoder_cmd encoder_cmd;
    memset(&encoder_cmd, 0, sizeof(encoder_cmd));
    streaming = Running;
    for (i = 0; i < 100; i++) {
#ifdef PAUSE
        if (i == 20) {
            printf("\n");
            encoder_cmd.cmd = V4L2_ENC_CMD_PAUSE;
            if (doioctl(infh, VIDIOC_ENCODER_CMD, &encoder_cmd, 
"V4L2_ENC_CMD_PAUSE") == 0) {
                printf("V4L2_ENC_CMD_PAUSE set\n");
                streaming = Paused;
            } else {
                return 1;
            }
        }
        if (i == 30) {
            printf("\n");
            encoder_cmd.cmd = V4L2_ENC_CMD_RESUME;
            if (doioctl(infh, VIDIOC_ENCODER_CMD, &encoder_cmd, 
"V4L2_ENC_CMD_RESUME") == 0) {
                printf("V4L2_ENC_CMD_RESUME set\n");
                streaming = Resumed;
            } else {
                return 1;
            }
        }
#endif
        if (i == 40) {
            printf("\n");
            encoder_cmd.cmd = V4L2_ENC_CMD_STOP;
            encoder_cmd.flags = V4L2_ENC_CMD_STOP_AT_GOP_END;
            if (doioctl(infh, VIDIOC_ENCODER_CMD, &encoder_cmd, 
"V4L2_ENC_CMD_STOP") == 0) {
                printf("V4L2_ENC_CMD_STOP set\n");
                streaming = Off;
            } else {
                return 1;
            }
        }

#ifndef VERBOSE
        printf("%c", streaming2char(streaming));
        fflush(stdout);
#endif

        if (streaming == Paused) {
            usleep(250000);
            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 == Off) {
#ifdef VERBOSE
                printf("%3d, %s, bytes_read=%ld, finished\n", i,
                    streaming2name(streaming), bytes_read);
#else
                printf("%c\nfinished\n", streaming2char(streaming));
                fflush(stdout);
#endif
                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));
        }
#ifdef VERBOSE
        printf("%3d, %s, bytes_read=%ld, bytes_written=%ld\n", i,
            streaming2name(streaming), bytes_read, bytes_written);
#endif
    }

    close(infh);
    close(outfh);
    
    return 0;
}
EXTRA_CFLAGS = -DNDEBUG -O2 -g
EXTRA_LDFLAGS = -g -Wl,-rpath,$(LIBDIR)
CFLAGS = $(EXTRA_CFLAGS) -D_GNU_SOURCE -Wall
LDFLAGS = $(EXTRA_LDFLAGS)

all: encodercmd-test

encodercmd-test: encodercmd-test.c
        $(CC) $(CFLAGS) -o encodercmd-test encodercmd-test.c
        $(CC) $(CFLAGS) -DVERBOSE -o encodercmd-vtest encodercmd-test.c
        $(CC) $(CFLAGS) -DPAUSE -o encodercmd-pause encodercmd-test.c
        $(CC) $(CFLAGS) -DVERBOSE -DPAUSE -o encodercmd-vpause encodercmd-test.c

clean: 
        -rm -fv *.o encodercmd-test

_______________________________________________
ivtv-devel mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-devel

Reply via email to