10 #if defined(__GNUC__) // Needed for ffmpeg headers. Only allowed here when not 12 #define __STDC_CONSTANT_MACROS // Needed for having "UINT64_C" and so 17 #include <mrpt/config.h> 21 #define _MSC_STDINT_H_ // We already have pstdint.h in MRPT 22 #include <libavformat/avformat.h> 23 #include <libavcodec/avcodec.h> 24 #include <libswscale/swscale.h> 25 #include <libavutil/imgutils.h> 43 AVFormatContext* pFormatCtx;
45 AVCodecContext* pCodecCtx;
49 SwsContext* img_convert_ctx;
50 std::vector<uint8_t>
buffer;
58 TFFMPEGContext m_state;
67 : m_impl(mrpt::make_impl<CFFMPEG_InputStream::Impl>())
69 TFFMPEGContext* ctx = &m_impl->m_state;
71 ctx->pFormatCtx =
nullptr;
72 ctx->pCodecCtx =
nullptr;
73 ctx->pCodec =
nullptr;
75 ctx->pFrame =
nullptr;
76 ctx->pFrameRGB =
nullptr;
77 ctx->img_convert_ctx =
nullptr;
106 const TFFMPEGContext* ctx = &
m_impl->m_state;
107 return ctx->pFormatCtx !=
nullptr;
122 TFFMPEGContext* ctx = &
m_impl->m_state;
128 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 2, 0) 129 if (avformat_open_input(&ctx->pFormatCtx,
url.c_str(),
nullptr,
nullptr) !=
132 if (av_open_input_file(
133 &ctx->pFormatCtx,
url.c_str(),
nullptr, 0,
nullptr) != 0)
137 ctx->pFormatCtx =
nullptr;
138 std::cerr <<
"[CFFMPEG_InputStream::openURL] Cannot open video: " <<
url 145 #
if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 35, 0)
146 avformat_find_stream_info(ctx->pFormatCtx,
nullptr) < 0
148 av_find_stream_info(ctx->pFormatCtx) < 0
152 std::cerr <<
"[CFFMPEG_InputStream::openURL] Couldn't find stream " 161 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 2, 0) 162 av_dump_format(ctx->pFormatCtx, 0,
url.c_str(),
false);
164 dump_format(ctx->pFormatCtx, 0,
url.c_str(),
false);
169 ctx->videoStream = -1;
170 for (
unsigned int i = 0; i < ctx->pFormatCtx->nb_streams; i++)
172 if (ctx->pFormatCtx->streams[i]->codec->codec_type ==
173 #
if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 0, 0)
180 ctx->videoStream = (int)i;
184 if (ctx->videoStream == -1)
187 <<
"[CFFMPEG_InputStream::openURL] Didn't find a video stream: " 193 ctx->pCodecCtx = ctx->pFormatCtx->streams[ctx->videoStream]->codec;
196 ctx->pCodec = avcodec_find_decoder(ctx->pCodecCtx->codec_id);
197 if (ctx->pCodec ==
nullptr)
199 std::cerr <<
"[CFFMPEG_InputStream::openURL] Codec not found: " <<
url 205 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 6, 0) 206 if (avcodec_open2(ctx->pCodecCtx, ctx->pCodec,
nullptr) < 0)
208 if (avcodec_open(ctx->pCodecCtx, ctx->pCodec) < 0)
211 std::cerr <<
"[CFFMPEG_InputStream::openURL] Could not open codec: " 216 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 46, 0) 218 ctx->pFrame = av_frame_alloc();
220 ctx->pFrameRGB = av_frame_alloc();
223 ctx->pFrame = avcodec_alloc_frame();
225 ctx->pFrameRGB = avcodec_alloc_frame();
228 if (ctx->pFrameRGB ==
nullptr || ctx->pFrame ==
nullptr)
230 std::cerr <<
"[CFFMPEG_InputStream::openURL] Could not alloc memory " 231 "for frame buffers: " 237 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(54, 6, 0) 238 size_t numBytes = avpicture_get_size(
240 size_t numBytes = av_image_get_buffer_size(
243 #
if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 00, 0)
250 ctx->pCodecCtx->width, ctx->pCodecCtx->height
251 #
if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(54, 6, 0)
257 ctx->buffer.resize(numBytes);
261 (AVPicture*)ctx->pFrameRGB, &ctx->buffer[0],
263 #
if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 00, 0)
270 ctx->pCodecCtx->width, ctx->pCodecCtx->height);
284 if (!this->
isOpen())
return;
286 TFFMPEGContext* ctx = &
m_impl->m_state;
291 avcodec_close(ctx->pCodecCtx);
292 ctx->pCodecCtx =
nullptr;
298 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 35, 0) 299 avformat_close_input(&ctx->pFormatCtx);
301 av_close_input_file(ctx->pFormatCtx);
303 ctx->pFormatCtx =
nullptr;
311 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 46, 0) 312 av_frame_free(&ctx->pFrameRGB);
314 av_free(ctx->pFrameRGB);
316 ctx->pFrameRGB =
nullptr;
320 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 46, 0) 321 av_frame_free(&ctx->pFrame);
323 av_free(ctx->pFrame);
325 ctx->pFrame =
nullptr;
328 if (ctx->img_convert_ctx)
330 sws_freeContext(ctx->img_convert_ctx);
331 ctx->img_convert_ctx =
nullptr;
343 if (!this->
isOpen())
return false;
345 TFFMPEGContext* ctx = &
m_impl->m_state;
350 while (av_read_frame(ctx->pFormatCtx, &packet) >= 0)
353 if (packet.stream_index == ctx->videoStream)
356 #if LIBAVCODEC_VERSION_MAJOR > 52 || \ 357 (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 72) 358 avcodec_decode_video2(
359 ctx->pCodecCtx, ctx->pFrame, &frameFinished, &packet);
361 avcodec_decode_video(
362 ctx->pCodecCtx, ctx->pFrame, &frameFinished, packet.data,
369 ctx->img_convert_ctx = sws_getCachedContext(
370 ctx->img_convert_ctx, ctx->pCodecCtx->width,
371 ctx->pCodecCtx->height, ctx->pCodecCtx->pix_fmt,
372 ctx->pCodecCtx->width, ctx->pCodecCtx->height,
374 #
if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 00, 0)
381 SWS_BICUBIC,
nullptr,
nullptr,
nullptr);
384 ctx->img_convert_ctx, ctx->pFrame->data,
385 ctx->pFrame->linesize, 0, ctx->pCodecCtx->height,
386 ctx->pFrameRGB->data, ctx->pFrameRGB->linesize);
394 if (ctx->pFrameRGB->linesize[0] !=
397 "FIXME: linesize!=width case not handled yet.")
400 ctx->pCodecCtx->width, ctx->pCodecCtx->height,
402 ctx->pFrameRGB->data[0]);
405 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 16, 0) 406 av_free_packet(&packet);
408 av_packet_unref(&packet);
415 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 16, 0) 416 av_free_packet(&packet);
418 av_packet_unref(&packet);
434 if (!this->
isOpen())
return -1;
436 const TFFMPEGContext* ctx = &
m_impl->m_state;
438 if (!ctx->pCodecCtx)
return -1;
440 return static_cast<double>(ctx->pCodecCtx->time_base.den) /
441 ctx->pCodecCtx->time_base.num;
#define THROW_EXCEPTION(msg)
Contains classes for various device interfaces.
GLsizei const GLchar ** string
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A class for storing images as grayscale or RGB bitmaps.
void loadFromMemoryBuffer(unsigned int width, unsigned int height, bool color, unsigned char *rawpixels, bool swapRedBlue=false)
Reads the image from raw pixels buffer in memory.