Ticket #6130: video_surfaces.diff
File video_surfaces.diff, 12.2 KB (added by , 15 years ago) |
---|
-
libs/libmythtv/util-vdpau.cpp
60 60 VDPAUContext::VDPAUContext() 61 61 : nextframedelay(0), lastframetime(0), 62 62 pix_fmt(-1), maxVideoWidth(0), maxVideoHeight(0), 63 videoSurfaces(0), surface_render(0), checkVideoSurfaces(8), 64 numSurfaces(0), 65 videoSurface(0), outputSurface(0), checkOutputSurfaces(false), 63 checkVideoSurfaces(8), 64 outputSurface(0), checkOutputSurfaces(false), 66 65 outputSize(QSize(0,0)), decoder(0), maxReferences(2), 67 66 videoMixer(0), surfaceNum(0), osdVideoSurface(0), 68 67 osdOutputSurface(0), osdVideoMixer(0), osdAlpha(0), … … 526 525 } 527 526 } 528 527 528 int VDPAUContext::AddBuffer(int width, int height) 529 { 530 VdpStatus vdp_st; 531 bool ok = true; 532 533 video_surface tmp; 534 tmp.surface = 0; 535 536 vdp_st = vdp_video_surface_create( 537 vdp_device, 538 vdp_chroma_type, 539 width, 540 height, 541 &(tmp.surface) 542 ); 543 CHECK_ST 544 545 if (!ok || !tmp.surface) 546 { 547 VERBOSE(VB_PLAYBACK, LOC_ERR + 548 QString("Failed to create video surface.")); 549 return -1; 550 } 551 552 if (vdpauDecode) 553 { 554 vdpau_render_state_t new_rend; 555 memset(&new_rend, 0, sizeof(vdpau_render_state_t)); 556 new_rend.magic = MP_VDPAU_RENDER_MAGIC; 557 new_rend.state = 0; 558 new_rend.surface = tmp.surface; 559 tmp.render = new_rend; 560 } 561 562 videoSurfaces.push_back(tmp); 563 return GetNumBufs() - 1; 564 } 565 529 566 bool VDPAUContext::InitBuffers(int width, int height, int numbufs) 530 567 { 531 568 int num_bufs = numbufs; … … 566 603 return false; 567 604 } 568 605 569 videoSurfaces = (VdpVideoSurface *)malloc(sizeof(VdpVideoSurface) * num_bufs);570 if (vdpauDecode)571 {572 surface_render = (vdpau_render_state_t*)malloc(sizeof(vdpau_render_state_t) * num_bufs);573 memset(surface_render, 0, sizeof(vdpau_render_state_t) * num_bufs);574 }575 576 numSurfaces = num_bufs;577 578 606 for (i = 0; i < num_bufs; i++) 579 607 { 580 vdp_st = vdp_video_surface_create( 581 vdp_device, 582 vdp_chroma_type, 583 width, 584 height, 585 &(videoSurfaces[i]) 586 ); 587 CHECK_ST 588 589 if (!ok) 608 int tmp = AddBuffer(width, height); 609 if (tmp != i) 590 610 { 591 VERBOSE(VB_PLAYBACK, LOC_ERR + 592 QString("Failed to create video surface.")); 611 VERBOSE(VB_IMPORTANT, LOC + 612 QString("Failed to add buffer %1 of %2") 613 .arg(i+1).arg(num_bufs)); 593 614 return false; 594 615 } 595 596 if (vdpauDecode)597 {598 surface_render[i].magic = MP_VDPAU_RENDER_MAGIC;599 surface_render[i].state = 0;600 surface_render[i].surface = videoSurfaces[i];601 }602 616 } 603 617 604 618 // clear video surfaces to black … … 622 636 for (i = 0; i < num_bufs; i++) 623 637 { 624 638 vdp_video_surface_put_bits_y_cb_cr( 625 videoSurfaces[i] ,639 videoSurfaces[i].surface, 626 640 VDP_YCBCR_FORMAT_YV12, 627 641 planes, 628 642 pitches … … 712 726 CHECK_ST 713 727 } 714 728 715 if (videoSurfaces )729 if (videoSurfaces.size()) 716 730 { 717 for (i = 0; i < numSurfaces; i++)731 for (i = 0; i < GetNumBufs(); i++) 718 732 { 719 if (videoSurfaces[i] )733 if (videoSurfaces[i].surface) 720 734 { 721 735 vdp_st = vdp_video_surface_destroy( 722 videoSurfaces[i] );736 videoSurfaces[i].surface); 723 737 CHECK_ST 724 738 } 725 739 } 726 free(videoSurfaces); 727 videoSurfaces = NULL; 740 videoSurfaces.clear(); 728 741 } 729 730 if (surface_render) 731 free(surface_render); 732 surface_render = NULL; 742 checkVideoSurfaces = 8; 733 743 } 734 744 735 745 bool VDPAUContext::InitOutput(QSize size) … … 904 914 CHECK_ST 905 915 } 906 916 907 voidVDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect,917 int VDPAUContext::PrepareVideo(VideoFrame *frame, QRect video_rect, 908 918 QRect display_video_rect, 909 919 QSize screen_size, FrameScanType scan, 910 920 bool pause_frame) 911 921 { 922 int ret = (maxReferences + (deinterlacing ? 5 : 3)) - GetNumBufs(); 923 if (ret < 0 || !vdpauDecode || (checkVideoSurfaces != 1)) 924 ret = 0; 925 912 926 if (checkVideoSurfaces == 1) 913 927 checkOutputSurfaces = true; 914 928 … … 919 933 bool ok = true; 920 934 VdpTime dummy; 921 935 vdpau_render_state_t *render; 936 VdpVideoSurface video_surface = 0; 922 937 923 938 bool new_frame = true; 924 939 bool deint = (deinterlacing && needDeintRefs && !pause_frame); … … 933 948 { 934 949 render = (vdpau_render_state_t *)frame->buf; 935 950 if (!render) 936 return ;951 return ret; 937 952 938 video Surface = render->surface;953 video_surface = render->surface; 939 954 } 940 955 else if (new_frame && frame) 941 956 { … … 943 958 if (deint) 944 959 surf = (currentFrameNum + 1) % NUM_REFERENCE_FRAMES; 945 960 946 video Surface = videoSurfaces[surf];961 video_surface = videoSurfaces[surf].surface; 947 962 948 963 uint32_t pitches[3] = { 949 964 frame->pitches[0], … … 956 971 frame->buf + frame->offsets[1] 957 972 }; 958 973 vdp_st = vdp_video_surface_put_bits_y_cb_cr( 959 video Surface,974 video_surface, 960 975 VDP_YCBCR_FORMAT_YV12, 961 976 planes, 962 977 pitches); 963 978 CHECK_ST; 964 979 if (!ok) 965 return ;980 return ret; 966 981 } 967 982 else if (!frame) 968 983 { 969 984 deint = false; 970 if (!video Surface)971 video Surface = videoSurfaces[0];985 if (!video_surface) 986 video_surface = videoSurfaces[0].surface; 972 987 } 973 988 974 989 if (outRect.x1 != (uint)screen_size.width() || … … 1052 1067 int ref = (currentFrameNum + i - 1) % NUM_REFERENCE_FRAMES; 1053 1068 if (ref < 0) 1054 1069 ref = 0; 1055 refs[i] = videoSurfaces[ref] ;1070 refs[i] = videoSurfaces[ref].surface; 1056 1071 } 1057 1072 } 1058 1073 1059 video Surface = refs[1];1074 video_surface = refs[1]; 1060 1075 1061 1076 if (scan == kScan_Interlaced) 1062 1077 { … … 1104 1119 field, 1105 1120 deint ? ARSIZE(past_surfaces) : 0, 1106 1121 deint ? past_surfaces : NULL, 1107 video Surface,1122 video_surface, 1108 1123 deint ? ARSIZE(future_surfaces) : 0, 1109 1124 deint ? future_surfaces : NULL, 1110 1125 &srcRect, … … 1119 1134 if (pipReady) 1120 1135 pipReady--; 1121 1136 pipNeedsClear = true; 1137 1138 return ret; 1122 1139 } 1123 1140 1124 1141 void VDPAUContext::DisplayNextFrame(void) … … 1830 1847 VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME, 1831 1848 0, 1832 1849 NULL, 1833 videoSurfaces[0] ,1850 videoSurfaces[0].surface, 1834 1851 0, 1835 1852 NULL, 1836 1853 &srcRect, -
libs/libmythtv/util-vdpau.h
13 13 VdpVideoSurface videoSurface; 14 14 VdpVideoMixer videoMixer; 15 15 }; 16 17 struct video_surface 18 { 19 VdpVideoSurface surface; 20 vdpau_render_state_t render; 21 }; 22 16 23 class NuppelVideoPlayer; 17 24 18 25 class VDPAUContext … … 28 35 bool IsErrored(void) { return errored; } 29 36 30 37 bool InitBuffers(int width, int height, int numbufs); 38 int AddBuffer(int width, int height); 31 39 void FreeBuffers(void); 32 void *GetRenderData(int i) 33 { if (i < numSurfaces && i >= 0) return (void*)&(surface_render[i]);40 void *GetRenderData(int i) 41 { if (i < GetNumBufs() && i >= 0) return (void*)&(videoSurfaces[i].render); 34 42 return NULL; 35 43 } 36 int GetNumBufs(void) { return numSurfaces; }44 int GetNumBufs(void) { return videoSurfaces.size(); } 37 45 38 46 bool InitOutput(QSize size); 39 47 void FreeOutput(void); 40 48 41 49 void Decode(VideoFrame *frame); 42 50 43 voidPrepareVideo(VideoFrame *frame, QRect video_rect,51 int PrepareVideo(VideoFrame *frame, QRect video_rect, 44 52 QRect display_video_rect, 45 53 QSize screen_size, FrameScanType scan, 46 54 bool pause_frame); … … 93 101 94 102 uint maxVideoWidth; 95 103 uint maxVideoHeight; 96 VdpVideoSurface *videoSurfaces; 97 vdpau_render_state_t *surface_render; 104 vector<video_surface> videoSurfaces; 98 105 int checkVideoSurfaces; 99 int numSurfaces;100 106 101 107 vector<VdpOutputSurface> outputSurfaces; 102 VdpVideoSurface videoSurface;103 108 VdpOutputSurface outputSurface; 104 109 bool checkOutputSurfaces; 105 110 QSize outputSize; -
libs/libmythtv/videoout_xv.cpp
84 84 #define XVMC_CHROMA_FORMAT_420 0x00000001 85 85 #endif 86 86 87 #define NUM_VDPAU_BUFFERS 1787 #define NUM_VDPAU_BUFFERS 6 88 88 89 89 static QStringList allowed_video_renderers( 90 90 MythCodecID codec_id, Display *display, int screen, Window curwin); … … 3127 3127 if (!vdpau) 3128 3128 return; 3129 3129 3130 vdpau->PrepareVideo(3130 int extra_bufs = vdpau->PrepareVideo( 3131 3131 frame, windows[0].GetVideoRect(), windows[0].GetDisplayVideoRect(), 3132 3132 windows[0].GetDisplayVisibleRect().size(), scan, pause); 3133 3133 3134 if (extra_bufs) 3135 { 3136 vbuffers.begin_lock(kVideoBuffer_avail); 3137 QSize vid_dim = windows[0].GetVideoDim(); 3138 vbuffers.Add(vid_dim.width(), vid_dim.height(), vdpau, extra_bufs); 3139 vbuffers.end_lock(); 3140 } 3141 3134 3142 #endif 3135 3143 3136 3144 if (pause) -
libs/libmythtv/videobuffers.h
165 165 166 166 #ifdef USING_VDPAU 167 167 bool CreateBuffers(int width, int height, VDPAUContext *ctx); 168 void Add(int width, int height, VDPAUContext *ctx, int num); 168 169 #endif 169 170 170 171 QString GetStatus(int n=-1) const; // debugging method -
libs/libmythtv/videobuffers.cpp
1164 1164 } 1165 1165 1166 1166 #ifdef USING_VDPAU 1167 static unsigned char *ffmpeg_vdpau_hack = (unsigned char*) 1168 "avlib should not use this private data in VDPAU mode."; 1169 1167 1170 bool VideoBuffers::CreateBuffers(int width, int height, VDPAUContext *ctx) 1168 1171 { 1169 static unsigned char *ffmpeg_vdpau_hack = (unsigned char*)1170 "avlib should not use this private data in VDPAU mode.";1171 1172 1172 if (!ctx) 1173 1173 return false; 1174 1174 … … 1191 1191 } 1192 1192 return true; 1193 1193 } 1194 1195 void VideoBuffers::Add(int width, int height, VDPAUContext *ctx, int num) 1196 { 1197 if (!ctx) 1198 return; 1199 1200 int cnt = 0; 1201 QMutexLocker locker(&global_lock); 1202 1203 for (int i =0; i < num; i++) 1204 { 1205 int new_surf = ctx->AddBuffer(width, height); 1206 if (new_surf > 0) 1207 { 1208 int ref = allocSize(); 1209 if (ref != new_surf) 1210 { 1211 VERBOSE(VB_PLAYBACK, QString("VideoBuffers::Add - ") + 1212 QString("mis-match between VideoBuffers and VDPAU.")); 1213 continue; 1214 } 1215 VideoFrame tmp; 1216 memset(&tmp, 0, sizeof(VideoFrame)); 1217 buffers.push_back(tmp); 1218 init(&buffers[ref], FMT_VDPAU, (unsigned char*)ctx->GetRenderData(new_surf), width, height, -1, 0); 1219 vbufferMap[at(ref)] = ref; 1220 numbuffers = allocSize(); 1221 buffers[ref].priv[0] = ffmpeg_vdpau_hack; 1222 buffers[ref].priv[1] = ffmpeg_vdpau_hack; 1223 enqueue(kVideoBuffer_avail, at(ref)); 1224 cnt++; 1225 } 1226 else 1227 { 1228 continue; 1229 } 1230 } 1231 VERBOSE(VB_PLAYBACK, 1232 QString("Added %1 VDPAU video buffer(s) (%2 requested).") 1233 .arg(cnt).arg(num)); 1234 return; 1235 } 1194 1236 #endif 1195 1237 1196 1238 #ifdef USING_XVMC