46 #include <visp3/core/vpConfig.h>
47 #include <visp3/core/vpDebug.h>
48 #include <visp3/io/vpFFMPEG.h>
49 #include <visp3/core/vpImageConvert.h>
51 #ifdef VISP_HAVE_FFMPEG
56 #include <libavformat/avformat.h>
57 #include <libswscale/swscale.h>
64 : width(-1), height(-1), frameNumber(0), pFormatCtx(NULL), pCodecCtx(NULL),
65 pCodec(NULL), pFrame(NULL), pFrameRGB(NULL), pFrameGRAY(NULL), packet(NULL),
66 img_convert_ctx(NULL), videoStream(0), numBytes(0), buffer(NULL), index(),
67 streamWasOpen(false), streamWasInitialized(false), color_type(COLORED),
68 f(NULL), outbuf(NULL), picture_buf(NULL), outbuf_size(0), out_size(0),
69 bit_rate(500000), encoderWasOpened(false),
70 framerate_stream(-1), framerate_encoder(25)
72 packet =
new AVPacket;
97 this->color_type = colortype;
100 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,0,0) // libavformat 52.84.0
101 if (av_open_input_file (&pFormatCtx, filename, NULL, 0, NULL) != 0)
103 if (avformat_open_input (&pFormatCtx, filename, NULL, NULL) != 0)
106 vpTRACE(
"Couldn't open file ");
110 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,21,0) // libavformat 53.21.0
111 if (av_find_stream_info (pFormatCtx) < 0)
113 if (avformat_find_stream_info (pFormatCtx, NULL) < 0)
118 bool found_codec =
false;
123 for (
unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
125 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,0,0)
126 if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
128 if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
133 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(55,12,0)
134 framerate_stream = pFormatCtx->streams[i]->r_frame_rate.num;
135 framerate_stream /= pFormatCtx->streams[i]->r_frame_rate.den;
137 framerate_stream = pFormatCtx->streams[i]->avg_frame_rate.num;
138 framerate_stream /= pFormatCtx->streams[i]->avg_frame_rate.den;
147 pCodecCtx = pFormatCtx->streams[videoStream]->codec;
148 pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
156 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
157 if (avcodec_open (pCodecCtx, pCodec) < 0)
159 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
162 vpTRACE(
"Could not open codec");
166 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
167 pFrame = avcodec_alloc_frame();
169 pFrame = av_frame_alloc();
174 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
175 pFrameRGB=avcodec_alloc_frame();
177 pFrameRGB=av_frame_alloc();
180 if (pFrameRGB == NULL)
183 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
188 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
189 pFrameGRAY=avcodec_alloc_frame();
191 pFrameGRAY=av_frame_alloc();
194 if (pFrameGRAY == NULL)
197 numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
203 width = pCodecCtx->width ;
204 height = pCodecCtx->height ;
205 buffer = (uint8_t *) malloc ((
unsigned int)(
sizeof (uint8_t)) * (
unsigned int)numBytes);
209 vpTRACE(
"Didn't find a video stream");
214 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
217 avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
219 streamWasOpen =
true;
234 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
237 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_GRAY8, SWS_BICUBIC, NULL, NULL, NULL);
239 int ret = av_seek_frame(pFormatCtx, (
int)videoStream, 0, AVSEEK_FLAG_ANY) ;
242 vpTRACE(
"Error rewinding stream for full indexing") ;
245 avcodec_flush_buffers(pCodecCtx) ;
250 av_init_packet(packet);
251 while (av_read_frame (pFormatCtx, packet) >= 0)
253 if (packet->stream_index == (
int)videoStream)
255 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
256 ret = avcodec_decode_video(pCodecCtx, pFrame,
257 &frameFinished, packet->data, packet->size);
259 ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
265 vpTRACE(
"Unable to decode video picture");
267 index.push_back(packet->dts);
273 frameNumber = index.size();
274 av_free_packet(packet);
276 streamWasInitialized =
true;
293 if (frame < frameNumber && streamWasInitialized==
true)
295 int64_t targetPts = index[frame];
296 av_seek_frame(pFormatCtx, (
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
300 vpTRACE(
"Couldn't get a frame");
304 avcodec_flush_buffers(pCodecCtx) ;
308 av_init_packet(packet);
309 while (av_read_frame (pFormatCtx, packet) >= 0)
311 if (packet->stream_index == (
int)videoStream)
313 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
314 avcodec_decode_video(pCodecCtx, pFrame,
315 &frameFinished, packet->data, packet->size);
317 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
322 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
324 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
332 av_free_packet(packet);
348 if (streamWasInitialized ==
false)
350 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
354 av_init_packet(packet);
355 while (av_read_frame (pFormatCtx, packet) >= 0)
357 if (packet->stream_index == (
int)videoStream)
359 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
360 avcodec_decode_video(pCodecCtx, pFrame,
361 &frameFinished, packet->data, packet->size);
363 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
368 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
370 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
377 av_free_packet(packet);
392 if (frame < frameNumber && streamWasInitialized==
true)
394 int64_t targetPts = index[frame];
395 av_seek_frame(pFormatCtx,(
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
399 vpTRACE(
"Couldn't get a frame");
403 avcodec_flush_buffers(pCodecCtx) ;
407 av_init_packet(packet);
408 while (av_read_frame (pFormatCtx, packet) >= 0)
410 if (packet->stream_index == (
int)videoStream)
412 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
413 avcodec_decode_video(pCodecCtx, pFrame,
414 &frameFinished, packet->data, packet->size);
416 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
421 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
423 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
431 av_free_packet(packet);
447 if (streamWasInitialized ==
false)
449 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
453 av_init_packet(packet);
454 while (av_read_frame (pFormatCtx, packet) >= 0)
456 if (packet->stream_index == (
int)videoStream)
458 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
459 avcodec_decode_video(pCodecCtx, pFrame,
460 &frameFinished, packet->data, packet->size);
462 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
467 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
469 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
476 av_free_packet(packet);
491 if(height < 0 || width < 0){
494 I.
resize((
unsigned int)height, (
unsigned int)width);
497 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
498 unsigned char* output = NULL;
502 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
503 int widthStep = pFrameRGB->linesize[0];
504 for(
int i=0 ; i < height ; i++)
507 output = beginOutput + 4 * width * i;
508 for(
int j=0 ; j < width ; j++)
510 *(output++) = *(line);
511 *(output++) = *(line+1);
512 *(output++) = *(line+2);
524 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
525 int widthStep = pFrameGRAY->linesize[0];
526 for(
int i=0 ; i < height ; i++)
529 output = beginOutput + 4 * width * i;
530 for(
int j=0 ; j < width ; j++)
535 *output++ = *(line);;
555 if(height < 0 || width < 0){
558 I.
resize((
unsigned int)height, (
unsigned int)width);
561 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
562 unsigned char* output = NULL;
566 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
567 int widthStep = pFrameGRAY->linesize[0];
568 for(
int i=0 ; i < height ; i++)
571 output = beginOutput + width * i;
572 for(
int j=0 ; j < width ; j++)
574 *(output++) = *(line);
585 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
586 int widthStep = pFrameRGB->linesize[0];
587 for (
int i = 0 ; i < height ; i++)
601 if (buffer != NULL) {
616 if (pCodecCtx) avcodec_close(pCodecCtx);
619 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
620 av_close_input_file(pFormatCtx);
622 avformat_close_input(&pFormatCtx);
625 streamWasOpen =
false;
627 if (encoderWasOpened)
631 if(buffer!=NULL)
delete[] buffer;
633 if(outbuf != NULL)
delete[] outbuf;
635 if(picture_buf != NULL)
delete[] picture_buf;
639 if (pCodecCtx) avcodec_close(pCodecCtx);
642 encoderWasOpened =
false;
644 if(streamWasInitialized || encoderWasOpened){
645 sws_freeContext (img_convert_ctx);
647 streamWasInitialized =
false;
665 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,51,110) // libavcodec 54.51.100
674 pCodec = avcodec_find_encoder(codec);
675 if (pCodec == NULL) {
676 fprintf(stderr,
"codec not found\n");
680 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
681 pCodecCtx = avcodec_alloc_context();
683 pCodecCtx = avcodec_alloc_context3(NULL);
686 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
687 pFrame = avcodec_alloc_frame();
688 pFrameRGB = avcodec_alloc_frame();
690 pFrame = av_frame_alloc();
691 pFrameRGB = av_frame_alloc();
695 pCodecCtx->bit_rate = (int)bit_rate;
697 pCodecCtx->width = (int)w;
698 pCodecCtx->height = (int)h;
699 this->width = (int)w;
700 this->height = (int)h;
702 pCodecCtx->time_base.num = 1;
703 pCodecCtx->time_base.den = framerate_encoder;
704 pCodecCtx->gop_size = 10;
705 pCodecCtx->max_b_frames=1;
706 pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
709 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
710 if (avcodec_open (pCodecCtx, pCodec) < 0) {
712 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
714 fprintf(stderr,
"could not open codec\n");
720 f = fopen(filename,
"wb");
722 fprintf(stderr,
"could not open %s\n", filename);
726 outbuf_size = 100000;
727 outbuf =
new uint8_t[outbuf_size];
729 numBytes = avpicture_get_size (PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);
730 picture_buf =
new uint8_t[numBytes];
731 avpicture_fill((AVPicture *)pFrame, picture_buf, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
733 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
734 buffer =
new uint8_t[numBytes];
735 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
737 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
739 encoderWasOpened =
true;
754 if (encoderWasOpened ==
false)
756 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
761 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
762 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
763 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
764 fwrite(outbuf, 1, (
size_t)out_size, f);
767 av_init_packet(&pkt);
772 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
774 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
778 fwrite(pkt.data, 1, pkt.size, f);
779 av_free_packet(&pkt);
796 if (encoderWasOpened ==
false)
798 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
803 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
804 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
805 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
806 fwrite(outbuf, 1, (
size_t)out_size, f);
809 av_init_packet(&pkt);
814 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
816 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
820 fwrite(pkt.data, 1, pkt.size, f);
821 av_free_packet(&pkt);
836 if (encoderWasOpened ==
false)
838 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
846 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
847 ret = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, NULL);
848 fwrite(outbuf, 1, (
size_t)out_size, f);
851 av_init_packet(&pkt);
855 ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);
857 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
861 fwrite(pkt.data, 1, pkt.size, f);
862 av_free_packet(&pkt);
872 fwrite(outbuf, 1, 4, f);
883 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
884 unsigned char* input = NULL;
885 unsigned char* output = NULL;
886 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
887 int widthStep = pFrameRGB->linesize[0];
889 for(
int i=0 ; i < height ; i++)
891 input = beginInput + 4 * i * width;
892 output = beginOutput + i * widthStep;
893 for(
int j=0 ; j < width ; j++)
895 *(output++) = *(input);
896 *(output++) = *(input+1);
897 *(output++) = *(input+2);
910 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
911 unsigned char* input = NULL;
912 unsigned char* output = NULL;
913 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
914 int widthStep = pFrameRGB->linesize[0];
916 for(
int i=0 ; i < height ; i++)
918 input = beginInput + i * width;
919 output = beginOutput + i * widthStep;
920 for(
int j=0 ; j < width ; j++)
922 *(output++) = *(input);
923 *(output++) = *(input);
924 *(output++) = *(input);
931 #elif !defined(VISP_BUILD_SHARED_LIBS)
933 void dummy_vpFFMPEG() {};
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
Type * bitmap
points toward the bitmap
bool saveFrame(vpImage< vpRGBa > &I)
bool getFrame(vpImage< vpRGBa > &I, unsigned int frameNumber)
error that can be emited by ViSP classes.
bool openStream(const char *filename, vpFFMPEGColorType color_type)
void resize(const unsigned int h, const unsigned int w)
set the size of the image without initializing it.
bool acquire(vpImage< vpRGBa > &I)
bool openEncoder(const char *filename, unsigned int width, unsigned int height, AVCodecID codec=AV_CODEC_ID_MPEG1VIDEO)