*
*/
+#include <linux/sort.h>
#include <linux/slab.h>
#include <soc/qcom/scm.h>
#include "msm_vidc_internal.h"
#include "vidc_hfi_api.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_dcvs.h"
+#include "msm_vdec.h"
#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
#define MIN_NUM_OUTPUT_BUFFERS 4
(1 << V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC)
),
.qmenu = mpeg_vidc_video_dpb_color_format,
+ .flags = V4L2_CTRL_FLAG_MODIFY_LAYOUT,
},
{
.id = V4L2_CID_VIDC_QBUF_MODE,
dprintk(VIDC_ERR,
"Core %pK in bad state, ignoring prepare buf\n",
inst->core);
- goto exit;
+ return -EINVAL;
}
switch (b->type) {
dprintk(VIDC_ERR, "Buffer type not recognized: %d\n", b->type);
break;
}
-exit:
+
return rc;
}
rc = -EINVAL;
break;
}
+ msm_dcvs_try_enable(inst);
/* Pretend as if FW itself is asking for
* additional buffers.
struct msm_vidc_inst *inst;
int rc = 0;
struct hfi_device *hdev;
+ struct vb2_buffer *vb;
struct vb2_buf_entry *temp, *next;
if (!q || !q->drv_priv) {
dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
return -EINVAL;
}
+
+ if (inst->state == MSM_VIDC_CORE_INVALID ||
+ inst->core->state == VIDC_CORE_INVALID ||
+ inst->core->state == VIDC_CORE_UNINIT) {
+ rc = -EINVAL;
+ goto stream_start_failed;
+ }
+
hdev = inst->core->device;
dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n",
q->type, inst);
break;
default:
dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type);
- rc = -EINVAL;
- goto stream_start_failed;
+ return -EINVAL;
}
if (rc) {
dprintk(VIDC_ERR,
stream_start_failed:
if (rc) {
+ list_for_each_entry(vb, &q->queued_list, queued_entry) {
+ if (vb->type == q->type &&
+ vb->state == VB2_BUF_STATE_ACTIVE)
+ vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED);
+ }
mutex_lock(&inst->pendingq.lock);
- list_for_each_entry_safe(temp, next, &inst->pendingq.list,
- list) {
+ list_for_each_entry_safe(temp, next,
+ &inst->pendingq.list, list) {
if (temp->vb->type == q->type) {
- vb2_buffer_done(temp->vb,
- VB2_BUF_STATE_QUEUED);
list_del(&temp->list);
kfree(temp);
}
struct hal_enable_picture enable_picture;
struct hal_enable hal_property;
enum hal_property property_id = 0;
+ enum hal_video_codec codec;
u32 property_val = 0;
void *pdata = NULL;
struct hfi_device *hdev;
case V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE:
property_id = HAL_PARAM_VDEC_PICTURE_TYPE_DECODE;
if (ctrl->val ==
- V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON)
+ V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON) {
enable_picture.picture_type = HAL_PICTURE_I;
- else
- enable_picture.picture_type = HAL_PICTURE_I |
- HAL_PICTURE_P | HAL_PICTURE_B |
- HAL_PICTURE_IDR;
+ } else {
+ codec = get_hal_codec(inst->fmts[OUTPUT_PORT].fourcc);
+ if (codec == HAL_VIDEO_CODEC_H264) {
+ enable_picture.picture_type = HAL_PICTURE_I |
+ HAL_PICTURE_P | HAL_PICTURE_B |
+ HAL_PICTURE_IDR;
+ } else if (codec == HAL_VIDEO_CODEC_HEVC) {
+ enable_picture.picture_type = HAL_PICTURE_I |
+ HAL_PICTURE_P | HAL_PICTURE_B |
+ HAL_PICTURE_IDR | HAL_PICTURE_CRA;
+ } else {
+ enable_picture.picture_type = HAL_PICTURE_I |
+ HAL_PICTURE_P | HAL_PICTURE_B;
+ }
+ }
pdata = &enable_picture;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO:
return msm_comm_ctrl_init(inst, msm_vdec_ctrls,
ARRAY_SIZE(msm_vdec_ctrls), &msm_vdec_ctrl_ops);
}
+
+void msm_vdec_g_ctrl(struct msm_vidc_ctrl **ctrls, int *num_ctrls)
+{
+ *ctrls = msm_vdec_ctrls;
+ *num_ctrls = NUM_CTRLS;
+}
+
+static int msm_vdec_ctrl_cmp(const void *st1, const void *st2)
+{
+ return (int32_t)((struct msm_vidc_ctrl *)st1)->id -
+ (int32_t)((struct msm_vidc_ctrl *)st2)->id;
+}
+
+void msm_vdec_ctrl_sort(void)
+{
+ sort(msm_vdec_ctrls, NUM_CTRLS, sizeof(struct msm_vidc_ctrl),
+ msm_vdec_ctrl_cmp, NULL);
+}