25 #include "VideoSource_FFmpeg.hh"
73 errMsg_ =
"VideoSource_FFmpeg already initialized. Call CloseDevice() first.";
83 if (av_open_input_file(&ic, filename, NULL, 0, NULL) < 0) {
84 errMsg_ =
"Could not open video file";
89 if (av_find_stream_info(ic) < 0) {
90 errMsg_ =
"Could not find stream information";
95 dump_format(ic, 0, filename,
false);
101 if (ic->streams[
DeviceChannel_]->codec->codec_type == CODEC_TYPE_VIDEO)
104 cout <<
"Video stream not found. Falling back to first video stream" << endl;
108 for (
unsigned int i = 0; i < ic->nb_streams; i++) {
109 if (ic->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
116 errMsg_ =
"Could not find a video stream";
124 codec = avcodec_find_decoder(c->codec_id);
126 errMsg_ =
"Could not find decoder";
131 if (avcodec_open(c, codec) < 0) {
132 errMsg_ =
"Could not open decoder";
137 pFrame_ = avcodec_alloc_frame();
139 errMsg_ =
"Could not allocate video frame";
146 errMsg_ =
"Could not allocate output frame";
162 mtag = av_metadata_get(ic->metadata,
"date", NULL, 0);
165 mtag = av_metadata_get(st->metadata,
"date", NULL, 0);
174 errMsg_ =
"Could not calculate video frame size";
181 errMsg_ =
"Could not allocate video frame buffer";
187 errMsg_ =
"Could not fill video frame buffer";
201 AVCodecContext *c = NULL;
227 av_close_input_file(ic);
239 BEXCEPTION(
"VideoSource Object not active, use PreGrab()");
242 BEXCEPTION(
"VideoSource Object is already grabbing()");
248 AVCodecContext *c = st->codec;
257 ret = av_read_frame(ic, &pkt);
259 errMsg_ = ret == EOF ?
"End of video file reached" :
"Could not read video frame";
265 ret = avcodec_decode_video2(c,
pFrame_, &gotPicture, &pkt);
267 errMsg_ =
"Could not decode video frame";
274 pSwsCtx_ = sws_getCachedContext(
pSwsCtx_, c->width, c->height, c->pix_fmt, c->width, c->height,
outputPixFmt_, SWS_BICUBIC, NULL, NULL, NULL);
276 errMsg_ =
"Could not initialize a conversion context";
288 pts_ = pkt.pts < 0 ? pkt.dts : pkt.pts;
289 pts_ =
pts_ * 1000000 * st->time_base.num / st->time_base.den;
296 m->
Add(
"#[num]", ascii.str());
300 m->
Add(
"#[pts]", ascii.str());
318 AVCodecContext *c = st->codec;
326 int64_t timestamp = frame * st->time_base.den / st->time_base.num /
328 cout << timestamp << endl;
329 if (av_seek_frame(ic,
streamIndex_, timestamp, 0) < 0) {
330 errMsg_ =
"Could not seek frame";
333 avcodec_flush_buffers(c);
342 AVCodecContext *c = st->codec;
343 int64_t ts = ms * st->time_base.den / st->time_base.num / 1000;
350 errMsg_ =
"Could not seek frame";
353 avcodec_flush_buffers(c);
402 errMsg_ =
"Unsupported color model";
414 int size = str.size();
418 dateStr = (
char *) malloc(20);
421 while (!done && pos < size) {
422 const char c = str[pos++];
435 switch (dateStrSize) {
438 dateStr[dateStrSize] =
'-';
442 dateStr[dateStrSize] =
' ';
447 dateStr[dateStrSize] =
':';
451 dateStr[dateStrSize] = c;
453 if (dateStrSize >= 19)
459 if (dateStrSize == 10) {
460 dateStr[dateStrSize] =
' ';
476 dateStr[dateStrSize] =
'\0';
477 if (!done || parse_date(dateStr, 0) < 0)
int64_t duration_
Stream duration in milliseconds, 0 if unknown.
EColorModel
These are the most often used color models.
YUYV422, 2 channels, full luminance Y, subsampled half U,V.
int SeekMs(int ms)
Seek to time in milliseconds in video stream.
int64_t pts_
Presentation timestamp of last decoded frame in microseconds.
virtual int GrabSingle(Camera< unsigned char > &image)
Get the next frame from the video file.
Defines a common interface to different devices.
int streamIndex_
Index of the video stream.
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
std::string errMsg_
The last error message.
BIAS::ImageBase::EColorModel ColorMode_
Color mode used by camera.
int DeviceChannel_
Device channel.
AVFrame * pFrame_
Video stream frame.
float BytesPerPixel_
BytesPerPixel cannot be int (e.g. it is 1.5 for YUV420p)
int64_t numFrames_
Number of frames of the stream, 0 if unknown.
YUV420P, 2 channels, full luminance Y, 1 U, 1 V. Y, U and V are grouped together for better compressi...
bool CompleteInitialized_
Complete_initialized_ is set when OpenDevice(), UseChannel() etc. are done.
int timeBaseNum_
Stream timebase numerator.
color values, 3 channels, order: blue,green,red
AVFormatContext * pFormatCtx_
Format context for video decoder.
virtual int SetColorModel(ImageBase::EColorModel mode)
Set output color model.
SwsContext * pSwsCtx_
Color conversion context.
bool Grabbing_
Grabbing flag is set and unset in GrabSingle() methods.
virtual int OpenDevice()
selects the first available device to open (e.g.
enum PixelFormat outputPixFmt_
Output frame pixel format.
float FramesPerSecond_
Capturing framerate.
color values, 3 channels, order: red,green,blue
char * ExtractDateString_(std::string str)
Try to extract date string of format "YYYYMMDD_HHMMSS" from string.
UYVY422, 2 channels, full luminance Y, subsampled half U,V inverse order.
int64_t frameNumber_
Number of decoded frames.
int SeekFrame(int64_t frame)
Seek to frame in video stream.
bool Active_
Active flag is set in PreGrab() und unset in PostGrab()
void InvalidateUID()
sets the image's uid to invalid
int timeBaseDen_
Stream timebase denumerator.
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
void SetUID(const BIAS::UUID &id)
RGBA, 4 channels, order: red,green,blue,alpha.
virtual int PostGrab()
Stop anything started in PreGrab()
unsigned int ImageSize_
Image size, useful for allocating and copying memory.
virtual int CloseDevice()
Close video file.
char * dateStr_
String representation of timestamp_.
virtual ~VideoSource_FFmpeg()
Clean up.
int64_t timestamp_
Stream timestamp.
void Init_()
Called by constructor to init variables.
void SetMetaData(const MetaData &m)
uint8_t * pBuffer_
Ouput frame buffer.
static UUID GenerateUUID(const bool &consecutively=DEFAULT_UUID_CONSECUTIVELY)
static function which simply produces a uuid and returns
VideoSource_FFmpeg()
Standard constructor.
BGRA color values, 4 channels, order: blue,green,red,alpha.
AVFrame * pOutputFrame_
Output frame.