diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 20:36:56 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 20:36:56 +0000 |
commit | 51de1d8436100f725f3576aefa24a2bd2057bc28 (patch) | |
tree | c6d1d5264b6d40a8d7ca34129f36b7d61e188af3 /video/out/vo_image.c | |
parent | Initial commit. (diff) | |
download | mpv-51de1d8436100f725f3576aefa24a2bd2057bc28.tar.xz mpv-51de1d8436100f725f3576aefa24a2bd2057bc28.zip |
Adding upstream version 0.37.0.upstream/0.37.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'video/out/vo_image.c')
-rw-r--r-- | video/out/vo_image.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/video/out/vo_image.c b/video/out/vo_image.c new file mode 100644 index 0000000..cc48ab3 --- /dev/null +++ b/video/out/vo_image.c @@ -0,0 +1,165 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <stdbool.h> +#include <sys/stat.h> + +#include <libswscale/swscale.h> + +#include "misc/bstr.h" +#include "osdep/io.h" +#include "options/m_config.h" +#include "options/path.h" +#include "mpv_talloc.h" +#include "common/common.h" +#include "common/msg.h" +#include "video/out/vo.h" +#include "video/csputils.h" +#include "video/mp_image.h" +#include "video/fmt-conversion.h" +#include "video/image_writer.h" +#include "video/sws_utils.h" +#include "sub/osd.h" +#include "options/m_option.h" + +static const struct m_sub_options image_writer_conf = { + .opts = image_writer_opts, + .size = sizeof(struct image_writer_opts), + .defaults = &image_writer_opts_defaults, +}; + +struct vo_image_opts { + struct image_writer_opts *opts; + char *outdir; +}; + +#define OPT_BASE_STRUCT struct vo_image_opts + +static const struct m_sub_options vo_image_conf = { + .opts = (const struct m_option[]) { + {"vo-image", OPT_SUBSTRUCT(opts, image_writer_conf)}, + {"vo-image-outdir", OPT_STRING(outdir), .flags = M_OPT_FILE}, + {0}, + }, + .size = sizeof(struct vo_image_opts), +}; + +struct priv { + struct vo_image_opts *opts; + + struct mp_image *current; + int frame; +}; + +static bool checked_mkdir(struct vo *vo, const char *buf) +{ + MP_INFO(vo, "Creating output directory '%s'...\n", buf); + if (mkdir(buf, 0755) < 0) { + char *errstr = mp_strerror(errno); + if (errno == EEXIST) { + struct stat stat_p; + if (stat(buf, &stat_p ) == 0 && S_ISDIR(stat_p.st_mode)) + return true; + } + MP_ERR(vo, "Error creating output directory: %s\n", errstr); + return false; + } + return true; +} + +static int reconfig(struct vo *vo, struct mp_image_params *params) +{ + return 0; +} + +static void draw_frame(struct vo *vo, struct vo_frame *frame) +{ + struct priv *p = vo->priv; + if (!frame->current) + return; + + p->current = frame->current; + + struct mp_osd_res dim = osd_res_from_image_params(vo->params); + osd_draw_on_image(vo->osd, dim, frame->current->pts, OSD_DRAW_SUB_ONLY, p->current); +} + +static void flip_page(struct vo *vo) +{ + struct priv *p = vo->priv; + if (!p->current) + return; + + (p->frame)++; + + void *t = talloc_new(NULL); + char *filename = talloc_asprintf(t, "%08d.%s", p->frame, + image_writer_file_ext(p->opts->opts)); + + if (p->opts->outdir && strlen(p->opts->outdir)) + filename = mp_path_join(t, p->opts->outdir, filename); + + MP_INFO(vo, "Saving %s\n", filename); + write_image(p->current, p->opts->opts, filename, vo->global, vo->log); + + talloc_free(t); +} + +static int query_format(struct vo *vo, int fmt) +{ + if (mp_sws_supported_format(fmt)) + return 1; + return 0; +} + +static void uninit(struct vo *vo) +{ +} + +static int preinit(struct vo *vo) +{ + struct priv *p = vo->priv; + p->opts = mp_get_config_group(vo, vo->global, &vo_image_conf); + if (p->opts->outdir && !checked_mkdir(vo, p->opts->outdir)) + return -1; + return 0; +} + +static int control(struct vo *vo, uint32_t request, void *data) +{ + return VO_NOTIMPL; +} + +const struct vo_driver video_out_image = +{ + .description = "Write video frames to image files", + .name = "image", + .untimed = true, + .priv_size = sizeof(struct priv), + .preinit = preinit, + .query_format = query_format, + .reconfig = reconfig, + .control = control, + .draw_frame = draw_frame, + .flip_page = flip_page, + .uninit = uninit, + .global_opts = &vo_image_conf, +}; |