Untitled
unknown
c_cpp
a year ago
4.8 kB
12
Indexable
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
}
#include "vdo-map.h"
#include "vdo-stream.h"
#include "vdo-types.h"
#include "vdo-error.h"
#include <glib.h>
#include <string.h>
#include <syslog.h>
#include "imgprovider.h"
#define VDO_CLIENT_ERROR g_quark_from_static_string("vdo-client-error")
const char* RTSP_SERVER = "rtsp://192.168.1.253:8553/stream";
int main(int argc, char* argv[]) {
openlog("acap_app", LOG_PID | LOG_CONS, LOG_USER);
syslog(LOG_INFO, "Running test ACAP app");
GError* error = nullptr;
VdoMap* settings = vdo_map_new();
// The desired width and height of the BGR frame
unsigned int width = 640; // 1024
unsigned int height = 360; // 576
// Set default arguments
vdo_map_set_uint32(settings, "width", width);
vdo_map_set_uint32(settings, "height", height);
vdo_map_set_uint32(settings, "format", VDO_FORMAT_H264);
// Create a new stream
VdoStream* vdostream = vdo_stream_new(settings, NULL, &error);
g_clear_object(&settings);
if (!vdostream) {
syslog(LOG_ERR, "Failed to create VDO stream.");
}
if (!vdo_stream_attach(vdostream, NULL, &error)) {
syslog(LOG_ERR, "Failed to attach to VDO stream.");
exit(1);
}
VdoMap* info = vdo_stream_get_info(vdostream, &error);
if (!info) {
syslog(LOG_ERR, "Failed to get VDO stream info.");
exit(1);
}
syslog(LOG_INFO,
"Starting stream: %s, %ux%u, %u fps\n",
"h264",
vdo_map_get_uint32(info, "width", 0),
vdo_map_get_uint32(info, "height", 0),
vdo_map_get_uint32(info, "framerate", 0));
g_clear_object(&info);
// Start the stream
if (!vdo_stream_start(vdostream, &error)) {
syslog(LOG_ERR, "Failed to start VDO stream.");
exit(1);
}
avformat_network_init();
AVFormatContext* ofmt_ctx = nullptr;
AVStream *stream = nullptr;
avformat_alloc_output_context2(&ofmt_ctx, nullptr, "rtsp", RTSP_SERVER);
if (!ofmt_ctx) {
fprintf(stderr, "Could not create output context.\n");
} else {
printf("Allocated output context.\n");
}
stream = avformat_new_stream(ofmt_ctx, nullptr);
if (!stream) {
fprintf(stderr, "Failed to create new livestream.\n");
exit(1);
} else {
printf("New livestream created.\n");
}
AVCodecParameters *codec_params = stream->codecpar;
// Set up codec parameters as per stream settings
codec_params->codec_id = AV_CODEC_ID_H264;
codec_params->codec_type = AVMEDIA_TYPE_VIDEO;
codec_params->width = width;
codec_params->height = height;
// Open output URL
if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
if (avio_open(&ofmt_ctx->pb, ofmt_ctx->url, AVIO_FLAG_WRITE) < 0) {
fprintf(stderr, "Could not open output URL.\n");
exit(1);
}
}
// Write header to output file
if (avformat_write_header(ofmt_ctx, nullptr) < 0) {
fprintf(stderr, "Error occurred when writing header.\n");
exit(1);
}
AVPacket pkt;
int frame_rate = 30;
int64_t pts = 0;
int64_t dts = 0;
int64_t frame_duration = AV_TIME_BASE / frame_rate;
av_init_packet(&pkt);
pkt.data = nullptr;
pkt.size = 0;
pkt.dts = 0;
while (true) {
VdoBuffer* buffer = vdo_stream_get_buffer(vdostream, &error);
VdoFrame* frame = vdo_buffer_get_frame(buffer);
if (!frame) {
syslog(LOG_INFO, "Failed to read frame.");
break;
}
pkt.stream_index = stream->index;
pkt.data = (uint8_t *)vdo_buffer_get_data(buffer);
pkt.size = vdo_frame_get_size(frame);
if (!pkt.data) {
syslog(LOG_INFO, "Failed to get packet data.");
av_packet_unref(&pkt);
vdo_stream_buffer_unref(vdostream, &buffer, &error);
break;
}
// Set DTS and PTS
pkt.dts = dts;
pkt.pts = pts;
pkt.duration = frame_duration;
if (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0) {
syslog(LOG_ERR, "Error writing frame to output context.");
break;
}
// Update DTS and PTS
dts += frame_duration;
pts += frame_duration;
// Release the buffer and allow the server to reuse it
if (!vdo_stream_buffer_unref(vdostream, &buffer, &error)){
syslog(LOG_ERR, "Failed to release buffer.");
break;
}
av_packet_unref(&pkt);
}
av_write_trailer(ofmt_ctx);
if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
avio_closep(&ofmt_ctx->pb);
printf("Program completed. Exiting...");
}Editor is loading...
Leave a Comment