summaryrefslogtreecommitdiff
authorNanxin 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)
commitbb5d3a9b20b3d51b9c07346ec43504cac5016c67 (patch)
treeadd4d560c03f1df601783ba9efa1b7f5cb7c3b84
parentfc199e88480b0d209449652365f0e9501bd1da43 (diff)
downloadmedia_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>
Diffstat
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.h2
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c88
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;