gpt4 book ai didi

FFMPEG Stream 系列图片通过网络

转载 作者:行者123 更新时间:2023-12-04 22:47:26 34 4
gpt4 key购买 nike

我想在一台计算机上生成视频帧并将它们流式传输到另一台计算机以进行操作和显示。我想以编程方式执行此操作,因为源图像是从第 3 方 c++ 库生成的,并且在接收端我想在显示图像之前对其进行操作。我一直在尝试 FFMPEG。我得到了编码示例,但不知道之后该怎么做。我几乎用谷歌搜索了我能想到的所有东西,但是一旦我有一个填充的 AVPacket,就无法弄清楚要调用哪个 FFMPEG 库/函数。似乎我需要使用 AVIO 或 AVFormat 或多路复用器,但不清楚如何初始化并让它们工作。我将不胜感激您能提供的任何帮助。

为了提供一些上下文,我提供了 ffmpeg 工作提供的示例“decoding_encoding.c”。这是我正在努力的地方:

        /* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit(1);
}

if (got_output) {
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);

//
// instead of writing to a file, i want to stream to a network
// What do I need to do with pkt to do that?
//
av_free_packet(&pkt);
}

大多数文档(和 Dranger 教程)都侧重于读取和写入文件。我不需要使用文件。我想通过网络流式传输视频。似乎我需要 AVFormat 和 Avio,但我无法弄清楚它们是如何组合在一起的。

最佳答案

关键是使用 avio_open2() 打开套接字连接,然后将 pkt 的数据和大小字段传递给 avio_write()。他是一个示例工作程序(源自 ffmpeg 的 doc/examples 目录中的 decode_encode.c):

#include "stdafx.h"
/*
* Copyright (c) 2001 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/**
* @file
* libavcodec API use example.
*
* @example decoding_encoding.c
* Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
* not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
* format handling
*/

#include <math.h>
#include <stdio.h>
#include <cstdio>
#include <winsock.h>

extern "C"
{
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
#include <libavformat\avio.h>
#include <libavformat\avformat.h>
}

#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096


static void video_encode_example(const char *filename, AVCodecID codec_id)
{
AVCodec *codec;
AVCodecContext *c = NULL;
int i, ret, x, y, got_output;
FILE *f;
AVFrame *frame;
AVPacket pkt;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
errno_t err;
int errval;
printf("Encode video file %s\n", filename);

/* find the mpeg1 video encoder */
codec = avcodec_find_encoder(codec_id);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}

c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}

/* put sample parameters */
c->bit_rate = 4000000;
/* resolution must be a multiple of two */
c->width = 1024;
c->height = 768;
/* frames per second */
c->time_base.den = 25;
c->time_base.num = 1;
/* emit one intra frame every ten frames
* check frame pict_type before passing frame
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
* then gop_size is ignored and the output of encoder
* will always be I frame irrespective to gop_size
*/
c->gop_size = 12;
c->max_b_frames = 0;
c->pix_fmt = AV_PIX_FMT_YUV420P;

if (codec_id == AV_CODEC_ID_H264)
{
av_opt_set(c->priv_data, "preset", "slow", 0);
av_opt_set(c->priv_data, "tune", "zerolatency", 0);
}

/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}

AVFormatContext* format = avformat_alloc_context();
AVDictionary *options = NULL;
av_dict_set(&options, "pkt_size", "1300", 0);
av_dict_set(&options, "buffer_size", "65535", 0);
AVIOContext * server = NULL;
avio_open2(&server, "udp://192.168.0.13:5555", AVIO_FLAG_WRITE, NULL, &options);

frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;

/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
c->pix_fmt, 32);
if (ret < 0) {
fprintf(stderr, "Could not allocate raw picture buffer\n");
exit(1);
}
// Cycle through the test pattern for 1 hour
for (int j = 0; j < 3600; j++)
{
/* encode 1 second of video */
for (i = 0; i < 25; i++) {

Sleep(40);
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 1300;

fflush(stdout);
/* prepare a dummy image */
/* Y */
for (y = 0; y < c->height; y++) {
for (x = 0; x < c->width; x++) {
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
}
}

/* Cb and Cr */
for (y = 0; y < c->height / 2; y++) {
for (x = 0; x < c->width / 2; x++) {
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
}
}

frame->pts = i+j*25;

/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit(1);
}

if (got_output) {
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
//fwrite(pkt.data, 1, pkt.size, f);
avio_write(server, pkt.data, pkt.size);
av_free_packet(&pkt);
}
}
}

/* get the delayed frames */
for (got_output = 1; got_output; i++) {
fflush(stdout);

ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit(1);
}

if (got_output) {
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
avio_write(server, pkt.data, pkt.size);
av_free_packet(&pkt);
}
}
avcodec_close(c);
av_free(c);
av_freep(&frame->data[0]);
av_frame_free(&frame);
printf("\n");
}

int main(int argc, char **argv)
{
const char *output_type;

/* register all the codecs */
av_register_all();
avcodec_register_all();
avformat_network_init();

video_encode_example("test.h264", AV_CODEC_ID_H264);

return 0;
}

关于FFMPEG Stream 系列图片通过网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32444176/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com