#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>
}
 
#define log(msg) std::wcout << L"[FFmpegRTSP] " << msg << std::endl << std::flush
#define logError(msg)std:: wcout << L"[Error] [FFmpegRTSP] " << msg << std::endl << std::flush
 
AVFormatContext* avFormatContext = nullptr;
SwsContext *swsContext = nullptr;
AVCodecContext* avCodecContext;
AVCodec *codec = nullptr;
int frameCount = 0;
 
void writePPM(AVFrame* frameRGB, int fileSuffix) {
    std::stringstream file_name;
    std::ofstream output_file;
    file_name << "test" << fileSuffix << ".ppm";
    output_file.open(file_name.str().c_str());
    output_file << "P3 " << avCodecContext->width << " " << avCodecContext->height
        << " 255\n";
    for (int y = 0; y < avCodecContext->height; y++) {
        for (int x = 0; x < avCodecContext->width * 3; x++) {
            output_file
                << (int)(frameRGB->data[0]
                    + y * frameRGB->linesize[0])[x] << " ";
        }
    }
    output_file.close();
}
 
int main(int argc, char** argv) {
    avFormatContext = avformat_alloc_context();
    if (avformat_open_input(&avFormatContext, "rtsp://admin:123456@192.168.2.109:554/h264Preview_01_main",
        NULL, NULL) != 0) {
        logError("Failed to open Stream");
        return EXIT_FAILURE;
    }
 
    if (avformat_find_stream_info(avFormatContext, NULL) < 0) {
        return EXIT_FAILURE;
    }
 
    int videoStreamIndex = -1;
    for (int i = 0; i < avFormatContext->nb_streams; i++) {
        if (avFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
        }
    }
    if (videoStreamIndex == -1) {
        return EXIT_FAILURE;
    }
 
    av_read_play(avFormatContext);
 
    codec = avcodec_find_decoder(AV_CODEC_ID_H264);
    if (!codec) {
        logError("H264 codec not found, compile FFmpeg with libopenh264 or libx264");
        return EXIT_FAILURE;
    }
    avCodecContext = avcodec_alloc_context3(codec);
    avcodec_get_context_defaults3(avCodecContext, codec);
    avcodec_copy_context(avCodecContext, avFormatContext->streams[videoStreamIndex]->codec);
 
    if (avcodec_open2(avCodecContext, codec, NULL) != 0) {
        logError("Failed to open codec");
        return EXIT_FAILURE;
    }
 
    int width = avCodecContext->width;
    int height = avCodecContext->height;
 
    swsContext = sws_getContext(width, height, avCodecContext->pix_fmt, width,
        height, AV_PIX_FMT_RGB24,    SWS_BICUBIC, NULL, NULL, NULL);
 
    AVFrame* frame = av_frame_alloc();
    frame->format = avCodecContext->pix_fmt;
    frame->width = width;
    frame->height = height;
    av_frame_get_buffer(frame, 0);
 
    AVFrame* frameRGB = av_frame_alloc();
    frameRGB->format = AV_PIX_FMT_RGB24;
    frameRGB->width = width;
    frameRGB->height = height;
    av_frame_get_buffer(frameRGB, 0);
 
    AVPacket packet;
    av_init_packet(&packet);
 
    while (av_read_frame(avFormatContext, &packet) >= 0 && frameCount < 1000) {
        if (packet.stream_index == videoStreamIndex) {
            int gotFrame = 0;
            packet.stream_index = frameCount;
            int result = avcodec_decode_video2(avCodecContext, frame, &gotFrame, &packet);
            if (frameCount % 100 == 1 && gotFrame){
                sws_scale(swsContext, frame->data, frame->linesize, 0,
                    avCodecContext->height, frameRGB->data, frameRGB->linesize);
                writePPM(frameRGB, frameCount);
            }
            frameCount++;
        }
        av_free_packet(&packet);
        av_init_packet(&packet);
    }
    av_frame_free(&frame);
    av_frame_free(&frameRGB);
 
    av_read_pause(avFormatContext);
    avcodec_free_context(&avCodecContext);
    avformat_free_context(avFormatContext);
 
    return EXIT_SUCCESS;
}
 

goto line:
Compare with:
text copy window edit this code post new code