Skip to content

Commit cef00f3

Browse files
author
Dikshita Agarwal
committed
FROMLIST: media: iris: Add support for buffer management ioctls for encoder device
Implement support for queuing and dequeuing input and output buffers for the encoder video device using the appropriate V4L2 buffer management ioctls. This enables userspace applications to manage streaming buffers required for encoding operations. Link: https://lore.kernel.org/linux-media/[email protected]/ Signed-off-by: Dikshita Agarwal <[email protected]>
1 parent 0dda4c0 commit cef00f3

File tree

12 files changed

+218
-82
lines changed

12 files changed

+218
-82
lines changed

drivers/media/platform/qcom/iris/iris_common.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,43 @@
1010
#include "iris_instance.h"
1111
#include "iris_power.h"
1212

13+
int iris_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf)
14+
{
15+
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
16+
17+
buf->type = iris_v4l2_type_to_driver(vb2->type);
18+
buf->index = vb2->index;
19+
buf->fd = vb2->planes[0].m.fd;
20+
buf->buffer_size = vb2->planes[0].length;
21+
buf->data_offset = vb2->planes[0].data_offset;
22+
buf->data_size = vb2->planes[0].bytesused - vb2->planes[0].data_offset;
23+
buf->flags = vbuf->flags;
24+
buf->timestamp = vb2->timestamp;
25+
do_div(buf->timestamp, NSEC_PER_USEC);
26+
buf->attr = 0;
27+
28+
return 0;
29+
}
30+
31+
void iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
32+
{
33+
u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
34+
struct vb2_buffer *vb = &vbuf->vb2_buf;
35+
u64 ts_us = vb->timestamp;
36+
37+
if (inst->metadata_idx >= ARRAY_SIZE(inst->tss))
38+
inst->metadata_idx = 0;
39+
40+
do_div(ts_us, NSEC_PER_USEC);
41+
42+
inst->tss[inst->metadata_idx].flags = vbuf->flags & mask;
43+
inst->tss[inst->metadata_idx].tc = vbuf->timecode;
44+
inst->tss[inst->metadata_idx].ts_us = ts_us;
45+
inst->tss[inst->metadata_idx].ts_ns = vb->timestamp;
46+
47+
inst->metadata_idx++;
48+
}
49+
1350
int iris_process_streamon_input(struct iris_inst *inst)
1451
{
1552
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;

drivers/media/platform/qcom/iris/iris_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
struct iris_inst;
1010
struct iris_buffer;
1111

12+
int iris_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf);
13+
void iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf);
1214
int iris_process_streamon_input(struct iris_inst *inst);
1315
int iris_process_streamon_output(struct iris_inst *inst);
1416
int iris_session_streamoff(struct iris_inst *inst, u32 plane);

drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -278,23 +278,44 @@ static int iris_hfi_gen1_session_continue(struct iris_inst *inst, u32 plane)
278278

