Untitled
unknown
c_cpp
2 years ago
3.5 kB
7
Indexable
#include "rtsp_decoder.h"
#include <iostream>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
struct RTSPDecoder {
AVFormatContext* formatCtx = nullptr;
AVStream* videoStream = nullptr;
AVCodecContext* codecCtx = nullptr;
AVFrame* frame = nullptr;
};
extern "C" {
void* CreateRTSPDecoder(const char* rtspUrl) {
RTSPDecoder* decoder = new RTSPDecoder();
avformat_network_init();
if (avformat_open_input(&decoder->formatCtx, rtspUrl, NULL, NULL) != 0) {
std::cerr << "Error opening RTSP stream" << std::endl;
delete decoder;
return nullptr;
}
for (unsigned int i = 0; i < decoder->formatCtx->nb_streams; ++i) {
if (decoder->formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
decoder->videoStream = decoder->formatCtx->streams[i];
break;
}
}
if (!decoder->videoStream) {
std::cerr << "No video stream found" << std::endl;
avformat_close_input(&decoder->formatCtx);
delete decoder;
return nullptr;
}
AVCodec* codec = avcodec_find_decoder(decoder->videoStream->codecpar->codec_id);
decoder->codecCtx = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(decoder->codecCtx, decoder->videoStream->codecpar);
avcodec_open2(decoder->codecCtx, codec, nullptr);
decoder->frame = av_frame_alloc();
return decoder;
}
void DestroyRTSPDecoder(void* decoderPtr) {
RTSPDecoder* decoder = static_cast<RTSPDecoder*>(decoderPtr);
av_frame_free(&decoder->frame);
avcodec_free_context(&decoder->codecCtx);
avformat_close_input(&decoder->formatCtx);
delete decoder;
}
bool GetDecodedFrame(void* decoderPtr, unsigned char** data, int* width, int* height) {
RTSPDecoder* decoder = static_cast<RTSPDecoder*>(decoderPtr);
AVPacket packet;
int ret = av_read_frame(decoder->formatCtx, &packet);
if (ret < 0) {
return false;
}
if (packet.stream_index == decoder->videoStream->index) {
ret = avcodec_send_packet(decoder->codecCtx, &packet);
if (ret < 0) {
std::cerr << "Error sending packet to decoder" << std::endl;
av_packet_unref(&packet);
return false;
}
while (ret >= 0) {
ret = avcodec_receive_frame(decoder->codecCtx, decoder->frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
av_packet_unref(&packet);
return false;
} else if (ret < 0) {
std::cerr << "Error receiving decoded frame" << std::endl;
av_packet_unref(&packet);
return false;
}
// Remplir les paramètres de sortie avec les données décodées
*data = decoder->frame->data[0];
*width = decoder->frame->width;
*height = decoder->frame->height;
av_packet_unref(&packet);
return true;
}
}
av_packet_unref(&packet);
return false;
}
}
Editor is loading...
Leave a Comment