Created
November 29, 2019 09:25
-
-
Save heyanlong/331e4bc789b84f25e50126ff12d66f0b to your computer and use it in GitHub Desktop.
rtsp codec
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.14) | |
PROJECT(m) | |
SET(CMAKE_CXX_STANDARD 11) | |
FIND_PATH(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h) | |
FIND_LIBRARY(AVCODEC_LIBRARY avcodec) | |
FIND_PATH(AVFORMAT_INCLUDE_DIR libavformat/avformat.h) | |
FIND_LIBRARY(AVFORMAT_LIBRARY avformat) | |
AUX_SOURCE_DIRECTORY(src DIR_SRCS) | |
AUX_SOURCE_DIRECTORY(src/video DIR_SRCS) | |
SET(M_SRCS | |
${DIR_SRCS}) | |
ADD_EXECUTABLE(${PROJECT_NAME} ${M_SRCS}) | |
TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE ${AVCODEC_INCLUDE_DIR} ${AVFORMAT_INCLUDE_DIR}) | |
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${AVCODEC_LIBRARY} ${AVFORMAT_LIBRARY}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Yanlong He on 2019/11/29. | |
// | |
#include "codec.h" | |
namespace m { | |
namespace detect { | |
Codec::Codec(std::string url) | |
: _url(std::move(url)) { | |
setOptions(); | |
} | |
void Codec::open() { | |
AVFormatContext *fmtCtx = avformat_alloc_context(); | |
avformat_open_input(&fmtCtx, _url.c_str(), nullptr, &_opt); | |
_fmtCtx.reset(fmtCtx); | |
avformat_find_stream_info(fmtCtx, nullptr); | |
int ret, streamIndex; | |
AVCodec *codec = nullptr; | |
AVStream *st; | |
ret = av_find_best_stream(fmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0); | |
if (ret < 0) { | |
return; | |
} | |
streamIndex = ret; | |
st = fmtCtx->streams[streamIndex]; | |
codec = avcodec_find_decoder(st->codecpar->codec_id); | |
_codecContext = avcodec_alloc_context3(codec); | |
avcodec_parameters_to_context(_codecContext, st->codecpar); | |
AVDictionary *opt = nullptr; | |
av_dict_set(&opt, "threads", "1", 0); | |
avcodec_open2(_codecContext, codec, &opt); | |
av_dict_free(&opt); | |
av_init_packet(&_packet); | |
_frame.reset(av_frame_alloc()); | |
av_seek_frame(fmtCtx, streamIndex, 0, AVSEEK_FLAG_BACKWARD); | |
avformat_flush(fmtCtx); | |
} | |
AVFrame *Codec::frame() { | |
AVFrame *f = nullptr; | |
if (av_read_frame(_fmtCtx.get(), &_packet) == 0) { | |
if (_packet.stream_index == _streamIndex) { | |
int response = avcodec_send_packet(_codecContext, &_packet); | |
if (response >= 0) { | |
response = avcodec_receive_frame(_codecContext, _frame.get()); | |
std::cout << response << std::endl; | |
if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) { | |
std::cout << "receive err: " << response << std::endl; | |
} else if (response < 0) { | |
} else if (response >= 0) { | |
f = _frame.get(); | |
} | |
} else { | |
std::cout << "send packet err: " << response << std::endl; | |
} | |
} | |
} else { | |
std::cout << "read frame err" << std::endl; | |
} | |
return f; | |
} | |
void Codec::setOptions() { | |
av_dict_set(&_opt, "allowed_media_types", "video", 0); | |
av_dict_set(&_opt, "reconnect_streamed", "1", 0); | |
av_dict_set(&_opt, "nobuffer", "1", 0); | |
av_dict_set(&_opt, "analyzeduration", "0", 0); | |
av_dict_set(&_opt, "rtsp_transport", "tcp", 0); | |
av_dict_set(&_opt, "buffer_size", "2097152", 0); | |
av_dict_set(&_opt, "max_delay", "0", 0); | |
av_dict_set(&_opt, "stimeout", "30000000", 0); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Yanlong He on 2019/11/29. | |
// | |
#ifndef M_CODEC_H | |
#define M_CODEC_H | |
#include <iostream> | |
#include <utility> | |
extern "C" { | |
#include <libavcodec/avcodec.h> | |
#include <libavformat/avformat.h> | |
#include <libavutil/dict.h> | |
}; | |
namespace m { | |
namespace detect { | |
class Codec { | |
private: | |
std::string _url; | |
AVDictionary *_opt = nullptr; | |
std::unique_ptr<AVFormatContext> _fmtCtx; | |
std::unique_ptr<AVFrame> _frame; | |
AVPacket _packet; | |
AVCodecContext *_codecContext = nullptr; | |
int _streamIndex; | |
void setOptions(); | |
public: | |
explicit Codec(std::string url); | |
void open(); | |
AVFrame* frame(); | |
}; | |
} | |
} | |
#endif //M_CODEC_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Yanlong He on 2019/11/29. | |
// | |
#include <iostream> | |
#include "video/codec.h" | |
int main(int argc, char **argv) { | |
m::detect::Codec codec("rtsp://127.0.0.1/live"); | |
codec.open(); | |
while (1) { | |
AVFrame *frame = codec.frame(); | |
if (frame != nullptr) { | |
std::cout << frame->width << " x " << frame->height << std::endl; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
偶像!