279279
static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct iris_buffer *buf)
280280
{
281-
struct hfi_session_empty_buffer_compressed_pkt ip_pkt;
281+
struct hfi_session_empty_buffer_compressed_pkt com_ip_pkt;
282+
struct hfi_session_empty_buffer_uncompressed_pkt uncom_ip_pkt;
282283

283-
ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt);
284-
ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
285-
ip_pkt.shdr.session_id = inst->session_id;
286-
ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp);
287-
ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp);
288-
ip_pkt.flags = buf->flags;
289-
ip_pkt.mark_target = 0;
290-
ip_pkt.mark_data = 0;
291-
ip_pkt.offset = buf->data_offset;
292-
ip_pkt.alloc_len = buf->buffer_size;
293-
ip_pkt.filled_len = buf->data_size;
294-
ip_pkt.input_tag = buf->index;
295-
ip_pkt.packet_buffer = buf->device_addr;
296-
297-
return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
284+
if (inst->domain == DECODER) {
285+
com_ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt);
286+
com_ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
287+
com_ip_pkt.shdr.session_id = inst->session_id;
288+
com_ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp);
289+
com_ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp);
290+
com_ip_pkt.flags = buf->flags;
291+
com_ip_pkt.mark_target = 0;
292+
com_ip_pkt.mark_data = 0;
293+
com_ip_pkt.offset = buf->data_offset;
294+
com_ip_pkt.alloc_len = buf->buffer_size;
295+
com_ip_pkt.filled_len = buf->data_size;
296+
com_ip_pkt.input_tag = buf->index;
297+
com_ip_pkt.packet_buffer = buf->device_addr;
298+
return iris_hfi_queue_cmd_write(inst->core, &com_ip_pkt,
299+
com_ip_pkt.shdr.hdr.size);
300+
} else {
301+
uncom_ip_pkt.shdr.hdr.size =
302+
sizeof(struct hfi_session_empty_buffer_uncompressed_pkt);
303+
uncom_ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
304+
uncom_ip_pkt.shdr.session_id = inst->session_id;
305+
uncom_ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp);
306+
uncom_ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp);
307+
uncom_ip_pkt.view_id = 0;
308+
uncom_ip_pkt.flags = buf->flags;
309+
uncom_ip_pkt.mark_target = 0;
310+
uncom_ip_pkt.mark_data = 0;
311+
uncom_ip_pkt.offset = buf->data_offset;
312+
uncom_ip_pkt.alloc_len = buf->buffer_size;
313+
uncom_ip_pkt.filled_len = buf->data_size;
314+
uncom_ip_pkt.input_tag = buf->index;
315+
uncom_ip_pkt.packet_buffer = buf->device_addr;
316+
return iris_hfi_queue_cmd_write(inst->core, &uncom_ip_pkt,
317+
uncom_ip_pkt.shdr.hdr.size);
318+
}
298319
}
299320

300321
static int iris_hfi_gen1_queue_output_buffer(struct iris_inst *inst, struct iris_buffer *buf)

drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,23 @@ struct hfi_session_empty_buffer_compressed_pkt {
217217
u32 data;
218218
};
219219

