YARP
Yet Another Robot Platform
ffmpegPortmonitor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
18 // Local imports
19 #include "ffmpegPortmonitor.h"
20 #include "constants.h"
21 // YARP imports
22 #include <yarp/os/LogComponent.h>
23 #include <yarp/sig/all.h>
24 // Standard imports
25 #include <cstring>
26 #include <cmath>
27 #include <algorithm>
28 #include <iostream>
29 
30 // Ffmpeg imports
31 extern "C" {
32  #include <libavcodec/avcodec.h>
33  #include <libavutil/opt.h>
34  #include <libavutil/imgutils.h>
35  #include <libavformat/avformat.h>
36  #include <libswscale/swscale.h>
37 }
38 
39 using namespace yarp::os;
40 using namespace yarp::sig;
41 using namespace std;
42 
43 namespace {
44 
45 // YARP logging component
46 YARP_LOG_COMPONENT(FFMPEGMONITOR,
47  "yarp.carrier.portmonitor.ffmpeg",
51  nullptr)
52 }
53 
62 void split(const std::string &s, char delim, vector<string> &elements) {
63  std::istringstream iss(s);
64  std::string item;
65  while (std::getline(iss, item, delim)) {
66  elements.push_back(item);
67  }
68 }
69 
71 {
72  // Check if this is sender or not
73  senderSide = (options.find("sender_side").asBool());
74 
75  // Set default codec
76  AVCodecID codecId = AV_CODEC_ID_MPEG2VIDEO;
77  codecName = "mpeg2video";
78 
79  // Parse command line parameters and set them into global variable "paramsMap"
80  std::string str = options.find("carrier").asString();
81  if (getParamsFromCommandLine(str, codecId) == -1)
82  return false;
83 
84  // Find encoder/decoder
85  if (senderSide) {
86  codec = avcodec_find_encoder(codecId);
87  } else {
88  codec = avcodec_find_decoder(codecId);
89  }
90  if (!codec) {
91  yCError(FFMPEGMONITOR, "Can't find codec %s", codecName.c_str());
92  return false;
93  }
94 
95  // Prepare codec context
96  if (codecContext == NULL) {
97  codecContext = avcodec_alloc_context3(codec);
98  } else {
99  yCError(FFMPEGMONITOR, "Codec context is already allocated");
100  return false;
101  }
102  if (!codecContext) {
103  yCError(FFMPEGMONITOR, "Could not allocate video codec context");
104  return false;
105  }
106 
107  firstTime = true;
108 
109  // Set time base parameter
110  codecContext->time_base = (AVRational) { 1, 15 };
111  // Set command line params
112  if (setCommandLineParams() == -1)
113  return false;
114 
115  return true;
116 }
117 
119 {
120  paramsMap.clear();
121 
122  // Check if codec context is freeable, if yes free it.
123  if (codecContext != NULL) {
124  avcodec_close(codecContext);
125  avcodec_free_context(&codecContext);
126  codecContext = NULL;
127  }
128 }
129 
131 {
132  yCTrace(FFMPEGMONITOR, "setparam");
133  return false;
134 }
135 
137 {
138  yCTrace(FFMPEGMONITOR, "getparam");
139  return false;
140 }
141 
143 {
144  if (senderSide) {
145  // If sender side
146  yCTrace(FFMPEGMONITOR, "accept - sender");
147  // Try to cast the Thing into an Image
148  Image* img = thing.cast_as< Image >();
149  // If cast fails, return error
150  if(img == nullptr) {
151  yCError(FFMPEGMONITOR, "Expected type Image in sender side, but got wrong data type!");
152  return false;
153  }
154  }
155  else {
156  // If receiver side
157  yCTrace(FFMPEGMONITOR, "accept - receiver");
158  // Try to cast the Thing into a Bottle
159  Bottle* bt = thing.cast_as<Bottle>();
160  // If cast fails, return error
161  if(bt == nullptr){
162  yCError(FFMPEGMONITOR, "Expected type Bottle in receiver side, but got wrong data type!");
163  return false;
164  }
165  }
166  return true;
167 }
168 
170 {
171  if (senderSide) {
172  bool success = true;
173  yCTrace(FFMPEGMONITOR, "update - sender");
174  // Cast Thing into an Image
175  Image* img = thing.cast_as< Image >();
176  // Allocate memory for packet
177  AVPacket *packet = av_packet_alloc();
178  if (packet == NULL) {
179  yCError(FFMPEGMONITOR, "Error in packet allocation");
180  success = false;
181  }
182 
183  // Call compress function
184  if (success && compress(img, packet) != 0) {
185  yCError(FFMPEGMONITOR, "Error in compression");
186  success = false;
187  }
188 
189  // Insert compressed image into a Bottle to be sent
190  data.clear();
191 
192  int successCode = success ? 1 : 0;
193  data.addInt32(successCode);
194  data.addInt32(img->width());
195  data.addInt32(img->height());
196  data.addInt32(img->getPixelCode());
197  data.addInt32(img->getPixelSize());
198 
199  if (success) { // If compression was successful, insert also compressed data
200  // Packet
201  Value p(packet, sizeof(*packet));
202  data.add(p);
203  // Packet data
204  Value d(packet->data, packet->size);
205  data.add(d);
206  // Buffer size
207  data.addInt32(packet->buf->size);
208  // Buffer data
209  Value bd(packet->buf->data, packet->buf->size);
210  data.add(bd);
211 
212  // Side data elements
213  for (int i = 0; i < packet->side_data_elems; i++) {
214  data.addInt32(packet->side_data[i].size);
215  data.addInt32(packet->side_data[i].type);
216  Value sd(packet->side_data[i].data, packet->side_data[i].size);
217  data.add(sd);
218  }
219  }
220  th.setPortWriter(&data);
221  // Free the memory allocated for the packet
222  av_packet_unref(packet);
223  }
224  else {
225 
226  yCTrace(FFMPEGMONITOR, "update - receiver");
227  // Cast the Thin as a Bottle
228  Bottle* compressedBottle = thing.cast_as<Bottle>();
229  // Fill the final image with zeros
230  imageOut.zero();
231  // Extract decompression data from the Bottle
232  int width = compressedBottle->get(1).asInt32();
233  int height = compressedBottle->get(2).asInt32();
234  int pixelCode = compressedBottle->get(3).asInt32();
235  int pixelSize = compressedBottle->get(4).asInt32();
236  // Set information into final image
237  imageOut.setPixelCode(pixelCode);
238  imageOut.setPixelSize(pixelSize);
239  imageOut.resize(width, height);
240 
241  // Check if compression was successful
242  if (compressedBottle->get(0).asInt32() == 1) {
243  bool success = true;
244  // Get compressed image from Bottle
245  AVPacket* tmp = (AVPacket*) compressedBottle->get(5).asBlob();
246  // Allocate memory for packet
247  AVPacket* packet = av_packet_alloc();
248  // Set all packet parameters
249  packet->dts = tmp->dts;
250  packet->duration = tmp->duration;
251  packet->flags = tmp->flags;
252  packet->pos = tmp->pos;
253  packet->pts = tmp->pts;
254  packet->side_data_elems = 0;
255  packet->stream_index = tmp->stream_index;
256  packet->size = tmp->size;
257  // Image data
258  packet->data = (uint8_t *) compressedBottle->get(6).asBlob();
259  // Buffer data
260  packet->buf = av_buffer_create((uint8_t *) compressedBottle->get(8).asBlob(),
261  compressedBottle->get(7).asInt32(), av_buffer_default_free,
262  nullptr, AV_BUFFER_FLAG_READONLY);
263 
264  // Packet side data
265  for (int i = 0; i < tmp->side_data_elems; i++) {
266 
267  int ret = av_packet_add_side_data(packet,
268  (AVPacketSideDataType) compressedBottle->get(10).asInt32(), // Type
269  (uint8_t *) compressedBottle->get(11).asBlob(), // Data
270  compressedBottle->get(9).asInt32()); // Size
271  if (ret < 0) {
272  success = false;
273  break;
274  }
275  }
276 
277  // Call to decompress function
278  if (success && decompress(packet, width, height, pixelCode) != 0) {
279  yCError(FFMPEGMONITOR, "Error in decompression");
280  success = false;
281  }
282 
283  // Free memory allocated for side data and packet
284  av_freep(&packet->side_data);
285  av_freep(&packet);
286 
287  }
288  th.setPortWriter(&imageOut);
289 
290  }
291  return th;
292 }
293 
294 int FfmpegMonitorObject::compress(Image* img, AVPacket *pkt) {
295 
296  yCTrace(FFMPEGMONITOR, "compress");
297  AVFrame *startFrame;
298  AVFrame *endFrame;
299 
300  // Get width and height
301  int w = img->width();
302  int h = img->height();
303 
304  // Allocate video frame for original frames
305  startFrame = av_frame_alloc();
306  if (startFrame == NULL) {
307  yCError(FFMPEGMONITOR, "Cannot allocate starting frame!");
308  return -1;
309  }
310 
311  // Allocate a video frame for end frame
312  endFrame = av_frame_alloc();
313  if (endFrame == NULL) {
314  yCError(FFMPEGMONITOR, "Cannot allocate end frame!");
315  av_frame_free(&startFrame);
316  return -1;
317  }
318 
319  // Allocate space into start frame to contain data
320  int success = av_image_alloc(startFrame->data, startFrame->linesize,
321  w, h,
322  (AVPixelFormat) FFMPEGPORTMONITOR_PIXELMAP[img->getPixelCode()], 16);
323 
324  if (success < 0) {
325  yCError(FFMPEGMONITOR, "Cannot allocate starting frame buffer!");
326  av_frame_free(&startFrame);
327  av_frame_free(&endFrame);
328  return -1;
329  }
330 
331  // Set Image data into AVFrame
332  startFrame->linesize[0] = img->getRowSize();
333  // Free old pointer (because we will use the buffer contained into img)
334  av_freep(&startFrame->data[0]);
335  startFrame->data[0] = img->getRawImage();
336  startFrame->height = h;
337  startFrame->width = w;
338  startFrame->format = (AVPixelFormat) FFMPEGPORTMONITOR_PIXELMAP[img->getPixelCode()];
339 
340  // Allocate memory for end frame data
341  success = av_image_alloc(endFrame->data, endFrame->linesize,
342  w, h,
343  (AVPixelFormat) FFMPEGPORTMONITOR_CODECPIXELMAP[codecContext->codec_id], 16);
344 
345  if (success < 0) {
346  yCError(FFMPEGMONITOR, "Cannot allocate end frame buffer!");
347  av_frame_free(&startFrame);
348  av_frame_free(&endFrame);
349  return -1;
350  }
351 
352  // Set end frame parameters
353  endFrame->height = h;
354  endFrame->width = w;
355  endFrame->format = (AVPixelFormat) FFMPEGPORTMONITOR_CODECPIXELMAP[codecContext->codec_id];
356 
357  // Convert the image from start format into end format
358  static struct SwsContext *img_convert_ctx;
359 
360  // Allocate context for conversion
361  img_convert_ctx = sws_getContext(w, h,
362  (AVPixelFormat) FFMPEGPORTMONITOR_PIXELMAP[img->getPixelCode()],
363  w, h,
364  (AVPixelFormat) FFMPEGPORTMONITOR_CODECPIXELMAP[codecContext->codec_id],
365  SWS_BICUBIC,
366  NULL, NULL, NULL);
367  if (img_convert_ctx == NULL) {
368  yCError(FFMPEGMONITOR, "Cannot initialize pixel format conversion context!");
369  av_freep(&endFrame->data[0]);
370  av_frame_free(&startFrame);
371  av_frame_free(&endFrame);
372  return -1;
373  }
374 
375  // Perform conversion
376  int ret = sws_scale(img_convert_ctx, startFrame->data, startFrame->linesize, 0,
377  h, endFrame->data, endFrame->linesize);
378 
379  if (ret < 0) {
380  yCError(FFMPEGMONITOR, "Could not convert pixel format!");
381  sws_freeContext(img_convert_ctx);
382  av_freep(&endFrame->data[0]);
383  av_frame_free(&startFrame);
384  av_frame_free(&endFrame);
385  return -1;
386  }
387 
388  if (firstTime) {
389  // If this is the first compression
390 
391  // Set codec context parameters
392  codecContext->width = w;
393  codecContext->height = h;
394  codecContext->pix_fmt = (AVPixelFormat) FFMPEGPORTMONITOR_CODECPIXELMAP[codecContext->codec_id];
395 
396  // Open codec
397  ret = avcodec_open2(codecContext, codec, NULL);
398  if (ret < 0) {
399  yCError(FFMPEGMONITOR, "Could not open codec");
400  sws_freeContext(img_convert_ctx);
401  av_freep(&endFrame->data[0]);
402  av_frame_free(&startFrame);
403  av_frame_free(&endFrame);
404  return -1;
405  }
406  firstTime = false;
407  }
408 
409  // Set presentation timestamp
410  endFrame->pts = codecContext->frame_number;
411 
412  // Send image frame to codec
413  ret = avcodec_send_frame(codecContext, endFrame);
414  if (ret < 0) {
415  yCError(FFMPEGMONITOR, "Error sending a frame for encoding");
416  sws_freeContext(img_convert_ctx);
417  av_freep(&endFrame->data[0]);
418  av_frame_free(&startFrame);
419  av_frame_free(&endFrame);
420  return -1;
421  }
422 
423  // Receive compressed data into packet
424  ret = avcodec_receive_packet(codecContext, pkt);
425  sws_freeContext(img_convert_ctx);
426  av_freep(&endFrame->data[0]);
427  av_frame_free(&startFrame);
428  av_frame_free(&endFrame);
429 
430  if (ret == AVERROR(EAGAIN)) {
431  // Not enough data
432  yCError(FFMPEGMONITOR, "Error EAGAIN");
433  return -1;
434  } else if (ret == AVERROR_EOF) {
435  // End of file reached
436  yCError(FFMPEGMONITOR, "Error EOF");
437  return -1;
438  } else if (ret < 0) {
439  yCError(FFMPEGMONITOR, "Error during encoding");
440  return -1;
441  }
442 
443  return 0;
444 }
445 
446 int FfmpegMonitorObject::decompress(AVPacket* pkt, int w, int h, int pixelCode) {
447 
448  yCTrace(FFMPEGMONITOR, "decompress");
449  AVFrame *startFrame;
450  AVFrame *endFrame;
451 
452  if (firstTime) {
453  // If this is the first decompression
454 
455  // Set codec context parameters
456  codecContext->width = w;
457  codecContext->height = h;
458  codecContext->pix_fmt = (AVPixelFormat) FFMPEGPORTMONITOR_CODECPIXELMAP[codecContext->codec_id];
459 
460  // Open codec
461  int ret = avcodec_open2(codecContext, codec, NULL);
462  if (ret < 0) {
463  yCError(FFMPEGMONITOR, "Could not open codec");
464  return -1;
465  }
466  firstTime = false;
467  }
468 
469  // Allocate video frame
470  startFrame = av_frame_alloc();
471  if (startFrame == NULL) {
472  yCError(FFMPEGMONITOR, "Could not allocate start frame!");
473  return -1;
474  }
475 
476  // Send compressed packet to codec
477  int ret = avcodec_send_packet(codecContext, pkt);
478  if (ret < 0) {
479  yCError(FFMPEGMONITOR, "Error sending a frame for encoding");
480  av_frame_free(&startFrame);
481  return -1;
482  }
483 
484  // Receive decompressed image into an AVFrame
485  ret = avcodec_receive_frame(codecContext, startFrame);
486  if (ret == AVERROR(EAGAIN)) {
487  // No enough data
488  yCError(FFMPEGMONITOR, "Error EAGAIN");
489  av_frame_free(&startFrame);
490  return -1;
491  }
492  else if (ret == AVERROR_EOF) {
493  // End of file reached
494  yCError(FFMPEGMONITOR, "Error EOF");
495  av_frame_free(&startFrame);
496  return -1;
497  }
498  else if (ret < 0) {
499  yCError(FFMPEGMONITOR, "Error during encoding");
500  av_frame_free(&startFrame);
501  return -1;
502  }
503 
504  // Allocate a video frame for end frame
505  endFrame = av_frame_alloc();
506  if (endFrame == NULL) {
507  yCError(FFMPEGMONITOR, "Could not allocate start frame!");
508  av_frame_free(&startFrame);
509  return -1;
510  }
511 
512  // Allocate memory into end frame to contain data
513  int success = av_image_alloc(endFrame->data, endFrame->linesize,
514  w, h,
515  (AVPixelFormat) FFMPEGPORTMONITOR_PIXELMAP[pixelCode], 16);
516 
517  if (success < 0) {
518  yCError(FFMPEGMONITOR, "Error allocating end frame buffer!");
519  av_frame_free(&startFrame);
520  av_frame_free(&endFrame);
521  return -1;
522  }
523 
524  // Set end frame parameters
525  endFrame->height = h;
526  endFrame->width = w;
527  endFrame->format = (AVPixelFormat) FFMPEGPORTMONITOR_PIXELMAP[pixelCode];
528 
529  // Convert the image into RGB format
530  static struct SwsContext *img_convert_ctx;
531 
532  // Allocate conversion context
533  img_convert_ctx = sws_getContext(w, h,
534  (AVPixelFormat) FFMPEGPORTMONITOR_CODECPIXELMAP[codecContext->codec_id],
535  w, h,
536  (AVPixelFormat) FFMPEGPORTMONITOR_PIXELMAP[pixelCode],
537  SWS_BICUBIC,
538  NULL, NULL, NULL);
539  if (img_convert_ctx == NULL) {
540  yCError(FFMPEGMONITOR, "Cannot initialize the pixel format conversion context!");
541  av_freep(&endFrame->data[0]);
542  av_frame_free(&endFrame);
543  av_frame_free(&startFrame);
544  return -1;
545  }
546 
547  // Perform conversion
548  ret = sws_scale(img_convert_ctx, startFrame->data, startFrame->linesize, 0,
549  h, endFrame->data, endFrame->linesize);
550 
551  if (ret < 0) {
552  yCError(FFMPEGMONITOR, "Could not convert pixel format!");
553  av_freep(&endFrame->data[0]);
554  av_frame_free(&endFrame);
555  av_frame_free(&startFrame);
556  sws_freeContext(img_convert_ctx);
557  return -1;
558  }
559 
560  // Copy decompressed data from end frame to imageOut
561  memcpy(imageOut.getRawImage(), endFrame->data[0], success);
562 
563  // Free allocated memory
564  av_freep(&endFrame->data[0]);
565  av_frame_free(&endFrame);
566  av_frame_free(&startFrame);
567  sws_freeContext(img_convert_ctx);
568 
569  return 0;
570 
571 }
572 
573 int FfmpegMonitorObject::getParamsFromCommandLine(string carrierString, AVCodecID &codecId) {
574 
575  vector<string> parameters;
576  // Split command line string using '+' delimiter
577  split(carrierString, '+', parameters);
578 
579  // Iterate over result strings
580  for (string param: parameters) {
581 
582  // Skip YARP initial parameters
584  continue;
585  }
586 
587  // If there is no '.', the param is bad formatted, return error
588  auto pointPosition = param.find('.');
589  if (pointPosition == string::npos) {
590  yCError(FFMPEGMONITOR, "Error parsing parameters!");
591  return -1;
592  }
593 
594  // Otherwise, separate key and value
595  string paramKey = param.substr(0, pointPosition);
596  string paramValue = param.substr(pointPosition + 1, param.length());
597 
598  // Parsing codec
599  if (paramKey == FFMPEGPORTMONITOR_CL_CODEC_KEY) {
600  bool found = false;
601  // Iterate over codecs command line possibilities
602  for (size_t i = 0; i < FFMPEGPORTMONITOR_CL_CODECS.size(); i++) {
603  // If found
604  if (paramValue == FFMPEGPORTMONITOR_CL_CODECS[i]) {
605  // Set codec id basing on codec command line name
606  codecId = (AVCodecID) FFMPEGPORTMONITOR_CODE_CODECS[i];
607  codecName = paramValue;
608  found = true;
609  break;
610  }
611  }
612 
613  // If not found, unrecognized codec, return error
614  if (!found) {
615  yCError(FFMPEGMONITOR, "Unrecognized codec: %s", paramValue.c_str());
616  return -1;
617  } else {
618  continue;
619  }
620 
621  }
622 
623  // Save param into params map
624  paramsMap.insert( pair<string, string>(paramKey, paramValue) );
625  }
626  return 0;
627 
628 }
629 
631 
632  // Iterate over all saved parameters
633  for (auto const& x : paramsMap) {
634 
635  // Get key and value
636  string key = x.first;
637  string value = x.second;
638 
639  // Try to set this pair (key, value) into codec context (global parameters).
640  int globalError = av_opt_set(codecContext, key.c_str(), value.c_str(), 0);
641  // Try to set this pair (key, value) into codec context -> priv data (parameters that are specific for a codec).
642  int privError = av_opt_set(codecContext->priv_data, key.c_str(), value.c_str(), 0);
643 
644  // If the param exists, but the value is out of range
645  if (globalError == AVERROR(ERANGE) || privError == AVERROR(ERANGE)) {
646  yCError(FFMPEGMONITOR, "Parameter out of range: %s", key.c_str());
647  return -1;
648  }
649  // If the param exists, but the value is invalid
650  else if (globalError == AVERROR(EINVAL) || privError == AVERROR(EINVAL)) {
651  yCError(FFMPEGMONITOR, "Invalid value for parameter: %s", key.c_str());
652  return -1;
653  }
654  // If the param doesn't exists (we check only in sender side because some parameters doesn't exist in the decoders)
655  else if (senderSide && globalError == AVERROR_OPTION_NOT_FOUND && privError == AVERROR_OPTION_NOT_FOUND) {
656  yCError(FFMPEGMONITOR, "Parameter not found: %s", key.c_str());
657  return -1;
658  }
659 
660  }
661  return 0;
662 }
bool ret
int getParamsFromCommandLine(std::string carrierString, AVCodecID &codecId)
This function parses the command line parameters from a string containing the entire command used to ...
int compress(yarp::sig::Image *img, AVPacket *pkt)
This function performs all the compression actions on the incoming Image and saves the resulting comp...
bool accept(yarp::os::Things &thing) override
This function is used by the port monitor to decide if an incoming packet can be accepted (it tries t...
int setCommandLineParams()
This function iterates over the attribute paramsMap and sets all the specified parameters into the at...
yarp::os::Things & update(yarp::os::Things &thing) override
This function is the one that manipulates the incoming packet.
bool create(const yarp::os::Property &options) override
This function is called when the object is created and it is used to initialize all its attributes.
bool setparam(const yarp::os::Property &params) override
This will be called when the portmonitor carrier parameters are set via Yarp admin port.
bool getparam(yarp::os::Property &params) override
This will be called when the portmonitor carrier parameters are requested via Yarp admin port.
int decompress(AVPacket *pkt, int w, int h, int pixelCode)
This function decompresses the incoming AVPacket passed as parameter and saves decompressed data into...
void destroy(void) override
This function is called when the execution is terminated and the object is destroyed.
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:76
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
static LogCallback printCallback()
Get current print callback.
Definition: Log.cpp:852
static LogType minimumPrintLevel()
Get current minimum print level.
Definition: Log.cpp:805
@ LogTypeReserved
Definition: Log.h:83
A class for storing options and configuration information.
Definition: Property.h:37
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Property.cpp:1054
Base class for generic things.
Definition: Things.h:22
T * cast_as()
Definition: Things.h:57
A single value (typically within a Bottle).
Definition: Value.h:47
virtual bool asBool() const
Get boolean value.
Definition: Value.cpp:189
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
virtual const char * asBlob() const
Get binary data value.
Definition: Value.cpp:264
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
Base class for storing images.
Definition: Image.h:85
size_t width() const
Gets width of image in pixels.
Definition: Image.h:153
size_t getRowSize() const
Size of the underlying image buffer rows.
Definition: Image.h:179
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition: Image.cpp:534
virtual size_t getPixelSize() const
Gets pixel size in memory in bytes.
Definition: Image.cpp:449
size_t height() const
Gets height of image in pixels.
Definition: Image.h:159
virtual int getPixelCode() const
Gets pixel type identifier.
Definition: Image.cpp:454
File containing constans used in FfmpegPortmonitor.cpp.
static const std::vector< std::string > FFMPEGPORTMONITOR_IGNORE_PARAMS
This vector contains all parameters that have to be ignored while parsing command line string.
Definition: constants.h:37
static const std::string FFMPEGPORTMONITOR_CL_CODEC_KEY
This string is the "key" value for the codec parameter.
Definition: constants.h:51
static std::map< int, int > FFMPEGPORTMONITOR_CODECPIXELMAP
This structure maps Ffmpeg video codecs with their needed Ffmpeg pixel format code.
Definition: constants.h:89
static const std::vector< std::string > FFMPEGPORTMONITOR_CL_CODECS
This vector contains the only accepted values for the command line parameter "codec".
Definition: constants.h:57
static std::map< int, int > FFMPEGPORTMONITOR_PIXELMAP
This structure maps YARP pixel format codec into Ffmpeg pixel format codes.
Definition: constants.h:77
static const std::vector< int > FFMPEGPORTMONITOR_CODE_CODECS
This vector contains the codec ids corresponding to the codecs of the FFMPEGPORTMONITOR_CL_CODECS vec...
Definition: constants.h:67
void split(const std::string &s, char delim, vector< string > &elements)
This function simply splits a string into a vector of strings basing on a delimiter character.
Header file of FfmpegPortmonitor: a port monitor for video compression/decompression.
#define yCError(component,...)
Definition: LogComponent.h:157
#define yCTrace(component,...)
Definition: LogComponent.h:88
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
An interface to the operating system, including Port based communication.
Signal processing.
Definition: Image.h:25