Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Coda multi-standard codec IP - MPEG-4 helper functions
0004  *
0005  * Copyright (C) 2019 Pengutronix, Philipp Zabel
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/videodev2.h>
0010 
0011 #include "coda.h"
0012 
0013 int coda_mpeg4_profile(int profile_idc)
0014 {
0015     switch (profile_idc) {
0016     case 0:
0017         return V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
0018     case 15:
0019         return V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
0020     case 2:
0021         return V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE;
0022     case 1:
0023         return V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE;
0024     case 11:
0025         return V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
0026     default:
0027         return -EINVAL;
0028     }
0029 }
0030 
0031 int coda_mpeg4_level(int level_idc)
0032 {
0033     switch (level_idc) {
0034     case 0:
0035         return V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
0036     case 1:
0037         return V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
0038     case 2:
0039         return V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
0040     case 3:
0041         return V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
0042     case 4:
0043         return V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
0044     case 5:
0045         return V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
0046     default:
0047         return -EINVAL;
0048     }
0049 }
0050 
0051 /*
0052  * Check if the buffer starts with the MPEG-4 visual object sequence and visual
0053  * object headers, for example:
0054  *
0055  *   00 00 01 b0 f1
0056  *   00 00 01 b5 a9 13 00 00 01 00 00 00 01 20 08
0057  *               d4 8d 88 00 f5 04 04 08 14 30 3f
0058  *
0059  * Returns the detected header size in bytes or 0.
0060  */
0061 u32 coda_mpeg4_parse_headers(struct coda_ctx *ctx, u8 *buf, u32 size)
0062 {
0063     static const u8 vos_start[4] = { 0x00, 0x00, 0x01, 0xb0 };
0064     static const union {
0065         u8 vo_start[4];
0066         u8 start_code_prefix[3];
0067     } u = { { 0x00, 0x00, 0x01, 0xb5 } };
0068 
0069     if (size < 30 ||
0070         memcmp(buf, vos_start, 4) != 0 ||
0071         memcmp(buf + 5, u.vo_start, 4) != 0)
0072         return 0;
0073 
0074     if (size == 30 ||
0075         (size >= 33 && memcmp(buf + 30, u.start_code_prefix, 3) == 0))
0076         return 30;
0077 
0078     if (size == 31 ||
0079         (size >= 34 && memcmp(buf + 31, u.start_code_prefix, 3) == 0))
0080         return 31;
0081 
0082     if (size == 32 ||
0083         (size >= 35 && memcmp(buf + 32, u.start_code_prefix, 3) == 0))
0084         return 32;
0085 
0086     return 0;
0087 }