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);
560 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
564 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
565 int widthStep = pFrameGRAY->linesize[0];
566 for(
int i=0 ; i < height ; i++)
568 unsigned char *line = input;
569 unsigned char *output = beginOutput + width * i;
570 for(
int j=0 ; j < width ; j++)
572 *(output++) = *(line);
583 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
584 int widthStep = pFrameRGB->linesize[0];
585 for (
int i = 0 ; i < height ; i++)
599 if (buffer != NULL) {
614 if (pCodecCtx) avcodec_close(pCodecCtx);
617 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
618 av_close_input_file(pFormatCtx);
620 avformat_close_input(&pFormatCtx);
623 streamWasOpen =
false;
625 if (encoderWasOpened)
629 if(buffer!=NULL)
delete[] buffer;
631 if(outbuf != NULL)
delete[] outbuf;
633 if(picture_buf != NULL)
delete[] picture_buf;
637 if (pCodecCtx) avcodec_close(pCodecCtx);
640 encoderWasOpened =
false;
642 if(streamWasInitialized || encoderWasOpened){
643 sws_freeContext (img_convert_ctx);
645 streamWasInitialized =
false;
663 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,51,110) // libavcodec 54.51.100
672 pCodec = avcodec_find_encoder(codec);
673 if (pCodec == NULL) {
674 fprintf(stderr,
"codec not found\n");
678 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
679 pCodecCtx = avcodec_alloc_context();
681 pCodecCtx = avcodec_alloc_context3(NULL);
684 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
685 pFrame = avcodec_alloc_frame();
686 pFrameRGB = avcodec_alloc_frame();
688 pFrame = av_frame_alloc();
689 pFrameRGB = av_frame_alloc();
693 pCodecCtx->bit_rate = (int)bit_rate;
695 pCodecCtx->width = (int)w;
696 pCodecCtx->height = (int)h;
697 this->width = (int)w;
698 this->height = (int)h;
700 pCodecCtx->time_base.num = 1;
701 pCodecCtx->time_base.den = framerate_encoder;
702 pCodecCtx->gop_size = 10;
703 pCodecCtx->max_b_frames=1;
704 pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
707 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
708 if (avcodec_open (pCodecCtx, pCodec) < 0) {
710 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
712 fprintf(stderr,
"could not open codec\n");
718 f = fopen(filename,
"wb");
720 fprintf(stderr,
"could not open %s\n", filename);
724 outbuf_size = 100000;
725 outbuf =
new uint8_t[outbuf_size];
727 numBytes = avpicture_get_size (PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);
728 picture_buf =
new uint8_t[numBytes];
729 avpicture_fill((AVPicture *)pFrame, picture_buf, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
731 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
732 buffer =
new uint8_t[numBytes];
733 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
735 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
737 encoderWasOpened =
true;
752 if (encoderWasOpened ==
false)
754 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
759 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
760 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
761 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
762 fwrite(outbuf, 1, (
size_t)out_size, f);
765 av_init_packet(&pkt);
770 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
772 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
776 fwrite(pkt.data, 1, pkt.size, f);
777 av_free_packet(&pkt);
794 if (encoderWasOpened ==
false)
796 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
801 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
802 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
803 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
804 fwrite(outbuf, 1, (
size_t)out_size, f);
807 av_init_packet(&pkt);
812 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
814 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
818 fwrite(pkt.data, 1, pkt.size, f);
819 av_free_packet(&pkt);
834 if (encoderWasOpened ==
false)
836 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
844 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
845 ret = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, NULL);
846 fwrite(outbuf, 1, (
size_t)out_size, f);
849 av_init_packet(&pkt);
853 ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);
855 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
859 fwrite(pkt.data, 1, pkt.size, f);
860 av_free_packet(&pkt);
870 fwrite(outbuf, 1, 4, f);
881 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
882 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
883 int widthStep = pFrameRGB->linesize[0];
885 for(
int i=0 ; i < height ; i++)
887 unsigned char *input = beginInput + 4 * i * width;
888 unsigned char *output = beginOutput + i * widthStep;
889 for(
int j=0 ; j < width ; j++)
891 *(output++) = *(input);
892 *(output++) = *(input+1);
893 *(output++) = *(input+2);
906 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
907 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
908 int widthStep = pFrameRGB->linesize[0];
910 for(
int i=0 ; i < height ; i++)
912 unsigned char *input = beginInput + i * width;
913 unsigned char *output = beginOutput + i * widthStep;
914 for(
int j=0 ; j < width ; j++)
916 *(output++) = *(input);
917 *(output++) = *(input);
918 *(output++) = *(input);
925 #elif !defined(VISP_BUILD_SHARED_LIBS)
927 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)
resize the image : Image initialization
bool acquire(vpImage< vpRGBa > &I)
bool openEncoder(const char *filename, unsigned int width, unsigned int height, AVCodecID codec=AV_CODEC_ID_MPEG1VIDEO)