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;
105 this->color_type = color_type;
108 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,0,0) // libavformat 52.84.0
109 if (av_open_input_file (&pFormatCtx, filename, NULL, 0, NULL) != 0)
111 if (avformat_open_input (&pFormatCtx, filename, NULL, NULL) != 0)
114 vpTRACE(
"Couldn't open file ");
118 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,21,0) // libavformat 53.21.0
119 if (av_find_stream_info (pFormatCtx) < 0)
121 if (avformat_find_stream_info (pFormatCtx, NULL) < 0)
126 bool found_codec =
false;
131 for (
unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
133 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,0,0)
134 if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
136 if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
147 pCodecCtx = pFormatCtx->streams[videoStream]->codec;
148 pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
156 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
157 if (avcodec_open (pCodecCtx, pCodec) < 0)
159 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
162 vpTRACE(
"Could not open codec");
166 pFrame = avcodec_alloc_frame();
170 pFrameRGB=avcodec_alloc_frame();
172 if (pFrameRGB == NULL)
175 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
180 pFrameGRAY=avcodec_alloc_frame();
182 if (pFrameGRAY == NULL)
185 numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
191 width = pCodecCtx->width ;
192 height = pCodecCtx->height ;
193 buffer = (uint8_t *) malloc ((
unsigned int)(
sizeof (uint8_t)) * (
unsigned int)numBytes);
197 vpTRACE(
"Didn't find a video stream");
202 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
205 avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
207 streamWasOpen =
true;
222 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
225 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_GRAY8, SWS_BICUBIC, NULL, NULL, NULL);
227 int ret = av_seek_frame(pFormatCtx, (
int)videoStream, 0, AVSEEK_FLAG_ANY) ;
230 vpTRACE(
"Error rewinding stream for full indexing") ;
233 avcodec_flush_buffers(pCodecCtx) ;
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 while (av_read_frame (pFormatCtx, packet) >= 0)
297 if (packet->stream_index == (
int)videoStream)
299 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
300 avcodec_decode_video(pCodecCtx, pFrame,
301 &frameFinished, packet->data, packet->size);
303 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
308 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
310 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
318 av_free_packet(packet);
334 if (streamWasInitialized ==
false)
336 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
340 while (av_read_frame (pFormatCtx, packet) >= 0)
342 if (packet->stream_index == (
int)videoStream)
344 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
345 avcodec_decode_video(pCodecCtx, pFrame,
346 &frameFinished, packet->data, packet->size);
348 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
353 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
355 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
362 av_free_packet(packet);
377 if (frame < frameNumber && streamWasInitialized==
true)
379 int64_t targetPts = index[frame];
380 av_seek_frame(pFormatCtx,(
int)videoStream,targetPts, AVSEEK_FLAG_ANY);
384 vpTRACE(
"Couldn't get a frame");
388 avcodec_flush_buffers(pCodecCtx) ;
392 while (av_read_frame (pFormatCtx, packet) >= 0)
394 if (packet->stream_index == (
int)videoStream)
396 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
397 avcodec_decode_video(pCodecCtx, pFrame,
398 &frameFinished, packet->data, packet->size);
400 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
405 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
407 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
415 av_free_packet(packet);
431 if (streamWasInitialized ==
false)
433 vpTRACE(
"Couldn't get a frame. The parameters have to be initialized before ");
437 while (av_read_frame (pFormatCtx, packet) >= 0)
439 if (packet->stream_index == (
int)videoStream)
441 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
442 avcodec_decode_video(pCodecCtx, pFrame,
443 &frameFinished, packet->data, packet->size);
445 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet);
450 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
452 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
459 av_free_packet(packet);
474 if(height < 0 || width < 0){
477 I.
resize((
unsigned int)height, (
unsigned int)width);
480 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
481 unsigned char* output = NULL;
485 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
486 int widthStep = pFrameRGB->linesize[0];
487 for(
int i=0 ; i < height ; i++)
490 output = beginOutput + 4 * width * i;
491 for(
int j=0 ; j < width ; j++)
493 *(output++) = *(line);
494 *(output++) = *(line+1);
495 *(output++) = *(line+2);
507 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
508 int widthStep = pFrameGRAY->linesize[0];
509 for(
int i=0 ; i < height ; i++)
512 output = beginOutput + 4 * width * i;
513 for(
int j=0 ; j < width ; j++)
518 *output++ = *(line);;
538 if(height < 0 || width < 0){
541 I.
resize((
unsigned int)height, (
unsigned int)width);
544 unsigned char* beginOutput = (
unsigned char*)I.
bitmap;
545 unsigned char* output = NULL;
549 unsigned char* input = (
unsigned char*)pFrameGRAY->data[0];
550 int widthStep = pFrameGRAY->linesize[0];
551 for(
int i=0 ; i < height ; i++)
554 output = beginOutput + width * i;
555 for(
int j=0 ; j < width ; j++)
557 *(output++) = *(line);
568 unsigned char* input = (
unsigned char*)pFrameRGB->data[0];
569 int widthStep = pFrameRGB->linesize[0];
570 for (
int i = 0 ; i < height ; i++)
596 avcodec_close(pCodecCtx);
599 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
600 av_close_input_file(pFormatCtx);
602 avformat_close_input(&pFormatCtx);
605 streamWasOpen =
false;
607 if (encoderWasOpened)
611 if(buffer!=NULL)
delete[] buffer;
613 if(outbuf != NULL)
delete[] outbuf;
615 if(picture_buf != NULL)
delete[] picture_buf;
619 avcodec_close(pCodecCtx);
622 encoderWasOpened =
false;
624 if(streamWasInitialized){
625 sws_freeContext (img_convert_ctx);
627 streamWasInitialized =
false;
649 pCodec = avcodec_find_encoder(codec);
650 if (pCodec == NULL) {
651 fprintf(stderr,
"codec not found\n");
655 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodev 53.5.0
656 pCodecCtx = avcodec_alloc_context();
658 pCodecCtx = avcodec_alloc_context3(NULL);
660 pFrame = avcodec_alloc_frame();
661 pFrameRGB = avcodec_alloc_frame();
664 pCodecCtx->bit_rate = (int)bit_rate;
666 pCodecCtx->width = (int)width;
667 pCodecCtx->height = (int)height;
668 this->width = (int)width;
669 this->height = (int)height;
671 pCodecCtx->time_base= (AVRational){1,25};
672 pCodecCtx->gop_size = 10;
673 pCodecCtx->max_b_frames=1;
674 pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
677 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodev 53.35.0
678 if (avcodec_open (pCodecCtx, pCodec) < 0) {
680 if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
682 fprintf(stderr,
"could not open codec\n");
688 f = fopen(filename,
"wb");
690 fprintf(stderr,
"could not open %s\n", filename);
694 outbuf_size = 100000;
695 outbuf =
new uint8_t[outbuf_size];
697 numBytes = avpicture_get_size (PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);
698 picture_buf =
new uint8_t[numBytes];
699 avpicture_fill((AVPicture *)pFrame, picture_buf, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
701 numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
702 buffer =
new uint8_t[numBytes];
703 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
705 img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
707 encoderWasOpened =
true;
722 if (encoderWasOpened ==
false)
724 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
729 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
730 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
731 fwrite(outbuf, 1, (
size_t)out_size, f);
746 if (encoderWasOpened ==
false)
748 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
753 sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
754 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
755 fwrite(outbuf, 1, (
size_t)out_size, f);
767 if (encoderWasOpened ==
false)
769 vpTRACE(
"Couldn't save a frame. The parameters have to be initialized before ");
773 while (out_size != 0)
775 out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, NULL);
776 fwrite(outbuf, 1, (
size_t)out_size, f);
784 fwrite(outbuf, 1, 4, f);
795 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
796 unsigned char* input = NULL;
797 unsigned char* output = NULL;
798 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
799 int widthStep = pFrameRGB->linesize[0];
801 for(
int i=0 ; i < height ; i++)
803 input = beginInput + 4 * i * width;
804 output = beginOutput + i * widthStep;
805 for(
int j=0 ; j < width ; j++)
807 *(output++) = *(input);
808 *(output++) = *(input+1);
809 *(output++) = *(input+2);
822 unsigned char* beginInput = (
unsigned char*)I.
bitmap;
823 unsigned char* input = NULL;
824 unsigned char* output = NULL;
825 unsigned char* beginOutput = (
unsigned char*)pFrameRGB->data[0];
826 int widthStep = pFrameRGB->linesize[0];
828 for(
int i=0 ; i < height ; i++)
830 input = beginInput + i * width;
831 output = beginOutput + i * widthStep;
832 for(
int j=0 ; j < width ; j++)
834 *(output++) = *(input);
835 *(output++) = *(input);
836 *(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 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)