static int bgr_deliver(const frame_info_t *fi, glw_video_t *gv, glw_video_engine_t *gve) { glw_video_surface_t *s; int64_t pts = fi->fi_pts; int wvec[3] = {0}; int hvec[3] = {0}; wvec[0] = fi->fi_width; hvec[0] = fi->fi_height; glw_video_configure(gv, gve); if((s = glw_video_get_surface(gv, wvec, hvec)) == NULL) return -1; int linesize = LINESIZE(fi->fi_width, 3); const uint8_t *src = fi->fi_data[0]; uint8_t *dst = s->gvs_data[0]; for(int y = 0; y < fi->fi_height; y++) { memcpy(dst, src, linesize); src += fi->fi_pitch[0]; dst += linesize; } glw_video_put_surface(gv, s, pts, fi->fi_epoch, fi->fi_duration, 0, 0); return 0; }
static int rvd_set_codec(media_codec_t *mc, glw_video_t *gv, const frame_info_t *fi) { media_pipe_t *mp = gv->gv_mp; glw_video_configure(gv, &glw_video_rvd); gv->gv_width = fi->fi_width; gv->gv_height = fi->fi_height; rpi_video_display_t *rvd = gv->gv_aux; rpi_video_codec_t *rvc = mc->opaque; if(rvd->rvd_vrender == NULL) { rvd->rvd_vrender = omx_component_create("OMX.broadcom.video_render", &rvd->rvd_mutex, NULL); rvd->rvd_vsched = omx_component_create("OMX.broadcom.video_scheduler", &rvd->rvd_mutex, NULL); rvd->rvd_vsched->oc_opaque = rvd; rvd->rvd_vrender->oc_opaque = rvd; gv->gv_vd->vd_render_component = rvd->rvd_vrender; omx_enable_buffer_marks(rvd->rvd_vrender); rvd->rvd_tun_clock_vsched = omx_tunnel_create(omx_get_clock(mp), 81, rvd->rvd_vsched, 12, "clock -> vsched"); rvd->rvd_vsched->oc_port_settings_changed_cb = vsched_port_settings_changed; rvd->rvd_vrender->oc_event_mark_cb = buffer_mark; } omx_set_state(rvd->rvd_vrender, OMX_StateIdle); if(rvd->rvd_tun_vdecoder_vsched != NULL) omx_tunnel_destroy(rvd->rvd_tun_vdecoder_vsched); if(rvd->rvd_mc != NULL) media_codec_deref(rvd->rvd_mc); rvd->rvd_mc = media_codec_ref(mc); rvd->rvd_tun_vdecoder_vsched = omx_tunnel_create(rvc->rvc_decoder, 131, rvd->rvd_vsched, 10, "vdecoder -> vsched"); omx_set_state(rvd->rvd_vsched, OMX_StateExecuting); return 0; }
static int rsx_deliver(const frame_info_t *fi, glw_video_t *gv, glw_video_engine_t *gve) { int hvec[3], wvec[3]; int i; int hshift = 1, vshift = 1; glw_video_surface_t *gvs; wvec[0] = fi->fi_width; wvec[1] = fi->fi_width >> hshift; wvec[2] = fi->fi_width >> hshift; hvec[0] = fi->fi_height >> fi->fi_interlaced; hvec[1] = fi->fi_height >> (vshift + fi->fi_interlaced); hvec[2] = fi->fi_height >> (vshift + fi->fi_interlaced); glw_video_configure(gv, gve); gv_color_matrix_set(gv, fi); if((gvs = glw_video_get_surface(gv, NULL, NULL)) == NULL) return -1; surface_reset(gv, gvs); gvs->gvs_offset = fi->fi_pitch[0]; gvs->gvs_size = fi->fi_pitch[1]; gvs->gvs_width[0] = fi->fi_width; gvs->gvs_height[0] = fi->fi_height; int offset = gvs->gvs_offset; if(fi->fi_interlaced) { // Interlaced for(i = 0; i < 3; i++) { int w = wvec[i]; int h = hvec[i]; init_tex(&gvs->gvs_tex[i], offset + !fi->fi_tff * wvec[i], w, h, w*2, NV30_3D_TEX_FORMAT_FORMAT_I8, 0, NV30_3D_TEX_SWIZZLE_S0_X_S1 | NV30_3D_TEX_SWIZZLE_S0_Y_S1 | NV30_3D_TEX_SWIZZLE_S0_Z_S1 | NV30_3D_TEX_SWIZZLE_S0_W_S1 | NV30_3D_TEX_SWIZZLE_S1_X_X | NV30_3D_TEX_SWIZZLE_S1_Y_Y | NV30_3D_TEX_SWIZZLE_S1_Z_Z | NV30_3D_TEX_SWIZZLE_S1_W_W ); offset += w * (fi->fi_height >> (i ? vshift : 0)); } glw_video_put_surface(gv, gvs, fi->fi_pts, fi->fi_epoch, fi->fi_duration/2, 1, !fi->fi_tff); if((gvs = glw_video_get_surface(gv, NULL, NULL)) == NULL) return -1; surface_reset(gv, gvs); gvs->gvs_offset = fi->fi_pitch[0]; gvs->gvs_size = fi->fi_pitch[1]; gvs->gvs_width[0] = fi->fi_width; gvs->gvs_height[0] = fi->fi_height; offset = gvs->gvs_offset; for(i = 0; i < 3; i++) { int w = wvec[i]; int h = hvec[i]; init_tex(&gvs->gvs_tex[i], offset + !!fi->fi_tff * wvec[i], w, h, w*2, NV30_3D_TEX_FORMAT_FORMAT_I8, 0, NV30_3D_TEX_SWIZZLE_S0_X_S1 | NV30_3D_TEX_SWIZZLE_S0_Y_S1 | NV30_3D_TEX_SWIZZLE_S0_Z_S1 | NV30_3D_TEX_SWIZZLE_S0_W_S1 | NV30_3D_TEX_SWIZZLE_S1_X_X | NV30_3D_TEX_SWIZZLE_S1_Y_Y | NV30_3D_TEX_SWIZZLE_S1_Z_Z | NV30_3D_TEX_SWIZZLE_S1_W_W ); offset += w * (fi->fi_height >> (i ? vshift : 0)); } glw_video_put_surface(gv, gvs, fi->fi_pts + fi->fi_duration, fi->fi_epoch, fi->fi_duration/2, 1, fi->fi_tff); } else { // Progressive for(i = 0; i < 3; i++) {
static int yuvp_deliver(const frame_info_t *fi, glw_video_t *gv, glw_video_engine_t *gve) { int hvec[3], wvec[3]; int i, h, w; const uint8_t *src; uint8_t *dst; int tff; int hshift = fi->fi_hshift, vshift = fi->fi_vshift; glw_video_surface_t *s; const int parity = 0; wvec[0] = fi->fi_width; wvec[1] = fi->fi_width >> hshift; wvec[2] = fi->fi_width >> hshift; hvec[0] = fi->fi_height >> fi->fi_interlaced; hvec[1] = fi->fi_height >> (vshift + fi->fi_interlaced); hvec[2] = fi->fi_height >> (vshift + fi->fi_interlaced); glw_video_configure(gv, gve); gv_color_matrix_set(gv, fi); if((s = glw_video_get_surface(gv, wvec, hvec)) == NULL) return -1; if(!fi->fi_interlaced) { for(i = 0; i < 3; i++) { w = wvec[i]; h = hvec[i]; src = fi->fi_data[i]; dst = s->gvs_data[i]; while(h--) { memcpy(dst, src, w); dst += w; src += fi->fi_pitch[i]; } } glw_video_put_surface(gv, s, fi->fi_pts, fi->fi_epoch, fi->fi_duration, 0, 0); } else { int duration = fi->fi_duration >> 1; tff = fi->fi_tff ^ parity; for(i = 0; i < 3; i++) { w = wvec[i]; h = hvec[i]; src = fi->fi_data[i]; dst = s->gvs_data[i]; while(h--) { memcpy(dst, src, w); dst += w; src += fi->fi_pitch[i] * 2; } } glw_video_put_surface(gv, s, fi->fi_pts, fi->fi_epoch, duration, 1, !tff); if((s = glw_video_get_surface(gv, wvec, hvec)) == NULL) return -1; for(i = 0; i < 3; i++) { w = wvec[i]; h = hvec[i]; src = fi->fi_data[i] + fi->fi_pitch[i]; dst = s->gvs_data[i]; while(h--) { memcpy(dst, src, w); dst += w; src += fi->fi_pitch[i] * 2; } } glw_video_put_surface(gv, s, fi->fi_pts + duration, fi->fi_epoch, duration, 1, tff); } return 0; }
static int gvv_deliver(const frame_info_t *fi, glw_video_t *gv, glw_video_engine_t *gve) { vdpau_dev_t *vd = gv->w.glw_root->gr_be.gbr_vdpau_dev; glw_video_surface_t *s; VdpRect src_rect = { 0, 0, fi->fi_width, fi->fi_height }; int hvec[3], wvec[3]; wvec[0] = fi->fi_width; wvec[1] = 0; wvec[2] = 0; hvec[0] = fi->fi_height; hvec[1] = 0; hvec[2] = 0; VdpRect dst_rect = { 0, 0, fi->fi_width, fi->fi_height }; if(glw_video_configure(gv, gve)) return -1; glw_video_vdpau_t *gvv = gv->gv_aux; vdpau_mixer_t *vm = &gvv->gvv_vm; gv->gv_cmatrix_tgt[0] = 1.0f; /* Video mixer */ if(vm->vm_width != fi->fi_width || vm->vm_height != fi->fi_height) { VdpStatus st; vdpau_mixer_deinit(vm); st = vdpau_mixer_create(vd, vm, fi->fi_width, fi->fi_height); if(st != VDP_STATUS_OK) { TRACE(TRACE_ERROR, "VDPAU", "Unable to create video mixer"); return -1; } } if((s = glw_video_get_surface(gv, wvec, hvec)) == NULL) return -1; s->gvs_width[0] = fi->fi_width; s->gvs_height[0] = fi->fi_height; vdpau_mixer_set_color_matrix(vm, fi); if(fi->fi_interlaced) { int duration = fi->fi_duration >> 1; if(video_settings.vdpau_deinterlace_resolution_limit > 0 && fi->fi_height > video_settings.vdpau_deinterlace_resolution_limit) vdpau_mixer_set_deinterlacer(vm, 0); else vdpau_mixer_set_deinterlacer(vm, video_settings.vdpau_deinterlace); if(vm->vm_surfaces[3] != NULL) av_frame_unref(vm->vm_surfaces[3]); vm->vm_surfaces[3] = vm->vm_surfaces[2]; vm->vm_surfaces[2] = vm->vm_surfaces[1]; vm->vm_surfaces[1] = vm->vm_surfaces[0]; vm->vm_surfaces[0] = av_frame_clone(fi->fi_avframe); VdpVideoSurface past[2], present, future; past[1] = frame_to_surface(vm->vm_surfaces[3]); past[0] = frame_to_surface(vm->vm_surfaces[2]); present = frame_to_surface(vm->vm_surfaces[1]); future = frame_to_surface(vm->vm_surfaces[0]); vd->vdp_video_mixer_render(vm->vm_mixer, VDP_INVALID_HANDLE, NULL, !fi->fi_tff, 2, past, present, 1, &future, &src_rect, s->gvs_vdpau_surface, &dst_rect, &dst_rect, 0, NULL); glw_video_put_surface(gv, s, fi->fi_pts - duration, fi->fi_epoch, duration, 0, 0); if((s = glw_video_get_surface(gv, wvec, hvec)) == NULL) return -1; s->gvs_width[0] = fi->fi_width; s->gvs_height[0] = fi->fi_height; vd->vdp_video_mixer_render(vm->vm_mixer, VDP_INVALID_HANDLE, NULL, fi->fi_tff, 2, past, present, 1, &future, &src_rect, s->gvs_vdpau_surface, &dst_rect, &dst_rect, 0, NULL); } else {
void glw_video_input_vdpau(glw_video_t *gv, uint8_t * const data[], const int pitch[], const frame_info_t *fi) { struct vdpau_render_state *rs = (struct vdpau_render_state *)data[0]; vdpau_dev_t *vd = gv->w.glw_root->gr_be.gbr_vdpau_dev; vdpau_mixer_t *vm = &gv->gv_vm; glw_video_surface_t *s; int wvec[3] = {fi->fi_width}; int hvec[3] = {fi->fi_height}; VdpRect src_rect = { 0, 0, fi->fi_width, fi->fi_height }; #if 0 VdpRect dst_rect = { 0, 0, gv->gv_rwidth ?: fi->fi_width, gv->gv_rheight ?: fi->fi_height }; #else VdpRect dst_rect = { 0, 0, fi->fi_width, fi->fi_height }; #endif if(glw_video_configure(gv, &glw_video_vdpau, wvec, hvec, 4, 0)) return; if((s = glw_video_get_surface(gv)) == NULL) return; s->gvs_width = fi->fi_width; s->gvs_height = fi->fi_height; vdpau_mixer_set_color_matrix(vm, fi); if(fi->fi_interlaced) { int duration = fi->fi_duration >> 1; if(video_settings.vdpau_deinterlace_resolution_limit > 0 && fi->fi_height > video_settings.vdpau_deinterlace_resolution_limit) vdpau_mixer_set_deinterlacer(vm, 0); else vdpau_mixer_set_deinterlacer(vm, video_settings.vdpau_deinterlace); vm->vm_surface_win[3] = vm->vm_surface_win[2]; vm->vm_surface_win[2] = vm->vm_surface_win[1]; vm->vm_surface_win[1] = vm->vm_surface_win[0]; vm->vm_surface_win[0] = rs->surface; vd->vdp_video_mixer_render(vm->vm_mixer, VDP_INVALID_HANDLE, NULL, !fi->fi_tff, 2, &vm->vm_surface_win[2], vm->vm_surface_win[1], 1, &vm->vm_surface_win[0], &src_rect, s->gvs_vdpau_surface, &dst_rect, &dst_rect, 0, NULL); glw_video_put_surface(gv, s, fi->fi_pts - duration, fi->fi_epoch, duration, 0); if((s = glw_video_get_surface(gv)) == NULL) return; s->gvs_width = fi->fi_width; s->gvs_height = fi->fi_height; vd->vdp_video_mixer_render(vm->vm_mixer, VDP_INVALID_HANDLE, NULL, fi->fi_tff, 2, &vm->vm_surface_win[2], vm->vm_surface_win[1], 1, &vm->vm_surface_win[0], &src_rect, s->gvs_vdpau_surface, &dst_rect, &dst_rect, 0, NULL); } else {
void glw_video_input_yuvp(glw_video_t *gv, uint8_t * const data[], const int pitch[], const frame_info_t *fi) { int hvec[3], wvec[3]; int i, h, w; uint8_t *src; uint8_t *dst; int tff; int hshift, vshift; glw_video_surface_t *s; const int parity = 0; int64_t pts = fi->pts; avcodec_get_chroma_sub_sample(fi->pix_fmt, &hshift, &vshift); wvec[0] = fi->width; wvec[1] = fi->width >> hshift; wvec[2] = fi->width >> hshift; hvec[0] = fi->height >> fi->interlaced; hvec[1] = fi->height >> (vshift + fi->interlaced); hvec[2] = fi->height >> (vshift + fi->interlaced); if(glw_video_configure(gv, &glw_video_opengl, wvec, hvec, 3, fi->interlaced ? (GVC_YHALF | GVC_CUTBORDER) : 0)) return; gv_color_matrix_set(gv, fi); if((s = glw_video_get_surface(gv)) == NULL) return; if(!fi->interlaced) { for(i = 0; i < 3; i++) { w = wvec[i]; h = hvec[i]; src = data[i]; dst = s->gvs_data[i]; while(h--) { memcpy(dst, src, w); dst += w; src += pitch[i]; } } glw_video_put_surface(gv, s, pts, fi->epoch, fi->duration, 0); } else { int duration = fi->duration >> 1; tff = fi->tff ^ parity; for(i = 0; i < 3; i++) { w = wvec[i]; h = hvec[i]; src = data[i]; dst = s->gvs_data[i]; while(h -= 2 > 0) { memcpy(dst, src, w); dst += w; src += pitch[i] * 2; } } glw_video_put_surface(gv, s, pts, fi->epoch, duration, !tff); if((s = glw_video_get_surface(gv)) == NULL) return; for(i = 0; i < 3; i++) { w = wvec[i]; h = hvec[i]; src = data[i] + pitch[i]; dst = s->gvs_data[i]; while(h -= 2 > 0) { memcpy(dst, src, w); dst += w; src += pitch[i] * 2; } } if(pts != AV_NOPTS_VALUE) pts += duration; glw_video_put_surface(gv, s, pts, fi->epoch, duration, tff); } }
void glw_video_input_rsx_mem(glw_video_t *gv, void *frame, const frame_info_t *fi) { rsx_video_frame_t *rvf = frame; int hvec[3], wvec[3]; int i; int hshift, vshift; glw_video_surface_t *gvs; avcodec_get_chroma_sub_sample(fi->fi_pix_fmt, &hshift, &vshift); wvec[0] = fi->fi_width; wvec[1] = fi->fi_width >> hshift; wvec[2] = fi->fi_width >> hshift; hvec[0] = fi->fi_height >> fi->fi_interlaced; hvec[1] = fi->fi_height >> (vshift + fi->fi_interlaced); hvec[2] = fi->fi_height >> (vshift + fi->fi_interlaced); if(glw_video_configure(gv, &glw_video_rsxmem, wvec, hvec, 3, fi->fi_interlaced ? (GVC_YHALF | GVC_CUTBORDER) : 0)) return; gv_color_matrix_set(gv, fi); if((gvs = glw_video_get_surface(gv)) == NULL) return; surface_reset(gv, gvs); gvs->gvs_size = rvf->rvf_size; gvs->gvs_offset = rvf->rvf_offset; int offset = gvs->gvs_offset; if(fi->fi_interlaced) { // Interlaced for(i = 0; i < 3; i++) { int w = wvec[i]; int h = hvec[i]; init_tex(&gvs->gvs_tex[i], offset + !fi->fi_tff * wvec[i], w, h, w*2, NV30_3D_TEX_FORMAT_FORMAT_I8, 0, NV30_3D_TEX_SWIZZLE_S0_X_S1 | NV30_3D_TEX_SWIZZLE_S0_Y_S1 | NV30_3D_TEX_SWIZZLE_S0_Z_S1 | NV30_3D_TEX_SWIZZLE_S0_W_S1 | NV30_3D_TEX_SWIZZLE_S1_X_X | NV30_3D_TEX_SWIZZLE_S1_Y_Y | NV30_3D_TEX_SWIZZLE_S1_Z_Z | NV30_3D_TEX_SWIZZLE_S1_W_W ); offset += w * (fi->fi_height >> (i ? vshift : 0)); } glw_video_put_surface(gv, gvs, fi->fi_pts, fi->fi_epoch, fi->fi_duration/2, 0); if((gvs = glw_video_get_surface(gv)) == NULL) return; surface_reset(gv, gvs); gvs->gvs_size = rvf->rvf_size; gvs->gvs_offset = rvf->rvf_offset; offset = gvs->gvs_offset; for(i = 0; i < 3; i++) { int w = wvec[i]; int h = hvec[i]; init_tex(&gvs->gvs_tex[i], offset + !!fi->fi_tff * wvec[i], w, h, w*2, NV30_3D_TEX_FORMAT_FORMAT_I8, 0, NV30_3D_TEX_SWIZZLE_S0_X_S1 | NV30_3D_TEX_SWIZZLE_S0_Y_S1 | NV30_3D_TEX_SWIZZLE_S0_Z_S1 | NV30_3D_TEX_SWIZZLE_S0_W_S1 | NV30_3D_TEX_SWIZZLE_S1_X_X | NV30_3D_TEX_SWIZZLE_S1_Y_Y | NV30_3D_TEX_SWIZZLE_S1_Z_Z | NV30_3D_TEX_SWIZZLE_S1_W_W ); offset += w * (fi->fi_height >> (i ? vshift : 0)); } glw_video_put_surface(gv, gvs, fi->fi_pts + fi->fi_duration, fi->fi_epoch, fi->fi_duration/2, 0); } else { // Progressive for(i = 0; i < 3; i++) {