ctx->scratch_buf_size + enc->tmv_buffer_size +
(ctx->dpb_count * (enc->luma_dpb_size +
enc->chroma_dpb_size + enc->me_buffer_size));
-
- ctx->scratch_buf_size = max(ctx->scratch_buf_size, ctx->min_scratch_buf_size);
- ctx->min_scratch_buf_size = 0;
break;
case S5P_FIMV_CODEC_MPEG4_ENC:
case S5P_FIMV_CODEC_H263_ENC:
int dpb_count;
int buf_stride;
- int old_img_width;
- int old_img_height;
int min_dpb_size[3];
- unsigned int enc_drc_flag;
- int enc_res_change;
- int enc_res_change_state;
- int enc_res_change_re_input;
- size_t min_scratch_buf_size;
-
struct s5p_mfc_raw_info raw_buf;
size_t mv_size;
if (ctx->state == MFCINST_RUNNING) {
s5p_mfc_change_state(ctx, MFCINST_GOT_INST);
mfc_info_ctx("Enc resolution is changed\n");
- if (((ctx->old_img_width != 0) && (ctx->old_img_width != ctx->img_width))
- || ((ctx->old_img_height != 0) && (ctx->old_img_height != ctx->img_height)))
- ctx->enc_drc_flag = 1;
}
mfc_info_ctx("Enc input pixelformat : %s\n", ctx->src_fmt->name);
if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
s5p_mfc_qos_reset_last_framerate(ctx);
- ctx->old_img_width = ctx->img_width;
- ctx->old_img_height = ctx->img_height;
-
- mfc_debug(2, "vidioc_streamoff ctx->old_img_width = %d\n", ctx->old_img_width);
- mfc_debug(2, "vidioc_streamoff ctx->old_img_height = %d\n", ctx->old_img_height);
-
ret = vb2_streamoff(&ctx->vq_src, type);
if (!ret)
s5p_mfc_qos_off(ctx);
return 0;
}
-/*
- When the resolution is changed,
- s5p_mfc_start_change_resol_enc() should be called right before NAL_START.
- return value
- 0: no resolution change
- 1: resolution swap
- 2: resolution change
-*/
-static int mfc_start_change_resol_enc(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc *enc = ctx->enc_priv;
- struct s5p_mfc_enc_params *p = &enc->params;
- unsigned int reg = 0;
- int old_img_width;
- int old_img_height;
- int new_img_width;
- int new_img_height;
- int ret = 0;
-
- if ((ctx->img_width == 0) || (ctx->img_height == 0)) {
- mfc_err_dev("new_img_width = %d, new_img_height = %d\n",
- ctx->img_width, ctx->img_height);
- return 0;
- }
-
- old_img_width = ctx->old_img_width;
- old_img_height = ctx->old_img_height;
-
- new_img_width = ctx->img_width;
- new_img_height = ctx->img_height;
-
- if ((old_img_width == new_img_width) && (old_img_height == new_img_height)) {
- mfc_err_dev("Resolution is not changed. new_img_width = %d, new_img_height = %d\n",
- new_img_width, new_img_height);
- return 0;
- }
-
- mfc_info_ctx("Resolution Change : (%d x %d) -> (%d x %d)\n",
- old_img_width, old_img_height, new_img_width, new_img_height);
-
- if ((old_img_width == new_img_height) && (old_img_height == new_img_width)) {
- reg = MFC_READL(S5P_FIMV_E_PARAM_CHANGE);
- reg &= ~(0x1 << 6);
- reg |= (0x1 << 6); /* resolution swap */
- MFC_WRITEL(reg, S5P_FIMV_E_PARAM_CHANGE);
- ret = 1;
- } else {
- reg = MFC_READL(S5P_FIMV_E_PARAM_CHANGE);
- reg &= ~(0x3 << 7);
- /* For now, FW does not care S5P_FIMV_E_PARAM_CHANGE is 1 or 2.
- * It cares S5P_FIMV_E_PARAM_CHANGE is NOT zero.
- */
- if ((old_img_width*old_img_height) < (new_img_width*new_img_height)) {
- reg |= (0x1 << 7); /* resolution increased */
- mfc_info_ctx("Resolution Increased\n");
- } else {
- reg |= (0x2 << 7); /* resolution decreased */
- mfc_info_ctx("Resolution Decreased\n");
- }
- MFC_WRITEL(reg, S5P_FIMV_E_PARAM_CHANGE);
-
- /** set cropped width */
- MFC_WRITEL(ctx->img_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH);
- /** set cropped height */
- MFC_WRITEL(ctx->img_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT);
-
- /* bit rate */
- if (p->rc_frame)
- MFC_WRITEL(p->rc_bitrate, S5P_FIMV_E_RC_BIT_RATE);
- else
- MFC_WRITEL(1, S5P_FIMV_E_RC_BIT_RATE);
- ret = 2;
- }
-
- /** set new stride */
- s5p_mfc_set_enc_stride(ctx);
-
- /** set cropped offset */
- MFC_WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET);
-
- return ret;
-}
-
/* Encode a single frame */
int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx, int last_frame)
{
s5p_mfc_set_slice_mode(ctx);
- if (ctx->enc_drc_flag) {
- ctx->enc_res_change = mfc_start_change_resol_enc(ctx);
- ctx->enc_drc_flag = 0;
- }
-
MFC_WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID);
if ((sfr_dump & MFC_DUMP_ENC_NAL_START) && !ctx->check_dump) {
mfc_debug(2, "Assesing whether this context should be run again.\n");
}
-/* Handle encoder resolution change */
-static void mfc_enc_res_change(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- unsigned int reg = 0;
-
- /*
- * Right after the first NAL_START finished with the new resolution,
- * We need to reset the fields
- */
- if (ctx->enc_res_change) {
- /* clear resolution change bits */
- s5p_mfc_clear_enc_res_change(dev);
-
- ctx->enc_res_change_state = ctx->enc_res_change;
- ctx->enc_res_change = 0;
- }
-
- if (ctx->enc_res_change_state == 1) { /* resolution swap */
- ctx->enc_res_change_state = 0;
- } else if (ctx->enc_res_change_state == 2) { /* resolution change */
- reg = s5p_mfc_get_enc_nal_done_info();
-
- /*
- * Encoding resolution status
- * 0: Normal encoding
- * 1: Resolution Change for B-frame
- * (Encode with previous resolution)
- * 2: Resolution Change for B-frame
- * (Last encoding with previous resolution)
- * 3: Resolution Change for only P-frame
- * (No encode, as all frames with previous resolution are encoded)
- */
- mfc_debug(2, "Encoding Resolution Status : %d\n", reg);
-
- if (reg == 2 || reg == 3) {
- if (dev->has_mmcache && dev->mmcache.is_on_status)
- s5p_mfc_invalidate_mmcache(dev);
-
- s5p_mfc_release_codec_buffers(ctx);
- /* for INIT_BUFFER cmd */
- s5p_mfc_change_state(ctx, MFCINST_HEAD_PARSED);
-
- ctx->enc_res_change_state = 0;
- ctx->min_scratch_buf_size = s5p_mfc_get_enc_scratch_size();
- mfc_debug(2, "S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE = 0x%x\n",
- (unsigned int)ctx->min_scratch_buf_size);
- if (reg == 3)
- ctx->enc_res_change_re_input = 1;
- }
- }
-}
-
static void mfc_handle_stream_copy_timestamp(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *src_mb)
{
struct s5p_mfc_dev *dev;
raw = &ctx->raw_buf;
- if (!ctx->enc_res_change_re_input && slice_type >= 0) {
+ if (slice_type >= 0) {
if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
ctx->state == MFCINST_RUNNING_BUF_FULL)
s5p_mfc_change_state(ctx, MFCINST_RUNNING);
return 0;
}
- if (ctx->enc_res_change || ctx->enc_res_change_state)
- mfc_enc_res_change(ctx);
-
/* set encoded frame type */
enc->frame_type = slice_type;
raw = &ctx->raw_buf;
if (IS_BUFFER_BATCH_MODE(ctx))
return 0;
- if (ctx->enc_res_change_re_input)
- ctx->enc_res_change_re_input = 0;
-
if (s5p_mfc_is_queue_count_greater(&ctx->buf_queue_lock, &ctx->src_buf_queue, 0)) {
s5p_mfc_move_first_buf_used(&ctx->buf_queue_lock,
&ctx->ref_buf_queue, &ctx->src_buf_queue, MFC_QUEUE_ADD_BOTTOM);