'GStreamer'에 해당되는 글 5건

  1. 2011.07.06 [qt4] read mpeg4 stream from network IP cam
  2. 2011.06.23 [s3c6410] gstreamer-0.10.30 + plugins cross compile
  3. 2011.06.23 [s3c6410] gst-plugins-base-0.10.35 cross compile
  4. 2011.06.22 [s3c6410] gstreamer test
  5. 2011.06.14 [s3c6410] gst-plugins-base-0.10.22 cross compile

[qt4] read mpeg4 stream from network IP cam

  • jvccthread.h
  • #include <QThread>
    #include <QMutex>
    #include <QWaitCondition>
    #include <QBuffer>
    extern "C"
    {
    #include <libavformat/avformat.h>
    #include <libavcodec/avcodec.h>
    #include <libswscale/swscale.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <cstdio>
    }
    class jvcMpegThread : public QThread
    {
    Q_OBJECT
    public:
    jvcMpegThread(QByteArray *parent_array=0,unsigned int read_buffer_size=1024,QObject *parent=0);
    void getMpegImage(AVFrame *pFrame, int w, int h,int i);
    int read_packet(uint8_t *buf,int buf_size);

    bool readyForNextPacket;
    protected:
    void run();
    QMutex mutex;
    QWaitCondition condition;
    QBuffer *buf,*dataBuf;
    QByteArray byteArray,*dataArray;
    unsigned intbio_buffer_size;

    signals:
    void newImageSignal(QByteArray *);
    void giveMoreData();
    };
  • jvccthread.cpp
  • #include "jvccthread.h"
    #include <QDebug>
    FILE *pFile = NULL;
    AVFormatContext *pFormatCtx;
    int         i, videoStream;
    AVCodecContext  *pCodecCtx;
    AVCodec     *pCodec;
    AVFrame     *pFrame;
    AVFrame     *pFrameRGB;
    AVPacket    packet;
    int         frameFinished;
    int         numBytes;
    uint8_t     *buffer;
    unsigned char   *bio_buffer;
    AVInputFormat   *fmt;
    AVFormatParameters ap;
    ByteIOContext *io;
    static struct SwsContext *img_convert_ctx;

    static int read_packets(void *opaque,uint8_t *buf,int buf_size)
    {
    jvcMpegThread *mp=(jvcMpegThread *)opaque;
    int ret=mp->read_packet(buf,buf_size);
    //Debug("HRE");
       // int ret = fread(buf, 1, buf_size, pFile);
    return ret;
    }
    jvcMpegThread::jvcMpegThread(QByteArray *parent_array,unsigned int read_buffer_size,QObject *parent)
        :QThread(parent),dataArray(parent_array),bio_buffer_size(read_buffer_size)
    {
    buf=new QBuffer(&byteArray);
    //data=new QDataStream(buf);
    buf->open(QIODevice::WriteOnly);
    dataBuf=new QBuffer(dataArray);
    dataBuf->open(QIODevice::ReadWrite);
    readyForNextPacket=false;
       // QThread::start(QThread::LowPriority);

    }

    void jvcMpegThread::getMpegImage(AVFrame *pFrame, int w, int h,int i)
    {
    int  y,x;
     //byteArray.clear();
     buf->seek(0);
     buf->write(QString("P6\n"+QString::number(w)+" "+QString::number(h)+"\n255\n").toLatin1().data());

    // Write pixel data
    for(y=0; y<h; y++)
    {
        buf->write((char *)(pFrame->data[0]+y*pFrame->linesize[0]),w*3);
    }
    emit newImageSignal(&byteArray);
    }

    void jvcMpegThread::run()
    {
       // mutex.lock();

      //  mutex.unlock();
    //pFile = fopen("test.mpg", "rb");
    av_register_all();

    fmt=av_find_input_format("m4v");

    fmt->flags |= AVFMT_NOFILE|AVFMT_FLAG_IGNIDX;
    //bio_buffer_size=61440;
    bio_buffer=(unsigned char *)av_malloc(bio_buffer_size);
    io=new ByteIOContext;
    io->is_streamed=1;

    int ret = init_put_byte(io, bio_buffer, bio_buffer_size, 0, this, read_packets, NULL, NULL);
    if (av_open_input_stream(&pFormatCtx, io, "", fmt, NULL)!=0)
        return;
    qDebug("Stream Opened");
    if(av_find_stream_info(pFormatCtx)<0)
    {
        qDebug("Stream Info Error");
        return;
    }//qDebug("Stream Info Error"); // Couldn't find stream information
       qDebug("Stream Finded");
    // dump_format(pFormatCtx, 0, "test.mpg", false);

    videoStream=-1;
    for(i=0; i<pFormatCtx->nb_streams; i++)
        if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
        {
            videoStream=i;
            break;
        }
    if(videoStream==-1)
        return;// Didn't find a video strea
    qDebug()<<"Codec Finded"<<videoStream;

    // Get a pointer to the codec context for the video stream
    pCodecCtx=pFormatCtx->streams[videoStream]->codec;

    // Find the decoder for the video stream
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL)
        qDebug("Codec Error"); // Codec not found

    // Open codec
    if(avcodec_open(pCodecCtx, pCodec)<0)
        qDebug("Codec Open Error"); // Could not open codec

    // Hack to correct wrong frame rates that seem to be generated by some codecs
      //  if(pCodecCtx->time_base.num>1000 && pCodecCtx->time_base.den==1)
      //      pCodecCtx->time_base.den=1000;

    // Allocate video frame
    pFrame=avcodec_alloc_frame();

    // Allocate an AVFrame structure
    pFrameRGB=avcodec_alloc_frame();
    if(pFrameRGB==NULL)
        qDebug("Error");

    // Determine required buffer size and allocate buffer
    numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height);
    qDebug()<<numBytes;
    buffer=(uint8_t *)malloc(numBytes);

    // Assign appropriate parts of buffer to image planes in pFrameRGB
    avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
        pCodecCtx->width, pCodecCtx->height);

    // Read frames and save first five frames to disk
    i=0;
    int w = pCodecCtx->width;
    int h = pCodecCtx->height;
    int dst_w=800;
    int dst_h=600;

    img_convert_ctx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC,NULL, NULL, NULL);
    while (av_read_frame(pFormatCtx, &packet)>=0)
        {

          // Is this a packet from the video stream?
        if(packet.stream_index==videoStream)
        {

            // Decode video frame
            avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
                packet.data, packet.size);

            // Did we get a video frame?
            if(frameFinished)
            {
                    sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
                    i++;
                    getMpegImage(pFrameRGB, pCodecCtx->width, pCodecCtx->height,i);
            }
        }

        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);
        }

    }
    int jvcMpegThread::read_packet(uint8_t *buf,int buf_size)
    {
    emit giveMoreData();
    while (!readyForNextPacket)
    {
           // qDebug("Waiting for READ");
        this->msleep(1);
    }
    readyForNextPacket=false;
    dataBuf->seek(0);
    qint64 ret=dataBuf->read((char *)buf,buf_size);
    return ret;

    }
  • mpeggstream.h
  • #include "jvccthread.h"
    #include <QTcpSocket>
    class mpegStream : public QObject
    {
    Q_OBJECT
    public:
    mpegStream(QTcpSocket *parent=0);
    public slots:
    void startStopThread(bool);
    private slots:
    void readDataStream();



    signals:
    //void newImageSignal(QByteArray *);
    void newDataForDecode(uint);
    void newDataSignal(QByteArray *);
    private:
    QByteArray block,dataArray;
    uchar *frame;
    int blockcount;
    jvcMpegThread *th;
    unsigned int read_buffer_size;
    int wait_interval;
    QTcpSocket *socket;
    };
  • mpeggstream.cpp
  • #include "mpegstream.h"


    mpegStream::mpegStream(QTcpSocket *parent)
    :socket(parent)
    {
    //file=new QFile;
    //file->open(QIODevice::ReadOnly);
    blockcount=0;
    read_buffer_size=61440/2;
    th=new jvcMpegThread(&dataArray,read_buffer_size);
    connect(th,SIGNAL(newImageSignal(QByteArray*)),this,SIGNAL(newDataSignal(QByteArray*)));
    connect(th,SIGNAL(giveMoreData()),this,SLOT(readDataStream()));
    connect(this,SIGNAL(newDataForDecode(uint)),th,SLOT(getPacket(uint)));
    block.clear();


    }

    void mpegStream::readDataStream()
    {
    //qDebug()<<block.data();
    if (socket->bytesAvailable()>200000) qDebug()<<socket->bytesAvailable();
     while (block.size()<read_buffer_size)
        {
        //qDebug()<<"Entering While"<<socket->bytesAvailable()<<block.size();
            if (socket->bytesAvailable()==0)
            {
                socket->waitForReadyRead(3000);
             //   qDebug()<<block.data();
               // qDebug("Bytes Available 0");
            }
            if (socket->bytesAvailable()+block.size()<read_buffer_size)

                block.append(socket->readAll());
            else
            {
                if (block.size()>0 && block.size()<read_buffer_size) block.append(socket->read(read_buffer_size-block.size()));
                //else if (block.size()==61 440) readyForDecode=true;
                else block=socket->read(read_buffer_size);
            }
        }
        dataArray=block;
        th->readyForNextPacket=true;
      //  qDebug()<<block.data();
        block.clear();
    }

    void mpegStream::startStopThread(bool b)
    {
    if (b) th->start(QThread::LowPriority);
        else
       {
        th->terminate();
        th->wait(100);
    }
    }


