直接貼代碼,
907 void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
908 {
909 › struct vb2_queue *q = vb->vb2_queue;
910 › unsigned long flags;
911 › unsigned int plane;
912
913 › if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE))
914 › › return;
915
916 › if (WARN_ON(state != VB2_BUF_STATE_DONE &&
917 › › state != VB2_BUF_STATE_ERROR &&
918 › › state != VB2_BUF_STATE_QUEUED &&
919 › › state != VB2_BUF_STATE_REQUEUEING))
920 › › state = VB2_BUF_STATE_ERROR;
921
922 #ifdef CONFIG_VIDEO_ADV_DEBUG
923 › /*
924 › * Although this is not a callback, it still does have to balance
925 › * with the buf_queue op. So update this counter manually.
926 › */
927 › vb->cnt_buf_done++;
928 #endif
929 › dprintk(4, "done processing on buffer %d, state: %d\n", 930 › › › vb->index, state);
931
932 › if (state != VB2_BUF_STATE_QUEUED &&
933 › state != VB2_BUF_STATE_REQUEUEING) {
934 › › /* sync buffers */
935 › › for (plane = 0; plane < vb->num_planes; ++plane)
936 › › › call_void_memop(vb, finish, vb->planes[plane].mem_priv);
937 › › vb->synced = false;
938 › }
939
940 › spin_lock_irqsave(&q->done_lock, flags);
941 › if (state == VB2_BUF_STATE_QUEUED ||
942 › state == VB2_BUF_STATE_REQUEUEING) {
943 › › vb->state = VB2_BUF_STATE_QUEUED;
944 › } else {
945 › › /* Add the buffer to the done buffers list */
946 › › list_add_tail(&vb->done_entry, &q->done_list);
947 › › vb->state = state;
948 › }
949 › atomic_dec(&q->owned_by_drv_count);
950
951 › if (state != VB2_BUF_STATE_QUEUED && vb->req_obj.req) {
952 › › /* This is not supported at the moment */
953 › › WARN_ON(state == VB2_BUF_STATE_REQUEUEING);
954 › › media_request_object_unbind(&vb->req_obj);
955 › › media_request_object_put(&vb->req_obj);
956 › }
957
958 › spin_unlock_irqrestore(&q->done_lock, flags);
959
960 › trace_vb2_buf_done(q, vb);
961
962 › switch (state) {
963 › case VB2_BUF_STATE_QUEUED:
964 › › return;
965 › case VB2_BUF_STATE_REQUEUEING:
966 › › if (q->start_streaming_called)
967 › › › __enqueue_in_driver(vb);
968 › › return;
969 › default:
970 › › /* Inform any processes that may be waiting for buffers */
971 › › wake_up(&q->done_wq);
972 › › break;
973 › }
974 }
主要幹一件事情, queued_list中的buffer處理後, 需要放到done_list中。
誰來做這個動作。不是v4l2核心層, 而是具體的驅動如vivi, uvc, coda等。
如何放入done_list,
請調用vb2_buffer_done!!
具體細節, 後續研究並添加...