25 #include "VideoSource_FFMPEGVideo.hh"
41 static bool firstCall =
true;
55 if (av_open_input_file(&_fmtCtx, file, NULL, 0, NULL) != 0)
57 _errMsg = string(
"Could not open file ") + file;
60 if (av_find_stream_info(_fmtCtx) < 0)
62 _errMsg =
"Could not find stream info";
67 for (
unsigned int i = 0; i < _fmtCtx->nb_streams; i++)
69 if (_fmtCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
71 _vidStreams.push_back(i);
74 if (CountVideoStreams() == 0)
76 _errMsg =
"No video streams found";
84 unsigned int streamIndex)
87 _streamIndex = streamIndex;
88 if (_streamIndex >= CountVideoStreams())
91 _codecCtx = _fmtCtx->streams[_streamIndex]->codec;
92 _codec = avcodec_find_decoder(_codecCtx->codec_id);
95 _errMsg =
"Codec not found";
98 if (avcodec_open(_codecCtx, _codec) < 0)
100 _errMsg =
"Could not open codec";
105 int w = _codecCtx->width;
106 int h = _codecCtx->height;
108 if (width == 0 && height == 0)
114 else if (width != 0 && height == 0)
116 height = (float)width / w * h;
118 else if (width == 0 && height != 0)
120 width = (float)height / h * w;
123 _swsCtx = sws_getContext(w, h, _codecCtx->pix_fmt,
124 width, height, pixFmt,
125 SWS_BICUBIC, NULL, NULL, NULL);
128 _errMsg =
"Cannot initialize the conversion context!";
132 _frame = avcodec_alloc_frame();
133 _frameRGB = avcodec_alloc_frame();
134 int nBytes = avpicture_get_size(pixFmt, _codecCtx->width,
136 _buffer = (uint8_t*)av_malloc((nBytes + 8) *
sizeof(uint8_t));
137 avpicture_fill((AVPicture*)_frameRGB, _buffer, pixFmt, w, h);
145 av_close_input_file(_fmtCtx);
146 if (_codecCtx != NULL)
147 avcodec_close(_codecCtx);
150 if (_frameRGB != NULL)
165 return _vidStreams.size();
171 if (_codecCtx != NULL)
172 return _codecCtx->width;
174 return _fmtCtx->streams[_streamIndex]->codec->width;
179 if (_codecCtx != NULL)
180 return _codecCtx->height;
182 return _fmtCtx->streams[_streamIndex]->codec->height;
192 while (av_read_frame(_fmtCtx, &packet) >= 0 && !ret)
194 if (packet.stream_index == _vidStreams[_streamIndex])
196 avcodec_decode_video2(_codecCtx, _frame, &frameFinished,&packet);
200 sws_scale(_swsCtx, _frame->data, _frame->linesize, 0, _codecCtx->height,
201 (uint8_t**)&data, _frameRGB->linesize);
207 av_free_packet(&packet);
213 av_seek_frame(_fmtCtx, _vidStreams[_streamIndex], time, 0);
218 return _codecCtx->time_base;
223 return _fmtCtx->streams[_vidStreams[_streamIndex]]->cur_dts;
228 AVStream *s = _fmtCtx->streams[_vidStreams[_streamIndex]];
244 return PIX_FMT_RGB24;
246 return PIX_FMT_BGR24;
248 return PIX_FMT_GRAY8;
EColorModel
These are the most often used color models.
bool Open(const char *file)
Open file and retreive info.
AVRational TimeBase()
Returns the TimeBase of the video stream.
unsigned int GetCurrentDTS() const
Returns the current decoding timestamp.
bool Init(int width=0, int height=0, PixelFormat pixFmt=PIX_FMT_RGB24, unsigned int streamIndex=0)
Select video stream, initialize stuff and set destination size and pixel format.
color values, 3 channels, order: blue,green,red
const void * GetImageData() const
void Close()
Close file and free buffers.
color values, 3 channels, order: red,green,blue
void Seek(int64_t time)
Seeks to time which is given in TimeBase units.
unsigned int CountVideoStreams()
Return number of video streams.
~VideoSource_FFMPEGVideo()
int Width()
Return width of selected video stream.
static PixelFormat Colormodel2PixFmt(ImageBase::EColorModel cm)
Maps BIAS colormodels to ffmpeg pixelformats.
std::string ErrMsg()
Returns last error message.
VideoSource_FFMPEGVideo()
unsigned int GetLength() const
Returns the length of the video in TimeBase units.
int Height()
Return height of selected video stream.
This is the base class for images in BIAS.
bool GetFrame(BIAS::ImageBase &img)
Retreive the next frame from the video.