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 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(55,12,0)
138 framerate_stream = pFormatCtx->streams[i]->r_frame_rate.num;
139 framerate_stream /= pFormatCtx->streams[i]->r_frame_rate.den;
141 framerate_stream = pFormatCtx->streams[i]->avg_frame_rate.num;
142 framerate_stream /= pFormatCtx->streams[i]->avg_frame_rate.den;
151 pCodecCtx = pFormatCtx->streams[videoStream]->codec;
152 pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
160 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
161 if (avcodec_open (pCodecCtx, pCodec) < 0)
163 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
166 vpTRACE(
"Could not open codec");
170 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
171 pFrame = avcodec_alloc_frame();
173 pFrame = av_frame_alloc();
178 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
179 pFrameRGB=avcodec_alloc_frame();
181 pFrameRGB=av_frame_alloc();
184 if (pFrameRGB == NULL)
187 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
192 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
193 pFrameGRAY=avcodec_alloc_frame();
195 pFrameGRAY=av_frame_alloc();
198 if (pFrameGRAY == NULL)
201 numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
207 width = pCodecCtx->width ;
208 height = pCodecCtx->height ;
209 buffer = (uint8_t *) malloc ((
unsigned int)(
sizeof (uint8_t)) * (
unsigned int)numBytes);
213 vpTRACE(
"Didn't find a video stream");
218 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
221 avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
223 streamWasOpen =
true;
238 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
241 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_GRAY8, SWS_BICUBIC, NULL, NULL, NULL);
243 int ret = av_seek_frame(pFormatCtx, (
int)videoStream, 0, AVSEEK_FLAG_ANY) ;
246 vpTRACE(
"Error rewinding stream for full indexing") ;
249 avcodec_flush_buffers(pCodecCtx) ;
254 av_init_packet(packet);
255 while (av_read_frame (pFormatCtx, packet) >= 0)
257 if (packet->stream_index == (
int)videoStream)
259 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
260 ret = avcodec_decode_video(pCodecCtx, pFrame,
261 &frameFinished, packet->data, packet->size);
263 ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
269 vpTRACE(
"Unable to decode video picture");
271 index.push_back(packet->dts);
277 frameNumber = index.size();
278 av_free_packet(packet);
280 streamWasInitialized =
true;
297 if (frame < frameNumber && streamWasInitialized==
true)
299 int64_t targetPts = index[frame];
300 av_seek_frame(pFormatCtx, (
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
304 vpTRACE(
"Couldn't get a frame");
308 avcodec_flush_buffers(pCodecCtx) ;
312 av_init_packet(packet);
313 while (av_read_frame (pFormatCtx, packet) >= 0)
315 if (packet->stream_index == (
int)videoStream)
317 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
318 avcodec_decode_video(pCodecCtx, pFrame,
319 &frameFinished, packet->data, packet->size);
321 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
326 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
328 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
336 av_free_packet(packet);
352 if (streamWasInitialized ==
false)
354 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
358 av_init_packet(packet);
359 while (av_read_frame (pFormatCtx, packet) >= 0)
361 if (packet->stream_index == (
int)videoStream)
363 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
364 avcodec_decode_video(pCodecCtx, pFrame,
365 &frameFinished, packet->data, packet->size);
367 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
372 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
374 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
381 av_free_packet(packet);
396 if (frame < frameNumber && streamWasInitialized==
true)
398 int64_t targetPts = index[frame];
399 av_seek_frame(pFormatCtx,(
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
403 vpTRACE(
"Couldn't get a frame");
407 avcodec_flush_buffers(pCodecCtx) ;
411 av_init_packet(packet);
412 while (av_read_frame (pFormatCtx, packet) >= 0)
414 if (packet->stream_index == (
int)videoStream)
416 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
417 avcodec_decode_video(pCodecCtx, pFrame,
418 &frameFinished, packet->data, packet->size);
420 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
425 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
427 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
435 av_free_packet(packet);
451 if (streamWasInitialized ==
false)
453 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
457 av_init_packet(packet);
458 while (av_read_frame (pFormatCtx, packet) >= 0)
460 if (packet->stream_index == (
int)videoStream)
462 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
463 avcodec_decode_video(pCodecCtx, pFrame,
464 &frameFinished, packet->data, packet->size);
466 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
471 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
473 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
480 av_free_packet(packet);
495 if(height < 0 || width < 0){
498 I.
resize((
unsigned int)height, (
unsigned int)width);
501 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
502 unsigned char* output = NULL;
506 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
507 int widthStep = pFrameRGB->linesize[0];
508 for(
int i=0 ; i < height ; i++)
511 output = beginOutput + 4 * width * i;
512 for(
int j=0 ; j < width ; j++)
514 *(output++) = *(line);
515 *(output++) = *(line+1);
516 *(output++) = *(line+2);
528 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
529 int widthStep = pFrameGRAY->linesize[0];
530 for(
int i=0 ; i < height ; i++)
533 output = beginOutput + 4 * width * i;
534 for(
int j=0 ; j < width ; j++)
539 *output++ = *(line);;
559 if(height < 0 || width < 0){
562 I.
resize((
unsigned int)height, (
unsigned int)width);
565 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
566 unsigned char* output = NULL;
570 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
571 int widthStep = pFrameGRAY->linesize[0];
572 for(
int i=0 ; i < height ; i++)
575 output = beginOutput + width * i;
576 for(
int j=0 ; j < width ; j++)
578 *(output++) = *(line);
589 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
590 int widthStep = pFrameRGB->linesize[0];
591 for (
int i = 0 ; i < height ; i++)
605 if (buffer != NULL) {
620 if (pCodecCtx) avcodec_close(pCodecCtx);
623 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
624 av_close_input_file(pFormatCtx);
626 avformat_close_input(&pFormatCtx);
629 streamWasOpen =
false;
631 if (encoderWasOpened)
635 if(buffer!=NULL)
delete[] buffer;
637 if(outbuf != NULL)
delete[] outbuf;
639 if(picture_buf != NULL)
delete[] picture_buf;
643 if (pCodecCtx) avcodec_close(pCodecCtx);
646 encoderWasOpened =
false;
648 if(streamWasInitialized || encoderWasOpened){
649 sws_freeContext (img_convert_ctx);
651 streamWasInitialized =
false;
669 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,51,110) // libavcodec 54.51.100
678 pCodec = avcodec_find_encoder(codec);
679 if (pCodec == NULL) {
680 fprintf(stderr,
"codec not found\n");
684 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
685 pCodecCtx = avcodec_alloc_context();
687 pCodecCtx = avcodec_alloc_context3(NULL);
690 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
691 pFrame = avcodec_alloc_frame();
692 pFrameRGB = avcodec_alloc_frame();
694 pFrame = av_frame_alloc();
695 pFrameRGB = av_frame_alloc();
699 pCodecCtx->bit_rate = (int)bit_rate;
701 pCodecCtx->width = (int)w;
702 pCodecCtx->height = (int)h;
703 this->width = (int)w;
704 this->height = (int)h;
706 pCodecCtx->time_base.num = 1;
707 pCodecCtx->time_base.den = framerate_encoder;
708 pCodecCtx->gop_size = 10;
709 pCodecCtx->max_b_frames=1;
710 pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
713 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
714 if (avcodec_open (pCodecCtx, pCodec) < 0) {
716 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
718 fprintf(stderr,
"could not open codec\n");
724 f = fopen(filename,
"wb");
726 fprintf(stderr,
"could not open %s\n", filename);
730 outbuf_size = 100000;
731 outbuf =
new uint8_t[outbuf_size];
733 numBytes = avpicture_get_size (PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);
734 picture_buf =
new uint8_t[numBytes];
735 avpicture_fill((AVPicture *)pFrame, picture_buf, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
737 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
738 buffer =
new uint8_t[numBytes];
739 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
741 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
743 encoderWasOpened =
true;
758 if (encoderWasOpened ==
false)
760 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
765 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
766 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
767 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
768 fwrite(outbuf, 1, (
size_t)out_size, f);
771 av_init_packet(&pkt);
776 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
778 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
782 fwrite(pkt.data, 1, pkt.size, f);
783 av_free_packet(&pkt);
800 if (encoderWasOpened ==
false)
802 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
807 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
808 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
809 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
810 fwrite(outbuf, 1, (
size_t)out_size, f);
813 av_init_packet(&pkt);
818 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
820 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
824 fwrite(pkt.data, 1, pkt.size, f);
825 av_free_packet(&pkt);
840 if (encoderWasOpened ==
false)
842 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
850 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
851 ret = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, NULL);
852 fwrite(outbuf, 1, (
size_t)out_size, f);
855 av_init_packet(&pkt);
859 ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);
861 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
865 fwrite(pkt.data, 1, pkt.size, f);
866 av_free_packet(&pkt);
876 fwrite(outbuf, 1, 4, f);
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 + 4 * i * width;
896 output = beginOutput + i * widthStep;
897 for(
int j=0 ; j < width ; j++)
899 *(output++) = *(input);
900 *(output++) = *(input+1);
901 *(output++) = *(input+2);
914 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
915 unsigned char* input = NULL;
916 unsigned char* output = NULL;
917 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
918 int widthStep = pFrameRGB->linesize[0];
920 for(
int i=0 ; i < height ; i++)
922 input = beginInput + i * width;
923 output = beginOutput + i * widthStep;
924 for(
int j=0 ; j < width ; j++)
926 *(output++) = *(input);
927 *(output++) = *(input);
928 *(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 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)