22 #define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
65 audioBufferAt(nullptr),
72 return frameFinished!=0;
82 if (pCodecCtx!=
nullptr) {
83 avcodec_close(pCodecCtx);
85 if (audioBuffer!=
nullptr) {
86 delete [] audioBuffer;
91 if (pFrameRGB!=
nullptr) {
94 if (pFrame!=
nullptr) {
97 if (pAudio!=
nullptr) {
102 int getStream(AVFormatContext *pFormatCtx, AVMediaType code,
const char *name)
106 for(
int i=0; i<(int)(pFormatCtx->nb_streams); i++) {
107 if(pFormatCtx->streams[i]->codecpar->codec_type==code) {
109 yCInfo(FFMPEGGRABBER,
"First %s stream is stream #%d", name, i);
113 if(videoStream==-1) {
114 yCError(FFMPEGGRABBER,
"Could not find %s stream", name);
124 pCodecCtx=pFormatCtx->streams[index]->codec;
127 pCodec = avcodec_find_decoder(pFormatCtx->streams[index]->codecpar->codec_id);
128 if(pCodec==
nullptr) {
129 yCError(FFMPEGGRABBER,
"Codec not found");
134 if (avcodec_open2(pCodecCtx, pCodec,
nullptr) < 0) {
135 yCError(FFMPEGGRABBER,
"Could not open codec");
146 pFrame=av_frame_alloc();
149 pFrameRGB=av_frame_alloc();
150 if(pFrameRGB==
nullptr) {
151 yCError(FFMPEGGRABBER,
"Could not allocate a frame");
156 int numBytes=avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width,
158 buffer=
new uint8_t[numBytes];
161 avpicture_fill((AVPicture *)pFrameRGB,
buffer, AV_PIX_FMT_RGB24,
162 pCodecCtx->width, pCodecCtx->height);
169 audioBuffer =
new int16_t[audioBufferLen];
170 audioBufferAt = audioBuffer;
172 "channels %d, sample_rate %d, frame_size %d",
174 pCodecCtx->sample_rate,
175 pCodecCtx->frame_size);
181 return pCodecCtx->width;
186 return pCodecCtx->height;
192 return pCodecCtx->sample_rate;
197 return pCodecCtx->channels;
204 int bytesWritten = 0;
206 while (bytesRead<packet.size) {
208 AVPacket tmp = packet;
209 tmp.data += bytesRead;
210 tmp.size -= bytesRead;
212 if (!(pAudio = av_frame_alloc())) {
213 yCFatal(FFMPEGGRABBER,
"out of memory");
216 av_frame_unref(pAudio);
218 int r = avcodec_decode_audio4(pCodecCtx, pAudio, &gotFrame, &packet);
221 ct = av_samples_get_buffer_size(
nullptr,
224 pCodecCtx->sample_fmt,
228 yCError(FFMPEGGRABBER,
"error decoding audio");
231 int num_channels = getChannels();
232 int num_rate = getRate();
237 if (bytesRead==packet.size) {
238 int num_samples = bytesWritten/(
sizeof(int16_t)*num_channels);
239 sound.
resize(num_samples,num_channels);
243 for (
int i=0; i<num_samples; i++) {
244 for (
int j=0; j<num_channels; j++) {
245 sound.
set(audioBuffer[idx],i,j);
257 avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
263 int w = pCodecCtx->width;
264 int h = pCodecCtx->height;
265 static struct SwsContext *img_convert_ctx =
nullptr;
266 if (img_convert_ctx==
nullptr) {
267 img_convert_ctx = sws_getContext(w,h,
269 w, h, AV_PIX_FMT_RGB24,
273 nullptr,
nullptr,
nullptr);
275 if (img_convert_ctx!=
nullptr) {
276 sws_scale(img_convert_ctx, ((AVPicture*)pFrame)->data,
277 ((AVPicture*)pFrame)->linesize, 0,
279 ((AVPicture*)pFrameRGB)->data,
280 ((AVPicture*)pFrameRGB)->linesize);
282 yCFatal(FFMPEGGRABBER,
"Software scaling not working");
285 return frameFinished;
301 return frameFinished;
306 return frameFinished;
318 #define HELPER(x) (*((FfmpegHelper*)x))
323 if (str[0]==
'-')
return nullptr;
328 AVFormatContext **ppFormatCtx,
329 AVFormatContext **ppFormatCtx2)
331 bool audio = (ppFormatCtx==
nullptr);
332 AVDictionary*& formatParams =
333 *(audio?(&formatParamsAudio):(&formatParamsVideo));
335 AVInputFormat *iformat;
340 v = config.
check(
"v4ldevice",
341 Value(
"/dev/video0"),
344 v = config.
check(
"audio",
346 "optional audio device name");
353 av_dict_set_int(&formatParams,
355 config.
check(
"audio_rate",
357 "audio sample rate").asInt32(),
359 av_dict_set_int(&formatParams,
361 config.
check(
"channels",
363 "number of channels").asInt32(),
366 if (config.
check(
"time_base_num") && config.
check(
"time_base_den")) {
368 sprintf(buf,
"%d/%d",
369 config.
check(
"time_base_num",
371 "numerator of basic time unit").asInt32(),
372 config.
check(
"time_base_den",
374 "denominator of basic time unit").asInt32());
375 av_dict_set(&formatParams,
"framerate", buf, 0);
378 if (config.
check(
"channel")) {
379 av_dict_set_int(&formatParams,
381 config.
check(
"channel",
383 "channel identifier").asInt32(),
386 if (config.
check(
"standard")) {
387 av_dict_set(&formatParams,
389 config.
check(
"standard",
391 "pal versus ntsc").asString().c_str(),
394 av_dict_set_int(&formatParams,
396 config.
check(
"width",
398 "width of image").asInt32(),
400 av_dict_set_int(&formatParams,
402 config.
check(
"height",
404 "height of image").asInt32(),
408 std::string videoDevice = (config.
check(
"v4l1") ?
"video4linux" :
"video4linux2");
409 iformat = av_find_input_format(audio ?
"audio_device" : videoDevice.c_str());
411 int result = avformat_open_input(audio ? ppFormatCtx2 : ppFormatCtx,
416 bool ok = (result==0);
418 yCError(FFMPEGGRABBER,
"%s: ffmpeg error %d", v.
asString().c_str(), result);
422 if (ppFormatCtx!=
nullptr) {
423 if (config.
check(
"audio",
424 "optional audio device")) {
425 ok = openV4L(config,
nullptr,ppFormatCtx2);
436 AVFormatContext **ppFormatCtx)
438 AVInputFormat *iformat;
439 std::string devname = config.
check(
"devname",
440 Value(
"/dev/dv1394"),
441 "firewire device name").asString();
442 iformat = av_find_input_format(
"dv1394");
443 yCInfo(FFMPEGGRABBER,
"Checking for digital video in %s", devname.c_str());
447 return avformat_open_input(ppFormatCtx, strdup(devname.c_str()), iformat,
nullptr) == 0;
455 return avformat_open_input(ppFormatCtx, fname,
nullptr,
nullptr) == 0;
462 config.
check(
"source",
463 Value(
"default.avi"),
464 "media file to read from").asString();
466 if (config.
check(
"loop",
"media should loop (default)")) {
470 if (config.
check(
"noloop",
"media should not loop")) {
478 "sync on image or audio (if have to choose)?").asString();
479 imageSync = (sync==
"image");
481 needRateControl =
true;
483 if (config.
check(
"nodelay",
"media will play in simulated realtime unless this is present")) {
484 needRateControl =
false;
488 "simulated realtime multiplier factor (must be <1 right now)").asFloat64();
492 avdevice_register_all();
495 if (config.
check(
"v4l",
"if present, read from video4linux") || config.
check(
"v4l1",
"if present, read from video4linux") || config.
check(
"v4l2",
"if present, read from video4linux2")) {
496 needRateControl =
false;
497 if (!openV4L(config,&pFormatCtx,&pFormatCtx2)) {
498 yCError(FFMPEGGRABBER,
"Could not open Video4Linux input");
501 }
else if (config.
check(
"ieee1394",
"if present, read from firewire")) {
502 needRateControl =
false;
503 if (!openFirewire(config,&pFormatCtx)) {
504 yCError(FFMPEGGRABBER,
"Could not open ieee1394 input");
508 if (!openFile(&pFormatCtx,fname.c_str())) {
509 yCError(FFMPEGGRABBER,
"Could not open media file %s", fname.c_str());
516 if(avformat_find_stream_info(pFormatCtx,
nullptr)<0) {
517 yCError(FFMPEGGRABBER,
"Could not find stream information in %s", m_uri.c_str());
522 av_dump_format(pFormatCtx, 0, m_uri.c_str(),
false);
524 if (pFormatCtx2!=
nullptr) {
526 if(avformat_find_stream_info(pFormatCtx2,
nullptr)<0) {
527 yCError(FFMPEGGRABBER,
"Could not find stream information in %s", m_uri.c_str());
532 av_dump_format(pFormatCtx2, 0, m_uri.c_str(),
false);
536 if (pFormatCtx2!=
nullptr) {
537 pAudioFormatCtx = pFormatCtx2;
539 pAudioFormatCtx = pFormatCtx;
542 yCAssert(FFMPEGGRABBER, system_resource ==
nullptr);
544 yCAssert(FFMPEGGRABBER, system_resource !=
nullptr);
552 int videoStream = videoDecoder.
getStream(pFormatCtx,
556 int audioStream = audioDecoder.
getStream(pAudioFormatCtx,
560 if (videoStream==-1&&audioStream==-1) {
564 _hasVideo = (videoStream!=-1);
565 _hasAudio = (audioStream!=-1);
569 ok = ok && videoDecoder.
getCodec(pFormatCtx);
572 ok = ok && audioDecoder.
getCodec(pAudioFormatCtx);
574 if (!ok)
return false;
582 if (!ok)
return false;
590 m_rate = audioDecoder.
getRate();
593 " video size %dx%d, audio %dHz with %d channels, %s sync",
598 imageSync ?
"image" :
"audio");
600 if (!(_hasVideo||_hasAudio)) {
609 if (formatParamsVideo) {
610 av_dict_free(&formatParamsVideo);
611 formatParamsVideo =
nullptr;
613 if (formatParamsAudio) {
614 av_dict_free(&formatParamsAudio);
615 formatParamsAudio =
nullptr;
623 if (pFormatCtx!=
nullptr) {
624 avformat_close_input(&pFormatCtx);
626 if (pFormatCtx2!=
nullptr) {
627 avformat_close_input(&pFormatCtx2);
629 if (system_resource!=
nullptr) {
630 delete &
HELPER(system_resource);
631 system_resource =
nullptr;
644 return getAudioVisual(image,sound);
653 return getAudioVisual(image, sound);
665 bool tryAgain =
false;
666 bool triedAgain =
false;
670 bool gotAudio =
false;
671 bool gotVideo =
false;
675 double time_target = 0;
676 while(av_read_frame(pFormatCtx, &packet)>=0) {
679 if (packet.stream_index==videoDecoder.
getIndex()) {
680 done = videoDecoder.
getVideo(packet);
683 yCTrace(FFMPEGGRABBER,
"got a video frame");
686 }
if (packet.stream_index==audioDecoder.
getIndex()) {
687 done = audioDecoder.
getAudio(packet,sound);
689 yCTrace(FFMPEGGRABBER,
"got an audio frame");
693 AVRational& time_base = pFormatCtx->streams[packet.stream_index]->time_base;
694 double rbase = av_q2d(time_base);
696 time_target = packet.pts*rbase;
698 av_free_packet(&packet);
699 if (((imageSync?gotVideo:videoDecoder.
haveFrame())||!_hasVideo)&&
700 ((imageSync?1:gotAudio)||!_hasAudio)) {
706 if (needRateControl) {
721 tryAgain = !triedAgain;
727 av_seek_frame(pFormatCtx,-1,0,AVSEEK_FLAG_BACKWARD);