ffmpeg 读取rtp h264视频流解码C代码
时间: 2023-07-19 13:56:48 浏览: 249
从ffmpeg中提取出来的h264解码源代码
4星 · 用户满意度95%
以下是使用FFmpeg读取RTP H.264视频流并解码的示例代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
int main(int argc, char **argv)
{
AVCodec *codec = NULL;
AVCodecContext *codec_ctx = NULL;
AVPacket packet;
AVFrame *frame = NULL;
int ret, got_frame;
int frame_count = 0;
int video_width, video_height;
struct timeval start_time, end_time;
if (argc < 2)
{
printf("Usage: %s <rtp_address>\n", argv[0]);
return -1;
}
avcodec_register_all();
av_register_all();
avformat_network_init();
// 打开RTP流并读取视频流信息
AVFormatContext *format_ctx = NULL;
if (avformat_open_input(&format_ctx, argv[1], NULL, NULL) != 0)
{
printf("Couldn't open input file\n");
return -1;
}
if (avformat_find_stream_info(format_ctx, NULL) < 0)
{
printf("Couldn't find stream information\n");
return -1;
}
// 查找视频流,并初始化解码器
int video_stream_index = -1;
for (int i = 0; i < format_ctx->nb_streams; i++)
{
if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
video_stream_index = i;
codec_ctx = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(codec_ctx, format_ctx->streams[i]->codecpar);
codec = avcodec_find_decoder(codec_ctx->codec_id);
if (!codec)
{
printf("Unsupported codec\n");
return -1;
}
if (avcodec_open2(codec_ctx, codec, NULL) < 0)
{
printf("Could not open codec\n");
return -1;
}
video_width = codec_ctx->width;
video_height = codec_ctx->height;
break;
}
}
// 初始化AVFrame并分配内存
frame = av_frame_alloc();
if (!frame)
{
printf("Could not allocate frame\n");
return -1;
}
gettimeofday(&start_time, NULL);
// 读取RTP流并解码
while (1)
{
ret = av_read_frame(format_ctx, &packet);
if (ret < 0)
{
printf("Error reading packet\n");
break;
}
if (packet.stream_index == video_stream_index)
{
ret = avcodec_send_packet(codec_ctx, &packet);
if (ret < 0)
{
printf("Error sending packet for decoding\n");
break;
}
while (ret >= 0)
{
ret = avcodec_receive_frame(codec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
break;
}
else if (ret < 0)
{
printf("Error during decoding\n");
break;
}
printf("Decoded frame %d\n", frame_count++);
// 在这里可以处理解码后的帧,例如渲染到屏幕上
}
}
av_packet_unref(&packet);
}
gettimeofday(&end_time, NULL);
double elapsed_time = (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_usec - start_time.tv_usec) / 1000000.0;
printf("Decoded %d frames in %f seconds (average fps: %f)\n", frame_count, elapsed_time, frame_count / elapsed_time);
avcodec_free_context(&codec_ctx);
avformat_close_input(&format_ctx);
av_frame_free(&frame);
return 0;
}
```
这段代码打开指定的RTP流并读取视频流信息,查找视频流并初始化解码器,然后循环读取RTP流并解码每个视频帧。在解码每个帧后,您可以将其渲染到屏幕上或进行其他处理。最后,它将打印解码帧的数量和解码时间,然后释放所有资源。
请注意,为了简化代码,这个示例忽略了错误处理和内存释放。在实际应用中,您需要确保正确地处理和释放所有资源,以避免内存泄漏和其他问题。
阅读全文