Anonymous
Использование FFMPEG ENCODE и UDP с веб -камерой?
Сообщение
Anonymous » 14 мар 2025, 20:29
Я пытаюсь получить кадры из веб -камеры, используя OpenCV, кодируйте их с FFMPEG и отправить их с помощью UDP.
Код: Выделить всё
#include
#include
#include
#include
extern "C" {
#include
#include
#include
#include
#include
#include
#include
}
#include
using namespace std;
using namespace cv;
#define WIDTH 640
#define HEIGHT 480
#define CODEC_ID AV_CODEC_ID_H264
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P
static AVFrame *frame, *pFrameBGR;
int main(int argc, char **argv)
{
VideoCapture cap(0);
const char *url = "udp://127.0.0.1:8080";
AVFormatContext *formatContext;
AVStream *stream;
AVCodec *codec;
AVCodecContext *c;
AVDictionary *opts = NULL;
int ret, got_packet;
if (!cap.isOpened())
{
return -1;
}
av_log_set_level(AV_LOG_TRACE);
av_register_all();
avformat_network_init();
avformat_alloc_output_context2(&formatContext, NULL, "h264", url);
if (!formatContext)
{
av_log(NULL, AV_LOG_FATAL, "Could not allocate an output context for '%s'.\n", url);
}
codec = avcodec_find_encoder(CODEC_ID);
if (!codec)
{
av_log(NULL, AV_LOG_ERROR, "Could not find encoder.\n");
}
stream = avformat_new_stream(formatContext, codec);
c = avcodec_alloc_context3(codec);
stream->id = formatContext->nb_streams - 1;
stream->time_base = (AVRational){1, 25};
c->codec_id = CODEC_ID;
c->bit_rate = 400000;
c->width = WIDTH;
c->height = HEIGHT;
c->time_base = stream->time_base;
c->gop_size = 12;
c->pix_fmt = STREAM_PIX_FMT;
if (formatContext->flags & AVFMT_GLOBALHEADER)
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
av_dict_set(&opts, "preset", "fast", 0);
av_dict_set(&opts, "tune", "zerolatency", 0);
ret = avcodec_open2(c, codec, NULL);
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "Could not open video codec.\n");
}
pFrameBGR = av_frame_alloc();
if (!pFrameBGR)
{
av_log(NULL, AV_LOG_ERROR, "Could not allocate video frame.\n");
}
frame = av_frame_alloc();
if (!frame)
{
av_log(NULL, AV_LOG_ERROR, "Could not allocate video frame.\n");
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
ret = avcodec_parameters_from_context(stream->codecpar, c);
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "Could not open video codec.\n");
}
av_dump_format(formatContext, 0, url, 1);
ret = avformat_write_header(formatContext, NULL);
if (ret != 0)
{
av_log(NULL, AV_LOG_ERROR, "Failed to connect to '%s'.\n", url);
}
Mat image(Size(HEIGHT, WIDTH), CV_8UC3);
SwsContext *swsctx = sws_getContext(WIDTH, HEIGHT, AV_PIX_FMT_BGR24, WIDTH, HEIGHT, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
int frame_pts = 0;
while (1)
{
cap >> image;
int numBytesYUV = av_image_get_buffer_size(STREAM_PIX_FMT, WIDTH, HEIGHT, 1);
uint8_t *bufferYUV = (uint8_t *)av_malloc(numBytesYUV * sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameBGR, image.data, AV_PIX_FMT_BGR24, WIDTH, HEIGHT);
avpicture_fill((AVPicture *)frame, bufferYUV, STREAM_PIX_FMT, WIDTH, HEIGHT);
sws_scale(swsctx, (uint8_t const *const *)pFrameBGR->data, pFrameBGR->linesize, 0, HEIGHT, frame->data, frame->linesize);
AVPacket pkt = {0};
av_init_packet(&pkt);
frame->pts = frame_pts;
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "Error encoding frame\n");
}
if (got_packet)
{
pkt.pts = av_rescale_q_rnd(pkt.pts, c->time_base, stream->time_base, AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, c->time_base, stream->time_base, AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q(pkt.duration, c->time_base, stream->time_base);
pkt.stream_index = stream->index;
return av_interleaved_write_frame(formatContext, &pkt);
cout
Подробнее здесь: [url]https://stackoverflow.com/questions/48564047/using-ffmpeg-encode-and-udp-with-a-webcam[/url]
1741973372
Anonymous
Я пытаюсь получить кадры из веб -камеры, используя OpenCV, кодируйте их с FFMPEG и отправить их с помощью UDP.[code]#include #include #include #include extern "C" { #include #include #include #include #include #include #include } #include using namespace std; using namespace cv; #define WIDTH 640 #define HEIGHT 480 #define CODEC_ID AV_CODEC_ID_H264 #define STREAM_PIX_FMT AV_PIX_FMT_YUV420P static AVFrame *frame, *pFrameBGR; int main(int argc, char **argv) { VideoCapture cap(0); const char *url = "udp://127.0.0.1:8080"; AVFormatContext *formatContext; AVStream *stream; AVCodec *codec; AVCodecContext *c; AVDictionary *opts = NULL; int ret, got_packet; if (!cap.isOpened()) { return -1; } av_log_set_level(AV_LOG_TRACE); av_register_all(); avformat_network_init(); avformat_alloc_output_context2(&formatContext, NULL, "h264", url); if (!formatContext) { av_log(NULL, AV_LOG_FATAL, "Could not allocate an output context for '%s'.\n", url); } codec = avcodec_find_encoder(CODEC_ID); if (!codec) { av_log(NULL, AV_LOG_ERROR, "Could not find encoder.\n"); } stream = avformat_new_stream(formatContext, codec); c = avcodec_alloc_context3(codec); stream->id = formatContext->nb_streams - 1; stream->time_base = (AVRational){1, 25}; c->codec_id = CODEC_ID; c->bit_rate = 400000; c->width = WIDTH; c->height = HEIGHT; c->time_base = stream->time_base; c->gop_size = 12; c->pix_fmt = STREAM_PIX_FMT; if (formatContext->flags & AVFMT_GLOBALHEADER) c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; av_dict_set(&opts, "preset", "fast", 0); av_dict_set(&opts, "tune", "zerolatency", 0); ret = avcodec_open2(c, codec, NULL); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Could not open video codec.\n"); } pFrameBGR = av_frame_alloc(); if (!pFrameBGR) { av_log(NULL, AV_LOG_ERROR, "Could not allocate video frame.\n"); } frame = av_frame_alloc(); if (!frame) { av_log(NULL, AV_LOG_ERROR, "Could not allocate video frame.\n"); } frame->format = c->pix_fmt; frame->width = c->width; frame->height = c->height; ret = avcodec_parameters_from_context(stream->codecpar, c); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Could not open video codec.\n"); } av_dump_format(formatContext, 0, url, 1); ret = avformat_write_header(formatContext, NULL); if (ret != 0) { av_log(NULL, AV_LOG_ERROR, "Failed to connect to '%s'.\n", url); } Mat image(Size(HEIGHT, WIDTH), CV_8UC3); SwsContext *swsctx = sws_getContext(WIDTH, HEIGHT, AV_PIX_FMT_BGR24, WIDTH, HEIGHT, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL); int frame_pts = 0; while (1) { cap >> image; int numBytesYUV = av_image_get_buffer_size(STREAM_PIX_FMT, WIDTH, HEIGHT, 1); uint8_t *bufferYUV = (uint8_t *)av_malloc(numBytesYUV * sizeof(uint8_t)); avpicture_fill((AVPicture *)pFrameBGR, image.data, AV_PIX_FMT_BGR24, WIDTH, HEIGHT); avpicture_fill((AVPicture *)frame, bufferYUV, STREAM_PIX_FMT, WIDTH, HEIGHT); sws_scale(swsctx, (uint8_t const *const *)pFrameBGR->data, pFrameBGR->linesize, 0, HEIGHT, frame->data, frame->linesize); AVPacket pkt = {0}; av_init_packet(&pkt); frame->pts = frame_pts; ret = avcodec_encode_video2(c, &pkt, frame, &got_packet); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error encoding frame\n"); } if (got_packet) { pkt.pts = av_rescale_q_rnd(pkt.pts, c->time_base, stream->time_base, AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); pkt.dts = av_rescale_q_rnd(pkt.dts, c->time_base, stream->time_base, AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); pkt.duration = av_rescale_q(pkt.duration, c->time_base, stream->time_base); pkt.stream_index = stream->index; return av_interleaved_write_frame(formatContext, &pkt); cout Подробнее здесь: [url]https://stackoverflow.com/questions/48564047/using-ffmpeg-encode-and-udp-with-a-webcam[/url]