summaryrefslogtreecommitdiffstats
path: root/screenshot.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-08-06 17:46:42 +0200
committerwm4 <wm4@nowhere>2012-08-06 17:46:42 +0200
commit39593c138d505c0f99a5534d972a9c81fd676c4d (patch)
tree2f1db132336537be1919f133a57a0b3e941866af /screenshot.c
parent7aae399239d02e48de9060dded1d0232310d2141 (diff)
downloadmpv-39593c138d505c0f99a5534d972a9c81fd676c4d.tar.bz2
mpv-39593c138d505c0f99a5534d972a9c81fd676c4d.tar.xz
screenshot: move image writer code into new file image_writer.c
Diffstat (limited to 'screenshot.c')
-rw-r--r--screenshot.c220
1 files changed, 16 insertions, 204 deletions
diff --git a/screenshot.c b/screenshot.c
index 2ed2734155..6c734f57b5 100644
--- a/screenshot.c
+++ b/screenshot.c
@@ -16,22 +16,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <inttypes.h>
-#include <setjmp.h>
#include <time.h>
-#include <libswscale/swscale.h>
-#include <libavcodec/avcodec.h>
-
#include "config.h"
-#ifdef CONFIG_JPEG
-#include <jpeglib.h>
-#endif
-
#include "osdep/io.h"
#include "talloc.h"
@@ -42,16 +32,12 @@
#include "mp_msg.h"
#include "metadata.h"
#include "path.h"
-#include "libmpcodecs/img_format.h"
#include "libmpcodecs/mp_image.h"
#include "libmpcodecs/dec_video.h"
#include "libmpcodecs/vf.h"
#include "libvo/video_out.h"
+#include "image_writer.h"
-#include "fmt-conversion.h"
-
-//for sws_getContextFromCmdLine_hq and mp_sws_set_colorspace
-#include "libmpcodecs/vf_scale.h"
#include "libvo/csputils.h"
typedef struct screenshot_ctx {
@@ -64,11 +50,6 @@ typedef struct screenshot_ctx {
int frameno;
} screenshot_ctx;
-struct img_writer {
- const char *file_ext;
- int (*write)(screenshot_ctx *ctx, mp_image_t *image, FILE *fp);
-};
-
void screenshot_init(struct MPContext *mpctx)
{
mpctx->screenshot_ctx = talloc(mpctx, screenshot_ctx);
@@ -78,143 +59,6 @@ void screenshot_init(struct MPContext *mpctx)
};
}
-static int write_png(screenshot_ctx *ctx, struct mp_image *image, FILE *fp)
-{
- void *outbuffer = NULL;
- int success = 0;
- AVFrame *pic = NULL;
-
- struct AVCodec *png_codec = avcodec_find_encoder(CODEC_ID_PNG);
- AVCodecContext *avctx = NULL;
- if (!png_codec)
- goto print_open_fail;
- avctx = avcodec_alloc_context3(png_codec);
- if (!avctx)
- goto print_open_fail;
-
- avctx->time_base = AV_TIME_BASE_Q;
- avctx->width = image->width;
- avctx->height = image->height;
- avctx->pix_fmt = PIX_FMT_RGB24;
- avctx->compression_level = ctx->mpctx->opts.screenshot_png_compression;
-
- if (avcodec_open2(avctx, png_codec, NULL) < 0) {
- print_open_fail:
- mp_msg(MSGT_CPLAYER, MSGL_INFO, "Could not open libavcodec PNG encoder"
- " for saving screenshot\n");
- goto error_exit;
- }
-
- size_t outbuffer_size = image->width * image->height * 3 * 2;
- outbuffer = malloc(outbuffer_size);
- if (!outbuffer)
- goto error_exit;
-
- pic = avcodec_alloc_frame();
- if (!pic)
- goto error_exit;
- avcodec_get_frame_defaults(pic);
- for (int n = 0; n < 4; n++) {
- pic->data[n] = image->planes[n];
- pic->linesize[n] = image->stride[n];
- }
- int size = avcodec_encode_video(avctx, outbuffer, outbuffer_size, pic);
- if (size < 1)
- goto error_exit;
-
- fwrite(outbuffer, size, 1, fp);
-
- success = 1;
-error_exit:
- if (avctx)
- avcodec_close(avctx);
- av_free(avctx);
- av_free(pic);
- free(outbuffer);
- return success;
-}
-
-#ifdef CONFIG_JPEG
-
-static void write_jpeg_error_exit(j_common_ptr cinfo)
-{
- // NOTE: do not write error message, too much effort to connect the libjpeg
- // log callbacks with mplayer's log function mp_msp()
-
- // Return control to the setjmp point
- longjmp(*(jmp_buf*)cinfo->client_data, 1);
-}
-
-static int write_jpeg(screenshot_ctx *ctx, mp_image_t *image, FILE *fp)
-{
- struct jpeg_compress_struct cinfo;
- struct jpeg_error_mgr jerr;
-
- cinfo.err = jpeg_std_error(&jerr);
- jerr.error_exit = write_jpeg_error_exit;
-
- jmp_buf error_return_jmpbuf;
- cinfo.client_data = &error_return_jmpbuf;
- if (setjmp(cinfo.client_data)) {
- jpeg_destroy_compress(&cinfo);
- return 0;
- }
-
- jpeg_create_compress(&cinfo);
- jpeg_stdio_dest(&cinfo, fp);
-
- cinfo.image_width = image->width;
- cinfo.image_height = image->height;
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
-
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, ctx->mpctx->opts.screenshot_jpeg_quality, 1);
-
- jpeg_start_compress(&cinfo, TRUE);
-
- while (cinfo.next_scanline < cinfo.image_height) {
- JSAMPROW row_pointer[1];
- row_pointer[0] = image->planes[0] +
- cinfo.next_scanline * image->stride[0];
- jpeg_write_scanlines(&cinfo, row_pointer,1);
- }
-
- jpeg_finish_compress(&cinfo);
-
- jpeg_destroy_compress(&cinfo);
-
- return 1;
-}
-
-#endif
-
-static const struct img_writer img_writers[] = {
- { "png", write_png },
-#ifdef CONFIG_JPEG
- { "jpg", write_jpeg },
- { "jpeg", write_jpeg },
-#endif
-};
-
-static const struct img_writer *get_writer(screenshot_ctx *ctx)
-{
- const char *type = ctx->mpctx->opts.screenshot_filetype;
-
- for (size_t n = 0; n < sizeof(img_writers) / sizeof(img_writers[0]); n++) {
- const struct img_writer *writer = &img_writers[n];
- if (type && strcmp(type, writer->file_ext) == 0)
- return writer;
- }
-
- return &img_writers[0];
-}
-
-static int fexists(char *fname)
-{
- return mp_path_exists(fname);
-}
-
static char *stripext(void *talloc_ctx, const char *s)
{
const char *end = strrchr(s, '.');
@@ -379,14 +223,14 @@ error_exit:
return NULL;
}
-static char *gen_fname(screenshot_ctx *ctx)
+static char *gen_fname(screenshot_ctx *ctx, const char *file_ext)
{
int sequence = 0;
for (;;) {
int prev_sequence = sequence;
char *fname = create_fname(ctx->mpctx,
ctx->mpctx->opts.screenshot_template,
- get_writer(ctx)->file_ext,
+ file_ext,
&sequence,
&ctx->frameno);
@@ -397,7 +241,7 @@ static char *gen_fname(screenshot_ctx *ctx)
return NULL;
}
- if (!fexists(fname))
+ if (!mp_path_exists(fname))
return fname;
if (sequence == prev_sequence) {
@@ -414,54 +258,22 @@ static char *gen_fname(screenshot_ctx *ctx)
void screenshot_save(struct MPContext *mpctx, struct mp_image *image)
{
screenshot_ctx *ctx = mpctx->screenshot_ctx;
- const struct img_writer *writer = get_writer(ctx);
- struct mp_image *allocated_image = NULL;
- const int destfmt = IMGFMT_RGB24;
-
- if (image->imgfmt != destfmt) {
- struct mp_image *dst = alloc_mpi(image->w, image->h, destfmt);
-
- struct SwsContext *sws = sws_getContextFromCmdLine_hq(image->width,
- image->height,
- image->imgfmt,
- dst->width,
- dst->height,
- dst->imgfmt);
-
- struct mp_csp_details colorspace;
- get_detected_video_colorspace(mpctx->sh_video, &colorspace);
- // this is a property of the output device; images always use
- // full-range RGB
- colorspace.levels_out = MP_CSP_LEVELS_PC;
- mp_sws_set_colorspace(sws, &colorspace);
-
- sws_scale(sws, (const uint8_t **)image->planes, image->stride, 0,
- image->height, dst->planes, dst->stride);
-
- sws_freeContext(sws);
-
- allocated_image = dst;
- image = dst;
- }
- char *filename = gen_fname(ctx);
+ struct mp_csp_details colorspace;
+ get_detected_video_colorspace(mpctx->sh_video, &colorspace);
+
+ struct image_writer_opts opts = image_writer_opts_defaults;
+ opts.filetype = mpctx->opts.screenshot_filetype;
+ opts.jpeg_quality = mpctx->opts.screenshot_jpeg_quality;
+ opts.png_compression = mpctx->opts.screenshot_png_compression;
+
+ char *filename = gen_fname(ctx, image_writer_file_ext(&opts));
if (filename) {
- FILE *fp = fopen(filename, "wb");
- if (fp == NULL) {
- mp_msg(MSGT_CPLAYER, MSGL_ERR,
- "\nError opening '%s' for writing!\n", filename);
- } else {
- mp_msg(MSGT_CPLAYER, MSGL_INFO, "*** screenshot '%s' ***\n",
- filename);
- int success = writer->write(ctx, image, fp);
- success = !fclose(fp) && success;
- if (!success)
- mp_msg(MSGT_CPLAYER, MSGL_ERR, "Error writing screenshot!\n");
- }
+ mp_msg(MSGT_CPLAYER, MSGL_INFO, "*** screenshot '%s' ***\n", filename);
+ if (!write_image(image, &colorspace, &opts, filename))
+ mp_msg(MSGT_CPLAYER, MSGL_ERR, "\nError writing screenshot!\n");
talloc_free(filename);
}
-
- free_mp_image(allocated_image);
}
static void vf_screenshot_callback(void *pctx, struct mp_image *image)