[s3c6410] gstreamer-0.10.30 + plugins cross compile

gstreamer-0.10.30
#!/bin/sh

./configure \
    --prefix="/app" \
    --host=arm-generic-linux-gnueabi \
    --with-pkg-config-path="/app/bin/pkg-config" \
    GLIB_LIBS="-L/app/lib -lgobject-2.0 -lglib-2.0 -lgthread-2.0 -lgmodule-2.0" \
    GLIB_ONLY_LIBS="-L/app/lib -lglib-2.0"

gst-plugins-base-0.10.30
#!/bin/sh


./configure \
    --prefix=/app \
    --host=arm-generic-linux-gnueabi \
    --disable-x \
    --disable-xvideo \
    --disable-xshm \
    --disable-cdparanoia \
    --disable-gnome-vfs \
    PKG_CONFIG="/app/bin/pkg-config"

gst-plugins-good-0.10.24
#!/bin/sh


./configure \
    --prefix="/app" \
    --host=arm-generic-linux-gnueabi \
    --disable-x \
    --disable-xshm \
    --disable-xvideo \
    --disable-esd \
    --disable-shout2 \
    --enable-orc \
    --disable-aalib \
    PKG_CONFIG="/app/bin/pkg-config"

gst-plugins-bad-0.10.20
#!/bin/sh

