author | Nanxin Qin <nanxin.qin@amlogic.com> | 2020-07-23 09:17:49 (GMT) |
---|---|---|
committer | Nanxin Qin <nanxin.qin@amlogic.com> | 2020-07-23 09:42:33 (GMT) |
commit | bb5d3a9b20b3d51b9c07346ec43504cac5016c67 (patch) | |
tree | add4d560c03f1df601783ba9efa1b7f5cb7c3b84 | |
parent | fc199e88480b0d209449652365f0e9501bd1da43 (diff) | |
download | media_modules-bb5d3a9b20b3d51b9c07346ec43504cac5016c67.zip media_modules-bb5d3a9b20b3d51b9c07346ec43504cac5016c67.tar.gz media_modules-bb5d3a9b20b3d51b9c07346ec43504cac5016c67.tar.bz2 |
v4l: fixed the issue of vp9 can't playback on linux. [1/1]
PD#SWPL-29656
Problem:
has wrong of the private head data of vp9 cause playback failed,
becuase usually the head process on the omx but if on the linux
the v4l codec driver need to handle it.
Solution:
restore the function of use supperframe split filter make sure
add head data process normal if work on linux.
Verify:
u212
Change-Id: Ie3cf4858c2c4160b9ca551e39faca5a5c127fe19
Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
-rw-r--r-- | drivers/amvdec_ports/decoder/aml_vp9_parser.h | 2 | ||||
-rw-r--r-- | drivers/amvdec_ports/decoder/vdec_vp9_if.c | 88 |
2 files changed, 88 insertions, 2 deletions
diff --git a/drivers/amvdec_ports/decoder/aml_vp9_parser.h b/drivers/amvdec_ports/decoder/aml_vp9_parser.h index 9f7dfd9..ddeddec 100644 --- a/drivers/amvdec_ports/decoder/aml_vp9_parser.h +++ b/drivers/amvdec_ports/decoder/aml_vp9_parser.h @@ -174,12 +174,10 @@ struct vp9_param_sets { struct VP9Context ctx; }; - #ifdef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER int vp9_superframe_split_filter(struct vp9_superframe_split *s); int vp9_decode_extradata_ps(u8 *data, int size, struct vp9_param_sets *ps); #else -inline int vp9_superframe_split_filter(struct vp9_superframe_split *s) { return -1;} inline int vp9_decode_extradata_ps(u8 *data, int size, struct vp9_param_sets *ps) { return -1; } #endif diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c index ec9ce64..be08628 100644 --- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c +++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c @@ -669,6 +669,94 @@ static void add_prefix_data(struct vp9_superframe_split *s, *out_size = length; } +#ifndef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER +static int vp9_superframe_split_filter(struct vp9_superframe_split *s) +{ + int i, j, ret, marker; + bool is_superframe = false; + int *prefix = (int *)s->data; + + if (!s->data) + return -1; + +#define AML_PREFIX ('V' << 24 | 'L' << 16 | 'M' << 8 | 'A') + if (prefix[3] == AML_PREFIX) { + s->prefix_size = 16; + /*pr_info("the frame data has beed added header\n");*/ + } + + marker = s->data[s->data_size - 1]; + if ((marker & 0xe0) == 0xc0) { + int length_size = 1 + ((marker >> 3) & 0x3); + int nb_frames = 1 + (marker & 0x7); + int idx_size = 2 + nb_frames * length_size; + + if (s->data_size >= idx_size && + s->data[s->data_size - idx_size] == marker) { + s64 total_size = 0; + int idx = s->data_size + 1 - idx_size; + + for (i = 0; i < nb_frames; i++) { + int frame_size = 0; + for (j = 0; j < length_size; j++) + frame_size |= s->data[idx++] << (j * 8); + + total_size += frame_size; + if (frame_size < 0 || + total_size > s->data_size - idx_size) { + v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "Invalid frame size in a sframe: %d\n", + frame_size); + ret = -EINVAL; + goto fail; + } + s->sizes[i] = frame_size; + } + + s->nb_frames = nb_frames; + s->size = total_size; + s->next_frame = 0; + s->next_frame_offset = 0; + is_superframe = true; + } + }else { + s->nb_frames = 1; + s->sizes[0] = s->data_size; + s->size = s->data_size; + } + + /*pr_info("sframe: %d, frames: %d, IN: %x, OUT: %x\n", + is_superframe, s->nb_frames, + s->data_size, s->size);*/ + + /* parse uncompressed header. */ + if (is_superframe) { + /* bitstream profile. */ + /* frame type. (intra or inter) */ + /* colorspace descriptor */ + /* ... */ + + v4l_dbg(0, V4L_DEBUG_CODEC_PARSER, "the frame is a superframe.\n"); + } + + /*pr_err("in: %x, %d, out: %x, sizes %d,%d,%d,%d,%d,%d,%d,%d\n", + s->data_size, + s->nb_frames, + s->size, + s->sizes[0], + s->sizes[1], + s->sizes[2], + s->sizes[3], + s->sizes[4], + s->sizes[5], + s->sizes[6], + s->sizes[7]);*/ + + return 0; +fail: + return ret; +} +#endif + static void trigger_decoder(struct aml_vdec_adapt *vdec) { int i, ret; |