我正在尝试将视频文件流式传输到 MCU,但每当它在设备上播放视频时,它的卡顿程度都非常适中。如果我在流媒体时使用我的电脑,情况会变得更糟。
例如,如果我正在流式传输,然后我滚动浏览聊天记录,比如 Discord,口吃变得非常非常糟糕,这非常奇怪,但可能是找到问题根源的关键因素。
注意:我们必须以 512 字节块流式传输 2352 字节(这是针对我正在流式传输的 ISO9660 光盘视频格式,对正在播放它的系统至关重要,因此不要认为这是问题或错误)。
这是我当前的代码实现。
// main streaming loop
// we send the data by 512 bytes, so 2352 fits into 5 x 512
// [0] code
// [1] sync_id
// [2] readsync_id
// [3, 4, 5, 6] cd_lba
int VideoStream(char *image_path)
{
#define BYTES_PER_SECTOR 2352
int error = 0; // the error returned from the LibUSB transfer functions
int received = 0;
int length = 0;
unsigned char curr_req_id = 0, req_id = 0;
unsigned char curr_rdsync_id = 0, rdsync_id = 0;
unsigned char wr_lock = 0;
unsigned char *pbuf;
int fread_result; // contains the result from 'fread'
unsigned char code;
unsigned int cd_lba, offset;
memset(cd_buffer, 0, CD_BUFFER_MAX_LEN); // clear the 'cd_buffer' array before we use it
fp = fopen(image_path, "rb"); // open the video file (read mode)
if (fp == NULL)
{
#ifdef DEBUG
printf("Failed to open the video file \"%s\"\n", image_path);
#endif
return 0;
}
fseek(fp, 0L, SEEK_END);
// calculate the size of the file
size_t fsize = ftell(fp);
if (fsize <= 0) return 0;
fseek(fp, 0, SEEK_SET);
// clear the 'cd_buffer' array again
memset(cd_buffer, 0, CD_BUFFER_MAX_LEN);
// main streaming loop
while (1)
{
if(libusb_interrupt_transfer(handle, BULK_EP_IN, cd_buffer, 16, &transferred, 3000) < 0)
{
StopUSBStream();
// these crash the program? why??
//libusb_close(handle);
//libusb_exit(NULL);
return 0;
}
code = cd_buffer[0];
curr_req_id = cd_buffer[1];
curr_rdsync_id = cd_buffer[2];
if (req_id == curr_req_id) continue;
req_id = curr_req_id;
if (code == 0x99)
{
// idle
}
else if (code == 0x01) // data request
{
if (wr_lock)
{
if (rdsync_id != curr_rdsync_id)
{
wr_lock = 0;
}
}
if (!wr_lock)
{
cd_lba = cd_buffer[3] + 0x0000100 * cd_buffer[4] + 0x0010000 * cd_buffer[5] + 0x1000000 * cd_buffer[6];
offset = (cd_lba - 150) * 0x930;
fseek(fp, 0, SEEK_SET);
fseek(fp, offset, SEEK_SET);
fread_result = fread(cd_buffer + 4, 1, BYTES_PER_SECTOR, fp);
if (fread_result < BYTES_PER_SECTOR)
{
int rd_try = 10;
int rd_cmplt = 0;
int rd_more = BYTES_PER_SECTOR;
int rd_total = fread_result;
while (rd_try)
{
rd_more -= fread_result;
offset += fread_result;
fseek(fp, offset, SEEK_SET);
fread_result = fread(cd_buffer + 4, 1, rd_more, fp);
rd_total += fread_result;
if (rd_total == BYTES_PER_SECTOR) rd_cmplt = 1; // if we have read all the bytes, flag that the reading is completed
rd_try--; // negate 1 byte
}
// if reading is still not complete, flag that we have an error
if (!rd_cmplt) rd_cmplt = 0;
}
pbuf = &cd_buffer[2];
int n = CD_BUFFER_MAX_LEN;
int c = 0;
int wrlen = 512;
while (n)
{
pbuf[0] = 2;
pbuf[1] = c;
error = libusb_bulk_transfer(handle, BULK_EP_OUT, pbuf, wrlen, &transferred, 0);
pbuf += (wrlen-2);
n -= wrlen;
c++;
}
if (error == 0)
{
rdsync_id = curr_rdsync_id;
wr_lock = 1;
}
}
}
}
}
关于为什么会发生这种情况的任何建议?我们libusbk
在 Windows 7(32 位)下用作驱动程序。
任何帮助将不胜感激。