220+
struct hfi_session_empty_buffer_uncompressed_pkt {
221+
struct hfi_session_hdr_pkt shdr;
222+
u32 view_id;
223+
u32 time_stamp_hi;
224+
u32 time_stamp_lo;
225+
u32 flags;
226+
u32 mark_target;
227+
u32 mark_data;
228+
u32 alloc_len;
229+
u32 filled_len;
230+
u32 offset;
231+
u32 input_tag;
232+
u32 packet_buffer;
233+
u32 extradata_buffer;
234+
u32 data;
235+
};
236+
220237
struct hfi_session_fill_buffer_pkt {
221238
struct hfi_session_hdr_pkt shdr;
222239
u32 stream_id;
@@ -462,6 +479,26 @@ struct hfi_msg_session_empty_buffer_done_pkt {
462479
u32 data[];
463480
};
464481

482+
struct hfi_msg_session_fbd_compressed_pkt {
483+
struct hfi_session_hdr_pkt shdr;
484+
u32 time_stamp_hi;
485+
u32 time_stamp_lo;
486+
u32 error_type;
487+
u32 flags;
488+
u32 mark_target;
489+
u32 mark_data;
490+
u32 stats;
491+
u32 offset;
492+
u32 alloc_len;
493+
u32 filled_len;
494+
u32 input_tag;
495+
u32 output_tag;
496+
u32 picture_type;
497+
u32 packet_buffer;
498+
u32 extradata_buffer;
499+
u32 data[];
500+
};
501+
465502
struct hfi_msg_session_fbd_uncompressed_plane0_pkt {
466503
struct hfi_session_hdr_pkt shdr;
467504
u32 stream_id;

drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -387,24 +387,45 @@ static void iris_hfi_gen1_session_etb_done(struct iris_inst *inst, void *packet)
387387

388388
static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
389389
{
390-
struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt = packet;
390+
struct hfi_msg_session_fbd_compressed_pkt *com_pkt;
391+
struct hfi_msg_session_fbd_uncompressed_plane0_pkt *uncom_pkt;
391392
struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
392393
struct v4l2_m2m_buffer *m2m_buffer, *n;
393394
struct hfi_session_flush_pkt flush_pkt;
394-
u32 timestamp_hi = pkt->time_stamp_hi;
395-
u32 timestamp_lo = pkt->time_stamp_lo;
395+
u32 timestamp_hi;
396+
u32 timestamp_lo;
396397
struct iris_core *core = inst->core;
397-
u32 filled_len = pkt->filled_len;
398-
u32 pic_type = pkt->picture_type;
399-
u32 output_tag = pkt->output_tag;
398+
u32 filled_len;
399+
u32 pic_type;
400+
u32 output_tag;
400401
struct iris_buffer *buf, *iter;
401402
struct iris_buffers *buffers;
402-
u32 hfi_flags = pkt->flags;
403-
u32 offset = pkt->offset;
403+
u32 hfi_flags;
404+
u32 offset;
404405
u64 timestamp_us = 0;
405406
bool found = false;
406407
u32 flags = 0;
407408

409+
if (inst->domain == DECODER) {
410+
uncom_pkt = packet;
411+
timestamp_hi = uncom_pkt->time_stamp_hi;
412+
timestamp_lo = uncom_pkt->time_stamp_lo;
413+
filled_len = uncom_pkt->filled_len;
414+
pic_type = uncom_pkt->picture_type;
415+
output_tag = uncom_pkt->output_tag;
416+
hfi_flags = uncom_pkt->flags;
417+
offset = uncom_pkt->offset;
418+
} else {
419+
com_pkt = packet;
420+
timestamp_hi = com_pkt->time_stamp_hi;
421+
timestamp_lo = com_pkt->time_stamp_lo;
422+
filled_len = com_pkt->filled_len;
423+
pic_type = com_pkt->picture_type;
424+
output_tag = com_pkt->output_tag;
425+
hfi_flags = com_pkt->flags;
426+
offset = com_pkt->offset;
427+
}
428+
408429
if ((hfi_flags & HFI_BUFFERFLAG_EOS) && !filled_len) {
409430
reinit_completion(&inst->flush_completion);
410431

@@ -418,7 +439,8 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
418439
iris_inst_sub_state_change_drain_last(inst);
419440
}
420441

421-
if (iris_split_mode_enabled(inst) && pkt->stream_id == 0) {
442+
if (iris_split_mode_enabled(inst) && inst->domain == DECODER &&
443+
uncom_pkt->stream_id == 0) {
422444
buffers = &inst->buffers[BUF_DPB];
423445
if (!buffers)
424446
goto error;
@@ -459,7 +481,8 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
459481
timestamp_us = timestamp_hi;
460482
timestamp_us = (timestamp_us << 32) | timestamp_lo;
461483
} else {
462-
if (pkt->stream_id == 1 && !inst->last_buffer_dequeued) {
484+
if (inst->domain == DECODER && uncom_pkt->stream_id == 1 &&
485+
!inst->last_buffer_dequeued) {
463486
if (iris_drc_pending(inst) || iris_drain_pending(inst)) {
464487
flags |= V4L2_BUF_FLAG_LAST;
465488
inst->last_buffer_dequeued = true;
@@ -551,7 +574,7 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = {
551574
},
552575
{
553576
.pkt = HFI_MSG_SESSION_FILL_BUFFER,
554-
.pkt_sz = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt),
577+
.pkt_sz = sizeof(struct hfi_msg_session_fbd_compressed_pkt),
555578
},
556579
{
557580
.pkt = HFI_MSG_SESSION_FLUSH,

drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,13 +1043,19 @@ static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
10431043
inst_hfi_gen2->packet->size);
10441044
}
10451045

1046-
static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type)
1046+
static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type buffer_type)
10471047
{
10481048
switch (buffer_type) {
10491049
case BUF_INPUT:
1050-
return HFI_BUFFER_BITSTREAM;
1050+
if (domain == DECODER)
1051+
return HFI_BUFFER_BITSTREAM;
1052+
else
1053+
return HFI_BUFFER_RAW;
10511054
case BUF_OUTPUT:
1052-
return HFI_BUFFER_RAW;
1055+
if (domain == DECODER)
1056+
return HFI_BUFFER_RAW;
1057+
else
1058+
return HFI_BUFFER_BITSTREAM;
10531059
case BUF_BIN:
10541060
return HFI_BUFFER_BIN;
10551061
case BUF_COMV:
@@ -1089,16 +1095,17 @@ static int iris_set_num_comv(struct iris_inst *inst)
10891095
&num_comv, sizeof(u32));
10901096
}
10911097

1092-
static void iris_hfi_gen2_get_buffer(struct iris_buffer *buffer, struct iris_hfi_buffer *buf)
1098+
static void iris_hfi_gen2_get_buffer(u32 domain, struct iris_buffer *buffer,
1099+
struct iris_hfi_buffer *buf)
10931100
{
10941101
memset(buf, 0, sizeof(*buf));
1095-
buf->type = iris_hfi_gen2_buf_type_from_driver(buffer->type);
1102+
buf->type = iris_hfi_gen2_buf_type_from_driver(domain, buffer->type);
10961103
buf->index = buffer->index;
10971104
buf->base_address = buffer->device_addr;
10981105
buf->addr_offset = 0;
10991106
buf->buffer_size = buffer->buffer_size;
11001107

1101-
if (buffer->type == BUF_INPUT)
1108+
if (domain == DECODER && buffer->type == BUF_INPUT)
11021109
buf->buffer_size = ALIGN(buffer->buffer_size, 256);
11031110
buf->data_offset = buffer->data_offset;
11041111
buf->data_size = buffer->data_size;
@@ -1115,7 +1122,7 @@ static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iri
11151122
u32 port;
11161123
int ret;
11171124

1118-
iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
1125+
iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
11191126
if (buffer->type == BUF_COMV) {
11201127
ret = iris_set_num_comv(inst);
11211128
if (ret)
@@ -1142,7 +1149,7 @@ static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct i
11421149
struct iris_hfi_buffer hfi_buffer;
11431150
u32 port;
11441151

1145-
iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
1152+
iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
11461153
hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
11471154
port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
11481155

drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -480,12 +480,22 @@ static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst,
480480
if (!iris_hfi_gen2_is_valid_hfi_port(pkt->port, buffer->type))
481481
return 0;
482482

483-
if (buffer->type == HFI_BUFFER_BITSTREAM)
484-
return iris_hfi_gen2_handle_input_buffer(inst, buffer);
485-
else if (buffer->type == HFI_BUFFER_RAW)
486-
return iris_hfi_gen2_handle_output_buffer(inst, buffer);
487-
else
488-
return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
483+
if (inst->domain == DECODER) {
484+
if (buffer->type == HFI_BUFFER_BITSTREAM)
485+
return iris_hfi_gen2_handle_input_buffer(inst, buffer);
486+
else if (buffer->type == HFI_BUFFER_RAW)
487+
return iris_hfi_gen2_handle_output_buffer(inst, buffer);
488+
else
489+
return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
490+
} else {
491+
if (buffer->type == HFI_BUFFER_RAW)
492+
return iris_hfi_gen2_handle_input_buffer(inst, buffer);
493+
else if (buffer->type == HFI_BUFFER_BITSTREAM)
494+
return iris_hfi_gen2_handle_output_buffer(inst, buffer);
495+
else
496+
return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
497+
}
498+
return 0;
489499
}
490500

491501
static int iris_hfi_gen2_handle_session_drain(struct iris_inst *inst,

drivers/media/platform/qcom/iris/iris_vb2.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,10 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2)
327327

328328
v4l2_m2m_buf_queue(m2m_ctx, vbuf);
329329

330-
ret = iris_vdec_qbuf(inst, vbuf);
330+
if (inst->domain == DECODER)
331+
ret = iris_vdec_qbuf(inst, vbuf);
332+
else
333+
ret = iris_venc_qbuf(inst, vbuf);
331334

332335
exit:
333336
if (ret) {

0 commit comments

Comments
 (0)