Ticket #2171: 2171-v1.patch

File 2171-v1.patch, 11.3 KB (added by danielk, 14 years ago)

Possible fix

  • libs/libmythtv/avformatdecoder.cpp

     
    15161516
    15171517    VideoFrame *frame = nd->GetNVP()->GetNextVideoFrame(true);
    15181518
    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    }
    15211524
    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 
    15301525    pic->opaque = frame;
    15311526    pic->type = FF_BUFFER_TYPE_USER;
    15321527
  • libs/libmythtv/frame.h

     
    3737    int top_field_first; // 1 if top field is first.
    3838    int repeat_pict;
    3939    int forcekey; // hardware encoded .nuv
     40
     41    int pitches[3]; // Y, U, & V pitches
     42    int offsets[3]; // Y, U, & V offsets
    4043} VideoFrame;
    4144
    4245#endif
  • libs/libmythtv/videoout_xv.h

     
    187187
    188188    // Used for all non-XvMC drawing
    189189    VideoFrame           av_pause_frame;
    190     vector<XShmSegmentInfo> XJ_shm_infos;
     190    vector<XShmSegmentInfo*> XJ_shm_infos;
     191    vector<YUVInfo>      XJ_yuv_infos;
    191192
    192193    // Basic non-Xv drawing info
    193194    XImage              *XJ_non_xv_image;
  • libs/libmythtv/videoout_xv.cpp

     
    15001500            .arg(num).arg(video_dim.width()).arg(video_dim.height()));
    15011501
    15021502    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));
    15071503    for (uint i = 0; i < num; i++)
    15081504    {
    1509         XJ_shm_infos.push_back(blank);
     1505        XShmSegmentInfo *info = new XShmSegmentInfo;
    15101506        void *image = NULL;
    15111507        int size = 0;
    15121508        int desiredsize = 0;
     
    15151511
    15161512        if (use_xv)
    15171513        {
    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;
    15221519            desiredsize = video_dim.width() * video_dim.height() * 3 / 2;
    15231520
    15241521            if (image && size < desiredsize)
     
    15281525                        "requested size.");
    15291526                XFree(image);
    15301527                image = NULL;
     1528                delete info;
    15311529            }
     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            }
    15321546        }
    15331547        else
    15341548        {
    15351549            XImage *img =
    15361550                XShmCreateImage(XJ_disp, DefaultVisual(XJ_disp, XJ_screen_num),
    1537                                 XJ_depth, ZPixmap, 0, &XJ_shm_infos[i],
     1551                                XJ_depth, ZPixmap, 0, info,
    15381552                                display_visible_rect.width(),
    15391553                                display_visible_rect.height());
    15401554            size = img->bytes_per_line * img->height + 64;
     
    15481562                        "requested size.");
    15491563                XDestroyImage((XImage *)image);
    15501564                image = NULL;
     1565                delete info;
    15511566            }
     1567
     1568            if (image)
     1569            {
     1570                YUVInfo tmp(img->width, img->height, NULL, NULL);
     1571                XJ_yuv_infos.push_back(tmp);
     1572            }
    15521573        }
    15531574
    15541575        X11U;
    15551576
    15561577        if (image)
    15571578        {
    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)
    15601581            {
    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);
    15621583                if (use_xv)
    1563                     ((XvImage*)image)->data = XJ_shm_infos[i].shmaddr;
     1584                    ((XvImage*)image)->data = XJ_shm_infos[i]->shmaddr;
    15641585                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;
    15681589
    15691590                X11L;
    1570                 XShmAttach(XJ_disp, &XJ_shm_infos[i]);
     1591                XShmAttach(XJ_disp, XJ_shm_infos[i]);
    15711592                XSync(XJ_disp, False); // needed for FreeBSD?
    15721593                X11U;
    15731594
    15741595                // Mark for delete immediately.
    15751596                // 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);
    15771598
    1578                 bufs.push_back((unsigned char*) XJ_shm_infos[i].shmaddr);
     1599                bufs.push_back((unsigned char*) XJ_shm_infos[i]->shmaddr);
    15791600            }
    15801601            else
    15811602            {
     
    16051626        vector<unsigned char*> bufs =
    16061627            CreateShmImages(vbuffers.allocSize(), true);
    16071628        ok = vbuffers.CreateBuffers(
    1608             video_dim.width(), video_dim.height(), bufs);
     1629            video_dim.width(), video_dim.height(), bufs, XJ_yuv_infos);
    16091630
    16101631        clear_xv_buffers(vbuffers, video_dim.width(), video_dim.height(),
    16111632                         xv_chroma);
     
    17471768        }
    17481769    }
    17491770
    1750     for (uint i=0; i<XJ_shm_infos.size(); ++i)
     1771    for (uint i = 0; i < XJ_shm_infos.size(); i++)
    17511772    {
    1752         X11S(XShmDetach(XJ_disp, &(XJ_shm_infos[i])));
     1773        X11S(XShmDetach(XJ_disp, XJ_shm_infos[i]));
    17531774        XvImage *image = (XvImage*)
    1754             xv_buffers[(unsigned char*)XJ_shm_infos[i].shmaddr];
     1775            xv_buffers[(unsigned char*) XJ_shm_infos[i]->shmaddr];
    17551776        if (image)
    17561777        {
    17571778            if ((XImage*)image == (XImage*)XJ_non_xv_image)
     
    17591780            else
    17601781                X11S(XFree(image));
    17611782        }
    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];
    17661788    }
    17671789    XJ_shm_infos.clear();
    17681790    xv_buffers.clear();
  • libs/libmythtv/videobuffers.h

     
    4444    kVideoBuffer_all       = 0x0000001F,
    4545};
    4646
     47class 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
    4759class VideoBuffers
    4860{
    4961  public:
     
    5567              uint needprebuffer_small, uint keepprebuffer,
    5668              bool enable_frame_locking = false);
    5769
    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);
    5973    bool CreateBuffers(int width, int height);
    6074    void DeleteBuffers(void);
    6175
  • libs/libmythtv/videobuffers.cpp

     
    1818
    1919int next_dbg_str = 0;
    2020
     21YUVInfo::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
    2146/**
    2247 * \class VideoBuffers
    2348 *  This class creates tracks the state of the buffers used by
     
    10711096bool VideoBuffers::CreateBuffers(int width, int height)
    10721097{
    10731098    vector<unsigned char*> bufs;
    1074     return CreateBuffers(width, height, bufs);
     1099    vector<YUVInfo>        yuvinfo;
     1100    return CreateBuffers(width, height, bufs, yuvinfo);
    10751101}
    10761102
    10771103bool VideoBuffers::CreateBuffers(int width, int height,
    1078                                  vector<unsigned char*> bufs)
     1104                                 vector<unsigned char*> bufs,
     1105                                 vector<YUVInfo>        yuvinfo)
    10791106{
    10801107    bool ok = true;
    10811108    uint bpp = 12 / 4; /* bits per pixel div common factor */
     
    10871114    uint adj_w = (width  + 15) & ~0xF;
    10881115    uint adj_h = (height + 15) & ~0xF;
    10891116    uint buf_size = (adj_w * adj_h * bpp + 4/* to round up */) / bpb;
     1117
    10901118    while (bufs.size() < allocSize())
    10911119    {
    10921120        unsigned char *data = (unsigned char*)av_malloc(buf_size + 64);
     
    10971125        memset(data + width * height, 127, width * height / 2);
    10981126
    10991127        bufs.push_back(data);
     1128        yuvinfo.push_back(YUVInfo(width, height, NULL, NULL));
     1129
    11001130        if (bufs.back())
    11011131        {
    11021132            VERBOSE(VB_PLAYBACK, "Created data @"
     
    11061136        else
    11071137            ok = false;
    11081138    }
     1139
    11091140    for (uint i = 0; i < allocSize(); i++)
    11101141    {
    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));
    11131146        buffers[i].bpp = 12;
    11141147        buffers[i].size = buf_size;
    11151148        buffers[i].codec = FMT_YV12;