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++)
617 if (pCodecCtx) avcodec_close(pCodecCtx);
620 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
621 av_close_input_file(pFormatCtx);
623 avformat_close_input(&pFormatCtx);
626 streamWasOpen =
false;
628 if (encoderWasOpened)
632 if(buffer!=NULL)
delete[] buffer;
634 if(outbuf != NULL)
delete[] outbuf;
636 if(picture_buf != NULL)
delete[] picture_buf;
640 if (pCodecCtx) avcodec_close(pCodecCtx);
643 encoderWasOpened =
false;
645 if(streamWasInitialized || encoderWasOpened){
646 sws_freeContext (img_convert_ctx);
648 streamWasInitialized =
false;
666 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,51,110) // libavcodec 54.51.100
675 pCodec = avcodec_find_encoder(codec);
676 if (pCodec == NULL) {
677 fprintf(stderr,
"codec not found\n");
681 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
682 pCodecCtx = avcodec_alloc_context();
684 pCodecCtx = avcodec_alloc_context3(NULL);
687 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
688 pFrame = avcodec_alloc_frame();
689 pFrameRGB = avcodec_alloc_frame();
691 pFrame = av_frame_alloc();
692 pFrameRGB = av_frame_alloc();
696 pCodecCtx->bit_rate = (int)bit_rate;
698 pCodecCtx->width = (int)w;
699 pCodecCtx->height = (int)h;
700 this->width = (int)w;
701 this->height = (int)h;
703 pCodecCtx->time_base= (AVRational){1,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);
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)