diff --git a/host_applications/linux/apps/hello_pi/hello_encode/encode.c b/host_applications/linux/apps/hello_pi/hello_encode/encode.c index 7acb54b5f..0f2a95a5a 100644 --- a/host_applications/linux/apps/hello_pi/hello_encode/encode.c +++ b/host_applications/linux/apps/hello_pi/hello_encode/encode.c @@ -38,34 +38,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define NUMFRAMES 300 #define WIDTH 640 -#define PITCH ((WIDTH+31)&~31) #define HEIGHT ((WIDTH)*9/16) -#define HEIGHT16 ((HEIGHT+15)&~15) -#define SIZE ((WIDTH * HEIGHT16 * 3)/2) // generate an animated test card in YUV format static int -generate_test_card(void *buf, OMX_U32 * filledLen, int frame) +generate_test_card(void *buf, OMX_U32 * filledLen, int frame, OMX_PARAM_PORTDEFINITIONTYPE *def) { int i, j; - char *y = buf, *u = y + PITCH * HEIGHT16, *v = - u + (PITCH >> 1) * (HEIGHT16 >> 1); - - for (j = 0; j < HEIGHT / 2; j++) { - char *py = y + 2 * j * PITCH; - char *pu = u + j * (PITCH >> 1); - char *pv = v + j * (PITCH >> 1); - for (i = 0; i < WIDTH / 2; i++) { - int z = (((i + frame) >> 4) ^ ((j + frame) >> 4)) & 15; - py[0] = py[1] = py[PITCH] = py[PITCH + 1] = 0x80 + z * 0x8; - pu[0] = 0x00 + z * 0x10; - pv[0] = 0x80 + z * 0x30; - py += 2; - pu++; - pv++; + OMX_VIDEO_PORTDEFINITIONTYPE *vid = &def->format.video; + char *y = buf; + char *u = y + vid->nStride * vid->nSliceHeight; + char *v = u + (vid->nStride >> 1) * (vid->nSliceHeight >> 1); + + for (j = 0; j < vid->nFrameHeight / 2; j++) { + char *py = y + 2 * j * vid->nStride; + char *pu = u + j * (vid->nStride >> 1); + char *pv = v + j * (vid->nStride >> 1); + for (i = 0; i < vid->nFrameWidth / 2; i++) { + int z = (((i + frame) >> 4) ^ ((j + frame) >> 4)) & 15; + py[0] = py[1] = py[vid->nStride] = py[vid->nStride + 1] = 0x80 + z * 0x8; + pu[0] = 0x00 + z * 0x10; + pv[0] = 0x80 + z * 0x30; + py += 2; + pu++; + pv++; } } - *filledLen = SIZE; + *filledLen = (vid->nStride * vid->nSliceHeight * 3) >> 1; return 1; } @@ -73,20 +72,20 @@ static void print_def(OMX_PARAM_PORTDEFINITIONTYPE def) { printf("Port %u: %s %u/%u %u %u %s,%s,%s %ux%u %ux%u @%u %u\n", - def.nPortIndex, - def.eDir == OMX_DirInput ? "in" : "out", - def.nBufferCountActual, - def.nBufferCountMin, - def.nBufferSize, - def.nBufferAlignment, - def.bEnabled ? "enabled" : "disabled", - def.bPopulated ? "populated" : "not pop.", - def.bBuffersContiguous ? "contig." : "not cont.", - def.format.video.nFrameWidth, - def.format.video.nFrameHeight, - def.format.video.nStride, - def.format.video.nSliceHeight, - def.format.video.xFramerate, def.format.video.eColorFormat); + def.nPortIndex, + def.eDir == OMX_DirInput ? "in" : "out", + def.nBufferCountActual, + def.nBufferCountMin, + def.nBufferSize, + def.nBufferAlignment, + def.bEnabled ? "enabled" : "disabled", + def.bPopulated ? "populated" : "not pop.", + def.bBuffersContiguous ? "contig." : "not cont.", + def.format.video.nFrameWidth, + def.format.video.nFrameHeight, + def.format.video.nStride, + def.format.video.nSliceHeight, + def.format.video.xFramerate, def.format.video.eColorFormat); } static int @@ -117,13 +116,13 @@ video_encode_test(char *outputfilename) // create video_encode r = ilclient_create_component(client, &video_encode, "video_encode", - ILCLIENT_DISABLE_ALL_PORTS | - ILCLIENT_ENABLE_INPUT_BUFFERS | - ILCLIENT_ENABLE_OUTPUT_BUFFERS); + ILCLIENT_DISABLE_ALL_PORTS | + ILCLIENT_ENABLE_INPUT_BUFFERS | + ILCLIENT_ENABLE_OUTPUT_BUFFERS); if (r != 0) { printf - ("ilclient_create_component() for video_encode failed with %x!\n", - r); + ("ilclient_create_component() for video_encode failed with %x!\n", + r); exit(1); } list[0] = video_encode; @@ -136,9 +135,9 @@ video_encode_test(char *outputfilename) if (OMX_GetParameter (ILC_GET_HANDLE(video_encode), OMX_IndexParamPortDefinition, - &def) != OMX_ErrorNone) { + &def) != OMX_ErrorNone) { printf("%s:%d: OMX_GetParameter() for video_encode port 200 failed!\n", - __FUNCTION__, __LINE__); + __FUNCTION__, __LINE__); exit(1); } @@ -148,18 +147,18 @@ video_encode_test(char *outputfilename) def.format.video.nFrameWidth = WIDTH; def.format.video.nFrameHeight = HEIGHT; def.format.video.xFramerate = 30 << 16; - def.format.video.nSliceHeight = def.format.video.nFrameHeight; + def.format.video.nSliceHeight = ALIGN_UP(def.format.video.nFrameHeight, 16); def.format.video.nStride = def.format.video.nFrameWidth; def.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar; print_def(def); r = OMX_SetParameter(ILC_GET_HANDLE(video_encode), - OMX_IndexParamPortDefinition, &def); + OMX_IndexParamPortDefinition, &def); if (r != OMX_ErrorNone) { printf - ("%s:%d: OMX_SetParameter() for video_encode port 200 failed with %x!\n", - __FUNCTION__, __LINE__, r); + ("%s:%d: OMX_SetParameter() for video_encode port 200 failed with %x!\n", + __FUNCTION__, __LINE__, r); exit(1); } @@ -171,11 +170,11 @@ video_encode_test(char *outputfilename) printf("OMX_SetParameter for video_encode:201...\n"); r = OMX_SetParameter(ILC_GET_HANDLE(video_encode), - OMX_IndexParamVideoPortFormat, &format); + OMX_IndexParamVideoPortFormat, &format); if (r != OMX_ErrorNone) { printf - ("%s:%d: OMX_SetParameter() for video_encode port 201 failed with %x!\n", - __FUNCTION__, __LINE__, r); + ("%s:%d: OMX_SetParameter() for video_encode port 201 failed with %x!\n", + __FUNCTION__, __LINE__, r); exit(1); } @@ -217,8 +216,8 @@ video_encode_test(char *outputfilename) printf("encode to idle...\n"); if (ilclient_change_component_state(video_encode, OMX_StateIdle) == -1) { printf - ("%s:%d: ilclient_change_component_state(video_encode, OMX_StateIdle) failed", - __FUNCTION__, __LINE__); + ("%s:%d: ilclient_change_component_state(video_encode, OMX_StateIdle) failed", + __FUNCTION__, __LINE__); } printf("enabling port buffers for 200...\n"); @@ -246,45 +245,41 @@ video_encode_test(char *outputfilename) do { buf = ilclient_get_input_buffer(video_encode, 200, 1); if (buf == NULL) { - printf("Doh, no buffers for me!\n"); - } - else { - /* fill it */ - generate_test_card(buf->pBuffer, &buf->nFilledLen, framenumber++); - - if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_encode), buf) != - OMX_ErrorNone) { - printf("Error emptying buffer!\n"); - } - - out = ilclient_get_output_buffer(video_encode, 201, 1); - - r = OMX_FillThisBuffer(ILC_GET_HANDLE(video_encode), out); - if (r != OMX_ErrorNone) { - printf("Error filling buffer: %x\n", r); - } - - if (out != NULL) { - if (out->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { - int i; - for (i = 0; i < out->nFilledLen; i++) - printf("%x ", out->pBuffer[i]); - printf("\n"); - } - - r = fwrite(out->pBuffer, 1, out->nFilledLen, outf); - if (r != out->nFilledLen) { - printf("fwrite: Error emptying buffer: %d!\n", r); - } - else { - printf("Writing frame %d/%d\n", framenumber, NUMFRAMES); - } - out->nFilledLen = 0; - } - else { - printf("Not getting it :(\n"); - } - + printf("Doh, no buffers for me!\n"); + } else { + /* fill it */ + generate_test_card(buf->pBuffer, &buf->nFilledLen, framenumber++, &def); + + if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_encode), buf) != + OMX_ErrorNone) { + printf("Error emptying buffer!\n"); + } + + out = ilclient_get_output_buffer(video_encode, 201, 1); + + if (out != NULL) { + if (out->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + int i; + for (i = 0; i < out->nFilledLen; i++) + printf("%x ", out->pBuffer[i]); + printf("\n"); + } + + r = fwrite(out->pBuffer, 1, out->nFilledLen, outf); + if (r != out->nFilledLen) { + printf("fwrite: Error emptying buffer: %d!\n", r); + } else { + printf("Writing frame %d/%d, len %u\n", framenumber, NUMFRAMES, out->nFilledLen); + } + out->nFilledLen = 0; + } else { + printf("Not getting it :(\n"); + } + + r = OMX_FillThisBuffer(ILC_GET_HANDLE(video_encode), out); + if (r != OMX_ErrorNone) { + printf("Error sending buffer for filling: %x\n", r); + } } } while (framenumber < NUMFRAMES); diff --git a/host_applications/linux/apps/raspicam/RaspiCamControl.c b/host_applications/linux/apps/raspicam/RaspiCamControl.c index 8dd9b7b42..77351c436 100755 --- a/host_applications/linux/apps/raspicam/RaspiCamControl.c +++ b/host_applications/linux/apps/raspicam/RaspiCamControl.c @@ -203,7 +203,7 @@ static COMMAND_LIST cmdline_commands[] = {CommandStereoMode, "-stereo", "3d", "Select stereoscopic mode", 1}, {CommandStereoDecimate,"-decimate","dec", "Half width/height of stereo image"}, {CommandStereoSwap, "-3dswap", "3dswap", "Swap camera order for stereoscopic"}, - {CommandAnnotateExtras,"-annotateex","ae", "Set extra annotation parameters (text size, text colour(hex YUV), bg colour(hex YUV))", 2}, + {CommandAnnotateExtras,"-annotateex","ae", "Set extra annotation parameters (text size, text colour(hex YUV), bg colour(hex YUV), justify, x, y)", 2}, {CommandAnalogGain, "-analoggain", "ag", "Set the analog gain (floating point)", 1}, {CommandDigitalGain, "-digitalgain", "dg", "Set the digital gain (floating point)", 1}, }; @@ -772,9 +772,13 @@ int raspicamcontrol_parse_cmdline(RASPICAM_CAMERA_PARAMETERS *params, const char case CommandAnnotateExtras: { // 3 parameters - text size (6-80), text colour (Hex VVUUYY) and background colour (Hex VVUUYY) - sscanf(arg2, "%u,%X,%X", ¶ms->annotate_text_size, + sscanf(arg2, "%u,%X,%X,%u,%u,%u", ¶ms->annotate_text_size, ¶ms->annotate_text_colour, - ¶ms->annotate_bg_colour); + ¶ms->annotate_bg_colour, + ¶ms->annotate_justify, + ¶ms->annotate_x, + ¶ms->annotate_y + ); used=2; break; } @@ -1065,7 +1069,11 @@ int raspicamcontrol_set_all_parameters(MMAL_COMPONENT_T *camera, const RASPICAM_ result += raspicamcontrol_set_annotate(camera, params->enable_annotate, params->annotate_string, params->annotate_text_size, params->annotate_text_colour, - params->annotate_bg_colour); + params->annotate_bg_colour, + params->annotate_justify, + params->annotate_x, + params->annotate_y + ); result += raspicamcontrol_set_gains(camera, params->analog_gain, params->digital_gain); return result; @@ -1594,16 +1602,17 @@ int raspicamcontrol_set_stats_pass(MMAL_COMPONENT_T *camera, int stats_pass) * @return 0 if successful, non-zero if any parameters out of range */ int raspicamcontrol_set_annotate(MMAL_COMPONENT_T *camera, const int settings, const char *string, - const int text_size, const int text_colour, const int bg_colour) + const int text_size, const int text_colour, const int bg_colour, + const unsigned int justify, const unsigned int x, const unsigned int y) { - MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T annotate = - {{MMAL_PARAMETER_ANNOTATE, sizeof(MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T)}}; + MMAL_PARAMETER_CAMERA_ANNOTATE_V4_T annotate = + {{MMAL_PARAMETER_ANNOTATE, sizeof(MMAL_PARAMETER_CAMERA_ANNOTATE_V4_T)}}; if (settings) { time_t t = time(NULL); struct tm tm = *localtime(&t); - char tmp[MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V3]; + char tmp[MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V4]; int process_datetime = 1; annotate.enable = 1; @@ -1682,6 +1691,10 @@ int raspicamcontrol_set_annotate(MMAL_COMPONENT_T *camera, const int settings, c } else annotate.custom_background_colour = MMAL_FALSE; + + annotate.justify = justify; + annotate.x_offset = x; + annotate.y_offset = y; } else annotate.enable = 0; diff --git a/host_applications/linux/apps/raspicam/RaspiCamControl.h b/host_applications/linux/apps/raspicam/RaspiCamControl.h index 0286d9ff9..c06c539c2 100644 --- a/host_applications/linux/apps/raspicam/RaspiCamControl.h +++ b/host_applications/linux/apps/raspicam/RaspiCamControl.h @@ -163,6 +163,10 @@ typedef struct raspicam_camera_parameters_s int annotate_text_size; // Text size for annotation int annotate_text_colour; // Text colour for annotation int annotate_bg_colour; // Background colour for annotation + unsigned int annotate_justify; + unsigned int annotate_x; + unsigned int annotate_y; + MMAL_PARAMETER_STEREOSCOPIC_MODE_T stereo_mode; float analog_gain; // Analog gain float digital_gain; // Digital gain @@ -210,7 +214,8 @@ int raspicamcontrol_set_shutter_speed(MMAL_COMPONENT_T *camera, int speed_ms); int raspicamcontrol_set_DRC(MMAL_COMPONENT_T *camera, MMAL_PARAMETER_DRC_STRENGTH_T strength); int raspicamcontrol_set_stats_pass(MMAL_COMPONENT_T *camera, int stats_pass); int raspicamcontrol_set_annotate(MMAL_COMPONENT_T *camera, const int bitmask, const char *string, - const int text_size, const int text_colour, const int bg_colour); + const int text_size, const int text_colour, const int bg_colour, + const unsigned int justify, const unsigned int x, const unsigned int y); int raspicamcontrol_set_stereo_mode(MMAL_PORT_T *port, MMAL_PARAMETER_STEREOSCOPIC_MODE_T *stereo_mode); int raspicamcontrol_set_gains(MMAL_COMPONENT_T *camera, float analog, float digital); diff --git a/host_applications/linux/apps/raspicam/RaspiStill.c b/host_applications/linux/apps/raspicam/RaspiStill.c index d980c75be..f4f7526dd 100644 --- a/host_applications/linux/apps/raspicam/RaspiStill.c +++ b/host_applications/linux/apps/raspicam/RaspiStill.c @@ -2065,7 +2065,11 @@ int main(int argc, const char **argv) state.camera_parameters.annotate_string, state.camera_parameters.annotate_text_size, state.camera_parameters.annotate_text_colour, - state.camera_parameters.annotate_bg_colour); + state.camera_parameters.annotate_bg_colour, + state.camera_parameters.annotate_justify, + state.camera_parameters.annotate_x, + state.camera_parameters.annotate_y + ); if (state.verbose) fprintf(stderr, "Starting capture %d\n", frame); diff --git a/host_applications/linux/apps/raspicam/RaspiVid.c b/host_applications/linux/apps/raspicam/RaspiVid.c index 6340e13e6..0352cbde8 100755 --- a/host_applications/linux/apps/raspicam/RaspiVid.c +++ b/host_applications/linux/apps/raspicam/RaspiVid.c @@ -1258,7 +1258,11 @@ static void update_annotation_data(RASPIVID_STATE *state) raspicamcontrol_set_annotate(state->camera_component, state->camera_parameters.enable_annotate, text, state->camera_parameters.annotate_text_size, state->camera_parameters.annotate_text_colour, - state->camera_parameters.annotate_bg_colour); + state->camera_parameters.annotate_bg_colour, + state->camera_parameters.annotate_justify, + state->camera_parameters.annotate_x, + state->camera_parameters.annotate_y + ); free(text); } @@ -1267,7 +1271,11 @@ static void update_annotation_data(RASPIVID_STATE *state) raspicamcontrol_set_annotate(state->camera_component, state->camera_parameters.enable_annotate, state->camera_parameters.annotate_string, state->camera_parameters.annotate_text_size, state->camera_parameters.annotate_text_colour, - state->camera_parameters.annotate_bg_colour); + state->camera_parameters.annotate_bg_colour, + state->camera_parameters.annotate_justify, + state->camera_parameters.annotate_x, + state->camera_parameters.annotate_y + ); } } diff --git a/interface/mmal/mmal_parameters_camera.h b/interface/mmal/mmal_parameters_camera.h index 8a8857107..577b7a2cd 100644 --- a/interface/mmal/mmal_parameters_camera.h +++ b/interface/mmal/mmal_parameters_camera.h @@ -782,6 +782,35 @@ typedef struct MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T char text[MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V3]; } MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T; +#define MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V4 256 +typedef struct MMAL_PARAMETER_CAMERA_ANNOTATE_V4_T +{ + MMAL_PARAMETER_HEADER_T hdr; + + MMAL_BOOL_T enable; + MMAL_BOOL_T show_shutter; + MMAL_BOOL_T show_analog_gain; + MMAL_BOOL_T show_lens; + MMAL_BOOL_T show_caf; + MMAL_BOOL_T show_motion; + MMAL_BOOL_T show_frame_num; + MMAL_BOOL_T enable_text_background; + MMAL_BOOL_T custom_background_colour; + uint8_t custom_background_Y; + uint8_t custom_background_U; + uint8_t custom_background_V; + uint8_t dummy1; + MMAL_BOOL_T custom_text_colour; + uint8_t custom_text_Y; + uint8_t custom_text_U; + uint8_t custom_text_V; + uint8_t text_size; + char text[MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V3]; + uint32_t justify; //0=centre, 1=left, 2=right + uint32_t x_offset; //Offset from the justification edge + uint32_t y_offset; +} MMAL_PARAMETER_CAMERA_ANNOTATE_V4_T; + typedef enum MMAL_STEREOSCOPIC_MODE_T { MMAL_STEREOSCOPIC_MODE_NONE = 0, MMAL_STEREOSCOPIC_MODE_SIDE_BY_SIDE = 1,