Ошибка основного ввода и задержки при загрузке изображений libvlc в память
Каждый!
Я работаю над проектом для потоковой передачи изображений в память с помощью libvlc.Для теста я транслирую кадры камеры. У меня тут проблемы: сначала огромные задержки (около 7 секунд), а поток очень нестабильный.
Было бы полезно найти ошибки в моем коде!
Я повторял эти 3 ошибки много раз.
ошибка основного ввода: ES_OUT_SET_PCR вызывается слишком поздно (задержка pts_delay увеличена до 692 мс)
ошибка основного входа: вызвана ES_OUT_RESET_PCR
Ошибка декодера avcodec: более 5 секунд позднего видео -> сброс кадра (компьютер работает слишком медленно?)
Меня особенно интересует последняя ошибка: почему возникает ошибка декодера, когда я хочу кодировать только некоторые изображения?
И вот мой код:
#include <Windows.h>
#include <vlc.h>
#include <vlc_common.h>
#include <vlc_threads.h>
//#include <vlc/plugins/vlc_threads.h>
using namespace std;
#include <opencv2/opencv.hpp>
using namespace cv;
#define CAMERA_WIDTH 640
#define CAMERA_HEIGHT 480
vlc_mutex_t imem_get_mutex;
VideoCapture *g_camera;
int g_transport_number = 8080;
static int vlc_imem_get_callback(void *data, const char *cookie,
int64_t * dts, int64_t * pts,
unsigned *flags, size_t * size,
void **output)
{
//usleep(20000);
Mat frame;
vlc_mutex_lock(&imem_get_mutex);
(*g_camera) >> frame;
*output = malloc(frame.rows * frame.cols * 3);
memcpy(*output,frame.data,frame.rows * frame.cols * 3);
if (pts)
*pts = 1;
if (dts)
*dts = 1;
// *size=(size_t)300;
*size=(size_t)(frame.rows * frame.cols * 3);
vlc_mutex_unlock(&imem_get_mutex);
frame.release();
return 0;
}
static void vlc_imem_release_callback(void *data, const char *cookie,
size_t size, void *unknown)
{
// printf("release\n\n");
free(unknown);
}
int main()
{
vlc_mutex_init(&imem_get_mutex);
g_camera = new VideoCapture(0);
g_camera->set(CV_CAP_PROP_FRAME_WIDTH, CAMERA_WIDTH);
g_camera->set(CV_CAP_PROP_FRAME_WIDTH, CAMERA_HEIGHT);
libvlc_instance_t * inst;
libvlc_media_player_t *mp;
libvlc_media_t *m;
char smem_options1[2000];
char venc_options[1000];
// sprintf(venc_options,"profile=baseline,level=3,keyint=50,bframes=3,no-cabac,ref=3,no-interlaced,vbv-maxrate=512,vbv-bufsize=256,aq-mode=0,no-mbtree,partitions=none,no-weightb,weightp=0,me=dia,subme=0,no-mixed-refs,no-8x8dct,trellis=0");
sprintf(venc_options,"bframes=6,ref=6");
sprintf(smem_options1,"#transcode{venc=x264{%s},vcodec=h264,vb=1000,fps=30,scale=0,width=640,height=480,channels=1,samplerate=44100}:duplicate{dst=http{mux=ts,dst=:%d/test}",venc_options,g_transport_number);
// sprintf(smem_options1,"#transcode{vcodec=h264,vb=1000,fps=30,scale=0,width=640,height=480,channels=1,samplerate=44100}:duplicate{dst=http{mux=ts,dst=:%d/test},dst=display",venc_options,g_transport_number);
char str_imem_get[100], str_imem_release[100],str_imem_data[100];
sprintf(str_imem_get, "--imem-get=%ld", vlc_imem_get_callback);
sprintf(str_imem_release, "--imem-release=%ld", vlc_imem_release_callback);
// sprintf(str_imem_data,"--imem-data=%ld",(long int)test_buffer);
const char * const vlc_args[] = {
"-I","dummy",
"--ignore-config",
"--demux","rawvideo",
"--rawvid-fps","30",
"--rawvid-width","640",
"--rawvid-height","480",
"--rawvid-chroma","RV24",
"--imem-channels=1",
"--imem-data=0",
"--imem-cat=4",
"--imem-fps=30",
"--imem-codec=none",
str_imem_get,
str_imem_release,
"--sout",
smem_options1
};
inst = libvlc_new (sizeof (vlc_args) / sizeof (vlc_args[0]), vlc_args);
m = libvlc_media_new_location(inst, "imem://");
mp = libvlc_media_player_new_from_media (m);
libvlc_media_release (m);
libvlc_media_player_play (mp);
Sleep (200000);
libvlc_media_player_stop (mp);
libvlc_media_player_release (mp);
libvlc_release (inst);
return 0;
}
Спасибо за вашу помощь, и я извиняюсь за мой плохой английский...
1 ответ
У меня была точно такая же проблема, и я обнаружил, что проблема связана со значениями DTS и PTS, которые я использовал при захвате из живого источника с использованием OpenCV, подобного вам. Я вычислял значения DTS и PTS в режиме реального времени, чтобы избежать увеличения pts_delay, но затем примерно через 5 секунд, как и вы, время между обратными вызовами функции imem get продолжало увеличиваться. Затем я использовал фиксированное значение интервала значения частоты кадров, например, 33333, добавляемое каждый раз. Это исправило проблему задержки, но привело к 1-й ошибке с сбросом часов. Решение, которое я нашел, состояло в том, чтобы установить DTS в -1 (не используется) и установить значение PTS в libvlc_clock(). Например:
int MyImemGetCallback (void *data,
const char *cookie,
int64_t *dts,
int64_t *pts,
unsigned *flags,
size_t * bufferSize,
void ** buffer)
{
MyImemData* imem = (MyImemData*)data;
if(imem == NULL)
return 0;
if(imem->mQuitFlag)
return 1; // Exit
if(imem->mFrameNumber == imem->mPrevFrameNumber)
{
return 0; // No new image data
}
// Update frame count information...
imem->mPrevFrameNumber = imem->mFrameNumber;
*dts = -1;
// You can use libvlc_clock to avoid PCR reset and delays
// on realtime data...
*pts = libvlc_clock();
*bufferSize =
imem->mOpenCvImage->rows *
imem->mOpenCvImage->cols *
imem->mOpenCvImage->channels();
*buffer = imem->mOpenCvImage->data;
return 0; // Success.
}
Я знаю, что это было опубликовано 6 месяцев назад, но сегодня я столкнулся с той же проблемой и подумал, что еще кое-что может.