ViSP  2.10.0
vpFFMPEG.cpp
1 /****************************************************************************
2  *
3  * $Id: vpImagePoint.h 2359 2009-11-24 15:09:25Z nmelchio $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Class that manages the FFMPEG library.
36  *
37  * Authors:
38  * Nicolas Melchior
39  * Fabien Spindler
40  *
41  *****************************************************************************/
42 
48 #include <stdio.h>
49 
50 #include <visp/vpConfig.h>
51 #include <visp/vpDebug.h>
52 #include <visp/vpFFMPEG.h>
53 #include <visp/vpImageConvert.h>
54 
55 #ifdef VISP_HAVE_FFMPEG
56 
57 extern "C"
58 {
59 //#include <libavcodec/avcodec.h>
60 #include <libavformat/avformat.h>
61 #include <libswscale/swscale.h>
62 }
63 
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)
75 {
76  packet = new AVPacket;
77 }
78 
83 {
84  closeStream();
85  delete packet;
86 }
87 
99 bool vpFFMPEG::openStream(const char *filename, vpFFMPEGColorType colortype)
100 {
101  this->color_type = colortype;
102 
103  av_register_all();
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)
106 #else
107  if (avformat_open_input (&pFormatCtx, filename, NULL, NULL) != 0) // libavformat 53.4.0
108 #endif
109  {
110  vpTRACE("Couldn't open file ");
111  return false;
112  }
113 
114 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,21,0) // libavformat 53.21.0
115  if (av_find_stream_info (pFormatCtx) < 0)
116 #else
117  if (avformat_find_stream_info (pFormatCtx, NULL) < 0)
118 #endif
119  return false;
120 
121  videoStream = 0;
122  bool found_codec = false;
123 
124  /*
125  * Detect streams types
126  */
127  for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
128  {
129 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,0,0)
130  if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) // avutil 50.33.0
131 #else
132  if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) // avutil 51.9.1
133 #endif
134  {
135  videoStream = i;
136  //std::cout << "rate: " << pFormatCtx->streams[i]->r_frame_rate.num << " " << pFormatCtx->streams[i]->r_frame_rate.den << std::endl;
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;
140 #else
141  framerate_stream = pFormatCtx->streams[i]->avg_frame_rate.num;
142  framerate_stream /= pFormatCtx->streams[i]->avg_frame_rate.den;
143 #endif
144  found_codec= true;
145  break;
146  }
147  }
148 
149  if (found_codec)
150  {
151  pCodecCtx = pFormatCtx->streams[videoStream]->codec;
152  pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
153 
154  if (pCodec == NULL)
155  {
156  vpTRACE("unsuported codec");
157  return false; // Codec not found
158  }
159 
160 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
161  if (avcodec_open (pCodecCtx, pCodec) < 0)
162 #else
163  if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
164 #endif
165  {
166  vpTRACE("Could not open codec");
167  return false; // Could not open codec
168  }
169 
170 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
171  pFrame = avcodec_alloc_frame();
172 #else
173  pFrame = av_frame_alloc(); // libavcodec 55.34.1
174 #endif
175 
176  if (color_type == vpFFMPEG::COLORED)
177  {
178 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
179  pFrameRGB=avcodec_alloc_frame();
180 #else
181  pFrameRGB=av_frame_alloc(); // libavcodec 55.34.1
182 #endif
183 
184  if (pFrameRGB == NULL)
185  return false;
186 
187  numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
188  }
189 
190  else if (color_type == vpFFMPEG::GRAY_SCALED)
191  {
192 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
193  pFrameGRAY=avcodec_alloc_frame();
194 #else
195  pFrameGRAY=av_frame_alloc(); // libavcodec 55.34.1
196 #endif
197 
198  if (pFrameGRAY == NULL)
199  return false;
200 
201  numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
202  }
203 
204  /*
205  * Determine required buffer size and allocate buffer
206  */
207  width = pCodecCtx->width ;
208  height = pCodecCtx->height ;
209  buffer = (uint8_t *) malloc ((unsigned int)(sizeof (uint8_t)) * (unsigned int)numBytes);
210  }
211  else
212  {
213  vpTRACE("Didn't find a video stream");
214  return false;
215  }
216 
217  if (color_type == vpFFMPEG::COLORED)
218  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
219 
220  else if (color_type == vpFFMPEG::GRAY_SCALED)
221  avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
222 
223  streamWasOpen = true;
224 
225  return true;
226 }
227 
236 {
237  if (color_type == vpFFMPEG::COLORED)
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);
239 
240  else if (color_type == vpFFMPEG::GRAY_SCALED)
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);
242 
243  int ret = av_seek_frame(pFormatCtx, (int)videoStream, 0, AVSEEK_FLAG_ANY) ;
244  if (ret < 0 )
245  {
246  vpTRACE("Error rewinding stream for full indexing") ;
247  return false ;
248  }
249  avcodec_flush_buffers(pCodecCtx) ;
250 
251  int frame_no = 0 ;
252  int frameFinished ;
253 
254  av_init_packet(packet);
255  while (av_read_frame (pFormatCtx, packet) >= 0)
256  {
257  if (packet->stream_index == (int)videoStream)
258  {
259 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
260  ret = avcodec_decode_video(pCodecCtx, pFrame,
261  &frameFinished, packet->data, packet->size);
262 #else
263  ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
264 #endif
265  if (frameFinished)
266  {
267  if (ret < 0 )
268  {
269  vpTRACE("Unable to decode video picture");
270  }
271  index.push_back(packet->dts);
272  frame_no++ ;
273  }
274  }
275  }
276 
277  frameNumber = index.size();
278  av_free_packet(packet);
279 
280  streamWasInitialized = true;
281 
282  return true;
283 }
284 
285 
294 bool vpFFMPEG::getFrame(vpImage<vpRGBa> &I, unsigned int frame)
295 {
296 
297  if (frame < frameNumber && streamWasInitialized== true)
298  {
299  int64_t targetPts = index[frame];
300  av_seek_frame(pFormatCtx, (int)videoStream,targetPts, AVSEEK_FLAG_ANY);
301  }
302  else
303  {
304  vpTRACE("Couldn't get a frame");
305  return false;
306  }
307 
308  avcodec_flush_buffers(pCodecCtx) ;
309 
310  int frameFinished ;
311 
312  av_init_packet(packet);
313  while (av_read_frame (pFormatCtx, packet) >= 0)
314  {
315  if (packet->stream_index == (int)videoStream)
316  {
317 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
318  avcodec_decode_video(pCodecCtx, pFrame,
319  &frameFinished, packet->data, packet->size);
320 #else
321  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
322 #endif
323  if (frameFinished)
324  {
325  if (color_type == vpFFMPEG::COLORED)
326  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
327  else if (color_type == vpFFMPEG::GRAY_SCALED)
328  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
329 
330  copyBitmap(I);
331  break;
332  }
333  }
334  }
335 
336  av_free_packet(packet);
337  return true;
338 }
339 
340 
349 {
350  int frameFinished ;
351 
352  if (streamWasInitialized == false)
353  {
354  vpTRACE("Couldn't get a frame. The parameters have to be initialized before ");
355  return false;
356  }
357 
358  av_init_packet(packet);
359  while (av_read_frame (pFormatCtx, packet) >= 0)
360  {
361  if (packet->stream_index == (int)videoStream)
362  {
363 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
364  avcodec_decode_video(pCodecCtx, pFrame,
365  &frameFinished, packet->data, packet->size);
366 #else
367  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
368 #endif
369  if (frameFinished)
370  {
371  if (color_type == vpFFMPEG::COLORED)
372  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
373  else if (color_type == vpFFMPEG::GRAY_SCALED)
374  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
375 
376  copyBitmap(I);
377  break;
378  }
379  }
380  }
381  av_free_packet(packet);
382  return true;
383 }
384 
393 bool vpFFMPEG::getFrame(vpImage<unsigned char> &I, unsigned int frame)
394 {
395 
396  if (frame < frameNumber && streamWasInitialized== true)
397  {
398  int64_t targetPts = index[frame];
399  av_seek_frame(pFormatCtx,(int)videoStream,targetPts, AVSEEK_FLAG_ANY);
400  }
401  else
402  {
403  vpTRACE("Couldn't get a frame");
404  return false;
405  }
406 
407  avcodec_flush_buffers(pCodecCtx) ;
408 
409  int frameFinished ;
410 
411  av_init_packet(packet);
412  while (av_read_frame (pFormatCtx, packet) >= 0)
413  {
414  if (packet->stream_index == (int)videoStream)
415  {
416 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
417  avcodec_decode_video(pCodecCtx, pFrame,
418  &frameFinished, packet->data, packet->size);
419 #else
420  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
421 #endif
422  if (frameFinished)
423  {
424  if (color_type == vpFFMPEG::COLORED)
425  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
426  else if (color_type == vpFFMPEG::GRAY_SCALED)
427  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
428 
429  copyBitmap(I);
430  break;
431  }
432  }
433  }
434 
435  av_free_packet(packet);
436  return true;
437 }
438 
439 
448 {
449  int frameFinished ;
450 
451  if (streamWasInitialized == false)
452  {
453  vpTRACE("Couldn't get a frame. The parameters have to be initialized before ");
454  return false;
455  }
456 
457  av_init_packet(packet);
458  while (av_read_frame (pFormatCtx, packet) >= 0)
459  {
460  if (packet->stream_index == (int)videoStream)
461  {
462 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
463  avcodec_decode_video(pCodecCtx, pFrame,
464  &frameFinished, packet->data, packet->size);
465 #else
466  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
467 #endif
468  if (frameFinished)
469  {
470  if (color_type == vpFFMPEG::COLORED)
471  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
472  else if (color_type == vpFFMPEG::GRAY_SCALED)
473  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
474 
475  copyBitmap(I);
476  break;
477  }
478  }
479  }
480  av_free_packet(packet);
481  return true;
482 }
483 
484 
493 void vpFFMPEG::copyBitmap(vpImage<vpRGBa> &I)
494 {
495  if(height < 0 || width < 0){
496  throw vpException(vpException::dimensionError, "width or height negative.");
497  }
498  I.resize((unsigned int)height, (unsigned int)width);
499 
500  unsigned char* line;
501  unsigned char* beginOutput = (unsigned char*)I.bitmap;
502  unsigned char* output = NULL;
503 
504  if (color_type == COLORED)
505  {
506  unsigned char* input = (unsigned char*)pFrameRGB->data[0];
507  int widthStep = pFrameRGB->linesize[0];
508  for(int i=0 ; i < height ; i++)
509  {
510  line = input;
511  output = beginOutput + 4 * width * i;
512  for(int j=0 ; j < width ; j++)
513  {
514  *(output++) = *(line);
515  *(output++) = *(line+1);
516  *(output++) = *(line+2);
517  *(output++) = 0;
518 
519  line+=3;
520  }
521  //go to the next line
522  input+=widthStep;
523  }
524  }
525 
526  else if (color_type == GRAY_SCALED)
527  {
528  unsigned char* input = (unsigned char*)pFrameGRAY->data[0];
529  int widthStep = pFrameGRAY->linesize[0];
530  for(int i=0 ; i < height ; i++)
531  {
532  line = input;
533  output = beginOutput + 4 * width * i;
534  for(int j=0 ; j < width ; j++)
535  {
536  *output++ = *(line);
537  *output++ = *(line);
538  *output++ = *(line);
539  *output++ = *(line);;
540 
541  line++;
542  }
543  //go to the next line
544  input+=widthStep;
545  }
546  }
547 }
548 
557 void vpFFMPEG::copyBitmap(vpImage<unsigned char> &I)
558 {
559  if(height < 0 || width < 0){
560  throw vpException(vpException::dimensionError, "width or height negative.");
561  }
562  I.resize((unsigned int)height, (unsigned int)width);
563 
564  unsigned char* line;
565  unsigned char* beginOutput = (unsigned char*)I.bitmap;
566  unsigned char* output = NULL;
567 
568  if (color_type == GRAY_SCALED)
569  {
570  unsigned char* input = (unsigned char*)pFrameGRAY->data[0];
571  int widthStep = pFrameGRAY->linesize[0];
572  for(int i=0 ; i < height ; i++)
573  {
574  line = input;
575  output = beginOutput + width * i;
576  for(int j=0 ; j < width ; j++)
577  {
578  *(output++) = *(line);
579 
580  line++;
581  }
582  //go to the next line
583  input+=widthStep;
584  }
585  }
586 
587  if (color_type == COLORED)
588  {
589  unsigned char* input = (unsigned char*)pFrameRGB->data[0];
590  int widthStep = pFrameRGB->linesize[0];
591  for (int i = 0 ; i < height ; i++)
592  {
593  vpImageConvert::RGBToGrey(input + i*widthStep, beginOutput + i*width, (unsigned int)width, 1, false);
594  }
595  }
596 }
597 
602 {
603  if (streamWasOpen)
604  {
605  if (buffer != NULL) {
606  free(buffer);
607  buffer = NULL;
608  }
609 
610  if (color_type == vpFFMPEG::COLORED)
611  av_free(pFrameRGB);
612 
613  else if (color_type == vpFFMPEG::GRAY_SCALED)
614  av_free(pFrameGRAY);
615 
616  // Free the YUV frame
617  av_free(pFrame);
618 
619  // Close the codec
620  if (pCodecCtx) avcodec_close(pCodecCtx);
621 
622  // Close the video file
623 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
624  av_close_input_file(pFormatCtx);
625 #else
626  avformat_close_input(&pFormatCtx);
627 #endif
628  }
629  streamWasOpen = false;
630 
631  if (encoderWasOpened)
632  {
633  if(f!=NULL) endWrite();
634 
635  if(buffer!=NULL) delete[] buffer;
636 
637  if(outbuf != NULL) delete[] outbuf;
638 
639  if(picture_buf != NULL) delete[] picture_buf;
640 
641  av_free(pFrameRGB);
642  av_free(pFrame);
643  if (pCodecCtx) avcodec_close(pCodecCtx);
644  }
645 
646  encoderWasOpened = false;
647 
648  if(streamWasInitialized || encoderWasOpened){
649  sws_freeContext (img_convert_ctx);
650  }
651  streamWasInitialized = false;
652 }
653 
669 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,51,110) // libavcodec 54.51.100
670 bool vpFFMPEG::openEncoder(const char *filename, unsigned int w, unsigned int h, CodecID codec)
671 #else
672 bool vpFFMPEG::openEncoder(const char *filename, unsigned int w, unsigned int h, AVCodecID codec)
673 #endif
674 {
675  av_register_all();
676 
677  /* find the mpeg1 video encoder */
678  pCodec = avcodec_find_encoder(codec);
679  if (pCodec == NULL) {
680  fprintf(stderr, "codec not found\n");
681  return false;
682  }
683 
684 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
685  pCodecCtx = avcodec_alloc_context();
686 #else
687  pCodecCtx = avcodec_alloc_context3(NULL);
688 #endif
689 
690 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,34,0)
691  pFrame = avcodec_alloc_frame();
692  pFrameRGB = avcodec_alloc_frame();
693 #else
694  pFrame = av_frame_alloc(); // libavcodec 55.34.1
695  pFrameRGB = av_frame_alloc(); // libavcodec 55.34.1
696 #endif
697 
698  /* put sample parameters */
699  pCodecCtx->bit_rate = (int)bit_rate;
700  /* resolution must be a multiple of two */
701  pCodecCtx->width = (int)w;
702  pCodecCtx->height = (int)h;
703  this->width = (int)w;
704  this->height = (int)h;
705  /* frames per second */
706  pCodecCtx->time_base.num = 1;
707  pCodecCtx->time_base.den = framerate_encoder;
708  pCodecCtx->gop_size = 10; /* emit one intra frame every ten frames */
709  pCodecCtx->max_b_frames=1;
710  pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
711 
712  /* open it */
713 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
714  if (avcodec_open (pCodecCtx, pCodec) < 0) {
715 #else
716  if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
717 #endif
718  fprintf(stderr, "could not open codec\n");
719  return false;
720  }
721 
722  /* the codec gives us the frame size, in samples */
723 
724  f = fopen(filename, "wb");
725  if (!f) {
726  fprintf(stderr, "could not open %s\n", filename);
727  return false;
728  }
729 
730  outbuf_size = 100000;
731  outbuf = new uint8_t[outbuf_size];
732 
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);
736 
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);
740 
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);
742 
743  encoderWasOpened = true;
744 
745  return true;
746 }
747 
748 
757 {
758  if (encoderWasOpened == false)
759  {
760  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
761  return false;
762  }
763 
764  writeBitmap(I);
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);
769 #else
770  AVPacket pkt;
771  av_init_packet(&pkt);
772  pkt.data = NULL; // packet data will be allocated by the encoder
773  pkt.size = 0;
774 
775  int got_output;
776  int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
777  if (ret < 0) {
778  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
779  return false;
780  }
781  if (got_output) {
782  fwrite(pkt.data, 1, pkt.size, f);
783  av_free_packet(&pkt);
784  }
785 #endif
786  fflush(stdout);
787  return true;
788 }
789 
790 
799 {
800  if (encoderWasOpened == false)
801  {
802  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
803  return false;
804  }
805 
806  writeBitmap(I);
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);
811 #else
812  AVPacket pkt;
813  av_init_packet(&pkt);
814  pkt.data = NULL; // packet data will be allocated by the encoder
815  pkt.size = 0;
816 
817  int got_output;
818  int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
819  if (ret < 0) {
820  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
821  return false;
822  }
823  if (got_output) {
824  fwrite(pkt.data, 1, pkt.size, f);
825  av_free_packet(&pkt);
826  }
827 #endif
828 
829  fflush(stdout);
830  return true;
831 }
832 
839 {
840  if (encoderWasOpened == false)
841  {
842  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
843  return false;
844  }
845 
846  int ret = 1;
847  while (ret != 0)
848  {
849 
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);
853 #else
854  AVPacket pkt;
855  av_init_packet(&pkt);
856  pkt.data = NULL; // packet data will be allocated by the encoder
857  pkt.size = 0;
858  int got_output;
859  ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);
860  if (ret < 0) {
861  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
862  return false;
863  }
864  if (got_output) {
865  fwrite(pkt.data, 1, pkt.size, f);
866  av_free_packet(&pkt);
867  }
868 #endif
869  }
870 
871  /*The end of a mpeg file*/
872  outbuf[0] = 0x00;
873  outbuf[1] = 0x00;
874  outbuf[2] = 0x01;
875  outbuf[3] = 0xb7;
876  fwrite(outbuf, 1, 4, f);
877  fclose(f);
878  f = NULL;
879  return true;
880 }
881 
885 void vpFFMPEG::writeBitmap(vpImage<vpRGBa> &I)
886 {
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];
892 
893  for(int i=0 ; i < height ; i++)
894  {
895  input = beginInput + 4 * i * width;
896  output = beginOutput + i * widthStep;
897  for(int j=0 ; j < width ; j++)
898  {
899  *(output++) = *(input);
900  *(output++) = *(input+1);
901  *(output++) = *(input+2);
902 
903  input+=4;
904  }
905  }
906 }
907 
908 
912 void vpFFMPEG::writeBitmap(vpImage<unsigned char> &I)
913 {
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];
919 
920  for(int i=0 ; i < height ; i++)
921  {
922  input = beginInput + i * width;
923  output = beginOutput + i * widthStep;
924  for(int j=0 ; j < width ; j++)
925  {
926  *(output++) = *(input);
927  *(output++) = *(input);
928  *(output++) = *(input);
929 
930  input++;
931  }
932  }
933 }
934 
935 #endif
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
#define vpTRACE
Definition: vpDebug.h:418
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
bool saveFrame(vpImage< vpRGBa > &I)
Definition: vpFFMPEG.cpp:756
bool getFrame(vpImage< vpRGBa > &I, unsigned int frameNumber)
Definition: vpFFMPEG.cpp:294
error that can be emited by ViSP classes.
Definition: vpException.h:76
vpFFMPEG()
Definition: vpFFMPEG.cpp:67
bool openStream(const char *filename, vpFFMPEGColorType color_type)
Definition: vpFFMPEG.cpp:99
void resize(const unsigned int h, const unsigned int w)
set the size of the image without initializing it.
Definition: vpImage.h:536
~vpFFMPEG()
Definition: vpFFMPEG.cpp:82
vpFFMPEGColorType
Definition: vpFFMPEG.h:152
void closeStream()
Definition: vpFFMPEG.cpp:601
bool acquire(vpImage< vpRGBa > &I)
Definition: vpFFMPEG.cpp:348
bool initStream()
Definition: vpFFMPEG.cpp:235
bool endWrite()
Definition: vpFFMPEG.cpp:838
bool openEncoder(const char *filename, unsigned int width, unsigned int height, AVCodecID codec=AV_CODEC_ID_MPEG1VIDEO)
Definition: vpFFMPEG.cpp:672