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>
72 framerate_stream = -1;
73 framerate_encoder = 25;
75 streamWasOpen =
false;
76 streamWasInitialized =
false;
81 encoderWasOpened =
false;
82 packet =
new AVPacket;
109 this->color_type = color_type;
112 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,0,0) // libavformat 52.84.0
113 if (av_open_input_file (&pFormatCtx, filename, NULL, 0, NULL) != 0)
115 if (avformat_open_input (&pFormatCtx, filename, NULL, NULL) != 0)
118 vpTRACE(
"Couldn't open file ");
122 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,21,0) // libavformat 53.21.0
123 if (av_find_stream_info (pFormatCtx) < 0)
125 if (avformat_find_stream_info (pFormatCtx, NULL) < 0)
130 bool found_codec =
false;
135 for (
unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
137 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,0,0)
138 if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
140 if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
144 std::cout <<
"rate: " << pFormatCtx->streams[i]->r_frame_rate.num <<
" " << pFormatCtx->streams[i]->r_frame_rate.den << std::endl;
145 framerate_stream = pFormatCtx->streams[i]->r_frame_rate.num;
146 framerate_stream /= pFormatCtx->streams[i]->r_frame_rate.den;
154 pCodecCtx = pFormatCtx->streams[videoStream]->codec;
155 pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
163 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
164 if (avcodec_open (pCodecCtx, pCodec) < 0)
166 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
169 vpTRACE(
"Could not open codec");
173 pFrame = avcodec_alloc_frame();
177 pFrameRGB=avcodec_alloc_frame();
179 if (pFrameRGB == NULL)
182 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
187 pFrameGRAY=avcodec_alloc_frame();
189 if (pFrameGRAY == NULL)
192 numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
198 width = pCodecCtx->width ;
199 height = pCodecCtx->height ;
200 buffer = (uint8_t *) malloc ((
unsigned int)(
sizeof (uint8_t)) * (
unsigned int)numBytes);
204 vpTRACE(
"Didn't find a video stream");
209 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
212 avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
214 streamWasOpen =
true;
229 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
232 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_GRAY8, SWS_BICUBIC, NULL, NULL, NULL);
234 int ret = av_seek_frame(pFormatCtx, (
int)videoStream, 0, AVSEEK_FLAG_ANY) ;
237 vpTRACE(
"Error rewinding stream for full indexing") ;
240 avcodec_flush_buffers(pCodecCtx) ;
245 av_init_packet(packet);
246 while (av_read_frame (pFormatCtx, packet) >= 0)
248 if (packet->stream_index == (
int)videoStream)
250 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
251 ret = avcodec_decode_video(pCodecCtx, pFrame,
252 &frameFinished, packet->data, packet->size);
254 ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
260 vpTRACE(
"Unable to decode video picture");
262 index.push_back(packet->dts);
268 frameNumber = index.size();
269 av_free_packet(packet);
271 streamWasInitialized =
true;
288 if (frame < frameNumber && streamWasInitialized==
true)
290 int64_t targetPts = index[frame];
291 av_seek_frame(pFormatCtx, (
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
295 vpTRACE(
"Couldn't get a frame");
299 avcodec_flush_buffers(pCodecCtx) ;
303 av_init_packet(packet);
304 while (av_read_frame (pFormatCtx, packet) >= 0)
306 if (packet->stream_index == (
int)videoStream)
308 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
309 avcodec_decode_video(pCodecCtx, pFrame,
310 &frameFinished, packet->data, packet->size);
312 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
317 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
319 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
327 av_free_packet(packet);
343 if (streamWasInitialized ==
false)
345 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
349 av_init_packet(packet);
350 while (av_read_frame (pFormatCtx, packet) >= 0)
352 if (packet->stream_index == (
int)videoStream)
354 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
355 avcodec_decode_video(pCodecCtx, pFrame,
356 &frameFinished, packet->data, packet->size);
358 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
363 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
365 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
372 av_free_packet(packet);
387 if (frame < frameNumber && streamWasInitialized==
true)
389 int64_t targetPts = index[frame];
390 av_seek_frame(pFormatCtx,(
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
394 vpTRACE(
"Couldn't get a frame");
398 avcodec_flush_buffers(pCodecCtx) ;
402 av_init_packet(packet);
403 while (av_read_frame (pFormatCtx, packet) >= 0)
405 if (packet->stream_index == (
int)videoStream)
407 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
408 avcodec_decode_video(pCodecCtx, pFrame,
409 &frameFinished, packet->data, packet->size);
411 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
416 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
418 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
426 av_free_packet(packet);
442 if (streamWasInitialized ==
false)
444 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
448 av_init_packet(packet);
449 while (av_read_frame (pFormatCtx, packet) >= 0)
451 if (packet->stream_index == (
int)videoStream)
453 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
454 avcodec_decode_video(pCodecCtx, pFrame,
455 &frameFinished, packet->data, packet->size);
457 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
462 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
464 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
471 av_free_packet(packet);
486 if(height < 0 || width < 0){
489 I.
resize((
unsigned int)height, (
unsigned int)width);
492 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
493 unsigned char* output = NULL;
497 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
498 int widthStep = pFrameRGB->linesize[0];
499 for(
int i=0 ; i < height ; i++)
502 output = beginOutput + 4 * width * i;
503 for(
int j=0 ; j < width ; j++)
505 *(output++) = *(line);
506 *(output++) = *(line+1);
507 *(output++) = *(line+2);
519 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
520 int widthStep = pFrameGRAY->linesize[0];
521 for(
int i=0 ; i < height ; i++)
524 output = beginOutput + 4 * width * i;
525 for(
int j=0 ; j < width ; j++)
530 *output++ = *(line);;
550 if(height < 0 || width < 0){
553 I.
resize((
unsigned int)height, (
unsigned int)width);
556 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
557 unsigned char* output = NULL;
561 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
562 int widthStep = pFrameGRAY->linesize[0];
563 for(
int i=0 ; i < height ; i++)
566 output = beginOutput + width * i;
567 for(
int j=0 ; j < width ; j++)
569 *(output++) = *(line);
580 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
581 int widthStep = pFrameRGB->linesize[0];
582 for (
int i = 0 ; i < height ; i++)
608 if (pCodecCtx) avcodec_close(pCodecCtx);
611 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
612 av_close_input_file(pFormatCtx);
614 avformat_close_input(&pFormatCtx);
617 streamWasOpen =
false;
619 if (encoderWasOpened)
623 if(buffer!=NULL)
delete[] buffer;
625 if(outbuf != NULL)
delete[] outbuf;
627 if(picture_buf != NULL)
delete[] picture_buf;
631 if (pCodecCtx) avcodec_close(pCodecCtx);
634 encoderWasOpened =
false;
636 if(streamWasInitialized || encoderWasOpened){
637 sws_freeContext (img_convert_ctx);
639 streamWasInitialized =
false;
658 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,51,110) // libavcodec 54.51.100
659 bool vpFFMPEG::openEncoder(
const char *filename,
unsigned int width,
unsigned int height, CodecID codec)
667 pCodec = avcodec_find_encoder(codec);
668 if (pCodec == NULL) {
669 fprintf(stderr,
"codec not found\n");
673 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
674 pCodecCtx = avcodec_alloc_context();
676 pCodecCtx = avcodec_alloc_context3(NULL);
678 pFrame = avcodec_alloc_frame();
679 pFrameRGB = avcodec_alloc_frame();
682 pCodecCtx->bit_rate = (int)bit_rate;
684 pCodecCtx->width = (int)width;
685 pCodecCtx->height = (int)height;
686 this->width = (int)width;
687 this->height = (int)height;
689 pCodecCtx->time_base= (AVRational){1,framerate_encoder};
690 pCodecCtx->gop_size = 10;
691 pCodecCtx->max_b_frames=1;
692 pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
695 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
696 if (avcodec_open (pCodecCtx, pCodec) < 0) {
698 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
700 fprintf(stderr,
"could not open codec\n");
706 f = fopen(filename,
"wb");
708 fprintf(stderr,
"could not open %s\n", filename);
712 outbuf_size = 100000;
713 outbuf =
new uint8_t[outbuf_size];
715 numBytes = avpicture_get_size (PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);
716 picture_buf =
new uint8_t[numBytes];
717 avpicture_fill((AVPicture *)pFrame, picture_buf, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
719 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
720 buffer =
new uint8_t[numBytes];
721 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
723 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
725 encoderWasOpened =
true;
740 if (encoderWasOpened ==
false)
742 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
747 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
748 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
749 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
750 fwrite(outbuf, 1, (
size_t)out_size, f);
753 av_init_packet(&pkt);
758 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
760 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
764 fwrite(pkt.data, 1, pkt.size, f);
765 av_free_packet(&pkt);
782 if (encoderWasOpened ==
false)
784 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
789 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
790 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
791 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
792 fwrite(outbuf, 1, (
size_t)out_size, f);
795 av_init_packet(&pkt);
800 int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
802 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
806 fwrite(pkt.data, 1, pkt.size, f);
807 av_free_packet(&pkt);
822 if (encoderWasOpened ==
false)
824 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
832 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
833 ret = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, NULL);
834 fwrite(outbuf, 1, (
size_t)out_size, f);
837 av_init_packet(&pkt);
841 ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);
843 std::cerr <<
"Error encoding frame in " << __FILE__ <<
" " << __LINE__ <<
" " << __FUNCTION__ << std::endl;
847 fwrite(pkt.data, 1, pkt.size, f);
848 av_free_packet(&pkt);
858 fwrite(outbuf, 1, 4, f);
869 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
870 unsigned char* input = NULL;
871 unsigned char* output = NULL;
872 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
873 int widthStep = pFrameRGB->linesize[0];
875 for(
int i=0 ; i < height ; i++)
877 input = beginInput + 4 * i * width;
878 output = beginOutput + i * widthStep;
879 for(
int j=0 ; j < width ; j++)
881 *(output++) = *(input);
882 *(output++) = *(input+1);
883 *(output++) = *(input+2);
896 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
897 unsigned char* input = NULL;
898 unsigned char* output = NULL;
899 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
900 int widthStep = pFrameRGB->linesize[0];
902 for(
int i=0 ; i < height ; i++)
904 input = beginInput + i * width;
905 output = beginOutput + i * widthStep;
906 for(
int j=0 ; j < width ; j++)
908 *(output++) = *(input);
909 *(output++) = *(input);
910 *(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
error that can be emited by ViSP classes.
bool openStream(const char *filename, vpFFMPEGColorType color_type)
bool acquire(vpImage< vpRGBa > &I)
bool openEncoder(const char *filename, unsigned int width, unsigned int height, AVCodecID codec=AV_CODEC_ID_MPEG1VIDEO)