UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
file.c
Go to the documentation of this file.
1
7/*
8 * Copyright (c) 2019-2023 CESNET, z. s. p. o.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, is permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * 3. Neither the name of CESNET nor the names of its contributors may be
23 * used to endorse or promote products derived from this software without
24 * specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
28 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
30 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
31 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
37 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
54#include <assert.h>
55#include <inttypes.h>
56#include <libavcodec/avcodec.h>
57#include <libavcodec/version.h>
58#include <libavformat/avformat.h>
59#include <libavformat/version.h>
60#include <libavutil/avutil.h>
61#include <libswscale/swscale.h>
62#include <limits.h>
63#include <stdbool.h>
64#include <stdint.h>
65#include <tv.h>
66
67#include "audio/types.h"
68#include "audio/utils.h"
69#include "debug.h"
70#include "lib_common.h"
73#include "messaging.h"
74#include "module.h"
75#include "pixfmt_conv.h"
76#include "playback.h"
77#include "types.h"
78#include "utils/color_out.h"
79#include "utils/fs.h"
80#include "utils/list.h"
81#include "utils/macros.h"
82#include "utils/math.h"
83#include "utils/ring_buffer.h"
84#include "utils/thread.h"
85#include "utils/time.h"
86#include "video.h"
87#include "video_capture.h"
88
89static const double AUDIO_RATIO = 1.05;
90enum {
93};
94#define MAGIC to_fourcc('u', 'g', 'l', 'f')
95#define MOD_NAME "[File cap.] "
96
98 struct module mod;
100 AVFormatContext *fmt_ctx;
101 AVCodecContext *aud_ctx, *vid_ctx;
104
105 struct SwsContext *sws_ctx;
107
108 bool failed;
109 bool loop;
113 bool paused;
114 bool ended;
116
118 int64_t last_vid_pts;
119
122
124 struct simple_linked_list *vid_frm_noaud; // auxilliary queue for worker
129 pthread_mutex_t audio_frame_lock;
130
131 pthread_t thread_id;
132 pthread_mutex_t lock;
133 pthread_cond_t new_frame_ready;
134 pthread_cond_t frame_consumed;
135 struct timeval last_frame;
136 struct timeval last_stream_stat;
137
139
140 long long audio_frames;
141 long long video_frames;
142};
143
145
146static void vidcap_file_show_help(bool full) {
147 color_printf("Usage:\n");
148 color_printf(TERM_BOLD TERM_FG_RED "\t-t file:<name>" TERM_FG_RESET "[:loop][:nodecode][:codec=<c>][:seek=<sec>]%s\n" TERM_RESET,
149 full ? "[:opportunistic_audio][:queue=<len>][:threads=<n>[FS]]" : "");
150 color_printf("where\n");
152 color_printf("\t\tloop the playback\n");
153 color_printf(TERM_BOLD "\tnodecode\n" TERM_RESET);
154 color_printf("\t\tdon't decompress the video (may not work because required data for correct decompess are in container or UG doesn't recognize the codec)\n");
155 color_printf(TERM_BOLD "\tcodec\n" TERM_RESET);
156 color_printf("\t\tcodec to decode to\n");
157 if (full) {
158 color_printf(TERM_BOLD "\topportunistic_audio\n" TERM_RESET);
159 color_printf("\t\tgrab audio if not present but do not fail if not\n");
160 color_printf(TERM_BOLD "\tqueue\n" TERM_RESET);
161 color_printf("\t\tmax queue len (default: %d), increasing may help if video stutters\n", FILE_DEFAULT_QUEUE_LEN);
162 color_printf(TERM_BOLD "\tthreads\n" TERM_RESET);
163 color_printf("\t\tnumber of threads (0 is default), 'S' and/or 'F' to use slice/frame threads, use at least one flag\n");
164 } else {
165 color_printf("\n(use \":fullhelp\" to see all available options)\n");
166 }
167}
168
170 struct video_frame *f = NULL;
171 while ((f = simple_linked_list_pop(s->video_frame_queue)) != NULL) {
173 }
174 while ((f = simple_linked_list_pop(s->vid_frm_noaud)) != NULL) {
176 }
177 if (s->audio_data) {
179 }
180 if (s->vid_ctx) {
181 avcodec_flush_buffers(s->vid_ctx);
182 }
183 if (s->aud_ctx) {
184 avcodec_flush_buffers(s->aud_ctx);
185 }
186 s->audio_end_ts = AV_NOPTS_VALUE;
187}
188
190 if (s->sws_ctx) {
191 sws_freeContext(s->sws_ctx);
192 }
193 if (s->vid_ctx) {
194 avcodec_free_context(&s->vid_ctx);
195 }
196 if (s->aud_ctx) {
197 avcodec_free_context(&s->aud_ctx);
198 }
199 if (s->fmt_ctx) {
200 avformat_close_input(&s->fmt_ctx);
201 }
202
204
207
208 pthread_mutex_destroy(&s->audio_frame_lock);
209 pthread_mutex_destroy(&s->lock);
210 pthread_cond_destroy(&s->frame_consumed);
211 pthread_cond_destroy(&s->new_frame_ready);
212 free(s->src_filename);
213 module_done(&s->mod);
216 free(s);
217}
218
219static void vidcap_file_write_audio(struct vidcap_state_lavf_decoder *s, AVFrame * frame) {
220 const int plane_count = av_sample_fmt_is_planar(s->aud_ctx->sample_fmt)
222 : 1;
223 // transform from floats
224 if (av_get_alt_sample_fmt(s->aud_ctx->sample_fmt, 0) == AV_SAMPLE_FMT_FLT) {
225 for (int i = 0; i < plane_count; ++i) {
226 float2int((char *) frame->data[i], (char *) frame->data[i], frame->nb_samples * 4);
227 }
228 } else if (av_get_alt_sample_fmt(s->aud_ctx->sample_fmt, 0) == AV_SAMPLE_FMT_DBL) {
229 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Doubles not supported!\n");
230 return;
231 }
232
233 pthread_mutex_lock(&s->audio_frame_lock);
234 if (ring_get_current_size(s->audio_data) == 0) {
235 s->audio_start_ts = frame->pts;
236 }
237 if (av_sample_fmt_is_planar(s->aud_ctx->sample_fmt)) {
238 int bps = av_get_bytes_per_sample(s->aud_ctx->sample_fmt);
239 char tmp[plane_count * bps * frame->nb_samples];
240 for (int i = 0; i < plane_count; ++i) {
241 mux_channel(tmp, (char *)frame->data[i], bps,
242 frame->nb_samples * bps, plane_count,
243 i, 1.0);
244 }
245 ring_buffer_write(s->audio_data, tmp, sizeof tmp);
246 } else {
247 if (plane_count == s->audio_desc.ch_count) {
248 int data_size = av_samples_get_buffer_size(NULL, s->audio_desc.ch_count,
249 frame->nb_samples,
250 s->aud_ctx->sample_fmt, 1);
251 if (data_size < 0) {
252 print_libav_error(LOG_LEVEL_WARNING, MOD_NAME " av_samples_get_buffer_size", data_size);
253 } else {
254 ring_buffer_write(s->audio_data, (char *)frame->data[0],
255 data_size);
256 }
257 } else {
258 int src_len = s->audio_desc.bps * plane_count;
259 int dst_len =
261 for (int i = 0; i < frame->nb_samples; ++i) {
263 (char *)frame->data[0] +
264 i * src_len,
265 dst_len);
266 }
267 }
268 }
269 pthread_mutex_unlock(&s->audio_frame_lock);
270}
271
272static bool have_audio_for_video(struct vidcap_state_lavf_decoder *s, int64_t vid_frm_ts, int64_t vid_frm_dur) {
274 log_msg(LOG_LEVEL_WARNING, "More than 300 video frames cached, "
275 "giving up!\n");
276 s->audio_end_ts = INT64_MAX / INT_MAX; // allow int mult
277 }
278 AVRational atb = s->fmt_ctx->streams[s->audio_stream_idx]->time_base;
279 AVRational vtb = s->fmt_ctx->streams[s->video_stream_idx]->time_base;
280 // Note the 3/4 of the frame was chosen because it is safely more
281 // than 1/2 without need to tackle with integer division and/or A/V
282 // frame alignment. The remainder (if there will be any) would be
283 // dropped with next frame if it was greater than 1/2 (@sa get_audio).
284 return s->audio_end_ts * atb.num / atb.den >=
285 vid_frm_ts * vtb.num / vtb.den + // at least 3/4 of audio
286 (vid_frm_dur * vtb.num * 3 / vtb.den / 4);
287}
288
290 AVPacket *pkt, AVFrame *frame) {
291 int ret = avcodec_send_packet(s->aud_ctx, pkt);
292 if (ret < 0) {
294 return;
295 }
296 while (ret >= 0) {
297 ret = avcodec_receive_frame(s->aud_ctx, frame);
298 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
299 break;
300 }
301 if (ret < 0) {
303 break;
304 }
305 /* if a frame has been decoded, output it */
306 s->audio_end_ts = pkt->pts + pkt->duration;
308 }
309 // try to process decoded video frames that didn't have corresponding
310 // audio when decompressed
312 while (vid_frm != NULL) {
313 if (!have_audio_for_video(s, vid_frm->seq, vid_frm->duration)) {
315 break;
316 }
317 pthread_mutex_lock(&s->lock);
319 pthread_mutex_unlock(&s->lock);
320 pthread_cond_signal(&s->new_frame_ready);
322 }
323}
324
326{
327 AVStream *st = s->fmt_ctx->streams[s->video_stream_idx];
328 AVRational tb = st->time_base;
329 static _Thread_local char position[12 * 2 + 3 + 1];
330 format_time_ms(s->last_vid_pts * tb.num * 1000 / tb.den, position);
331 strncat(position, " / ", sizeof position - strlen(position) - 1);
332 format_time_ms(st->duration * tb.num * 1000 / tb.den,
333 position + strlen(position));
334 return position;
335}
336
338 struct timeval t)
339{
340 if (tv_diff(t, s->last_stream_stat) < 30) {
341 return;
342 }
343 log_msg(LOG_LEVEL_INFO, MOD_NAME "Current position: %s\n",
345 s->last_stream_stat = t;
346}
347
348#define CHECK_FF(cmd, action_failed) do { int rc = cmd; if (rc < 0) { char buf[1024]; av_strerror(rc, buf, 1024); log_msg(LOG_LEVEL_ERROR, MOD_NAME #cmd ": %s\n", buf); action_failed} } while(0)
350 struct msg_universal *msg;
351 while ((msg = (struct msg_universal *) check_message(&s->mod)) != NULL) {
352 log_msg(LOG_LEVEL_VERBOSE, MOD_NAME "Message: \"%s\"\n", msg->text);
353 if (strstr(msg->text, "seek ") != NULL) {
354 const char *count_str = msg->text + strlen("seek ");
355 char *endptr = NULL;
356 double sec = strtol(count_str, &endptr, 0);
357 if (endptr[0] != 's') {
358 sec /= s->video_desc.fps;
359 }
360 AVStream *st = s->fmt_ctx->streams[s->video_stream_idx];
361 AVRational tb = st->time_base;
362 s->last_vid_pts =
363 MAX(s->last_vid_pts + (sec * tb.den) / tb.num,
364 st->start_time);
365 CHECK_FF(
366 avformat_seek_file(s->fmt_ctx, s->video_stream_idx,
367 INT64_MIN, s->last_vid_pts,
368 INT64_MAX, AVSEEK_FLAG_FRAME),
369 {});
370 log_msg(LOG_LEVEL_NOTICE, MOD_NAME "Seeking to %s\n",
373 s->ended = false;
374 } else if (strcmp(msg->text, "pause") == 0) {
375 s->paused = !s->paused;
376 pthread_cond_signal(&s->new_frame_ready);
377 log_msg(LOG_LEVEL_NOTICE, MOD_NAME "%s\n", s->paused ? "paused" : "unpaused");
378 } else if (strcmp(msg->text, "quit") == 0) {
379 exit_uv(0);
380 } else {
381 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unknown message: %s\n", msg->text);
382 free_message((struct message *) msg, new_response(RESPONSE_BAD_REQUEST, "unknown message"));
383 continue;
384 }
385
386 free_message((struct message *) msg, new_response(RESPONSE_OK, NULL));
387 }
388}
389
391 AVPacket *pkt, AVFrame *frame) {
392 s->last_vid_pts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;
393 if (s->no_decode) {
394 struct video_frame *out = vf_alloc_desc(s->video_desc);
397 out->tiles[0].data_len = pkt->size;
398 out->tiles[0].data = malloc(pkt->size);
399 memcpy(out->tiles[0].data, pkt->data, pkt->size);
400 return out;
401 }
403 int ret = avcodec_send_packet(s->vid_ctx, pkt);
404 if (ret != 0 && ret != AVERROR(EAGAIN)) {
405 print_decoder_error(MOD_NAME "send - ", ret);
406 return NULL;
407 }
408 ret = avcodec_receive_frame(s->vid_ctx, frame);
410 MOD_NAME "Video decompressing %c frame (pts %" PRId64 ") "
411 "duration: %f s\n",
412 av_get_picture_type_char(frame->pict_type), frame->pts,
413 (get_time_in_ns() - t0) / NS_IN_SEC_DBL);
414
415 if (ret < 0) {
416 print_decoder_error(MOD_NAME "recv - ", ret);
417 return NULL;
418 }
419 struct video_frame *out = vf_alloc_desc_data(s->video_desc);
420 out->flags |= TIMESTAMP_VALID;
421
422 /* copy decoded frame to destination buffer:
423 * this is required since rawvideo expects non aligned data */
424 int video_dst_linesize[4] = {
425 vc_get_linesize(out->tiles[0].width, out->color_spec)};
426 uint8_t *dst[4] = {(uint8_t *)out->tiles[0].data};
427 if (s->conv_uv) {
428 int rgb_shift[] = DEFAULT_RGB_SHIFT_INIT;
430 out->tiles[0].width, out->tiles[0].height,
431 video_dst_linesize[0], rgb_shift);
432 } else {
433 sws_scale(s->sws_ctx, (const uint8_t *const *)frame->data,
434 frame->linesize, 0, frame->height, dst,
435 video_dst_linesize);
436 }
437 out->seq = frame->pts < 0 ? UINT32_MAX : MIN(frame->pts, UINT32_MAX);
438#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 30, 100)
439 out->duration = frame->duration;
440#else
441 out->duration = frame->pkt_duration;
442#endif
444 return out;
445}
446
447static void print_packet_info(const AVPacket *pkt, const AVStream *st) {
448 AVRational tb = st->time_base;
449
450 char pts_val[128] = "NO VALUE";
451 if (pkt->pts != AV_NOPTS_VALUE) {
452 snprintf(pts_val, sizeof pts_val, "%" PRId64, pkt->pts);
453 }
454 char dts_val[128] = "NO VALUE";
455 if (pkt->dts != AV_NOPTS_VALUE) {
456 snprintf(dts_val, sizeof dts_val, "%" PRId64, pkt->dts);
457 }
459 MOD_NAME "rcv %s pkt, ID %d, pos %.2f s (pts %s, dts "
460 "%s, dur %" PRId64 ", tb %d/%d), sz %d B\n",
461 av_get_media_type_string(st->codecpar->codec_type),
462 pkt->stream_index,
463 (double)(pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts) *
464 tb.num / tb.den,
465 pts_val, dts_val, pkt->duration, tb.num, tb.den, pkt->size);
466}
467
468#define FAIL_WORKER { pthread_mutex_lock(&s->lock); s->failed = true; pthread_mutex_unlock(&s->lock); pthread_cond_signal(&s->new_frame_ready); return NULL; }
469static void *vidcap_file_worker(void *state) {
470 set_thread_name(__func__);
472 AVPacket *pkt = av_packet_alloc();
473 AVFrame *frame = av_frame_alloc();
474
475 pkt->size = 0;
476 pkt->data = 0;
477 while (true) {
478 pthread_mutex_lock(&s->lock);
479 while (!s->should_exit && !s->new_msg &&
481 s->max_queue_len || s->ended)) {
482 pthread_cond_wait(&s->frame_consumed, &s->lock);
483 }
484 if (s->should_exit) {
485 pthread_mutex_unlock(&s->lock);
486 break;
487 }
488 if (s->new_msg) {
490 s->new_msg = false;
491 pthread_mutex_unlock(&s->lock);
492 continue;
493 }
494 pthread_mutex_unlock(&s->lock);
495
496 av_packet_unref(pkt);
497 int ret = av_read_frame(s->fmt_ctx, pkt);
498 if (ret == AVERROR_EOF) {
499 if (s->loop) {
500 CHECK_FF(avio_seek(s->fmt_ctx->pb, s->video_stream_idx, SEEK_SET), {}); // handle single JPEG loop, inspired by libavformat's seek_frame_generic because img_read_seek (AVInputFormat::read_seek) doesn't do the job - seeking is inmplemeted just in img2dec if VideoDemuxData::loop == 1
501 CHECK_FF(avformat_seek_file(s->fmt_ctx, -1, INT64_MIN, s->fmt_ctx->start_time, INT64_MAX, 0), FAIL_WORKER);
503 log_msg(LOG_LEVEL_NOTICE, MOD_NAME "Rewinding the file.\n");
504 continue;
505 } else {
506 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Playback ended.\n");
507 s->ended = true;
508 continue;
509 }
510 }
511 CHECK_FF(ret, FAIL_WORKER); // check the retval of av_read_frame for error other than EOF
512
513 if (log_level >= LOG_LEVEL_DEBUG) {
515 pkt, s->fmt_ctx->streams[pkt->stream_index]);
516 }
517
518 if (pkt->stream_index == s->audio_stream_idx) {
520 } else if (pkt->stream_index == s->video_stream_idx) {
521 struct video_frame *out =
522 process_video_pkt(s, pkt, frame);
523 if (!out) {
524 continue;
525 }
526 if (s->audio_stream_idx != -1 && out->seq != UINT32_MAX) {
527 if (!have_audio_for_video(s, out->seq, out->duration)) {
529 out);
530 continue;
531 }
532 }
533 pthread_mutex_lock(&s->lock);
535 pthread_mutex_unlock(&s->lock);
536 pthread_cond_signal(&s->new_frame_ready);
537 }
538 }
539
540 av_packet_free(&pkt);
541 av_frame_free(&frame);
542
543 return NULL;
544}
545
546static bool vidcap_file_parse_fmt(struct vidcap_state_lavf_decoder *s, const char *fmt,
547 bool *opportunistic_audio) {
548 char fmt_cpy[MAX_PATH_SIZE] = "";
549 strncpy(fmt_cpy, fmt, sizeof fmt_cpy - 1);
550 char *tmp = fmt_cpy;
551 char *item = NULL;
552 char *saveptr = NULL;
553 while ((item = strtok_r(tmp, ":", &saveptr)) != NULL) {
554 if (tmp != NULL) { // first item
556 IS_KEY_PREFIX(item, "name") ? strchr(item, '=') + 1
557 : item);
558 tmp = NULL;
559 continue;
560 }
561 if (strcmp(item, "loop") == 0) {
562 s->loop = true;
563 } else if (strcmp(item, "nodecode") == 0) {
564 s->no_decode = true;
565 } else if (strcmp(item, "opportunistic_audio") == 0) {
566 *opportunistic_audio = true;
567 } else if (strncmp(item, "codec=", strlen("codec=")) == 0) {
568 char *codec_name = item + strlen("codec=");
569 if ((s->convert_to = get_codec_from_name(codec_name)) == VIDEO_CODEC_NONE) {
570 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unknown codec: %s\n", codec_name);
571 return false;
572 }
573 } else if (strncmp(item, "queue=", strlen("queue=")) == 0) {
574 s->max_queue_len = atoi(item + strlen("queue="));
575 } else if (strncmp(item, "threads=", strlen("threads=")) == 0) {
576 char *endptr = NULL;
577 long count = strtol(item + strlen("threads="), &endptr, 0);
578 s->thread_count = CLAMP(count, 0, INT_MAX);
579 s->thread_type = strchr(endptr, 'F') != NULL ? FF_THREAD_FRAME : 0;
580 s->thread_type |= strchr(endptr, 'S') != NULL ? FF_THREAD_SLICE : 0;
581 } else if (strstr(item, "seek=") == item) {
582 s->seek_sec = atoi(strchr(item, '=') + 1);
583 } else {
584 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unknown option: %s\n", item);
585 return false;
586 }
587 }
588 return true;
589}
590
591static AVCodecContext *vidcap_file_open_dec_ctx(const AVCodec *dec, AVStream *st, int thread_count, int thread_type) {
592 AVCodecContext *dec_ctx = avcodec_alloc_context3(dec);
593 if (!dec_ctx) {
594 return NULL;
595 }
596 dec_ctx->thread_count = thread_count;
597 dec_ctx->thread_type = thread_type;
598
599 /* Copy codec parameters from input stream to output codec context */
600 if (avcodec_parameters_to_context(dec_ctx, st->codecpar) < 0) {
601 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unable to copy parameters\n");
602 avcodec_free_context(&dec_ctx);
603 return NULL;
604 }
605 /* Init the decoders, with or without reference counting */
606 AVDictionary *opts = NULL;
607 av_dict_set(&opts, "refcounted_frames", "0", 0);
608 if (avcodec_open2(dec_ctx, dec, &opts) < 0) {
609 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Failed to open codec\n");
610 avcodec_free_context(&dec_ctx);
611 return NULL;
612 }
613 return dec_ctx;
614}
615
616static void vidcap_file_new_message(struct module *mod) {
618 pthread_mutex_lock(&s->lock);
619 s->new_msg = true;
620 pthread_mutex_unlock(&s->lock);
621 pthread_cond_signal(&s->frame_consumed);
622}
623
624static void vidcap_file_should_exit(void *state) {
626 pthread_mutex_lock(&s->lock);
627 s->should_exit = true;
628 pthread_mutex_unlock(&s->lock);
629 pthread_cond_signal(&s->new_frame_ready);
630 pthread_cond_signal(&s->frame_consumed);
631}
632
633static void seek_start(struct vidcap_state_lavf_decoder *s) {
634 if (s->seek_sec <= 0) {
635 return;
636 }
637 AVStream *st = s->fmt_ctx->streams[s->video_stream_idx];
638 AVRational tb = st->time_base;
639 int64_t ts = st->start_time + (int64_t) s->seek_sec * tb.den / tb.num;
640 CHECK_FF(avformat_seek_file(s->fmt_ctx, s->video_stream_idx, INT64_MIN,
641 ts, INT64_MAX, AVSEEK_FLAG_FRAME),
642 {});
643}
644
645static enum interlacing_t get_field_order(enum AVFieldOrder av_fo) {
646 switch (av_fo) {
647 case AV_FIELD_UNKNOWN:
649 MOD_NAME "Unknown field order, using progressive.\n");
650 return PROGRESSIVE;
651 case AV_FIELD_PROGRESSIVE:
652 return PROGRESSIVE;
653 case AV_FIELD_TT:
654 case AV_FIELD_BT:
655 return INTERLACED_MERGED;
656 default:
658 MOD_NAME "Potentially unsupported field order (lower-"
659 "field first): %d! Using progressive.\n",
660 (int)av_fo);
661 return PROGRESSIVE;
662 }
663}
664
666 AVStream *st = s->fmt_ctx->streams[s->video_stream_idx];
667 s->video_desc.width = st->codecpar->width;
668 s->video_desc.height = st->codecpar->height;
669 s->video_desc.fps = (double)st->r_frame_rate.num / st->r_frame_rate.den;
670 s->video_desc.tile_count = 1;
671 if (s->no_decode) {
673 get_av_to_ug_codec(st->codecpar->codec_id);
676 MOD_NAME "Unsupported codec %s.\n",
677 avcodec_get_name(st->codecpar->codec_id));
678 return false;
679 }
681 return true;
682 }
683 const AVCodec *dec = avcodec_find_decoder(st->codecpar->codec_id);
684 s->vid_ctx =
686 if (!s->vid_ctx) {
687 return false;
688 }
689 s->video_desc.interlacing = get_field_order(s->vid_ctx->field_order);
690
691 enum AVPixelFormat suggested[] = {s->vid_ctx->pix_fmt, AV_PIX_FMT_NONE};
693 s->convert_to, get_best_ug_codec_to_av(suggested, false));
696 UYVY; // fallback, swscale will perhaps be used
697 }
698 s->conv_uv = get_av_to_uv_conversion(s->vid_ctx->pix_fmt,
700 if (s->conv_uv) {
701 return true;
702 }
703 // else swscale needed
704 enum AVPixelFormat target_pixfmt =
706 if (target_pixfmt == AV_PIX_FMT_NONE) {
708 MOD_NAME "Cannot find suitable AVPixelFormat "
709 "for swscale conversion!\n");
710 return false;
711 }
712 s->sws_ctx = sws_getContext(s->video_desc.width, s->video_desc.height,
713 s->vid_ctx->pix_fmt, s->video_desc.width,
714 s->video_desc.height, target_pixfmt, 0,
715 NULL, NULL, NULL);
716 if (s->sws_ctx == NULL) {
718 MOD_NAME "Cannot find neither UltraGrid nor "
719 "swscale conversion!\n");
720 return false;
721 }
722 return true;
723}
724
725static int get_ach_count(int file_channels) {
726 if (audio_capture_channels == 0) {
727 return file_channels;
728 }
729 if ((int)audio_capture_channels > file_channels) {
731 MOD_NAME "Requested %d channels, file "
732 "contains only %d!\n",
733 audio_capture_channels, file_channels);
734 return file_channels;
735 }
737}
738
739#define CHECK(call) { int ret = call; if (ret != 0) abort(); }
740static int vidcap_file_init(struct vidcap_params *params, void **state) {
741 bool opportunistic_audio = false; // do not fail if audio requested but not found
742 int rc = 0;
743 char errbuf[1024] = "";
744 bool fullhelp = strcmp(vidcap_params_get_fmt(params), "fullhelp") == 0;
745 if (strlen(vidcap_params_get_fmt(params)) == 0 ||
746 strcmp(vidcap_params_get_fmt(params), "help") == 0 || fullhelp) {
747 vidcap_file_show_help(fullhelp);
749 }
750
751#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 12, 100)
752 av_register_all();
753#endif
754#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(58, 9, 100)
755 avcodec_register_all();
756#endif
757
758 struct vidcap_state_lavf_decoder *s = calloc(1, sizeof (struct vidcap_state_lavf_decoder));
761 s->audio_stream_idx = -1;
762 s->video_stream_idx = -1;
763 s->audio_end_ts = AV_NOPTS_VALUE;
765 s->thread_count = 0; // means auto for most codecs
766 s->thread_type = FF_THREAD_FRAME | FF_THREAD_SLICE;
767 CHECK(pthread_mutex_init(&s->audio_frame_lock, NULL));
768 CHECK(pthread_mutex_init(&s->lock, NULL));
769 CHECK(pthread_cond_init(&s->frame_consumed, NULL));
770 CHECK(pthread_cond_init(&s->new_frame_ready, NULL));
772 s->mod.priv_magic = MAGIC;
774 s->mod.priv_data = s;
777
778 if (!vidcap_file_parse_fmt(s, vidcap_params_get_fmt(params), &opportunistic_audio)) {
780 return VIDCAP_INIT_FAIL;
781 }
782
783 /* open input file, and allocate format context */
784 if ((rc = avformat_open_input(&s->fmt_ctx, s->src_filename, NULL, NULL)) < 0) {
785 snprintf(errbuf, sizeof errbuf, MOD_NAME "Could not open source file %s", s->src_filename);
786 }
787
788 /* retrieve stream information */
789 if (rc >= 0 && (rc = avformat_find_stream_info(s->fmt_ctx, NULL)) < 0) {
790 snprintf(errbuf, sizeof errbuf, MOD_NAME "Could not find stream information");
791 }
792
793 if (rc < 0) {
796 return VIDCAP_INIT_FAIL;
797 }
798
800 const AVCodec *dec = NULL;
801 s->audio_stream_idx = av_find_best_stream(
802 s->fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, (void *)&dec, 0);
803 if (s->audio_stream_idx < 0 && !opportunistic_audio) {
804 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Could not find audio stream!\n");
806 return VIDCAP_INIT_FAIL;
807 }
808 if (s->audio_stream_idx >= 0) {
810 s->fmt_ctx->streams[s->audio_stream_idx], s->thread_count, s->thread_type);
811
812 if (s->aud_ctx == NULL) {
814 return VIDCAP_INIT_FAIL;
815 }
816 log_msg(LOG_LEVEL_VERBOSE, MOD_NAME "Input audio sample bps: %s\n",
817 av_get_sample_fmt_name(s->aud_ctx->sample_fmt));
818 s->audio_desc.bps = av_get_bytes_per_sample(s->aud_ctx->sample_fmt);
819 s->audio_desc.sample_rate = s->aud_ctx->sample_rate;
825 }
826 }
827
828 s->video_stream_idx = av_find_best_stream(s->fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
829 if (s->video_stream_idx < 0) {
830 log_msg(LOG_LEVEL_WARNING, MOD_NAME "No video stream found!\n");
832 return VIDCAP_INIT_FAIL;
833 }
834 if (!setup_video(s)) {
836 return VIDCAP_INIT_FAIL;
837 }
838
840 av_dump_format(s->fmt_ctx, 0, s->src_filename, 0);
841 }
842 log_msg(LOG_LEVEL_INFO, MOD_NAME "Audio format: %s\n",
844 : "(no audio)");
845 log_msg(LOG_LEVEL_INFO, MOD_NAME "Video format: %s\n",
847 log_msg(LOG_LEVEL_VERBOSE, MOD_NAME "Capturing audio idx %d, video idx %d\n", s->audio_stream_idx, s->video_stream_idx);
848
849 s->last_vid_pts = s->fmt_ctx->streams[s->video_stream_idx]->start_time;
850 seek_start(s);
851
854
855 pthread_create(&s->thread_id, NULL, vidcap_file_worker, s);
856
857 *state = s;
858 return VIDCAP_INIT_OK;
859}
860
861static void vidcap_file_done(void *state) {
864 assert(s->mod.priv_magic == MAGIC);
865
867
868 pthread_join(s->thread_id, NULL);
869
871}
872
874 free(f->data);
875 free(f);
876}
877
879 const struct video_frame *vid_frm) {
880 if (vid_frm == NULL) {
881 return NULL;
882 }
883 pthread_mutex_lock(&s->audio_frame_lock);
884 if (ring_get_current_size(s->audio_data) == 0) {
885 pthread_mutex_unlock(&s->audio_frame_lock);
886 return NULL;
887 }
888
889 struct audio_frame *ret = calloc(1, sizeof *ret);
891 ret->flags |= TIMESTAMP_VALID;
892
893 AVRational atb = s->fmt_ctx->streams[s->audio_stream_idx]->time_base;
894 long drop_samples = 0;
895 if (vid_frm->seq == UINT32_MAX) {
897 MOD_NAME "Cannot get video PTS or too high!\n");
898 // capture more data to ensure the buffer won't grow - it is
899 // capped with actually read data, still. Moreover there
900 // number of audio samples per video frame period may not be
901 // integer. It shouldn't be much, however, not to confuse
902 // adaptible audio buffer.
903 ret->max_size = (int)(AUDIO_RATIO * s->audio_desc.sample_rate /
904 vid_frm->fps) *
906 } else {
907 AVRational vtb =
908 s->fmt_ctx->streams[s->video_stream_idx]->time_base;
909 int64_t apts_start = (int64_t)vid_frm->seq * vtb.num * atb.den /
910 ((int64_t)vtb.den * atb.num);
911 int64_t apts_end =
912 (((int64_t)vid_frm->seq + vid_frm->duration) *
913 (int64_t)vtb.num * atb.den +
914 ((int64_t)vtb.den * atb.num - 1)) /
915 ((int64_t)vtb.den * atb.num);
916 const int64_t l = lcm(s->audio_desc.sample_rate, atb.den);
917 const int64_t sample_alignment_tb = atb.num * (l / atb.den);
918 const int64_t samples_aligned_tb =
919 (apts_end - s->audio_start_ts + sample_alignment_tb + 1) /
920 sample_alignment_tb * sample_alignment_tb;
921 const int64_t samples =
922 samples_aligned_tb *
923 ((int64_t)s->audio_desc.sample_rate * atb.num) / atb.den;
924 drop_samples = (apts_start - s->audio_start_ts) *
925 ((int64_t)s->audio_desc.sample_rate * atb.num) /
926 atb.den;
927 // drop only if >.5 frm time, @sa have_audio_for_video:
928 drop_samples = drop_samples < samples / 2 ? 0 : drop_samples;
929 ret->max_size =
930 samples * s->audio_desc.bps * s->audio_desc.ch_count;
932 "audio samples: %" PRId64
933 ", drop: %ld, reqB:%d, ring:%d, ast_ts: %" PRIu64
934 ", apts_st: %" PRIu64 ", apts_end: %" PRIu64 "\n",
935 samples, drop_samples, ret->max_size,
937 s->audio_start_ts, apts_start, apts_end);
938 if (ret->max_size <= 0) { // seek - have new audio but old video
939 free(ret);
940 pthread_mutex_unlock(&s->audio_frame_lock);
941 return NULL;
942 }
943 }
944 ret->data = (char *)malloc(ret->max_size);
945 ret->data_len =
947 int64_t samples_written =
948 ret->data_len / (s->audio_desc.bps * s->audio_desc.ch_count);
949 s->audio_start_ts += samples_written * atb.den /
950 ((int64_t)s->audio_desc.sample_rate * atb.num);
951
952 long drop_bytes = drop_samples * ret->bps * ret->ch_count;
953 if (ret->data_len == 0 || drop_bytes >= ret->data_len) {
955 ret = NULL;
956 } else {
958 }
959 if (ret && drop_samples > 0) {
960 log_msg(LOG_LEVEL_INFO, MOD_NAME "Dropped %ld audio bytes.\n",
961 drop_bytes);
962 memmove(ret->data, ret->data + drop_bytes,
963 ret->data_len - drop_bytes);
964 ret->data_len -= drop_bytes;
965 }
966
967 pthread_mutex_unlock(&s->audio_frame_lock);
968 return ret;
969}
970
971static struct audio_frame *
973 const struct video_frame *vid_frm)
974{
975 if (s->audio_stream_idx == -1) {
976 return NULL;
977 }
978 struct audio_frame *aud_frm = get_audio(s, vid_frm);
979 if (aud_frm == NULL) {
980 s->audio_frames = -1; // invalide timestamp
981 return NULL;
982 }
983 if (s->audio_frames == -1) {
984 MSG(WARNING, "Resynchronizing audio timestamps.\n");
985 s->audio_frames = (long long) (((double) s->video_frames /
986 s->video_desc.fps) *
987 aud_frm->sample_rate);
988 }
989 aud_frm->timestamp =
990 ((int64_t) s->audio_frames * kHz90 + aud_frm->sample_rate) /
991 aud_frm->sample_rate;
992 s->audio_frames +=
993 aud_frm->data_len / (aud_frm->ch_count * aud_frm->bps);
994 return aud_frm;
995}
996
997static struct video_frame *
999{
1001 struct video_frame *out;
1002
1003 assert(s->mod.priv_magic == MAGIC);
1004 pthread_mutex_lock(&s->lock);
1005 while ((simple_linked_list_size(s->video_frame_queue) == 0 || s->paused) &&
1006 !s->failed && !s->should_exit) {
1007 pthread_cond_wait(&s->new_frame_ready, &s->lock);
1008 }
1009 if (s->failed || s->should_exit) {
1010 pthread_mutex_unlock(&s->lock);
1011 return NULL;
1012 }
1014 pthread_mutex_unlock(&s->lock);
1015 pthread_cond_signal(&s->frame_consumed);
1016
1017 out->timestamp =
1018 (uint32_t) ((double) s->video_frames * kHz90 / s->video_desc.fps);
1019
1020 *audio = get_timestamped_audio(s, out);
1021 s->video_frames += 1;
1022
1023 struct timeval t;
1024 do {
1025 gettimeofday(&t, NULL);
1026 } while (tv_diff(t, s->last_frame) < 1 / s->video_desc.fps);
1027 s->last_frame = t;
1028 print_current_pos(s, t);
1029
1030 return out;
1031}
1032
1033static void vidcap_file_probe(struct device_info **available_cards, int *count, void (**deleter)(void *)) {
1034 *deleter = free;
1035 *available_cards = NULL;
1036 *count = 0;
1037}
1038
1046
1048
void ** state
struct video_frame * frame
const char * fmt
struct audio_frame ** audio
int void(** deleter)(void *))
void vf_free(struct video_frame *buf)
Frees video_frame structure.
void vf_data_deleter(struct video_frame *buf)
int vc_get_linesize(unsigned int width, codec_t codec)
struct video_frame * vf_alloc_desc(struct video_desc desc)
Allocates video frame accordig given desc.
struct video_frame * vf_alloc_desc_data(struct video_desc desc)
codec_t get_codec_from_name(const char *name)
This file contains definition of some common audio types.
int color_printf(const char *format,...)
#define TERM_BOLD
Definition color_out.h:48
#define TERM_FG_RED
Definition color_out.h:50
#define TERM_RESET
Definition color_out.h:47
#define TERM_FG_RESET
Definition color_out.h:59
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
void log_msg_once(int level, uint32_t id, const char *msg,...)
Definition debug.cpp:137
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG_LEVEL_VERBOSE
Definition debug.h:63
#define MSG(l, fmt,...)
Definition debug.h:96
#define debug_msg(...)
#define debug_msg(...) log_msg(LOG_LEVEL_DEBUG, "[pid/%d +%d %s] ", getpid(), LINE,...
Definition debug.h:92
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
av_to_uv_convert_t * get_av_to_uv_conversion(int av_codec, codec_t uv_codec)
codec_t get_best_ug_codec_to_av(const enum AVPixelFormat *fmt, bool use_hwaccel)
void av_to_uv_conversion_destroy(av_to_uv_convert_t **s)
void av_to_uv_convert(const av_to_uv_convert_t *convert, char *dst, AVFrame *in, int width, int height, int pitch, const int rgb_shift[3])
char * strdup_path_with_expansion(const char *orig_path)
Definition fs.c:164
#define MAX_PATH_SIZE
Definition fs.h:48
void module_init_default(struct module *module_data)
Definition module.c:48
void module_register(struct module *module_data, struct module *parent)
Definition module.c:82
void module_done(struct module *module_data)
Definition module.c:93
@ MODULE_CLASS_DATA
Definition module.h:86
#define VIDCAP_INIT_NOERR
state not initialized, other action performed (typically help)
#define VIDCAP_INIT_OK
initialization successful
#define VIDEO_CAPTURE_ABI_VERSION
#define VIDCAP_INIT_FAIL
error ocured
int count
Definition hd-rum.c:44
void exit_uv(int status)
Definition host.cpp:625
void register_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
Definition host.cpp:1144
void unregister_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
Definition host.cpp:1158
unsigned int audio_capture_channels
Definition host.cpp:163
last_frame
Definition interlace.c:52
#define LOG_LEVEL_DEBUG
Definition kernels.cu:48
volatile int log_level
Definition debug.cpp:65
codec_t get_av_to_ug_codec(enum AVCodecID av_codec)
Definition lavc_common.c:79
void print_decoder_error(const char *mod_name, int rc)
void print_libav_error(int verbosity, const char *msg, int rc)
#define AVCODECCTX_CHANNELS(context)
Definition lavc_common.h:91
@ LIBRARY_CLASS_VIDEO_CAPTURE
Definition lib_common.h:78
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
Definition lib_common.h:144
void simple_linked_list_append(struct simple_linked_list *l, void *data)
Definition list.cpp:68
void simple_linked_list_prepend(struct simple_linked_list *l, void *data)
Definition list.cpp:63
int simple_linked_list_size(struct simple_linked_list *l)
Definition list.cpp:93
struct simple_linked_list * simple_linked_list_init(void)
Definition list.cpp:53
void simple_linked_list_destroy(struct simple_linked_list *l)
Definition list.cpp:58
void * simple_linked_list_pop(struct simple_linked_list *l)
Definition list.cpp:82
#define MIN(a, b)
Definition macros.h:63
#define CLAMP(x, low, high)
Definition macros.h:67
#define IS_KEY_PREFIX(tok, key)
expands to true value if <k> from tok in format <k>=<v> is prefix of key
Definition macros.h:138
#define IF_NOT_NULL_ELSE(val, default_val)
Definition macros.h:51
#define MAX(a, b)
Definition macros.h:65
long long lcm(long long a, long long b)
Definition math.c:64
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct message * check_message(struct module *mod)
#define RESPONSE_OK
Definition messaging.h:57
#define RESPONSE_BAD_REQUEST
Definition messaging.h:60
#define DEFAULT_RGB_SHIFT_INIT
Definition pixfmt_conv.h:73
void playback_register_keyboard_ctl(struct module *mod)
Definition playback.c:102
int ring_get_current_size(struct ring_buffer *ring)
void ring_buffer_destroy(struct ring_buffer *ring)
struct ring_buffer * ring_buffer_init(int size)
void ring_buffer_flush(struct ring_buffer *buf)
int ring_buffer_read(struct ring_buffer *ring, char *out, int max_len)
void ring_buffer_write(struct ring_buffer *ring, const char *in, int len)
struct msghdr msg
int sample_rate
Definition types.h:78
int ch_count
Definition types.h:79
int bps
Definition types.h:77
struct used to comunicate with audio capture/playback device
Definition types.h:99
int sample_rate
Definition types.h:101
int64_t timestamp
Definition types.h:109
char * data
Definition types.h:102
void(* dispose)(struct audio_frame *)
called by sender when frame was processed
Definition types.h:112
int ch_count
Definition types.h:104
int data_len
Definition types.h:103
int flags
Definition types.h:111
int bps
Definition types.h:100
int max_size
Definition types.h:105
Definition hd-rum.c:27
uint32_t priv_magic
optional magic number that can a module set
Definition module.h:113
enum module_class cls
Definition module.h:115
void * priv_data
Definition module.h:126
notify_t new_message
if set, notifies module that new message is in queue, receiver lock is hold during the call
Definition module.h:119
unsigned int width
Definition types.h:280
char * data
Raw tile data. Pointer must be at least 4B aligned.
Definition types.h:287
unsigned int data_len
length of the data
Definition types.h:288
unsigned int height
Definition types.h:281
struct timeval last_stream_stat
Definition file.c:136
pthread_mutex_t lock
Definition file.c:132
struct video_desc video_desc
Definition file.c:120
pthread_cond_t frame_consumed
Definition file.c:134
AVCodecContext * aud_ctx
Definition file.c:101
struct module mod
Definition file.c:98
struct timeval last_frame
Definition file.c:135
long long video_frames
Definition file.c:141
long long audio_frames
Definition file.c:140
pthread_cond_t new_frame_ready
Definition file.c:133
AVFormatContext * fmt_ctx
Definition file.c:100
struct ring_buffer * audio_data
Definition file.c:126
AVCodecContext * vid_ctx
Definition file.c:101
struct audio_desc audio_desc
Definition file.c:121
struct simple_linked_list * vid_frm_noaud
Definition file.c:124
struct simple_linked_list * video_frame_queue
Definition file.c:123
av_to_uv_convert_t * conv_uv
Definition file.c:106
pthread_mutex_t audio_frame_lock
Definition file.c:129
struct SwsContext * sws_ctx
Definition file.c:105
int64_t last_vid_pts
last played PTS, if PTS == PTS_NO_VALUE, DTS is stored instead
Definition file.c:118
unsigned int tile_count
Definition types.h:185
codec_t color_spec
Definition types.h:182
enum interlacing_t interlacing
Definition types.h:184
double fps
Definition types.h:183
unsigned int width
width of every tile (!)
Definition types.h:179
unsigned int height
height of every tile (!)
Definition types.h:180
void(* data_deleter)(struct video_frame *)
Definition types.h:256
void(* dispose)(struct video_frame *)
Definition types.h:245
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
Definition types.h:345
uint32_t seq
seq num, used internally by JPEG enc, file cap
Definition types.h:333
int64_t timestamp
Definition types.h:331
double fps
Definition types.h:308
uint32_t duration
used by file cap
Definition types.h:336
int flags
Definition types.h:329
struct video_frame_callbacks callbacks
Definition types.h:324
codec_t color_spec
Definition types.h:306
uint32_t ts
Definition tfrc.c:101
void set_thread_name(const char *name)
Definition thread.c:72
void format_time_ms(uint64_t ts, char buf[static FORMAT_TIME_MS_BUF_LEN])
Definition time.c:46
double tv_diff(struct timeval curr_time, struct timeval prev_time)
Definition tv.c:97
long long time_ns_t
Definition tv.h:81
#define NS_IN_SEC_DBL
Definition tv.h:93
static time_ns_t get_time_in_ns()
Definition tv.h:101
This file contains some common data types.
@ TIMESTAMP_VALID
timestamp set by source (in 90 kHz clock)
Definition types.h:223
@ kHz90
timestamp time base
Definition types.h:149
interlacing_t
Definition types.h:163
@ PROGRESSIVE
progressive frame
Definition types.h:164
@ INTERLACED_MERGED
Columngs of both fields are interlaced together.
Definition types.h:167
codec_t
Definition types.h:65
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
enum AVPixelFormat get_ug_to_av_pixfmt(codec_t ug_codec)
Definition utils.c:84
void float2int(char *out, const char *in, int len)
Definition utils.cpp:482
void audio_frame_write_desc(struct audio_frame *f, struct audio_desc desc)
Definition utils.cpp:220
void mux_channel(char *out, const char *in, int bps, int in_len, int out_stream_channels, int pos_in_stream, double scale)
Definition utils.cpp:371
const char * audio_desc_to_cstring(struct audio_desc desc)
Definition utils.cpp:644
const char * video_desc_to_string(struct video_desc d)
Definition video.cpp:241
This is an umbrella header for video functions.
static enum interlacing_t get_field_order(enum AVFieldOrder av_fo)
Definition file.c:645
static const struct video_capture_info vidcap_file_info
Definition file.c:1039
static bool setup_video(struct vidcap_state_lavf_decoder *s)
Definition file.c:665
static struct audio_frame * get_audio(struct vidcap_state_lavf_decoder *s, const struct video_frame *vid_frm)
Definition file.c:878
#define CHECK_FF(cmd, action_failed)
Definition file.c:348
static struct video_frame * vidcap_file_grab(void *state, struct audio_frame **audio)
Definition file.c:998
static void * vidcap_file_worker(void *state)
Definition file.c:469
static bool have_audio_for_video(struct vidcap_state_lavf_decoder *s, int64_t vid_frm_ts, int64_t vid_frm_dur)
Definition file.c:272
static void vidcap_file_show_help(bool full)
Definition file.c:146
static void vidcap_file_dispose_audio(struct audio_frame *f)
Definition file.c:873
static void print_current_pos(struct vidcap_state_lavf_decoder *s, struct timeval t)
Definition file.c:337
#define FAIL_WORKER
Definition file.c:468
static struct video_frame * process_video_pkt(struct vidcap_state_lavf_decoder *s, AVPacket *pkt, AVFrame *frame)
Definition file.c:390
static int vidcap_file_init(struct vidcap_params *params, void **state)
Definition file.c:740
static void flush_captured_data(struct vidcap_state_lavf_decoder *s)
Definition file.c:169
static void vidcap_file_common_cleanup(struct vidcap_state_lavf_decoder *s)
Definition file.c:189
@ AUD_BUF_LEN_SEC
Definition file.c:91
@ FILE_DEFAULT_QUEUE_LEN
Definition file.c:92
static void vidcap_file_done(void *state)
Definition file.c:861
static void vidcap_file_process_audio_pkt(struct vidcap_state_lavf_decoder *s, AVPacket *pkt, AVFrame *frame)
Definition file.c:289
static struct audio_frame * get_timestamped_audio(struct vidcap_state_lavf_decoder *s, const struct video_frame *vid_frm)
Definition file.c:972
static bool vidcap_file_parse_fmt(struct vidcap_state_lavf_decoder *s, const char *fmt, bool *opportunistic_audio)
Definition file.c:546
static void vidcap_file_write_audio(struct vidcap_state_lavf_decoder *s, AVFrame *frame)
Definition file.c:219
static int get_ach_count(int file_channels)
Definition file.c:725
static const double AUDIO_RATIO
at this ratio the audio frame can be longer than the video frame
Definition file.c:89
#define MAGIC
Definition file.c:94
static void print_packet_info(const AVPacket *pkt, const AVStream *st)
Definition file.c:447
#define CHECK(call)
Definition file.c:739
static void vidcap_file_probe(struct device_info **available_cards, int *count, void(**deleter)(void *))
Definition file.c:1033
#define MOD_NAME
Definition file.c:95
static void seek_start(struct vidcap_state_lavf_decoder *s)
Definition file.c:633
static void vidcap_file_process_messages(struct vidcap_state_lavf_decoder *s)
Definition file.c:349
static AVCodecContext * vidcap_file_open_dec_ctx(const AVCodec *dec, AVStream *st, int thread_count, int thread_type)
Definition file.c:591
static const char * get_current_position_str(struct vidcap_state_lavf_decoder *s)
Definition file.c:325
static void vidcap_file_should_exit(void *state)
Definition file.c:624
static void vidcap_file_new_message(struct module *mod)
Definition file.c:616
struct module * vidcap_params_get_parent(const struct vidcap_params *params)
const char * vidcap_params_get_fmt(const struct vidcap_params *params)
unsigned int vidcap_params_get_flags(const struct vidcap_params *params)
#define VIDCAP_FLAG_AUDIO_ANY
#define VIDEO_FRAME_DISPOSE(frame)
Definition video_frame.h:76