ViSP  2.8.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 - 2013 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 {
69  frameNumber = 0;
70  width = -1;
71  height = -1;
72  framerate_stream = -1;
73  framerate_encoder = 25;
74  buffer = NULL;
75  streamWasOpen = false;
76  streamWasInitialized = false;
77  bit_rate = 500000;
78  outbuf = NULL;
79  picture_buf = NULL;
80  f = NULL;
81  encoderWasOpened = false;
82  packet = new AVPacket;
83 
84  pFormatCtx = NULL;
85 }
86 
91 {
92  closeStream();
93  delete packet;
94 }
95 
107 bool vpFFMPEG::openStream(const char *filename, vpFFMPEGColorType color_type)
108 {
109  this->color_type = color_type;
110 
111  av_register_all();
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)
114 #else
115  if (avformat_open_input (&pFormatCtx, filename, NULL, NULL) != 0) // libavformat 53.4.0
116 #endif
117  {
118  vpTRACE("Couldn't open file ");
119  return false;
120  }
121 
122 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,21,0) // libavformat 53.21.0
123  if (av_find_stream_info (pFormatCtx) < 0)
124 #else
125  if (avformat_find_stream_info (pFormatCtx, NULL) < 0)
126 #endif
127  return false;
128 
129  videoStream = 0;
130  bool found_codec = false;
131 
132  /*
133  * Detect streams types
134  */
135  for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
136  {
137 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,0,0)
138  if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) // avutil 50.33.0
139 #else
140  if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) // avutil 51.9.1
141 #endif
142  {
143  videoStream = i;
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;
147  found_codec= true;
148  break;
149  }
150  }
151 
152  if (found_codec)
153  {
154  pCodecCtx = pFormatCtx->streams[videoStream]->codec;
155  pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
156 
157  if (pCodec == NULL)
158  {
159  vpTRACE("unsuported codec");
160  return false; // Codec not found
161  }
162 
163 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
164  if (avcodec_open (pCodecCtx, pCodec) < 0)
165 #else
166  if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0)
167 #endif
168  {
169  vpTRACE("Could not open codec");
170  return false; // Could not open codec
171  }
172 
173  pFrame = avcodec_alloc_frame();
174 
175  if (color_type == vpFFMPEG::COLORED)
176  {
177  pFrameRGB=avcodec_alloc_frame();
178 
179  if (pFrameRGB == NULL)
180  return false;
181 
182  numBytes = avpicture_get_size (PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height);
183  }
184 
185  else if (color_type == vpFFMPEG::GRAY_SCALED)
186  {
187  pFrameGRAY=avcodec_alloc_frame();
188 
189  if (pFrameGRAY == NULL)
190  return false;
191 
192  numBytes = avpicture_get_size (PIX_FMT_GRAY8,pCodecCtx->width,pCodecCtx->height);
193  }
194 
195  /*
196  * Determine required buffer size and allocate buffer
197  */
198  width = pCodecCtx->width ;
199  height = pCodecCtx->height ;
200  buffer = (uint8_t *) malloc ((unsigned int)(sizeof (uint8_t)) * (unsigned int)numBytes);
201  }
202  else
203  {
204  vpTRACE("Didn't find a video stream");
205  return false;
206  }
207 
208  if (color_type == vpFFMPEG::COLORED)
209  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
210 
211  else if (color_type == vpFFMPEG::GRAY_SCALED)
212  avpicture_fill((AVPicture *)pFrameGRAY, buffer, PIX_FMT_GRAY8, pCodecCtx->width, pCodecCtx->height);
213 
214  streamWasOpen = true;
215 
216  return true;
217 }
218 
227 {
228  if (color_type == vpFFMPEG::COLORED)
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);
230 
231  else if (color_type == vpFFMPEG::GRAY_SCALED)
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);
233 
234  int ret = av_seek_frame(pFormatCtx, (int)videoStream, 0, AVSEEK_FLAG_ANY) ;
235  if (ret < 0 )
236  {
237  vpTRACE("Error rewinding stream for full indexing") ;
238  return false ;
239  }
240  avcodec_flush_buffers(pCodecCtx) ;
241 
242  int frame_no = 0 ;
243  int frameFinished ;
244 
245  av_init_packet(packet);
246  while (av_read_frame (pFormatCtx, packet) >= 0)
247  {
248  if (packet->stream_index == (int)videoStream)
249  {
250 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
251  ret = avcodec_decode_video(pCodecCtx, pFrame,
252  &frameFinished, packet->data, packet->size);
253 #else
254  ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
255 #endif
256  if (frameFinished)
257  {
258  if (ret < 0 )
259  {
260  vpTRACE("Unable to decode video picture");
261  }
262  index.push_back(packet->dts);
263  frame_no++ ;
264  }
265  }
266  }
267 
268  frameNumber = index.size();
269  av_free_packet(packet);
270 
271  streamWasInitialized = true;
272 
273  return true;
274 }
275 
276 
285 bool vpFFMPEG::getFrame(vpImage<vpRGBa> &I, unsigned int frame)
286 {
287 
288  if (frame < frameNumber && streamWasInitialized== true)
289  {
290  int64_t targetPts = index[frame];
291  av_seek_frame(pFormatCtx, (int)videoStream,targetPts, AVSEEK_FLAG_ANY);
292  }
293  else
294  {
295  vpTRACE("Couldn't get a frame");
296  return false;
297  }
298 
299  avcodec_flush_buffers(pCodecCtx) ;
300 
301  int frameFinished ;
302 
303  av_init_packet(packet);
304  while (av_read_frame (pFormatCtx, packet) >= 0)
305  {
306  if (packet->stream_index == (int)videoStream)
307  {
308 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
309  avcodec_decode_video(pCodecCtx, pFrame,
310  &frameFinished, packet->data, packet->size);
311 #else
312  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
313 #endif
314  if (frameFinished)
315  {
316  if (color_type == vpFFMPEG::COLORED)
317  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
318  else if (color_type == vpFFMPEG::GRAY_SCALED)
319  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
320 
321  copyBitmap(I);
322  break;
323  }
324  }
325  }
326 
327  av_free_packet(packet);
328  return true;
329 }
330 
331 
340 {
341  int frameFinished ;
342 
343  if (streamWasInitialized == false)
344  {
345  vpTRACE("Couldn't get a frame. The parameters have to be initialized before ");
346  return false;
347  }
348 
349  av_init_packet(packet);
350  while (av_read_frame (pFormatCtx, packet) >= 0)
351  {
352  if (packet->stream_index == (int)videoStream)
353  {
354 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
355  avcodec_decode_video(pCodecCtx, pFrame,
356  &frameFinished, packet->data, packet->size);
357 #else
358  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
359 #endif
360  if (frameFinished)
361  {
362  if (color_type == vpFFMPEG::COLORED)
363  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
364  else if (color_type == vpFFMPEG::GRAY_SCALED)
365  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
366 
367  copyBitmap(I);
368  break;
369  }
370  }
371  }
372  av_free_packet(packet);
373  return true;
374 }
375 
384 bool vpFFMPEG::getFrame(vpImage<unsigned char> &I, unsigned int frame)
385 {
386 
387  if (frame < frameNumber && streamWasInitialized== true)
388  {
389  int64_t targetPts = index[frame];
390  av_seek_frame(pFormatCtx,(int)videoStream,targetPts, AVSEEK_FLAG_ANY);
391  }
392  else
393  {
394  vpTRACE("Couldn't get a frame");
395  return false;
396  }
397 
398  avcodec_flush_buffers(pCodecCtx) ;
399 
400  int frameFinished ;
401 
402  av_init_packet(packet);
403  while (av_read_frame (pFormatCtx, packet) >= 0)
404  {
405  if (packet->stream_index == (int)videoStream)
406  {
407 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
408  avcodec_decode_video(pCodecCtx, pFrame,
409  &frameFinished, packet->data, packet->size);
410 #else
411  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
412 #endif
413  if (frameFinished)
414  {
415  if (color_type == vpFFMPEG::COLORED)
416  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
417  else if (color_type == vpFFMPEG::GRAY_SCALED)
418  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
419 
420  copyBitmap(I);
421  break;
422  }
423  }
424  }
425 
426  av_free_packet(packet);
427  return true;
428 }
429 
430 
439 {
440  int frameFinished ;
441 
442  if (streamWasInitialized == false)
443  {
444  vpTRACE("Couldn't get a frame. The parameters have to be initialized before ");
445  return false;
446  }
447 
448  av_init_packet(packet);
449  while (av_read_frame (pFormatCtx, packet) >= 0)
450  {
451  if (packet->stream_index == (int)videoStream)
452  {
453 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52,72,2)
454  avcodec_decode_video(pCodecCtx, pFrame,
455  &frameFinished, packet->data, packet->size);
456 #else
457  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); // libavcodec >= 52.72.2 (0.6)
458 #endif
459  if (frameFinished)
460  {
461  if (color_type == vpFFMPEG::COLORED)
462  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
463  else if (color_type == vpFFMPEG::GRAY_SCALED)
464  sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameGRAY->data, pFrameGRAY->linesize);
465 
466  copyBitmap(I);
467  break;
468  }
469  }
470  }
471  av_free_packet(packet);
472  return true;
473 }
474 
475 
484 void vpFFMPEG::copyBitmap(vpImage<vpRGBa> &I)
485 {
486  if(height < 0 || width < 0){
487  throw vpException(vpException::dimensionError, "width or height negative.");
488  }
489  I.resize((unsigned int)height, (unsigned int)width);
490 
491  unsigned char* line;
492  unsigned char* beginOutput = (unsigned char*)I.bitmap;
493  unsigned char* output = NULL;
494 
495  if (color_type == COLORED)
496  {
497  unsigned char* input = (unsigned char*)pFrameRGB->data[0];
498  int widthStep = pFrameRGB->linesize[0];
499  for(int i=0 ; i < height ; i++)
500  {
501  line = input;
502  output = beginOutput + 4 * width * i;
503  for(int j=0 ; j < width ; j++)
504  {
505  *(output++) = *(line);
506  *(output++) = *(line+1);
507  *(output++) = *(line+2);
508  *(output++) = 0;
509 
510  line+=3;
511  }
512  //go to the next line
513  input+=widthStep;
514  }
515  }
516 
517  else if (color_type == GRAY_SCALED)
518  {
519  unsigned char* input = (unsigned char*)pFrameGRAY->data[0];
520  int widthStep = pFrameGRAY->linesize[0];
521  for(int i=0 ; i < height ; i++)
522  {
523  line = input;
524  output = beginOutput + 4 * width * i;
525  for(int j=0 ; j < width ; j++)
526  {
527  *output++ = *(line);
528  *output++ = *(line);
529  *output++ = *(line);
530  *output++ = *(line);;
531 
532  line++;
533  }
534  //go to the next line
535  input+=widthStep;
536  }
537  }
538 }
539 
548 void vpFFMPEG::copyBitmap(vpImage<unsigned char> &I)
549 {
550  if(height < 0 || width < 0){
551  throw vpException(vpException::dimensionError, "width or height negative.");
552  }
553  I.resize((unsigned int)height, (unsigned int)width);
554 
555  unsigned char* line;
556  unsigned char* beginOutput = (unsigned char*)I.bitmap;
557  unsigned char* output = NULL;
558 
559  if (color_type == GRAY_SCALED)
560  {
561  unsigned char* input = (unsigned char*)pFrameGRAY->data[0];
562  int widthStep = pFrameGRAY->linesize[0];
563  for(int i=0 ; i < height ; i++)
564  {
565  line = input;
566  output = beginOutput + width * i;
567  for(int j=0 ; j < width ; j++)
568  {
569  *(output++) = *(line);
570 
571  line++;
572  }
573  //go to the next line
574  input+=widthStep;
575  }
576  }
577 
578  if (color_type == COLORED)
579  {
580  unsigned char* input = (unsigned char*)pFrameRGB->data[0];
581  int widthStep = pFrameRGB->linesize[0];
582  for (int i = 0 ; i < height ; i++)
583  {
584  vpImageConvert::RGBToGrey(input + i*widthStep, beginOutput + i*width, (unsigned int)width, 1, false);
585  }
586  }
587 }
588 
593 {
594  if (streamWasOpen)
595  {
596  av_free(buffer);
597 
598  if (color_type == vpFFMPEG::COLORED)
599  av_free(pFrameRGB);
600 
601  else if (color_type == vpFFMPEG::GRAY_SCALED)
602  av_free(pFrameGRAY);
603 
604  // Free the YUV frame
605  av_free(pFrame);
606 
607  // Close the codec
608  if (pCodecCtx) avcodec_close(pCodecCtx);
609 
610  // Close the video file
611 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53,17,0) // libavformat 53.17.0
612  av_close_input_file(pFormatCtx);
613 #else
614  avformat_close_input(&pFormatCtx);
615 #endif
616  }
617  streamWasOpen = false;
618 
619  if (encoderWasOpened)
620  {
621  if(f!=NULL) endWrite();
622 
623  if(buffer!=NULL) delete[] buffer;
624 
625  if(outbuf != NULL) delete[] outbuf;
626 
627  if(picture_buf != NULL) delete[] picture_buf;
628 
629  av_free(pFrameRGB);
630  av_free(pFrame);
631  if (pCodecCtx) avcodec_close(pCodecCtx);
632  }
633 
634  encoderWasOpened = false;
635 
636  if(streamWasInitialized || encoderWasOpened){
637  sws_freeContext (img_convert_ctx);
638  }
639  streamWasInitialized = false;
640 }
641 
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)
660 #else
661 bool vpFFMPEG::openEncoder(const char *filename, unsigned int width, unsigned int height, AVCodecID codec)
662 #endif
663 {
664  av_register_all();
665 
666  /* find the mpeg1 video encoder */
667  pCodec = avcodec_find_encoder(codec);
668  if (pCodec == NULL) {
669  fprintf(stderr, "codec not found\n");
670  return false;
671  }
672 
673 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,5,0) // libavcodec 53.5.0
674  pCodecCtx = avcodec_alloc_context();
675 #else
676  pCodecCtx = avcodec_alloc_context3(NULL);
677 #endif
678  pFrame = avcodec_alloc_frame();
679  pFrameRGB = avcodec_alloc_frame();
680 
681  /* put sample parameters */
682  pCodecCtx->bit_rate = (int)bit_rate;
683  /* resolution must be a multiple of two */
684  pCodecCtx->width = (int)width;
685  pCodecCtx->height = (int)height;
686  this->width = (int)width;
687  this->height = (int)height;
688  /* frames per second */
689  pCodecCtx->time_base= (AVRational){1,framerate_encoder};
690  pCodecCtx->gop_size = 10; /* emit one intra frame every ten frames */
691  pCodecCtx->max_b_frames=1;
692  pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
693 
694  /* open it */
695 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,35,0) // libavcodec 53.35.0
696  if (avcodec_open (pCodecCtx, pCodec) < 0) {
697 #else
698  if (avcodec_open2 (pCodecCtx, pCodec, NULL) < 0) {
699 #endif
700  fprintf(stderr, "could not open codec\n");
701  return false;
702  }
703 
704  /* the codec gives us the frame size, in samples */
705 
706  f = fopen(filename, "wb");
707  if (!f) {
708  fprintf(stderr, "could not open %s\n", filename);
709  return false;
710  }
711 
712  outbuf_size = 100000;
713  outbuf = new uint8_t[outbuf_size];
714 
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);
718 
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);
722 
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);
724 
725  encoderWasOpened = true;
726 
727  return true;
728 }
729 
730 
739 {
740  if (encoderWasOpened == false)
741  {
742  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
743  return false;
744  }
745 
746  writeBitmap(I);
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);
751 #else
752  AVPacket pkt;
753  av_init_packet(&pkt);
754  pkt.data = NULL; // packet data will be allocated by the encoder
755  pkt.size = 0;
756 
757  int got_output;
758  int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
759  if (ret < 0) {
760  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
761  return false;
762  }
763  if (got_output) {
764  fwrite(pkt.data, 1, pkt.size, f);
765  av_free_packet(&pkt);
766  }
767 #endif
768  fflush(stdout);
769  return true;
770 }
771 
772 
781 {
782  if (encoderWasOpened == false)
783  {
784  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
785  return false;
786  }
787 
788  writeBitmap(I);
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);
793 #else
794  AVPacket pkt;
795  av_init_packet(&pkt);
796  pkt.data = NULL; // packet data will be allocated by the encoder
797  pkt.size = 0;
798 
799  int got_output;
800  int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output);
801  if (ret < 0) {
802  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
803  return false;
804  }
805  if (got_output) {
806  fwrite(pkt.data, 1, pkt.size, f);
807  av_free_packet(&pkt);
808  }
809 #endif
810 
811  fflush(stdout);
812  return true;
813 }
814 
821 {
822  if (encoderWasOpened == false)
823  {
824  vpTRACE("Couldn't save a frame. The parameters have to be initialized before ");
825  return false;
826  }
827 
828  int ret = 1;
829  while (ret != 0)
830  {
831 
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);
835 #else
836  AVPacket pkt;
837  av_init_packet(&pkt);
838  pkt.data = NULL; // packet data will be allocated by the encoder
839  pkt.size = 0;
840  int got_output;
841  ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output);
842  if (ret < 0) {
843  std::cerr << "Error encoding frame in " << __FILE__ << " " << __LINE__ << " " << __FUNCTION__ << std::endl;
844  return false;
845  }
846  if (got_output) {
847  fwrite(pkt.data, 1, pkt.size, f);
848  av_free_packet(&pkt);
849  }
850 #endif
851  }
852 
853  /*The end of a mpeg file*/
854  outbuf[0] = 0x00;
855  outbuf[1] = 0x00;
856  outbuf[2] = 0x01;
857  outbuf[3] = 0xb7;
858  fwrite(outbuf, 1, 4, f);
859  fclose(f);
860  f = NULL;
861  return true;
862 }
863 
867 void vpFFMPEG::writeBitmap(vpImage<vpRGBa> &I)
868 {
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];
874 
875  for(int i=0 ; i < height ; i++)
876  {
877  input = beginInput + 4 * i * width;
878  output = beginOutput + i * widthStep;
879  for(int j=0 ; j < width ; j++)
880  {
881  *(output++) = *(input);
882  *(output++) = *(input+1);
883  *(output++) = *(input+2);
884 
885  input+=4;
886  }
887  }
888 }
889 
890 
894 void vpFFMPEG::writeBitmap(vpImage<unsigned char> &I)
895 {
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];
901 
902  for(int i=0 ; i < height ; i++)
903  {
904  input = beginInput + i * width;
905  output = beginOutput + i * widthStep;
906  for(int j=0 ; j < width ; j++)
907  {
908  *(output++) = *(input);
909  *(output++) = *(input);
910  *(output++) = *(input);
911 
912  input++;
913  }
914  }
915 }
916 
917 #endif
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
#define vpTRACE
Definition: vpDebug.h:401
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
bool saveFrame(vpImage< vpRGBa > &I)
Definition: vpFFMPEG.cpp:738
bool getFrame(vpImage< vpRGBa > &I, unsigned int frameNumber)
Definition: vpFFMPEG.cpp:285
void resize(const unsigned int height, const unsigned int width)
set the size of the image
Definition: vpImage.h:535
error that can be emited by ViSP classes.
Definition: vpException.h:75
vpFFMPEG()
Definition: vpFFMPEG.cpp:67
bool openStream(const char *filename, vpFFMPEGColorType color_type)
Definition: vpFFMPEG.cpp:107
~vpFFMPEG()
Definition: vpFFMPEG.cpp:90
vpFFMPEGColorType
Definition: vpFFMPEG.h:152
void closeStream()
Definition: vpFFMPEG.cpp:592
bool acquire(vpImage< vpRGBa > &I)
Definition: vpFFMPEG.cpp:339
bool initStream()
Definition: vpFFMPEG.cpp:226
bool endWrite()
Definition: vpFFMPEG.cpp:820
bool openEncoder(const char *filename, unsigned int width, unsigned int height, AVCodecID codec=AV_CODEC_ID_MPEG1VIDEO)
Definition: vpFFMPEG.cpp:661