diff options
Diffstat (limited to 'video')
-rw-r--r-- | video/decode/dec_video.c | 11 | ||||
-rw-r--r-- | video/decode/dec_video.h | 1 | ||||
-rw-r--r-- | video/decode/dxva2.c | 5 | ||||
-rw-r--r-- | video/decode/vd_lavc.c | 4 | ||||
-rw-r--r-- | video/filter/vf.c | 5 | ||||
-rw-r--r-- | video/filter/vf.h | 1 | ||||
-rw-r--r-- | video/filter/vf_crop.c | 7 | ||||
-rw-r--r-- | video/filter/vf_expand.c | 13 | ||||
-rw-r--r-- | video/filter/vf_mirror.c | 89 | ||||
-rw-r--r-- | video/filter/vf_screenshot.c | 74 | ||||
-rw-r--r-- | video/filter/vf_vapoursynth.c | 14 | ||||
-rw-r--r-- | video/filter/vf_vdpaupp.c | 4 | ||||
-rw-r--r-- | video/image_writer.c | 72 | ||||
-rw-r--r-- | video/image_writer.h | 10 | ||||
-rw-r--r-- | video/mp_image.c | 3 | ||||
-rw-r--r-- | video/mp_image.h | 3 | ||||
-rw-r--r-- | video/out/drm_common.c | 149 | ||||
-rw-r--r-- | video/out/drm_common.h | 36 | ||||
-rw-r--r-- | video/out/vo.c | 50 | ||||
-rw-r--r-- | video/out/vo_drm.c | 641 | ||||
-rw-r--r-- | video/out/vo_opengl.c | 3 | ||||
-rw-r--r-- | video/out/vo_rpi.c | 8 | ||||
-rw-r--r-- | video/out/w32_common.c | 26 | ||||
-rw-r--r-- | video/out/win_state.c | 2 | ||||
-rw-r--r-- | video/out/x11_common.c | 67 | ||||
-rw-r--r-- | video/out/x11_common.h | 6 |
26 files changed, 1012 insertions, 292 deletions
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c index afbda5142f..0c733b0aa6 100644 --- a/video/decode/dec_video.c +++ b/video/decode/dec_video.c @@ -385,13 +385,6 @@ int video_reconfig_filters(struct dec_video *d_video, struct mp_image_params p = *params; struct sh_video *sh = d_video->header->video; - MP_VERBOSE(d_video, "VIDEO: %dx%d %5.3f fps %5.1f kbps (%4.1f kB/s)\n", - p.w, p.h, sh->fps, sh->bitrate / 1000.0, - sh->bitrate / 8000.0); - - MP_VERBOSE(d_video, "VDec: vo config request - %d x %d (%s)\n", - p.w, p.h, vo_format_name(p.imgfmt)); - float decoder_aspect = p.d_w / (float)p.d_h; if (d_video->initial_decoder_aspect == 0) d_video->initial_decoder_aspect = decoder_aspect; @@ -414,10 +407,6 @@ int video_reconfig_filters(struct dec_video *d_video, // Detect colorspace from resolution. mp_image_params_guess_csp(&p); - // Time to config libvo! - MP_VERBOSE(d_video, "VO Config (%dx%d->%dx%d,0x%X)\n", - p.w, p.h, p.d_w, p.d_h, p.imgfmt); - if (vf_reconfig(d_video->vfilter, params, &p) < 0) { MP_FATAL(d_video, "Cannot initialize video filters.\n"); return -1; diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h index ce24d5a58e..5ab7213ee7 100644 --- a/video/decode/dec_video.h +++ b/video/decode/dec_video.h @@ -71,7 +71,6 @@ struct dec_video { // Final PTS of previously decoded image double decoded_pts; - int bitrate; // compressed bits/sec float fps; // FPS from demuxer or from user override float initial_decoder_aspect; diff --git a/video/decode/dxva2.c b/video/decode/dxva2.c index cbd08a7e52..ef7756178d 100644 --- a/video/decode/dxva2.c +++ b/video/decode/dxva2.c @@ -256,6 +256,9 @@ static void copy_nv12_fallback(struct mp_image *dest, uint8_t *src_bits, mp_image_copy(dest, &buf); } +#pragma GCC push_options +#pragma GCC target("sse4.1") + static void copy_nv12_gpu_sse4(struct mp_image *dest, uint8_t *src_bits, unsigned src_pitch, unsigned surf_height) { @@ -291,6 +294,8 @@ static void copy_nv12_gpu_sse4(struct mp_image *dest, uint8_t *src_bits, } } +#pragma GCC pop_options + static struct mp_image *dxva2_retrieve_image(struct lavc_ctx *s, struct mp_image *img) { diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 1a0d504461..ca9ab9e5eb 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -328,9 +328,6 @@ static int init(struct dec_video *vd, const char *decoder) } } - if (ctx->avctx->bit_rate != 0) - vd->bitrate = ctx->avctx->bit_rate; - return 1; } @@ -362,7 +359,6 @@ static void init_avctx(struct dec_video *vd, const char *decoder, AVCodecContext *avctx = ctx->avctx; if (!ctx->avctx) goto error; - avctx->bit_rate = 0; avctx->opaque = vd; avctx->codec_type = AVMEDIA_TYPE_VIDEO; avctx->codec_id = lavc_codec->id; diff --git a/video/filter/vf.c b/video/filter/vf.c index 888e937fa5..4f9f43f2e0 100644 --- a/video/filter/vf.c +++ b/video/filter/vf.c @@ -54,7 +54,6 @@ extern const vf_info_t vf_info_hqdn3d; extern const vf_info_t vf_info_dsize; extern const vf_info_t vf_info_pullup; extern const vf_info_t vf_info_delogo; -extern const vf_info_t vf_info_screenshot; extern const vf_info_t vf_info_sub; extern const vf_info_t vf_info_yadif; extern const vf_info_t vf_info_stereo3d; @@ -74,9 +73,9 @@ static const vf_info_t *const filter_list[] = { &vf_info_format, &vf_info_noformat, &vf_info_flip, - &vf_info_mirror, #if HAVE_LIBAVFILTER + &vf_info_mirror, &vf_info_lavfi, &vf_info_rotate, &vf_info_noise, @@ -88,8 +87,6 @@ static const vf_info_t *const filter_list[] = { &vf_info_yadif, #endif - &vf_info_screenshot, - &vf_info_eq, &vf_info_dsize, &vf_info_sub, diff --git a/video/filter/vf.h b/video/filter/vf.h index f7ee9d011b..76835528b5 100644 --- a/video/filter/vf.h +++ b/video/filter/vf.h @@ -144,7 +144,6 @@ enum vf_ctrl { VFCTRL_SEEK_RESET = 1, // reset on picture and PTS discontinuities VFCTRL_SET_EQUALIZER, // set color options (brightness,contrast etc) VFCTRL_GET_EQUALIZER, // get color options (brightness,contrast etc) - VFCTRL_SCREENSHOT, // Take screenshot, arg is mp_image** VFCTRL_INIT_OSD, // Filter OSD renderer present? VFCTRL_SET_DEINTERLACE, // Set deinterlacing status VFCTRL_GET_DEINTERLACE, // Get deinterlacing status diff --git a/video/filter/vf_crop.c b/video/filter/vf_crop.c index 498b2a9037..02787b8f22 100644 --- a/video/filter/vf_crop.c +++ b/video/filter/vf_crop.c @@ -58,7 +58,7 @@ static int config(struct vf_instance *vf, // check: if(vf->priv->crop_w+vf->priv->crop_x>width || vf->priv->crop_h+vf->priv->crop_y>height){ - MP_WARN(vf, "[CROP] Bad position/width/height - cropped area outside of the original!\n"); + MP_WARN(vf, "Bad position/width/height - cropped area outside of the original!\n"); return 0; } vf_rescale_dsize(&d_width, &d_height, width, height, @@ -85,11 +85,6 @@ static int vf_open(vf_instance_t *vf){ vf->config=config; vf->filter=filter; vf->query_format=query_format; - MP_INFO(vf, "Crop: %d x %d, %d ; %d\n", - vf->priv->crop_w, - vf->priv->crop_h, - vf->priv->crop_x, - vf->priv->crop_y); return 1; } diff --git a/video/filter/vf_expand.c b/video/filter/vf_expand.c index 44a8ec5767..6d5b694613 100644 --- a/video/filter/vf_expand.c +++ b/video/filter/vf_expand.c @@ -63,18 +63,12 @@ static int config(struct vf_instance *vf, vf->priv->exp_y = vf->priv->cfg_exp_y; vf->priv->exp_w = vf->priv->cfg_exp_w; vf->priv->exp_h = vf->priv->cfg_exp_h; - // calculate the missing parameters: -#if 0 - if(vf->priv->exp_w<width) vf->priv->exp_w=width; - if(vf->priv->exp_h<height) vf->priv->exp_h=height; -#else if ( vf->priv->exp_w == -1 ) vf->priv->exp_w=width; else if (vf->priv->exp_w < -1 ) vf->priv->exp_w=width - vf->priv->exp_w; else if ( vf->priv->exp_w<width ) vf->priv->exp_w=width; if ( vf->priv->exp_h == -1 ) vf->priv->exp_h=height; else if ( vf->priv->exp_h < -1 ) vf->priv->exp_h=height - vf->priv->exp_h; else if( vf->priv->exp_h<height ) vf->priv->exp_h=height; -#endif if (vf->priv->aspect) { float adjusted_aspect = vf->priv->aspect; adjusted_aspect *= ((double)width/height) / ((double)d_width/d_height); @@ -149,13 +143,6 @@ static int vf_open(vf_instance_t *vf){ vf->config=config; vf->query_format=query_format; vf->filter=filter; - MP_INFO(vf, "Expand: %d x %d, %d ; %d, aspect: %f, round: %d\n", - vf->priv->cfg_exp_w, - vf->priv->cfg_exp_h, - vf->priv->cfg_exp_x, - vf->priv->cfg_exp_y, - vf->priv->aspect, - vf->priv->round); return 1; } diff --git a/video/filter/vf_mirror.c b/video/filter/vf_mirror.c index d92f320235..342c6abd2a 100644 --- a/video/filter/vf_mirror.c +++ b/video/filter/vf_mirror.c @@ -15,93 +15,14 @@ * with mpv. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> +#include <stddef.h> -#include "config.h" -#include "common/msg.h" - -#include "video/img_format.h" -#include "video/mp_image.h" #include "vf.h" +#include "vf_lavfi.h" -static int config(struct vf_instance *vf, int width, int height, - int d_width, int d_height, - unsigned int flags, unsigned int fmt) -{ - struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); - int a_w = MP_ALIGN_DOWN(width, desc.align_x); - vf_rescale_dsize(&d_width, &d_height, width, height, a_w, height); - return vf_next_config(vf, a_w, height, d_width, d_height, flags, fmt); -} - -static inline void mirror_4_m(uint8_t *dst, uint8_t *src, int p, - int c0, int c1, int c2, int c3) -{ - for (int x = 0; x < p; x++) { - dst[x * 4 + 0] = src[(p - x - 1) * 4 + c0]; - dst[x * 4 + 1] = src[(p - x - 1) * 4 + c1]; - dst[x * 4 + 2] = src[(p - x - 1) * 4 + c2]; - dst[x * 4 + 3] = src[(p - x - 1) * 4 + c3]; - } -} - -static inline void mirror(uint8_t *dst, uint8_t *src, int bp, int w) -{ - for (int x = 0; x < w; x++) - memcpy(dst + x * bp, src + (w - x - 1) * bp, bp); -} - -static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) +static int vf_open(vf_instance_t *vf) { - mp_image_t *dmpi = vf_alloc_out_image(vf); - if (!dmpi) - return NULL; - mp_image_copy_attributes(dmpi, mpi); - - for (int p = 0; p < mpi->num_planes; p++) { - int plane_h = mp_image_plane_h(mpi, p); - for (int y = 0; y < plane_h; y++) { - void *p_src = mpi->planes[p] + mpi->stride[p] * y; - void *p_dst = dmpi->planes[p] + dmpi->stride[p] * y; - int w = mp_image_plane_w(dmpi, p); - if (mpi->imgfmt == IMGFMT_YUYV) { - mirror_4_m(p_dst, p_src, w / 2, 2, 1, 0, 3); - } else if (mpi->imgfmt == IMGFMT_UYVY) { - mirror_4_m(p_dst, p_src, w / 2, 0, 3, 2, 1); - } else { - // make the compiler unroll the memcpy in mirror() - switch (mpi->fmt.bytes[p]) { - case 1: mirror(p_dst, p_src, 1, w); break; - case 2: mirror(p_dst, p_src, 2, w); break; - case 3: mirror(p_dst, p_src, 3, w); break; - case 4: mirror(p_dst, p_src, 4, w); break; - default: - mirror(p_dst, p_src, mpi->fmt.bytes[p], w); - } - } - } - } - - talloc_free(mpi); - return dmpi; -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); - if (!(desc.flags & MP_IMGFLAG_BYTE_ALIGNED)) - return 0; - return vf_next_query_format(vf, fmt); -} - -static int vf_open(vf_instance_t *vf){ - vf->config=config; - vf->filter=filter; - vf->query_format=query_format; - return 1; + return vf_lw_set_graph(vf, NULL, NULL, "hflip") >= 0; } const vf_info_t vf_info_mirror = { @@ -109,5 +30,3 @@ const vf_info_t vf_info_mirror = { .name = "mirror", .open = vf_open, }; - -//===========================================================================// diff --git a/video/filter/vf_screenshot.c b/video/filter/vf_screenshot.c deleted file mode 100644 index 57cd9fbb0b..0000000000 --- a/video/filter/vf_screenshot.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of mpv. - * - * mpv is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#include "talloc.h" - -#include "video/img_format.h" -#include "video/mp_image.h" -#include "video/sws_utils.h" -#include "video/out/vo.h" - -#include "vf.h" - -struct vf_priv_s { - struct mp_image *current; -}; - -static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi) -{ - mp_image_unrefp(&vf->priv->current); - vf->priv->current = talloc_steal(vf, mp_image_new_ref(mpi)); - return mpi; -} - -static int control (vf_instance_t *vf, int request, void *data) -{ - if (request == VFCTRL_SCREENSHOT && vf->priv->current) { - *(struct mp_image **)data = mp_image_new_ref(vf->priv->current); - return CONTROL_TRUE; - } - return CONTROL_UNKNOWN; -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - if (mp_sws_supported_format(fmt)) - return vf_next_query_format(vf, fmt); - return 0; -} - -static int vf_open(vf_instance_t *vf) -{ - vf->control = control; - vf->filter = filter; - vf->query_format = query_format; - vf->priv = talloc_zero(vf, struct vf_priv_s); - return 1; -} - -const vf_info_t vf_info_screenshot = { - .description = "screenshot to file", - .name = "screenshot", - .open = vf_open, -}; diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c index db0bce3210..01cacbf742 100644 --- a/video/filter/vf_vapoursynth.c +++ b/video/filter/vf_vapoursynth.c @@ -20,6 +20,7 @@ #include <string.h> #include <inttypes.h> #include <pthread.h> +#include <limits.h> #include <assert.h> #include <VapourSynth.h> @@ -167,10 +168,10 @@ static void copy_mp_to_vs_frame_props_map(struct vf_priv_s *p, VSMap *map, } if (pict_type) p->vsapi->propSetData(map, "_PictType", &pict_type, 1, 0); - p->vsapi->propSetInt(map, "_FieldBased", - !!(img->fields & MP_IMGFIELD_INTERLACED), 0); - p->vsapi->propSetInt(map, "_Field", - !!(img->fields & MP_IMGFIELD_TOP_FIRST), 0); + int field = 0; + if (img->fields & MP_IMGFIELD_INTERLACED) + field = img->fields & MP_IMGFIELD_TOP_FIRST ? 2 : 1; + p->vsapi->propSetInt(map, "_FieldBased", field, 0); } static int set_vs_frame_props(struct vf_priv_s *p, VSFrameRef *frame, @@ -407,6 +408,10 @@ static void VS_CC infiltInit(VSMap *in, VSMap *out, void **instanceData, { struct vf_instance *vf = *instanceData; struct vf_priv_s *p = vf->priv; + // The number of frames of our input node is obviously unknown. The user + // could for example seek any time, randomly "ending" the clip. + // This specific value was suggested by the VapourSynth developer. + int enough_for_everyone = INT_MAX / 16; // Note: this is called from createFilter, so no need for locking. @@ -414,6 +419,7 @@ static void VS_CC infiltInit(VSMap *in, VSMap *out, void **instanceData, .format = p->vsapi->getFormatPreset(mp_to_vs(p->fmt_in.imgfmt), p->vscore), .width = p->fmt_in.w, .height = p->fmt_in.h, + .numFrames = enough_for_everyone, }; if (!fmt.format) { p->vsapi->setError(out, "Unsupported input format.\n"); diff --git a/video/filter/vf_vdpaupp.c b/video/filter/vf_vdpaupp.c index 4db6ab9186..26c1eef5ca 100644 --- a/video/filter/vf_vdpaupp.c +++ b/video/filter/vf_vdpaupp.c @@ -92,9 +92,7 @@ static bool output_field(struct vf_instance *vf, int pos) frame->field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; if (p->opts.deint) { - int top_field_first = 1; - if (mpi->fields & MP_IMGFIELD_ORDERED) - top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST); + int top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST); frame->field = top_field_first ^ (pos & 1) ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD: VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; diff --git a/video/image_writer.c b/video/image_writer.c index 491828aa22..bcb71f4863 100644 --- a/video/image_writer.c +++ b/video/image_writer.c @@ -78,14 +78,14 @@ struct image_writer_ctx { struct img_writer { const char *file_ext; - int (*write)(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp); + bool (*write)(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp); const int *pixfmts; int lavc_codec; }; -static int write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) +static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) { - int success = 0; + bool success = 0; AVFrame *pic = NULL; AVPacket pkt = {0}; int got_output = 0; @@ -161,7 +161,7 @@ static void write_jpeg_error_exit(j_common_ptr cinfo) longjmp(*(jmp_buf*)cinfo->client_data, 1); } -static int write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) +static bool write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; @@ -173,7 +173,7 @@ static int write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) cinfo.client_data = &error_return_jmpbuf; if (setjmp(cinfo.client_data)) { jpeg_destroy_compress(&cinfo); - return 0; + return false; } jpeg_create_compress(&cinfo); @@ -209,7 +209,7 @@ static int write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) jpeg_destroy_compress(&cinfo); - return 1; + return true; } #endif @@ -279,15 +279,38 @@ const char *image_writer_file_ext(const struct image_writer_opts *opts) return get_writer(opts)->file_ext; } -int write_image(struct mp_image *image, const struct image_writer_opts *opts, - const char *filename, struct mp_log *log) +struct mp_image *convert_image(struct mp_image *image, int destfmt, + struct mp_log *log) { - struct mp_image *allocated_image = NULL; - struct image_writer_opts defs = image_writer_opts_defaults; int d_w = image->params.d_w; int d_h = image->params.d_h; bool is_anamorphic = image->w != d_w || image->h != d_h; + // Caveat: no colorspace/levels conversion done if pixel formats equal + // it's unclear what colorspace/levels the target wants + if (image->imgfmt == destfmt && !is_anamorphic) + return mp_image_new_ref(image); + + struct mp_image *dst = mp_image_alloc(destfmt, d_w, d_h); + if (!dst) { + mp_err(log, "Out of memory.\n"); + return NULL; + } + mp_image_copy_attributes(dst, image); + + if (mp_image_swscale(dst, image, mp_sws_hq_flags) < 0) { + mp_err(log, "Error when converting image.\n"); + talloc_free(dst); + return NULL; + } + + return dst; +} + +bool write_image(struct mp_image *image, const struct image_writer_opts *opts, + const char *filename, struct mp_log *log) +{ + struct image_writer_opts defs = image_writer_opts_defaults; if (!opts) opts = &defs; @@ -295,39 +318,22 @@ int write_image(struct mp_image *image, const struct image_writer_opts *opts, struct image_writer_ctx ctx = { log, opts, writer, image->fmt }; int destfmt = get_target_format(&ctx, image->imgfmt); - // Caveat: no colorspace/levels conversion done if pixel formats equal - // it's unclear what colorspace/levels the target wants - if (image->imgfmt != destfmt || is_anamorphic) { - struct mp_image *dst = mp_image_alloc(destfmt, d_w, d_h); - if (!dst) { - mp_err(log, "Out of memory.\n"); - return 0; - } - mp_image_copy_attributes(dst, image); - - if (mp_image_swscale(dst, image, mp_sws_hq_flags) < 0) { - mp_err(log, "Error when converting image.\n"); - talloc_free(dst); - return 0; - } - - allocated_image = dst; - image = dst; - } + struct mp_image *dst = convert_image(image, destfmt, log); + if (!dst) + return false; FILE *fp = fopen(filename, "wb"); - int success = 0; + bool success = false; if (fp == NULL) { mp_err(log, "Error opening '%s' for writing!\n", filename); } else { - success = writer->write(&ctx, image, fp); + success = writer->write(&ctx, dst, fp); success = !fclose(fp) && success; if (!success) mp_err(log, "Error writing file '%s'!\n", filename); } - talloc_free(allocated_image); - + talloc_free(dst); return success; } diff --git a/video/image_writer.h b/video/image_writer.h index 7db4293712..b27db3981a 100644 --- a/video/image_writer.h +++ b/video/image_writer.h @@ -48,8 +48,14 @@ const char *image_writer_file_ext(const struct image_writer_opts *opts); * accordingly. Setting w and width or h and height to different values * can be used to store snapshots of anamorphic video. */ -int write_image(struct mp_image *image, const struct image_writer_opts *opts, - const char *filename, struct mp_log *log); +bool write_image(struct mp_image *image, const struct image_writer_opts *opts, + const char *filename, struct mp_log *log); + +/* Return the image converted to the given format. If the pixel aspect ratio is + * not 1:1, the image is scaled as well. Returns NULL on failure. + */ +struct mp_image *convert_image(struct mp_image *image, int destfmt, + struct mp_log *log); // Debugging helper. void dump_png(struct mp_image *image, const char *filename, struct mp_log *log); diff --git a/video/mp_image.c b/video/mp_image.c index e97ca1564b..dc305a4b63 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -625,14 +625,13 @@ void mp_image_copy_fields_from_av_frame(struct mp_image *dst, dst->pict_type = src->pict_type; - dst->fields = MP_IMGFIELD_ORDERED; + dst->fields = 0; if (src->interlaced_frame) dst->fields |= MP_IMGFIELD_INTERLACED; if (src->top_field_first) dst->fields |= MP_IMGFIELD_TOP_FIRST; if (src->repeat_pict == 1) dst->fields |= MP_IMGFIELD_REPEAT_FIRST; - } // Copy properties and data of the mp_image into the AVFrame, without taking diff --git a/video/mp_image.h b/video/mp_image.h index f2028c33e6..b0110c1376 100644 --- a/video/mp_image.h +++ b/video/mp_image.h @@ -30,11 +30,8 @@ #define MP_PALETTE_SIZE (256 * 4) -#define MP_IMGFIELD_ORDERED 0x01 #define MP_IMGFIELD_TOP_FIRST 0x02 #define MP_IMGFIELD_REPEAT_FIRST 0x04 -#define MP_IMGFIELD_TOP 0x08 -#define MP_IMGFIELD_BOTTOM 0x10 #define MP_IMGFIELD_INTERLACED 0x20 // Describes image parameters that usually stay constant. diff --git a/video/out/drm_common.c b/video/out/drm_common.c new file mode 100644 index 0000000000..c61ad69eba --- /dev/null +++ b/video/out/drm_common.c @@ -0,0 +1,149 @@ +/* + * This file is part of mpv. + * + * by rr- <rr-@sakuya.pl> + * + * mpv is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <errno.h> +#include <signal.h> +#include <sys/ioctl.h> +#include <sys/poll.h> +#include <sys/vt.h> +#include <unistd.h> + +#include "drm_common.h" + +#include "common/common.h" +#include "common/msg.h" +#include "osdep/io.h" + +#define EVT_RELEASE 1 +#define EVT_ACQUIRE 2 +#define EVT_INTERRUPT 255 +#define HANDLER_ACQUIRE 0 +#define HANDLER_RELEASE 1 + +static int vt_switcher_pipe[2]; + +static void vt_switcher_sighandler(int sig) +{ + unsigned char event = sig == SIGUSR1 ? EVT_RELEASE : EVT_ACQUIRE; + write(vt_switcher_pipe[1], &event, sizeof(event)); +} + +int vt_switcher_init(struct vt_switcher *s, struct mp_log *log) +{ + s->log = log; + s->tty_fd = -1; + vt_switcher_pipe[0] = -1; + vt_switcher_pipe[1] = -1; + + if (mp_make_cloexec_pipe(vt_switcher_pipe)) { + MP_ERR(s, "Creating pipe failed: %s", mp_strerror(errno)); + return -1; + } + + s->tty_fd = open("/dev/tty", O_RDWR | O_CLOEXEC); + if (s->tty_fd < 0) { + MP_ERR(s, "Can't open TTY for VT control: %s", mp_strerror(errno)); + return -1; + } + + struct sigaction act; + act.sa_handler = vt_switcher_sighandler; + act.sa_flags = SA_RESTART; + sigemptyset(&act.sa_mask); + sigaction(SIGUSR1, &act, 0); + sigaction(SIGUSR2, &act, 0); + + struct vt_mode vt_mode; + if (ioctl(s->tty_fd, VT_GETMODE, &vt_mode) < 0) { + MP_ERR(s, "VT_GETMODE failed: %s", mp_strerror(errno)); + return -1; + } + + vt_mode.mode = VT_PROCESS; + vt_mode.relsig = SIGUSR1; + vt_mode.acqsig = SIGUSR2; + if (ioctl(s->tty_fd, VT_SETMODE, &vt_mode) < 0) { + MP_ERR(s, "VT_SETMODE failed: %s", mp_strerror(errno)); + return -1; + } + + return 0; +} + +void vt_switcher_acquire(struct vt_switcher *s, + void (*handler)(void*), void *user_data) +{ + s->handlers[HANDLER_ACQUIRE] = handler; + s->handler_data[HANDLER_ACQUIRE] = user_data; +} + +void vt_switcher_release(struct vt_switcher *s, + void (*handler)(void*), void *user_data) +{ + s->handlers[HANDLER_RELEASE] = handler; + s->handler_data[HANDLER_RELEASE] = user_data; +} + +void vt_switcher_interrupt_poll(struct vt_switcher *s) +{ + unsigned char event = EVT_INTERRUPT; + write(vt_switcher_pipe[1], &event, sizeof(event)); +} + +void vt_switcher_destroy(struct vt_switcher *s) +{ + close(s->tty_fd); + close(vt_switcher_pipe[0]); + close(vt_switcher_pipe[1]); +} + +void vt_switcher_poll(struct vt_switcher *s, int timeout_ms) +{ + struct pollfd fds[1] = { + { .events = POLLIN, .fd = vt_switcher_pipe[0] }, + }; + poll(fds, 1, timeout_ms); + if (!fds[0].revents) + return; + + unsigned char event; + if (read(fds[0].fd, &event, sizeof(event)) != sizeof(event)) + return; + + switch (event) { + case EVT_RELEASE: + s->handlers[HANDLER_RELEASE](s->handler_data[HANDLER_RELEASE]); + + if (ioctl(s->tty_fd, VT_RELDISP, 1) < 0) { + MP_ERR(s, "Failed to release virtual terminal\n"); + } + break; + + case EVT_ACQUIRE: + s->handlers[HANDLER_ACQUIRE](s->handler_data[HANDLER_ACQUIRE]); + + if (ioctl(s->tty_fd, VT_RELDISP, VT_ACKACQ) < 0) { + MP_ERR(s, "Failed to acquire virtual terminal\n"); + } + break; + + case EVT_INTERRUPT: + break; + } +} diff --git a/video/out/drm_common.h b/video/out/drm_common.h new file mode 100644 index 0000000000..5e6c1915ba --- /dev/null +++ b/video/out/drm_common.h @@ -0,0 +1,36 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more d |