Hi,
I'm trying to use the psp application, capture_prev_rsz_on_the_fly on DM365 board, with RR SDK kernel. I have no display hw, so I removed that form the app.
I'm using CMEM and user_ptr buffers, and my sensor board is MT9P031.
With the capture part, 720x480 is works with 30FPS and I can save raw bayer images as well. With bigger resolutions (example 1920x1080), the framerate is 10FPS.
This is becouse in the SDK kernel patch the mt9p031 clock is set and fixed to 32Mhz. Is there any reason to not using the 96Mhz max?
When I enable the preview/resize part in the app, again with 720x480 I can save YUYV or NV12 YUV images, but in bigger resolutions, the app stops when
I try to DEQUEUE the buffer.In this resolutions I can get only images when I enable cropping.
Is there anybody, who can use this sample applications with bigger resolutions with RR SDK 2.6.18 kernel? Or is any idea what may be wrong with my setup.
(I tried the ipipe_aew_demo, it's the same)
I attach my app, any comment welcome.
Thanks
Andras
/* * capture_prev_rsz_onthe_fly_bayer - Capture from MT9T031, preview and resize * in on the fly mode * * This example shows how to do capture from MT9T031 and * do on the fly processing on the captured image such as IPIPE preview * Resize and format conversion. Here is the configuration of IP for * this usecase * * MT9T031 -> CCDC/ISIF ->IPIPEIF ->IPIPE->Resizer->SDRAM * * NOTE: This application requires CMEM * * In this mode, CCDC output is sent to IPIPE and Resizer. * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **/#include <stdio.h>#include <sys/types.h>#include <sys/ioctl.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/mman.h>#include <getopt.h>#include <sys/mman.h>#include <sys/time.h>#include <linux/videodev.h>#include <linux/videodev2.h>#include <media/davinci/mt9t001.h>#include <media/davinci/mt9p031.h>#include <media/davinci/mt9v034.h>#include <media/davinci/davinci_vpfe.h> #include <media/davinci/ccdc_dm365.h>#include <asm/arch/imp_previewer.h>#include <asm/arch/imp_resizer.h>#include <asm/arch/dm365_ipipe.h>#include "cmem.h"char dev_name_prev[1][30] = {"/dev/davinci_previewer"};char dev_name_rsz[1][30] = {"/dev/davinci_resizer"};#define APP_NUM_BUFS 3#define CAPTURE_DEVICE "/dev/video0"#define CLEAR(x) memset (&(x), 0, sizeof (x))/* 0 - UYVY, 1 - NV12 */#define CAMERA_INPUT_MT9T001 "RAW-1"#define MAX_STDS 11int max_stds = MAX_STDS;int regular_col_pat = 1;/* display 0 - output1 (RSZ_A)) or 1 - output2 (RSZ_B) from resizer */static int disp_second_output;/* second output width and height */static int second_out_width = 320;static int second_out_height = 240;int second_output_offset;struct capt_std_params { v4l2_std_id std; /* input image params */ unsigned int scan_width; unsigned int scan_height; /* crop params */ struct v4l2_rect crop; /* output image params */ unsigned int image_width; unsigned int image_height; char *name;}; struct capt_std_params mt9p031_std_params[MAX_STDS] = { { .std = V4L2_STD_MT9P031_VGA_30FPS, .scan_width = 640, .scan_height = 480, .crop = { 0 , 0, 640, 480}, .image_width = 720, .image_height = 480, .name = "V4L2_STD_MT9P031_VGA_30FPS", }, { .std = V4L2_STD_MT9P031_480p_30FPS, .scan_width = 720, .scan_height = 480, .crop = { 0 , 0, 720, 480}, .image_width = 720, .image_height = 480, .name = "V4L2_STD_MT9P031_480p_30FPS", }, { .std = V4L2_STD_MT9P031_576p_25FPS, .scan_width = 720, .scan_height = 576, .crop = { 0 , 0, 720, 576}, .image_width = 720, .image_height = 576, .name = "V4L2_STD_MT9P031_576p_25FPS", }, { .std = V4L2_STD_MT9P031_720p_60FPS, .scan_width = 1280, .scan_height = 720, .crop = { 0 , 0, 1280, 720}, .image_width = 1280, .image_height = 720, .name = "V4L2_STD_MT9P031_720p_60FPS", }, { .std = V4L2_STD_MT9P031_1080p_30FPS, .scan_width = 1920, .scan_height = 1080, .crop = { 0 , 0, 1920, 1080}, .image_width = 1920, .image_height = 1080, .name = "V4L2_STD_MT9P031_1080p_30FPS", }, { .std = V4L2_STD_MT9P031_1080p_25FPS, .scan_width = 1920, .scan_height = 1080, .crop = { 0 , 0, 1920, 1080}, .image_width = 1920, .image_height = 1080, .name = "V4L2_STD_MT9P031_1080p_25FPS", }, { .std = V4L2_STD_MT9P031_SXGA_30FPS, .scan_width = 1280, .scan_height = 1024, .crop = { 0 , 0, 1280, 1024}, .image_width = 1280, .image_height = 1024, .name = "V4L2_STD_MT9P031_SXGA_30FPS", }, { .std = V4L2_STD_MT9P031_UXGA_30FPS, .scan_width = 1600, .scan_height = 1200, .crop = { 0 , 0, 1600, 1200}, .image_width = 1600, .image_height = 1200, .name = "V4L2_STD_MT9P031_UXGA_30FPS", }, { .std = V4L2_STD_MT9P031_QXGA_15FPS, .scan_width = 2048, .scan_height = 1536, .crop = { 0 , 0, 2048, 1536}, .image_width = 2048, .image_height = 1536, .name = "V4L2_STD_MT9P031_QXGA_15FPS", },};/* used for indexing into above table */static unsigned int in_std; /* input std param for selected standard */struct capt_std_params input_std_params;unsigned char camera_input[20];int cam_input;struct app_buf_type { void *start; int offset; int length; int index;}; static int output_format;#define ALIGN(x, y) (((x + (y-1))/y)*y)int buf_size = ALIGN((1920*1080*2), 4096);struct buf_info { void *user_addr; unsigned long phy_addr;};struct buf_info capture_buffers[APP_NUM_BUFS];static int display_image_size;/* to enable gamma correction, enable this */static int gamma_flag;//enum ccdc_compress_alg compress_alg = CCDC_ALAW;//enum ccdc_compress_alg compress_alg = CCDC_DPCM;enum ccdc_compress_alg compress_alg = CCDC_NO_COMPRESSION;// flag to enable linearizationstatic int linearization_en;// flag to enable color space conversion// input sensor should output CMYG pattern instead of RGGB// to test this. This is currently just used for unit// test verificationstatic int csc_en;// vertical line defect correction enablestatic int vldfc_en;// enable culling// static int en_culling;static int en_culling;#define BYTESPERPIXEL 2static struct v4l2_rect crop_default = { 320, 240, 320, 240 };static int en_crop;static unsigned long long prev_ts;static unsigned long long curr_ts;static unsigned long fp_period_average;static unsigned long fp_period_max;static unsigned long fp_period_min;static unsigned long fp_period;void usage(){ printf("Usage:capture_prev_rsz_onthe_fly\n");}int init_resizer(unsigned int user_mode, int out_width, int out_height){ int rsz_fd; unsigned int oper_mode; struct rsz_channel_config rsz_chan_config; struct rsz_continuous_config rsz_cont_config; // continuous mode printf("opening resize device\n"); rsz_fd = open((const char *)dev_name_rsz[0], O_RDWR); if(rsz_fd <= 0) { printf("Cannot open resize device \n"); return -1; } if (ioctl(rsz_fd, RSZ_S_OPER_MODE, &user_mode) < 0) { perror("Can't get operation mode\n"); close(rsz_fd); return -1; } if (ioctl(rsz_fd, RSZ_G_OPER_MODE, &oper_mode) < 0) { perror("Can't get operation mode\n"); close(rsz_fd); return -1; } if (oper_mode == user_mode) printf("Successfully set mode to continuous in resizer\n"); else { printf("failed to set mode to continuous in resizer\n"); close(rsz_fd); return -1; } // set configuration to chain resizer with preview rsz_chan_config.oper_mode = user_mode; rsz_chan_config.chain = 1; rsz_chan_config.len = 0; rsz_chan_config.config = NULL; /* to set defaults in driver */ if (ioctl(rsz_fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { perror("Error in setting default configuration in resizer\n"); close(rsz_fd); return -1; } printf("default configuration setting in Resizer successfull\n"); bzero(&rsz_cont_config, sizeof(struct rsz_continuous_config)); rsz_chan_config.oper_mode = user_mode; rsz_chan_config.chain = 1; rsz_chan_config.len = sizeof(struct rsz_continuous_config); rsz_chan_config.config = &rsz_cont_config; if (ioctl(rsz_fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) { perror("Error in getting resizer channel configuration from driver\n"); close(rsz_fd); return -1; } // we can ignore the input spec since we are chaining. So only // set output specs rsz_cont_config.output1.enable = 1;/* if (disp_second_output) { rsz_cont_config.output2.enable = 1; rsz_cont_config.output2.width = second_out_width; rsz_cont_config.output2.height = second_out_height; if (output_format) rsz_cont_config.output2.pix_fmt = IPIPE_YUV420SP; else rsz_cont_config.output2.pix_fmt = IPIPE_UYVY; } else */ rsz_cont_config.output2.enable = 0;// rsz_cont_config.output1.h_flip = 1; rsz_chan_config.oper_mode = user_mode; rsz_chan_config.chain = 1; rsz_chan_config.len = sizeof(struct rsz_continuous_config); rsz_chan_config.config = &rsz_cont_config; if (ioctl(rsz_fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { perror("Error in setting configuration in resizer\n"); close(rsz_fd); return -1; } printf("Resizer initialized\n"); return rsz_fd;}int init_previewer(unsigned int user_mode, int in_format){ int preview_fd, ret; unsigned int oper_mode; struct prev_channel_config prev_chan_config; struct prev_continuous_config prev_cont_config; // continuous mode struct prev_cap cap; struct prev_module_param mod_param; struct prev_wb wb; struct prev_lum_adj lum_adj; struct prev_gamma gamma; preview_fd = open((const char *)dev_name_prev[0], O_RDWR); if(preview_fd <= 0) { printf("Cannot open previewer device\n"); return -1; } if (ioctl(preview_fd,PREV_S_OPER_MODE, &user_mode) < 0) { perror("Can't get operation mode\n"); close(preview_fd); return -1; } if (ioctl(preview_fd,PREV_G_OPER_MODE, &oper_mode) < 0) { perror("Can't get operation mode\n"); close(preview_fd); return -1; } if (oper_mode == user_mode) printf("Operating mode changed successfully to continuous in previewer"); else { printf("failed to set mode to continuous in resizer\n"); close(preview_fd); return -1; } printf("Setting default configuration in previewer\n"); prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = 0; prev_chan_config.config = NULL; /* to set defaults in driver */ if (ioctl(preview_fd, PREV_S_CONFIG, &prev_chan_config) < 0) { perror("Error in setting default configuration\n"); close(preview_fd); return -1; } printf("default configuration setting in previewer successfull\n"); prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = sizeof(struct prev_continuous_config); prev_chan_config.config = &prev_cont_config; if (ioctl(preview_fd, PREV_G_CONFIG, &prev_chan_config) < 0) { perror("Error in getting configuration from driver\n"); close(preview_fd); return -1; } prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = sizeof(struct prev_continuous_config); prev_chan_config.config = &prev_cont_config;/* Gr R B Gb*/ /* Some reason, MT9P031 color pattern is flipped horizontally * for some of the scan resolution */ if (regular_col_pat) { prev_cont_config.input.colp_elep= IPIPE_BLUE; prev_cont_config.input.colp_elop= IPIPE_GREEN_BLUE; prev_cont_config.input.colp_olep= IPIPE_GREEN_RED; prev_cont_config.input.colp_olop= IPIPE_RED; } else { prev_cont_config.input.colp_elep= IPIPE_GREEN_BLUE; prev_cont_config.input.colp_elop= IPIPE_BLUE; prev_cont_config.input.colp_olep= IPIPE_RED; prev_cont_config.input.colp_olop= IPIPE_GREEN_RED; } if (ioctl(preview_fd, PREV_S_CONFIG, &prev_chan_config) < 0) { perror("Error in setting default configuration\n"); close(preview_fd); return -1; } cap.index=0; while (1) { ret = ioctl(preview_fd , PREV_ENUM_CAP, &cap); if (ret < 0) { break; } // find the defaults for this module strcpy(mod_param.version,cap.version); mod_param.module_id = cap.module_id; // using defaults printf("Setting default for %s\n", cap.module_name); mod_param.param = NULL; if (ioctl(preview_fd, PREV_S_PARAM, &mod_param) < 0) { printf("Error in Setting %s params from driver\n", cap.module_name); close(preview_fd); return -1; } cap.index++; } printf("previewer initialized\n"); return preview_fd;}static int set_data_format(int fdCapture, v4l2_std_id std, int width, int height){ v4l2_std_id ipipe_std, cur_std; struct v4l2_format fmt; struct v4l2_input input; int ret; cur_std = ipipe_std = std; int found = 0; struct v4l2_standard stdinfo; struct v4l2_streamparm streamparam; struct v4l2_crop crop; printf("SetDataFormat:setting std to %d\n", (int)cur_std); // first set the input input.type = V4L2_INPUT_TYPE_CAMERA; input.index = 0; while (-EINVAL != ioctl(fdCapture, VIDIOC_ENUMINPUT, &input)) { printf("input.name = %s\n", input.name); if (!strcmp(input.name, camera_input)) break; input.index++; } if (-1 == ioctl (fdCapture, VIDIOC_S_INPUT, &input.index)) { perror("ioctl:VIDIOC_S_INPUT failed\n"); return -1; } printf ("InitDevice:ioctl:VIDIOC_S_INPUT, selected input\n"); printf("\nCalling configCCDCraw()\n"); ret = configCCDCraw(fdCapture, width, height); if (ret < 0) { perror("configCCDCraw"); return -1; } else { printf("\nconfigCCDCraw Done\n"); } if (-1 == ioctl(fdCapture, VIDIOC_S_STD, &cur_std)) { printf ("SetDataFormat:unable to set standard automatically\n"); return -1; } else printf("\nS_STD Done\n"); sleep(1); /* wait until device is fully locked */ cur_std = 0; if (-1 == ioctl(fdCapture, VIDIOC_G_STD, &cur_std)) { perror("SetDataFormat:ioctl:VIDIOC_G_STD:"); return -1; } else printf("\nGetSTD Done WITH std = %u\n", (int) cur_std); stdinfo.index = 0; found = 0; while ( 0 == ioctl(fdCapture, VIDIOC_ENUMSTD, &stdinfo)) { if (stdinfo.id == cur_std) { printf("Found the std information\n"); printf("stdinfo.name = %s\n",stdinfo.name); printf("stdinfo.frameperiod.numerator = %d\n", stdinfo.frameperiod.numerator); printf("stdinfo.frameperiod.denominator = %d\n", stdinfo.frameperiod.denominator); found = 1; break; } stdinfo.index++; } if (!found) { printf("Couldn't find the detected std information\n"); return -1; } printf("SetDataFormat:requesting width:%d height:%d\n", width, height); CLEAR(fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = width; fmt.fmt.pix.height = height;#if 0 if (compress_alg == CCDC_ALAW || compress_alg == CCDC_DPCM) { fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;// printf("Compression enabled\n"); } else {// printf("No Compression\n"); fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR16; }#endif// if (output_format) {// printf("Setting format to V4L2_PIX_FMT_NV12 at capture\n");// fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;// fmt.fmt.pix.bytesperline = width;// }// else { printf("Setting format to V4L2_PIX_FMT_UYVY at capture\n"); fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;// } fmt.fmt.pix.field = V4L2_FIELD_NONE; if (-1 == ioctl(fdCapture, VIDIOC_S_FMT, &fmt)) { perror("SetDataFormat:ioctl:VIDIOC_S_FMT"); return -1; } else printf("\nS_FMT Done\n");#if 0 if (half_fps) { /* set the streaming parameter */ CLEAR(streamparam); streamparam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; streamparam.parm.capture.timeperframe.numerator = stdinfo.frameperiod.numerator; streamparam.parm.capture.timeperframe.denominator = stdinfo.frameperiod.denominator/2; if (ioctl(fdCapture, VIDIOC_S_PARM , &streamparam) < 0 ) { perror("Error in VIDIOC_S_PARM\n"); return -1; } /* verify the params */ if (ioctl(fdCapture, VIDIOC_G_PARM, &streamparam) < 0) { perror("Error in VIDIOC_G_PARM\n"); return -1; } printf("VIDIOC_G_PARM: Got timeperframe.numerator = %d\n", streamparam.parm.capture.timeperframe.numerator); printf("VIDIOC_G_PARM: Got timeperframe.denominator = %d\n", streamparam.parm.capture.timeperframe.denominator); }#endif CLEAR(crop); if (en_crop) { printf("******Cropping the input @%d,%d,%d,%d***********\n", crop_default.top, crop_default.left, crop_default.width, crop_default.height); input_std_params.crop = crop_default; CLEAR(crop); crop.c = input_std_params.crop; crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl(fdCapture, VIDIOC_S_CROP, &crop)) { perror("set_data_format:ioctl:VIDIOC_S_CROP"); return -1; } else printf("\nS_CROP Done\n"); } return 0;}int configCCDCraw(int capt_fd, int width, int height){ struct ccdc_param raw_params; struct ccdc_module_params module_params; struct ccdc_bayer_config *cfg; /* Change these values for testing Gain - Offsets */ struct ccdc_float_16 r = {0, 511}; struct ccdc_float_16 gr = {0, 511}; struct ccdc_float_16 gb = {0, 511}; struct ccdc_float_16 b = {0, 511}; struct ccdc_float_8 csc_coef_val = { 1, 0 }; int i; cfg = &raw_params.cfg.bayer; raw_params.if_type = 0; raw_params.module_params = &module_params; if (-1 == ioctl(capt_fd, VPFE_CMD_G_CCDC_PARAMS, &raw_params)) { perror("InitDevice:ioctl:VPFE_CMD_G_CCDC_PARAMS"); return -1; }/* printf("pix_fmt = %d\n", cfg->pix_fmt); printf("frm_fmt = %d\n", cfg->frm_fmt); printf("fid_pol = %d\n", cfg->fid_pol); printf("vd_pol = %d\n", cfg->vd_pol); printf("hd_pol = %d\n", cfg->hd_pol); printf("data_size = %d\n", cfg->data_size); printf("data_shift = %d\n", cfg->data_shift); printf("test_pat_gen = %d\n", cfg->test_pat_gen); printf("win.width = %d\n", cfg->win.width); printf("win.height = %d\n", cfg->win.height); printf("module_params.culling.hcpat_odd = 0x%x\n",module_params.culling.hcpat_odd); printf("module_params.culling.hcpat_even = 0x%x\n",module_params.culling.hcpat_even); */ raw_params.if_type = 0; cfg->win.width = width; cfg->win.height = height; module_params.compress.alg = compress_alg; cfg->data_msb = CCDC_BIT_MSB_11; cfg->data_shift = CCDC_NO_SHIFT; module_params.gain_offset.gain.r_ye = r; module_params.gain_offset.gain.gr_cy = gr; module_params.gain_offset.gain.gb_g = gb; module_params.gain_offset.gain.b_mg = b; module_params.gain_offset.gain_sdram_en = 1; module_params.gain_offset.offset = 0; module_params.gain_offset.offset_sdram_en = 1; /* To test linearization, set this to 1, and update the * linearization table with correct data */ if (linearization_en) { module_params.linearize.en = 1; module_params.linearize.corr_shft = CCDC_1BIT_SHIFT; module_params.linearize.scale_fact.integer = 0; module_params.linearize.scale_fact.decimal = 10; for (i = 0; i < CCDC_LINEAR_TAB_SIZE; i++) module_params.linearize.table[i] = i; } else { module_params.linearize.en = 0; } /* CSC */ if (csc_en) { module_params.df_csc.df_or_csc = 0; module_params.df_csc.csc.en = 1; /* I am hardcoding this here. But this should * really match with that of the capture standard */ module_params.df_csc.start_pix = 1; module_params.df_csc.num_pixels = 720; module_params.df_csc.start_line = 1; module_params.df_csc.num_lines = 480; /* These are unit test values. For real case, use * correct values in this table */ module_params.df_csc.csc.coeff[0] = csc_coef_val; module_params.df_csc.csc.coeff[1].decimal = 1; module_params.df_csc.csc.coeff[2].decimal = 2; module_params.df_csc.csc.coeff[3].decimal = 3; module_params.df_csc.csc.coeff[4].decimal = 4; module_params.df_csc.csc.coeff[5].decimal = 5; module_params.df_csc.csc.coeff[6].decimal = 6; module_params.df_csc.csc.coeff[7].decimal = 7; module_params.df_csc.csc.coeff[8].decimal = 8; module_params.df_csc.csc.coeff[9].decimal = 9; module_params.df_csc.csc.coeff[10].decimal = 10; module_params.df_csc.csc.coeff[11].decimal = 11; module_params.df_csc.csc.coeff[12].decimal = 12; module_params.df_csc.csc.coeff[13].decimal = 13; module_params.df_csc.csc.coeff[14].decimal = 14; module_params.df_csc.csc.coeff[15].decimal = 15; } else { module_params.df_csc.df_or_csc = 0; module_params.df_csc.csc.en = 0; } /* vertical line defect correction */ if (vldfc_en) { module_params.dfc.en = 1; // correction method module_params.dfc.corr_mode = CCDC_VDFC_HORZ_INTERPOL_IF_SAT; // not pixels upper than the defect corrected module_params.dfc.corr_whole_line = 1; module_params.dfc.def_level_shift = CCDC_VDFC_SHIFT_2; module_params.dfc.def_sat_level = 20; module_params.dfc.num_vdefects = 7; for (i = 0; i < module_params.dfc.num_vdefects; i++) { module_params.dfc.table[i].pos_vert = i; module_params.dfc.table[i].pos_horz = i + 1; module_params.dfc.table[i].level_at_pos = i + 5; module_params.dfc.table[i].level_up_pixels = i + 6; module_params.dfc.table[i].level_low_pixels = i + 7; } printf("DFC enabled\n"); } else { module_params.dfc.en = 0; } if (en_culling) { printf("Culling enabled\n"); module_params.culling.hcpat_odd = 0xcc; module_params.culling.hcpat_even = 0xcc; module_params.culling.vcpat = 0x55; module_params.culling.en_lpf = 1; } if (-1 == ioctl(capt_fd, VPFE_CMD_S_CCDC_PARAMS, &raw_params)) { perror("InitDevice:ioctl:VPFE_CMD_S_CCDC_PARAMS"); return -1; } return 0;}static int InitCaptureBuffers(int fdCapture){ struct v4l2_requestbuffers req; int nIndex = 0, i; CLEAR(req); req.count = APP_NUM_BUFS/2; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_USERPTR; if (-1 == ioctl(fdCapture, VIDIOC_REQBUFS, &req)) { perror("InitCaptureBuffers:ioctl:VIDIOC_REQBUFS"); return -1; } else printf("\nREQBUF Done\n"); if (req.count != APP_NUM_BUFS/2) { printf("VIDIOC_REQBUFS failed for capture"); return -1; } return 0;}int init_camera_capture(v4l2_std_id std, int width, int height){ int capt_fd; int ret = 0; struct v4l2_capability cap; if ((capt_fd = open(CAPTURE_DEVICE, O_RDWR | O_NONBLOCK, 0)) <= -1) { perror("init_camera_capture:open::"); return -1; } /*Is capture supported? */ if (-1 == ioctl(capt_fd, VIDIOC_QUERYCAP, &cap)) { perror("init_camera_capture:ioctl:VIDIOC_QUERYCAP:"); close(capt_fd); return -1; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { printf("InitDevice:capture is not supported on:%s\n", CAPTURE_DEVICE); close(capt_fd); return -1; } /*is MMAP-IO supported? */ if (!(cap.capabilities & V4L2_CAP_STREAMING)) { printf ("InitDevice:IO method MMAP is not supported on:%s\n", CAPTURE_DEVICE); close(capt_fd); return -1; } printf("setting data format\n"); if (set_data_format(capt_fd, std, width, height) < 0) { printf("SetDataFormat failed\n"); close(capt_fd); return -1; } printf("initializing capture buffers\n"); if (InitCaptureBuffers(capt_fd) < 0) { printf("InitCaptureBuffers failed\n"); close(capt_fd); return -1; } ret = start_capture_streaming(capt_fd); if (ret) { printf("Failed to start capture streaming\n"); return ret; } printf("Capture initialized\n"); return capt_fd;}int start_capture_streaming(int fdCapture){ int i = 0; enum v4l2_buf_type type; for (i = 0; i < (APP_NUM_BUFS/2); i++) { struct v4l2_buffer buf; CLEAR(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_USERPTR; buf.index = i; buf.length = buf_size; buf.m.userptr = (unsigned long)capture_buffers[i].user_addr; printf("Queing buffer:%d\n", i); if (-1 == ioctl(fdCapture, VIDIOC_QBUF, &buf)) { perror("StartStreaming:VIDIOC_QBUF failed"); return -1; } else printf("\nQ_BUF Done\n"); } /* all done , get set go */ type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl(fdCapture, VIDIOC_STREAMON, &type)) { perror("StartStreaming:ioctl:VIDIOC_STREAMON:"); return -1; } else printf("\nSTREAMON Done\n"); return 0;}int cleanup_capture(int fd){ int i, err = 0; enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type)) { perror("cleanup_capture :ioctl:VIDIOC_STREAMOFF"); err = -1; } if (close(fd) < 0) { perror("Error in closing device\n"); err = -1; } return err;}int cleanup_preview(int fd){ int i, err = 0; if (close(fd) < 0) { perror("Error in closing preview device\n"); err = -1; } return err;}/******************************************************************************* * allocate_user_buffers() allocate buffer using CMEM ******************************************************************************/int allocate_user_buffers(void){ void *pool; int i; CMEM_AllocParams alloc_params; printf("calling cmem utilities for allocating frame buffers\n"); CMEM_init(); alloc_params.type = CMEM_POOL; alloc_params.flags = CMEM_NONCACHED; alloc_params.alignment = 32; pool = CMEM_allocPool(0, &alloc_params); if (NULL == pool) { printf("Failed to allocate cmem pool\n"); return -1; } printf("Allocating capture buffers :buf size = %d \n", buf_size); for (i=0; i < APP_NUM_BUFS; i++) { capture_buffers[i].user_addr = CMEM_alloc(buf_size, &alloc_params); if (capture_buffers[i].user_addr) { capture_buffers[i].phy_addr = CMEM_getPhys(capture_buffers[i].user_addr); if (0 == capture_buffers[i].phy_addr) { printf("Failed to get phy cmem buffer address\n"); return -1; } } else { printf("Failed to allocate cmem buffer\n"); return -1; } printf("Got %p from CMEM, phy = %p\n", capture_buffers[i].user_addr, (void *)capture_buffers[i].phy_addr); } return 0;}int main(int argc, char *argp[]){ char shortoptions[] = "x:t:f:p:s:m:i:o:c:"; int mode = O_RDWR,c,ret,index, display_index; int preview_fd, rsz_fd, capt_fd, display_fd, dev_idx; unsigned int oper_mode, user_mode=IMP_MODE_CONTINUOUS; int level; int *capbuf_addr; fd_set fds; struct timeval tv; int r, i; int quit=0; struct timezone zone; int in_format=0;// void *display_buf; void *src, *dest; int sizeimage; struct v4l2_buffer buf; int captFrmCnt = 0; struct v4l2_buffer cap_buf; strcpy(camera_input, "RAW-1"); for(;;) { c = getopt_long(argc, argp, shortoptions, NULL, (void *)&index); if(-1 == c) break; switch(c) { case 't': gamma_flag = atoi(optarg); break; case 'f': output_format = atoi(optarg); if (output_format < 0 || output_format > 1) { printf("Choose 0 - UYVY 1 - NV12 for output pix format\n"); exit(1); } break; case 'm': in_std = atoi(optarg); break; case 'x': disp_second_output = atoi(optarg); break; case 's': case 'S': stress_test = atoi(optarg); break; case 'i': case 'I': cam_input = atoi(optarg); if (cam_input != 0 && cam_input != 1) { printf("Select source as as 0 or 1\n"); exit(0); } if (cam_input == 0) { strcpy(camera_input, CAMERA_INPUT_MT9T001); max_stds = 6; } break; case 'p': printfn = atoi(optarg); break; case 'c': en_crop = atoi(optarg); break; default: usage(); exit(1); } } if (in_std >= max_stds) { printf("in_std is more than maximum, max = %d\n", max_stds); exit(1); } input_std_params = mt9p031_std_params[in_std]; printf("input_std_params: name = %s\n", input_std_params.name); printf("input_std_params: output width = %d\n", input_std_params.image_width); if (output_format) sizeimage = (input_std_params.image_width * input_std_params.image_height) + (input_std_params.image_width * (input_std_params.image_height >>1)); else sizeimage = (input_std_params.image_width * input_std_params.image_height * BYTESPERPIXEL); if (allocate_user_buffers() < 0) { printf("Unable to Allocate user buffers\n"); exit(1); } // intialize resizer in continuous mode rsz_fd = init_resizer(user_mode, input_std_params.image_width, input_std_params.image_height); if (rsz_fd < 0) { printf("Error in initializing resizer\n"); exit(1); } // initialize previewer in continuous mode preview_fd = init_previewer(user_mode, in_format); if (preview_fd < 0) { close(rsz_fd); exit(1); } // intialize capture capt_fd = init_camera_capture( input_std_params.std, input_std_params.image_width, input_std_params.image_height); if (capt_fd < 0) { close(preview_fd); close(rsz_fd); exit(1); } if (!output_format) second_output_offset = input_std_params.image_width * input_std_params.image_height * 2; else second_output_offset = ALIGN(input_std_params.image_width,32) * input_std_params.image_height * 1.5; second_output_offset = ALIGN(second_output_offset, 4096);#if 0 printf("Second output offset = %d\n", second_output_offset); if (!disp_second_output) display_fd = init_display_device(0, input_std_params.image_width, input_std_params.image_height); else display_fd = init_display_device(0, second_out_width, second_out_height); if (display_fd < 0) { cleanup_preview(preview_fd); close(rsz_fd); close(capt_fd); exit(1); } printf("Initialized display\n"); #endif while (!quit) { unsigned long temp; CLEAR(cap_buf); CLEAR(disp_buf); cap_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; cap_buf.memory = V4L2_MEMORY_USERPTR;try2: ret = ioctl(capt_fd, VIDIOC_DQBUF, &cap_buf); if (ret < 0) { if (errno == EAGAIN) { goto try2; } perror("VIDIOC_DQBUF for capture failed\n"); return ret; } ret = ioctl(capt_fd, VIDIOC_QBUF, &cap_buf); if (ret < 0) { perror("VIDIOC_QBUF for capture failed\n"); return ret; } captFrmCnt++; printf("frame:%5u, ", captFrmCnt); printf("buf.timestamp:%lu:%lu\n", cap_buf.timestamp.tv_sec, cap_buf.timestamp.tv_usec); } printf("Cleaning capture\n"); cleanup_capture(capt_fd); cleanup_preview(preview_fd); printf("closing preview- end\n"); close(rsz_fd); printf("closing resize - end\n"); exit(0);}
problem solved
Hi Saam,
i want to know how to enable Crop feature ?
what is the crop area supported and how how many Crop areas we can select per frame ?
How does it happen ? is it like crop the frame as per the crop area and then send for encode ?
what parameters need to be set in H264 codec parameter settings.
i was going through your code but could not understand. if you can suggest me some document also it will be helpfull.
This app is the one what Ti is shipping with PSP_02_10_00_14.
You can enable croppng by setting en_crop to 1.
As I don't use cropping, I don't know the cropping features.
You can always look the kernel drivers source code and found what and how can be configured. ( in this case /drivers/media/video/davinci/ccdc_dm365.c and davinci_vpfe.c )
You can found some documentation about the kernel drivers in the PSP doc directory, and of course from the hw side in DM365 VPFE users guide.
does DM365 support V4L2_MEMORY_USERPTR for capture???
yes
Hi saam,
I have the same problem that you had.
When I try to DEQUEUE a buffer of a big resolutions such as 720p, the app stops.. As I understood you solve the problem.. So, can you please share your idea or even better , can you post your code here?
thanks
My problem comes from the wrong MT9P031 STD setups. You need to tweek the standards parameters in the kernel code.
I have not my sources here with me, if you can't solve I can post my setups later.