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