• 9997阅读
  • 5回复

【提问】畫面顯示的問題!! [复制链接]

上一主题 下一主题
离线btopcst
 
只看楼主 倒序阅读 楼主  发表于: 2005-09-07
DrawView::DrawView()
{
  setCaption( "Qt Draw Demo Application" );
  setBackgroundColor( white );
  col =new QColor[256];
  printer =new QPrinter ;
  if ( (fd=fopen("bus_cif.yuv","r"))== NULL )
      printf ("exit \n");
  for (int i=0;i<256 ;i++)
    col[i] =QColor (i,i,i);
}
void drawShapes( QPainter *p )
{    
  for (int i;i<256;i++)
  {
        p->drawPoint(i,20);
  }
}
void DrawView::paintEvent(QPaintEvent*event)
{
  static QPixmap pixmap;
  QRect rect=event->rect();
  QSize newSize = rect.size().expandedTo(pixmap.size());
  pixmap.resize(newSize);
  pixmap.fill(this,rect.topLeft());
  QPainter painter (&pixmap,this);
  painter.translate(-rect.x(),-rect.y());
  unsigned char yuv[352];
  int h,w,tmp ;
  for (int i=0;i<100;i++)
  {
    for (h=0;h<288;h++)
    {
      fread(yuv,1,352,fd);
      for (w=0;w<352;w++)
    {
      tmp =yuv[w];                
      painter.setPen(col[tmp]);
      painter.drawPoint(w,h);
      }
    }
    bitBlt(this,0,0,&pixmap,0,0,352,288);

    for (h=0 ;h<144;h++)
    fread (yuv,1,176,fd);
    for (h=0 ;h<144;h++)
    fread (yuv,1,176,fd);
  }
}

打算寫個像即時通訊那樣的 capture …

一直播放畫面…畫面所傳進來的是 YUV 資料…

所以必須寫一個 YUV 轉成 RGB資料…

但是上面的 code …它只做到播放 Y 的資料…並且

還沒有做 YUV 轉成 RGB 的步驟…而且…

它放資料至buffer的方式…是一個點、一個點的放…

以致於造成畫面的閃爍…不知道各位高手…有沒有

不一樣的放法…解決閃爍的問題…以及…如何寫YUV

轉成RGB!!麻煩給個意見 ^^
[ 此贴被XChinux在2005-09-08 21:19重新编辑 ]
离线XChinux

只看该作者 1楼 发表于: 2005-09-07
对这个没研究,呵呵,还请会的朋友解答
[ 此贴被XChinux在2005-09-07 12:34重新编辑 ]
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线btopcst
只看该作者 2楼 发表于: 2005-09-08
我看過qtopia 的displayer的程式…

發現它的程式想法大概如下:
1.先宣告一個QImage *currentframe;
2.再利用的 currentframe 格式來建立一個framebuffer來儲存要顯示的畫面
3.建立framebuffer的目的…是為了做YUV->RGB
4.最後以
      p->drawImage(x,y,*currentFrame,framewidth,frameheight);來顯示


我寫了一個小程式…

功能:在視窗下顯示黑白相間的畫面

想法:
1.先宣告一個QImage *currentframe;
2.再利用的 currentframe 格式來建立一個
    h=288 w=352*4的framebuffer來儲存畫面
3.再以自行寫入framebuffer
4.最後以
      print->drawImage(x,y,*currentFrame,framewidth,frameheight);來顯示

但是有錯誤…高手們能否幫我看看…我的code技巧有很大的錯誤…能否指教…

/////////////////////////////////framebuffer////////////////////////////

#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
typedef unsigned char uchar;
class FrameBuffer {
public:
  FrameBuffer();
  ~FrameBuffer();
  void create( uchar *bits, int lineStep, int x, int y, int w, int h );
  uchar **jumpTable();
  int width();
  int height();
private:
  uchar **jt;
  int x, y, w, h;
  uchar *bits;
  int lineStep;
};
#endif // FRAMEBUFFER_H

