大家好。
我的代码有问题。我正在尝试编写一个程序来使用 JPEG 编码器从相机拍摄照片并将其作为动态 jpeg 视频 (MJPEG) 保存到 USB 中。我已经构建了 MJPEG 文件的标题和结构,但是当我尝试运行该视频文件时出现问题。同样由STM提供的源代码,我完成了创建JPEG文件。
下 面这个链接简单地展示了一些关于 MJPEG 构造的信息 https://blog.goo.ne.jp/sirius506 ... 018a32471f1ecd4ae77
我查了一下,f_write写的frames和idx1的输出数据是不正确的。有时又写了 2 个字节。有人告诉我问题可能是“3 个字节被丢弃”。
我写到文件开头的文件头数据总是正确的,但是我写到frame处和idx1处的数据通常有问题。
例如:我想在下面写这样的数据
01 02 03 04 05
01 02 03 04 05
01 02 03 04 05
01 02 03 04 05
但输出是这样的
01 02 03 04 05
*01 02 01 02* 03
04 05 01 02 03
04 05 01 02 03
我曾尝试改变很多方式,比如让它变慢(fps = 1 或 2)或改变 f_write 函数的参数,但它仍然出错。
这是 f_write 函数
- UINT frame_count = 0;
- f_write (&JPEG_File, Frame, sizeof(Frame), &frame_count);
- FRESULT f_write (
- FIL* fp, /* Pointer to the file object */
- const void* buff, /* Pointer to the data to be written */
- UINT btw, /* Number of bytes to write */
- UINT* bw /* Pointer to number of bytes written */
- )
编写框架代码
- uint8_t buf_4[4];
- if(f_open(&JPEG_File, "video.avi", FA_CREATE_ALWAYS|FA_WRITE) == FR_OK) // 4
- {
- //header
- UINT header_count = 0;
- f_write (&JPEG_File, Header , 5754, &header_count);
- //create avi with 50 frames
- for(int i_loop = 0; i_loop < num_frame_tam; i_loop++){
- /* Suspend the camera capture */
- BSP_CAMERA_Suspend();
- cameraState = CAMERA_STATE_SAVING_PICTURE;
- PicturePrepare1(); //prepare buffer for writer
- uint32_t before_avi_file = f_size(&JPEG_File); //get before size
- //8 connected bytes stand before each frame
- UINT frame_count = 2;
- uint8_t connect_frame[8] = {0x30, 0x30, 0x64, 0x63, 0x00, 0x00, 0x00, 0x00};
- f_write (&JPEG_File, connect_frame , 8, &frame_count);
- //write frame by Jpeg encoder
- /*
- uint32_t JpegEncodeProcessing_End = 0;
- JPEG_Encode_DMA(&JPEG_Handle, CONVERTED_FRAME_BUFFER,
- CameraResX * CameraResY * RGB888_BYTE_PER_PIXEL, &JPEG_File);
- do
- {
- JPEG_EncodeInputHandler(&JPEG_Handle);
- JpegEncodeProcessing_End = JPEG_EncodeOutputHandler(&JPEG_Handle);
- } while(JpegEncodeProcessing_End == 0);
- */
- //write the data was prepared before for test
- f_write (&JPEG_File, frame , sizeof(frame), &frame_count); //
- //calculate frame size and change last 4 bytes of connected 8bytes before each frame
- uint32_t newframe_size = f_size(&JPEG_File) - before_avi_file - 8; // size of frame
- num_to_array_4byte(newframe_size, buf_4);
- f_lseek(&JPEG_File, before_avi_file + 4);
- UINT bytesWritefile = 0;
- f_write (&JPEG_File, buf_4 , 4, &bytesWritefile);// ghi vao gia size of frame
- f_lseek(&JPEG_File, f_size(&JPEG_File));
- ////create dx1
- uint8_t idx1_combi[16] = {0x30, 0x30, 0x64, 0x63, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- change_aray_noptr(idx1_combi, 12, buf_4 , 4); //ghi real size vao byte 12
- num_to_array_4byte(idx1_next_size, buf_4);
- change_aray_noptr(idx1_combi, 8, buf_4 , 4); //ghi tong size vao byte 8
- //increase size of idx1
- change_aray_noptr(idx1,idx1_size, idx1_combi, 16);
- idx1_size +=16;
- idx1_next_size = idx1_next_size + newframe_size + 8; // 8 bit dau moi frame
- BSP_CAMERA_Resume();
- }//for
- //Write idx1
- num_to_array_4byte(idx1_size-8, buf_4);
- change_aray_noptr(idx1, 4, buf_4 , 4);
- UINT after_write = 0;
- f_write (&JPEG_File, idx1, idx1_size, &after_write);
- //fill size of avi in the header
- f_lseek(&JPEG_File, 4);
- num_to_array_4byte(f_size(&JPEG_File) - 8, buf_4);
- f_write (&JPEG_File, buf_4 , 4, &after_write);
- //fill total frame size
- f_lseek(&JPEG_File, 5742+4);
- num_to_array_4byte(idx1_next_size, buf_4);
- f_write (&JPEG_File, buf_4 , 4, &after_write);
- //Close the JPEG file
- f_close(&JPEG_File);
- }
USB初始化
- USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost)
- {
- #ifdef USE_USB_HS
- /* Set the LL driver parameters */
- hhcd.Instance = USB_OTG_HS;
- hhcd.Init.Host_channels = 11;
- hhcd.Init.dma_enable = 1;
- hhcd.Init.low_power_enable = 0;
- #ifdef USE_USB_HS_IN_FS
- hhcd.Init.phy_itface = HCD_PHY_EMBEDDED; //This is not
- #else
- hhcd.Init.phy_itface = HCD_PHY_ULPI; //This ok
- #endif
- hhcd.Init.Sof_enable = 0;
- hhcd.Init.speed = HCD_SPEED_HIGH;
- hhcd.Init.use_external_vbus = 1;
- /* Link the driver to the stack */
- hhcd.pData = phost;
- phost->pData = &hhcd;
- /* Initialize the LL driver */
- HAL_HCD_Init(&hhcd);
- #endif /*USE_USB_HS*/
- USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd));
- return USBH_OK;
- }
有人对此有经验吗?我非常感谢任何建议。
对不起我的英语不好。非常感谢。
我用 RIFF pad 打开了我的 MJPEG (avi) 文件,它告诉我标题被写入这个输出文件是完全没问题的。
0
|
1个回答
|
|
|