diff --git a/libvo/vo_lavc.c b/libvo/vo_lavc.c index 5b467f1f6a..4cf4003031 100644 --- a/libvo/vo_lavc.c +++ b/libvo/vo_lavc.c @@ -34,6 +34,7 @@ #include "encode_lavc.h" #include "sub/sub.h" +#include "sub/draw_bmp.h" #include "libvo/osd.h" struct priv { @@ -49,13 +50,12 @@ struct priv { int64_t lastframeipts; double expected_next_pts; mp_image_t *lastimg; + int lastimg_wants_osd; int lastdisplaycount; AVRational worst_time_base; int worst_time_base_is_stream; - struct osd_state *osd; - struct mp_csp_details colorspace; }; @@ -156,12 +156,13 @@ static int config(struct vo *vo, uint32_t width, uint32_t height, encode_lavc_set_csp(vo->encode_lavc_ctx, vc->stream, vc->colorspace.format); encode_lavc_set_csp_levels(vo->encode_lavc_ctx, vc->stream, vc->colorspace.levels_out); - vc->colorspace.format = encode_lavc_get_csp(vo->encode_lavc_ctx, vc->stream); - vc->colorspace.levels_out = encode_lavc_get_csp_levels(vo->encode_lavc_ctx, vc->stream); if (encode_lavc_open_codec(vo->encode_lavc_ctx, vc->stream) < 0) goto error; + vc->colorspace.format = encode_lavc_get_csp(vo->encode_lavc_ctx, vc->stream); + vc->colorspace.levels_out = encode_lavc_get_csp_levels(vo->encode_lavc_ctx, vc->stream); + vc->buffer_size = 6 * width * height + 200; if (vc->buffer_size < FF_MIN_BUFFER_SIZE) vc->buffer_size = FF_MIN_BUFFER_SIZE; @@ -191,8 +192,18 @@ static int query_format(struct vo *vo, uint32_t format) if (!vo->encode_lavc_ctx) return 0; - return encode_lavc_supports_pixfmt(vo->encode_lavc_ctx, pix_fmt) ? - VFCAP_CSP_SUPPORTED : 0; + if (!encode_lavc_supports_pixfmt(vo->encode_lavc_ctx, pix_fmt)) + return 0; + + return + VFCAP_CSP_SUPPORTED | + // we can do it + VFCAP_CSP_SUPPORTED_BY_HW | + // we don't convert colorspaces here (TODO: if we add EOSD rendering, only set this flag if EOSD can be rendered without extra conversions) + VFCAP_OSD | VFCAP_EOSD | + // we have OSD + VOCAP_NOSLICES; + // we don't use slices } static void write_packet(struct vo *vo, int size, AVPacket *packet) @@ -275,63 +286,6 @@ static int encode_video(struct vo *vo, AVFrame *frame, AVPacket *packet) } } -static void add_osd_to_lastimg_draw_func(void *ctx, int x0,int y0, int w,int h,unsigned char* src, unsigned char *srca, int stride){ - struct priv *vc = ctx; - unsigned char* dst; - if(w<=0 || h<=0) return; // nothing to do... - // printf("OSD redraw: %d;%d %dx%d \n",x0,y0,w,h); - dst=vc->lastimg->planes[0]+ - vc->lastimg->stride[0]*y0+ - (vc->lastimg->bpp>>3)*x0; - switch(vc->lastimg->imgfmt){ - case IMGFMT_BGR12: - case IMGFMT_RGB12: - vo_draw_alpha_rgb12(w, h, src, srca, stride, dst, vc->lastimg->stride[0]); - break; - case IMGFMT_BGR15: - case IMGFMT_RGB15: - vo_draw_alpha_rgb15(w,h,src,srca,stride,dst,vc->lastimg->stride[0]); - break; - case IMGFMT_BGR16: - case IMGFMT_RGB16: - vo_draw_alpha_rgb16(w,h,src,srca,stride,dst,vc->lastimg->stride[0]); - break; - case IMGFMT_BGR24: - case IMGFMT_RGB24: - vo_draw_alpha_rgb24(w,h,src,srca,stride,dst,vc->lastimg->stride[0]); - break; - case IMGFMT_BGR32: - case IMGFMT_RGB32: - vo_draw_alpha_rgb32(w,h,src,srca,stride,dst,vc->lastimg->stride[0]); - break; - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_Y800: - case IMGFMT_Y8: - vo_draw_alpha_yv12(w,h,src,srca,stride,dst,vc->lastimg->stride[0]); - break; - case IMGFMT_YUY2: - vo_draw_alpha_yuy2(w,h,src,srca,stride,dst,vc->lastimg->stride[0]); - break; - case IMGFMT_UYVY: - vo_draw_alpha_yuy2(w,h,src,srca,stride,dst+1,vc->lastimg->stride[0]); - break; - default: - mp_msg(MSGT_ENCODE, MSGL_WARN, "vo-lavc: tried to draw OSD on an usnupported pixel format\n"); - } -} - -static void add_osd_to_lastimg(struct vo *vo) -{ - struct priv *vc = vo->priv; - if(vc->osd) { - osd_draw_text(vc->osd, vc->lastimg->w, vc->lastimg->h, add_osd_to_lastimg_draw_func, vc); - } -} - static void draw_image(struct vo *vo, mp_image_t *mpi, double pts) { struct priv *vc = vo->priv; @@ -503,7 +457,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi, double pts) "vo-lavc: Frame at pts %d got displayed %d times\n", (int) vc->lastframeipts, vc->lastdisplaycount); copy_mpi(vc->lastimg, mpi); - add_osd_to_lastimg(vo); + vc->lastimg_wants_osd = true; // palette hack if (vc->lastimg->imgfmt == IMGFMT_RGB8 || @@ -516,12 +470,22 @@ static void draw_image(struct vo *vo, mp_image_t *mpi, double pts) vc->lastipts = -1; } vc->lastdisplaycount = 0; - } else + } else { mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: Frame at pts %d got dropped " "entirely because pts went backwards\n", (int) frameipts); + vc->lastimg_wants_osd = false; + } } } +static void flip_page_timed(struct vo *vo, unsigned int pts_us, int duration) +{ +} + +static void check_events(struct vo *vo) +{ +} + static int control(struct vo *vo, uint32_t request, void *data) { struct priv *vc = vo->priv; @@ -543,26 +507,29 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_GET_YUV_COLORSPACE: *(struct mp_csp_details *)data = vc->colorspace; return 1; + case VOCTRL_DRAW_EOSD: + if (vc->lastimg && vc->lastimg_wants_osd) { + struct sub_bitmaps *imgs = data; + mp_draw_sub_bitmaps(vc->lastimg, imgs, &vc->colorspace); + } + return VO_TRUE; + case VOCTRL_GET_EOSD_RES: { + struct mp_eosd_res *r = data; + r->w = vc->stream->codec->width; + r->h = vc->stream->codec->height; + r->ml = r->mr = 0; + r->mt = r->mb = 0; + return VO_TRUE; + } + case VOCTRL_QUERY_EOSD_FORMAT: { + int format = *(int *)data; + return (format == SUBBITMAP_LIBASS || format == SUBBITMAP_RGBA) + ? VO_TRUE : VO_NOTIMPL; + } } return VO_NOTIMPL; } -static void draw_osd(struct vo *vo, struct osd_state *osd) -{ - struct priv *vc = vo->priv; - vc->osd = osd; - if(vc->lastimg) - osd_update(vc->osd, vc->lastimg->w, vc->lastimg->h); -} - -static void flip_page_timed(struct vo *vo, unsigned int pts_us, int duration) -{ -} - -static void check_events(struct vo *vo) -{ -} - const struct vo_driver video_out_lavc = { .is_new = true, .buffer_frames = false, @@ -577,8 +544,8 @@ const struct vo_driver video_out_lavc = { .control = control, .uninit = uninit, .check_events = check_events, - .draw_osd = draw_osd, + .draw_osd = draw_osd_with_eosd, .flip_page_timed = flip_page_timed, }; -// vim: sw=4 ts=4 et +// vim: sw=4 ts=4 et tw=80