summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--drivers/amvdec_ports/Makefile13
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c22
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.h3
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c534
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h39
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_drv.c57
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h11
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.c18
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.h8
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.c9
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.h6
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.c662
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_h264_parser.h226
-rw-r--r--drivers/amvdec_ports/decoder/aml_hevc_parser.c1274
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_hevc_parser.h137
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.c397
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.h163
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.c198
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.h74
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.c1233
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.h250
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.c299
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_vp9_parser.h279
-rw-r--r--drivers/amvdec_ports/decoder/h264_parse.c389
-rw-r--r--drivers/amvdec_ports/decoder/h264_parse.h141
-rw-r--r--drivers/amvdec_ports/decoder/h264_stream.c111
-rw-r--r--drivers/amvdec_ports/decoder/h264_stream.h39
-rw-r--r--drivers/amvdec_ports/decoder/vdec_h264_if.c357
-rw-r--r--drivers/amvdec_ports/decoder/vdec_hevc_if.c477
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mjpeg_if.c498
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg12_if.c490
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg4_if.c499
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c461
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/vdec_vp9_trigger.h0
-rw-r--r--drivers/amvdec_ports/test/vcodec_m2m_test.c18
-rw-r--r--drivers/amvdec_ports/utils/common.c221
-rw-r--r--drivers/amvdec_ports/utils/common.h72
-rw-r--r--drivers/amvdec_ports/utils/get_bits.h590
-rw-r--r--drivers/amvdec_ports/utils/golomb.c147
-rw-r--r--drivers/amvdec_ports/utils/golomb.h500
-rw-r--r--drivers/amvdec_ports/utils/pixfmt.h470
-rw-r--r--drivers/amvdec_ports/utils/put_bits.h323
-rw-r--r--drivers/amvdec_ports/vdec_drv_base.h11
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.c45
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.h10
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c219
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c308
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c334
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c233
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c317
-rw-r--r--drivers/frame_provider/decoder/utils/Makefile1
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_input.c19
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c131
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h22
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c388
55 files changed, 11471 insertions, 2282 deletions
diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c
index efa9fc7..02848b8 100644
--- a/drivers/amvdec_ports/decoder/vdec_h264_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -22,16 +22,16 @@
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+
#include "../vdec_drv_if.h"
#include "../aml_vcodec_util.h"
#include "../aml_vcodec_dec.h"
-//#include "../aml_vcodec_intr.h"
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
#include "../aml_vcodec_vfm.h"
-#include "h264_stream.h"
-#include "h264_parse.h"
-#include <uapi/linux/swab.h>
+#include "aml_h264_parser.h"
+#include "../utils/common.h"
/* h264 NALU type */
#define NAL_NON_IDR_SLICE 0x01
@@ -39,8 +39,9 @@
#define NAL_H264_SEI 0x06
#define NAL_H264_SPS 0x07
#define NAL_H264_PPS 0x08
+#define NAL_H264_AUD 0x09
-#define NAL_TYPE(value) ((value) & 0x1F)
+#define AVC_NAL_TYPE(value) ((value) & 0x1F)
#define BUF_PREDICTION_SZ (64 * 1024)//(32 * 1024)
@@ -52,7 +53,7 @@
#define H264_MAX_FB_NUM 17
#define HDR_PARSING_BUF_SZ 1024
-#define HEADER_BUFFER_SIZE (32 * 1024)
+#define HEADER_BUFFER_SIZE (128 * 1024)
/**
* struct h264_fb - h264 decode frame buffer information
@@ -113,11 +114,6 @@ struct vdec_h264_dec_info {
* by VPU.
* AP-W/R : AP is writer/reader on this item
* VPU-W/R: VPU is write/reader on this item
- * @hdr_buf : Header parsing buffer (AP-W, VPU-R)
- * @pred_buf_dma : HW working predication buffer dma address (AP-W, VPU-R)
- * @mv_buf_dma : HW working motion vector buffer dma address (AP-W, VPU-R)
- * @list_free : free frame buffer ring list (AP-W/R, VPU-W)
- * @list_disp : display frame buffer ring list (AP-R, VPU-W)
* @dec : decode information (AP-R, VPU-W)
* @pic : picture information (AP-R, VPU-W)
* @crop : crop information (AP-R, VPU-W)
@@ -129,10 +125,6 @@ struct vdec_h264_vsi {
int pps_size;
int sei_size;
int head_offset;
- uint64_t pred_buf_dma;
- uint64_t mv_buf_dma[H264_MAX_FB_NUM];
- struct h264_ring_fb_list list_free;
- struct h264_ring_fb_list list_disp;
struct vdec_h264_dec_info dec;
struct vdec_pic_info pic;
struct vdec_pic_info cur_pic;
@@ -155,10 +147,10 @@ struct vdec_h264_inst {
struct aml_vcodec_ctx *ctx;
struct aml_vcodec_mem pred_buf;
struct aml_vcodec_mem mv_buf[H264_MAX_FB_NUM];
- //struct vdec_vpu_inst vpu;
struct aml_vdec_adapt vdec;
struct vdec_h264_vsi *vsi;
struct vcodec_vfm_s vfm;
+ struct completion comp;
};
#if 0
@@ -241,18 +233,6 @@ static void get_dpb_size(struct vdec_h264_inst *inst, unsigned int *dpb_sz)
aml_vcodec_debug(inst, "sz=%d", *dpb_sz);
}
-static int find_start_code(unsigned char *data, unsigned int data_sz)
-{
- if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1)
- return 3;
-
- if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 &&
- data[3] == 1)
- return 4;
-
- return -1;
-}
-
static void skip_aud_data(u8 **data, u32 *size)
{
int i;
@@ -275,7 +255,7 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
inst->ctx = ctx;
- inst->vdec.format = VFORMAT_H264;
+ inst->vdec.video_type = VFORMAT_H264;
inst->vdec.dev = ctx->dev->vpu_plat_dev;
inst->vdec.filp = ctx->dev->filp;
inst->vdec.ctx = ctx;
@@ -318,6 +298,8 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
inst->vsi->pic.c_bs_sz = 0;
inst->vsi->pic.c_len_sz = (1920 * 1088 / 2);
+ init_completion(&inst->comp);
+
aml_vcodec_debug(inst, "H264 Instance >> %p", inst);
ctx->ada_ctx = &inst->vdec;
@@ -336,11 +318,11 @@ error_free_inst:
return ret;
}
-static int refer_buffer_num(int level_idc, int poc_cnt,
+#if 0
+static int refer_buffer_num(int level_idc, int max_poc_cnt,
int mb_width, int mb_height)
{
- int max_ref_num = 27;
- int size, size_margin = 6;
+ int size;
int pic_size = mb_width * mb_height * 384;
switch (level_idc) {
@@ -399,51 +381,28 @@ static int refer_buffer_num(int level_idc, int poc_cnt,
size /= pic_size;
size = size + 1; /* need more buffers */
- if (poc_cnt > size)
- size = poc_cnt;
-
- size = size + size_margin;
- if (size > max_ref_num)
- size = max_ref_num;
+ if (size > max_poc_cnt)
+ size = max_poc_cnt;
return size;
}
+#endif
static void fill_vdec_params(struct vdec_h264_inst *inst, struct h264_SPS_t *sps)
{
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_h264_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- unsigned int mb_w, mb_h, width, height;
- unsigned int crop_unit_x = 0, crop_unit_y = 0;
- unsigned int poc_cnt = 0;
-
- mb_w = sps->pic_width_in_mbs_minus1 + 1;
- mb_h = sps->pic_height_in_map_units_minus1 + 1;
-
- width = mb_w << 4; // 16
- height = (2 - sps->frame_mbs_only_flag) * (mb_h << 4);
-
- if (sps->frame_cropping_flag) {
- if (0 == sps->chroma_format_idc) {// monochrome
- crop_unit_x = 1;
- crop_unit_y = 2 - sps->frame_mbs_only_flag;
- } else if (1 == sps->chroma_format_idc) {// 4:2:0
- crop_unit_x = 2;
- crop_unit_y = 2 * (2 - sps->frame_mbs_only_flag);
- } else if (2 == sps->chroma_format_idc) {// 4:2:2
- crop_unit_x = 2;
- crop_unit_y = 2 - sps->frame_mbs_only_flag;
- } else {// 3 == sps.chroma_format_idc // 4:4:4
- crop_unit_x = 1;
- crop_unit_y = 2 - sps->frame_mbs_only_flag;
- }
- }
+ u32 mb_w, mb_h, width, height;
- width -= crop_unit_x * (sps->frame_crop_left_offset +
- sps->frame_crop_right_offset);
- height -= crop_unit_y * (sps->frame_crop_top_offset +
- sps->frame_crop_bottom_offset);
+ mb_w = sps->mb_width;
+ mb_h = sps->mb_height;
+
+ width = mb_w << 4;
+ height = mb_h << 4;
+
+ width -= (sps->crop_left + sps->crop_right);
+ height -= (sps->crop_top + sps->crop_bottom);
/* fill visible area size that be used for EGL. */
pic->visible_width = width;
@@ -462,19 +421,16 @@ static void fill_vdec_params(struct vdec_h264_inst *inst, struct h264_SPS_t *sps
pic->c_len_sz = pic->y_len_sz >> 1;
/* calc DPB size */
- poc_cnt = sps->pic_order_cnt_type;
- if (!poc_cnt)
- poc_cnt = (sps->log2_max_pic_order_cnt_lsb_minus4 + 4) << 1;
-
- dec->dpb_sz = refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h);
+ dec->dpb_sz = sps->ref_frame_count;
aml_vcodec_debug(inst, "[%d] The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n",
inst->ctx->id, pic->coded_width, pic->coded_height,
pic->visible_width, pic->visible_height, dec->dpb_sz);
}
-static void search_from_st(u8 *buf, u32 size, int *pos, bool *is_combine)
+static bool check_frame_combine(u8 *buf, u32 size, int *pos)
{
+ bool combine = false;
int i = 0, j = 0, cnt = 0;
u8 *p = buf;
@@ -482,7 +438,7 @@ static void search_from_st(u8 *buf, u32 size, int *pos, bool *is_combine)
j = find_start_code(p, 7);
if (j > 0) {
if (++cnt > 1) {
- *is_combine = true;
+ combine = true;
break;
}
@@ -494,22 +450,40 @@ static void search_from_st(u8 *buf, u32 size, int *pos, bool *is_combine)
}
//pr_info("nal pos: %d, is_combine: %d\n",*pos, *is_combine);
+ return combine;
+}
+
+static int stream_parse_by_ucode(struct vdec_h264_inst *inst, u8 *buf, u32 size)
+{
+ int ret = 0;
+ struct aml_vdec_adapt *vdec = &inst->vdec;
+
+ ret = vdec_vframe_write(vdec, buf, size, 0);
+ if (ret < 0) {
+ pr_err("write frame data failed. err: %d\n", ret);
+ return ret;
+ }
+
+ /* wait ucode parse ending. */
+ wait_for_completion_timeout(&inst->comp,
+ msecs_to_jiffies(1000));
+
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int stream_parse(struct vdec_h264_inst *inst, u8 *buf, u32 size)
{
- struct h264_stream_t s;
- struct h264_SPS_t *sps;
- unsigned int nal_type;
+ int ret = 0;
+ struct h264_param_sets *ps;
+ u32 nal_type;
int nal_idx = 0;
- int real_data_pos, real_data_size;
bool is_combine = false;
- search_from_st(buf, size, &nal_idx, &is_combine);
+ is_combine = check_frame_combine(buf, size, &nal_idx);
if (nal_idx < 0)
return -1;
- nal_type = NAL_TYPE(buf[nal_idx]);
+ nal_type = AVC_NAL_TYPE(buf[nal_idx]);
if (nal_type != NAL_H264_SPS)
return -1;
@@ -517,23 +491,24 @@ static int stream_parse(struct vdec_h264_inst *inst, u8 *buf, u32 size)
inst->vsi->is_combine = is_combine;
inst->vsi->nalu_pos = nal_idx;
- /* start code plus nal type. */
- real_data_pos = nal_idx + 1;
- real_data_size = size - real_data_pos;
-
- sps = kzalloc(sizeof(struct h264_SPS_t), GFP_KERNEL);
- if (sps == NULL)
+ ps = kzalloc(sizeof(struct h264_param_sets), GFP_KERNEL);
+ if (ps == NULL)
return -ENOMEM;
- h264_stream_set(&s, &buf[real_data_pos], real_data_size);
- h264_sps_parse(&s, sps);
- //h264_sps_info(sps);
+ ret = h264_decode_extradata_ps(buf, size, ps);
+ if (ret) {
+ pr_err("parse extra data failed. err: %d\n", ret);
+ goto out;
+ }
- fill_vdec_params(inst, sps);
+ if (ps->sps_parsed)
+ fill_vdec_params(inst, &ps->sps);
- kfree(sps);
+ ret = ps->sps_parsed ? 0 : -1;
+out:
+ kfree(ps);
- return 0;
+ return ret;
}
static int vdec_h264_probe(unsigned long h_vdec,
@@ -542,7 +517,7 @@ static int vdec_h264_probe(unsigned long h_vdec,
struct vdec_h264_inst *inst =
(struct vdec_h264_inst *)h_vdec;
struct stream_info *st;
- u8 *buf = (u8 *)bs->va;
+ u8 *buf = (u8 *)bs->vaddr;
u32 size = bs->size;
int ret = 0;
@@ -556,7 +531,11 @@ static int vdec_h264_probe(unsigned long h_vdec,
}
skip_aud_data(&buf, &size);
- ret = stream_parse(inst, buf, size);
+
+ if (inst->ctx->param_sets_from_ucode)
+ ret = stream_parse_by_ucode(inst, buf, size);
+ else
+ ret = stream_parse(inst, buf, size);
inst->vsi->cur_pic = inst->vsi->pic;
@@ -565,10 +544,9 @@ static int vdec_h264_probe(unsigned long h_vdec,
static void vdec_h264_deinit(unsigned long h_vdec)
{
+ ulong flags;
struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
-
- if (!inst)
- return;
+ struct aml_vcodec_ctx *ctx = inst->ctx;
aml_vcodec_debug_enter(inst);
@@ -578,6 +556,7 @@ static void vdec_h264_deinit(unsigned long h_vdec)
//dump_deinit();
+ spin_lock_irqsave(&ctx->slock, flags);
if (inst->vsi && inst->vsi->header_buf)
kfree(inst->vsi->header_buf);
@@ -585,20 +564,20 @@ static void vdec_h264_deinit(unsigned long h_vdec)
kfree(inst->vsi);
kfree(inst);
+
+ ctx->drv_handle = 0;
+ spin_unlock_irqrestore(&ctx->slock, flags);
}
-static int vdec_h264_get_fb(struct vdec_h264_inst *inst, struct vdec_fb **out)
+static int vdec_h264_get_fb(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out)
{
return get_fb_from_queue(inst->ctx, out);
}
-static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_fb **out)
+static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out)
{
struct vframe_s *vf = NULL;
- struct vdec_fb *fb = NULL;
-
- aml_vcodec_debug(inst, "%s() [%d], vfm: %p",
- __func__, __LINE__, &inst->vfm);
+ struct vdec_v4l2_buffer *fb = NULL;
vf = peek_video_frame(&inst->vfm);
if (!vf) {
@@ -616,28 +595,18 @@ static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_fb **out)
atomic_set(&vf->use_cnt, 1);
- aml_vcodec_debug(inst, "%s() [%d], vf: %p, v4l_mem_handle: %lx, idx: %d\n",
- __func__, __LINE__, vf, vf->v4l_mem_handle, vf->index);
-
- fb = (struct vdec_fb *)vf->v4l_mem_handle;
+ fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
fb->vf_handle = (unsigned long)vf;
fb->status = FB_ST_DISPLAY;
*out = fb;
//pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
- //dump_write(fb->base_y.va, fb->base_y.bytes_used);
- //dump_write(fb->base_c.va, fb->base_c.bytes_used);
+ //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
+ //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
/* convert yuv format. */
- //swap_uv(fb->base_c.va, fb->base_c.size);
-
- aml_vcodec_debug(inst, "%s() [%d], va: %p, phy: %x, size: %zu",
- __func__, __LINE__, fb->base_y.va,
- (unsigned int)virt_to_phys(fb->base_y.va), fb->base_y.size);
- aml_vcodec_debug(inst, "%s() [%d], va: %p, phy: %x, size: %zu",
- __func__, __LINE__, fb->base_c.va,
- (unsigned int)virt_to_phys(fb->base_c.va), fb->base_c.size);
+ //swap_uv(fb->base_c.vaddr, fb->base_c.size);
}
static int vdec_write_nalu(struct vdec_h264_inst *inst,
@@ -653,8 +622,8 @@ static int vdec_write_nalu(struct vdec_h264_inst *inst,
if (nalu_pos < 0)
goto err;
- nal_type = NAL_TYPE(buf[nalu_pos]);
- aml_vcodec_debug(inst, "NALU type: %d, size: %u", nal_type, size);
+ nal_type = AVC_NAL_TYPE(buf[nalu_pos]);
+ //aml_vcodec_debug(inst, "NALU type: %d, size: %u", nal_type, size);
if (nal_type == NAL_H264_SPS && !is_combine) {
if (inst->vsi->head_offset + size > HEADER_BUFFER_SIZE) {
@@ -686,9 +655,6 @@ static int vdec_write_nalu(struct vdec_h264_inst *inst,
ret = size;
} else if (inst->vsi->head_offset == 0) {
ret = vdec_vframe_write(vdec, buf, size, ts);
-
- aml_vcodec_debug(inst, "buf: %p, buf size: %u, write to: %d",
- buf, size, ret);
} else {
char *write_buf = vmalloc(inst->vsi->head_offset + size);
if (!write_buf) {
@@ -702,9 +668,6 @@ static int vdec_write_nalu(struct vdec_h264_inst *inst,
ret = vdec_vframe_write(vdec, write_buf,
inst->vsi->head_offset + size, ts);
- aml_vcodec_debug(inst, "buf: %p, buf size: %u, write to: %d",
- write_buf, inst->vsi->head_offset + size, ret);
-
memset(inst->vsi->header_buf, 0, HEADER_BUFFER_SIZE);
inst->vsi->head_offset = 0;
inst->vsi->sps_size = 0;
@@ -720,14 +683,46 @@ err:
return ret;
}
+static bool monitor_res_change(struct vdec_h264_inst *inst, u8 *buf, u32 size)
+{
+ int ret = 0, i = 0, j = 0;
+ u8 *p = buf;
+ int len = size;
+ u32 type;
+
+ for (i = 4; i < size; i++) {
+ j = find_start_code(p, len);
+ if (j > 0) {
+ len = size - (p - buf);
+ type = AVC_NAL_TYPE(p[j]);
+ if (type != NAL_H264_AUD &&
+ (type > NAL_H264_PPS || type < NAL_H264_SEI))
+ break;
+
+ if (type == NAL_H264_SPS) {
+ ret = stream_parse(inst, p, len);
+ if (!ret && (inst->vsi->cur_pic.coded_width !=
+ inst->vsi->pic.coded_width ||
+ inst->vsi->cur_pic.coded_height !=
+ inst->vsi->pic.coded_height)) {
+ inst->vsi->cur_pic = inst->vsi->pic;
+ return true;
+ }
+ }
+ p += j;
+ }
+ p++;
+ }
+
+ return false;
+}
+
static int vdec_h264_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
- unsigned long int timestamp, bool *res_chg)
+ u64 timestamp, bool *res_chg)
{
struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
struct aml_vdec_adapt *vdec = &inst->vdec;
struct stream_info *st;
- int nalu_pos;
- u32 nal_type;
u8 *buf;
u32 size;
int ret = -1;
@@ -736,7 +731,7 @@ static int vdec_h264_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
if (bs == NULL)
return -1;
- buf = (u8 *)bs->va;
+ buf = (u8 *)bs->vaddr;
size = bs->size;
st = (struct stream_info *)buf;
@@ -749,28 +744,10 @@ static int vdec_h264_decode(unsigned long h_vdec, struct aml_vcodec_mem *bs,
else if (inst->ctx->is_stream_mode)
ret = vdec_vbuf_write(vdec, buf, size);
else {
- /*checked whether the resolution chagnes.*/
- u8 *p = buf;
- u32 l = size;
-
- skip_aud_data(&p, &l);
-
- nalu_pos = find_start_code(p, l);
- if (nalu_pos < 0)
- return -1;
-
- nal_type = NAL_TYPE(p[nalu_pos]);
- if (nal_type == NAL_H264_SPS) {
- stream_parse(inst, p, l);
- if (inst->vsi->cur_pic.coded_width !=
- inst->vsi->pic.coded_width ||
- inst->vsi->cur_pic.coded_height !=
- inst->vsi->pic.coded_height) {
- inst->vsi->cur_pic = inst->vsi->pic;
- *res_chg = true;
- return 0;
- }
- }
+ /*checked whether the resolution changes.*/
+ if ((*res_chg = monitor_res_change(inst, buf, size)))
+ return 0;
+
ret = vdec_write_nalu(inst, buf, size, timestamp);
}
@@ -817,12 +794,80 @@ static int vdec_h264_get_param(unsigned long h_vdec,
return ret;
}
+static void set_param_write_sync(struct vdec_h264_inst *inst)
+{
+ complete(&inst->comp);
+}
+
+static void set_param_pic_info(struct vdec_h264_inst *inst,
+ struct aml_vdec_pic_infos *info)
+{
+ struct vdec_pic_info *pic = &inst->vsi->pic;
+ struct vdec_h264_dec_info *dec = &inst->vsi->dec;
+ struct v4l2_rect *rect = &inst->vsi->crop;
+
+ /* fill visible area size that be used for EGL. */
+ pic->visible_width = info->visible_width;
+ pic->visible_height = info->visible_height;
+
+ /* calc visible ares. */
+ rect->left = 0;
+ rect->top = 0;
+ rect->width = pic->visible_width;
+ rect->height = pic->visible_height;
+
+ /* config canvas size that be used for decoder. */
+ pic->coded_width = info->coded_width;
+ pic->coded_height = info->coded_height;
+ pic->y_len_sz = pic->coded_width * pic->coded_height;
+ pic->c_len_sz = pic->y_len_sz >> 1;
+
+ dec->dpb_sz = info->dpb_size;
+
+ /*wake up*/
+ complete(&inst->comp);
+
+ pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
+ info->visible_width, info->visible_height,
+ info->coded_width, info->coded_height,
+ info->dpb_size);
+}
+
+static int vdec_h264_set_param(unsigned long h_vdec,
+ enum vdec_set_param_type type, void *in)
+{
+ int ret = 0;
+ struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
+
+ if (!inst) {
+ pr_err("the h264 inst of dec is invalid.\n");
+ return -1;
+ }
+
+ switch (type) {
+ case SET_PARAM_WRITE_FRAME_SYNC:
+ set_param_write_sync(inst);
+ break;
+
+ case SET_PARAM_PIC_INFO:
+ set_param_pic_info(inst, in);
+ break;
+
+ default:
+ aml_vcodec_err(inst, "invalid set parameter type=%d", type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
static struct vdec_common_if vdec_h264_if = {
- vdec_h264_init,
- vdec_h264_probe,
- vdec_h264_decode,
- vdec_h264_get_param,
- vdec_h264_deinit,
+ .init = vdec_h264_init,
+ .probe = vdec_h264_probe,
+ .decode = vdec_h264_decode,
+ .get_param = vdec_h264_get_param,
+ .set_param = vdec_h264_set_param,
+ .deinit = vdec_h264_deinit,
};
struct vdec_common_if *get_h264_dec_comm_if(void);