*参照元 [#la25221b]
#backlinks

*説明 [#j280d8ea]
-パス: [[linux-4.4.1/drivers/media/v4l2-core/videobuf2-core.c]]

-FIXME: これは何?
--説明


**引数 [#tfd92376]
-struct vb2_queue *q
--
--[[linux-4.4.1/vb2_queue]]
-enum vb2_memory memory
--
--[[linux-4.4.1/vb2_memory]]
-unsigned int *count
--


**返り値 [#t0fef9e1]
-int
--


**参考 [#u5d4bbee]


*実装 [#v1cad5b5]
 /**
  * vb2_core_reqbufs() - Initiate streaming
  * @q:          videobuf2 queue
  * @memory: memory type
  * @count: requested buffer count
  *
  * Should be called from vidioc_reqbufs ioctl handler of a driver.
  * This function:
  * 1) verifies streaming parameters passed from the userspace,
  * 2) sets up the queue,
  * 3) negotiates number of buffers and planes per buffer with the driver
  *    to be used during streaming,
  * 4) allocates internal buffer structures (struct vb2_buffer), according to
  *    the agreed parameters,
  * 5) for MMAP memory type, allocates actual video memory, using the
  *    memory handling/allocation routines provided during queue initialization
  *
  * If req->count is 0, all the memory will be freed instead.
  * If the queue has been allocated previously (by a previous vb2_reqbufs) call
  * and the queue is not busy, memory will be reallocated.
  *
  * The return values from this function are intended to be directly returned
  * from vidioc_reqbufs handler in driver.
  */
 int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
                 unsigned int *count)
 {
         unsigned int num_buffers, allocated_buffers, num_planes = 0;
         int ret;
 
         if (q->streaming) {
                 dprintk(1, "streaming active\n");
                 return -EBUSY;
         }
 
-
--[[linux-4.4.1/dprintk()]]

         if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
                 /*
                  * We already have buffers allocated, so first check if they
                  * are not in use and can be freed.
                  */
                 mutex_lock(&q->mmap_lock);
                 if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) {
                         mutex_unlock(&q->mmap_lock);
                         dprintk(1, "memory in use, cannot free\n");
                         return -EBUSY;
                 }
 
-
--[[linux-4.4.1/mutex_lock()]]
--[[linux-4.4.1/__buffers_in_use()]]
--[[linux-4.4.1/mutex_unlock()]]

                 /*
                  * Call queue_cancel to clean up any buffers in the PREPARED or
                  * QUEUED state which is possible if buffers were prepared or
                  * queued without ever calling STREAMON.
                  */
                 __vb2_queue_cancel(q);
                 ret = __vb2_queue_free(q, q->num_buffers);
                 mutex_unlock(&q->mmap_lock);
                 if (ret)
                         return ret;
 
-
--[[linux-4.4.1/__vb2_queue_cancel()]]
--[[linux-4.4.1/__vb2_queue_free()]]

                 /*
                  * In case of REQBUFS(0) return immediately without calling
                  * driver's queue_setup() callback and allocating resources.
                  */
                 if (*count == 0)
                         return 0;
         }
 
         /*
          * Make sure the requested values and current defaults are sane.
          */
         num_buffers = min_t(unsigned int, *count, VB2_MAX_FRAME);
         num_buffers = max_t(unsigned int, num_buffers, q->min_buffers_needed);
         memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
         memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
         q->memory = memory;
 
-
--[[linux-4.4.1/min_t()]]
--[[linux-4.4.1/max_t()]]
--[[linux-4.4.1/memset()]]

         /*
          * Ask the driver how many buffers and planes per buffer it requires.
          * Driver also sets the size and allocator context for each plane.
          */
         ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes,
                        q->plane_sizes, q->alloc_ctx);
         if (ret)
                 return ret;
 
-
--q->ops->queue_setup を呼び出す。
---q->ops は const struct vb2_ops * 型
---[[linux-4.4.1/vb2_ops]]
--[[linux-4.4.1/call_qop()]]

         /* Finally, allocate buffers and video memory */
         allocated_buffers =
                 __vb2_queue_alloc(q, memory, num_buffers, num_planes);
         if (allocated_buffers == 0) {
                 dprintk(1, "memory allocation failed\n");
                 return -ENOMEM;
         }
 
-
--[[linux-4.4.1/__vb2_queue_alloc()]]

         /*
          * There is no point in continuing if we can't allocate the minimum
          * number of buffers needed by this vb2_queue.
          */
         if (allocated_buffers < q->min_buffers_needed)
                 ret = -ENOMEM;
 
         /*
          * Check if driver can handle the allocated number of buffers.
          */
         if (!ret && allocated_buffers < num_buffers) {
                 num_buffers = allocated_buffers;
 
                 ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
                                &num_planes, q->plane_sizes, q->alloc_ctx);
 
-
--q->ops->queue_setup を呼び出す。
---q->ops は const struct vb2_ops * 型
---[[linux-4.4.1/vb2_ops]]
--[[linux-4.4.1/call_qop()]]

                 if (!ret && allocated_buffers < num_buffers)
                         ret = -ENOMEM;
 
                 /*
                  * Either the driver has accepted a smaller number of buffers,
                  * or .queue_setup() returned an error
                  */
         }
 
         mutex_lock(&q->mmap_lock);
         q->num_buffers = allocated_buffers;
 
         if (ret < 0) {
                 /*
                  * Note: __vb2_queue_free() will subtract 'allocated_buffers'
                  * from q->num_buffers.
                  */
                 __vb2_queue_free(q, allocated_buffers);
                 mutex_unlock(&q->mmap_lock);
                 return ret;
         }
         mutex_unlock(&q->mmap_lock);
 
-
--[[linux-4.4.1/__vb2_queue_free()]]

         /*
          * Return the number of successfully allocated buffers
          * to the userspace.
          */
         *count = allocated_buffers;
         q->waiting_for_buffers = !q->is_output;
 
         return 0;
 }
 EXPORT_SYMBOL_GPL(vb2_core_reqbufs);
-
--[[linux-4.4.1/EXPORT_SYMBOL_GPL()]]


*コメント [#c9ad2e89]


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS