coda-mpeg2.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Coda multi-standard codec IP - MPEG-2 helper functions
  4. *
  5. * Copyright (C) 2019 Pengutronix, Philipp Zabel
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/videodev2.h>
  9. #include "coda.h"
  10. int coda_mpeg2_profile(int profile_idc)
  11. {
  12. switch (profile_idc) {
  13. case 5:
  14. return V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE;
  15. case 4:
  16. return V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN;
  17. case 3:
  18. return V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE;
  19. case 2:
  20. return V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE;
  21. case 1:
  22. return V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH;
  23. default:
  24. return -EINVAL;
  25. }
  26. }
  27. int coda_mpeg2_level(int level_idc)
  28. {
  29. switch (level_idc) {
  30. case 10:
  31. return V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW;
  32. case 8:
  33. return V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN;
  34. case 6:
  35. return V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440;
  36. case 4:
  37. return V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH;
  38. default:
  39. return -EINVAL;
  40. }
  41. }
  42. /*
  43. * Check if the buffer starts with the MPEG-2 sequence header (with or without
  44. * quantization matrix) and extension header, for example:
  45. *
  46. * 00 00 01 b3 2d 01 e0 34 08 8b a3 81
  47. * 10 11 11 12 12 12 13 13 13 13 14 14 14 14 14 15
  48. * 15 15 15 15 15 16 16 16 16 16 16 16 17 17 17 17
  49. * 17 17 17 17 18 18 18 19 18 18 18 19 1a 1a 1a 1a
  50. * 19 1b 1b 1b 1b 1b 1c 1c 1c 1c 1e 1e 1e 1f 1f 21
  51. * 00 00 01 b5 14 8a 00 01 00 00
  52. *
  53. * or:
  54. *
  55. * 00 00 01 b3 08 00 40 15 ff ff e0 28
  56. * 00 00 01 b5 14 8a 00 01 00 00
  57. *
  58. * Returns the detected header size in bytes or 0.
  59. */
  60. u32 coda_mpeg2_parse_headers(struct coda_ctx *ctx, u8 *buf, u32 size)
  61. {
  62. static const u8 sequence_header_start[4] = { 0x00, 0x00, 0x01, 0xb3 };
  63. static const union {
  64. u8 extension_start[4];
  65. u8 start_code_prefix[3];
  66. } u = { { 0x00, 0x00, 0x01, 0xb5 } };
  67. if (size < 22 ||
  68. memcmp(buf, sequence_header_start, 4) != 0)
  69. return 0;
  70. if ((size == 22 ||
  71. (size >= 25 && memcmp(buf + 22, u.start_code_prefix, 3) == 0)) &&
  72. memcmp(buf + 12, u.extension_start, 4) == 0)
  73. return 22;
  74. if ((size == 86 ||
  75. (size > 89 && memcmp(buf + 86, u.start_code_prefix, 3) == 0)) &&
  76. memcmp(buf + 76, u.extension_start, 4) == 0)
  77. return 86;
  78. return 0;
  79. }