From 897867cc9d3bc869317666993a9cc6ef38c163e2 Mon Sep 17 00:00:00 2001 From: deva Date: Thu, 15 Jun 2006 17:35:33 +0000 Subject: Prepared for the client to use uncompressed frames (YUV422 instead of DV). Still a lot of work to do though! --- client/decoder.cc | 44 ++++++++++++++++++++++++-------- client/decoder.h | 5 ++-- client/dv1394.cc | 7 +++-- client/dv1394.h | 2 +- client/dvfile.cc | 10 +++++--- client/dvfile.h | 2 +- client/networksender.cc | 8 +++--- client/networksender.h | 2 +- client/player.cc | 14 +++++----- client/player.h | 5 ---- lib/frame.cc | 24 +++++++++++++++++ lib/frame.h | 35 +++++++++++++++++++++++-- lib/frame_stream.h | 6 +++-- lib/libdv_wrapper.cc | 68 ++++++++++++++++++++++++++++++++++--------------- lib/libdv_wrapper.h | 8 +++--- 15 files changed, 174 insertions(+), 66 deletions(-) diff --git a/client/decoder.cc b/client/decoder.cc index 11cee08..c7a5097 100644 --- a/client/decoder.cc +++ b/client/decoder.cc @@ -47,7 +47,7 @@ Decoder::Decoder() { running = true; - memset(pframe, 0, sizeof(pframe)); // Init an empty frame + pframe = NULL; qApp->installEventFilter(this); } @@ -68,16 +68,29 @@ void Decoder::run() reader.connect(); #endif/* READ_DV_FROM_FILE*/ + LibDVWrapper dvdecoder(DV::ColorBest, DV::PAL, DV::YUV_422); + while(running) { - char *frame = (char*)reader.readFrame(); - if(!frame) continue; // An empty frame + Frame *dvframe = reader.readFrame(); + if(!dvframe) continue; // An empty frame + + Frame *yuvframe = dvdecoder.decode(dvframe); // Decode the DV frame to YUV422 and PCM audio + if(!yuvframe) continue; // An error ocurred if(MIaV::control.isFrozen() == false) { - pmutex.lock(); - memcpy(pframe, frame, DVPACKAGE_SIZE); - pmutex.unlock(); + if(yuvframe->vformat != VF_YUV422) { + fprintf(stderr, "Wrong videoformat in Decoder, expected VF_YUV422, got %i\n", yuvframe->vformat); + } else { + if(!pframe) { + fprintf(stderr, "PFrame data not set!\n"); + } else { + pmutex.lock(); + memcpy(pframe, yuvframe->vframe, yuvframe->vframesize); + pmutex.unlock(); + } + } } - + if(MIaV::control.isRecording()) { if(newconnection) { NetworkSender *sender = new NetworkSender(MIaV::control.getCpr()); @@ -92,7 +105,7 @@ void Decoder::run() sendersmutex.lock(); if(senders.isEmpty() == false) - senders.back()->pushFrame(frame, + senders.back()->pushFrame(yuvframe, MIaV::control.getShot(), MIaV::control.getFreeze()); sendersmutex.unlock(); @@ -113,17 +126,24 @@ void Decoder::run() sendersmutex.unlock(); - free(frame); + // free(frame); newconnection = true; + } } // closesem.release(); // Unlock the shutdown process } -char *Decoder::pframeAcquire() +void Decoder::setPFrameData(char *pframe) +{ + pmutex.lock(); + this->pframe = pframe; + pmutex.unlock(); +} + +void Decoder::pframeAcquire() { pmutex.lock();; - return pframe; } void Decoder::pframeRelease() @@ -133,12 +153,14 @@ void Decoder::pframeRelease() void Decoder::snapshot(char *rgb) { + /* LibDVWrapper dv; dv.setOutputBuffer(rgb, DV::BGR0); pmutex.lock(); dv.decode(pframe); pmutex.unlock(); + */ } bool Decoder::eventFilter(QObject *o, QEvent *e) diff --git a/client/decoder.h b/client/decoder.h index 2f8d575..f156884 100644 --- a/client/decoder.h +++ b/client/decoder.h @@ -51,7 +51,8 @@ public: void snapshot(char *rgb); - char *pframeAcquire(); + void setPFrameData(char *pframe); + void pframeAcquire(); void pframeRelease(); Status status(); @@ -64,7 +65,7 @@ private: QSemaphore closesem; QMutex pmutex; - char pframe[DVPACKAGE_SIZE]; // Player frame + char *pframe; // Player frame QMutex mutex; diff --git a/client/dv1394.cc b/client/dv1394.cc index e463c54..7dac7b3 100644 --- a/client/dv1394.cc +++ b/client/dv1394.cc @@ -150,7 +150,7 @@ bool dv1394::connect() return true; } -unsigned char *dv1394::readFrame() +Frame *dv1394::readFrame() { // Firewire port not correctly opened. if(!handle) return NULL; @@ -164,6 +164,9 @@ unsigned char *dv1394::readFrame() break; } } - return ptr; + + Frame *frame = new Frame((char*)ptr, DVPACKAGE_SIZE, VF_DV, NULL, 0, AF_DV); + + return frame; } diff --git a/client/dv1394.h b/client/dv1394.h index 8485638..5f99199 100644 --- a/client/dv1394.h +++ b/client/dv1394.h @@ -39,7 +39,7 @@ public: bool connect(); - unsigned char *readFrame(); + Frame *readFrame(); private: raw1394handle_t handle; diff --git a/client/dvfile.cc b/client/dvfile.cc index 676d6b1..601c21d 100644 --- a/client/dvfile.cc +++ b/client/dvfile.cc @@ -42,19 +42,21 @@ dvfile::~dvfile() fclose(fp); } -unsigned char *dvfile::readFrame() +Frame *dvfile::readFrame() { - unsigned char *frame = new unsigned char[DVPACKAGE_SIZE]; + unsigned char *ptr = new unsigned char[DVPACKAGE_SIZE]; sleep_1_frame(); if(fp) { - while(fread(frame, DVPACKAGE_SIZE, 1, fp) == 0) { + while(fread(ptr, DVPACKAGE_SIZE, 1, fp) == 0) { fseek(fp, 0L, SEEK_SET); } } else { - memset(frame, 0, sizeof(frame)); + memset(ptr, 0, sizeof(ptr)); } + Frame *frame = new Frame((char*)ptr, DVPACKAGE_SIZE, VF_DV, NULL, 0, AF_DV); + return frame; } diff --git a/client/dvfile.h b/client/dvfile.h index 9eedd00..b65dc36 100644 --- a/client/dvfile.h +++ b/client/dvfile.h @@ -40,7 +40,7 @@ public: dvfile(); ~dvfile(); - unsigned char *readFrame(); + Frame *readFrame(); private: FILE* fp; diff --git a/client/networksender.cc b/client/networksender.cc index 11eb259..f8912f1 100644 --- a/client/networksender.cc +++ b/client/networksender.cc @@ -32,7 +32,7 @@ NetworkSender::NetworkSender(QString cpr) { - ip = "192.168.0.10"; + ip = "127.0.0.1"; port = 6666; // Connect @@ -60,11 +60,11 @@ NetworkSender::~NetworkSender() fprintf(stderr, "Disconnect [%p]\n", this); } -void NetworkSender::pushFrame(char* framedata, bool freeze, bool snapshot) +void NetworkSender::pushFrame(Frame* frame, bool freeze, bool snapshot) { printf("F: %d S %d\n", freeze, snapshot); - Frame *frame = new Frame((unsigned char*)framedata); + // Frame *frame = new Frame((unsigned char*)framedata); frame->freeze = freeze; frame->shoot = snapshot; @@ -104,6 +104,8 @@ void NetworkSender::run() sleep_1_frame(); sleep_1_frame(); sleep_1_frame(); + if(frame->vframe) delete frame->vframe; + if(frame->aframe) delete frame->aframe; delete frame; // TODO: Read status from network diff --git a/client/networksender.h b/client/networksender.h index e3beb5a..71ce7e7 100644 --- a/client/networksender.h +++ b/client/networksender.h @@ -43,7 +43,7 @@ public: NetworkSender(QString cpr); ~NetworkSender(); - void pushFrame(char* frame, bool freeze, bool snapshot); + void pushFrame(Frame* frame, bool freeze, bool snapshot); unsigned int queueSize(); void run(); diff --git a/client/player.cc b/client/player.cc index 44e9cc9..dc3002d 100644 --- a/client/player.cc +++ b/client/player.cc @@ -34,25 +34,21 @@ Player::Player(QWidget *w, Decoder *d) : { widget = w; decoder = d; - dvdecoder = new LibDVWrapper(DV::ColorBest, DV::PAL, DV::YUV_422); connect(this, SIGNAL(timeout()), this, SLOT(show_frame())); - - dvdecoder->setOutputBuffer(render.getDisplayData()); + decoder->setPFrameData(render.getDisplayData()); } Player::~Player() { - delete dvdecoder; + // delete dvdecoder; } void Player::show_frame() { - char *frame; + // char *frame; - frame = decoder->pframeAcquire(); // Acquire frame data - dvdecoder->decode(frame); // Decode the DV frame to YUV - decoder->pframeRelease(); // Release frame data + decoder->pframeAcquire(); // Acquire frame data // Scale the video in aspect: if((double)widget->width() / WIDTH < (double)widget->height() / HEIGHT) { @@ -65,4 +61,6 @@ void Player::show_frame() // Display the YUV frame render.display(WIDTH, HEIGHT); + + decoder->pframeRelease(); // Release frame data } diff --git a/client/player.h b/client/player.h index d56ae4b..edd7bcf 100644 --- a/client/player.h +++ b/client/player.h @@ -38,9 +38,6 @@ #include #include - -#include "libdv_wrapper.h" - #include "xvaccelrenderer.h" class Player : public QTimer @@ -54,8 +51,6 @@ public slots: void show_frame(); private: - LibDVWrapper *dvdecoder; - Decoder *decoder; QWidget *widget; XvAccelRender render; diff --git a/lib/frame.cc b/lib/frame.cc index caab521..b3ad28f 100644 --- a/lib/frame.cc +++ b/lib/frame.cc @@ -30,6 +30,30 @@ #include #include +Frame::Frame(char *vframe, int vframesize, int vformat, + char *aframe, int aframesize, int aformat) +{ + // Video + this->vframe = vframe; + this->vframesize = vframesize; + this->vformat = vformat; + + // Audio + this->aframe = aframe; + this->aframesize = aframesize; + this->aformat = aformat; +} + + + + + + + + +/** + * Old frame code... to be removed shortly + */ Frame::Frame(unsigned char *d, int sz) { if(sz) data = new unsigned char[sz]; diff --git a/lib/frame.h b/lib/frame.h index 66c2ce7..ecfa308 100644 --- a/lib/frame.h +++ b/lib/frame.h @@ -28,13 +28,44 @@ #ifndef __FRAME_H__ #define __FRAME_H__ -#define START_USE_FRAME(x) x->usage++ -#define STOP_USE_FRAME(x) if(--x->usage == 0) delete x; x = NULL +//#define START_USE_FRAME(x) x->usage++ +//#define STOP_USE_FRAME(x) if(--x->usage == 0) delete x; x = NULL // Definition of vector #include +// VIDEO FORMATS +#define VF_NONE 0x00 +#define VF_DV 0x01 +#define VF_YUV422 0x02 +#define VF_YV12 0x03 +#define VF_RGB 0x04 +#define VF_BRG0 0x05 + +// AUDIO FORMATS +#define AF_NONE 0x00 // Dummy +#define AF_DV 0x01 // Audio data is in the DV video frame +#define AF_PCM_48KHZ_16BIT 0x02 // Raw pcm data in 48khz and 16bit +#define AF_MP3 0x03 // Lame encoded audio + class Frame { +public: + Frame(char *aframe, int aframesize, int aformat, + char *vframe, int vframesize, int vformat); + + // Video + char* vframe; + int vframesize; + int vformat; + + // Audio + char *aframe; + int aframesize; + int aformat; + + /** + * Old frame code... to be removed shortly + */ public: Frame(unsigned char *d, int sz = 0); ~Frame(); diff --git a/lib/frame_stream.h b/lib/frame_stream.h index bc0b9a2..32fea15 100644 --- a/lib/frame_stream.h +++ b/lib/frame_stream.h @@ -26,14 +26,16 @@ */ #include "config.h" #ifndef __MIAV_FRAME_STREAM_H__ -#define __MIAV_FRAME_STREAM_H__ +#define __MIAV_FRAME_STREAM_H_ + +#include "frame.h" class frame_stream { public: frame_stream() {} virtual ~frame_stream() {} - virtual unsigned char *readFrame() = 0; + virtual Frame *readFrame() = 0; }; diff --git a/lib/libdv_wrapper.cc b/lib/libdv_wrapper.cc index df624b6..cb9cc7c 100644 --- a/lib/libdv_wrapper.cc +++ b/lib/libdv_wrapper.cc @@ -40,6 +40,7 @@ LibDVWrapper::LibDVWrapper(DV::Quality quality, setSampling(sampling); yuv[0] = yuv[1] = yuv[2] = NULL; + pitches[0] = pitches[1] = pitches[2] = 0; width = 720; height = 576; @@ -73,56 +74,83 @@ void LibDVWrapper::setSampling(DV::Sampling sampling) decoder->sampling = (dv_sample_t)sampling; } -void LibDVWrapper::setOutputBuffer(char *output, DV::ColorSpace c) +Frame *LibDVWrapper::decode(Frame *input, DV::ColorSpace c) { - colorspace = c; + if(input->vformat != VF_DV) { + fprintf(stderr, "Wrong format in LibDVWrapper, expected VF_DV, got: %i\n", input->vformat); + return NULL; + } + + /* + if(first) { + dv_parse_header(decoder, (const uint8_t*)input); + //dv_parse_packs(decoder, frame->data); // Not needed anyway! + decoder->std = e_dv_std_iec_61834; + decoder->num_dif_seqs = 12; + first = false; + } + */ + + + int size = 0; + char* buf = NULL; + int type = VF_NONE; + DV::ColorSpace colorspace = c; switch(colorspace) { case DV::YUV: #ifdef COLORSPACE_YV12 - yuv[0] = (unsigned char*)output; + size = width*height*2; + buf = (char*)malloc(size); + type = VF_YV12; + yuv[0] = (unsigned char*)buf; yuv[1] = (unsigned char*)yuv[0] + (width * height); yuv[2] = (unsigned char*)yuv[1] + (width * height / 4); pitches[0] = width; pitches[1] = width / 2; pitches[2] = width / 2; #else - yuv[0] = (unsigned char*)output; + printf("!\n"); + size = width*height*2; + buf = (char*)malloc(size); + type = VF_YUV422; + yuv[0] = (unsigned char*)buf; + yuv[1] = yuv[2] = NULL; pitches[0] = width * 2; + pitches[1] = pitches[2] = 0; #endif break; case DV::RGB: - yuv[0] = (unsigned char*)output; + size = width*height*3; + buf = (char*)malloc(size); + type = VF_RGB; + yuv[0] = (unsigned char*)buf; yuv[1] = yuv[2] = NULL; pitches[0] = width * 3; + pitches[1] = pitches[2] = 0; break; case DV::BGR0: - yuv[0] = (unsigned char*)output; + size = width*height*4; + buf = (char*)malloc(size); + type = VF_BRG0; + yuv[0] = (unsigned char*)buf; yuv[1] = yuv[2] = NULL; pitches[0] = width * 4; + pitches[1] = pitches[2] = 0; break; } -} - -void LibDVWrapper::decode(char *input) -{ - if(!yuv[0]) return; // outputbuffer not set! - /* - if(first) { - dv_parse_header(decoder, (const uint8_t*)input); - //dv_parse_packs(decoder, frame->data); // Not needed anyway! - decoder->std = e_dv_std_iec_61834; - decoder->num_dif_seqs = 12; - first = false; - } - */ dv_decode_full_frame(decoder, (const uint8_t*)input, (dv_color_space_t)colorspace, yuv, pitches); + // memset(buf, 1, width*height); + // memset(buf+width*height, 100, width*height/2); + // memset(buf+width*height+width*height/2, 200, width*height/2); + Frame *frame = new Frame(buf, size, type, NULL, 0, AF_NONE); + return frame; } diff --git a/lib/libdv_wrapper.h b/lib/libdv_wrapper.h index 16a7d94..bde5620 100644 --- a/lib/libdv_wrapper.h +++ b/lib/libdv_wrapper.h @@ -31,6 +31,8 @@ #include #include +#include "frame.h" + namespace DV { /* #define DV_QUALITY_COLOR 1 // Clear this bit to make monochrome @@ -104,9 +106,7 @@ public: void setSystem(DV::System system); void setSampling(DV::Sampling sampling); - void setOutputBuffer(char *output, DV::ColorSpace colorspace = DV::YUV); - - void decode(char *input); + Frame *decode(Frame *input, DV::ColorSpace colorspace = DV::YUV); private: bool first; @@ -116,7 +116,7 @@ private: unsigned char* yuv[3]; dv_decoder_t *decoder; - DV::ColorSpace colorspace; + // DV::ColorSpace colorspace; }; #endif/*__MIAV_LIBDV_WRAPPER_H__*/ -- cgit v1.2.3