50 #include <visp/vpConfig.h>
51 #include <visp/vpDebug.h>
52 #include <visp/vpFFMPEG.h>
53 #include <visp/vpImageConvert.h>
55 #ifdef VISP_HAVE_FFMPEG
60 #include <libavformat/avformat.h>
61 #include <libswscale/swscale.h>
68 : width(-1), height(-1), frameNumber(0), pFormatCtx(NULL), pCodecCtx(NULL),
69 pCodec(NULL), pFrame(NULL), pFrameRGB(NULL), pFrameGRAY(NULL), packet(NULL),
70 img_convert_ctx(NULL), videoStream(0), numBytes(0), buffer(NULL), index(),
71 streamWasOpen(false), streamWasInitialized(false), color_type(COLORED),
72 f(NULL), outbuf(NULL), picture_buf(NULL), outbuf_size(0), out_size(0),
73 bit_rate(500000), encoderWasOpened(false),
74 framerate_stream(-1), framerate_encoder(25)
76 packet =
new AVPacket;
101 this->color_type = colortype;
104 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,0,0) // libavformat 52.84.0
105 if (av_open_input_file (&pFormatCtx, filename, NULL, 0, NULL) != 0)
107 if (avformat_open_input (&pFormatCtx, filename, NULL, NULL) != 0)
110 vpTRACE(
"Couldn't open file ");
114 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,21,0) // libavformat 53.21.0
115 if (av_find_stream_info (pFormatCtx) < 0)
117 if (avformat_find_stream_info (pFormatCtx, NULL) < 0)
122 bool found_codec =
false;
127 for (
unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
129 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,0,0)
130 if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
132 if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
137 framerate_stream = pFormatCtx->streams[i]->r_frame_rate.num;
138 framerate_stream /= pFormatCtx->streams[i]->r_frame_rate.den;
146 pCodecCtx = pFormatCtx->streams[videoStream]->codec;
147 pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
155 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
156 if (avcodec_open (pCodecCtx, pCodec) < 0)
158 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
161 vpTRACE(
"Could not open codec");
165 pFrame = avcodec_alloc_frame();
169 pFrameRGB=avcodec_alloc_frame();
171 if (pFrameRGB == NULL)
174 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
179 pFrameGRAY=avcodec_alloc_frame();
181 if (pFrameGRAY == NULL)
184 numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
190 width = pCodecCtx->width ;
191 height = pCodecCtx->height ;
192 buffer = (uint8_t *) malloc ((
unsigned int)(
sizeof (uint8_t)) * (
unsigned int)numBytes);
196 vpTRACE(
"Didn't find a video stream");
201 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
204 avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
206 streamWasOpen =
true;
221 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
224 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_GRAY8, SWS_BICUBIC, NULL, NULL, NULL);
226 int ret = av_seek_frame(pFormatCtx, (
int)videoStream, 0, AVSEEK_FLAG_ANY) ;
229 vpTRACE(
"Error rewinding stream for full indexing") ;
232 avcodec_flush_buffers(pCodecCtx) ;
237 av_init_packet(packet);
238 while (av_read_frame (pFormatCtx, packet) >= 0)
240 if (packet->stream_index == (
int)videoStream)
242 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
243 ret = avcodec_decode_video(pCodecCtx, pFrame,
244 &frameFinished, packet->data, packet->size);
246 ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
252 vpTRACE(
"Unable to decode video picture");
254 index.push_back(packet->dts);
260 frameNumber = index.size();
261 av_free_packet(packet);
263 streamWasInitialized =
true;
280 if (frame < frameNumber && streamWasInitialized==
true)
282 int64_t targetPts = index[frame];
283 av_seek_frame(pFormatCtx, (
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
287 vpTRACE(
"Couldn't get a frame");
291 avcodec_flush_buffers(pCodecCtx) ;
295 av_init_packet(packet);
296 while (av_read_frame (pFormatCtx, packet) >= 0)
298 if (packet->stream_index == (
int)videoStream)
300 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
301 avcodec_decode_video(pCodecCtx, pFrame,
302 &frameFinished, packet->data, packet->size);
304 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
309 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
311 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
319 av_free_packet(packet);
335 if (streamWasInitialized ==
false)
337 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
341 av_init_packet(packet);
342 while (av_read_frame (pFormatCtx, packet) >= 0)
344 if (packet->stream_index == (
int)videoStream)
346 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
347 avcodec_decode_video(pCodecCtx, pFrame,
348 &frameFinished, packet->data, packet->size);
350 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
355 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
357 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
364 av_free_packet(packet);
379 if (frame < frameNumber && streamWasInitialized==
true)
381 int64_t targetPts = index[frame];
382 av_seek_frame(pFormatCtx,(
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
386 vpTRACE(
"Couldn't get a frame");
390 avcodec_flush_buffers(pCodecCtx) ;
394 av_init_packet(packet);
395 while (av_read_frame (pFormatCtx, packet) >= 0)
397 if (packet->stream_index == (
int)videoStream)
399 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
400 avcodec_decode_video(pCodecCtx, pFrame,
401 &frameFinished, packet->data, packet->size);
403 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
408 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
410 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
418 av_free_packet(packet);
434 if (streamWasInitialized ==
false)
436 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
440 av_init_packet(packet);
441 while (av_read_frame (pFormatCtx, packet) >= 0)
443 if (packet->stream_index == (
int)videoStream)
445 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
446 avcodec_decode_video(pCodecCtx, pFrame,
447 &frameFinished, packet->data, packet->size);
449 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
454 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
456 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
463 av_free_packet(packet);
478 if(height < 0 || width < 0){
481 I.
resize((
unsigned int)height, (
unsigned int)width);
484 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
485 unsigned char* output = NULL;
489 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
490 int widthStep = pFrameRGB->linesize[0];
491 for(
int i=0 ; i < height ; i++)
494 output = beginOutput + 4 * width * i;
495 for(
int j=0 ; j < width ; j++)
497 *(output++) = *(line);
498 *(output++) = *(line+1);
499 *(output++) = *(line+2);
511 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
512 int widthStep = pFrameGRAY->linesize[0];
513 for(
int i=0 ; i < height ; i++)
516 output = beginOutput + 4 * width * i;
517 for(
int j=0 ; j < width ; j++)
522 *output++ = *(line);;
542 if(height < 0 || width < 0){
545 I.
resize((
unsigned int)height, (
unsigned int)width);
548 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
549 unsigned char* output = NULL;
553 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
554 int widthStep = pFrameGRAY->linesize[0];
555 for(
int i=0 ; i < height ; i++)
558 output = beginOutput + width * i;
559 for(
int j=0 ; j < width ; j++)
561 *(output++) = *(line);
572 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
573 int widthStep = pFrameRGB->linesize[0];
574 for (
int i = 0 ; i < height ; i++)
600 if (pCodecCtx) avcodec_close(pCodecCtx);
603 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
604 av_close_input_file(pFormatCtx);
606 avformat_close_input(&pFormatCtx);
609 streamWasOpen =
false;
611 if (encoderWasOpened)
615 if(buffer!=NULL)
delete[] buffer;
617 if(outbuf != NULL)
delete[] outbuf;
619 if(picture_buf != NULL)
delete[] picture_buf;
623 if (pCodecCtx) avcodec_close(pCodecCtx);
626 encoderWasOpened =
false;
628 if(streamWasInitialized || encoderWasOpened){
629 sws_freeContext (img_convert_ctx);
631 streamWasInitialized =
false;
649 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,51,110) // libavcodec 54.51.100
658 pCodec = avcodec_find_encoder(codec);
659 if (pCodec == NULL) {
660 fprintf(stderr,
"codec not found\n");
664 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
665 pCodecCtx = avcodec_alloc_context();
667 pCodecCtx = avcodec_alloc_context3(NULL);
669 pFrame = avcodec_alloc_frame();
670 pFrameRGB = avcodec_alloc_frame();
673 pCodecCtx->bit_rate = (int)bit_rate;
675 pCodecCtx->width = (int)w;
676 pCodecCtx->height = (int)h;
677 this->width = (int)w;
678 this->height = (int)h;
680 pCodecCtx->time_base= (AVRational){1,framerate_encoder};
681 pCodecCtx->gop_size = 10;
682 pCodecCtx->max_b_frames=1;
683 pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
686 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
687 if (avcodec_open (pCodecCtx, pCodec) < 0) {
689 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
691 fprintf(stderr,
"could not open codec\n");
697 f = fopen(filename,
"wb");
699 fprintf(stderr,
"could not open %s\n", filename);
703 outbuf_size = 100000;
704 outbuf =
new uint8_t[outbuf_size];
706 numBytes = avpicture_get_size (PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);
707 picture_buf =
new uint8_t[numBytes];
708 avpicture_fill((AVPicture *)pFrame, picture_buf, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
710 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
711 buffer =
new uint8_t[numBytes];
712 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
714 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
716 encoderWasOpened =
true;
731 if (encoderWasOpened ==
false)
733 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
738 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
739 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
740 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
741 fwrite(outbuf, 1, (
size_t)out_size, f);
744 av_init_packet(&pkt);
749 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
751 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
755 fwrite(pkt.data, 1, pkt.size, f);
756 av_free_packet(&pkt);
773 if (encoderWasOpened ==
false)
775 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
780 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
781 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
782 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
783 fwrite(outbuf, 1, (
size_t)out_size, f);
786 av_init_packet(&pkt);
791 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
793 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
797 fwrite(pkt.data, 1, pkt.size, f);
798 av_free_packet(&pkt);
813 if (encoderWasOpened ==
false)
815 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
823 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
824 ret = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, NULL);
825 fwrite(outbuf, 1, (
size_t)out_size, f);
828 av_init_packet(&pkt);
832 ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);
834 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
838 fwrite(pkt.data, 1, pkt.size, f);
839 av_free_packet(&pkt);
849 fwrite(outbuf, 1, 4, f);
860 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
861 unsigned char* input = NULL;
862 unsigned char* output = NULL;
863 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
864 int widthStep = pFrameRGB->linesize[0];
866 for(
int i=0 ; i < height ; i++)
868 input = beginInput + 4 * i * width;
869 output = beginOutput + i * widthStep;
870 for(
int j=0 ; j < width ; j++)
872 *(output++) = *(input);
873 *(output++) = *(input+1);
874 *(output++) = *(input+2);
887 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
888 unsigned char* input = NULL;
889 unsigned char* output = NULL;
890 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
891 int widthStep = pFrameRGB->linesize[0];
893 for(
int i=0 ; i < height ; i++)
895 input = beginInput + i * width;
896 output = beginOutput + i * widthStep;
897 for(
int j=0 ; j < width ; j++)
899 *(output++) = *(input);
900 *(output++) = *(input);
901 *(output++) = *(input);
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
bool acquire(vpImage< vpRGBa > &I)
bool openEncoder(const char *filename, unsigned int width, unsigned int height, AVCodecID codec=AV_CODEC_ID_MPEG1VIDEO)