#include <qpixmap.h>
#include "framebuffer.h"
FrameBuffer::FrameBuffer() :x(0), y(0), w(0), h(0), bits(0), lineStep(0)
{
  jt = new uchar*[1];
}
FrameBuffer::~FrameBuffer()
{
  delete []jt;
  delete []write_reg;
  delete []read_reg;
  delete []bits;
}
void FrameBuffer::create( uchar *b, int ls, int x1, int y1, int width, int height )
{
  if ( bits == b && ls == lineStep && x == x1 && y == y1 && w == width && h == height )
    return;  
  delete []jt;
  jt = new uchar*[height];
  x = x1;
  y = y1;
  bits = b;
  lineStep = ls;
  w = width;
  h = height;  
  uchar *fp = bits + lineStep * y + QPixmap::defaultDepth() * x / 8;
  for ( int i = 0; i < h; i++,fp += lineStep )
  {    
    jt[i] = fp;    
  }
}
uchar **FrameBuffer::jumpTable()
{
  return jt;
}
int FrameBuffer::width()
{
  return w;
}
int FrameBuffer::height()
{
  return h;
}
template<class T>
static inline void rotateLoopTemplate(
    uchar *src, int srcBytesPerLine, uchar *dst, int dstBytesPerLine,
    int width, int height, bool rotateDirection )
{
  int dstXAdd = 0;
  int dstYAdd = 0;
  int dstXOfs = 0;
  int dstYOfs = 0;
  int srcYAdd = srcBytesPerLine - width * sizeof(T);

  if ( rotateDirection ) {
        dstXOfs = 0;
        dstYOfs = width - 1;
        dstXAdd = -dstBytesPerLine;
        dstYAdd = 1 * sizeof(T) + width * dstBytesPerLine;
  } else {
        dstXOfs = height - 1;
        dstYOfs = 0;
        dstXAdd = dstBytesPerLine;
        dstYAdd = -1 * sizeof(T) - width * dstBytesPerLine;
  }

  T *dstPtr = (T *)(dst + dstYOfs * dstBytesPerLine) + dstXOfs;
  T *srcPtr = (T *)src;
  for ( int y = 0; y < height; y++ ) {
    for ( int x = 0; x < width; x++ ) {
        *dstPtr = *srcPtr++;
        dstPtr = (T *)((uchar*)dstPtr + dstXAdd); // add dstXAdd number of bytes
    }
    srcPtr = (T *)((uchar*)srcPtr + srcYAdd); // add srcYAdd number of bytes
    dstPtr = (T *)((uchar*)dstPtr + dstYAdd); // add dstYAdd number of bytes
  }
}
/////////////////////////////point.cpp//////////////////////////////////
#define framewidth 352
#define frameheight 288
#include <qimage.h>
#include <qwidget.h>
#include <qpainter.h>
#include <qprinter.h>
#include <qpushbutton.h>
#include <qradiobutton.h>
#include <qbuttongroup.h>
#include <qapplication.h>
#include <math.h>
#include <qpixmap.h>
#include <qrect.h>
#include <stdio.h>
#include "framebuffer.h"
typedef unsigned char uchar;
class DrawView : public QWidget
{
  Q_OBJECT
public:
  DrawView();
  ~DrawView();
  void write_buffer(uchar **temp_data);
  QColor *col;
protected:
  void   paintEvent(QPaintEvent*event);
private:
  QPrinter     *printer;
  QPrinter   p;
  FrameBuffer imageFB;
  FrameBuffer *framebuffer;
  FrameBuffer *tempbuffer;
  QImage *currentFrame;
  uchar **temp_data;  
};

DrawView::DrawView()
{
  setCaption( "Qt Draw Demo Application" );
  setBackgroundColor( white );  
  printer =new QPrinter;
  currentFrame=new QImage(framewidth,frameheight,(QPixmap::defaultDepth()==16)?16:32);
  imageFB.create( currentFrame->bits(),currentFrame->bytesPerLine(), 0, 0, framewidth,frameheight);  
}
DrawView::~DrawView()
{
  delete currentFrame;
   
}
void DrawView::paintEvent(QPaintEvent*event)
{
  write_buffer(framebuffer->jumpTable());
  printer->drawImage(0,0,*currentFrame,framewidth,frameheight);
  char a[10];
  scanf("%s",a);  
}
void DrawView::write_buffer(uchar **temp_data)
{
  for(int i=0;i<288;i++)
  {
    for(int j=0;j<1408;j++)
    {
      if(i%2)
      temp_data[i][j]=255;
      else
      temp_data[i][j]=0;
    }    
  }
}
//==================================================
#include "point.moc"

int main( int argc, char **argv )
{
  QApplication app( argc, argv );
  DrawView   draw;
  app.setMainWidget( &draw );
  draw.setCaption("Drawdemo");
  draw.show();
  return app.exec();
}

/////////////////////////////make訊息///////////////////////////////

point.cpp: In member function `DrawView::DrawView()':
point.cpp:56: warning: unused variable `FrameBuffer*framebuffer'
point.cpp: In member function `virtual void
  DrawView::paintEvent(QPaintEvent*)':
point.cpp:68: no matching function for call to `QPrinter::drawImage(int, int,
  QImage&, int, int)'
point.cpp:66: warning: unused parameter `QPaintEvent*event'
make: *** [point.o] Error 1
[ 此贴被XChinux在2005-09-08 21:18重新编辑 ]
离线giscn
只看该作者 3楼 发表于: 2005-09-09
它放資料至buffer的方式…是一個點、一個點的放…

以致於造成畫面的閃爍…
->放buffer里是不会千万画面闪烁了。你的程序应用了double buffer,做的很好。
但我不知道
  for (int i=0;i<100;i++)
{
这个100次是干什么用的,画一次图你bitBlt了100次,当然闪烁了,但不是由于一点一点画的原因造成的。

另外,拜托,又不是不会用简体,干什么用繁体,看着别扭
http://nzt.spaces.live.com
离线XChinux

只看该作者 4楼 发表于: 2005-09-09
楼上的息怒,呵呵,楼主是台湾的朋友,从他的帖子中不光文字是繁体,连词语都是台湾的称呼就知道了,呵呵。我使用繁体是由于在做繁体网站项目,经常切换来切换去麻烦了,就懒得切换了。但从行文上还是能分辨出是是哪边的语言习惯的。
[ 此贴被XChinux在2005-09-09 13:14重新编辑 ]
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线btopcst
只看该作者 5楼 发表于: 2005-09-09
我是台灣來的…所以使用繁體字…如果有一些名詞不了解的話…

我可以解釋的…

在程式中: for (int i=0;i<100;i++)

這個的作用是播放一百張圖…因為有開一個.yuv影片…

能請問一下…yuv轉rgb要怎麼做呢??可否給我一個方向…
快速回复
限100 字节
 
上一个 下一个