> > + > > +int vpu_v4l2_open(struct file *file, struct vpu_inst *inst) > > +{ > > + struct vpu_dev *vpu = video_drvdata(file); > > + struct vpu_func *func; > > + int ret = 0; > > + > > + WARN_ON(!file || !inst || !inst->ops); > > + > > + if (inst->type == VPU_CORE_TYPE_ENC) > > + func = &vpu->encoder; > > + else > > + func = &vpu->decoder; > > + > > + atomic_set(&inst->ref_count, 0); > > + vpu_inst_get(inst); > > + inst->vpu = vpu; > > + inst->core = vpu_request_core(vpu, inst->type); > > + if (inst->core) > > + inst->dev = get_device(inst->core->dev); > > + mutex_init(&inst->lock); > > + INIT_LIST_HEAD(&inst->cmd_q); > > + inst->id = VPU_INST_NULL_ID; > > + inst->release = vpu_v4l2_release; > > + inst->pid = current->pid; > > + inst->tgid = current->tgid; > > + inst->min_buffer_cap = 2; > > + inst->min_buffer_out = 2; > > Assuming this means the minimum number of buffers needed, why is > min_buffers_needed set to 1 when initializing the vb2_queue structs? In my opinion, the min_buffers_needed determine when vb2_start_streaming will be called, Like the following code: if (q->queued_count >= q->min_buffers_needed) { ... ... ret = vb2_start_streaming(q); ... ... } I hope driver starts a vpu instance when 1 frame is queued, so I set the min_buffers_needed to 1. And the min_buffer_cap means the minimum vb2 buffer count, and it will changed according to the stream, I just set default value to 2, it will be changed after vpu parsed the stream info. > > > + v4l2_fh_init(&inst->fh, func->vfd); > > + v4l2_fh_add(&inst->fh); > > + > > + ret = call_vop(inst, ctrl_init); > > + if (ret) > > + goto error; > > + > > + inst->fh.m2m_ctx = v4l2_m2m_ctx_init(func->m2m_dev, > > + inst, vpu_m2m_queue_init); > > + if (IS_ERR(inst->fh.m2m_ctx)) { > > + dev_err(vpu->dev, "v4l2_m2m_ctx_init fail\n"); > > + ret = PTR_ERR(func->m2m_dev); > > + goto error; > > + } > > + > > + inst->fh.ctrl_handler = &inst->ctrl_handler; > > + file->private_data = &inst->fh; > > + inst->state = VPU_CODEC_STATE_DEINIT; > > + inst->workqueue = alloc_workqueue("vpu_inst", WQ_UNBOUND | > WQ_MEM_RECLAIM, 1); > > + if (inst->workqueue) { > > + INIT_WORK(&inst->msg_work, vpu_inst_run_work); > > + ret = kfifo_init(&inst->msg_fifo, > > + inst->msg_buffer, > > + > roundup_pow_of_two(sizeof(inst->msg_buffer))); > > + if (ret) { > > + destroy_workqueue(inst->workqueue); > > + inst->workqueue = NULL; > > + } > > + } > > + vpu_trace(vpu->dev, "tgid = %d, pid = %d, type = %s, inst = %p\n", > > + inst->tgid, inst->pid, > vpu_core_type_desc(inst->type), inst); > > + > > + return 0; > > +error: > > + vpu_inst_put(inst); > > + return ret; > > +} > > +