├── .gitignore ├── ingenic ├── include └── custom.c ├── hisilicon ├── include └── custom.c ├── sigmastar ├── include └── custom.c ├── Makefile ├── .gitmodules ├── plugin.h ├── plugin.c ├── README.md └── LICENSE.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.sh 2 | *.so 3 | -------------------------------------------------------------------------------- /ingenic/include: -------------------------------------------------------------------------------- 1 | ../submodule/capjpeg/include -------------------------------------------------------------------------------- /hisilicon/include: -------------------------------------------------------------------------------- 1 | ../submodule/glutinium/hisi-osdrv4/include -------------------------------------------------------------------------------- /sigmastar/include: -------------------------------------------------------------------------------- 1 | ../submodule/glutinium/sigmastar-osdrv-ssc335/include -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCE := $(shell ls *.c $(TARGET)/*.c) 2 | 3 | $(TARGET): 4 | $(CC) $(SOURCE) -I. -I$@/include -o $@.so -Os -s -shared -fPIC 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodule/capjpeg"] 2 | path = submodule/capjpeg 3 | url = https://github.com/openipc/capjpeg.git 4 | [submodule "submodule/glutinium"] 5 | path = submodule/glutinium 6 | url = https://github.com/zigfisher/glutinium.git 7 | -------------------------------------------------------------------------------- /plugin.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define RETURN(f, ...) snprintf(common.buffer, sizeof(common.buffer), f, ##__VA_ARGS__); return 8 | 9 | typedef struct { 10 | const char *cmd; 11 | void (*func)(const char *); 12 | } table; 13 | 14 | typedef struct { 15 | char buffer[512]; 16 | table *list; 17 | int size; 18 | } config; 19 | 20 | extern config common; 21 | void get_usage(); 22 | -------------------------------------------------------------------------------- /plugin.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void get_usage() { 4 | int sum = sprintf(common.buffer, "Usage:"); 5 | for (int i = 0; i < common.size; i++) { 6 | sum += snprintf(common.buffer + sum, 7 | sizeof(common.buffer) - sum, " %s", common.list[i].cmd); 8 | } 9 | } 10 | 11 | char *plugin_call(const char *command, const char *value) { 12 | for (int i = 0; i < common.size; i++) { 13 | if (strstr(command, common.list[i].cmd)) { 14 | common.list[i].func(value); 15 | break; 16 | } 17 | } 18 | 19 | return common.buffer; 20 | } 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![OpenIPC logo][logo] 2 | 3 | ## Majestic plugins for OpenIPC 4 | **_Experimental system for creating open source plugins for Majestic_** 5 | 6 | ### Important information: 7 | - At the moment, examples of plugins have been implemented [only][only] for the most [popular][popular] processors today. 8 | - Nothing prevents everyone and enthusiasts from adding them to other processors and actively developing them. 9 | - By default, the plugin system is disabled and does not contribute any actions to the main operation of the device. 10 | 11 | --- 12 | 13 | ### Example function: 14 | - New functions can be added to `vendor/custom.c` 15 | - RETURN is a macro to simplify the plugin response output. 16 | ``` 17 | static void get_example(const char *value) { 18 | RETURN("plugin get_example: %s", value); 19 | } 20 | 21 | static table custom[] = { 22 | [...] 23 | { "example", &get_example }, 24 | }; 25 | ``` 26 | 27 | ### Example result: 28 | 29 | ``` 30 | root@openipc-ssc337de:~# echo example test123 | nc localhost 4000 31 | plugin get_example: test123 32 | ``` 33 | 34 | --- 35 | 36 | ### Prepare source: 37 | ``` 38 | git clone https://github.com/OpenIPC/firmware --depth 1 39 | cd firmware 40 | ``` 41 | 42 | ### Build usage: 43 | ``` 44 | - Hisilicon: 45 | make br-majestic-plugins-rebuild BOARD=hi3516ev300_lite 46 | 47 | - Goke: 48 | make br-majestic-plugins-rebuild BOARD=gk7202v300_lite 49 | 50 | - Ingenic: 51 | make br-majestic-plugins-rebuild BOARD=t31_lite 52 | 53 | - Sigmastar: 54 | make br-majestic-plugins-rebuild BOARD=ssc335_lite 55 | ``` 56 | 57 | ### Upload file: 58 | ``` 59 | scp -O output/build/majestic-plugins-master/*.so root@192.168.1.10:/usr/lib 60 | ``` 61 | 62 | --- 63 | 64 | ### Activate plugin support: 65 | ``` 66 | ssh root@192.168.1.10 67 | cli -s .system.plugins true 68 | killall -1 majestic 69 | ``` 70 | 71 | ### Send local command: 72 | ``` 73 | echo brightness 100 | nc localhost 4000 74 | ``` 75 | 76 | ### Send remote command: 77 | ``` 78 | echo -e '#!/usr/bin/haserl\nServer: $SERVER_SOFTWARE\nCache-Control: no-store\n\n<% echo $(echo $GET_cmd $GET_val | nc localhost 4000) %>' > /var/www/cgi-bin/plugins.cgi 79 | chmod 755 /var/www/cgi-bin/plugins.cgi 80 | ``` 81 | - http://192.168.1.10/cgi-bin/plugins.cgi?cmd=brightness&val=100 82 | 83 | [logo]: https://openipc.org/assets/openipc-logo-black.svg 84 | [only]: https://github.com/OpenIPC/firmware/blob/1a39728b88f2359a75069082caf7f62367f96f6a/general/package/majestic/majestic.mk#L15 85 | [popular]: https://openipc.org/supported-hardware/featured 86 | -------------------------------------------------------------------------------- /hisilicon/custom.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static void set_blackwhite(const char *value) { 9 | bool index = strlen(value) ? atoi(value) : false; 10 | 11 | VENC_CHN_PARAM_S param; 12 | if (HI_MPI_VENC_GetChnParam(0, ¶m)) { 13 | RETURN("HI_MPI_VENC_GetChnParam failed"); 14 | } 15 | 16 | param.bColor2Grey = index; 17 | if (HI_MPI_VENC_SetChnParam(0, ¶m)) { 18 | RETURN("HI_MPI_VENC_SetChnParam failed"); 19 | } 20 | 21 | RETURN("Set blackwhite: %d", index); 22 | } 23 | 24 | static void set_brightness(const char *value) { 25 | ISP_CSC_ATTR_S attr; 26 | if (HI_MPI_ISP_GetCSCAttr(0, &attr)) { 27 | RETURN("HI_MPI_ISP_GetCSCAttr failed"); 28 | } 29 | 30 | if (!strlen(value)) { 31 | RETURN("Get brightness: %d", attr.u8Luma); 32 | } 33 | 34 | int index = atoi(value); 35 | attr.u8Luma = index; 36 | 37 | if (HI_MPI_ISP_SetCSCAttr(0, &attr)) { 38 | RETURN("HI_MPI_ISP_SetCSCAttr failed"); 39 | } 40 | 41 | RETURN("Set brightness: %d", index); 42 | } 43 | 44 | static void set_contrast(const char *value) { 45 | ISP_CSC_ATTR_S attr; 46 | if (HI_MPI_ISP_GetCSCAttr(0, &attr)) { 47 | RETURN("HI_MPI_ISP_GetCSCAttr failed"); 48 | } 49 | 50 | if (!strlen(value)) { 51 | RETURN("Get contrast: %d", attr.u8Contr); 52 | } 53 | 54 | int index = atoi(value); 55 | attr.u8Contr = index; 56 | 57 | if (HI_MPI_ISP_SetCSCAttr(0, &attr)) { 58 | RETURN("HI_MPI_ISP_SetCSCAttr failed"); 59 | } 60 | 61 | RETURN("Set contrast: %d", index); 62 | } 63 | 64 | static void set_rotation(const char *value) { 65 | int index = strlen(value) ? atoi(value) : -1; 66 | 67 | VPSS_CHN_ATTR_S attr; 68 | if (HI_MPI_VPSS_GetChnAttr(0, 0, &attr)) { 69 | RETURN("HI_MPI_VPSS_GetChnAttr failed"); 70 | } 71 | 72 | switch (index) { 73 | case 0: 74 | attr.bMirror = false; 75 | attr.bFlip = false; 76 | break; 77 | 78 | case 1: 79 | attr.bMirror = true; 80 | attr.bFlip = false; 81 | break; 82 | 83 | case 2: 84 | attr.bMirror = false; 85 | attr.bFlip = true; 86 | break; 87 | 88 | case 3: 89 | attr.bMirror = true; 90 | attr.bFlip = true; 91 | break; 92 | 93 | default: 94 | RETURN("Unknown rotation: %d", index); 95 | } 96 | 97 | if (HI_MPI_VPSS_SetChnAttr(0, 0, &attr)) { 98 | RETURN("HI_MPI_VPSS_SetChnAttr failed"); 99 | } 100 | 101 | RETURN("Set rotation: %d", index); 102 | } 103 | 104 | static void get_version() { 105 | MPP_VERSION_S version; 106 | if (HI_MPI_SYS_GetVersion(&version)) { 107 | RETURN("HI_MPI_SYS_GetVersion failed"); 108 | } 109 | 110 | RETURN("%s", version.aVersion); 111 | } 112 | 113 | static table custom[] = { 114 | { "blackwhite", &set_blackwhite }, 115 | { "brightness", &set_brightness }, 116 | { "contrast", &set_contrast }, 117 | { "rotation", &set_rotation }, 118 | { "version", &get_version }, 119 | { "help", &get_usage }, 120 | }; 121 | 122 | config common = { 123 | .list = custom, 124 | .size = sizeof(custom) / sizeof(table), 125 | }; 126 | -------------------------------------------------------------------------------- /sigmastar/custom.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static void set_blackwhite(const char *value) { 8 | bool index = strlen(value) ? atoi(value) : false; 9 | 10 | MI_ISP_IQ_COLORTOGRAY_TYPE_t color; 11 | color.bEnable = index; 12 | 13 | if (MI_ISP_IQ_SetColorToGray(0, &color)) { 14 | RETURN("MI_ISP_IQ_SetColorToGray failed"); 15 | } 16 | 17 | RETURN("Set blackwhite: %d", index); 18 | } 19 | 20 | static void set_brightness(const char *value) { 21 | MI_ISP_IQ_BRIGHTNESS_TYPE_t brightness; 22 | if (MI_ISP_IQ_GetBrightness(0, &brightness)) { 23 | RETURN("MI_ISP_IQ_GetBrightness failed"); 24 | } 25 | 26 | if (!strlen(value)) { 27 | RETURN("Get brightness: %d", brightness.stManual.stParaAPI.u32Lev); 28 | } 29 | 30 | int index = atoi(value); 31 | brightness.bEnable = SS_TRUE; 32 | brightness.enOpType = SS_OP_TYP_MANUAL; 33 | brightness.stManual.stParaAPI.u32Lev = index; 34 | 35 | if (MI_ISP_IQ_SetBrightness(0, &brightness)) { 36 | RETURN("MI_ISP_IQ_SetBrightness failed"); 37 | } 38 | 39 | RETURN("Set brightness: %d", index); 40 | } 41 | 42 | static void set_contrast(const char *value) { 43 | MI_ISP_IQ_CONTRAST_TYPE_t contrast; 44 | if (MI_ISP_IQ_GetContrast(0, &contrast)) { 45 | RETURN("MI_ISP_IQ_GetContrast failed"); 46 | } 47 | 48 | if (!strlen(value)) { 49 | RETURN("Get contrast: %d", contrast.stManual.stParaAPI.u32Lev); 50 | } 51 | 52 | int index = atoi(value); 53 | contrast.bEnable = SS_TRUE; 54 | contrast.enOpType = SS_OP_TYP_MANUAL; 55 | contrast.stManual.stParaAPI.u32Lev = index; 56 | 57 | if (MI_ISP_IQ_SetContrast(0, &contrast)) { 58 | RETURN("MI_ISP_IQ_SetContrast failed"); 59 | } 60 | 61 | RETURN("Set contrast: %d", index); 62 | } 63 | 64 | static void set_rotation(const char *value) { 65 | int index = strlen(value) ? atoi(value) : -1; 66 | bool mirror, flip; 67 | 68 | switch (index) { 69 | case 0: 70 | mirror = false; 71 | flip = false; 72 | break; 73 | 74 | case 1: 75 | mirror = true; 76 | flip = false; 77 | break; 78 | 79 | case 2: 80 | mirror = false; 81 | flip = true; 82 | break; 83 | 84 | case 3: 85 | mirror = true; 86 | flip = true; 87 | break; 88 | 89 | default: 90 | RETURN("Unknown rotation: %d", index); 91 | } 92 | 93 | if (MI_SNR_SetOrien(0, mirror, flip)) { 94 | RETURN("MI_SNR_SetOrien failed"); 95 | } 96 | 97 | RETURN("Set rotation: %d", index); 98 | } 99 | 100 | static void get_version() { 101 | MI_SYS_Version_t version; 102 | if (MI_SYS_GetVersion(&version)) { 103 | RETURN("MI_SYS_GetVersion failed"); 104 | } 105 | 106 | RETURN("%s", version.u8Version); 107 | } 108 | 109 | static table custom[] = { 110 | { "blackwhite", &set_blackwhite }, 111 | { "brightness", &set_brightness }, 112 | { "contrast", &set_contrast }, 113 | { "rotation", &set_rotation }, 114 | { "version", &get_version }, 115 | { "help", &get_usage }, 116 | }; 117 | 118 | config common = { 119 | .list = custom, 120 | .size = sizeof(custom) / sizeof(table), 121 | }; 122 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The Prosperity Public License 3.0.0 2 | 3 | Contributor: OpenIPC (c) 2025 4 | 5 | ## Purpose 6 | 7 | This license allows you to use and share this software for noncommercial purposes for free and to try this software for commercial purposes for thirty days. 8 | 9 | ## Agreement 10 | 11 | In order to receive this license, you have to agree to its rules. Those rules are both obligations under that agreement and conditions to your license. Don't do anything with this software that triggers a rule you can't or won't follow. 12 | 13 | ## Notices 14 | 15 | Make sure everyone who gets a copy of any part of this software from you, with or without changes, also gets the text of this license and the contributor and source code lines above. 16 | 17 | ## Commercial Trial 18 | 19 | Limit your use of this software for commercial purposes to a thirty-day trial period. If you use this software for work, your company gets one trial period for all personnel, not one trial per person. 20 | 21 | ## Contributions Back 22 | 23 | Developing feedback, changes, or additions that you contribute back to the contributor on the terms of a standardized public software license such as [the Blue Oak Model License 1.0.0](https://blueoakcouncil.org/license/1.0.0), [the Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0.html), [the MIT license](https://spdx.org/licenses/MIT.html), or [the two-clause BSD license](https://spdx.org/licenses/BSD-2-Clause.html) doesn't count as use for a commercial purpose. 24 | 25 | ## Personal Uses 26 | 27 | Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, doesn't count as use for a commercial purpose. 28 | 29 | ## Noncommercial Organizations 30 | 31 | Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution doesn't count as use for a commercial purpose regardless of the source of funding or obligations resulting from the funding. 32 | 33 | ## Defense 34 | 35 | Don't make any legal claim against anyone accusing this software, with or without changes, alone or with other technology, of infringing any patent. 36 | 37 | ## Copyright 38 | 39 | The contributor licenses you to do everything with this software that would otherwise infringe their copyright in it. 40 | 41 | ## Patent 42 | 43 | The contributor licenses you to do everything with this software that would otherwise infringe any patents they can license or become able to license. 44 | 45 | ## Reliability 46 | 47 | The contributor can't revoke this license. 48 | 49 | ## Excuse 50 | 51 | You're excused for unknowingly breaking [Notices](#notices) if you take all practical steps to comply within thirty days of learning you broke the rule. 52 | 53 | ## No Liability 54 | 55 | ***As far as the law allows, this software comes as is, without any warranty or condition, and the contributor won't be liable to anyone for any damages related to this software or this license, under any kind of legal claim.*** 56 | -------------------------------------------------------------------------------- /ingenic/custom.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static void set_blackwhite(const char *value) { 7 | bool index = strlen(value) ? atoi(value) : false; 8 | if (IMP_ISP_Tuning_SetISPRunningMode(index)) { 9 | RETURN("IMP_ISP_Tuning_SetISPRunningMode failed"); 10 | } 11 | 12 | RETURN("Set blackwhite: %d", index); 13 | } 14 | 15 | static void set_brightness(const char *value) { 16 | if (strlen(value)) { 17 | unsigned char index = atoi(value); 18 | if (IMP_ISP_Tuning_SetBrightness(index)) { 19 | RETURN("IMP_ISP_Tuning_SetBrightness failed"); 20 | } 21 | 22 | RETURN("Set brightness: %d", index); 23 | } else { 24 | unsigned char current; 25 | if (IMP_ISP_Tuning_GetBrightness(¤t)) { 26 | RETURN("IMP_ISP_Tuning_GetBrightness failed"); 27 | } 28 | 29 | RETURN("Get brightness: %d", current); 30 | } 31 | } 32 | 33 | static void set_contrast(const char *value) { 34 | if (strlen(value)) { 35 | unsigned char index = atoi(value); 36 | if (IMP_ISP_Tuning_SetContrast(index)) { 37 | RETURN("IMP_ISP_Tuning_SetContrast failed"); 38 | } 39 | 40 | RETURN("Set contrast: %d", index); 41 | } else { 42 | unsigned char current; 43 | if (IMP_ISP_Tuning_GetContrast(¤t)) { 44 | RETURN("IMP_ISP_Tuning_GetContrast failed"); 45 | } 46 | 47 | RETURN("Get contrast: %d", current); 48 | } 49 | } 50 | 51 | static void set_rotation(const char *value) { 52 | int index = strlen(value) ? atoi(value) : -1; 53 | 54 | switch (index) { 55 | case 0: 56 | IMP_ISP_Tuning_SetISPHflip(0); 57 | IMP_ISP_Tuning_SetISPVflip(0); 58 | break; 59 | 60 | case 1: 61 | IMP_ISP_Tuning_SetISPHflip(1); 62 | IMP_ISP_Tuning_SetISPVflip(0); 63 | break; 64 | 65 | case 2: 66 | IMP_ISP_Tuning_SetISPHflip(0); 67 | IMP_ISP_Tuning_SetISPVflip(1); 68 | break; 69 | 70 | case 3: 71 | IMP_ISP_Tuning_SetISPHflip(1); 72 | IMP_ISP_Tuning_SetISPVflip(1); 73 | break; 74 | 75 | default: 76 | RETURN("Unknown rotation: %d", index); 77 | } 78 | 79 | RETURN("Set rotation: %d", index); 80 | } 81 | 82 | static void set_fps(const char *value) { 83 | uint32_t fps_den = 1; // Initialize fps_den to 1 by default 84 | if (strlen(value)) { 85 | unsigned char index = atoi(value); 86 | if (IMP_ISP_Tuning_SetSensorFPS(index, fps_den)) { 87 | RETURN("IMP_ISP_Tuning_SetSensorFPS failed"); 88 | } 89 | 90 | RETURN("Set fps: %d", index); 91 | } else { 92 | uint32_t current; 93 | if (IMP_ISP_Tuning_GetSensorFPS(¤t, &fps_den)) { 94 | RETURN("IMP_ISP_Tuning_GetSensorFPS failed"); 95 | } 96 | 97 | RETURN("Get fps: %d", current); 98 | } 99 | } 100 | 101 | static void set_aovol(const char *value) { 102 | if (strlen(value)) { 103 | unsigned char index = atoi(value); 104 | if (IMP_AO_SetVol(0, 0, index)) { 105 | RETURN("IMP_AO_SetVol failed"); 106 | } 107 | 108 | RETURN("Set aovol: %d", index); 109 | } else { 110 | int current; 111 | if (IMP_AO_GetVol(0, 0, ¤t)) { 112 | RETURN("IMP_AO_GetVol failed"); 113 | } 114 | 115 | RETURN("Get aovol: %d", current); 116 | } 117 | } 118 | 119 | static void get_version() { 120 | SUVersion version; 121 | if (SU_Base_GetVersion(&version)) { 122 | RETURN("SU_Base_GetVersion failed"); 123 | } 124 | 125 | RETURN("%s", version.chr); 126 | } 127 | 128 | static table custom[] = { 129 | { "blackwhite", &set_blackwhite }, 130 | { "brightness", &set_brightness }, 131 | { "contrast", &set_contrast }, 132 | { "rotation", &set_rotation }, 133 | { "fps", &set_fps }, 134 | { "aovol", &set_aovol }, 135 | { "version", &get_version }, 136 | { "help", &get_usage }, 137 | }; 138 | 139 | config common = { 140 | .list = custom, 141 | .size = sizeof(custom) / sizeof(table), 142 | }; 143 | --------------------------------------------------------------------------------