rockchip-linux / mpp

Media Process Platform (MPP) module
596 stars 172 forks source link

从v4l2设备中获取mjpeg数据,然后解码,解码后frame不完整 #655

Open lxyevl opened 3 months ago

lxyevl commented 3 months ago

测试代码 `std::array<char[192010804], 60> bufArr; int usedArr[60]; void testDecoderA() { const int BUF_CONUT = 4; const int width = 1920; const int height = 1080;

CamSource *cam = camera_source_initA("/dev/video0", BUF_CONUT, width, height);
VideoDecoderMJPEG decoder(width, height, MppCodingType::MPP_VIDEO_CodingMJPEG);
MppPacket packet;
FILE *outFile = fopen("1.out", "w+b");
char filePath[40];
for (int decFrameNum = 0; decFrameNum < 60; decFrameNum++)
{
    //usleep(40000);
    clock_t time = clock();
    int index = camera_source_get_frameA(cam);
    MppBuffer buf = camera_frame_to_bufA(cam, index);
    mpp_packet_init_with_buffer(&packet, buf);
    if (decFrameNum%4 == 2)
    {
        snprintf(filePath, 40, "%02d.jpeg", decFrameNum);

        std::ofstream outF(filePath, std::fstream::binary);
        if(!outF.is_open())
        {
            printf("open %s Failed!\n", filePath);
            exit(1);
        }
        void *ptr = mpp_packet_get_pos(packet);
        size_t len = mpp_packet_get_length(packet);
        outF.write((char *)ptr, len);
        printf("write to %s\n", filePath);
    }
    MppFrame frame =  decoder.putPacketA(packet);

    //usleep(40000);
    if (decFrameNum%4 == 0)
        dump_mpp_frame_to_file(frame, outFile);

    mpp_packet_deinit(&packet);
    camera_source_put_frameA(cam, index);
    MppFrameFormat fmt = mpp_frame_get_fmt(frame);
    printf("frame %d , fmt %d, time %lf\n", decFrameNum, fmt, ((double) (clock() - time))/1000);
    //usleep(40000);
}

fclose(outFile);
camera_source_deinitA(cam);

}` 从v4l2设备中获取mjpeg数据,然后解码,解码后frame不完整。 测试发现:

  1. 如果sleep时间超过v4l2设备的帧间隔时间,比如v4l2设备帧率是25,那么sleep超过40ms得到的就是完整数据。
  2. 如果putPacketA前,将packet写入硬盘或者memcpy进行复制,获得的jpeg图片都是完整的,同时该packet解码后frame也是完整的
  3. 如果没有sleep足够的时间,或者packet没有写入硬盘就直接解码,获得的frame都是不完整的 感觉是内存的问题,但是不知道怎么处理

Screenshot