if (IS_BUFFER_BATCH_MODE(ctx)) {
int count = 0;
+ ctx->framerate = ctx->num_bufs_in_vb * ENC_DEFAULT_CAM_FPS;
+ mfc_debug(3, "framerate: %ld\n", ctx->framerate);
+
count = s5p_mfc_bufcon_get_daddr(ctx, buf, dmabuf, i);
if (count != ctx->num_bufs_in_vb) {
mfc_err_ctx("invalid buffer count %d != num_bufs_in_vb %d\n",
s5p_mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, buf);
} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
s5p_mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, buf);
+
+ mfc_debug(7, "framerate: %ld, timestamp: %lld\n",
+ ctx->framerate, buf->vb.vb2_buf.timestamp);
+ mfc_debug(7, "qos ratio: %d\n", ctx->qos_ratio);
+
+ s5p_mfc_qos_update_last_framerate(ctx, buf->vb.vb2_buf.timestamp);
+ s5p_mfc_qos_update_framerate(ctx);
} else {
mfc_err_ctx("unsupported buffer type (%d)\n", vq->type);
}
- mfc_debug(7, "timestamp: %lld\n", buf->vb.vb2_buf.timestamp);
- mfc_debug(7, "qos ratio: %d\n", ctx->qos_ratio);
-
- s5p_mfc_qos_update_last_framerate(ctx, buf->vb.vb2_buf.timestamp);
- s5p_mfc_qos_update_framerate(ctx);
-
if (s5p_mfc_enc_ctx_ready(ctx)) {
s5p_mfc_set_bit(ctx->num, &dev->work_bits);
}
}
}
+static void mfc_handle_stream_copy_timestamp(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *src_mb)
+{
+ struct s5p_mfc_dev *dev;
+ struct s5p_mfc_buf *dst_mb;
+ u64 interval;
+ u64 start_timestamp;
+ u64 new_timestamp;
+
+ if (!ctx) {
+ mfc_err_dev("no mfc context to run\n");
+ return;
+ }
+
+ dev = ctx->dev;
+ if (!dev) {
+ mfc_err_dev("no device to run\n");
+ return;
+ }
+
+ start_timestamp = src_mb->vb.vb2_buf.timestamp;
+ interval = NSEC_PER_SEC / (ctx->framerate / 1000);
+ mfc_debug(3, "%ldfps, start timestamp: %lld, base interval: %lld\n",
+ ctx->framerate / 1000, start_timestamp, interval);
+
+ new_timestamp = start_timestamp + (interval * src_mb->done_index);
+ mfc_debug(3, "new timestamp: %lld, interval: %lld\n",
+ new_timestamp, interval * src_mb->done_index);
+
+ /* Get the destination buffer */
+ dst_mb = s5p_mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
+ if (dst_mb)
+ dst_mb->vb.vb2_buf.timestamp = new_timestamp;
+}
+
static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type)
{
struct s5p_mfc_raw_info *raw;
&ctx->src_ctrls[index]) < 0)
mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+ mfc_handle_stream_copy_timestamp(ctx, src_mb);
+
/* last image in a buffer container */
if (src_mb->done_index == ctx->num_bufs_in_vb) {
src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
ctx->sequence++;
- /* handle destination buffer */
- mfc_handle_stream_output(ctx, slice_type, strm_size);
-
if (enc->in_slice) {
if (s5p_mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0)) {
s5p_mfc_clear_bit(ctx->num, &dev->work_bits);
/* handle source buffer */
mfc_handle_stream_input(ctx, slice_type);
+ /* handle destination buffer */
+ mfc_handle_stream_output(ctx, slice_type, strm_size);
+
if (IS_BUFFER_BATCH_MODE(ctx))
return 0;
mfc_debug(2, "NAL Q: recon c addr: 0x%08lx\n", enc_recon_c_addr);
}
+static void mfc_nal_q_handle_stream_copy_timestamp(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *src_mb)
+{
+ struct s5p_mfc_dev *dev;
+ struct s5p_mfc_buf *dst_mb;
+ u64 interval;
+ u64 start_timestamp;
+ u64 new_timestamp;
+
+ if (!ctx) {
+ mfc_err_dev("NAL Q: no mfc context to run\n");
+ return;
+ }
+
+ dev = ctx->dev;
+ if (!dev) {
+ mfc_err_dev("NAL Q: no device to run\n");
+ return;
+ }
+
+ start_timestamp = src_mb->vb.vb2_buf.timestamp;
+ interval = NSEC_PER_SEC / (ctx->framerate / 1000);
+ mfc_debug(3, "NAL Q: %ldfps, start timestamp: %lld, base interval: %lld\n",
+ ctx->framerate / 1000, start_timestamp, interval);
+
+ new_timestamp = start_timestamp + (interval * src_mb->done_index);
+ mfc_debug(3, "NAL Q: new timestamp: %lld, interval: %lld\n",
+ new_timestamp, interval * src_mb->done_index);
+
+ /* Get the destination buffer */
+ dst_mb = s5p_mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_nal_queue, MFC_BUF_NO_TOUCH_USED);
+ if (dst_mb)
+ dst_mb->vb.vb2_buf.timestamp = new_timestamp;
+}
+
static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type,
unsigned int strm_size, EncoderOutputStr *pOutStr)
{
if (src_mb) {
src_mb->done_index++;
mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
+
+ mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb);
} else {
src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
&ctx->src_buf_nal_queue, enc_addr[0], ctx->num_bufs_in_vb);
src_mb->done_index++;
mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
+ mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb);
+
/* last image in a buffer container */
if (src_mb->done_index == ctx->num_bufs_in_vb) {
src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
ctx->sequence++;
+ /* handle input buffer */
+ mfc_nal_q_handle_stream_input(ctx, slice_type, strm_size, pOutStr);
+
/* handle output buffer */
if (strm_size > 0) {
/* at least one more dest. buffers exist always */
vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
- /* handle input buffer */
- mfc_nal_q_handle_stream_input(ctx, slice_type, strm_size, pOutStr);
-
mfc_debug_leave();
return;
return (prev_interval < next_interval ? prev_interval : next_interval);
}
-static int mfc_qos_dec_add_timestamp(struct s5p_mfc_ctx *ctx,
+static int mfc_qos_add_timestamp(struct s5p_mfc_ctx *ctx,
struct timeval *time, struct list_head *head)
{
int replace_entry = 0;
}
if (list_empty(&ctx->ts_list)) {
- mfc_qos_dec_add_timestamp(ctx, time, &ctx->ts_list);
+ mfc_qos_add_timestamp(ctx, time, &ctx->ts_list);
return mfc_qos_get_framerate_by_interval(0);
} else {
found = 0;
break;
} else if (time_diff > 0) {
/* Add this after temp_ts */
- mfc_qos_dec_add_timestamp(ctx, time, &temp_ts->list);
+ mfc_qos_add_timestamp(ctx, time, &temp_ts->list);
found = 1;
break;
}
}
if (!found) /* Add this at first entry */
- mfc_qos_dec_add_timestamp(ctx, time, &ctx->ts_list);
+ mfc_qos_add_timestamp(ctx, time, &ctx->ts_list);
}
list_for_each_entry(temp_ts, &ctx->ts_list, list) {
#define MFC_MAX_FPS (480000)
#define DEC_DEFAULT_FPS (240000)
#define ENC_DEFAULT_FPS (240000)
+#define ENC_DEFAULT_CAM_FPS (60000)
#define MB_COUNT_PER_UHD_FRAME 32400
#define MAX_FPS_PER_UHD_FRAME 120