mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
v4l2: Add run-time environment to enable libv4l2
The library has started preventing a lot of interesting use cases, like CREATE_BUFS, DMABuf, usage of TRY_FMT. As the libv4l2 is totally inactive and not maintained, we decided to disable it. As a convenience we added a run-time environment that let you enable it for testing. GST_V4L2_USE_LIBV4L2=1 This of course only works if you have enabled libv4l2 at build time.
This commit is contained in:
parent
ab3b289bf2
commit
31d8a1d929
12 changed files with 171 additions and 130 deletions
|
@ -241,9 +241,9 @@ gst_v4l2_memory_group_free (GstV4l2MemoryGroup * group)
|
||||||
static GstV4l2MemoryGroup *
|
static GstV4l2MemoryGroup *
|
||||||
gst_v4l2_memory_group_new (GstV4l2Allocator * allocator, guint32 index)
|
gst_v4l2_memory_group_new (GstV4l2Allocator * allocator, guint32 index)
|
||||||
{
|
{
|
||||||
gint video_fd = allocator->video_fd;
|
GstV4l2Object *obj = allocator->obj;
|
||||||
guint32 memory = allocator->memory;
|
guint32 memory = allocator->memory;
|
||||||
struct v4l2_format *format = &allocator->format;
|
struct v4l2_format *format = &obj->format;
|
||||||
GstV4l2MemoryGroup *group;
|
GstV4l2MemoryGroup *group;
|
||||||
gsize img_size, buf_size;
|
gsize img_size, buf_size;
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ gst_v4l2_memory_group_new (GstV4l2Allocator * allocator, guint32 index)
|
||||||
group->n_mem = 1;
|
group->n_mem = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v4l2_ioctl (video_fd, VIDIOC_QUERYBUF, &group->buffer) < 0)
|
if (obj->ioctl (obj->video_fd, VIDIOC_QUERYBUF, &group->buffer) < 0)
|
||||||
goto querybuf_failed;
|
goto querybuf_failed;
|
||||||
|
|
||||||
if (group->buffer.index != index) {
|
if (group->buffer.index != index) {
|
||||||
|
@ -273,17 +273,17 @@ gst_v4l2_memory_group_new (GstV4l2Allocator * allocator, guint32 index)
|
||||||
|
|
||||||
/* Check that provided size matches the format we have negotiation. Failing
|
/* Check that provided size matches the format we have negotiation. Failing
|
||||||
* there usually means a driver of libv4l bug. */
|
* there usually means a driver of libv4l bug. */
|
||||||
if (V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
for (i = 0; i < group->n_mem; i++) {
|
for (i = 0; i < group->n_mem; i++) {
|
||||||
img_size = allocator->format.fmt.pix_mp.plane_fmt[i].sizeimage;
|
img_size = obj->format.fmt.pix_mp.plane_fmt[i].sizeimage;
|
||||||
buf_size = group->planes[i].length;
|
buf_size = group->planes[i].length;
|
||||||
if (buf_size < img_size)
|
if (buf_size < img_size)
|
||||||
goto buffer_too_short;
|
goto buffer_too_short;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
img_size = allocator->format.fmt.pix.sizeimage;
|
img_size = obj->format.fmt.pix.sizeimage;
|
||||||
buf_size = group->buffer.length;
|
buf_size = group->buffer.length;
|
||||||
if (buf_size < img_size)
|
if (buf_size < img_size)
|
||||||
goto buffer_too_short;
|
goto buffer_too_short;
|
||||||
|
@ -378,6 +378,7 @@ static void
|
||||||
gst_v4l2_allocator_free (GstAllocator * gallocator, GstMemory * gmem)
|
gst_v4l2_allocator_free (GstAllocator * gallocator, GstMemory * gmem)
|
||||||
{
|
{
|
||||||
GstV4l2Allocator *allocator = (GstV4l2Allocator *) gallocator;
|
GstV4l2Allocator *allocator = (GstV4l2Allocator *) gallocator;
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
GstV4l2Memory *mem = (GstV4l2Memory *) gmem;
|
GstV4l2Memory *mem = (GstV4l2Memory *) gmem;
|
||||||
GstV4l2MemoryGroup *group = mem->group;
|
GstV4l2MemoryGroup *group = mem->group;
|
||||||
|
|
||||||
|
@ -388,7 +389,7 @@ gst_v4l2_allocator_free (GstAllocator * gallocator, GstMemory * gmem)
|
||||||
|
|
||||||
if (allocator->memory == V4L2_MEMORY_MMAP) {
|
if (allocator->memory == V4L2_MEMORY_MMAP) {
|
||||||
if (mem->data)
|
if (mem->data)
|
||||||
v4l2_munmap (mem->data, group->planes[mem->plane].length);
|
obj->munmap (mem->data, group->planes[mem->plane].length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This apply for both mmap with expbuf, and dmabuf imported memory */
|
/* This apply for both mmap with expbuf, and dmabuf imported memory */
|
||||||
|
@ -424,7 +425,6 @@ gst_v4l2_allocator_finalize (GObject * obj)
|
||||||
|
|
||||||
GST_LOG_OBJECT (obj, "called");
|
GST_LOG_OBJECT (obj, "called");
|
||||||
|
|
||||||
v4l2_close (allocator->video_fd);
|
|
||||||
gst_atomic_queue_unref (allocator->free_queue);
|
gst_atomic_queue_unref (allocator->free_queue);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (obj);
|
G_OBJECT_CLASS (parent_class)->finalize (obj);
|
||||||
|
@ -478,22 +478,23 @@ static guint32
|
||||||
gst_v4l2_allocator_probe (GstV4l2Allocator * allocator, guint32 memory,
|
gst_v4l2_allocator_probe (GstV4l2Allocator * allocator, guint32 memory,
|
||||||
guint32 breq_flag, guint32 bcreate_flag)
|
guint32 breq_flag, guint32 bcreate_flag)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
struct v4l2_requestbuffers breq = { 0 };
|
struct v4l2_requestbuffers breq = { 0 };
|
||||||
guint32 flags = 0;
|
guint32 flags = 0;
|
||||||
|
|
||||||
breq.type = allocator->type;
|
breq.type = obj->type;
|
||||||
breq.count = 0;
|
breq.count = 0;
|
||||||
breq.memory = memory;
|
breq.memory = memory;
|
||||||
|
|
||||||
if (v4l2_ioctl (allocator->video_fd, VIDIOC_REQBUFS, &breq) == 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) == 0) {
|
||||||
struct v4l2_create_buffers bcreate = { 0 };
|
struct v4l2_create_buffers bcreate = { 0 };
|
||||||
|
|
||||||
flags |= breq_flag;
|
flags |= breq_flag;
|
||||||
|
|
||||||
bcreate.memory = memory;
|
bcreate.memory = memory;
|
||||||
bcreate.format = allocator->format;
|
bcreate.format = obj->format;
|
||||||
|
|
||||||
if ((v4l2_ioctl (allocator->video_fd, VIDIOC_CREATE_BUFS, &bcreate) == 0))
|
if ((obj->ioctl (obj->video_fd, VIDIOC_CREATE_BUFS, &bcreate) == 0))
|
||||||
flags |= bcreate_flag;
|
flags |= bcreate_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,6 +504,7 @@ gst_v4l2_allocator_probe (GstV4l2Allocator * allocator, guint32 memory,
|
||||||
static GstV4l2MemoryGroup *
|
static GstV4l2MemoryGroup *
|
||||||
gst_v4l2_allocator_create_buf (GstV4l2Allocator * allocator)
|
gst_v4l2_allocator_create_buf (GstV4l2Allocator * allocator)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
struct v4l2_create_buffers bcreate = { 0 };
|
struct v4l2_create_buffers bcreate = { 0 };
|
||||||
GstV4l2MemoryGroup *group = NULL;
|
GstV4l2MemoryGroup *group = NULL;
|
||||||
|
|
||||||
|
@ -512,13 +514,13 @@ gst_v4l2_allocator_create_buf (GstV4l2Allocator * allocator)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
bcreate.memory = allocator->memory;
|
bcreate.memory = allocator->memory;
|
||||||
bcreate.format = allocator->format;
|
bcreate.format = obj->format;
|
||||||
bcreate.count = 1;
|
bcreate.count = 1;
|
||||||
|
|
||||||
if (!allocator->can_allocate)
|
if (!allocator->can_allocate)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (v4l2_ioctl (allocator->video_fd, VIDIOC_CREATE_BUFS, &bcreate) < 0)
|
if (obj->ioctl (obj->video_fd, VIDIOC_CREATE_BUFS, &bcreate) < 0)
|
||||||
goto create_bufs_failed;
|
goto create_bufs_failed;
|
||||||
|
|
||||||
if (allocator->groups[bcreate.index] != NULL)
|
if (allocator->groups[bcreate.index] != NULL)
|
||||||
|
@ -577,6 +579,7 @@ static void
|
||||||
gst_v4l2_allocator_reset_size (GstV4l2Allocator * allocator,
|
gst_v4l2_allocator_reset_size (GstV4l2Allocator * allocator,
|
||||||
GstV4l2MemoryGroup * group)
|
GstV4l2MemoryGroup * group)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
gsize size;
|
gsize size;
|
||||||
gboolean imported = FALSE;
|
gboolean imported = FALSE;
|
||||||
|
|
||||||
|
@ -587,11 +590,11 @@ gst_v4l2_allocator_reset_size (GstV4l2Allocator * allocator,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
for (i = 0; i < group->n_mem; i++) {
|
for (i = 0; i < group->n_mem; i++) {
|
||||||
size = allocator->format.fmt.pix_mp.plane_fmt[i].sizeimage;
|
size = obj->format.fmt.pix_mp.plane_fmt[i].sizeimage;
|
||||||
|
|
||||||
if (imported)
|
if (imported)
|
||||||
group->mem[i]->maxsize = size;
|
group->mem[i]->maxsize = size;
|
||||||
|
@ -600,7 +603,7 @@ gst_v4l2_allocator_reset_size (GstV4l2Allocator * allocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
size = allocator->format.fmt.pix.sizeimage;
|
size = obj->format.fmt.pix.sizeimage;
|
||||||
|
|
||||||
if (imported)
|
if (imported)
|
||||||
group->mem[0]->maxsize = size;
|
group->mem[0]->maxsize = size;
|
||||||
|
@ -628,8 +631,7 @@ _cleanup_failed_alloc (GstV4l2Allocator * allocator, GstV4l2MemoryGroup * group)
|
||||||
|
|
||||||
|
|
||||||
GstV4l2Allocator *
|
GstV4l2Allocator *
|
||||||
gst_v4l2_allocator_new (GstObject * parent, gint video_fd,
|
gst_v4l2_allocator_new (GstObject * parent, GstV4l2Object * v4l2object)
|
||||||
struct v4l2_format *format)
|
|
||||||
{
|
{
|
||||||
GstV4l2Allocator *allocator;
|
GstV4l2Allocator *allocator;
|
||||||
guint32 flags = 0;
|
guint32 flags = 0;
|
||||||
|
@ -644,9 +646,7 @@ gst_v4l2_allocator_new (GstObject * parent, gint video_fd,
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
/* Save everything */
|
/* Save everything */
|
||||||
allocator->video_fd = v4l2_dup (video_fd);
|
allocator->obj = v4l2object;
|
||||||
allocator->type = format->type;
|
|
||||||
allocator->format = *format;
|
|
||||||
|
|
||||||
flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, MMAP);
|
flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, MMAP);
|
||||||
flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, USERPTR);
|
flags |= GST_V4L2_ALLOCATOR_PROBE (allocator, USERPTR);
|
||||||
|
@ -672,7 +672,8 @@ guint
|
||||||
gst_v4l2_allocator_start (GstV4l2Allocator * allocator, guint32 count,
|
gst_v4l2_allocator_start (GstV4l2Allocator * allocator, guint32 count,
|
||||||
guint32 memory)
|
guint32 memory)
|
||||||
{
|
{
|
||||||
struct v4l2_requestbuffers breq = { count, allocator->type, memory };
|
GstV4l2Object *obj = allocator->obj;
|
||||||
|
struct v4l2_requestbuffers breq = { count, obj->type, memory };
|
||||||
gboolean can_allocate;
|
gboolean can_allocate;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
|
@ -683,7 +684,7 @@ gst_v4l2_allocator_start (GstV4l2Allocator * allocator, guint32 count,
|
||||||
if (g_atomic_int_get (&allocator->active))
|
if (g_atomic_int_get (&allocator->active))
|
||||||
goto already_active;
|
goto already_active;
|
||||||
|
|
||||||
if (v4l2_ioctl (allocator->video_fd, VIDIOC_REQBUFS, &breq) < 0)
|
if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
|
||||||
goto reqbufs_failed;
|
goto reqbufs_failed;
|
||||||
|
|
||||||
if (breq.count < 1)
|
if (breq.count < 1)
|
||||||
|
@ -752,7 +753,8 @@ error:
|
||||||
GstV4l2Return
|
GstV4l2Return
|
||||||
gst_v4l2_allocator_stop (GstV4l2Allocator * allocator)
|
gst_v4l2_allocator_stop (GstV4l2Allocator * allocator)
|
||||||
{
|
{
|
||||||
struct v4l2_requestbuffers breq = { 0, allocator->type, allocator->memory };
|
GstV4l2Object *obj = allocator->obj;
|
||||||
|
struct v4l2_requestbuffers breq = { 0, obj->type, allocator->memory };
|
||||||
gint i = 0;
|
gint i = 0;
|
||||||
GstV4l2Return ret = GST_V4L2_OK;
|
GstV4l2Return ret = GST_V4L2_OK;
|
||||||
|
|
||||||
|
@ -781,7 +783,7 @@ gst_v4l2_allocator_stop (GstV4l2Allocator * allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not all drivers support rebufs(0), so warn only */
|
/* Not all drivers support rebufs(0), so warn only */
|
||||||
if (v4l2_ioctl (allocator->video_fd, VIDIOC_REQBUFS, &breq) < 0)
|
if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) < 0)
|
||||||
GST_WARNING_OBJECT (allocator,
|
GST_WARNING_OBJECT (allocator,
|
||||||
"error releasing buffers buffers: %s", g_strerror (errno));
|
"error releasing buffers buffers: %s", g_strerror (errno));
|
||||||
|
|
||||||
|
@ -797,6 +799,7 @@ done:
|
||||||
GstV4l2MemoryGroup *
|
GstV4l2MemoryGroup *
|
||||||
gst_v4l2_allocator_alloc_mmap (GstV4l2Allocator * allocator)
|
gst_v4l2_allocator_alloc_mmap (GstV4l2Allocator * allocator)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
GstV4l2MemoryGroup *group;
|
GstV4l2MemoryGroup *group;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
|
@ -810,8 +813,8 @@ gst_v4l2_allocator_alloc_mmap (GstV4l2Allocator * allocator)
|
||||||
for (i = 0; i < group->n_mem; i++) {
|
for (i = 0; i < group->n_mem; i++) {
|
||||||
if (group->mem[i] == NULL) {
|
if (group->mem[i] == NULL) {
|
||||||
gpointer data;
|
gpointer data;
|
||||||
data = v4l2_mmap (NULL, group->planes[i].length, PROT_READ | PROT_WRITE,
|
data = obj->mmap (NULL, group->planes[i].length, PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED, allocator->video_fd, group->planes[i].m.mem_offset);
|
MAP_SHARED, obj->video_fd, group->planes[i].m.mem_offset);
|
||||||
|
|
||||||
if (data == MAP_FAILED)
|
if (data == MAP_FAILED)
|
||||||
goto mmap_failed;
|
goto mmap_failed;
|
||||||
|
@ -852,6 +855,7 @@ GstV4l2MemoryGroup *
|
||||||
gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * allocator,
|
gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * allocator,
|
||||||
GstAllocator * dmabuf_allocator)
|
GstAllocator * dmabuf_allocator)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
GstV4l2MemoryGroup *group;
|
GstV4l2MemoryGroup *group;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
|
@ -870,12 +874,12 @@ gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * allocator,
|
||||||
if (group->mem[i] == NULL) {
|
if (group->mem[i] == NULL) {
|
||||||
struct v4l2_exportbuffer expbuf = { 0 };
|
struct v4l2_exportbuffer expbuf = { 0 };
|
||||||
|
|
||||||
expbuf.type = allocator->type;
|
expbuf.type = obj->type;
|
||||||
expbuf.index = group->buffer.index;
|
expbuf.index = group->buffer.index;
|
||||||
expbuf.plane = i;
|
expbuf.plane = i;
|
||||||
expbuf.flags = O_CLOEXEC | O_RDWR;
|
expbuf.flags = O_CLOEXEC | O_RDWR;
|
||||||
|
|
||||||
if (v4l2_ioctl (allocator->video_fd, VIDIOC_EXPBUF, &expbuf) < 0)
|
if (obj->ioctl (obj->video_fd, VIDIOC_EXPBUF, &expbuf) < 0)
|
||||||
goto expbuf_failed;
|
goto expbuf_failed;
|
||||||
|
|
||||||
GST_LOG_OBJECT (allocator, "exported DMABUF as fd %i plane %d",
|
GST_LOG_OBJECT (allocator, "exported DMABUF as fd %i plane %d",
|
||||||
|
@ -933,6 +937,7 @@ static void
|
||||||
gst_v4l2_allocator_clear_dmabufin (GstV4l2Allocator * allocator,
|
gst_v4l2_allocator_clear_dmabufin (GstV4l2Allocator * allocator,
|
||||||
GstV4l2MemoryGroup * group)
|
GstV4l2MemoryGroup * group)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
GstV4l2Memory *mem;
|
GstV4l2Memory *mem;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
|
@ -961,7 +966,7 @@ gst_v4l2_allocator_clear_dmabufin (GstV4l2Allocator * allocator,
|
||||||
group->planes[i].data_offset = 0;
|
group->planes[i].data_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (!V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
group->buffer.bytesused = 0;
|
group->buffer.bytesused = 0;
|
||||||
group->buffer.length = 0;
|
group->buffer.length = 0;
|
||||||
group->buffer.m.fd = -1;
|
group->buffer.m.fd = -1;
|
||||||
|
@ -1004,6 +1009,7 @@ static void
|
||||||
gst_v4l2_allocator_clear_userptr (GstV4l2Allocator * allocator,
|
gst_v4l2_allocator_clear_userptr (GstV4l2Allocator * allocator,
|
||||||
GstV4l2MemoryGroup * group)
|
GstV4l2MemoryGroup * group)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
GstV4l2Memory *mem;
|
GstV4l2Memory *mem;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
|
@ -1024,7 +1030,7 @@ gst_v4l2_allocator_clear_userptr (GstV4l2Allocator * allocator,
|
||||||
group->planes[i].m.userptr = 0;
|
group->planes[i].m.userptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (!V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
group->buffer.bytesused = 0;
|
group->buffer.bytesused = 0;
|
||||||
group->buffer.length = 0;
|
group->buffer.length = 0;
|
||||||
group->buffer.m.userptr = 0;
|
group->buffer.m.userptr = 0;
|
||||||
|
@ -1068,6 +1074,7 @@ gboolean
|
||||||
gst_v4l2_allocator_import_dmabuf (GstV4l2Allocator * allocator,
|
gst_v4l2_allocator_import_dmabuf (GstV4l2Allocator * allocator,
|
||||||
GstV4l2MemoryGroup * group, gint n_mem, GstMemory ** dma_mem)
|
GstV4l2MemoryGroup * group, gint n_mem, GstMemory ** dma_mem)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
GstV4l2Memory *mem;
|
GstV4l2Memory *mem;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
|
@ -1106,7 +1113,7 @@ gst_v4l2_allocator_import_dmabuf (GstV4l2Allocator * allocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy into buffer structure if not using planes */
|
/* Copy into buffer structure if not using planes */
|
||||||
if (!V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (!V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
group->buffer.bytesused = group->planes[0].bytesused;
|
group->buffer.bytesused = group->planes[0].bytesused;
|
||||||
group->buffer.length = group->planes[0].length;
|
group->buffer.length = group->planes[0].length;
|
||||||
group->buffer.m.fd = group->planes[0].m.userptr;
|
group->buffer.m.fd = group->planes[0].m.userptr;
|
||||||
|
@ -1140,24 +1147,25 @@ gst_v4l2_allocator_import_userptr (GstV4l2Allocator * allocator,
|
||||||
GstV4l2MemoryGroup * group, gsize img_size, int n_planes,
|
GstV4l2MemoryGroup * group, gsize img_size, int n_planes,
|
||||||
gpointer * data, gsize * size)
|
gpointer * data, gsize * size)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
GstV4l2Memory *mem;
|
GstV4l2Memory *mem;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
g_return_val_if_fail (allocator->memory == V4L2_MEMORY_USERPTR, FALSE);
|
g_return_val_if_fail (allocator->memory == V4L2_MEMORY_USERPTR, FALSE);
|
||||||
|
|
||||||
/* TODO Support passing N plane from 1 memory to MPLANE v4l2 format */
|
/* TODO Support passing N plane from 1 memory to MPLANE v4l2 format */
|
||||||
if (V4L2_TYPE_IS_MULTIPLANAR (allocator->type) && n_planes != group->n_mem)
|
if (V4L2_TYPE_IS_MULTIPLANAR (obj->type) && n_planes != group->n_mem)
|
||||||
goto n_mem_missmatch;
|
goto n_mem_missmatch;
|
||||||
|
|
||||||
for (i = 0; i < group->n_mem; i++) {
|
for (i = 0; i < group->n_mem; i++) {
|
||||||
gsize maxsize, psize;
|
gsize maxsize, psize;
|
||||||
|
|
||||||
if (V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
struct v4l2_pix_format_mplane *pix = &allocator->format.fmt.pix_mp;
|
struct v4l2_pix_format_mplane *pix = &obj->format.fmt.pix_mp;
|
||||||
maxsize = pix->plane_fmt[i].sizeimage;
|
maxsize = pix->plane_fmt[i].sizeimage;
|
||||||
psize = size[i];
|
psize = size[i];
|
||||||
} else {
|
} else {
|
||||||
maxsize = allocator->format.fmt.pix.sizeimage;
|
maxsize = obj->format.fmt.pix.sizeimage;
|
||||||
psize = img_size;
|
psize = img_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1179,7 +1187,7 @@ gst_v4l2_allocator_import_userptr (GstV4l2Allocator * allocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy into buffer structure if not using planes */
|
/* Copy into buffer structure if not using planes */
|
||||||
if (!V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (!V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
group->buffer.bytesused = group->planes[0].bytesused;
|
group->buffer.bytesused = group->planes[0].bytesused;
|
||||||
group->buffer.length = group->planes[0].length;
|
group->buffer.length = group->planes[0].length;
|
||||||
group->buffer.m.userptr = group->planes[0].m.userptr;
|
group->buffer.m.userptr = group->planes[0].m.userptr;
|
||||||
|
@ -1229,13 +1237,14 @@ gboolean
|
||||||
gst_v4l2_allocator_qbuf (GstV4l2Allocator * allocator,
|
gst_v4l2_allocator_qbuf (GstV4l2Allocator * allocator,
|
||||||
GstV4l2MemoryGroup * group)
|
GstV4l2MemoryGroup * group)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
g_return_val_if_fail (g_atomic_int_get (&allocator->active), FALSE);
|
g_return_val_if_fail (g_atomic_int_get (&allocator->active), FALSE);
|
||||||
|
|
||||||
/* update sizes */
|
/* update sizes */
|
||||||
if (V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
for (i = 0; i < group->n_mem; i++)
|
for (i = 0; i < group->n_mem; i++)
|
||||||
group->planes[i].bytesused =
|
group->planes[i].bytesused =
|
||||||
gst_memory_get_sizes (group->mem[i], NULL, NULL);
|
gst_memory_get_sizes (group->mem[i], NULL, NULL);
|
||||||
|
@ -1247,7 +1256,7 @@ gst_v4l2_allocator_qbuf (GstV4l2Allocator * allocator,
|
||||||
for (i = 0; i < group->n_mem; i++)
|
for (i = 0; i < group->n_mem; i++)
|
||||||
gst_memory_ref (group->mem[i]);
|
gst_memory_ref (group->mem[i]);
|
||||||
|
|
||||||
if (v4l2_ioctl (allocator->video_fd, VIDIOC_QBUF, &group->buffer) < 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_QBUF, &group->buffer) < 0) {
|
||||||
GST_ERROR_OBJECT (allocator, "failed queueing buffer %i: %s",
|
GST_ERROR_OBJECT (allocator, "failed queueing buffer %i: %s",
|
||||||
group->buffer.index, g_strerror (errno));
|
group->buffer.index, g_strerror (errno));
|
||||||
|
|
||||||
|
@ -1281,6 +1290,7 @@ GstFlowReturn
|
||||||
gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator,
|
gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator,
|
||||||
GstV4l2MemoryGroup ** group_out)
|
GstV4l2MemoryGroup ** group_out)
|
||||||
{
|
{
|
||||||
|
GstV4l2Object *obj = allocator->obj;
|
||||||
struct v4l2_buffer buffer = { 0 };
|
struct v4l2_buffer buffer = { 0 };
|
||||||
struct v4l2_plane planes[VIDEO_MAX_PLANES] = { {0} };
|
struct v4l2_plane planes[VIDEO_MAX_PLANES] = { {0} };
|
||||||
gint i;
|
gint i;
|
||||||
|
@ -1289,15 +1299,15 @@ gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator,
|
||||||
|
|
||||||
g_return_val_if_fail (g_atomic_int_get (&allocator->active), GST_FLOW_ERROR);
|
g_return_val_if_fail (g_atomic_int_get (&allocator->active), GST_FLOW_ERROR);
|
||||||
|
|
||||||
buffer.type = allocator->type;
|
buffer.type = obj->type;
|
||||||
buffer.memory = allocator->memory;
|
buffer.memory = allocator->memory;
|
||||||
|
|
||||||
if (V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
buffer.length = allocator->format.fmt.pix_mp.num_planes;
|
buffer.length = obj->format.fmt.pix_mp.num_planes;
|
||||||
buffer.m.planes = planes;
|
buffer.m.planes = planes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v4l2_ioctl (allocator->video_fd, VIDIOC_DQBUF, &buffer) < 0)
|
if (obj->ioctl (obj->video_fd, VIDIOC_DQBUF, &buffer) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
group = allocator->groups[buffer.index];
|
group = allocator->groups[buffer.index];
|
||||||
|
@ -1319,7 +1329,7 @@ gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator,
|
||||||
UNSET_QUEUED (group->buffer);
|
UNSET_QUEUED (group->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
|
if (V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
|
||||||
group->buffer.m.planes = group->planes;
|
group->buffer.m.planes = group->planes;
|
||||||
memcpy (group->planes, buffer.m.planes, sizeof (planes));
|
memcpy (group->planes, buffer.m.planes, sizeof (planes));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1330,7 +1340,7 @@ gst_v4l2_allocator_dqbuf (GstV4l2Allocator * allocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And update memory size */
|
/* And update memory size */
|
||||||
if (V4L2_TYPE_IS_OUTPUT (allocator->type)) {
|
if (V4L2_TYPE_IS_OUTPUT (obj->type)) {
|
||||||
gst_v4l2_allocator_reset_size (allocator, group);
|
gst_v4l2_allocator_reset_size (allocator, group);
|
||||||
} else {
|
} else {
|
||||||
/* for capture, simply read the size */
|
/* for capture, simply read the size */
|
||||||
|
|
|
@ -50,6 +50,7 @@ typedef struct _GstV4l2MemoryGroup GstV4l2MemoryGroup;
|
||||||
typedef struct _GstV4l2Memory GstV4l2Memory;
|
typedef struct _GstV4l2Memory GstV4l2Memory;
|
||||||
typedef enum _GstV4l2Capabilities GstV4l2Capabilities;
|
typedef enum _GstV4l2Capabilities GstV4l2Capabilities;
|
||||||
typedef enum _GstV4l2Return GstV4l2Return;
|
typedef enum _GstV4l2Return GstV4l2Return;
|
||||||
|
typedef struct _GstV4l2Object GstV4l2Object;
|
||||||
|
|
||||||
enum _GstV4l2AllocatorFlags
|
enum _GstV4l2AllocatorFlags
|
||||||
{
|
{
|
||||||
|
@ -89,11 +90,9 @@ struct _GstV4l2MemoryGroup
|
||||||
struct _GstV4l2Allocator
|
struct _GstV4l2Allocator
|
||||||
{
|
{
|
||||||
GstAllocator parent;
|
GstAllocator parent;
|
||||||
gint video_fd;
|
GstV4l2Object *obj;
|
||||||
guint32 count;
|
guint32 count;
|
||||||
guint32 type;
|
|
||||||
guint32 memory;
|
guint32 memory;
|
||||||
struct v4l2_format format;
|
|
||||||
gboolean can_allocate;
|
gboolean can_allocate;
|
||||||
gboolean active;
|
gboolean active;
|
||||||
|
|
||||||
|
@ -117,8 +116,7 @@ gboolean gst_v4l2_allocator_is_active (GstV4l2Allocator * alloc
|
||||||
|
|
||||||
guint gst_v4l2_allocator_get_size (GstV4l2Allocator * allocator);
|
guint gst_v4l2_allocator_get_size (GstV4l2Allocator * allocator);
|
||||||
|
|
||||||
GstV4l2Allocator* gst_v4l2_allocator_new (GstObject *parent, gint video_fd,
|
GstV4l2Allocator* gst_v4l2_allocator_new (GstObject *parent, GstV4l2Object * obj);
|
||||||
struct v4l2_format * format);
|
|
||||||
|
|
||||||
guint gst_v4l2_allocator_start (GstV4l2Allocator * allocator,
|
guint gst_v4l2_allocator_start (GstV4l2Allocator * allocator,
|
||||||
guint32 count, guint32 memory);
|
guint32 count, guint32 memory);
|
||||||
|
|
|
@ -621,7 +621,7 @@ gst_v4l2_buffer_pool_streamon (GstV4l2BufferPool * pool)
|
||||||
case GST_V4L2_IO_DMABUF:
|
case GST_V4L2_IO_DMABUF:
|
||||||
case GST_V4L2_IO_DMABUF_IMPORT:
|
case GST_V4L2_IO_DMABUF_IMPORT:
|
||||||
if (!pool->streaming) {
|
if (!pool->streaming) {
|
||||||
if (v4l2_ioctl (pool->video_fd, VIDIOC_STREAMON, &obj->type) < 0)
|
if (obj->ioctl (pool->video_fd, VIDIOC_STREAMON, &obj->type) < 0)
|
||||||
goto streamon_failed;
|
goto streamon_failed;
|
||||||
|
|
||||||
pool->streaming = TRUE;
|
pool->streaming = TRUE;
|
||||||
|
@ -654,7 +654,7 @@ gst_v4l2_buffer_pool_streamoff (GstV4l2BufferPool * pool)
|
||||||
case GST_V4L2_IO_DMABUF:
|
case GST_V4L2_IO_DMABUF:
|
||||||
case GST_V4L2_IO_DMABUF_IMPORT:
|
case GST_V4L2_IO_DMABUF_IMPORT:
|
||||||
if (pool->streaming) {
|
if (pool->streaming) {
|
||||||
if (v4l2_ioctl (pool->video_fd, VIDIOC_STREAMOFF, &obj->type) < 0)
|
if (obj->ioctl (pool->video_fd, VIDIOC_STREAMOFF, &obj->type) < 0)
|
||||||
GST_WARNING_OBJECT (pool, "STREAMOFF failed with errno %d (%s)",
|
GST_WARNING_OBJECT (pool, "STREAMOFF failed with errno %d (%s)",
|
||||||
errno, g_strerror (errno));
|
errno, g_strerror (errno));
|
||||||
|
|
||||||
|
@ -728,7 +728,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
|
||||||
* queue to be initialized now. We only do this if we have a streaming
|
* queue to be initialized now. We only do this if we have a streaming
|
||||||
* driver. */
|
* driver. */
|
||||||
if (obj->device_caps & V4L2_CAP_STREAMING)
|
if (obj->device_caps & V4L2_CAP_STREAMING)
|
||||||
v4l2_read (obj->video_fd, NULL, 0);
|
obj->read (obj->video_fd, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case GST_V4L2_IO_DMABUF:
|
case GST_V4L2_IO_DMABUF:
|
||||||
|
@ -1609,8 +1609,7 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
|
||||||
pool->obj = obj;
|
pool->obj = obj;
|
||||||
pool->can_poll_device = TRUE;
|
pool->can_poll_device = TRUE;
|
||||||
|
|
||||||
pool->vallocator =
|
pool->vallocator = gst_v4l2_allocator_new (GST_OBJECT (pool), obj);
|
||||||
gst_v4l2_allocator_new (GST_OBJECT (pool), obj->video_fd, &obj->format);
|
|
||||||
if (pool->vallocator == NULL)
|
if (pool->vallocator == NULL)
|
||||||
goto allocator_failed;
|
goto allocator_failed;
|
||||||
|
|
||||||
|
@ -1657,7 +1656,7 @@ gst_v4l2_do_read (GstV4l2BufferPool * pool, GstBuffer * buf)
|
||||||
if ((res = gst_v4l2_buffer_pool_poll (pool)) != GST_FLOW_OK)
|
if ((res = gst_v4l2_buffer_pool_poll (pool)) != GST_FLOW_OK)
|
||||||
goto poll_error;
|
goto poll_error;
|
||||||
|
|
||||||
amount = v4l2_read (obj->video_fd, map.data, toread);
|
amount = obj->read (obj->video_fd, map.data, toread);
|
||||||
|
|
||||||
if (amount == toread) {
|
if (amount == toread) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -329,7 +329,7 @@ negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
|
||||||
if (control.value < 0)
|
if (control.value < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0) {
|
||||||
GST_WARNING_OBJECT (ctx->self, "Failed to set H264 profile: '%s'",
|
GST_WARNING_OBJECT (ctx->self, "Failed to set H264 profile: '%s'",
|
||||||
g_strerror (errno));
|
g_strerror (errno));
|
||||||
break;
|
break;
|
||||||
|
@ -371,7 +371,7 @@ negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
|
||||||
if (control.value < 0)
|
if (control.value < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0) {
|
||||||
GST_WARNING_OBJECT (ctx->self, "Failed to set H264 level: '%s'",
|
GST_WARNING_OBJECT (ctx->self, "Failed to set H264 level: '%s'",
|
||||||
g_strerror (errno));
|
g_strerror (errno));
|
||||||
break;
|
break;
|
||||||
|
@ -436,7 +436,7 @@ gst_v4l2_h264_enc_negotiate (GstVideoEncoder * encoder)
|
||||||
|
|
||||||
control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
|
control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
|
||||||
goto g_ctrl_failed;
|
goto g_ctrl_failed;
|
||||||
|
|
||||||
ctx.profile = v4l2_profile_to_string (control.value);
|
ctx.profile = v4l2_profile_to_string (control.value);
|
||||||
|
@ -447,7 +447,7 @@ gst_v4l2_h264_enc_negotiate (GstVideoEncoder * encoder)
|
||||||
|
|
||||||
control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
|
control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
|
||||||
goto g_ctrl_failed;
|
goto g_ctrl_failed;
|
||||||
|
|
||||||
ctx.level = v4l2_level_to_string (control.value);
|
ctx.level = v4l2_level_to_string (control.value);
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_GUDEV
|
#ifdef HAVE_GUDEV
|
||||||
#include <gudev/gudev.h>
|
#include <gudev/gudev.h>
|
||||||
|
@ -490,6 +493,28 @@ gst_v4l2_object_new (GstElement * element,
|
||||||
|
|
||||||
v4l2object->no_initial_format = FALSE;
|
v4l2object->no_initial_format = FALSE;
|
||||||
|
|
||||||
|
/* We now disable libv4l2 by default, but have an env to enable it. */
|
||||||
|
#ifdef HAVE_LIBV4L2
|
||||||
|
if (g_getenv ("GST_V4L2_USE_LIBV4L2")) {
|
||||||
|
v4l2object->fd_open = v4l2_fd_open;
|
||||||
|
v4l2object->close = v4l2_close;
|
||||||
|
v4l2object->dup = v4l2_dup;
|
||||||
|
v4l2object->ioctl = v4l2_ioctl;
|
||||||
|
v4l2object->read = v4l2_read;
|
||||||
|
v4l2object->mmap = v4l2_mmap;
|
||||||
|
v4l2object->munmap = v4l2_munmap;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
v4l2object->fd_open = NULL;
|
||||||
|
v4l2object->close = close;
|
||||||
|
v4l2object->dup = dup;
|
||||||
|
v4l2object->ioctl = ioctl;
|
||||||
|
v4l2object->read = read;
|
||||||
|
v4l2object->mmap = mmap;
|
||||||
|
v4l2object->munmap = munmap;
|
||||||
|
}
|
||||||
|
|
||||||
return v4l2object;
|
return v4l2object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,7 +800,7 @@ gst_v4l2_get_driver_min_buffers (GstV4l2Object * v4l2object)
|
||||||
else
|
else
|
||||||
control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
|
control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) == 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) == 0) {
|
||||||
GST_DEBUG_OBJECT (v4l2object->element,
|
GST_DEBUG_OBJECT (v4l2object->element,
|
||||||
"driver requires a minimum of %d buffers", control.value);
|
"driver requires a minimum of %d buffers", control.value);
|
||||||
v4l2object->min_buffers = control.value;
|
v4l2object->min_buffers = control.value;
|
||||||
|
@ -1113,7 +1138,7 @@ gst_v4l2_object_fill_format_list (GstV4l2Object * v4l2object,
|
||||||
format->index = n;
|
format->index = n;
|
||||||
format->type = type;
|
format->type = type;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0) {
|
||||||
if (errno == EINVAL) {
|
if (errno == EINVAL) {
|
||||||
g_free (format);
|
g_free (format);
|
||||||
break; /* end of enumeration */
|
break; /* end of enumeration */
|
||||||
|
@ -2065,7 +2090,7 @@ gst_v4l2_object_try_fmt (GstV4l2Object * v4l2object,
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
memcpy (&fmt, try_fmt, sizeof (fmt));
|
memcpy (&fmt, try_fmt, sizeof (fmt));
|
||||||
r = v4l2_ioctl (fd, VIDIOC_TRY_FMT, &fmt);
|
r = v4l2object->ioctl (fd, VIDIOC_TRY_FMT, &fmt);
|
||||||
|
|
||||||
if (r < 0 && errno == ENOTTY) {
|
if (r < 0 && errno == ENOTTY) {
|
||||||
/* The driver might not implement TRY_FMT, in which case we will try
|
/* The driver might not implement TRY_FMT, in which case we will try
|
||||||
|
@ -2074,7 +2099,7 @@ gst_v4l2_object_try_fmt (GstV4l2Object * v4l2object,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
memcpy (&fmt, try_fmt, sizeof (fmt));
|
memcpy (&fmt, try_fmt, sizeof (fmt));
|
||||||
r = v4l2_ioctl (fd, VIDIOC_S_FMT, &fmt);
|
r = v4l2object->ioctl (fd, VIDIOC_S_FMT, &fmt);
|
||||||
}
|
}
|
||||||
memcpy (try_fmt, &fmt, sizeof (fmt));
|
memcpy (try_fmt, &fmt, sizeof (fmt));
|
||||||
|
|
||||||
|
@ -2269,7 +2294,7 @@ gst_v4l2_object_probe_caps_for_format_and_size (GstV4l2Object * v4l2object,
|
||||||
|
|
||||||
/* keep in mind that v4l2 gives us frame intervals (durations); we invert the
|
/* keep in mind that v4l2 gives us frame intervals (durations); we invert the
|
||||||
* fraction to get framerate */
|
* fraction to get framerate */
|
||||||
if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0)
|
if (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0)
|
||||||
goto enum_frameintervals_failed;
|
goto enum_frameintervals_failed;
|
||||||
|
|
||||||
if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
||||||
|
@ -2296,7 +2321,7 @@ gst_v4l2_object_probe_caps_for_format_and_size (GstV4l2Object * v4l2object,
|
||||||
gst_value_list_append_value (&rates, &rate);
|
gst_value_list_append_value (&rates, &rate);
|
||||||
|
|
||||||
ival.index++;
|
ival.index++;
|
||||||
} while (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
|
} while (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
|
||||||
} else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
|
} else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
|
||||||
GValue min = { 0, };
|
GValue min = { 0, };
|
||||||
GValue step = { 0, };
|
GValue step = { 0, };
|
||||||
|
@ -2535,7 +2560,7 @@ gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
|
||||||
"Enumerating frame sizes for %" GST_FOURCC_FORMAT,
|
"Enumerating frame sizes for %" GST_FOURCC_FORMAT,
|
||||||
GST_FOURCC_ARGS (pixelformat));
|
GST_FOURCC_ARGS (pixelformat));
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0)
|
if (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0)
|
||||||
goto enum_framesizes_failed;
|
goto enum_framesizes_failed;
|
||||||
|
|
||||||
if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
|
if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
|
||||||
|
@ -2556,7 +2581,7 @@ gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
|
||||||
}
|
}
|
||||||
|
|
||||||
size.index++;
|
size.index++;
|
||||||
} while (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
|
} while (v4l2object->ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
|
||||||
GST_DEBUG_OBJECT (v4l2object->element,
|
GST_DEBUG_OBJECT (v4l2object->element,
|
||||||
"done iterating discrete frame sizes");
|
"done iterating discrete frame sizes");
|
||||||
} else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
|
} else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
|
||||||
|
@ -3369,10 +3394,10 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try_only) {
|
if (try_only) {
|
||||||
if (v4l2_ioctl (fd, VIDIOC_TRY_FMT, &format) < 0)
|
if (v4l2object->ioctl (fd, VIDIOC_TRY_FMT, &format) < 0)
|
||||||
goto try_fmt_failed;
|
goto try_fmt_failed;
|
||||||
} else {
|
} else {
|
||||||
if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
|
if (v4l2object->ioctl (fd, VIDIOC_S_FMT, &format) < 0)
|
||||||
goto set_fmt_failed;
|
goto set_fmt_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3454,7 +3479,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
||||||
ctl.id = V4L2_CID_ALPHA_COMPONENT;
|
ctl.id = V4L2_CID_ALPHA_COMPONENT;
|
||||||
ctl.value = 0xff;
|
ctl.value = 0xff;
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_S_CTRL, &ctl) < 0)
|
if (v4l2object->ioctl (fd, VIDIOC_S_CTRL, &ctl) < 0)
|
||||||
GST_WARNING_OBJECT (v4l2object->element,
|
GST_WARNING_OBJECT (v4l2object->element,
|
||||||
"Failed to set alpha component value");
|
"Failed to set alpha component value");
|
||||||
}
|
}
|
||||||
|
@ -3466,7 +3491,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
||||||
memset (&streamparm, 0x00, sizeof (struct v4l2_streamparm));
|
memset (&streamparm, 0x00, sizeof (struct v4l2_streamparm));
|
||||||
streamparm.type = v4l2object->type;
|
streamparm.type = v4l2object->type;
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_G_PARM, &streamparm) < 0)
|
if (v4l2object->ioctl (fd, VIDIOC_G_PARM, &streamparm) < 0)
|
||||||
goto get_parm_failed;
|
goto get_parm_failed;
|
||||||
|
|
||||||
if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|
if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|
||||||
|
@ -3500,7 +3525,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
||||||
streamparm.parm.capture.timeperframe.denominator = fps_n;
|
streamparm.parm.capture.timeperframe.denominator = fps_n;
|
||||||
|
|
||||||
/* some cheap USB cam's won't accept any change */
|
/* some cheap USB cam's won't accept any change */
|
||||||
if (v4l2_ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
|
if (v4l2object->ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
|
||||||
goto set_parm_failed;
|
goto set_parm_failed;
|
||||||
|
|
||||||
if (streamparm.parm.capture.timeperframe.numerator > 0 &&
|
if (streamparm.parm.capture.timeperframe.numerator > 0 &&
|
||||||
|
@ -3542,7 +3567,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
||||||
streamparm.parm.output.timeperframe.numerator = fps_d;
|
streamparm.parm.output.timeperframe.numerator = fps_d;
|
||||||
streamparm.parm.output.timeperframe.denominator = fps_n;
|
streamparm.parm.output.timeperframe.denominator = fps_n;
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
|
if (v4l2object->ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
|
||||||
goto set_parm_failed;
|
goto set_parm_failed;
|
||||||
|
|
||||||
if (streamparm.parm.output.timeperframe.numerator > 0 &&
|
if (streamparm.parm.output.timeperframe.numerator > 0 &&
|
||||||
|
@ -3750,7 +3775,7 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
|
||||||
|
|
||||||
memset (&fmt, 0x00, sizeof (struct v4l2_format));
|
memset (&fmt, 0x00, sizeof (struct v4l2_format));
|
||||||
fmt.type = v4l2object->type;
|
fmt.type = v4l2object->type;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_FMT, &fmt) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_FMT, &fmt) < 0)
|
||||||
goto get_fmt_failed;
|
goto get_fmt_failed;
|
||||||
|
|
||||||
fmtdesc = gst_v4l2_object_get_format_from_fourcc (v4l2object,
|
fmtdesc = gst_v4l2_object_get_format_from_fourcc (v4l2object,
|
||||||
|
@ -3775,13 +3800,13 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
|
||||||
memset (&sel, 0, sizeof (struct v4l2_selection));
|
memset (&sel, 0, sizeof (struct v4l2_selection));
|
||||||
sel.type = v4l2object->type;
|
sel.type = v4l2object->type;
|
||||||
sel.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
|
sel.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_SELECTION, &sel) >= 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_SELECTION, &sel) >= 0) {
|
||||||
r = &sel.r;
|
r = &sel.r;
|
||||||
} else {
|
} else {
|
||||||
/* For ancient kernels, fall back to G_CROP */
|
/* For ancient kernels, fall back to G_CROP */
|
||||||
memset (&crop, 0, sizeof (struct v4l2_crop));
|
memset (&crop, 0, sizeof (struct v4l2_crop));
|
||||||
crop.type = v4l2object->type;
|
crop.type = v4l2object->type;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_CROP, &crop) >= 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CROP, &crop) >= 0)
|
||||||
r = &crop.c;
|
r = &crop.c;
|
||||||
}
|
}
|
||||||
if (r) {
|
if (r) {
|
||||||
|
@ -3869,12 +3894,12 @@ gst_v4l2_object_set_crop (GstV4l2Object * obj)
|
||||||
"Desired cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
|
"Desired cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
|
||||||
crop.c.width, crop.c.height);
|
crop.c.width, crop.c.height);
|
||||||
|
|
||||||
if (v4l2_ioctl (obj->video_fd, VIDIOC_S_CROP, &crop) < 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_S_CROP, &crop) < 0) {
|
||||||
GST_WARNING_OBJECT (obj->element, "VIDIOC_S_CROP failed");
|
GST_WARNING_OBJECT (obj->element, "VIDIOC_S_CROP failed");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v4l2_ioctl (obj->video_fd, VIDIOC_G_CROP, &crop) < 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_G_CROP, &crop) < 0) {
|
||||||
GST_WARNING_OBJECT (obj->element, "VIDIOC_G_CROP failed");
|
GST_WARNING_OBJECT (obj->element, "VIDIOC_G_CROP failed");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -3972,7 +3997,7 @@ gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter)
|
||||||
memset (&cropcap, 0, sizeof (cropcap));
|
memset (&cropcap, 0, sizeof (cropcap));
|
||||||
|
|
||||||
cropcap.type = v4l2object->type;
|
cropcap.type = v4l2object->type;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_CROPCAP, &cropcap) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_CROPCAP, &cropcap) < 0) {
|
||||||
if (errno != ENOTTY)
|
if (errno != ENOTTY)
|
||||||
GST_WARNING_OBJECT (v4l2object->element,
|
GST_WARNING_OBJECT (v4l2object->element,
|
||||||
"Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: %s",
|
"Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: %s",
|
||||||
|
|
|
@ -24,23 +24,11 @@
|
||||||
#ifndef __GST_V4L2_OBJECT_H__
|
#ifndef __GST_V4L2_OBJECT_H__
|
||||||
#define __GST_V4L2_OBJECT_H__
|
#define __GST_V4L2_OBJECT_H__
|
||||||
|
|
||||||
|
#include "ext/videodev2.h"
|
||||||
#ifdef HAVE_LIBV4L2
|
#ifdef HAVE_LIBV4L2
|
||||||
# include <libv4l2.h>
|
# include <libv4l2.h>
|
||||||
#else
|
|
||||||
# include "ext/videodev2.h"
|
|
||||||
# include <sys/ioctl.h>
|
|
||||||
# include <sys/mman.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
# define v4l2_fd_open(fd, flags) (fd)
|
|
||||||
# define v4l2_close close
|
|
||||||
# define v4l2_dup dup
|
|
||||||
# define v4l2_ioctl ioctl
|
|
||||||
# define v4l2_read read
|
|
||||||
# define v4l2_mmap mmap
|
|
||||||
# define v4l2_munmap munmap
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ext/videodev2.h"
|
|
||||||
#include "v4l2-utils.h"
|
#include "v4l2-utils.h"
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
@ -212,6 +200,16 @@ struct _GstV4l2Object {
|
||||||
GstV4l2SetInOutFunction set_in_out_func;
|
GstV4l2SetInOutFunction set_in_out_func;
|
||||||
GstV4l2UpdateFpsFunction update_fps_func;
|
GstV4l2UpdateFpsFunction update_fps_func;
|
||||||
|
|
||||||
|
/* syscalls */
|
||||||
|
int (*fd_open) (int fd, int v4l2_flags);
|
||||||
|
int (*close) (int fd);
|
||||||
|
int (*dup) (int fd);
|
||||||
|
int (*ioctl) (int fd, unsigned long int request, ...);
|
||||||
|
ssize_t (*read) (int fd, void *buffer, size_t n);
|
||||||
|
void * (*mmap) (void *start, size_t length, int prot, int flags,
|
||||||
|
int fd, int64_t offset);
|
||||||
|
int (*munmap) (void *_start, size_t length);
|
||||||
|
|
||||||
/* Quirks */
|
/* Quirks */
|
||||||
/* Skips interlacing probes */
|
/* Skips interlacing probes */
|
||||||
gboolean never_interlaced;
|
gboolean never_interlaced;
|
||||||
|
|
|
@ -86,7 +86,7 @@ gst_v4l2radio_fill_channel_list (GstV4l2Radio * radio)
|
||||||
|
|
||||||
memset (&vc, 0, sizeof (vc));
|
memset (&vc, 0, sizeof (vc));
|
||||||
|
|
||||||
res = v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP, &vc);
|
res = v4l2object->ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP, &vc);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto caps_failed;
|
goto caps_failed;
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ gst_v4l2radio_fill_channel_list (GstV4l2Radio * radio)
|
||||||
memset (&vtun, 0, sizeof (vtun));
|
memset (&vtun, 0, sizeof (vtun));
|
||||||
vtun.index = 0;
|
vtun.index = 0;
|
||||||
|
|
||||||
res = v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &vtun);
|
res = v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &vtun);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto tuner_failed;
|
goto tuner_failed;
|
||||||
|
|
||||||
|
|
|
@ -246,16 +246,16 @@ gst_v4l2sink_sync_overlay_fields (GstV4l2Sink * v4l2sink)
|
||||||
|
|
||||||
if (GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
|
if (GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
|
||||||
|
|
||||||
gint fd = v4l2sink->v4l2object->video_fd;
|
GstV4l2Object *obj = v4l2sink->v4l2object;
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
|
|
||||||
memset (&format, 0x00, sizeof (struct v4l2_format));
|
memset (&format, 0x00, sizeof (struct v4l2_format));
|
||||||
if (v4l2sink->v4l2object->device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
|
if (obj->device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
|
||||||
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY;
|
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY;
|
||||||
else
|
else
|
||||||
format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
|
format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_G_FMT, &format) < 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_G_FMT, &format) < 0) {
|
||||||
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_G_FMT failed");
|
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_G_FMT failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ gst_v4l2sink_sync_overlay_fields (GstV4l2Sink * v4l2sink)
|
||||||
if (v4l2sink->overlay_fields_set & RECT_HEIGHT_SET)
|
if (v4l2sink->overlay_fields_set & RECT_HEIGHT_SET)
|
||||||
format.fmt.win.w.height = v4l2sink->overlay.height;
|
format.fmt.win.w.height = v4l2sink->overlay.height;
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_S_FMT, &format) < 0) {
|
||||||
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_S_FMT failed");
|
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_S_FMT failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -293,13 +293,13 @@ gst_v4l2sink_sync_crop_fields (GstV4l2Sink * v4l2sink)
|
||||||
|
|
||||||
if (GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
|
if (GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
|
||||||
|
|
||||||
gint fd = v4l2sink->v4l2object->video_fd;
|
GstV4l2Object *obj = v4l2sink->v4l2object;
|
||||||
struct v4l2_crop crop;
|
struct v4l2_crop crop;
|
||||||
|
|
||||||
memset (&crop, 0x00, sizeof (struct v4l2_crop));
|
memset (&crop, 0x00, sizeof (struct v4l2_crop));
|
||||||
crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_G_CROP, &crop) < 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_G_CROP, &crop) < 0) {
|
||||||
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_G_CROP failed");
|
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_G_CROP failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -319,12 +319,12 @@ gst_v4l2sink_sync_crop_fields (GstV4l2Sink * v4l2sink)
|
||||||
if (v4l2sink->crop_fields_set & RECT_HEIGHT_SET)
|
if (v4l2sink->crop_fields_set & RECT_HEIGHT_SET)
|
||||||
crop.c.height = v4l2sink->crop.height;
|
crop.c.height = v4l2sink->crop.height;
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_S_CROP, &crop) < 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_S_CROP, &crop) < 0) {
|
||||||
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_S_CROP failed");
|
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_S_CROP failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_G_CROP, &crop) < 0) {
|
if (obj->ioctl (obj->video_fd, VIDIOC_G_CROP, &crop) < 0) {
|
||||||
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_G_CROP failed");
|
GST_WARNING_OBJECT (v4l2sink, "VIDIOC_G_CROP failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,10 @@
|
||||||
* ]| This pipeline shows the video captured from a webcam that delivers jpeg
|
* ]| This pipeline shows the video captured from a webcam that delivers jpeg
|
||||||
* images.
|
* images.
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
|
*
|
||||||
|
* Since 1.14, the use of libv4l2 has been disabled due to major bugs in the
|
||||||
|
* emulation layer. To enable usage of this library, set the environment
|
||||||
|
* variable GST_V4L2_USE_LIBV4L2=1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
|
|
@ -311,7 +311,7 @@ gst_v4l2_decoder_cmd (GstV4l2Object * v4l2object, guint cmd, guint flags)
|
||||||
|
|
||||||
dcmd.cmd = cmd;
|
dcmd.cmd = cmd;
|
||||||
dcmd.flags = flags;
|
dcmd.flags = flags;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_DECODER_CMD, &dcmd) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_DECODER_CMD, &dcmd) < 0)
|
||||||
goto dcmd_failed;
|
goto dcmd_failed;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -241,7 +241,7 @@ gst_v4l2_encoder_cmd (GstV4l2Object * v4l2object, guint cmd, guint flags)
|
||||||
|
|
||||||
ecmd.cmd = cmd;
|
ecmd.cmd = cmd;
|
||||||
ecmd.flags = flags;
|
ecmd.flags = flags;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_ENCODER_CMD, &ecmd) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_ENCODER_CMD, &ecmd) < 0)
|
||||||
goto ecmd_failed;
|
goto ecmd_failed;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -68,7 +68,8 @@ gst_v4l2_get_capabilities (GstV4l2Object * v4l2object)
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP, &v4l2object->vcap) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP,
|
||||||
|
&v4l2object->vcap) < 0)
|
||||||
goto cap_failed;
|
goto cap_failed;
|
||||||
|
|
||||||
if (v4l2object->vcap.capabilities & V4L2_CAP_DEVICE_CAPS)
|
if (v4l2object->vcap.capabilities & V4L2_CAP_DEVICE_CAPS)
|
||||||
|
@ -147,7 +148,7 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
|
||||||
memset (&input, 0, sizeof (input));
|
memset (&input, 0, sizeof (input));
|
||||||
|
|
||||||
input.index = n;
|
input.index = n;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
|
||||||
if (errno == EINVAL || errno == ENOTTY)
|
if (errno == EINVAL || errno == ENOTTY)
|
||||||
break; /* end of enumeration */
|
break; /* end of enumeration */
|
||||||
else {
|
else {
|
||||||
|
@ -181,7 +182,7 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
|
||||||
channel->flags |= GST_TUNER_CHANNEL_FREQUENCY;
|
channel->flags |= GST_TUNER_CHANNEL_FREQUENCY;
|
||||||
|
|
||||||
vtun.index = input.tuner;
|
vtun.index = input.tuner;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &vtun) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &vtun) < 0) {
|
||||||
GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS,
|
GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS,
|
||||||
(_("Failed to get setting of tuner %d on device '%s'."),
|
(_("Failed to get setting of tuner %d on device '%s'."),
|
||||||
input.tuner, v4l2object->videodev), GST_ERROR_SYSTEM);
|
input.tuner, v4l2object->videodev), GST_ERROR_SYSTEM);
|
||||||
|
@ -222,7 +223,7 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
|
||||||
standard.frameperiod.denominator = 0;
|
standard.frameperiod.denominator = 0;
|
||||||
standard.index = n;
|
standard.index = n;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_ENUMSTD, &standard) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_ENUMSTD, &standard) < 0) {
|
||||||
if (errno == EINVAL || errno == ENOTTY)
|
if (errno == EINVAL || errno == ENOTTY)
|
||||||
break; /* end of enumeration */
|
break; /* end of enumeration */
|
||||||
#ifdef ENODATA
|
#ifdef ENODATA
|
||||||
|
@ -280,7 +281,8 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
|
||||||
GST_DEBUG_OBJECT (e, "checking control %08x", n);
|
GST_DEBUG_OBJECT (e, "checking control %08x", n);
|
||||||
|
|
||||||
control.id = n | next;
|
control.id = n | next;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYCTRL, &control) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_QUERYCTRL,
|
||||||
|
&control) < 0) {
|
||||||
if (next) {
|
if (next) {
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
GST_DEBUG_OBJECT (e, "controls finished");
|
GST_DEBUG_OBJECT (e, "controls finished");
|
||||||
|
@ -405,7 +407,8 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
|
||||||
menu.id = n;
|
menu.id = n;
|
||||||
for (i = 0;; i++) {
|
for (i = 0;; i++) {
|
||||||
menu.index = i;
|
menu.index = i;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYMENU, &menu) < 0) {
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_QUERYMENU,
|
||||||
|
&menu) < 0) {
|
||||||
if (errno == EINVAL)
|
if (errno == EINVAL)
|
||||||
break; /* end of enumeration */
|
break; /* end of enumeration */
|
||||||
else {
|
else {
|
||||||
|
@ -515,7 +518,7 @@ gboolean
|
||||||
gst_v4l2_open (GstV4l2Object * v4l2object)
|
gst_v4l2_open (GstV4l2Object * v4l2object)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int libv4l2_fd;
|
int libv4l2_fd = -1;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s",
|
GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s",
|
||||||
v4l2object->videodev);
|
v4l2object->videodev);
|
||||||
|
@ -541,8 +544,12 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
goto not_open;
|
goto not_open;
|
||||||
|
|
||||||
libv4l2_fd = v4l2_fd_open (v4l2object->video_fd,
|
#ifdef HAVE_LIBV4L2
|
||||||
V4L2_ENABLE_ENUM_FMT_EMULATION);
|
if (v4l2object->fd_open)
|
||||||
|
libv4l2_fd = v4l2object->fd_open (v4l2object->video_fd,
|
||||||
|
V4L2_ENABLE_ENUM_FMT_EMULATION);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Note the v4l2_xxx functions are designed so that if they get passed an
|
/* Note the v4l2_xxx functions are designed so that if they get passed an
|
||||||
unknown fd, the will behave exactly as their regular xxx counterparts, so
|
unknown fd, the will behave exactly as their regular xxx counterparts, so
|
||||||
if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom
|
if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom
|
||||||
|
@ -651,7 +658,7 @@ error:
|
||||||
{
|
{
|
||||||
if (GST_V4L2_IS_OPEN (v4l2object)) {
|
if (GST_V4L2_IS_OPEN (v4l2object)) {
|
||||||
/* close device */
|
/* close device */
|
||||||
v4l2_close (v4l2object->video_fd);
|
v4l2object->close (v4l2object->video_fd);
|
||||||
v4l2object->video_fd = -1;
|
v4l2object->video_fd = -1;
|
||||||
}
|
}
|
||||||
/* empty lists */
|
/* empty lists */
|
||||||
|
@ -676,7 +683,7 @@ gst_v4l2_dup (GstV4l2Object * v4l2object, GstV4l2Object * other)
|
||||||
v4l2object->device_caps = other->device_caps;
|
v4l2object->device_caps = other->device_caps;
|
||||||
gst_v4l2_adjust_buf_type (v4l2object);
|
gst_v4l2_adjust_buf_type (v4l2object);
|
||||||
|
|
||||||
v4l2object->video_fd = v4l2_dup (other->video_fd);
|
v4l2object->video_fd = v4l2object->dup (other->video_fd);
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
goto not_open;
|
goto not_open;
|
||||||
|
|
||||||
|
@ -717,7 +724,7 @@ gst_v4l2_close (GstV4l2Object * v4l2object)
|
||||||
GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
|
GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
|
||||||
|
|
||||||
/* close device */
|
/* close device */
|
||||||
v4l2_close (v4l2object->video_fd);
|
v4l2object->close (v4l2object->video_fd);
|
||||||
v4l2object->video_fd = -1;
|
v4l2object->video_fd = -1;
|
||||||
|
|
||||||
/* empty lists */
|
/* empty lists */
|
||||||
|
@ -740,7 +747,7 @@ gst_v4l2_get_norm (GstV4l2Object * v4l2object, v4l2_std_id * norm)
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_STD, norm) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_STD, norm) < 0)
|
||||||
goto std_failed;
|
goto std_failed;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -769,7 +776,7 @@ gst_v4l2_set_norm (GstV4l2Object * v4l2object, v4l2_std_id norm)
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_STD, &norm) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_STD, &norm) < 0)
|
||||||
goto std_failed;
|
goto std_failed;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -805,7 +812,7 @@ gst_v4l2_get_frequency (GstV4l2Object * v4l2object,
|
||||||
channel = gst_tuner_get_channel (GST_TUNER (v4l2object->element));
|
channel = gst_tuner_get_channel (GST_TUNER (v4l2object->element));
|
||||||
|
|
||||||
freq.tuner = tunernum;
|
freq.tuner = tunernum;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_FREQUENCY, &freq) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_FREQUENCY, &freq) < 0)
|
||||||
goto freq_failed;
|
goto freq_failed;
|
||||||
|
|
||||||
*frequency = freq.frequency * channel->freq_multiplicator;
|
*frequency = freq.frequency * channel->freq_multiplicator;
|
||||||
|
@ -846,10 +853,10 @@ gst_v4l2_set_frequency (GstV4l2Object * v4l2object,
|
||||||
|
|
||||||
freq.tuner = tunernum;
|
freq.tuner = tunernum;
|
||||||
/* fill in type - ignore error */
|
/* fill in type - ignore error */
|
||||||
(void) v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_FREQUENCY, &freq);
|
(void) v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_FREQUENCY, &freq);
|
||||||
freq.frequency = frequency / channel->freq_multiplicator;
|
freq.frequency = frequency / channel->freq_multiplicator;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_FREQUENCY, &freq) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_FREQUENCY, &freq) < 0)
|
||||||
goto freq_failed;
|
goto freq_failed;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -881,7 +888,7 @@ gst_v4l2_signal_strength (GstV4l2Object * v4l2object,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
tuner.index = tunernum;
|
tuner.index = tunernum;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &tuner) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &tuner) < 0)
|
||||||
goto tuner_failed;
|
goto tuner_failed;
|
||||||
|
|
||||||
*signal_strength = tuner.signal;
|
*signal_strength = tuner.signal;
|
||||||
|
@ -917,7 +924,7 @@ gst_v4l2_get_attribute (GstV4l2Object * v4l2object,
|
||||||
|
|
||||||
control.id = attribute_num;
|
control.id = attribute_num;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0)
|
||||||
goto ctrl_failed;
|
goto ctrl_failed;
|
||||||
|
|
||||||
*value = control.value;
|
*value = control.value;
|
||||||
|
@ -954,7 +961,7 @@ gst_v4l2_set_attribute (GstV4l2Object * v4l2object,
|
||||||
|
|
||||||
control.id = attribute_num;
|
control.id = attribute_num;
|
||||||
control.value = value;
|
control.value = value;
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0)
|
||||||
goto ctrl_failed;
|
goto ctrl_failed;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1027,7 +1034,7 @@ gst_v4l2_get_input (GstV4l2Object * v4l2object, gint * input)
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_INPUT, &n) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_INPUT, &n) < 0)
|
||||||
goto input_failed;
|
goto input_failed;
|
||||||
|
|
||||||
*input = n;
|
*input = n;
|
||||||
|
@ -1056,7 +1063,7 @@ gst_v4l2_set_input (GstV4l2Object * v4l2object, gint input)
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_INPUT, &input) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_INPUT, &input) < 0)
|
||||||
goto input_failed;
|
goto input_failed;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1084,7 +1091,7 @@ gst_v4l2_get_output (GstV4l2Object * v4l2object, gint * output)
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_OUTPUT, &n) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_OUTPUT, &n) < 0)
|
||||||
goto output_failed;
|
goto output_failed;
|
||||||
|
|
||||||
*output = n;
|
*output = n;
|
||||||
|
@ -1113,7 +1120,7 @@ gst_v4l2_set_output (GstV4l2Object * v4l2object, gint output)
|
||||||
if (!GST_V4L2_IS_OPEN (v4l2object))
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_OUTPUT, &output) < 0)
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_OUTPUT, &output) < 0)
|
||||||
goto output_failed;
|
goto output_failed;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in a new issue