Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8fd369ba authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Add window based bitrate check in decoder"

parents e8df88c3 15f3510a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2387,7 +2387,7 @@ static int venus_hfi_session_init(void *device, void *session_id,
	s->device = dev;
	s->codec = codec_type;
	s->domain = session_type;
	dprintk(VIDC_HIGH,
	dprintk(VIDC_HIGH|VIDC_PERF,
		"%s: inst %pK, session %pK, codec 0x%x, domain 0x%x\n",
		__func__, session_id, s, s->codec, s->domain);

+8 −6
Original line number Diff line number Diff line
@@ -158,7 +158,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					(struct hfi_frame_size *) data_ptr;
				event_notify.width = frame_sz->width;
				event_notify.height = frame_sz->height;
				dprintk(VIDC_HIGH, "height: %d width: %d\n",
				dprintk(VIDC_HIGH|VIDC_PERF,
					"height: %d width: %d\n",
					frame_sz->height, frame_sz->width);
				data_ptr +=
					sizeof(struct hfi_frame_size);
@@ -173,7 +174,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					(struct hfi_profile_level *) data_ptr;
				event_notify.profile = profile_level->profile;
				event_notify.level = profile_level->level;
				dprintk(VIDC_HIGH, "profile: %d level: %d\n",
				dprintk(VIDC_HIGH|VIDC_PERF,
					"profile: %d level: %d\n",
					profile_level->profile,
					profile_level->level);
				data_ptr +=
@@ -209,7 +211,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
						MSM_VIDC_BIT_DEPTH_10;
				else
					event_notify.bit_depth = luma_bit_depth;
				dprintk(VIDC_HIGH,
				dprintk(VIDC_HIGH|VIDC_PERF,
					"bitdepth(%d), luma_bit_depth(%d), chroma_bit_depth(%d)\n",
					event_notify.bit_depth, luma_bit_depth,
					chroma_bit_depth);
@@ -224,7 +226,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
				pic_struct = (struct hfi_pic_struct *) data_ptr;
				event_notify.pic_struct =
					pic_struct->progressive_only;
				dprintk(VIDC_HIGH,
				dprintk(VIDC_HIGH|VIDC_PERF,
					"Progressive only flag: %d\n",
						pic_struct->progressive_only);
				data_ptr +=
@@ -253,7 +255,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
				data_ptr = data_ptr + sizeof(u32);
				entropy_mode = *(u32 *)data_ptr;
				event_notify.entropy_mode = entropy_mode;
				dprintk(VIDC_HIGH,
				dprintk(VIDC_HIGH|VIDC_PERF,
					"Entropy Mode: 0x%x\n", entropy_mode);
				data_ptr +=
					sizeof(u32);
@@ -269,7 +271,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
						data_ptr;
				event_notify.capture_buf_count =
					buf_req->buffer_count_min;
				dprintk(VIDC_HIGH,
				dprintk(VIDC_HIGH|VIDC_PERF,
					"Capture Count : 0x%x\n",
						event_notify.capture_buf_count);
				data_ptr +=
+6 −1
Original line number Diff line number Diff line
@@ -920,7 +920,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
	 */
	if (inst->batch.enable)
		inst->batch.enable = is_batching_allowed(inst);
	dprintk(VIDC_HIGH, "%s: batching %s for inst %pK (%#x)\n",
	dprintk(VIDC_HIGH|VIDC_PERF, "%s: batching %s for inst %pK (%#x)\n",
		__func__, inst->batch.enable ? "enabled" : "disabled",
		inst, hash32_ptr(inst->session));

@@ -1524,6 +1524,7 @@ void *msm_vidc_open(int core_id, int session_type)
	INIT_MSM_VIDC_LIST(&inst->eosbufs);
	INIT_MSM_VIDC_LIST(&inst->etb_data);
	INIT_MSM_VIDC_LIST(&inst->fbd_data);
	INIT_MSM_VIDC_LIST(&inst->window_data);

	INIT_DELAYED_WORK(&inst->batch_work, msm_vidc_batch_handler);
	kref_init(&inst->kref);
@@ -1638,6 +1639,7 @@ void *msm_vidc_open(int core_id, int session_type)
	DEINIT_MSM_VIDC_LIST(&inst->input_crs);
	DEINIT_MSM_VIDC_LIST(&inst->etb_data);
	DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
	DEINIT_MSM_VIDC_LIST(&inst->window_data);

	kfree(inst);
	inst = NULL;
@@ -1709,6 +1711,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
		dprintk(VIDC_ERR,
			"Failed to release mark_data buffers\n");

	msm_comm_release_window_data(inst);

	msm_comm_release_eos_buffers(inst);

	if (msm_comm_release_dpb_only_buffers(inst, true))
@@ -1769,6 +1773,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
	DEINIT_MSM_VIDC_LIST(&inst->input_crs);
	DEINIT_MSM_VIDC_LIST(&inst->etb_data);
	DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
	DEINIT_MSM_VIDC_LIST(&inst->window_data);

	mutex_destroy(&inst->sync_lock);
	mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
+2 −1
Original line number Diff line number Diff line
@@ -1780,7 +1780,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id)
		out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt;
		inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt;
		dprintk(VIDC_PERF,
			"inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s %lu\n",
			"inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %u %s %s %lu\n",
			inst,
			inp_f->fmt.pix_mp.width,
			inp_f->fmt.pix_mp.height,
@@ -1790,6 +1790,7 @@ void msm_print_core_status(struct msm_vidc_core *core, u32 core_id)
			inst->session_type == MSM_VIDC_ENCODER ? "ENC" : "DEC",
			inst->clk_data.work_mode == HFI_WORKMODE_1 ?
				"WORK_MODE_1" : "WORK_MODE_2",
			inst->clk_data.work_route,
			inst->flags & VIDC_LOW_POWER ? "LP" : "HQ",
			inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime",
			inst->clk_data.min_freq);
+95 −5
Original line number Diff line number Diff line
@@ -1729,6 +1729,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data)

	inst->profile = event_notify->profile;
	inst->level = event_notify->level;
	inst->entropy_mode = event_notify->entropy_mode;
	inst->prop.crop_info.left =
		event_notify->crop_data.left;
	inst->prop.crop_info.top =
@@ -1795,7 +1796,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
		/* decide batching as configuration changed */
		if (inst->batch.enable)
			inst->batch.enable = is_batching_allowed(inst);
		dprintk(VIDC_HIGH, "%s: %x : batching %s\n",
		dprintk(VIDC_HIGH|VIDC_PERF, "%s: %x : batching %s\n",
			__func__, hash32_ptr(inst->session),
			inst->batch.enable ? "enabled" : "disabled");

@@ -2095,6 +2096,9 @@ static void handle_session_flush(enum hal_command_response cmd, void *data)
		goto exit;
	}

	if (flush_type == HAL_FLUSH_ALL)
		msm_comm_release_window_data(inst);

	dprintk(VIDC_HIGH,
		"Notify flush complete, flush_type: %x\n", flush_type);
	v4l2_event_queue_fh(&inst->event_handler, &flush_event);
@@ -4306,6 +4310,10 @@ static int msm_comm_qbuf_to_hfi(struct msm_vidc_inst *inst,
	mbuf->flags |= MSM_VIDC_FLAG_QUEUED;
	msm_vidc_debugfs_update(inst, e);

	if (mbuf->vvb.vb2_buf.type == INPUT_MPLANE &&
			is_decode_session(inst))
		rc = msm_comm_check_window_bitrate(inst, &frame_data);

err_bad_input:
	return rc;
}
@@ -4450,7 +4458,7 @@ static int msm_comm_qbuf_in_rbr(struct msm_vidc_inst *inst,
	if (rc)
		dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);

	print_vidc_buffer(VIDC_HIGH, "qbuf in rbr", inst, mbuf);
	print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf in rbr", inst, mbuf);
	rc = msm_comm_qbuf_to_hfi(inst, mbuf);
	if (rc)
		dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n", __func__, rc);
@@ -4487,7 +4495,7 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
	if (rc)
		dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);

	print_vidc_buffer(VIDC_HIGH, "qbuf", inst, mbuf);
	print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "qbuf", inst, mbuf);
	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME);
	if (ctrl->val)
		rc = msm_comm_qbuf_superframe_to_hfi(inst, mbuf);
@@ -4572,7 +4580,7 @@ int msm_comm_qbufs_batch(struct msm_vidc_inst *inst,
		if (buf->flags & MSM_VIDC_FLAG_RBR_PENDING)
			goto loop_end;

		print_vidc_buffer(VIDC_HIGH, "batch-qbuf", inst, buf);
		print_vidc_buffer(VIDC_HIGH|VIDC_PERF, "batch-qbuf", inst, buf);
		rc = msm_comm_qbuf_to_hfi(inst, buf);
		if (rc) {
			dprintk(VIDC_ERR, "%s: Failed batch qbuf to hfi: %d\n",
@@ -4614,7 +4622,8 @@ int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst,

	if (inst->state != MSM_VIDC_START_DONE) {
		mbuf->flags |= MSM_VIDC_FLAG_DEFERRED;
		print_vidc_buffer(VIDC_HIGH, "qbuf deferred", inst, mbuf);
		print_vidc_buffer(VIDC_HIGH|VIDC_PERF,
					"qbuf deferred", inst, mbuf);
		return 0;
	}

@@ -6170,6 +6179,10 @@ void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst,
{
	if (!(tag & msm_vidc_debug) || !inst || !vb2)
		return;
	if ((tag & VIDC_PERF) &&
		!(tag & VIDC_HIGH) &&
		(inst->session_type != MSM_VIDC_DECODER))
		return;

	if (vb2->num_planes == 1)
		dprintk(tag,
@@ -7195,3 +7208,80 @@ bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core)
	}
	return overload;
}

int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst,
	struct vidc_frame_data *frame_data)
{
	struct msm_vidc_window_data *pdata, *next;
	u32 bitrate, max_br, window_size;
	int buf_cnt = 1, fps, window_start;

	if (!inst || !inst->core || !frame_data) {
		dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
		return -EINVAL;
	}

	if (!inst->core->resources.avsync_window_size)
		return 0;

	fps = inst->clk_data.frame_rate >> 16;
	max_br = MAX_BITRATE_DECODER_CAVLC;
	if (inst->entropy_mode == HFI_H264_ENTROPY_CABAC)
		max_br = inst->clk_data.work_mode == HFI_WORKMODE_2 ?
			MAX_BITRATE_DECODER_2STAGE_CABAC :
			MAX_BITRATE_DECODER_1STAGE_CABAC;
	window_size = inst->core->resources.avsync_window_size * fps;
	window_size = DIV_ROUND_UP(window_size, 1000);

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata)  {
		dprintk(VIDC_ERR, "%s: malloc failure.\n", __func__);
		return -ENOMEM;
	}

	bitrate = pdata->frame_size = frame_data->filled_len;
	window_start = pdata->etb_count = inst->count.etb;

	mutex_lock(&inst->window_data.lock);
	list_add(&pdata->list, &inst->window_data.list);
	list_for_each_entry_safe_continue(pdata, next,
			&inst->window_data.list, list) {
		if (buf_cnt < window_size) {
			bitrate += pdata->frame_size;
			window_start = pdata->etb_count;
			buf_cnt++;
		} else {
			list_del(&pdata->list);
			kfree(pdata);
		}
	}
	mutex_unlock(&inst->window_data.lock);

	bitrate = DIV_ROUND_UP(((u64)bitrate * 8 * fps), window_size);
	if (bitrate > max_br) {
		dprintk(VIDC_PERF,
			"Unsupported bitrate %u max %u, window size %u [%u,%u]",
			bitrate, max_br, window_size,
			window_start, inst->count.etb);
	}

	return 0;
}

void msm_comm_release_window_data(struct msm_vidc_inst *inst)
{
	struct msm_vidc_window_data *pdata, *next;

	if (!inst) {
		dprintk(VIDC_ERR, "%s: invalid params %pK\n",
			__func__, inst);
		return;
	}

	mutex_lock(&inst->window_data.lock);
	list_for_each_entry_safe(pdata, next, &inst->window_data.list, list) {
		list_del(&pdata->list);
		kfree(pdata);
	}
	mutex_unlock(&inst->window_data.lock);
}
Loading