Ticket #2171: 2171-v2.patch
File 2171-v2.patch, 16.5 KB (added by , 18 years ago) |
---|
-
libs/libmythtv/avformatdecoder.cpp
1516 1516 1517 1517 VideoFrame *frame = nd->GetNVP()->GetNextVideoFrame(true); 1518 1518 1519 int width = frame->width; 1520 int height = frame->height; 1519 for (int i = 0; i < 3; i++) 1520 { 1521 pic->data[i] = frame->buf + frame->offsets[i]; 1522 pic->linesize[i] = frame->pitches[i]; 1523 } 1521 1524 1522 pic->data[0] = frame->buf;1523 pic->data[1] = pic->data[0] + width * height;1524 pic->data[2] = pic->data[1] + width * height / 4;1525 1526 pic->linesize[0] = width;1527 pic->linesize[1] = width / 2;1528 pic->linesize[2] = width / 2;1529 1530 1525 pic->opaque = frame; 1531 1526 pic->type = FF_BUFFER_TYPE_USER; 1532 1527 -
libs/libmythtv/util-xv.cpp
80 80 str.append("XvImageMask "); 81 81 return str; 82 82 } 83 84 void clear_xv_buffers(VideoBuffers &vbuffers,85 int width, int height, int xv_chroma)86 {87 if ((GUID_I420_PLANAR == xv_chroma) ||88 (GUID_YV12_PLANAR == xv_chroma))89 {90 for (uint i = 0; i < vbuffers.allocSize(); i++)91 {92 unsigned char *data = vbuffers.at(i)->buf;93 bzero(data, width * height);94 memset(data + width * height, 127,95 width * height / 2);96 }97 }98 } -
libs/libmythtv/frame.h
37 37 int top_field_first; // 1 if top field is first. 38 38 int repeat_pict; 39 39 int forcekey; // hardware encoded .nuv 40 41 int pitches[3]; // Y, U, & V pitches 42 int offsets[3]; // Y, U, & V offsets 40 43 } VideoFrame; 41 44 42 45 #endif -
libs/libmythtv/util-xv.h
28 28 extern bool has_open_xv_port(int port); 29 29 extern uint cnt_open_xv_port(void); 30 30 extern QString xvflags2str(int flags); 31 extern void clear_xv_buffers(VideoBuffers&, int w, int h, int xv_chroma);32 31 33 32 #endif // _UTIL_XV_H_ -
libs/libmythtv/videoout_xv.h
187 187 188 188 // Used for all non-XvMC drawing 189 189 VideoFrame av_pause_frame; 190 vector<XShmSegmentInfo> XJ_shm_infos; 190 vector<XShmSegmentInfo*> XJ_shm_infos; 191 vector<YUVInfo> XJ_yuv_infos; 191 192 192 193 // Basic non-Xv drawing info 193 194 XImage *XJ_non_xv_image; -
libs/libmythtv/videoout_xv.cpp
199 199 if (!res_changed && !cid_changed) 200 200 { 201 201 if (VideoOutputSubType() == XVideo) 202 clear_xv_buffers(vbuffers, video_dim.width(), video_dim.height(), 203 xv_chroma); 202 vbuffers.Clear(xv_chroma); 204 203 if (asp_changed) 205 204 MoveResize(); 206 205 return; … … 1500 1499 .arg(num).arg(video_dim.width()).arg(video_dim.height())); 1501 1500 1502 1501 vector<unsigned char*> bufs; 1503 XShmSegmentInfo blank;1504 // for now make reserve big enough to avoid realloc..1505 // we should really have vector of pointers...1506 XJ_shm_infos.reserve(max(num + 32, (uint)128));1507 1502 for (uint i = 0; i < num; i++) 1508 1503 { 1509 X J_shm_infos.push_back(blank);1504 XShmSegmentInfo *info = new XShmSegmentInfo; 1510 1505 void *image = NULL; 1511 1506 int size = 0; 1512 1507 int desiredsize = 0; … … 1515 1510 1516 1511 if (use_xv) 1517 1512 { 1518 image = XvShmCreateImage(XJ_disp, xv_port, xv_chroma, 0, 1519 video_dim.width(), video_dim.height(), 1520 &XJ_shm_infos[i]); 1521 size = ((XvImage*)image)->data_size + 64; 1513 XvImage *img = 1514 XvShmCreateImage(XJ_disp, xv_port, xv_chroma, 0, 1515 video_dim.width(), video_dim.height(), info); 1516 size = img->data_size + 64; 1517 image = img; 1522 1518 desiredsize = video_dim.width() * video_dim.height() * 3 / 2; 1523 1519 1524 1520 if (image && size < desiredsize) … … 1528 1524 "requested size."); 1529 1525 XFree(image); 1530 1526 image = NULL; 1527 delete info; 1531 1528 } 1529 1530 if (image && (3 == img->num_planes)) 1531 { 1532 XJ_shm_infos.push_back(info); 1533 YUVInfo tmp(img->width, img->height, img->data_size, 1534 img->pitches, img->offsets); 1535 XJ_yuv_infos.push_back(tmp); 1536 } 1537 else if (image) 1538 { 1539 VERBOSE(VB_IMPORTANT, LOC_ERR + "CreateXvShmImages(): " 1540 "XvShmCreateImage() failed to create image " 1541 "with the correct number of pixel planes."); 1542 XFree(image); 1543 image = NULL; 1544 delete info; 1545 } 1532 1546 } 1533 1547 else 1534 1548 { 1535 1549 XImage *img = 1536 1550 XShmCreateImage(XJ_disp, DefaultVisual(XJ_disp, XJ_screen_num), 1537 XJ_depth, ZPixmap, 0, &XJ_shm_infos[i],1551 XJ_depth, ZPixmap, 0, info, 1538 1552 display_visible_rect.width(), 1539 1553 display_visible_rect.height()); 1540 1554 size = img->bytes_per_line * img->height + 64; … … 1548 1562 "requested size."); 1549 1563 XDestroyImage((XImage *)image); 1550 1564 image = NULL; 1565 delete info; 1551 1566 } 1567 1568 if (image) 1569 { 1570 YUVInfo tmp(img->width, img->height, 1571 img->bytes_per_line * img->height, NULL, NULL); 1572 XJ_yuv_infos.push_back(tmp); 1573 } 1552 1574 } 1553 1575 1554 1576 X11U; 1555 1577 1556 1578 if (image) 1557 1579 { 1558 XJ_shm_infos[i] .shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);1559 if (XJ_shm_infos[i] .shmid >= 0)1580 XJ_shm_infos[i]->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); 1581 if (XJ_shm_infos[i]->shmid >= 0) 1560 1582 { 1561 XJ_shm_infos[i] .shmaddr = (char*) shmat(XJ_shm_infos[i].shmid, 0, 0);1583 XJ_shm_infos[i]->shmaddr = (char*) shmat(XJ_shm_infos[i]->shmid, 0, 0); 1562 1584 if (use_xv) 1563 ((XvImage*)image)->data = XJ_shm_infos[i] .shmaddr;1585 ((XvImage*)image)->data = XJ_shm_infos[i]->shmaddr; 1564 1586 else 1565 ((XImage*)image)->data = XJ_shm_infos[i] .shmaddr;1566 xv_buffers[(unsigned char*) XJ_shm_infos[i] .shmaddr] = image;1567 XJ_shm_infos[i] .readOnly = False;1587 ((XImage*)image)->data = XJ_shm_infos[i]->shmaddr; 1588 xv_buffers[(unsigned char*) XJ_shm_infos[i]->shmaddr] = image; 1589 XJ_shm_infos[i]->readOnly = False; 1568 1590 1569 1591 X11L; 1570 XShmAttach(XJ_disp, &XJ_shm_infos[i]);1592 XShmAttach(XJ_disp, XJ_shm_infos[i]); 1571 1593 XSync(XJ_disp, False); // needed for FreeBSD? 1572 1594 X11U; 1573 1595 1574 1596 // Mark for delete immediately. 1575 1597 // It won't actually be removed until after we detach it. 1576 shmctl(XJ_shm_infos[i] .shmid, IPC_RMID, 0);1598 shmctl(XJ_shm_infos[i]->shmid, IPC_RMID, 0); 1577 1599 1578 bufs.push_back((unsigned char*) XJ_shm_infos[i] .shmaddr);1600 bufs.push_back((unsigned char*) XJ_shm_infos[i]->shmaddr); 1579 1601 } 1580 1602 else 1581 1603 { … … 1605 1627 vector<unsigned char*> bufs = 1606 1628 CreateShmImages(vbuffers.allocSize(), true); 1607 1629 ok = vbuffers.CreateBuffers( 1608 video_dim.width(), video_dim.height(), bufs );1630 video_dim.width(), video_dim.height(), bufs, XJ_yuv_infos); 1609 1631 1610 clear_xv_buffers(vbuffers, video_dim.width(), video_dim.height(),1611 xv_chroma);1612 1613 1632 X11S(XSync(XJ_disp, False)); 1614 1633 if (xv_chroma != GUID_I420_PLANAR) 1615 1634 xv_color_conv_buf = new unsigned char[ … … 1747 1766 } 1748 1767 } 1749 1768 1750 for (uint i =0; i<XJ_shm_infos.size(); ++i)1769 for (uint i = 0; i < XJ_shm_infos.size(); i++) 1751 1770 { 1752 X11S(XShmDetach(XJ_disp, &(XJ_shm_infos[i])));1771 X11S(XShmDetach(XJ_disp, XJ_shm_infos[i])); 1753 1772 XvImage *image = (XvImage*) 1754 xv_buffers[(unsigned char*) XJ_shm_infos[i].shmaddr];1773 xv_buffers[(unsigned char*) XJ_shm_infos[i]->shmaddr]; 1755 1774 if (image) 1756 1775 { 1757 1776 if ((XImage*)image == (XImage*)XJ_non_xv_image) … … 1759 1778 else 1760 1779 X11S(XFree(image)); 1761 1780 } 1762 if (XJ_shm_infos[i].shmaddr) 1763 shmdt(XJ_shm_infos[i].shmaddr); 1764 if (XJ_shm_infos[i].shmid > 0) 1765 shmctl(XJ_shm_infos[0].shmid, IPC_RMID, 0); 1781 if (XJ_shm_infos[i]->shmaddr) 1782 shmdt(XJ_shm_infos[i]->shmaddr); 1783 if (XJ_shm_infos[i]->shmid > 0) 1784 shmctl(XJ_shm_infos[i]->shmid, IPC_RMID, 0); 1785 delete XJ_shm_infos[i]; 1766 1786 } 1767 1787 XJ_shm_infos.clear(); 1768 1788 xv_buffers.clear(); … … 2050 2070 #endif // USING_XVMC 2051 2071 } 2052 2072 2073 static void convert_yv12_to_yuv420(VideoFrame *frame, 2074 unsigned char *tmp) 2075 { 2076 if (!tmp) 2077 return; 2078 unsigned char *plane1 = frame->buf + frame->offsets[1]; 2079 unsigned char *plane2 = frame->buf + frame->offsets[2]; 2080 uint uv_plane_size = (frame->width * frame->height) >> 2; 2081 2082 memcpy(tmp, plane1, uv_plane_size); 2083 memcpy(plane1, plane2, uv_plane_size); 2084 memcpy(plane2, tmp, uv_plane_size); 2085 } 2086 2053 2087 /** 2054 2088 * \fn VideoOutputXv::PrepareFrameXv(VideoFrame *frame) 2055 2089 * … … 2072 2106 if (image && (GUID_YV12_PLANAR == xv_chroma)) 2073 2107 { 2074 2108 vbuffers.LockFrame(frame, "PrepareFrameXv -- color conversion"); 2075 int width = frame->width; 2076 int height = frame->height; 2077 2078 memcpy(xv_color_conv_buf, (unsigned char *)image->data + 2079 (width * height), width * height / 4); 2080 memcpy((unsigned char *)image->data + (width * height), 2081 (unsigned char *)image->data + (width * height) * 5 / 4, 2082 width * height / 4); 2083 memcpy((unsigned char *)image->data + (width * height) * 5 / 4, 2084 xv_color_conv_buf, width * height / 4); 2109 convert_yv12_to_yuv420(frame, xv_color_conv_buf); 2085 2110 vbuffers.UnlockFrame(frame, "PrepareFrameXv -- color conversion"); 2086 2111 } 2087 2112 -
libs/libmythtv/videobuffers.h
44 44 kVideoBuffer_all = 0x0000001F, 45 45 }; 46 46 47 class YUVInfo 48 { 49 public: 50 YUVInfo(uint w, uint h, uint size, const int *p, const int *o); 51 void Clear(unsigned char *data) const; 52 53 public: 54 uint width; 55 uint height; 56 uint size; 57 uint pitches[3]; 58 uint offsets[3]; 59 }; 60 47 61 class VideoBuffers 48 62 { 49 63 public: … … 55 69 uint needprebuffer_small, uint keepprebuffer, 56 70 bool enable_frame_locking = false); 57 71 58 bool CreateBuffers(int width, int height, vector<unsigned char*> bufs); 72 bool CreateBuffers(int width, int height, 73 vector<unsigned char*> bufs, 74 vector<YUVInfo> yuvinfo); 59 75 bool CreateBuffers(int width, int height); 60 76 void DeleteBuffers(void); 61 77 … … 120 136 frame_queue_t Children(const VideoFrame *frame); 121 137 bool HasChildren(const VideoFrame *frame); 122 138 139 void Clear(uint i, int fourcc); 140 void Clear(int fourcc); 141 123 142 #ifdef USING_XVMC 124 143 VideoFrame* PastFrame(const VideoFrame *frame); 125 144 VideoFrame* FutureFrame(const VideoFrame *frame); -
libs/libmythtv/videobuffers.cpp
5 5 #include "mythcontext.h" 6 6 #include "videobuffers.h" 7 7 #include "../libavcodec/avcodec.h" 8 #include "util-xv.h" 8 9 9 10 #ifdef USING_XVMC 10 11 #include "videoout_xv.h" // for xvmc stuff … … 18 19 19 20 int next_dbg_str = 0; 20 21 22 YUVInfo::YUVInfo(uint w, uint h, uint sz, const int *p, const int *o) 23 : width(w), height(h), size(sz) 24 { 25 if (p) 26 { 27 memcpy(pitches, p, 3 * sizeof(int)); 28 } 29 else 30 { 31 pitches[0] = width; 32 pitches[1] = pitches[2] = width >> 1; 33 } 34 35 if (o) 36 { 37 memcpy(offsets, o, 3 * sizeof(int)); 38 } 39 else 40 { 41 offsets[0] = 0; 42 offsets[1] = width * height; 43 offsets[2] = offsets[1] + (offsets[1] >> 2); 44 } 45 } 46 21 47 /** 48 * \fn YUVInfo::Clear(unsigned char *data) const 49 * \brief Init YUV buffer to black 50 */ 51 void YUVInfo::Clear(unsigned char *data) const 52 { 53 uint ysize = width * height; 54 uint uvsize = ysize >> 2; 55 56 bzero( data + offsets[0], ysize); 57 memset(data + offsets[1], 127, uvsize); 58 memset(data + offsets[2], 127, uvsize); 59 } 60 61 62 /** 22 63 * \class VideoBuffers 23 64 * This class creates tracks the state of the buffers used by 24 65 * various VideoOutput derived classes. … … 1071 1112 bool VideoBuffers::CreateBuffers(int width, int height) 1072 1113 { 1073 1114 vector<unsigned char*> bufs; 1074 return CreateBuffers(width, height, bufs); 1115 vector<YUVInfo> yuvinfo; 1116 return CreateBuffers(width, height, bufs, yuvinfo); 1075 1117 } 1076 1118 1077 1119 bool VideoBuffers::CreateBuffers(int width, int height, 1078 vector<unsigned char*> bufs) 1120 vector<unsigned char*> bufs, 1121 vector<YUVInfo> yuvinfo) 1079 1122 { 1080 1123 bool ok = true; 1081 1124 uint bpp = 12 / 4; /* bits per pixel div common factor */ … … 1087 1130 uint adj_w = (width + 15) & ~0xF; 1088 1131 uint adj_h = (height + 15) & ~0xF; 1089 1132 uint buf_size = (adj_w * adj_h * bpp + 4/* to round up */) / bpb; 1133 1090 1134 while (bufs.size() < allocSize()) 1091 1135 { 1092 1136 unsigned char *data = (unsigned char*)av_malloc(buf_size + 64); 1093 1137 1094 // init buffers (y plane to 0, u/v planes to 127), 1095 // to prevent green screens.. 1096 bzero(data, width * height); 1097 memset(data + width * height, 127, width * height / 2); 1138 bufs.push_back(data); 1139 yuvinfo.push_back(YUVInfo(width, height, buf_size, NULL, NULL)); 1098 1140 1099 bufs.push_back(data);1100 1141 if (bufs.back()) 1101 1142 { 1102 1143 VERBOSE(VB_PLAYBACK, "Created data @" … … 1106 1147 else 1107 1148 ok = false; 1108 1149 } 1150 1109 1151 for (uint i = 0; i < allocSize(); i++) 1110 1152 { 1111 buffers[i].width = width; 1112 buffers[i].height = height; 1153 yuvinfo[i].Clear(bufs[i]); 1154 buffers[i].width = yuvinfo[i].width; 1155 buffers[i].height = yuvinfo[i].height; 1156 memcpy(buffers[i].pitches, yuvinfo[i].pitches, 3 * sizeof(int)); 1157 memcpy(buffers[i].offsets, yuvinfo[i].offsets, 3 * sizeof(int)); 1113 1158 buffers[i].bpp = 12; 1114 buffers[i].size = buf_size;1159 buffers[i].size = max(buf_size, yuvinfo[i].size); 1115 1160 buffers[i].codec = FMT_YV12; 1116 1161 buffers[i].qscale_table = NULL; 1117 1162 buffers[i].qstride = 0; 1118 1163 buffers[i].buf = bufs[i]; 1119 1164 ok &= (bufs[i] != NULL); 1120 1165 } 1166 1121 1167 return ok; 1122 1168 } 1123 1169 … … 1273 1319 return str; 1274 1320 } 1275 1321 1322 void VideoBuffers::Clear(uint i, int fourcc) 1323 { 1324 if ((GUID_I420_PLANAR == fourcc) || 1325 (GUID_YV12_PLANAR == fourcc)) 1326 { 1327 VideoFrame *vf = at(i); 1328 uint ysize = vf->width * vf->height; 1329 uint uvsize = ysize >> 2; 1330 1331 bzero( vf->buf + vf->offsets[0], ysize); 1332 memset(vf->buf + vf->offsets[1], 127, uvsize); 1333 memset(vf->buf + vf->offsets[2], 127, uvsize); 1334 } 1335 } 1336 1337 void VideoBuffers::Clear(int fourcc) 1338 { 1339 for (uint i = 0; i < allocSize(); i++) 1340 Clear(i, fourcc); 1341 } 1342 1276 1343 /******************************* 1277 1344 ** Debugging functions below ** 1278 1345 *******************************/