#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <sstream>
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavformat/avio.h"
#include "libswscale/swscale.h"
}
#pragma warning(disable :4996)
int main(int argc, char** argv)
{
av_log_set_level(AV_LOG_TRACE); //AV_LOG_TRACE //AV_LOG_DEBUG
//open RTSP
AVDictionary* format_opts = NULL;
av_dict_set(&format_opts, "stimeout", std::to_string(2 * 1000000).c_str(), 0); //设置链接超时时间(us)
av_dict_set(&format_opts, "rtsp_transport", "tcp", 0); //设置推流的方式,默认udp。
//
AVFormatContext* format_ctx = avformat_alloc_context();
auto ret = avformat_open_input(&format_ctx, "rtsp://192.168.0.105/live/main_stream", NULL, &format_opts);
if (ret < 0) {
printf("avformat_open_input Failed\n");
return 0;
}
//
ret = avformat_find_stream_info(format_ctx, NULL);
if (ret < 0) {
printf("avformat_find_stream_info Failed\n");
return 0;
}
//search video stream
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;
}
}
if (video_stream_index == -1) {
printf("video_stream_index = -1\n");
return 0;
}
//
AVPacket packet;
av_init_packet(&packet);
//start reading packets from stream and write them to file
av_read_play(format_ctx); //play RTSP
// Get the codec
const AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec) {
printf("avcodec_find_decoder Failed\n");
return 0;
}
// Add this to allocate the context by codec
AVCodecContext* codec_ctx = avcodec_alloc_context3(codec);
avcodec_parameters_from_context(format_ctx->streams[video_stream_index]->codecpar, codec_ctx);
codec_ctx->width = 1920;
codec_ctx->height = 1080;
codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
printf("avcodec_open2 Failed\n");
return 0;
}
//
AVFrame* picture = av_frame_alloc();
if (!picture) {
fprintf(stderr, "Could not allocate video frame\n");
return 0;
}
picture->format = codec_ctx->pix_fmt;
picture->width = codec_ctx->width;
picture->height = codec_ctx->height;
//
ret = av_frame_get_buffer(picture, 0);
//
AVCodecParserContext* parser = av_parser_init(codec->id);
if (!parser) {
fprintf(stderr, "parser not found\n");
return 0;
}
FILE* pFile = fopen("e:\\1.264", "ab+");
AVStream* stream = NULL;
while (av_read_frame(format_ctx, &packet) >= 0)
{
if (stream == NULL)
{
stream = avformat_new_stream(format_ctx, codec);
avcodec_parameters_from_context(stream->codecpar, codec_ctx);
}
ret = avcodec_send_packet(codec_ctx, &packet);
if (ret < 0) {
continue;
}
while (ret >= 0) {
ret = avcodec_receive_frame(codec_ctx, picture);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
break;
}
if (pFile) {
fwrite(packet.data, 1, packet.size, pFile);
}
}
}
fclose(pFile);
av_free(picture);
av_read_pause(format_ctx);
return (EXIT_SUCCESS);
}
ffmpeg5.1 取流
最新推荐文章于 2024-08-23 17:29:55 发布