Ticket #2171: 2171-v1.patch
File 2171-v1.patch, 11.3 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/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/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
1500 1500 .arg(num).arg(video_dim.width()).arg(video_dim.height())); 1501 1501 1502 1502 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 1503 for (uint i = 0; i < num; i++) 1508 1504 { 1509 X J_shm_infos.push_back(blank);1505 XShmSegmentInfo *info = new XShmSegmentInfo; 1510 1506 void *image = NULL; 1511 1507 int size = 0; 1512 1508 int desiredsize = 0; … … 1515 1511 1516 1512 if (use_xv) 1517 1513 { 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; 1514 XvImage *img = 1515 XvShmCreateImage(XJ_disp, xv_port, xv_chroma, 0, 1516 video_dim.width(), video_dim.height(), info); 1517 size = img->data_size + 64; 1518 image = img; 1522 1519 desiredsize = video_dim.width() * video_dim.height() * 3 / 2; 1523 1520 1524 1521 if (image && size < desiredsize) … … 1528 1525 "requested size."); 1529 1526 XFree(image); 1530 1527 image = NULL; 1528 delete info; 1531 1529 } 1530 1531 if (image && (3 == img->num_planes)) 1532 { 1533 XJ_shm_infos.push_back(info); 1534 YUVInfo tmp(img->width, img->height, 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, NULL, NULL); 1571 XJ_yuv_infos.push_back(tmp); 1572 } 1552 1573 } 1553 1574 1554 1575 X11U; 1555 1576 1556 1577 if (image) 1557 1578 { 1558 XJ_shm_infos[i] .shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);1559 if (XJ_shm_infos[i] .shmid >= 0)1579 XJ_shm_infos[i]->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); 1580 if (XJ_shm_infos[i]->shmid >= 0) 1560 1581 { 1561 XJ_shm_infos[i] .shmaddr = (char*) shmat(XJ_shm_infos[i].shmid, 0, 0);1582 XJ_shm_infos[i]->shmaddr = (char*) shmat(XJ_shm_infos[i]->shmid, 0, 0); 1562 1583 if (use_xv) 1563 ((XvImage*)image)->data = XJ_shm_infos[i] .shmaddr;1584 ((XvImage*)image)->data = XJ_shm_infos[i]->shmaddr; 1564 1585 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;1586 ((XImage*)image)->data = XJ_shm_infos[i]->shmaddr; 1587 xv_buffers[(unsigned char*) XJ_shm_infos[i]->shmaddr] = image; 1588 XJ_shm_infos[i]->readOnly = False; 1568 1589 1569 1590 X11L; 1570 XShmAttach(XJ_disp, &XJ_shm_infos[i]);1591 XShmAttach(XJ_disp, XJ_shm_infos[i]); 1571 1592 XSync(XJ_disp, False); // needed for FreeBSD? 1572 1593 X11U; 1573 1594 1574 1595 // Mark for delete immediately. 1575 1596 // It won't actually be removed until after we detach it. 1576 shmctl(XJ_shm_infos[i] .shmid, IPC_RMID, 0);1597 shmctl(XJ_shm_infos[i]->shmid, IPC_RMID, 0); 1577 1598 1578 bufs.push_back((unsigned char*) XJ_shm_infos[i] .shmaddr);1599 bufs.push_back((unsigned char*) XJ_shm_infos[i]->shmaddr); 1579 1600 } 1580 1601 else 1581 1602 { … … 1605 1626 vector<unsigned char*> bufs = 1606 1627 CreateShmImages(vbuffers.allocSize(), true); 1607 1628 ok = vbuffers.CreateBuffers( 1608 video_dim.width(), video_dim.height(), bufs );1629 video_dim.width(), video_dim.height(), bufs, XJ_yuv_infos); 1609 1630 1610 1631 clear_xv_buffers(vbuffers, video_dim.width(), video_dim.height(), 1611 1632 xv_chroma); … … 1747 1768 } 1748 1769 } 1749 1770 1750 for (uint i =0; i<XJ_shm_infos.size(); ++i)1771 for (uint i = 0; i < XJ_shm_infos.size(); i++) 1751 1772 { 1752 X11S(XShmDetach(XJ_disp, &(XJ_shm_infos[i])));1773 X11S(XShmDetach(XJ_disp, XJ_shm_infos[i])); 1753 1774 XvImage *image = (XvImage*) 1754 xv_buffers[(unsigned char*) XJ_shm_infos[i].shmaddr];1775 xv_buffers[(unsigned char*) XJ_shm_infos[i]->shmaddr]; 1755 1776 if (image) 1756 1777 { 1757 1778 if ((XImage*)image == (XImage*)XJ_non_xv_image) … … 1759 1780 else 1760 1781 X11S(XFree(image)); 1761 1782 } 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); 1783 if (XJ_shm_infos[i]->shmaddr) 1784 shmdt(XJ_shm_infos[i]->shmaddr); 1785 if (XJ_shm_infos[i]->shmid > 0) 1786 shmctl(XJ_shm_infos[i]->shmid, IPC_RMID, 0); 1787 delete XJ_shm_infos[i]; 1766 1788 } 1767 1789 XJ_shm_infos.clear(); 1768 1790 xv_buffers.clear(); -
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, const int *p, const int *o); 51 52 public: 53 uint width; 54 uint height; 55 uint pitches[3]; 56 uint offsets[3]; 57 }; 58 47 59 class VideoBuffers 48 60 { 49 61 public: … … 55 67 uint needprebuffer_small, uint keepprebuffer, 56 68 bool enable_frame_locking = false); 57 69 58 bool CreateBuffers(int width, int height, vector<unsigned char*> bufs); 70 bool CreateBuffers(int width, int height, 71 vector<unsigned char*> bufs, 72 vector<YUVInfo> yuvinfo); 59 73 bool CreateBuffers(int width, int height); 60 74 void DeleteBuffers(void); 61 75 -
libs/libmythtv/videobuffers.cpp
18 18 19 19 int next_dbg_str = 0; 20 20 21 YUVInfo::YUVInfo(uint w, uint h, const int *p, const int *o) 22 : width(w), height(h) 23 { 24 if (p) 25 { 26 memcpy(pitches, p, 3 * sizeof(int)); 27 } 28 else 29 { 30 pitches[0] = width; 31 pitches[1] = pitches[2] = width >> 1; 32 } 33 34 if (o) 35 { 36 memcpy(offsets, o, 3 * sizeof(int)); 37 } 38 else 39 { 40 offsets[0] = 0; 41 offsets[1] = width * height; 42 offsets[2] = offsets[1] + (offsets[1] >> 2); 43 } 44 } 45 21 46 /** 22 47 * \class VideoBuffers 23 48 * This class creates tracks the state of the buffers used by … … 1071 1096 bool VideoBuffers::CreateBuffers(int width, int height) 1072 1097 { 1073 1098 vector<unsigned char*> bufs; 1074 return CreateBuffers(width, height, bufs); 1099 vector<YUVInfo> yuvinfo; 1100 return CreateBuffers(width, height, bufs, yuvinfo); 1075 1101 } 1076 1102 1077 1103 bool VideoBuffers::CreateBuffers(int width, int height, 1078 vector<unsigned char*> bufs) 1104 vector<unsigned char*> bufs, 1105 vector<YUVInfo> yuvinfo) 1079 1106 { 1080 1107 bool ok = true; 1081 1108 uint bpp = 12 / 4; /* bits per pixel div common factor */ … … 1087 1114 uint adj_w = (width + 15) & ~0xF; 1088 1115 uint adj_h = (height + 15) & ~0xF; 1089 1116 uint buf_size = (adj_w * adj_h * bpp + 4/* to round up */) / bpb; 1117 1090 1118 while (bufs.size() < allocSize()) 1091 1119 { 1092 1120 unsigned char *data = (unsigned char*)av_malloc(buf_size + 64); … … 1097 1125 memset(data + width * height, 127, width * height / 2); 1098 1126 1099 1127 bufs.push_back(data); 1128 yuvinfo.push_back(YUVInfo(width, height, NULL, NULL)); 1129 1100 1130 if (bufs.back()) 1101 1131 { 1102 1132 VERBOSE(VB_PLAYBACK, "Created data @" … … 1106 1136 else 1107 1137 ok = false; 1108 1138 } 1139 1109 1140 for (uint i = 0; i < allocSize(); i++) 1110 1141 { 1111 buffers[i].width = width; 1112 buffers[i].height = height; 1142 buffers[i].width = yuvinfo[i].width; 1143 buffers[i].height = yuvinfo[i].height; 1144 memcpy(buffers[i].pitches, yuvinfo[i].pitches, 3 * sizeof(int)); 1145 memcpy(buffers[i].offsets, yuvinfo[i].offsets, 3 * sizeof(int)); 1113 1146 buffers[i].bpp = 12; 1114 1147 buffers[i].size = buf_size; 1115 1148 buffers[i].codec = FMT_YV12;