10 #if defined(__GNUC__) // Needed for ffmpeg headers. Only allowed here when not using precomp. headers 11 #define __STDC_CONSTANT_MACROS // Needed for having "UINT64_C" and so 16 #include <mrpt/config.h> 22 #define _MSC_STDINT_H_ // We already have pstdint.h in MRPT 23 #include <libavformat/avformat.h> 24 #include <libavcodec/avcodec.h> 25 #include <libswscale/swscale.h> 46 AVFormatContext *pFormatCtx;
48 AVCodecContext *pCodecCtx;
52 SwsContext *img_convert_ctx;
53 std::vector<uint8_t>
buffer;
59 #define MY_FFMPEG_STATE const_cast<TFFMPEGContext*>(static_cast<const TFFMPEGContext*>(m_state.get())) 72 ctx->pFormatCtx = NULL;
73 ctx->pCodecCtx = NULL;
77 ctx->pFrameRGB = NULL;
78 ctx->img_convert_ctx = NULL;
109 return ctx->pFormatCtx != NULL;
129 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,2,0) 130 if(avformat_open_input( &ctx->pFormatCtx, url.c_str(), NULL, NULL)!=0)
132 if(av_open_input_file( &ctx->pFormatCtx, url.c_str(), NULL, 0, NULL)!=0)
136 ctx->pFormatCtx = NULL;
137 std::cerr <<
"[CFFMPEG_InputStream::openURL] Cannot open video: " << url << std::endl;
143 #
if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,35,0)
144 avformat_find_stream_info(ctx->pFormatCtx, NULL)<0
146 av_find_stream_info(ctx->pFormatCtx)<0
150 std::cerr <<
"[CFFMPEG_InputStream::openURL] Couldn't find stream information: " << url << std::endl;
157 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,2,0) 158 av_dump_format(ctx->pFormatCtx, 0, url.c_str(),
false);
160 dump_format(ctx->pFormatCtx, 0, url.c_str(),
false);
166 for(
unsigned int i=0; i<ctx->pFormatCtx->nb_streams; i++)
168 if(ctx->pFormatCtx->streams[i]->codec->codec_type==
169 #
if LIBAVCODEC_VERSION_INT<AV_VERSION_INT(53,0,0)
176 ctx->videoStream=(int)i;
180 if(ctx->videoStream==-1)
182 std::cerr <<
"[CFFMPEG_InputStream::openURL] Didn't find a video stream: " << url << std::endl;
187 ctx->pCodecCtx= ctx->pFormatCtx->streams[ctx->videoStream]->codec;
190 ctx->pCodec=avcodec_find_decoder(ctx->pCodecCtx->codec_id);
191 if(ctx->pCodec==NULL)
193 std::cerr <<
"[CFFMPEG_InputStream::openURL] Codec not found: " << url << std::endl;
198 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,6,0) 199 if(avcodec_open2(ctx->pCodecCtx, ctx->pCodec,NULL)<0)
201 if(avcodec_open(ctx->pCodecCtx, ctx->pCodec)<0)
204 std::cerr <<
"[CFFMPEG_InputStream::openURL] Could not open codec: " << url << std::endl;
208 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,46,0) 210 ctx->pFrame=av_frame_alloc();
212 ctx->pFrameRGB=av_frame_alloc();
215 ctx->pFrame=avcodec_alloc_frame();
217 ctx->pFrameRGB=avcodec_alloc_frame();
221 if(ctx->pFrameRGB==NULL || ctx->pFrame==NULL)
223 std::cerr <<
"[CFFMPEG_InputStream::openURL] Could not alloc memory for frame buffers: " << url << std::endl;
228 size_t numBytes=avpicture_get_size(
230 #
if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,00,0)
231 AV_PIX_FMT_GRAY8 : AV_PIX_FMT_BGR24,
233 PIX_FMT_GRAY8 : PIX_FMT_BGR24,
235 ctx->pCodecCtx->width,
236 ctx->pCodecCtx->height);
238 ctx->buffer.resize(numBytes);
242 (AVPicture *)ctx->pFrameRGB,
245 #
if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,00,0)
246 AV_PIX_FMT_GRAY8 : AV_PIX_FMT_BGR24,
248 PIX_FMT_GRAY8 : PIX_FMT_BGR24,
250 ctx->pCodecCtx->width,
251 ctx->pCodecCtx->height);
266 if (!this->
isOpen())
return;
273 avcodec_close(ctx->pCodecCtx);
280 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,35,0) 281 avformat_close_input(&ctx->pFormatCtx);
283 av_close_input_file(ctx->pFormatCtx);
285 ctx->pFormatCtx = NULL;
293 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,46,0) 294 av_frame_free(&ctx->pFrameRGB);
296 av_free(ctx->pFrameRGB);
302 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,46,0) 303 av_frame_free(&ctx->pFrame);
305 av_free(ctx->pFrame);
310 if (ctx->img_convert_ctx)
312 sws_freeContext( ctx->img_convert_ctx );
313 ctx->img_convert_ctx = NULL;
325 if (!this->
isOpen())
return false;
332 while(av_read_frame(ctx->pFormatCtx, &packet)>=0)
335 if(packet.stream_index==ctx->videoStream)
338 #if LIBAVCODEC_VERSION_MAJOR>52 || (LIBAVCODEC_VERSION_MAJOR==52 && LIBAVCODEC_VERSION_MINOR>=72) 339 avcodec_decode_video2(
345 avcodec_decode_video(
356 ctx->img_convert_ctx = sws_getCachedContext(
357 ctx->img_convert_ctx,
358 ctx->pCodecCtx->width,
359 ctx->pCodecCtx->height,
360 ctx->pCodecCtx->pix_fmt,
361 ctx->pCodecCtx->width,
362 ctx->pCodecCtx->height,
364 #
if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,00,0)
365 AV_PIX_FMT_GRAY8 : AV_PIX_FMT_BGR24,
367 PIX_FMT_GRAY8 : PIX_FMT_BGR24,
373 ctx->img_convert_ctx,
375 ctx->pFrame->linesize,0,
376 ctx->pCodecCtx->height,
377 ctx->pFrameRGB->data,
378 ctx->pFrameRGB->linesize);
387 ctx->pCodecCtx->width,
388 ctx->pCodecCtx->height,
390 ctx->pFrameRGB->data[0]
394 av_free_packet(&packet);
400 av_free_packet(&packet);
415 if (!this->
isOpen())
return -1;
419 if (!ctx->pCodecCtx)
return -1;
421 return static_cast<double>(ctx->pCodecCtx->time_base.den) / ctx->pCodecCtx->time_base.num;
A class for storing images as grayscale or RGB bitmaps.
#define THROW_EXCEPTION(msg)
Contains classes for various device interfaces.
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.
GLsizei const GLchar ** string
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void set(const T *p)
This method can change the pointer, since the change is made explicitly, not through copy operators t...