ViSP  2.9.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  framerate_stream = pFormatCtx->streams[i]->r_frame_rate.num;
138  framerate_stream /= pFormatCtx->streams[i]->r_frame_rate.den;
139  found_codec= true;
140  break;
141  }
142  }
143 
144  if (found_codec)
145  {
146  pCodecCtx = pFormatCtx->streams[videoStream]->codec;
147  pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
148 
149  if (pCodec == NULL)
150  {
151  vpTRACE("unsuported codec");
152  return false; // Codec not found
153  }
154 
155 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
156  if (avcodec_open (pCodecCtx, pCodec) < 0)
157 #else
158  if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
159 #endif
160  {
161  vpTRACE("Could not open codec");
162  return false; // Could not open codec
163  }
164 
165  pFrame = avcodec_alloc_frame();
166 
167  if (color_type == vpFFMPEG::COLORED)
168  {
169  pFrameRGB=avcodec_alloc_frame();
170 
171  if (pFrameRGB == NULL)
172  return false;
173 
174  numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
175  }
176 
177  else if (color_type == vpFFMPEG::GRAY_SCALED)
178  {
179  pFrameGRAY=avcodec_alloc_frame();
180 
181  if (pFrameGRAY == NULL)
182  return false;
183 
184  numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
185  }
186 
187  /*
188  * Determine required buffer size and allocate buffer
189  */
190  width = pCodecCtx->width ;
191  height = pCodecCtx->height ;
192  buffer = (uint8_t *) malloc ((unsigned int)(sizeof (uint8_t)) * (unsigned int)numBytes);
193  }
194  else
195  {
196  vpTRACE("Didn't find a video stream");
197  return false;
198  }
199 
200  if (color_type == vpFFMPEG::COLORED)
201  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
202 
203  else if (color_type == vpFFMPEG::GRAY_SCALED)
204  avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
205 
206  streamWasOpen = true;
207 
208  return true;
209 }
210 
219 {
220  if (color_type == vpFFMPEG::COLORED)
221  img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
222 
223  else if (color_type == vpFFMPEG::GRAY_SCALED)
224  img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height,PIX_FMT_GRAY8, SWS_BICUBIC, NULL, NULL, NULL);
225 
226  int ret = av_seek_frame(pFormatCtx, (int)videoStream, 0, AVSEEK_FLAG_ANY) ;
227  if (ret < 0 )
228  {
229  vpTRACE("Error rewinding stream for full indexing") ;
230  return false ;
231  }
232  avcodec_flush_buffers(pCodecCtx) ;
233 
234  int frame_no = 0 ;
235  int frameFinished ;
236 
237  av_init_packet(packet);
238  while (av_read_frame (pFormatCtx, packet) >= 0)
239  {
240  if (packet->stream_index == (int)videoStream)
241  {
242 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
243  ret = avcodec_decode_video(pCodecCtx, pFrame,
244  &frameFinished, packet->data, packet->size);
245 #else
246  ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
247 #endif
248  if (frameFinished)
249  {
250  if (ret < 0 )
251  {
252  vpTRACE("Unable to decode video picture");
253  }
254  index.push_back(packet->dts);
255  frame_no++ ;
256  }
257  }
258  }
259 
260  frameNumber = index.size();
261  av_free_packet(packet);
262 
263  streamWasInitialized = true;
264 
265  return true;
266 }
267 
268 
277 bool vpFFMPEG::getFrame(vpImage<vpRGBa> &I, unsigned int frame)
278 {
279 
280  if (frame < frameNumber && streamWasInitialized== true)
281  {
282  int64_t targetPts = index[frame];
283  av_seek_frame(pFormatCtx, (int)videoStream,targetPts, AVSEEK_FLAG_ANY);
284  }
285  else
286  {
287  vpTRACE("Couldn't get a frame");
288  return false;
289  }
290 
291  avcodec_flush_buffers(pCodecCtx) ;
292 
293  int frameFinished ;
294 
295  av_init_packet(packet);
296  while (av_read_frame (pFormatCtx, packet) >= 0)
297  {
298  if (packet->stream_index == (int)videoStream)
299  {
300 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
301  avcodec_decode_video(pCodecCtx, pFrame,
302  &frameFinished, packet->data, packet->size);
303 #else
304  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
305 #endif
306  if (frameFinished)
307  {
308  if (color_type == vpFFMPEG::COLORED)
309  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
310  else if (color_type == vpFFMPEG::GRAY_SCALED)
311  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
312 
313  copyBitmap(I);
314  break;
315  }
316  }
317  }
318 
319  av_free_packet(packet);
320  return true;
321 }
322 
323 
332 {
333  int frameFinished ;
334 
335  if (streamWasInitialized == false)
336  {
337  vpTRACE("Couldn't get a frame. The parameters have to be initialized before ");
338  return false;
339  }
340 
341  av_init_packet(packet);
342  while (av_read_frame (pFormatCtx, packet) >= 0)
343  {
344  if (packet->stream_index == (int)videoStream)
345  {
346 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
347  avcodec_decode_video(pCodecCtx, pFrame,
348  &frameFinished, packet->data, packet->size);
349 #else
350  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
351 #endif
352  if (frameFinished)
353  {
354  if (color_type == vpFFMPEG::COLORED)
355  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
356  else if (color_type == vpFFMPEG::GRAY_SCALED)
357  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
358 
359  copyBitmap(I);
360  break;
361  }
362  }
363  }
364  av_free_packet(packet);
365  return true;
366 }
367 
376 bool vpFFMPEG::getFrame(vpImage<unsigned char> &I, unsigned int frame)
377 {
378 
379  if (frame < frameNumber && streamWasInitialized== true)
380  {
381  int64_t targetPts = index[frame];
382  av_seek_frame(pFormatCtx,(int)videoStream,targetPts, AVSEEK_FLAG_ANY);
383  }
384  else
385  {
386  vpTRACE("Couldn't get a frame");
387  return false;
388  }
389 
390  avcodec_flush_buffers(pCodecCtx) ;
391 
392  int frameFinished ;
393 
394  av_init_packet(packet);
395  while (av_read_frame (pFormatCtx, packet) >= 0)
396  {
397  if (packet->stream_index == (int)videoStream)
398  {
399 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
400  avcodec_decode_video(pCodecCtx, pFrame,
401  &frameFinished, packet->data, packet->size);
402 #else
403  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
404 #endif
405  if (frameFinished)
406  {
407  if (color_type == vpFFMPEG::COLORED)
408  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
409  else if (color_type == vpFFMPEG::GRAY_SCALED)
410  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
411 
412  copyBitmap(I);
413  break;
414  }
415  }
416  }
417 
418  av_free_packet(packet);
419  return true;
420 }
421 
422 
431 {
432  int frameFinished ;
433 
434  if (streamWasInitialized == false)
435  {
436  vpTRACE("Couldn't get a frame. The parameters have to be initialized before ");
437  return false;
438  }
439 
440  av_init_packet(packet);
441  while (av_read_frame (pFormatCtx, packet) >= 0)
442  {
443  if (packet->stream_index == (int)videoStream)
444  {
445 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
446  avcodec_decode_video(pCodecCtx, pFrame,
447  &frameFinished, packet->data, packet->size);
448 #else
449  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
450 #endif
451  if (frameFinished)
452  {
453  if (color_type == vpFFMPEG::COLORED)
454  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
455  else if (color_type == vpFFMPEG::GRAY_SCALED)
456  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
457 
458  copyBitmap(I);
459  break;
460  }
461  }
462  }
463  av_free_packet(packet);
464  return true;
465 }
466 
467 
476 void vpFFMPEG::copyBitmap(vpImage<vpRGBa> &I)
477 {
478  if(height < 0 || width < 0){
479  throw vpException(vpException::dimensionError, "width or height negative.");
480  }
481  I.resize((unsigned int)height, (unsigned int)width);
482 
483  unsigned char* line;
484  unsigned char* beginOutput = (unsigned char*)I.bitmap;
485  unsigned char* output = NULL;
486 
487  if (color_type == COLORED)
488  {
489  unsigned char* input = (unsigned char*)pFrameRGB->data[0];
490  int widthStep = pFrameRGB->linesize[0];
491  for(int i=0 ; i < height ; i++)
492  {
493  line = input;
494  output = beginOutput + 4 * width * i;
495  for(int j=0 ; j < width ; j++)
496  {
497  *(output++) = *(line);
498  *(output++) = *(line+1);
499  *(output++) = *(line+2);
500  *(output++) = 0;
501 
502  line+=3;
503  }
504  //go to the next line
505  input+=widthStep;
506  }
507  }
508 
509  else if (color_type == GRAY_SCALED)
510  {
511  unsigned char* input = (unsigned char*)pFrameGRAY->data[0];
512  int widthStep = pFrameGRAY->linesize[0];
513  for(int i=0 ; i < height ; i++)
514  {
515  line = input;
516  output = beginOutput + 4 * width * i;
517  for(int j=0 ; j < width ; j++)
518  {
519  *output++ = *(line);
520  *output++ = *(line);
521  *output++ = *(line);
522  *output++ = *(line);;
523 
524  line++;
525  }
526  //go to the next line
527  input+=widthStep;
528  }
529  }
530 }
531 
540 void vpFFMPEG::copyBitmap(vpImage<unsigned char> &I)
541 {
542  if(height < 0 || width < 0){
543  throw vpException(vpException::dimensionError, "width or height negative.");
544  }
545  I.resize((unsigned int)height, (unsigned int)width);
546 
547  unsigned char* line;
548  unsigned char* beginOutput = (unsigned char*)I.bitmap;
549  unsigned char* output = NULL;
550 
551  if (color_type == GRAY_SCALED)
552  {
553  unsigned char* input = (unsigned char*)pFrameGRAY->data[0];
554  int widthStep = pFrameGRAY->linesize[0];
555  for(int i=0 ; i < height ; i++)
556  {
557  line = input;
558  output = beginOutput + width * i;
559  for(int j=0 ; j < width ; j++)
560  {
561  *(output++) = *(line);
562 
563  line++;
564  }
565  //go to the next line
566  input+=widthStep;
567  }
568  }
569 
570  if (color_type == COLORED)
571  {
572  unsigned char* input = (unsigned char*)pFrameRGB->data[0];
573  int widthStep = pFrameRGB->linesize[0];
574  for (int i = 0 ; i < height ; i++)
575  {
576  vpImageConvert::RGBToGrey(input + i*widthStep, beginOutput + i*width, (unsigned int)width, 1, false);
577  }
578  }
579 }
580 
585 {
586  if (streamWasOpen)
587  {
588  av_free(buffer);
589 
590  if (color_type == vpFFMPEG::COLORED)
591  av_free(pFrameRGB);
592 
593  else if (color_type == vpFFMPEG::GRAY_SCALED)
594  av_free(pFrameGRAY);
595 
596  // Free the YUV frame
597  av_free(pFrame);
598 
599  // Close the codec
600  if (pCodecCtx) avcodec_close(pCodecCtx);
601 
602  // Close the video file
603 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
604  av_close_input_file(pFormatCtx);
605 #else
606  avformat_close_input(&pFormatCtx);
607 #endif
608  }
609  streamWasOpen = false;
610 
611  if (encoderWasOpened)
612  {
613  if(f!=NULL) endWrite();
614 
615  if(buffer!=NULL) delete[] buffer;
616 
617  if(outbuf != NULL) delete[] outbuf;
618 
619  if(picture_buf != NULL) delete[] picture_buf;
620 
621  av_free(pFrameRGB);
622  av_free(pFrame);
623  if (pCodecCtx) avcodec_close(pCodecCtx);
624  }
625 
626  encoderWasOpened = false;
627 
628  if(streamWasInitialized || encoderWasOpened){
629  sws_freeContext (img_convert_ctx);
630  }
631  streamWasInitialized = false;
632 }
633 
649 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,51,110) // libavcodec 54.51.100
650 bool vpFFMPEG::openEncoder(const char *filename, unsigned int w, unsigned int h, CodecID codec)
651 #else
652 bool vpFFMPEG::openEncoder(const char *filename, unsigned int w, unsigned int h, AVCodecID codec)
653 #endif
654 {
655  av_register_all();
656 
657  /* find the mpeg1 video encoder */
658  pCodec = avcodec_find_encoder(codec);
659  if (pCodec == NULL) {
660  fprintf(stderr, "codec not found\n");
661  return false;
662  }
663 
664 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
665  pCodecCtx = avcodec_alloc_context();
666 #else
667  pCodecCtx = avcodec_alloc_context3(NULL);
668 #endif
669  pFrame = avcodec_alloc_frame();
670  pFrameRGB = avcodec_alloc_frame();
671 
672  /* put sample parameters */
673  pCodecCtx->bit_rate = (int)bit_rate;
674  /* resolution must be a multiple of two */
675  pCodecCtx->width = (int)w;
676  pCodecCtx->height = (int)h;
677  this->width = (int)w;
678  this->height = (int)h;
679  /* frames per second */
680  pCodecCtx->time_base= (AVRational){1,framerate_encoder};
681  pCodecCtx->gop_size = 10; /* emit one intra frame every ten frames */
682  pCodecCtx->max_b_frames=1;
683  pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
684 
685  /* open it */
686 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
687  if (avcodec_open (pCodecCtx, pCodec) < 0) {
688 #else
689  if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
690 #endif
691  fprintf(stderr, "could not open codec\n");
692  return false;
693  }
694 
695  /* the codec gives us the frame size, in samples */
696 
697  f = fopen(filename, "wb");
698  if (!f) {
699  fprintf(stderr, "could not open %s\n", filename);
700  return false;
701  }
702 
703  outbuf_size = 100000;
704  outbuf = new uint8_t[outbuf_size];
705 
706  numBytes = avpicture_get_size (PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);
707  picture_buf = new uint8_t[numBytes];
708  avpicture_fill((AVPicture *)pFrame, picture_buf, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
709 
710  numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
711  buffer = new uint8_t[numBytes];
712  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
713 
714  img_convert_ctx= sws_getContext(pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
715 
716  encoderWasOpened = true;
717 
718  return true;
719 }
720 
721 
730 {
731  if (encoderWasOpened == false)
732  {
733  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
734  return false;
735  }
736 
737  writeBitmap(I);
738  sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
739 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
740  out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
741  fwrite(outbuf, 1, (size_t)out_size, f);
742 #else
743  AVPacket pkt;
744  av_init_packet(&pkt);
745  pkt.data = NULL; // packet data will be allocated by the encoder
746  pkt.size = 0;
747 
748  int got_output;
749  int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
750  if (ret < 0) {
751  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
752  return false;
753  }
754  if (got_output) {
755  fwrite(pkt.data, 1, pkt.size, f);
756  av_free_packet(&pkt);
757  }
758 #endif
759  fflush(stdout);
760  return true;
761 }
762 
763 
772 {
773  if (encoderWasOpened == false)
774  {
775  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
776  return false;
777  }
778 
779  writeBitmap(I);
780  sws_scale(img_convert_ctx, pFrameRGB->data, pFrameRGB->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
781 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
782  out_size = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, pFrame);
783  fwrite(outbuf, 1, (size_t)out_size, f);
784 #else
785  AVPacket pkt;
786  av_init_packet(&pkt);
787  pkt.data = NULL; // packet data will be allocated by the encoder
788  pkt.size = 0;
789 
790  int got_output;
791  int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
792  if (ret < 0) {
793  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
794  return false;
795  }
796  if (got_output) {
797  fwrite(pkt.data, 1, pkt.size, f);
798  av_free_packet(&pkt);
799  }
800 #endif
801 
802  fflush(stdout);
803  return true;
804 }
805 
812 {
813  if (encoderWasOpened == false)
814  {
815  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
816  return false;
817  }
818 
819  int ret = 1;
820  while (ret != 0)
821  {
822 
823 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,2,100) // libavcodec 54.2.100
824  ret = avcodec_encode_video(pCodecCtx, outbuf, outbuf_size, NULL);
825  fwrite(outbuf, 1, (size_t)out_size, f);
826 #else
827  AVPacket pkt;
828  av_init_packet(&pkt);
829  pkt.data = NULL; // packet data will be allocated by the encoder
830  pkt.size = 0;
831  int got_output;
832  ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);
833  if (ret < 0) {
834  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
835  return false;
836  }
837  if (got_output) {
838  fwrite(pkt.data, 1, pkt.size, f);
839  av_free_packet(&pkt);
840  }
841 #endif
842  }
843 
844  /*The end of a mpeg file*/
845  outbuf[0] = 0x00;
846  outbuf[1] = 0x00;
847  outbuf[2] = 0x01;
848  outbuf[3] = 0xb7;
849  fwrite(outbuf, 1, 4, f);
850  fclose(f);
851  f = NULL;
852  return true;
853 }
854 
858 void vpFFMPEG::writeBitmap(vpImage<vpRGBa> &I)
859 {
860  unsigned char* beginInput = (unsigned char*)I.bitmap;
861  unsigned char* input = NULL;
862  unsigned char* output = NULL;
863  unsigned char* beginOutput = (unsigned char*)pFrameRGB->data[0];
864  int widthStep = pFrameRGB->linesize[0];
865 
866  for(int i=0 ; i < height ; i++)
867  {
868  input = beginInput + 4 * i * width;
869  output = beginOutput + i * widthStep;
870  for(int j=0 ; j < width ; j++)
871  {
872  *(output++) = *(input);
873  *(output++) = *(input+1);
874  *(output++) = *(input+2);
875 
876  input+=4;
877  }
878  }
879 }
880 
881 
885 void vpFFMPEG::writeBitmap(vpImage<unsigned char> &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 + i * width;
896  output = beginOutput + i * widthStep;
897  for(int j=0 ; j < width ; j++)
898  {
899  *(output++) = *(input);
900  *(output++) = *(input);
901  *(output++) = *(input);
902 
903  input++;
904  }
905  }
906 }
907 
908 #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:729
bool getFrame(vpImage< vpRGBa > &I, unsigned int frameNumber)
Definition: vpFFMPEG.cpp:277
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
Definition: vpImage.h:532
~vpFFMPEG()
Definition: vpFFMPEG.cpp:82
vpFFMPEGColorType
Definition: vpFFMPEG.h:152
void closeStream()
Definition: vpFFMPEG.cpp:584
bool acquire(vpImage< vpRGBa > &I)
Definition: vpFFMPEG.cpp:331
bool initStream()
Definition: vpFFMPEG.cpp:218
bool endWrite()
Definition: vpFFMPEG.cpp:811
bool openEncoder(const char *filename, unsigned int width, unsigned int height, AVCodecID codec=AV_CODEC_ID_MPEG1VIDEO)
Definition: vpFFMPEG.cpp:652