framereader: remove deprecated ffmpeg functions (#22895)

pull/22902/head
Dean Lee 4 years ago committed by GitHub
parent 6b20118fec
commit c0b9c1f3af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 69
      selfdrive/ui/replay/framereader.cc
  2. 4
      selfdrive/ui/replay/framereader.h

@ -1,30 +1,10 @@
#include "selfdrive/ui/replay/framereader.h" #include "selfdrive/ui/replay/framereader.h"
#include <unistd.h>
#include <cassert> #include <cassert>
#include <mutex>
#include <sstream> #include <sstream>
namespace { namespace {
int ffmpeg_lockmgr_cb(void **arg, enum AVLockOp op) {
std::mutex *mutex = (std::mutex *)*arg;
switch (op) {
case AV_LOCK_CREATE:
mutex = new std::mutex();
break;
case AV_LOCK_OBTAIN:
mutex->lock();
break;
case AV_LOCK_RELEASE:
mutex->unlock();
case AV_LOCK_DESTROY:
delete mutex;
break;
}
return 0;
}
int readFunction(void *opaque, uint8_t *buf, int buf_size) { int readFunction(void *opaque, uint8_t *buf, int buf_size) {
auto &iss = *reinterpret_cast<std::istringstream *>(opaque); auto &iss = *reinterpret_cast<std::istringstream *>(opaque);
iss.read(reinterpret_cast<char *>(buf), buf_size); iss.read(reinterpret_cast<char *>(buf), buf_size);
@ -34,12 +14,6 @@ int readFunction(void *opaque, uint8_t *buf, int buf_size) {
} // namespace } // namespace
FrameReader::FrameReader(bool local_cache, int chunk_size, int retries) : FileReader(local_cache, chunk_size, retries) { FrameReader::FrameReader(bool local_cache, int chunk_size, int retries) : FileReader(local_cache, chunk_size, retries) {
static std::once_flag once_flag;
std::call_once(once_flag, [] {
av_lockmgr_register(ffmpeg_lockmgr_cb);
av_register_all();
});
pFormatCtx_ = avformat_alloc_context(); pFormatCtx_ = avformat_alloc_context();
av_frame_ = av_frame_alloc(); av_frame_ = av_frame_alloc();
rgb_frame_ = av_frame_alloc(); rgb_frame_ = av_frame_alloc();
@ -50,6 +24,7 @@ FrameReader::~FrameReader() {
for (auto &f : frames_) { for (auto &f : frames_) {
av_free_packet(&f.pkt); av_free_packet(&f.pkt);
} }
if (pCodecCtx_) avcodec_free_context(&pCodecCtx_); if (pCodecCtx_) avcodec_free_context(&pCodecCtx_);
if (pFormatCtx_) avformat_close_input(&pFormatCtx_); if (pFormatCtx_) avformat_close_input(&pFormatCtx_);
if (av_frame_) av_frame_free(&av_frame_); if (av_frame_) av_frame_free(&av_frame_);
@ -75,22 +50,22 @@ bool FrameReader::load(const std::string &url, std::atomic<bool> *abort) {
pFormatCtx_->pb = avio_ctx_; pFormatCtx_->pb = avio_ctx_;
pFormatCtx_->probesize = 10 * 1024 * 1024; // 10MB pFormatCtx_->probesize = 10 * 1024 * 1024; // 10MB
int err = avformat_open_input(&pFormatCtx_, url.c_str(), NULL, NULL); int ret = avformat_open_input(&pFormatCtx_, url.c_str(), NULL, NULL);
if (err != 0) { if (ret != 0) {
char err_str[1024] = {0}; char err_str[1024] = {0};
av_strerror(err, err_str, std::size(err_str)); av_strerror(ret, err_str, std::size(err_str));
printf("Error loading video - %s - %s\n", err_str, url.c_str()); printf("Error loading video - %s - %s\n", err_str, url.c_str());
return false; return false;
} }
avformat_find_stream_info(pFormatCtx_, NULL); avformat_find_stream_info(pFormatCtx_, NULL);
// av_dump_format(pFormatCtx_, 0, url.c_str(), 0); // av_dump_format(pFormatCtx_, 0, url.c_str(), 0);
auto pCodecCtxOrig = pFormatCtx_->streams[0]->codec; AVStream *video = pFormatCtx_->streams[0];
auto pCodec = avcodec_find_decoder(pCodecCtxOrig->codec_id); auto pCodec = avcodec_find_decoder(video->codec->codec_id);
if (!pCodec) return false; if (!pCodec) return false;
pCodecCtx_ = avcodec_alloc_context3(pCodec); pCodecCtx_ = avcodec_alloc_context3(pCodec);
int ret = avcodec_copy_context(pCodecCtx_, pCodecCtxOrig); ret = avcodec_parameters_to_context(pCodecCtx_, video->codecpar);
if (ret != 0) return false; if (ret != 0) return false;
// pCodecCtx_->thread_count = 0; // pCodecCtx_->thread_count = 0;
@ -98,14 +73,14 @@ bool FrameReader::load(const std::string &url, std::atomic<bool> *abort) {
ret = avcodec_open2(pCodecCtx_, pCodec, NULL); ret = avcodec_open2(pCodecCtx_, pCodec, NULL);
if (ret < 0) return false; if (ret < 0) return false;
width = (pCodecCtxOrig->width + 3) & ~3; width = (pCodecCtx_->width + 3) & ~3;
height = pCodecCtxOrig->height; height = pCodecCtx_->height;
rgb_sws_ctx_ = sws_getContext(pCodecCtxOrig->width, pCodecCtxOrig->height, AV_PIX_FMT_YUV420P, rgb_sws_ctx_ = sws_getContext(pCodecCtx_->width, pCodecCtx_->height, AV_PIX_FMT_YUV420P,
width, height, AV_PIX_FMT_BGR24, width, height, AV_PIX_FMT_BGR24,
SWS_FAST_BILINEAR, NULL, NULL, NULL); SWS_FAST_BILINEAR, NULL, NULL, NULL);
if (!rgb_sws_ctx_) return false; if (!rgb_sws_ctx_) return false;
yuv_sws_ctx_ = sws_getContext(pCodecCtxOrig->width, pCodecCtxOrig->height, AV_PIX_FMT_YUV420P, yuv_sws_ctx_ = sws_getContext(pCodecCtx_->width, pCodecCtx_->height, AV_PIX_FMT_YUV420P,
width, height, AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_YUV420P,
SWS_FAST_BILINEAR, NULL, NULL, NULL); SWS_FAST_BILINEAR, NULL, NULL, NULL);
if (!yuv_sws_ctx_) return false; if (!yuv_sws_ctx_) return false;
@ -113,10 +88,10 @@ bool FrameReader::load(const std::string &url, std::atomic<bool> *abort) {
frames_.reserve(60 * 20); // 20fps, one minute frames_.reserve(60 * 20); // 20fps, one minute
while (!(abort && *abort)) { while (!(abort && *abort)) {
Frame &frame = frames_.emplace_back(); Frame &frame = frames_.emplace_back();
err = av_read_frame(pFormatCtx_, &frame.pkt); ret = av_read_frame(pFormatCtx_, &frame.pkt);
if (err < 0) { if (ret < 0) {
frames_.pop_back(); frames_.pop_back();
valid_ = (err == AVERROR_EOF); valid_ = (ret == AVERROR_EOF);
break; break;
} }
// some stream seems to contian no keyframes // some stream seems to contian no keyframes
@ -150,17 +125,27 @@ bool FrameReader::decode(int idx, uint8_t *rgb, uint8_t *yuv) {
for (int i = from_idx; i <= idx; ++i) { for (int i = from_idx; i <= idx; ++i) {
Frame &frame = frames_[i]; Frame &frame = frames_[i];
if ((!frame.decoded || i == idx) && !frame.failed) { if ((!frame.decoded || i == idx) && !frame.failed) {
avcodec_decode_video2(pCodecCtx_, av_frame_, &frame.decoded, &(frame.pkt)); frame.decoded = decodeFrame(&frame.pkt);
frame.failed = !frame.decoded; frame.failed = !frame.decoded;
if (frame.decoded && i == idx) { if (frame.decoded && i == idx) {
return decodeFrame(av_frame_, rgb, yuv); return copyBuffers(av_frame_, rgb, yuv);
} }
} }
} }
return false; return false;
} }
bool FrameReader::decodeFrame(AVFrame *f, uint8_t *rgb, uint8_t *yuv) { bool FrameReader::decodeFrame(AVPacket *pkt) {
int ret = avcodec_send_packet(pCodecCtx_, pkt);
if (ret < 0) {
printf("Error sending a packet for decoding\n");
return false;
}
ret = avcodec_receive_frame(pCodecCtx_, av_frame_);
return ret == 0;
}
bool FrameReader::copyBuffers(AVFrame *f, uint8_t *rgb, uint8_t *yuv) {
// images is going to be written to output buffers, no alignment (align = 1) // images is going to be written to output buffers, no alignment (align = 1)
if (yuv) { if (yuv) {
av_image_fill_arrays(yuv_frame_->data, yuv_frame_->linesize, yuv, AV_PIX_FMT_YUV420P, width, height, 1); av_image_fill_arrays(yuv_frame_->data, yuv_frame_->linesize, yuv, AV_PIX_FMT_YUV420P, width, height, 1);

@ -2,6 +2,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "selfdrive/ui/replay/filereader.h" #include "selfdrive/ui/replay/filereader.h"
extern "C" { extern "C" {
@ -26,7 +27,8 @@ public:
private: private:
bool decode(int idx, uint8_t *rgb, uint8_t *yuv); bool decode(int idx, uint8_t *rgb, uint8_t *yuv);
bool decodeFrame(AVFrame *f, uint8_t *rgb, uint8_t *yuv); bool decodeFrame(AVPacket *pkt);
bool copyBuffers(AVFrame *f, uint8_t *rgb, uint8_t *yuv);
struct Frame { struct Frame {
AVPacket pkt = {}; AVPacket pkt = {};

Loading…
Cancel
Save