diff options
Diffstat (limited to 'drivers/media/platform/qcom/venus/venc.c')
| -rw-r--r-- | drivers/media/platform/qcom/venus/venc.c | 132 |
1 files changed, 69 insertions, 63 deletions
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 6d773b000e8a..b478b982a80d 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -241,8 +241,6 @@ static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) struct vb2_queue *q; q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); - if (!q) - return -EINVAL; if (vb2_is_busy(q)) return -EBUSY; @@ -411,11 +409,9 @@ static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; do_div(us_per_frame, timeperframe->denominator); - if (!us_per_frame) - return -EINVAL; - - fps = (u64)USEC_PER_SEC; - do_div(fps, us_per_frame); + us_per_frame = clamp(us_per_frame, 1, USEC_PER_SEC); + fps = USEC_PER_SEC / (u32)us_per_frame; + fps = min(VENUS_MAX_FPS, fps); inst->timeperframe = *timeperframe; inst->fps = fps; @@ -734,6 +730,29 @@ static int venc_set_properties(struct venus_inst *inst) if (ret) return ret; + if (ctr->layer_bitrate) { + unsigned int i; + + ptype = HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER; + ret = hfi_session_set_property(inst, ptype, &ctr->h264_hier_layers); + if (ret) + return ret; + + ptype = HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER; + ret = hfi_session_set_property(inst, ptype, &ctr->layer_bitrate); + if (ret) + return ret; + + for (i = 0; i < ctr->h264_hier_layers; ++i) { + ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE; + brate.bitrate = ctr->h264_hier_layer_bitrate[i]; + brate.layer_id = i; + + ret = hfi_session_set_property(inst, ptype, &brate); + if (ret) + return ret; + } + } } if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 || @@ -823,18 +842,33 @@ static int venc_set_properties(struct venus_inst *inst) return ret; } - if (!ctr->bitrate) - bitrate = 64000; - else - bitrate = ctr->bitrate; + if (!ctr->layer_bitrate) { + if (!ctr->bitrate) + bitrate = 64000; + else + bitrate = ctr->bitrate; - ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE; - brate.bitrate = bitrate; - brate.layer_id = 0; + ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE; + brate.bitrate = bitrate; + brate.layer_id = 0; - ret = hfi_session_set_property(inst, ptype, &brate); - if (ret) - return ret; + ret = hfi_session_set_property(inst, ptype, &brate); + if (ret) + return ret; + + if (!ctr->bitrate_peak) + bitrate *= 2; + else + bitrate = ctr->bitrate_peak; + + ptype = HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE; + brate.bitrate = bitrate; + brate.layer_id = 0; + + ret = hfi_session_set_property(inst, ptype, &brate); + if (ret) + return ret; + } if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 || inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { @@ -849,19 +883,6 @@ static int venc_set_properties(struct venus_inst *inst) return ret; } - if (!ctr->bitrate_peak) - bitrate *= 2; - else - bitrate = ctr->bitrate_peak; - - ptype = HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE; - brate.bitrate = bitrate; - brate.layer_id = 0; - - ret = hfi_session_set_property(inst, ptype, &brate); - if (ret) - return ret; - ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP; if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { quant.qp_i = ctr->hevc_i_qp; @@ -1207,7 +1228,7 @@ static int venc_verify_conf(struct venus_inst *inst) return ret; if (inst->num_output_bufs < bufreq.count_actual || - inst->num_output_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) + inst->num_output_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) return -EINVAL; ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); @@ -1215,7 +1236,7 @@ static int venc_verify_conf(struct venus_inst *inst) return ret; if (inst->num_input_bufs < bufreq.count_actual || - inst->num_input_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) + inst->num_input_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) return -EINVAL; return 0; @@ -1398,7 +1419,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->drv_priv = inst; src_vq->buf_struct_size = sizeof(struct venus_buffer); src_vq->allow_zero_bytesused = 1; - src_vq->min_buffers_needed = 1; + src_vq->min_queued_buffers = 1; src_vq->dev = inst->core->dev; src_vq->lock = &inst->ctx_q_lock; if (inst->core->res->hfi_version == HFI_VERSION_1XX) @@ -1415,7 +1436,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->drv_priv = inst; dst_vq->buf_struct_size = sizeof(struct venus_buffer); dst_vq->allow_zero_bytesused = 1; - dst_vq->min_buffers_needed = 1; + dst_vq->min_queued_buffers = 1; dst_vq->dev = inst->core->dev; dst_vq->lock = &inst->ctx_q_lock; return vb2_queue_init(dst_vq); @@ -1467,10 +1488,6 @@ static int venc_open(struct file *file) if (ret) goto err_free; - ret = hfi_session_create(inst, &venc_hfi_ops); - if (ret) - goto err_ctrl_deinit; - venc_inst_init(inst); /* @@ -1480,30 +1497,33 @@ static int venc_open(struct file *file) inst->m2m_dev = v4l2_m2m_init(&venc_m2m_ops); if (IS_ERR(inst->m2m_dev)) { ret = PTR_ERR(inst->m2m_dev); - goto err_session_destroy; + goto err_ctrl_deinit; } inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init); if (IS_ERR(inst->m2m_ctx)) { ret = PTR_ERR(inst->m2m_ctx); - goto err_m2m_release; + goto err_m2m_dev_release; } + ret = hfi_session_create(inst, &venc_hfi_ops); + if (ret) + goto err_m2m_ctx_release; + v4l2_fh_init(&inst->fh, core->vdev_enc); inst->fh.ctrl_handler = &inst->ctrl_handler; - v4l2_fh_add(&inst->fh); + v4l2_fh_add(&inst->fh, file); inst->fh.m2m_ctx = inst->m2m_ctx; - file->private_data = &inst->fh; return 0; -err_m2m_release: +err_m2m_ctx_release: + v4l2_m2m_ctx_release(inst->m2m_ctx); +err_m2m_dev_release: v4l2_m2m_release(inst->m2m_dev); -err_session_destroy: - hfi_session_destroy(inst); err_ctrl_deinit: - venc_ctrl_deinit(inst); + v4l2_ctrl_handler_free(&inst->ctrl_handler); err_free: kfree(inst); return ret; @@ -1514,18 +1534,8 @@ static int venc_close(struct file *file) struct venus_inst *inst = to_inst(file); venc_pm_get(inst); - - v4l2_m2m_ctx_release(inst->m2m_ctx); - v4l2_m2m_release(inst->m2m_dev); - venc_ctrl_deinit(inst); - hfi_session_destroy(inst); - mutex_destroy(&inst->lock); - mutex_destroy(&inst->ctx_q_lock); - v4l2_fh_del(&inst->fh); - v4l2_fh_exit(&inst->fh); - + venus_close_common(inst, file); inst->enc_state = VENUS_ENC_STATE_DEINIT; - venc_pm_put(inst, false); kfree(inst); @@ -1548,12 +1558,9 @@ static int venc_probe(struct platform_device *pdev) struct venus_core *core; int ret; - if (!dev->parent) - return -EPROBE_DEFER; - core = dev_get_drvdata(dev->parent); if (!core) - return -EPROBE_DEFER; + return -EINVAL; platform_set_drvdata(pdev, core); @@ -1643,7 +1650,7 @@ MODULE_DEVICE_TABLE(of, venc_dt_match); static struct platform_driver qcom_venus_enc_driver = { .probe = venc_probe, - .remove_new = venc_remove, + .remove = venc_remove, .driver = { .name = "qcom-venus-encoder", .of_match_table = venc_dt_match, @@ -1652,6 +1659,5 @@ static struct platform_driver qcom_venus_enc_driver = { }; module_platform_driver(qcom_venus_enc_driver); -MODULE_ALIAS("platform:qcom-venus-encoder"); MODULE_DESCRIPTION("Qualcomm Venus video encoder driver"); MODULE_LICENSE("GPL v2"); |