./configure \
    --prefix="/app" \
    --host=arm-generic-linux-gnueabi \
    --enable-orc \
    --disable-neon \
    --with-sdl-prefix="/usr/arm-generic-linux-gnueabi" \
    PKG_CONFIG="/app/bin/pkg-config"


필요한 라이브러리 orc

[s3c6410] gst-plugins-base-0.10.35 cross compile

#!/bin/sh


./configure \
    --prefix=$PWD/_install \
    --host=arm-generic-linux-gnueabi \
    --disable-x \
    --disable-xvideo \
    --disable-xshm \
    --disable-cdparanoia \
    --disable-gnome-vfs \
    PKG_CONFIG="/app/bin/pkg-config"
orc 라이브러리를 요구 한다.(0.4.11 이상)
orc 라이브러리 다운로드
orc cross compile
#!/bin/sh


./configure \
    --prefix="/app" \
    --host=arm-generic-linux-gnueabi

**주의 gst-plugins-base 컴파일 중 orcc 유틸을 찾아서 실행하기 때문에 x86용 orcc도 만들어야 한다.

[s3c6410] gstreamer test

* 사운드 테스트
alsa 사운드 시스템
gst-launch audiotestsrc ! audioconvert ! audioresample ! alsasink

비디오 테스트
gst-launch -v videotestsrc ! fbdevsink

- 비디오 파일 테스트
-- 비디오만 테스트
gst-launch filesrc location="filename" ! avidemux name=demux demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! fbdevsink

-- 비디오 오디오 테스트
gst-launch filesrc location="filename" ! avidemux name=demux demux.audio_00 ! decodebin ! audioconvert ! audioresample ! osssink demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! fbdevsink



[s3c6410] gst-plugins-base-0.10.22 cross compile

* configure options
  ./configure --prefix=$PWD/_install --host=arm-generic-linux-gnueabi
   ./configure --prefix=$PWD/_install --host=arm-generic-linux-gnueabi --disable-x --disable-xvideo --disable-xshm --disable-cdparanoia --disable-gnome-vfs PKG_CONFIG="/usr/arm-generic-linux-gnueabi/bin/pkg-config"
  ./configure --prefix=$PWD/_install --host=arm-generic-linux-gnueabi --disable-x --disable-xvideo --disable-xshm --disable-cdparanoia --disable-gnome-vfs PKG_CONFIG="/usr/arm-generic-linux-gnueabi/bin/pkg-config" --disable-ogg --disable-oggtest --disable-vorbis --disable-vorbistest
* ogg, vorbis 라이브러리가 있을 경우
  ./configure --prefix=$PWD/_install --host=arm-generic-linux-gnueabi --disable-x --disable-xvideo --disable-xshm --disable-cdparanoia --disable-gnome-vfs PKG_CONFIG="/usr/arm-generic-linux-gnueabi/bin/pkg-config"

* 아래와 같은 에러 메세지 나옴.
checking whether arm-generic-linux-gnueabi-gcc implements __func__... yes
checking for GLIB... yes
checking for LIBOIL... no
configure: error: liboil-0.3.14 or later is required

* liboil-0.3.17 버젼 다운로드
./configure --prefix=$PWD/_install --host=arm-generic-linux-gnueabi LDFLAGS="-L/usr/arm-generic-linux-gnueabi/lib" LIBS="-lm -lrt" GLIB_LIBS="-L/usr/arm-generic-linux-gnueabi -lglib-2.0"
make clean && make -j8



완료!

'임베디드 > S3C6410' 카테고리의 다른 글

[s3c6410] libvorbis-1.3.2 cross compile  (0) 2011.06.15
[s3c641] libogg cross compile  (0) 2011.06.15
[s3c6410, qt4] glib cross compile  (0) 2011.06.10
[s3c6410] glib-2.2 porting 중 에러 대처  (0) 2011.06.09
[s3c6410] ffmpeg porting  (0) 2011.06.09
prev 1 next