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
73 streamWasOpen =
false;
74 streamWasInitialized =
false;
79 encoderWasOpened =
false;
80 packet =
new AVPacket;
103 this->color_type = color_type;
106 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,0,0) // libavformat 52.84.0
107 if (av_open_input_file (&pFormatCtx, filename, NULL, 0, NULL) != 0)
109 if (avformat_open_input (&pFormatCtx, filename, NULL, NULL) != 0)
112 vpTRACE(
"Couldn't open file ");
116 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,21,0) // libavformat 53.21.0
117 if (av_find_stream_info (pFormatCtx) < 0)
119 if (avformat_find_stream_info (pFormatCtx, NULL) < 0)
124 bool found_codec =
false;
129 for (
unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
131 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,0,0)
132 if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
134 if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
145 pCodecCtx = pFormatCtx->streams[videoStream]->codec;
146 pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
154 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
155 if (avcodec_open (pCodecCtx, pCodec) < 0)
157 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
160 vpTRACE(
"Could not open codec");
164 pFrame = avcodec_alloc_frame();
168 pFrameRGB=avcodec_alloc_frame();
170 if (pFrameRGB == NULL)
173 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
178 pFrameGRAY=avcodec_alloc_frame();
180 if (pFrameGRAY == NULL)
183 numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
189 width = pCodecCtx->width ;
190 height = pCodecCtx->height ;
191 buffer = (uint8_t *) malloc (
sizeof (uint8_t) * (size_t)numBytes);
195 vpTRACE(
"Didn't find a video stream");
200 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
203 avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
205 streamWasOpen =
true;
220 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
223 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_GRAY8, SWS_BICUBIC, NULL, NULL, NULL);
225 int ret = av_seek_frame(pFormatCtx, (
int)videoStream, 0, AVSEEK_FLAG_ANY) ;
228 vpTRACE(
"Error rewinding stream for full indexing") ;
231 avcodec_flush_buffers(pCodecCtx) ;
236 while (av_read_frame (pFormatCtx, packet) >= 0)
238 if (packet->stream_index == (
int)videoStream)
240 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
241 ret = avcodec_decode_video(pCodecCtx, pFrame,
242 &frameFinished, packet->data, packet->size);
244 ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
250 vpTRACE(
"Unable to decode video picture");
252 index.push_back(packet->dts);
258 frameNumber = index.size();
259 av_free_packet(packet);
261 streamWasInitialized =
true;
278 if (frame < frameNumber && streamWasInitialized==
true)
280 int64_t targetPts = index[frame];
281 av_seek_frame(pFormatCtx, (
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
285 vpTRACE(
"Couldn't get a frame");
289 avcodec_flush_buffers(pCodecCtx) ;
293 while (av_read_frame (pFormatCtx, packet) >= 0)
295 if (packet->stream_index == (
int)videoStream)
297 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
298 avcodec_decode_video(pCodecCtx, pFrame,
299 &frameFinished, packet->data, packet->size);
301 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
306 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
308 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
316 av_free_packet(packet);
332 if (streamWasInitialized ==
false)
334 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
338 while (av_read_frame (pFormatCtx, packet) >= 0)
340 if (packet->stream_index == (
int)videoStream)
342 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
343 avcodec_decode_video(pCodecCtx, pFrame,
344 &frameFinished, packet->data, packet->size);
346 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
351 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
353 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
360 av_free_packet(packet);
375 if (frame < frameNumber && streamWasInitialized==
true)
377 int64_t targetPts = index[frame];
378 av_seek_frame(pFormatCtx,(
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
382 vpTRACE(
"Couldn't get a frame");
386 avcodec_flush_buffers(pCodecCtx) ;
390 while (av_read_frame (pFormatCtx, packet) >= 0)
392 if (packet->stream_index == (
int)videoStream)
394 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
395 avcodec_decode_video(pCodecCtx, pFrame,
396 &frameFinished, packet->data, packet->size);
398 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
403 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
405 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
413 av_free_packet(packet);
429 if (streamWasInitialized ==
false)
431 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
435 while (av_read_frame (pFormatCtx, packet) >= 0)
437 if (packet->stream_index == (
int)videoStream)
439 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
440 avcodec_decode_video(pCodecCtx, pFrame,
441 &frameFinished, packet->data, packet->size);
443 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
448 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
450 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
457 av_free_packet(packet);
472 if(height < 0 || width < 0){
475 I.
resize((
unsigned int)height, (
unsigned int)width);
478 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
479 unsigned char* output = NULL;
483 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
484 int widthStep = pFrameRGB->linesize[0];
485 for(
int i=0 ; i < height ; i++)
488 output = beginOutput + 4 * width * i;
489 for(
int j=0 ; j < width ; j++)
491 *(output++) = *(line);
492 *(output++) = *(line+1);
493 *(output++) = *(line+2);
505 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
506 int widthStep = pFrameGRAY->linesize[0];
507 for(
int i=0 ; i < height ; i++)
510 output = beginOutput + 4 * width * i;
511 for(
int j=0 ; j < width ; j++)
516 *output++ = *(line);;
536 if(height < 0 || width < 0){
539 I.
resize((
unsigned int)height, (
unsigned int)width);
542 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
543 unsigned char* output = NULL;
547 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
548 int widthStep = pFrameGRAY->linesize[0];
549 for(
int i=0 ; i < height ; i++)
552 output = beginOutput + width * i;
553 for(
int j=0 ; j < width ; j++)
555 *(output++) = *(line);
566 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
567 int widthStep = pFrameRGB->linesize[0];
568 for (
int i = 0 ; i < height ; i++)
594 avcodec_close(pCodecCtx);
597 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
598 av_close_input_file(pFormatCtx);
600 avformat_close_input(&pFormatCtx);
603 streamWasOpen =
false;
605 if (encoderWasOpened)
609 if(buffer!=NULL)
delete[] buffer;
611 if(outbuf != NULL)
delete[] outbuf;
613 if(picture_buf != NULL)
delete[] picture_buf;
617 avcodec_close(pCodecCtx);
620 encoderWasOpened =
false;
622 if(streamWasInitialized){
623 sws_freeContext (img_convert_ctx);
625 streamWasInitialized =
false;
647 pCodec = avcodec_find_encoder(codec);
648 if (pCodec == NULL) {
649 fprintf(stderr,
"codec not found\n");
653 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodev 53.5.0
654 pCodecCtx = avcodec_alloc_context();
656 pCodecCtx = avcodec_alloc_context3(NULL);
658 pFrame = avcodec_alloc_frame();
659 pFrameRGB = avcodec_alloc_frame();
662 pCodecCtx->bit_rate = (int)bit_rate;
664 pCodecCtx->width = (int)width;
665 pCodecCtx->height = (int)height;
666 this->width = (int)width;
667 this->height = (int)height;
669 pCodecCtx->time_base= (AVRational){1,25};
670 pCodecCtx->gop_size = 10;
671 pCodecCtx->max_b_frames=1;
672 pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
675 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodev 53.35.0
676 if (avcodec_open (pCodecCtx, pCodec) < 0) {
678 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
680 fprintf(stderr,
"could not open codec\n");
686 f = fopen(filename,
"wb");
688 fprintf(stderr,
"could not open %s\n", filename);
692 outbuf_size = 100000;
693 outbuf =
new uint8_t[outbuf_size];
695 numBytes = avpicture_get_size (PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);
696 picture_buf =
new uint8_t[numBytes];
697 avpicture_fill((AVPicture *)pFrame, picture_buf, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
699 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
700 buffer =
new uint8_t[numBytes];
701 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
703 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
705 encoderWasOpened =
true;
720 if (encoderWasOpened ==
false)
722 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
727 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
728 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
729 fwrite(outbuf, 1, (
size_t)out_size, f);
744 if (encoderWasOpened ==
false)
746 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
751 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
752 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
753 fwrite(outbuf, 1, (
size_t)out_size, f);
765 if (encoderWasOpened ==
false)
767 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
771 while (out_size != 0)
773 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, NULL);
774 fwrite(outbuf, 1, (
size_t)out_size, f);
782 fwrite(outbuf, 1, 4, f);
793 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
794 unsigned char* input = NULL;
795 unsigned char* output = NULL;
796 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
797 int widthStep = pFrameRGB->linesize[0];
799 for(
int i=0 ; i < height ; i++)
801 input = beginInput + 4 * i * width;
802 output = beginOutput + i * widthStep;
803 for(
int j=0 ; j < width ; j++)
805 *(output++) = *(input);
806 *(output++) = *(input+1);
807 *(output++) = *(input+2);
820 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
821 unsigned char* input = NULL;
822 unsigned char* output = NULL;
823 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
824 int widthStep = pFrameRGB->linesize[0];
826 for(
int i=0 ; i < height ; i++)
828 input = beginInput + i * width;
829 output = beginOutput + i * widthStep;
830 for(
int j=0 ; j < width ; j++)
832 *(output++) = *(input);
833 *(output++) = *(input);
834 *(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)
void resize(const unsigned int height, const unsigned int width)
set the size of the image
bool openEncoder(const char *filename, unsigned int width, unsigned int height, CodecID codec=CODEC_ID_MPEG1VIDEO)
bool openStream(const char *filename, vpFFMPEGColorType color_type)
bool acquire(vpImage< vpRGBa > &I)