From: Jean-Baptiste Mardelle Date: Sat, 4 Jun 2011 23:17:18 +0000 (+0000) Subject: Cleanup capture stuff X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=875720c9414fb6170be525d47758df800c1a96fd;p=kdenlive Cleanup capture stuff svn path=/trunk/kdenlive/; revision=5655 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2144a2ec..f0072341 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -264,8 +264,6 @@ set(kdenlive_SRCS audiosignal.cpp blackmagic/include/DeckLinkAPIDispatch.cpp stopmotion/stopmotion.cpp - stopmotion/capturehandler.cpp - blackmagic/capture.cpp blackmagic/devices.cpp onmonitoritems/onmonitorrectitem.cpp onmonitoritems/onmonitorcornersitem.cpp diff --git a/src/blackmagic/capture.cpp b/src/blackmagic/capture.cpp deleted file mode 100644 index f57a48c6..00000000 --- a/src/blackmagic/capture.cpp +++ /dev/null @@ -1,889 +0,0 @@ -/* -LICENSE-START- -** Copyright (c) 2009 Blackmagic Design -** -** Permission is hereby granted, free of charge, to any person or organization -** obtaining a copy of the software and accompanying documentation covered by -** this license (the "Software") to use, reproduce, display, distribute, -** execute, and transmit the Software, and to prepare derivative works of the -** Software, and to permit third-parties to whom the Software is furnished to -** do so, all subject to the following: -** -** The copyright notices in the Software and this entire statement, including -** the above license grant, this restriction and the following disclaimer, -** must be included in all copies of the Software, in whole or in part, and -** all derivative works of the Software, unless such copies or derivative -** works are solely in the form of machine-executable object code generated by -** a source language processor. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -** DEALINGS IN THE SOFTWARE. -** -LICENSE-END- -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#ifndef GL_TEXTURE_RECTANGLE_EXT -#define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV -#endif - -#include -#include - -#include "capture.h" -#include "kdenlivesettings.h" - -pthread_mutex_t sleepMutex; -pthread_cond_t sleepCond; -int videoOutputFile = -1; -int audioOutputFile = -1; - -static BMDTimecodeFormat g_timecodeFormat = 0; -static int g_videoModeIndex = -1; -static int g_audioChannels = 2; -static int g_audioSampleDepth = 16; -static int g_maxFrames = -1; -static QString doCaptureFrame; -static double g_aspect_ratio = 16.0 / 9.0; - -static unsigned long frameCount = 0; - - -class CDeckLinkGLWidget : public QGLWidget, public IDeckLinkScreenPreviewCallback -{ -private: - QAtomicInt refCount; - QMutex mutex; - IDeckLinkInput* deckLinkIn; - IDeckLinkGLScreenPreviewHelper* deckLinkScreenPreviewHelper; - IDeckLinkVideoFrame* m_frame; - QColor m_backgroundColor; - GLuint m_texture; - QImage m_img; - double m_zx; - double m_zy; - int m_pictureWidth; - int m_pictureHeight; - bool m_transparentOverlay; - -public: - CDeckLinkGLWidget(IDeckLinkInput* deckLinkInput, QWidget* parent); - // IDeckLinkScreenPreviewCallback - virtual HRESULT QueryInterface(REFIID iid, LPVOID *ppv); - virtual ULONG AddRef(); - virtual ULONG Release(); - virtual HRESULT DrawFrame(IDeckLinkVideoFrame* theFrame); - void showOverlay(QImage img, bool transparent); - void hideOverlay(); - -protected: - void initializeGL(); - void paintGL(); - void resizeGL(int width, int height); - /*void initializeOverlayGL(); - void paintOverlayGL(); - void resizeOverlayGL(int width, int height);*/ -}; - -CDeckLinkGLWidget::CDeckLinkGLWidget(IDeckLinkInput* deckLinkInput, QWidget* parent) : QGLWidget(/*QGLFormat(QGL::HasOverlay | QGL::AlphaChannel),*/ parent) - , m_backgroundColor(KdenliveSettings::window_background()) - , m_zx(1.0) - , m_zy(1.0) - , m_transparentOverlay(true) -{ - refCount = 1; - deckLinkIn = deckLinkInput; - deckLinkScreenPreviewHelper = CreateOpenGLScreenPreviewHelper(); -} - -void CDeckLinkGLWidget::showOverlay(QImage img, bool transparent) -{ - m_transparentOverlay = transparent; - m_img = convertToGLFormat(img); - m_zx = (double)m_pictureWidth / m_img.width(); - m_zy = (double)m_pictureHeight / m_img.height(); - if (m_transparentOverlay) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR); - } else { - glDisable(GL_BLEND); - } -} - -void CDeckLinkGLWidget::hideOverlay() -{ - m_img = QImage(); - glDisable(GL_BLEND); -} - -void CDeckLinkGLWidget::initializeGL() -{ - if (deckLinkScreenPreviewHelper != NULL) { - mutex.lock(); - deckLinkScreenPreviewHelper->InitializeGL(); - glShadeModel(GL_FLAT); - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - glDisable(GL_DITHER); - glDisable(GL_BLEND); - - //Documents/images/alpha2.png");// - //m_texture = bindTexture(convertToGLFormat(img), GL_TEXTURE_RECTANGLE_EXT, GL_RGBA8, QGLContext::LinearFilteringBindOption); - mutex.unlock(); - } -} - -/*void CDeckLinkGLWidget::initializeOverlayGL () -{ - glDisable(GL_BLEND); - glEnable(GL_TEXTURE_RECTANGLE_EXT); - -} - -void CDeckLinkGLWidget::paintOverlayGL() -{ - makeOverlayCurrent(); - glEnable(GL_BLEND); - //glClearDepth(0.5f); - //glPixelTransferf(GL_ALPHA_SCALE, 10); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - -}*/ - -void CDeckLinkGLWidget::paintGL() -{ - mutex.lock(); - glLoadIdentity(); - qglClearColor(m_backgroundColor); - //glClearColor(1.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - deckLinkScreenPreviewHelper->PaintGL(); - if (!m_img.isNull()) { - glPixelZoom(m_zx, m_zy); - glDrawPixels(m_img.width(), m_img.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_img.bits()); - } - mutex.unlock(); -} -/* -void CDeckLinkGLWidget::paintEvent(QPaintEvent *event) -{ - mutex.lock(); - QPainter p(this); - QRect r = event->rect(); - p.setClipRect(r); - void *frameBytes; - m_frame->GetBytes(&frameBytes); - QImage img((uchar*)frameBytes, m_frame->GetWidth(), m_frame->GetHeight(), QImage::Format_ARGB32);//m_frame->GetPixelFormat()); - QRectF re(0, 0, width(), height()); - p.drawImage(re, img); - p.end(); - mutex.unlock(); -}*/ - -void CDeckLinkGLWidget::resizeGL(int width, int height) -{ - mutex.lock(); - m_pictureHeight = height; - m_pictureWidth = width; - int calculatedWidth = g_aspect_ratio * height; - if (calculatedWidth > width) m_pictureHeight = width / g_aspect_ratio; - else { - int calculatedHeight = width / g_aspect_ratio; - if (calculatedHeight > height) m_pictureWidth = height * g_aspect_ratio; - } - glViewport((width - m_pictureWidth) / 2, (height - m_pictureHeight) / 2, m_pictureWidth, m_pictureHeight); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); - glMatrixMode(GL_MODELVIEW); - glRasterPos2i(-1, -1); - if (!m_img.isNull()) { - m_zx = (double)m_pictureWidth / m_img.width(); - m_zy = (double)m_pictureHeight / m_img.height(); - } - - mutex.unlock(); -} - -/*void CDeckLinkGLWidget::resizeOverlayGL ( int width, int height ) -{ - int newwidth = width; - int newheight = height; - int calculatedWidth = g_aspect_ratio * height; - if (calculatedWidth > width) newheight = width / g_aspect_ratio; - else { - int calculatedHeight = width / g_aspect_ratio; - if (calculatedHeight > height) newwidth = height * g_aspect_ratio; - } - glViewport((width - newwidth) / 2, (height - newheight) / 2, newwidth, newheight); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, 0, height, -1.0, 1.0); - glMatrixMode(GL_MODELVIEW); - updateOverlayGL (); -}*/ - -HRESULT CDeckLinkGLWidget::QueryInterface(REFIID iid, LPVOID *ppv) -{ - Q_UNUSED(iid) - *ppv = NULL; - return E_NOINTERFACE; -} - -ULONG CDeckLinkGLWidget::AddRef() -{ - int oldValue; - - oldValue = refCount.fetchAndAddAcquire(1); - return (ULONG)(oldValue + 1); -} - -ULONG CDeckLinkGLWidget::Release() -{ - int oldValue; - - oldValue = refCount.fetchAndAddAcquire(-1); - if (oldValue == 1) { - delete this; - } - - return (ULONG)(oldValue - 1); -} - -HRESULT CDeckLinkGLWidget::DrawFrame(IDeckLinkVideoFrame* theFrame) -{ - if (deckLinkScreenPreviewHelper != NULL && theFrame != NULL) { - /*mutex.lock(); - m_frame = theFrame; - mutex.unlock();*/ - deckLinkScreenPreviewHelper->SetFrame(theFrame); - update(); - } - return S_OK; -} - - -DeckLinkCaptureDelegate::DeckLinkCaptureDelegate() : m_refCount(0) -{ - pthread_mutex_init(&m_mutex, NULL); -} - -DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() -{ - pthread_mutex_destroy(&m_mutex); -} - -ULONG DeckLinkCaptureDelegate::AddRef(void) -{ - pthread_mutex_lock(&m_mutex); - m_refCount++; - pthread_mutex_unlock(&m_mutex); - - return (ULONG)m_refCount; -} - -ULONG DeckLinkCaptureDelegate::Release(void) -{ - pthread_mutex_lock(&m_mutex); - m_refCount--; - pthread_mutex_unlock(&m_mutex); - - if (m_refCount == 0) { - delete this; - return 0; - } - - return (ULONG)m_refCount; -} - - -inline bool safe_write(int fd, const void* bytes, size_t length) { - int rc = 0; - size_t written = 0; - const char* buf = static_cast(bytes); - while (rc != -1 && written < length) { - rc = write(fd, &(buf[written]), length - written); - written += (rc >= 0 ? rc : 0); - } - return rc != -1; -} - -void DeckLinkCaptureDelegate::slotProcessFrame() -{ - if (m_framesList.isEmpty()) return; - IDeckLinkVideoInputFrame* videoFrame = m_framesList.takeFirst(); - QString capturePath = m_framePath.takeFirst(); - void *frameBytes; - videoFrame->GetBytes(&frameBytes); - if (capturePath.endsWith("raw")) { - // Save as raw uyvy422 imgage - videoOutputFile = open(capturePath.toUtf8().constData(), O_WRONLY | O_CREAT/*|O_TRUNC*/, 0664); - safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight()); - close(videoOutputFile); - emit frameSaved(capturePath); - } else { - QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied); - //convert from uyvy422 to rgba - CaptureHandler::uyvy2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight()); - image.save(capturePath); - emit frameSaved(capturePath); - } - videoFrame->Release(); -} - -void DeckLinkCaptureDelegate::setAnalyse(bool isOn) -{ - m_analyseFrame = isOn; -} - -HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame) -{ - IDeckLinkVideoFrame* rightEyeFrame = NULL; - IDeckLinkVideoFrame3DExtensions* threeDExtensions = NULL; - void* frameBytes; - void* audioFrameBytes; - - // Handle Video Frame - if (videoFrame) { - // If 3D mode is enabled we retreive the 3D extensions interface which gives. - // us access to the right eye frame by calling GetFrameForRightEye() . - if ((videoFrame->QueryInterface(IID_IDeckLinkVideoFrame3DExtensions, (void **) &threeDExtensions) != S_OK) || - (threeDExtensions->GetFrameForRightEye(&rightEyeFrame) != S_OK)) { - rightEyeFrame = NULL; - } - - if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) { - emit gotMessage(i18n("Frame (%1) - No input signal", frameCount)); - fprintf(stderr, "Frame received (#%lu) - No input signal detected\n", frameCount); - } else { - const char *timecodeString = NULL; - if (g_timecodeFormat != 0) { - IDeckLinkTimecode *timecode; - if (videoFrame->GetTimecode(g_timecodeFormat, &timecode) == S_OK) { - timecode->GetString(&timecodeString); - } - } - // There seems to be No timecode with HDMI... Using frame number - emit gotTimeCode(frameCount); - /*fprintf(stderr, "Frame received (#%lu) [%s] - %s - Size: %li bytes\n", - frameCount, - timecodeString != NULL ? timecodeString : "No timecode", - rightEyeFrame != NULL ? "Valid Frame (3D left/right)" : "Valid Frame", - videoFrame->GetRowBytes() * videoFrame->GetHeight());*/ - - if (timecodeString) - free((void*)timecodeString); - - if (!doCaptureFrame.isEmpty()) { - videoFrame->AddRef(); - m_framesList.append(videoFrame); - m_framePath.append(doCaptureFrame); - doCaptureFrame.clear(); - QtConcurrent::run(this, &DeckLinkCaptureDelegate::slotProcessFrame); - } - if (m_analyseFrame) { - QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied); - //convert from uyvy422 to rgba - videoFrame->GetBytes(&frameBytes); - CaptureHandler::uyvy2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight()); - emit gotFrame(image); - } - - if (videoOutputFile != -1) { - if (!m_analyseFrame) videoFrame->GetBytes(&frameBytes); - safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight()); - - if (rightEyeFrame) { - rightEyeFrame->GetBytes(&frameBytes); - safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight()); - } - } - } - frameCount++; - - if (g_maxFrames > 0 && frameCount >= (uint) g_maxFrames) { - pthread_cond_signal(&sleepCond); - } - } - - // Handle Audio Frame - if (audioFrame) { - if (audioOutputFile != -1) { - audioFrame->GetBytes(&audioFrameBytes); - safe_write(audioOutputFile, audioFrameBytes, audioFrame->GetSampleFrameCount() * g_audioChannels *(g_audioSampleDepth / 8)); - } - } - return S_OK; -} - -HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags) -{ - Q_UNUSED(events) - Q_UNUSED(mode) - return S_OK; -} - -/*int usage(int status) -{ - HRESULT result; - IDeckLinkDisplayMode *displayMode; - int displayModeCount = 0; - - fprintf(stderr, - "Usage: Capture -m [OPTIONS]\n" - "\n" - " -m :\n" - ); - - while (displayModeIterator->Next(&displayMode) == S_OK) - { - char * displayModeString = NULL; - - result = displayMode->GetName((const char **) &displayModeString); - if (result == S_OK) - { - BMDTimeValue frameRateDuration, frameRateScale; - displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); - - fprintf(stderr, " %2d: %-20s \t %li x %li \t %g FPS\n", - displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), (double)frameRateScale / (double)frameRateDuration); - - free(displayModeString); - displayModeCount++; - } - - // Release the IDeckLinkDisplayMode object to prevent a leak - displayMode->Release(); - } - - fprintf(stderr, - " -p \n" - " 0: 8 bit YUV (4:2:2) (default)\n" - " 1: 10 bit YUV (4:2:2)\n" - " 2: 10 bit RGB (4:4:4)\n" - " -t Print timecode\n" - " rp188: RP 188\n" - " vitc: VITC\n" - " serial: Serial Timecode\n" - " -f Filename raw video will be written to\n" - " -a Filename raw audio will be written to\n" - " -c Audio Channels (2, 8 or 16 - default is 2)\n" - " -s Audio Sample Depth (16 or 32 - default is 16)\n" - " -n Number of frames to capture (default is unlimited)\n" - " -3 Capture Stereoscopic 3D (Requires 3D Hardware support)\n" - "\n" - "Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n" - "\n" - " Capture -m2 -n 50 -f video.raw -a audio.raw\n" - " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n" - ); - - exit(status); -} -*/ - - - - -BmdCaptureHandler::BmdCaptureHandler(QVBoxLayout *lay, QWidget *parent): - CaptureHandler(lay, parent), - previewView(NULL), - deckLinkIterator(NULL), - delegate(NULL), - displayMode(NULL), - deckLink(NULL), - deckLinkInput(NULL), - displayModeIterator(NULL) -{ -} - -QStringList BmdCaptureHandler::getDeviceName(QString) -{ - return QStringList(); -} - -void BmdCaptureHandler::startPreview(int deviceId, int captureMode, bool audio) -{ - deckLinkIterator = CreateDeckLinkIteratorInstance(); - BMDVideoInputFlags inputFlags = 0; - BMDDisplayMode selectedDisplayMode = bmdModeNTSC; - BMDPixelFormat pixelFormat = bmdFormat8BitYUV; - int displayModeCount = 0; - int exitStatus = 1; - //int ch; - bool foundDisplayMode = false; - HRESULT result = 1; - - /*pthread_mutex_init(&sleepMutex, NULL); - pthread_cond_init(&sleepCond, NULL);*/ - kDebug() << "/// INIT CAPTURE ON DEV: " << deviceId; - - if (!deckLinkIterator) { - emit gotMessage(i18n("This application requires the DeckLink drivers installed.")); - fprintf(stderr, "This application requires the DeckLink drivers installed.\n"); - stopCapture(); - return; - } - - /* Connect to selected DeckLink instance */ - for (int i = 0; i < deviceId + 1; i++) - result = deckLinkIterator->Next(&deckLink); - if (result != S_OK) { - fprintf(stderr, "No DeckLink PCI cards found.\n"); - emit gotMessage(i18n("No DeckLink PCI cards found.")); - stopCapture(); - return; - } - - if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK) { - stopCapture(); - return; - } - - delegate = new DeckLinkCaptureDelegate(); - delegate->setAnalyse(m_analyseFrame); - connect(delegate, SIGNAL(gotTimeCode(ulong)), this, SIGNAL(gotTimeCode(ulong))); - connect(delegate, SIGNAL(gotFrame(QImage)), this, SIGNAL(gotFrame(QImage))); - connect(delegate, SIGNAL(gotMessage(const QString &)), this, SIGNAL(gotMessage(const QString &))); - connect(delegate, SIGNAL(frameSaved(const QString)), this, SIGNAL(frameSaved(const QString))); - deckLinkInput->SetCallback(delegate); - - previewView = new CDeckLinkGLWidget(deckLinkInput, m_parent); - m_layout->addWidget(previewView); - //previewView->resize(parent->size()); - previewView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - previewView->DrawFrame(NULL); - - // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output - result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); - if (result != S_OK) { - emit gotMessage(i18n("Could not obtain the video output display mode iterator - result = ", result)); - fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result); - stopCapture(); - return; - } - - g_videoModeIndex = captureMode; - /*g_audioChannels = 2; - g_audioSampleDepth = 16;*/ - - // Parse command line options - /*while ((ch = getopt(argc, argv, "?h3c:s:f:a:m:n:p:t:")) != -1) - { - switch (ch) - { - case 'm': - g_videoModeIndex = atoi(optarg); - break; - case 'c': - g_audioChannels = atoi(optarg); - if (g_audioChannels != 2 && - g_audioChannels != 8 && - g_audioChannels != 16) - { - fprintf(stderr, "Invalid argument: Audio Channels must be either 2, 8 or 16\n"); - stopCapture(); - } - break; - case 's': - g_audioSampleDepth = atoi(optarg); - if (g_audioSampleDepth != 16 && g_audioSampleDepth != 32) - { - fprintf(stderr, "Invalid argument: Audio Sample Depth must be either 16 bits or 32 bits\n"); - stopCapture(); - } - break; - case 'f': - g_videoOutputFile = optarg; - break; - case 'a': - g_audioOutputFile = optarg; - break; - case 'n': - g_maxFrames = atoi(optarg); - break; - case '3': - inputFlags |= bmdVideoInputDualStream3D; - break; - case 'p': - switch(atoi(optarg)) - { - case 0: pixelFormat = bmdFormat8BitYUV; break; - case 1: pixelFormat = bmdFormat10BitYUV; break; - case 2: pixelFormat = bmdFormat10BitRGB; break; - default: - fprintf(stderr, "Invalid argument: Pixel format %d is not valid", atoi(optarg)); - stopCapture(); - } - break; - case 't': - if (!strcmp(optarg, "rp188")) - g_timecodeFormat = bmdTimecodeRP188; - else if (!strcmp(optarg, "vitc")) - g_timecodeFormat = bmdTimecodeVITC; - else if (!strcmp(optarg, "serial")) - g_timecodeFormat = bmdTimecodeSerial; - else - { - fprintf(stderr, "Invalid argument: Timecode format \"%s\" is invalid\n", optarg); - stopCapture(); - } - break; - case '?': - case 'h': - usage(0); - } - }*/ - - if (g_videoModeIndex < 0) { - emit gotMessage(i18n("No video mode specified")); - fprintf(stderr, "No video mode specified\n"); - stopCapture(); - return; - } - - /*if (g_videoOutputFile != NULL) - { - videoOutputFile = open(g_videoOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664); - if (videoOutputFile < 0) - { - emit gotMessage(i18n("Could not open video output file %1", g_videoOutputFile)); - fprintf(stderr, "Could not open video output file \"%s\"\n", g_videoOutputFile); - stopCapture(); - } - } - if (g_audioOutputFile != NULL) - { - audioOutputFile = open(g_audioOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664); - if (audioOutputFile < 0) - { - emit gotMessage(i18n("Could not open audio output file %1", g_audioOutputFile)); - fprintf(stderr, "Could not open audio output file \"%s\"\n", g_audioOutputFile); - stopCapture(); - } - }*/ - - while (displayModeIterator->Next(&displayMode) == S_OK) { - if (g_videoModeIndex == displayModeCount) { - BMDDisplayModeSupport result; - const char *displayModeName; - - foundDisplayMode = true; - displayMode->GetName(&displayModeName); - selectedDisplayMode = displayMode->GetDisplayMode(); - - g_aspect_ratio = (double) displayMode->GetWidth() / (double) displayMode->GetHeight(); - - deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL); - - if (result == bmdDisplayModeNotSupported) { - emit gotMessage(i18n("The display mode %1 is not supported with the selected pixel format", displayModeName)); - fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName); - stopCapture(); - return; - } - - if (inputFlags & bmdVideoInputDualStream3D) { - if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) { - emit gotMessage(i18n("The display mode %1 is not supported with 3D", displayModeName)); - fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName); - stopCapture(); - return; - } - } - - break; - } - displayModeCount++; - displayMode->Release(); - } - - if (!foundDisplayMode) { - emit gotMessage(i18n("Invalid mode %1 specified", g_videoModeIndex)); - fprintf(stderr, "Invalid mode %d specified\n", g_videoModeIndex); - stopCapture(); - return; - } - - result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags); - if (result != S_OK) { - emit gotMessage(i18n("Failed to enable video input. Is another application using the card?")); - fprintf(stderr, "Failed to enable video input. Is another application using the card?\n"); - stopCapture(); - return; - } - - if (audio) { - result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels); - if (result != S_OK) { - stopCapture(); - return; - } - } - deckLinkInput->SetScreenPreviewCallback(previewView); - result = deckLinkInput->StartStreams(); - if (result != S_OK) { - qDebug() << "/// CAPTURE FAILED...."; - emit gotMessage(i18n("Capture failed")); - } - - // All Okay. - exitStatus = 0; - - // Block main thread until signal occurs - /* pthread_mutex_lock(&sleepMutex); - pthread_cond_wait(&sleepCond, &sleepMutex); - pthread_mutex_unlock(&sleepMutex);*/ - - /*bail: - - if (videoOutputFile) - close(videoOutputFile); - if (audioOutputFile) - close(audioOutputFile); - - if (displayModeIterator != NULL) - { - displayModeIterator->Release(); - displayModeIterator = NULL; - } - - if (deckLinkInput != NULL) - { - deckLinkInput->Release(); - deckLinkInput = NULL; - } - - if (deckLink != NULL) - { - deckLink->Release(); - deckLink = NULL; - } - - if (deckLinkIterator != NULL) - deckLinkIterator->Release(); - */ -} - -BmdCaptureHandler::~BmdCaptureHandler() -{ - stopCapture(); -} - -void BmdCaptureHandler::startCapture(const QString &path) -{ - int i = 0; - QString videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw"; - QString audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw"; - while (QFile::exists(videopath) || QFile::exists(audiopath)) { - i++; - videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw"; - audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw"; - } - videoOutputFile = open(videopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664); - if (videoOutputFile < 0) { - emit gotMessage(i18n("Could not open video output file %1", videopath)); - fprintf(stderr, "Could not open video output file \"%s\"\n", videopath.toUtf8().constData()); - return; - } - /*if (KdenliveSettings::hdmicaptureaudio()) { - audioOutputFile = open(audiopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664); - if (audioOutputFile < 0) { - emit gotMessage(i18n("Could not open audio output file %1", audiopath)); - fprintf(stderr, "Could not open video output file \"%s\"\n", audiopath.toUtf8().constData()); - return; - } - }*/ -} - -void BmdCaptureHandler::stopCapture() -{ - if (videoOutputFile) - close(videoOutputFile); - if (audioOutputFile) - close(audioOutputFile); - videoOutputFile = -1; - audioOutputFile = -1; -} - -void BmdCaptureHandler::captureFrame(const QString &fname) -{ - doCaptureFrame = fname; -} - -void BmdCaptureHandler::showOverlay(QImage img, bool transparent) -{ - if (previewView) previewView->showOverlay(img, transparent); -} - -void BmdCaptureHandler::hideOverlay() -{ - if (previewView) previewView->hideOverlay(); -} - -void BmdCaptureHandler::setDevice(const QString , QString) -{ -} - -void BmdCaptureHandler::hidePreview(bool hide) -{ - if (previewView) previewView->setHidden(hide); -} - -void BmdCaptureHandler::stopPreview() -{ - if (!previewView) return; - if (deckLinkInput != NULL) deckLinkInput->StopStreams(); - if (videoOutputFile) - close(videoOutputFile); - if (audioOutputFile) - close(audioOutputFile); - - if (displayModeIterator != NULL) { - displayModeIterator->Release(); - displayModeIterator = NULL; - } - - if (deckLinkInput != NULL) { - deckLinkInput->Release(); - deckLinkInput = NULL; - } - - if (deckLink != NULL) { - deckLink->Release(); - deckLink = NULL; - } - - if (deckLinkIterator != NULL) { - deckLinkIterator->Release(); - deckLinkIterator = NULL; - } - - if (previewView != NULL) { - delete previewView; - previewView = NULL; - } - - /*if (delegate != NULL) - delete delegate;*/ - -} diff --git a/src/blackmagic/capture.h b/src/blackmagic/capture.h deleted file mode 100644 index 5e038caf..00000000 --- a/src/blackmagic/capture.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __BMDCAPTURE_H__ -#define __BMDCAPTURE_H__ - -#include "include/DeckLinkAPI.h" -#include "../stopmotion/capturehandler.h" - -#include -#include -#include -#if defined(Q_WS_MAC) || defined(Q_OS_FREEBSD) -#include -#endif - -class CDeckLinkGLWidget; -class PlaybackDelegate; - -class DeckLinkCaptureDelegate : public QObject, public IDeckLinkInputCallback -{ - Q_OBJECT -public: - DeckLinkCaptureDelegate(); - virtual ~DeckLinkCaptureDelegate(); - void setAnalyse(bool isOn); - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID /*iid*/, LPVOID */*ppv*/) { - return E_NOINTERFACE; - } - virtual ULONG STDMETHODCALLTYPE AddRef(void); - virtual ULONG STDMETHODCALLTYPE Release(void); - virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents, IDeckLinkDisplayMode*, BMDDetectedVideoInputFormatFlags); - virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*); - -private: - ULONG m_refCount; - pthread_mutex_t m_mutex; - QList m_framesList; - QStringList m_framePath; - bool m_analyseFrame; - -private slots: - void slotProcessFrame(); - -signals: - void gotTimeCode(ulong); - void gotMessage(const QString &); - void frameSaved(const QString); - void gotFrame(QImage); -}; - -class BmdCaptureHandler : public CaptureHandler -{ - Q_OBJECT -public: - BmdCaptureHandler(QVBoxLayout *lay, QWidget *parent = 0); - ~BmdCaptureHandler(); - CDeckLinkGLWidget *previewView; - void startPreview(int deviceId, int captureMode, bool audio = true); - void stopPreview(); - void startCapture(const QString &path); - void stopCapture(); - void captureFrame(const QString &fname); - void showOverlay(QImage img, bool transparent = true); - void hideOverlay(); - void hidePreview(bool hide); - QStringList getDeviceName(QString); - void setDevice(const QString input, QString size = QString()); - -private: - IDeckLinkIterator *deckLinkIterator; - DeckLinkCaptureDelegate *delegate; - IDeckLinkDisplayMode *displayMode; - IDeckLink *deckLink; - IDeckLinkInput *deckLinkInput; - IDeckLinkDisplayModeIterator *displayModeIterator; -}; - - -#endif diff --git a/src/mltdevicecapture.cpp b/src/mltdevicecapture.cpp index 3f4f9794..f9e647f1 100644 --- a/src/mltdevicecapture.cpp +++ b/src/mltdevicecapture.cpp @@ -218,7 +218,7 @@ void MltDeviceCapture::stop() m_mltProducer = NULL; } // For some reason, the consumer seems to be deleted by previous stuff when in playlist mode - if (!isPlaylist) delete m_mltConsumer; + if (!isPlaylist && m_mltConsumer) delete m_mltConsumer; m_mltConsumer = NULL; } @@ -282,7 +282,9 @@ void MltDeviceCapture::showAudio(Mlt::Frame& frame) bool MltDeviceCapture::slotStartPreview(const QString &producer, bool xmlFormat) { - if (m_mltConsumer == NULL) buildConsumer(); + if (m_mltConsumer == NULL) { + buildConsumer(); + } char *tmp = qstrdup(producer.toUtf8().constData()); if (xmlFormat) m_mltProducer = new Mlt::Producer(*m_mltProfile, "xml-string", tmp); else m_mltProducer = new Mlt::Producer(*m_mltProfile, tmp); diff --git a/src/recmonitor.cpp b/src/recmonitor.cpp index 7ee3f745..9083abc2 100644 --- a/src/recmonitor.cpp +++ b/src/recmonitor.cpp @@ -53,7 +53,6 @@ RecMonitor::RecMonitor(QString name, MonitorManager *manager, QWidget *parent) : m_isCapturing(false), m_didCapture(false), m_isPlaying(false), - m_blackmagicCapturing(false), m_manager(manager), m_captureDevice(NULL), m_analyse(false) @@ -126,8 +125,6 @@ RecMonitor::RecMonitor(QString name, MonitorManager *manager, QWidget *parent) : #endif control_frame_firewire->setLayout(layout); - - slotVideoDeviceChanged(device_selector->currentIndex()); m_displayProcess = new QProcess; m_captureProcess = new QProcess; @@ -160,6 +157,7 @@ RecMonitor::RecMonitor(QString name, MonitorManager *manager, QWidget *parent) : setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1); kDebug() << "/////// BUILDING MONITOR, ID: " << video_frame->winId(); + slotVideoDeviceChanged(device_selector->currentIndex()); } RecMonitor::~RecMonitor() @@ -212,8 +210,6 @@ void RecMonitor::slotVideoDeviceChanged(int ix) { QString capturefile; QString capturename; - QString path; - m_videoBox->setHidden(true); enable_preview->setHidden(ix != VIDEO4LINUX && ix != BLACKMAGIC); m_fwdAction->setVisible(ix == FIREWIRE); m_discAction->setVisible(ix == FIREWIRE); @@ -227,6 +223,10 @@ void RecMonitor::slotVideoDeviceChanged(int ix) m_captureDevice = NULL; m_manager->clearScopeSource(); } + + // The m_videoBox container has to be shown once before the MLT consumer is build, or preview will fail + m_videoBox->setHidden(ix != VIDEO4LINUX && ix != BLACKMAGIC); + m_videoBox->setHidden(true); switch (ix) { case SCREENGRAB: m_discAction->setEnabled(false); @@ -245,8 +245,7 @@ void RecMonitor::slotVideoDeviceChanged(int ix) case VIDEO4LINUX: m_stopAction->setEnabled(false); m_playAction->setEnabled(true); - path = KStandardDirs::locateLocal("appdata", "profiles/video4linux"); - if (checkDeviceAvailability()) buildMltDevice(path); + checkDeviceAvailability(); break; case BLACKMAGIC: m_stopAction->setEnabled(false); @@ -258,8 +257,6 @@ void RecMonitor::slotVideoDeviceChanged(int ix) capturename.append(KdenliveSettings::decklink_extension()); capturefile.append(capturename); video_frame->setPixmap(mergeSideBySide(KIcon("camera-photo").pixmap(QSize(50, 50)), i18n("Plug your camcorder and\npress play button\nto start preview.\nFiles will be saved in:\n%1", capturefile))); - path = KdenliveSettings::current_profile(); - buildMltDevice(path); break; default: // FIREWIRE m_discAction->setEnabled(true); @@ -300,11 +297,6 @@ void RecMonitor::slotVideoDeviceChanged(int ix) } } -void RecMonitor::slotGotBlackmagicFrameNumber(ulong ix) -{ - m_dvinfo.setText(QString::number(ix)); -} - void RecMonitor::slotSetInfoMessage(const QString &message) { m_logger.insertItem(0, message); @@ -329,16 +321,14 @@ QPixmap RecMonitor::mergeSideBySide(const QPixmap& pix, const QString txt) } -bool RecMonitor::checkDeviceAvailability() +void RecMonitor::checkDeviceAvailability() { if (!KIO::NetAccess::exists(KUrl(KdenliveSettings::video4vdevice()), KIO::NetAccess::SourceSide , this)) { m_playAction->setEnabled(false); m_recAction->setEnabled(false); video_frame->setPixmap(mergeSideBySide(KIcon("camera-web").pixmap(QSize(50, 50)), i18n("Cannot read from device %1\nPlease check drivers and access rights.", KdenliveSettings::video4vdevice()))); - return false; } else { video_frame->setPixmap(mergeSideBySide(KIcon("camera-web").pixmap(QSize(50, 50)), i18n("Press play or record button\nto start video capture\nFiles will be saved in:\n%1", m_capturePath))); - return true; } } diff --git a/src/recmonitor.h b/src/recmonitor.h index e6df959c..64721381 100644 --- a/src/recmonitor.h +++ b/src/recmonitor.h @@ -100,14 +100,11 @@ private: QAction *m_stopAction; QAction *m_discAction; - - /** @brief Indicates whether we are currently capturing from BLACKMAGIC. */ - bool m_blackmagicCapturing; MonitorManager *m_manager; MltDeviceCapture *m_captureDevice; VideoPreviewContainer *m_videoBox; bool m_analyse; - bool checkDeviceAvailability(); + void checkDeviceAvailability(); QPixmap mergeSideBySide(const QPixmap& pix, const QString txt); void manageCapturedFiles(); /** @brief Build MLT producer for device, using path as profile. */ @@ -125,7 +122,6 @@ private slots: void slotConfigure(); void slotReadDvgrabInfo(); void slotUpdateFreeSpace(); - void slotGotBlackmagicFrameNumber(ulong ix); void slotSetInfoMessage(const QString &message); void slotDroppedFrames(int dropped); diff --git a/src/stopmotion/stopmotion.h b/src/stopmotion/stopmotion.h index cf88542e..1ddb4c5a 100644 --- a/src/stopmotion/stopmotion.h +++ b/src/stopmotion/stopmotion.h @@ -19,7 +19,6 @@ #define STOPMOTION_H #include "ui_stopmotion_ui.h" -#include "../blackmagic/capture.h" #include #include diff --git a/src/v4l/dec_bayer.c b/src/v4l/dec_bayer.c deleted file mode 100644 index ba27e85e..00000000 --- a/src/v4l/dec_bayer.c +++ /dev/null @@ -1,107 +0,0 @@ -/* fswebcam - Small and simple webcam for *nix */ -/*============================================================*/ -/* Copyright (C)2005-2010 Philip Heron */ -/* */ -/* This program is distributed under the terms of the GNU */ -/* General Public License, version 2. You may use, modify, */ -/* and redistribute it under the terms of this license. A */ -/* copy should be included with this source. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -/*#include "fswebcam.h"*/ -#include "src.h" - - -int fswc_add_image_bayer(avgbmp_t *dst, uint8_t *img, uint32_t length, uint32_t w, uint32_t h, int palette) -{ - uint32_t x = 0, y = 0; - uint32_t i = w * h; - - if(length < i) return(-1); - - /* SBGGR8 bayer pattern: - * - * BGBGBGBGBG - * GRGRGRGRGR - * BGBGBGBGBG - * GRGRGRGRGR - * - * SGBRG8 bayer pattern: - * - * GBGBGBGBGB - * RGRGRGRGRG - * GBGBGBGBGB - * RGRGRGRGRG - * - * SGRBG8 bayer pattern: - * - * GRGRGRGRGR - * BGBGBGBGBG - * GRGRGRGRGR - * BGBGBGBGBG - */ - - while(i-- > 0) - { - uint8_t *p[8]; - uint8_t hn, vn, di; - uint8_t r, g, b; - int mode; - - /* Setup pointers to this pixel's neighbours. */ - p[0] = img - w - 1; - p[1] = img - w; - p[2] = img - w + 1; - p[3] = img - 1; - p[4] = img + 1; - p[5] = img + w - 1; - p[6] = img + w; - p[7] = img + w + 1; - - /* Juggle pointers if they are out of bounds. */ - if(!y) { p[0]=p[5]; p[1]=p[6]; p[2]=p[7]; } - else if(y == h - 1) { p[5]=p[0]; p[6]=p[1]; p[7]=p[2]; } - if(!x) { p[0]=p[2]; p[3]=p[4]; p[5]=p[7]; } - else if(x == w - 1) { p[2]=p[0]; p[4]=p[3]; p[7]=p[5]; } - - /* Average matching neighbours. */ - hn = (*p[3] + *p[4]) / 2; - vn = (*p[1] + *p[6]) / 2; - di = (*p[0] + *p[2] + *p[5] + *p[7]) / 4; - - /* Calculate RGB */ - if(palette == SRC_PAL_BAYER) mode = (x + y) & 0x01; - else mode = ~(x + y) & 0x01; - - if(mode) - { - g = *img; - if(y & 0x01) { r = hn; b = vn; } - else { r = vn; b = hn; } - } - else if(y & 0x01) { r = *img; g = (vn + hn) / 2; b = di; } - else { b = *img; g = (vn + hn) / 2; r = di; } - - if(palette == SRC_PAL_SGRBG8) - { - uint8_t t = r; - r = b; - b = t; - } - - *(dst++) += r; - *(dst++) += g; - *(dst++) += b; - - /* Move to the next pixel (or line) */ - if(++x == w) { x = 0; y++; } - img++; - } - - return(0); -} - diff --git a/src/v4l/dec_grey.c b/src/v4l/dec_grey.c deleted file mode 100644 index 28cfbfd7..00000000 --- a/src/v4l/dec_grey.c +++ /dev/null @@ -1,51 +0,0 @@ -/* fswebcam - Small and simple webcam for *nix */ -/*============================================================*/ -/* Copyright (C)2005-2010 Philip Heron */ -/* */ -/* This program is distributed under the terms of the GNU */ -/* General Public License, version 2. You may use, modify, */ -/* and redistribute it under the terms of this license. A */ -/* copy should be included with this source. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "src.h" - -int fswc_add_image_y16(src_t *src, avgbmp_t *abitmap) -{ - uint16_t *bitmap = (uint16_t *) src->img; - uint32_t i = src->width * src->height; - - if(src->length < i) return(-1); - - while(i-- > 0) - { - *(abitmap++) += *bitmap >> 8; - *(abitmap++) += *bitmap >> 8; - *(abitmap++) += *(bitmap++) >> 8; - } - - return(0); -} - -int fswc_add_image_grey(src_t *src, avgbmp_t *abitmap) -{ - uint8_t *bitmap = (uint8_t *) src->img; - uint32_t i = src->width * src->height; - - if(src->length < i) return(-1); - - while(i-- > 0) - { - *(abitmap++) += *bitmap; - *(abitmap++) += *bitmap; - *(abitmap++) += *(bitmap++); - } - - return(0); -} - diff --git a/src/v4l/dec_jpeg.c b/src/v4l/dec_jpeg.c deleted file mode 100644 index a6796973..00000000 --- a/src/v4l/dec_jpeg.c +++ /dev/null @@ -1,108 +0,0 @@ -/* fswebcam - Small and simple webcam for *nix */ -/*============================================================*/ -/* Copyright (C)2005-2010 Philip Heron */ -/* */ -/* This program is distributed under the terms of the GNU */ -/* General Public License, version 2. You may use, modify, */ -/* and redistribute it under the terms of this license. A */ -/* copy should be included with this source. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "src.h" - -int verify_jpeg_dht(uint8_t *src, uint32_t lsrc, - uint8_t **dst, uint32_t *ldst) -{ - /* This function is based on a patch provided by Scott J. Bertin. */ - - static unsigned char dht[] = - { - 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, - 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, - 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, - 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, - 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, - 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - 0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, - 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, - 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, - 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, - 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, - 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa - }; - uint8_t *p, *i = NULL; - - /* By default we simply return the source image. */ - *dst = src; - *ldst = lsrc; - - /* Scan for an existing DHT segment or the first SOS segment. */ - for(p = src + 2; p - src < lsrc - 3 && i == NULL; ) - { - if(*(p++) != 0xFF) continue; - - if(*p == 0xD9) break; /* JPEG_EOI */ - if(*p == 0xC4) return(0); /* JPEG_DHT */ - if(*p == 0xDA && !i) i = p - 1; /* JPEG_SOS */ - - /* Move to next segment. */ - p += (p[1] << 8) + p[2]; - } - - /* If no SOS was found, insert the DHT directly after the SOI. */ - if(i == NULL) i = src + 2; - - - *ldst = lsrc + sizeof(dht); - *dst = malloc(*ldst); - if(!*dst) - { - return(-1); - } - - /* Copy the JPEG data, inserting the DHT segment. */ - memcpy((p = *dst), src, i - src); - memcpy((p += i - src), dht, sizeof(dht)); - memcpy((p += sizeof(dht)), i, lsrc - (i - src)); - - return(1); -} - - - diff --git a/src/v4l/dec_rgb.c b/src/v4l/dec_rgb.c deleted file mode 100644 index ab768578..00000000 --- a/src/v4l/dec_rgb.c +++ /dev/null @@ -1,133 +0,0 @@ -/* fswebcam - Small and simple webcam for *nix */ -/*============================================================*/ -/* Copyright (C)2005-2010 Philip Heron */ -/* */ -/* This program is distributed under the terms of the GNU */ -/* General Public License, version 2. You may use, modify, */ -/* and redistribute it under the terms of this license. A */ -/* copy should be included with this source. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "src.h" - -int fswc_add_image_rgb32(src_t *src, avgbmp_t *abitmap) -{ - uint8_t *img = (uint8_t *) src->img; - uint32_t i = src->width * src->height; - - if(src->length << 2 < i) return(-1); - - while(i-- > 0) - { - *(abitmap++) += *(img++); - *(abitmap++) += *(img++); - *(abitmap++) += *(img++); - img++; - } - - return(0); -} - -int fswc_add_image_bgr32(src_t *src, avgbmp_t *abitmap) -{ - uint8_t *img = (uint8_t *) src->img; - uint32_t p, i = src->width * src->height; - - if(src->length << 2 < i) return(-1); - - for(p = 0; p < i; p += 4) - { - abitmap[0] += img[2]; - abitmap[1] += img[1]; - abitmap[2] += img[0]; - abitmap += 3; - img += 4; - } - - return(0); -} - -int fswc_add_image_rgb24(src_t *src, avgbmp_t *abitmap) -{ - uint8_t *img = (uint8_t *) src->img; - uint32_t i = src->width * src->height * 3; - - if(src->length < i) return(-1); - while(i-- > 0) *(abitmap++) += *(img++); - - return(0); -} - -int fswc_add_image_bgr24(src_t *src, avgbmp_t *abitmap) -{ - uint8_t *img = (uint8_t *) src->img; - uint32_t p, i = src->width * src->height * 3; - - if(src->length < i) return(-1); - - for(p = 0; p < src->length; p += 3) - { - abitmap[0] += img[2]; - abitmap[1] += img[1]; - abitmap[2] += img[0]; - abitmap += 3; - img += 3; - } - - return(0); -} - -int fswc_add_image_rgb565(src_t *src, avgbmp_t *abitmap) -{ - uint16_t *img = (uint16_t *) src->img; - uint32_t i = src->width * src->height; - - if(src->length >> 1 < i) return(-1); - - while(i-- > 0) - { - uint8_t r, g, b; - - r = (*img & 0xF800) >> 8; - g = (*img & 0x7E0) >> 3; - b = (*img & 0x1F) << 3; - - *(abitmap++) += r + (r >> 5); - *(abitmap++) += g + (g >> 6); - *(abitmap++) += b + (b >> 5); - - img++; - } - - return(0); -} - -int fswc_add_image_rgb555(src_t *src, avgbmp_t *abitmap) -{ - uint16_t *img = (uint16_t *) src->img; - uint32_t i = src->width * src->height; - - if(src->length >> 1 < i) return(-1); - - while(i-- > 0) - { - uint8_t r, g, b; - - r = (*img & 0x7C00) >> 7; - g = (*img & 0x3E0) >> 2; - b = (*img & 0x1F) << 3; - - *(abitmap++) += r + (r >> 5); - *(abitmap++) += g + (g >> 5); - *(abitmap++) += b + (b >> 5); - - img++; - } - - return(0); -} - diff --git a/src/v4l/dec_s561.c b/src/v4l/dec_s561.c deleted file mode 100644 index ae1bc4fc..00000000 --- a/src/v4l/dec_s561.c +++ /dev/null @@ -1,908 +0,0 @@ -/* Spca561decoder (C) 2005 Andrzej Szombierski [qq@kuku.eu.org] */ -/*==============================================================*/ -/* This program is distributed under the terms of the GNU */ -/* General Public License, version 2. You may use, modify, */ -/* and redistribute it under the terms of this license. A */ -/* copy should be included with this source. */ - -/* - * Decoder for compressed spca561 images - * It was developed for "Labtec WebCam Elch 2(SPCA561A)" (046d:0929) - * but it might work with other spca561 cameras - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "src.h" -#include "dec.h" - -/*fixme: not reentrant */ -static unsigned int bit_bucket; -static const unsigned char *input_ptr; - -static void refill(int *bitfill) -{ - if (*bitfill < 8) { - bit_bucket = (bit_bucket << 8) | *(input_ptr++); - *bitfill += 8; - } -} - -static int nbits(int *bitfill, int n) -{ - bit_bucket = (bit_bucket << 8) | *(input_ptr++); - *bitfill -= n; - return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1); -} - -static int _nbits(int *bitfill, int n) -{ - *bitfill -= n; - return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1); -} - -static int fun_A(int *bitfill) -{ - int ret; - static int tab[] = { - 12, 13, 14, 15, 16, 17, 18, 19, -12, -13, -14, -15, - -16, -17, -18, -19, -19 - }; - - ret = tab[nbits(bitfill, 4)]; - - refill(bitfill); - return ret; -} -static int fun_B(int *bitfill) -{ - static int tab1[] = - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 16, 17, - 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 - }; - static int tab[] = - { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -5, - -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, - -18, -19 - }; - unsigned int tmp; - - tmp = nbits(bitfill, 7) - 68; - refill(bitfill); - if (tmp > 47) - return 0xff; - return tab[tab1[tmp]]; -} -static int fun_C(int *bitfill, int gkw) -{ - static int tab1[] = - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 12, 13, - 14, - 15, 16, 17, 18, 19, 20, 21, 22 - }; - static int tab[] = - { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -9, -10, -11, - -12, -13, -14, -15, -16, -17, -18, -19 - }; - unsigned int tmp; - - if (gkw == 0xfe) { - if (nbits(bitfill, 1) == 0) - return 7; - else - return -8; - } - - if (gkw != 0xff) - return 0xff; - - tmp = nbits(bitfill, 7) - 72; - if (tmp > 43) - return 0xff; - - refill(bitfill); - return tab[tab1[tmp]]; -} -static int fun_D(int *bitfill, int gkw) -{ - if (gkw == 0xfd) { - if (nbits(bitfill, 1) == 0) - return 12; - return -13; - } - - if (gkw == 0xfc) { - if (nbits(bitfill, 1) == 0) - return 13; - return -14; - } - - if (gkw == 0xfe) { - switch (nbits(bitfill, 2)) { - case 0: - return 14; - case 1: - return -15; - case 2: - return 15; - case 3: - return -16; - } - } - - if (gkw == 0xff) { - switch (nbits(bitfill, 3)) { - case 4: - return 16; - case 5: - return -17; - case 6: - return 17; - case 7: - return -18; - case 2: - return _nbits(bitfill, 1) ? 0xed : 0x12; - case 3: - (*bitfill)--; - return 18; - } - return 0xff; - } - return gkw; -} - -static int fun_E(int cur_byte, int *bitfill) -{ - static int tab0[] = { 0, -1, 1, -2, 2, -3, 3, -4 }; - static int tab1[] = { 4, -5, 5, -6, 6, -7, 7, -8 }; - static int tab2[] = { 8, -9, 9, -10, 10, -11, 11, -12 }; - static int tab3[] = { 12, -13, 13, -14, 14, -15, 15, -16 }; - static int tab4[] = { 16, -17, 17, -18, 18, -19, 19, -19 }; - - if ((cur_byte & 0xf0) >= 0x80) { - *bitfill -= 4; - return tab0[(cur_byte >> 4) & 7]; - } - if ((cur_byte & 0xc0) == 0x40) { - *bitfill -= 5; - return tab1[(cur_byte >> 3) & 7]; - - } - if ((cur_byte & 0xe0) == 0x20) { - *bitfill -= 6; - return tab2[(cur_byte >> 2) & 7]; - - } - if ((cur_byte & 0xf0) == 0x10) { - *bitfill -= 7; - return tab3[(cur_byte >> 1) & 7]; - - } - if ((cur_byte & 0xf8) == 8) { - *bitfill -= 8; - return tab4[cur_byte & 7]; - } - return 0xff; -} - -static int fun_F(int cur_byte, int *bitfill) -{ - *bitfill -= 5; - switch (cur_byte & 0xf8) { - case 0x80: - return 0; - case 0x88: - return -1; - case 0x90: - return 1; - case 0x98: - return -2; - case 0xa0: - return 2; - case 0xa8: - return -3; - case 0xb0: - return 3; - case 0xb8: - return -4; - case 0xc0: - return 4; - case 0xc8: - return -5; - case 0xd0: - return 5; - case 0xd8: - return -6; - case 0xe0: - return 6; - case 0xe8: - return -7; - case 0xf0: - return 7; - case 0xf8: - return -8; - } - - *bitfill -= 1; - switch (cur_byte & 0xfc) { - case 0x40: - return 8; - case 0x44: - return -9; - case 0x48: - return 9; - case 0x4c: - return -10; - case 0x50: - return 10; - case 0x54: - return -11; - case 0x58: - return 11; - case 0x5c: - return -12; - case 0x60: - return 12; - case 0x64: - return -13; - case 0x68: - return 13; - case 0x6c: - return -14; - case 0x70: - return 14; - case 0x74: - return -15; - case 0x78: - return 15; - case 0x7c: - return -16; - } - - *bitfill -= 1; - switch (cur_byte & 0xfe) { - case 0x20: - return 16; - case 0x22: - return -17; - case 0x24: - return 17; - case 0x26: - return -18; - case 0x28: - return 18; - case 0x2a: - return -19; - case 0x2c: - return 19; - } - - *bitfill += 7; - return 0xff; -} - -static int spca561_decode(int width, int height, - const unsigned char *inbuf, - unsigned char *outbuf) -{ - /* buffers */ - static int accum[8 * 8 * 8]; - static int i_hits[8 * 8 * 8]; - - const int nbits_A[] = - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, - 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - }; - const int tab_A[] = - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 11, -11, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, - 10, 10, - 255, 254, -4, - -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9, -10, -10, -1, - -1, -1, - -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, - 3, 3, 3, - -2, -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3, - -3, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, - 1 - }; - - const int nbits_B[] = - { 0, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }; - const int tab_B[] = - { 0xff, -4, 3, 3, -3, -3, -3, -3, 2, 2, 2, 2, 2, 2, 2, 2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - }; - - const int nbits_C[] = - { 0, 0, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, - 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - }; - const int tab_C[] = - { 0xff, 0xfe, 6, -7, 5, 5, -6, -6, 4, 4, 4, 4, -5, -5, -5, -5, - 3, 3, 3, 3, 3, 3, 3, 3, -4, -4, -4, -4, -4, -4, -4, -4, 2, - 2, 2, 2, - 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, -3, -3, -3, -3, -3, -3, -3, -3, - -3, -3, - -3, -3, -3, - -3, -3, -3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, -2, -2, -2, -2, -2, -2, - -2, -2, - -2, -2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - -2, -2, - -2, -2, - -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, - }; - - const int nbits_D[] = - { 0, 0, 0, 0, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, - 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, - 4, 4, - 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, - 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, - 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - }; - const int tab_D[] = - { 0xff, 0xfe, 0xfd, 0xfc, 10, -11, 11, -12, 8, 8, -9, -9, 9, 9, - -10, -10, 6, 6, 6, 6, -7, -7, -7, -7, 7, 7, 7, 7, -8, -8, - -8, -8, - 4, 4, 4, 4, - 4, 4, 4, 4, -5, -5, -5, -5, -5, -5, -5, -5, 5, 5, 5, 5, 5, - 5, 5, 5, - -6, -6, - -6, -6, -6, -6, -6, -6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, -3, - -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, - 3, 3, - 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -4, -4, -4, -4, -4, -4, -4, - -4, -4, - -4, -4, -4, - -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, -2, -2, -2, -2, -2, -2, -2, - -2, -2, - -2, -2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - -2, -2, - -2, -2 - }; - - /* a_curve[19 + i] = ... [-19..19] => [-160..160] */ - const int a_curve[] = - { -160, -144, -128, -112, -98, -88, -80, -72, -64, -56, -48, - -40, -32, -24, -18, -12, -8, -5, -2, 0, 2, 5, 8, 12, 18, - 24, 32, - 40, 48, 56, 64, - 72, 80, 88, 98, 112, 128, 144, 160 - }; - /* clamp0_255[256 + i] = min(max(i,255),0) */ - const unsigned char clamp0_255[] = - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, - 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, - 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, - 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, - 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, - 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, - 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, - 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, - 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, - 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, - 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, - 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, - 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255 - }; - /* abs_clamp15[19 + i] = min(abs(i), 15) */ - const int abs_clamp15[] = - { 15, 15, 15, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, - 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 15, 15, - 15 - }; - /* diff_encoding[256 + i] = ... */ - const int diff_encoding[] = - { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, - 5, 5, - 5, 5, 5, 5, 5, 3, 3, - 3, 3, 1, 1, 0, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6 - }; - - int block; - int bitfill = 0; - int xwidth = width + 6; - int off_up_right = 2 - 2 * xwidth; - int off_up_left = -2 - 2 * xwidth; - int pixel_U = 0, saved_pixel_UR = 0; - int pixel_x = 0, pixel_y = 2; - unsigned char *output_ptr = outbuf; - - memset(i_hits, 0, sizeof(i_hits)); - memset(accum, 0, sizeof(accum)); - - memcpy(outbuf + xwidth * 2 + 3, inbuf + 0x14, width); - memcpy(outbuf + xwidth * 3 + 3, inbuf + 0x14 + width, width); - - input_ptr = inbuf + 0x14 + width * 2; - output_ptr = outbuf + (xwidth) * 4 + 3; - - bit_bucket = 0; - - for (block = 0; block < ((height - 2) * width) / 32; ++block) { - int b_it, var_7 = 0; - int cur_byte; - - refill(&bitfill); - - cur_byte = (bit_bucket >> (bitfill & 7)) & 0xff; - - if ((cur_byte & 0x80) == 0) { - var_7 = 0; - bitfill--; - } else if ((cur_byte & 0xC0) == 0x80) { - var_7 = 1; - bitfill -= 2; - } else if ((cur_byte & 0xc0) == 0xc0) { - var_7 = 2; - bitfill -= 2; - } - - for (b_it = 0; b_it < 32; b_it++) { - int index; - int pixel_L, pixel_UR, pixel_UL; - int multiplier; - int dL, dC, dR; - int gkw; /* God knows what */ - - refill(&bitfill); - cur_byte = bit_bucket >> (bitfill & 7) & 0xff; - - pixel_L = output_ptr[-2]; - pixel_UR = output_ptr[off_up_right]; - pixel_UL = output_ptr[off_up_left]; - - dL = diff_encoding[0x100 + pixel_UL - pixel_L]; - dC = diff_encoding[0x100 + pixel_U - pixel_UL]; - dR = diff_encoding[0x100 + pixel_UR - pixel_U]; - - if (pixel_x < 2) { - pixel_L = pixel_UL = pixel_U = - output_ptr[-xwidth * 2]; - pixel_UR = output_ptr[off_up_right]; - dL = dC = 0; - dR = diff_encoding[0x100 + pixel_UR - - pixel_U]; - } else if (pixel_x > width - 3) - dR = 0; - - multiplier = 4; - index = dR + dC * 8 + dL * 64; - - if (pixel_L + pixel_U * 2 <= 144 - && (pixel_y & 1) == 0 - && (b_it & 3) == 0 && (dR < 5) && (dC < 5) - && (dL < 5)) { - multiplier = 1; - } else if (pixel_L <= 48 - && dL <= 4 && dC <= 4 && dL >= 1 - && dC >= 1) { - multiplier = 2; - } else if (var_7 == 1) { - multiplier = 2; - } else if (dC + dL >= 11 || var_7 == 2) { - multiplier = 8; - } - - if (i_hits[index] < 7) { - bitfill -= nbits_A[cur_byte]; - gkw = tab_A[cur_byte]; - if (gkw == 0xfe) - gkw = fun_A(&bitfill); - } else if (i_hits[index] >= accum[index]) { - bitfill -= nbits_B[cur_byte]; - gkw = tab_B[cur_byte]; - if (cur_byte == 0) - gkw = fun_B(&bitfill); - } else if (i_hits[index] * 2 >= accum[index]) { - bitfill -= nbits_C[cur_byte]; - gkw = tab_C[cur_byte]; - if (cur_byte < 2) - gkw = fun_C(&bitfill, gkw); - } else if (i_hits[index] * 4 >= accum[index]) { - bitfill -= nbits_D[cur_byte]; - gkw = tab_D[cur_byte]; - if (cur_byte < 4) - gkw = fun_D(&bitfill, gkw); - } else if (i_hits[index] * 8 >= accum[index]) { - gkw = fun_E(cur_byte, &bitfill); - } else { - gkw = fun_F(cur_byte, &bitfill); - } - - if (gkw == 0xff) - return -3; - - { - int tmp1, tmp2; - - tmp1 = - (pixel_U + pixel_L) * 3 - pixel_UL * 2; - tmp1 += (tmp1 < 0) ? 3 : 0; - tmp2 = a_curve[19 + gkw] * multiplier; - tmp2 += (tmp2 < 0) ? 1 : 0; - - *(output_ptr++) = - clamp0_255[0x100 + (tmp1 >> 2) - - (tmp2 >> 1)]; - } - pixel_U = saved_pixel_UR; - saved_pixel_UR = pixel_UR; - - if (++pixel_x == width) { - output_ptr += 6; - pixel_x = 0; - pixel_y++; - } - - accum[index] += abs_clamp15[19 + gkw]; - - if (i_hits[index]++ == 15) { - i_hits[index] = 8; - accum[index] /= 2; - } - } - } - return 0; -} - -/* FIXME, change spca561_decode not to need the extra border - around its dest buffer */ -int fswc_add_image_s561(avgbmp_t *dst, uint8_t *img, uint32_t length, uint32_t width, uint32_t height, int palette) -{ - uint x, y; - uint8_t *s, *d; - unsigned char tmpimg[650 * 490]; - - if(spca561_decode(width, height, img, tmpimg) != 0) - { - return(-1); - } - - /* Remove buffer border */ - d = tmpimg; - s = tmpimg + 2 * (width + 6) + 3; - for(y = 0; y < height; y++) - { - for(x = 0; x < width; x++) *(d++) = *(s++); - s += 6; - } - - fswc_add_image_bayer(dst, tmpimg, width * height, width, height, SRC_PAL_SGBRG8); - - return(0); -} - diff --git a/src/v4l/dec_yuv.c b/src/v4l/dec_yuv.c deleted file mode 100644 index 6336ce5e..00000000 --- a/src/v4l/dec_yuv.c +++ /dev/null @@ -1,170 +0,0 @@ -/* fswebcam - Small and simple webcam for *nix */ -/*============================================================*/ -/* Copyright (C)2005-2010 Philip Heron */ -/* */ -/* This program is distributed under the terms of the GNU */ -/* General Public License, version 2. You may use, modify, */ -/* and redistribute it under the terms of this license. A */ -/* copy should be included with this source. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "src.h" - -/* The following YUV functions are based on code by Vincent Hourdin. - * http://vinvin.dyndns.org/projects/ - * - * Faster integer maths from camE by Tom Gilbert. - * http://linuxbrit.co.uk/camE/ -*/ - -int fswc_add_image_yuyv(src_t *src, avgbmp_t *abitmap) -{ - uint8_t *ptr; - uint32_t x, y, z; - - if(src->length < (src->width * src->height * 2)) return(-1); - - /* YUYV and UYVY are very similar and so * - * are both handled by this one function. */ - - ptr = (uint8_t *) src->img; - z = 0; - - for(y = 0; y < src->height; y++) - { - for(x = 0; x < src->width; x++) - { - int r, g, b; - int y, u, v; - - if(src->palette == SRC_PAL_UYVY) - { - if(!z) y = ptr[1] << 8; - else y = ptr[3] << 8; - - u = ptr[0] - 128; - v = ptr[2] - 128; - } - else /* SRC_PAL_YUYV */ - { - if(!z) y = ptr[0] << 8; - else y = ptr[2] << 8; - - u = ptr[1] - 128; - v = ptr[3] - 128; - } - - r = (y + (359 * v)) >> 8; - g = (y - (88 * u) - (183 * v)) >> 8; - b = (y + (454 * u)) >> 8; - - *(abitmap++) += CLIP(r, 0x00, 0xFF); - *(abitmap++) += CLIP(g, 0x00, 0xFF); - *(abitmap++) += CLIP(b, 0x00, 0xFF); - - if(z++) - { - z = 0; - ptr += 4; - } - } - } - - return(0); -} - -int fswc_add_image_yuv420p(src_t *src, avgbmp_t *abitmap) -{ - uint8_t *yptr, *uptr, *vptr; - uint32_t x, y, p, o; - - if(src->length < (src->width * src->height * 3) / 2) return(-1); - - /* Setup pointers to Y, U and V buffers. */ - yptr = (uint8_t *) src->img; - uptr = yptr + (src->width * src->height); - vptr = uptr + (src->width * src->height / 4); - o = 0; - p = 0; - - for(y = 0; y < src->height; y++) - { - for(x = 0; x < src->width; x++) - { - int r, g, b; - int y, u, v; - - y = *(yptr++) << 8; - u = uptr[p] - 128; - v = vptr[p] - 128; - - r = (y + (359 * v)) >> 8; - g = (y - (88 * u) - (183 * v)) >> 8; - b = (y + (454 * u)) >> 8; - - *(abitmap++) += CLIP(r, 0x00, 0xFF); - *(abitmap++) += CLIP(g, 0x00, 0xFF); - *(abitmap++) += CLIP(b, 0x00, 0xFF); - - if(x & 1) p++; - } - - if(!(y & 1)) p -= src->width / 2; - } - - return(0); -} - -int fswc_add_image_nv12mb(src_t *src, avgbmp_t *abitmap) -{ - uint32_t x, y; - uint32_t bw; - - if(src->length != (src->width * src->height * 3) / 2) return(-1); - - bw = src->width >> 4; - - for(y = 0; y < src->height; y++) - { - for(x = 0; x < src->width; x++) - { - uint32_t bx, by; - int cy, cu, cv; - int cr, cg, cb; - uint8_t *py, *puv; - - bx = x >> 4; - by = y >> 4; - - py = src->img; - py += ((by * bw) + bx) * 0x100; - py += ((y - (by << 4)) * 0x10) + (x - (bx << 4)); - - by /= 2; - - puv = (avgbmp_t *)src->img + (src->width * src->height); - puv += ((by * bw) + bx) * 0x100; - puv += (((y / 2) - (by << 4)) * 0x10) + ((x - (bx << 4)) &~ 1); - - cy = *py << 8; - cu = puv[0] - 128; - cv = puv[1] - 128; - - cr = (cy + (359 * cv)) >> 8; - cg = (cy - (88 * cu) - (183 * cv)) >> 8; - cb = (cy + (454 * cu)) >> 8; - - *(abitmap++) += CLIP(cr, 0x00, 0xFF); - *(abitmap++) += CLIP(cg, 0x00, 0xFF); - *(abitmap++) += CLIP(cb, 0x00, 0xFF); - } - } - - return(0); -} - diff --git a/src/v4l/src_v4l2.c b/src/v4l/src_v4l2.c deleted file mode 100644 index 716804d9..00000000 --- a/src/v4l/src_v4l2.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* fswebcam - FireStorm.cx's webcam generator */ -/*============================================================*/ -/* Copyright (C)2005-2010 Philip Heron */ -/* */ -/* This program is distributed under the terms of the GNU */ -/* General Public License, version 2. You may use, modify, */ -/* and redistribute it under the terms of this license. A */ -/* copy should be included with this source. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include "videodev2.h" -#include "src.h" - -#ifdef HAVE_V4L2 - -int src_v4l2_get_capability(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - - if(ioctl(s->fd, VIDIOC_QUERYCAP, &s->cap) < 0) - { - /*ERROR("%s: Not a V4L2 device?", src->source);*/ - return(-1); - } - fprintf(stderr, "cap.card: \"%s\"", s->cap.card); - /*DEBUG("%s information:", src->source); - DEBUG("cap.driver: \"%s\"", s->cap.driver); - DEBUG("cap.card: \"%s\"", s->cap.card); - DEBUG("cap.bus_info: \"%s\"", s->cap.bus_info); - DEBUG("cap.capabilities=0x%08X", s->cap.capabilities);*/ - /*if(s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) DEBUG("- VIDEO_CAPTURE"); - if(s->cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) DEBUG("- VIDEO_OUTPUT"); - if(s->cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) DEBUG("- VIDEO_OVERLAY"); - if(s->cap.capabilities & V4L2_CAP_VBI_CAPTURE) DEBUG("- VBI_CAPTURE"); - if(s->cap.capabilities & V4L2_CAP_VBI_OUTPUT) DEBUG("- VBI_OUTPUT"); - if(s->cap.capabilities & V4L2_CAP_RDS_CAPTURE) DEBUG("- RDS_CAPTURE"); - if(s->cap.capabilities & V4L2_CAP_TUNER) DEBUG("- TUNER"); - if(s->cap.capabilities & V4L2_CAP_AUDIO) DEBUG("- AUDIO"); - if(s->cap.capabilities & V4L2_CAP_RADIO) DEBUG("- RADIO"); - if(s->cap.capabilities & V4L2_CAP_READWRITE) DEBUG("- READWRITE"); - if(s->cap.capabilities & V4L2_CAP_ASYNCIO) DEBUG("- ASYNCIO"); - if(s->cap.capabilities & V4L2_CAP_STREAMING) DEBUG("- STREAMING"); - if(s->cap.capabilities & V4L2_CAP_TIMEPERFRAME) DEBUG("- TIMEPERFRAME");*/ - - if(!s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) - { - /*ERROR("Device does not support capturing.");*/ - return(-1); - } - - return(0); -} - -int src_v4l2_set_input(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - struct v4l2_input input; - int count = 0, i = -1; - - memset(&input, 0, sizeof(input)); - - if(src->list & SRC_LIST_INPUTS) - { - /*HEAD("--- Available inputs:");*/ - - input.index = count; - while(!ioctl(s->fd, VIDIOC_ENUMINPUT, &input)) - { - /*MSG("%i: %s", count, input.name);*/ - input.index = ++count; - } - } - - /* If no input was specified, use input 0. */ - if(!src->input) - { - /*MSG("No input was specified, using the first.");*/ - count = 1; - i = 0; - } - - /* Check if the input is specified by name. */ - if(i == -1) - { - input.index = count; - while(!ioctl(s->fd, VIDIOC_ENUMINPUT, &input)) - { - if(!strncasecmp((char *) input.name, src->input, 32)) - i = count; - input.index = ++count; - } - } - - if(i == -1) - { - char *endptr; - - /* Is the input specified by number? */ - i = strtol(src->input, &endptr, 10); - - if(endptr == src->input) i = -1; - } - - if(i == -1 || i >= count) - { - /* The specified input wasn't found! */ - /*ERROR("Unrecognised input \"%s\"", src->input);*/ - return(-1); - } - - /* Set the input. */ - input.index = i; - if(ioctl(s->fd, VIDIOC_ENUMINPUT, &input) == -1) - { - /*ERROR("Unable to query input %i.", i); - ERROR("VIDIOC_ENUMINPUT: %s", strerror(errno));*/ - return(-1); - } - - /*DEBUG("%s: Input %i information:", src->source, i); - DEBUG("name = \"%s\"", input.name); - DEBUG("type = %08X", input.type); - if(input.type & V4L2_INPUT_TYPE_TUNER) DEBUG("- TUNER"); - if(input.type & V4L2_INPUT_TYPE_CAMERA) DEBUG("- CAMERA"); - DEBUG("audioset = %08X", input.audioset); - DEBUG("tuner = %08X", input.tuner); - DEBUG("status = %08X", input.status); - if(input.status & V4L2_IN_ST_NO_POWER) DEBUG("- NO_POWER"); - if(input.status & V4L2_IN_ST_NO_SIGNAL) DEBUG("- NO_SIGNAL"); - if(input.status & V4L2_IN_ST_NO_COLOR) DEBUG("- NO_COLOR"); - if(input.status & V4L2_IN_ST_NO_H_LOCK) DEBUG("- NO_H_LOCK"); - if(input.status & V4L2_IN_ST_COLOR_KILL) DEBUG("- COLOR_KILL"); - if(input.status & V4L2_IN_ST_NO_SYNC) DEBUG("- NO_SYNC"); - if(input.status & V4L2_IN_ST_NO_EQU) DEBUG("- NO_EQU"); - if(input.status & V4L2_IN_ST_NO_CARRIER) DEBUG("- NO_CARRIER"); - if(input.status & V4L2_IN_ST_MACROVISION) DEBUG("- MACROVISION"); - if(input.status & V4L2_IN_ST_NO_ACCESS) DEBUG("- NO_ACCESS"); - if(input.status & V4L2_IN_ST_VTR) DEBUG("- VTR");*/ - - if(ioctl(s->fd, VIDIOC_S_INPUT, &i) == -1) - { - /*ERROR("Error selecting input %i", i); - ERROR("VIDIOC_S_INPUT: %s", strerror(errno));*/ - return(-1); - } - - /* If this input is attached to a tuner, set the frequency. */ - if(input.type & V4L2_INPUT_TYPE_TUNER) - { - char *range; - struct v4l2_tuner tuner; - struct v4l2_frequency freq; - - /* Query the tuners capabilities. */ - - memset(&tuner, 0, sizeof(tuner)); - tuner.index = input.tuner; - - if(ioctl(s->fd, VIDIOC_G_TUNER, &tuner) == -1) - { - /*WARN("Error querying tuner %i.", input.tuner); - WARN("VIDIOC_G_TUNER: %s", strerror(errno));*/ - return(0); - } - - if(tuner.capability & V4L2_TUNER_CAP_LOW) range = "kHz"; - else range = "MHz"; - - /*DEBUG("%s: Tuner %i information:", src->source, input.tuner); - DEBUG("name = \"%s\"", tuner.name); - DEBUG("type = %08X", tuner.type); - if(tuner.type == V4L2_TUNER_RADIO) DEBUG("- RADIO"); - if(tuner.type == V4L2_TUNER_ANALOG_TV) DEBUG("- ANALOG_TV"); - DEBUG("capability = %08X", tuner.capability); - if(tuner.capability & V4L2_TUNER_CAP_LOW) DEBUG("- LOW"); - if(tuner.capability & V4L2_TUNER_CAP_NORM) DEBUG("- NORM"); - if(tuner.capability & V4L2_TUNER_CAP_STEREO) DEBUG("- STEREO"); - if(tuner.capability & V4L2_TUNER_CAP_LANG1) DEBUG("- LANG1"); - if(tuner.capability & V4L2_TUNER_CAP_LANG2) DEBUG("- LANG2"); - if(tuner.capability & V4L2_TUNER_CAP_SAP) DEBUG("- SAP"); - DEBUG("rangelow = %08X, (%.3f%s)", tuner.rangelow, (double) tuner.rangelow * 16 / 1000, range); - DEBUG("rangehigh = %08X, (%.3f%s)", tuner.rangehigh, (double) tuner.rangehigh * 16 / 1000, range); - DEBUG("signal = %08X", tuner.signal); - DEBUG("afc = %08X", tuner.afc);*/ - - /* Set the frequency. */ - memset(&freq, 0, sizeof(freq)); - freq.tuner = input.tuner; - freq.type = V4L2_TUNER_ANALOG_TV; - freq.frequency = (src->frequency / 1000) * 16; - - if(ioctl(s->fd, VIDIOC_S_FREQUENCY, &freq) == -1) - { - /*WARN("Error setting frequency %.3f%s", src->frequency / 16.0, range); - WARN("VIDIOC_S_FREQUENCY: %s", strerror(errno));*/ - return(0); - } - - /*MSG("Set frequency to %.3f%s", - (double) src->frequency / 1000, range);*/ - } - - return(0); -} - -int src_v4l2_show_control(src_t *src, struct v4l2_queryctrl *queryctrl) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - struct v4l2_querymenu querymenu; - struct v4l2_control control; - char *t; - int m; - - if(queryctrl->flags & V4L2_CTRL_FLAG_DISABLED) return(0); - - memset(&querymenu, 0, sizeof(querymenu)); - memset(&control, 0, sizeof(control)); - - if(queryctrl->type != V4L2_CTRL_TYPE_BUTTON) - { - control.id = queryctrl->id; - if(ioctl(s->fd, VIDIOC_G_CTRL, &control)) - { - /*ERROR("Error reading value of control '%s'.", queryctrl->name); - ERROR("VIDIOC_G_CTRL: %s", strerror(errno));*/ - } - } - - switch(queryctrl->type) - { - case V4L2_CTRL_TYPE_INTEGER: - - t = malloc(64); /* Ick ... TODO: re-write this. */ - if(!t) - { - /*ERROR("Out of memory.");*/ - return(-1); - } - - if(queryctrl->maximum - queryctrl->minimum <= 10) - { - snprintf(t, 63, "%i", control.value); - } - else - { - snprintf(t, 63, "%i (%i%%)", - control.value, - SCALE(0, 100, - queryctrl->minimum, - queryctrl->maximum, - control.value)); - } - - /*MSG("%-25s %-15s %i - %i", queryctrl->name, t, - queryctrl->minimum, queryctrl->maximum);*/ - - free(t); - - break; - - case V4L2_CTRL_TYPE_BOOLEAN: - /*MSG("%-25s %-15s True | False", queryctrl->name, - (control.value ? "True" : "False"));*/ - break; - - case V4L2_CTRL_TYPE_MENU: - - querymenu.id = queryctrl->id; - - t = calloc((queryctrl->maximum - queryctrl->minimum) + 1, 34); - m = queryctrl->minimum; - for(m = queryctrl->minimum; m <= queryctrl->maximum; m++) - { - querymenu.index = m; - if(!ioctl(s->fd, VIDIOC_QUERYMENU, &querymenu)) - { - strncat(t, (char *) querymenu.name, 32); - if(m < queryctrl->maximum) strncat(t, " | ", 3); - } - } - - querymenu.index = control.value; - if(ioctl(s->fd, VIDIOC_QUERYMENU, &querymenu)) - { - free(t); - /*ERROR("Error reading value of menu item %i for control '%s'", - control.value, queryctrl->name); - ERROR("VIDIOC_QUERYMENU: %s", strerror(errno));*/ - return(0); - } - - /*MSG("%-25s %-15s %s", queryctrl->name, querymenu.name, t);*/ - free(t); - - break; - - case V4L2_CTRL_TYPE_BUTTON: - /*MSG("%-25s %-15s %s", queryctrl->name, "-", "[Button]");*/ - break; - - default: - /*MSG("%-25s %-15s %s", queryctrl->name, "N/A", "[Unknown Control Type]");*/ - break; - } - - return(0); -} - -int src_v4l2_set_control(src_t *src, struct v4l2_queryctrl *queryctrl) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - struct v4l2_control control; - struct v4l2_querymenu querymenu; - char *sv; - int iv; - - if(queryctrl->flags & V4L2_CTRL_FLAG_DISABLED) return(0); - if(src_get_option_by_name(src->option, (char *) queryctrl->name, &sv)) - return(0); - - memset(&querymenu, 0, sizeof(querymenu)); - memset(&control, 0, sizeof(control)); - - control.id = queryctrl->id; - - switch(queryctrl->type) - { - case V4L2_CTRL_TYPE_INTEGER: - - /* Convert the value to an integer. */ - iv = atoi(sv); - - /* Is the value a precentage? */ - if(strchr(sv, '%')) - { - /* Adjust the precentage to fit the controls range. */ - iv = SCALE(queryctrl->minimum, queryctrl->maximum, - 0, 100, iv); - } - - /*MSG("Setting %s to %i (%i%%).", queryctrl->name, iv, - SCALE(0, 100, queryctrl->minimum, queryctrl->maximum, iv));*/ - - /*if(iv < queryctrl->minimum || iv > queryctrl->maximum) - WARN("Value is out of range. Setting anyway.");*/ - - control.value = iv; - ioctl(s->fd, VIDIOC_S_CTRL, &control); - break; - - case V4L2_CTRL_TYPE_BOOLEAN: - - iv = -1; - if(!strcasecmp(sv, "1") || !strcasecmp(sv, "true")) iv = 1; - if(!strcasecmp(sv, "0") || !strcasecmp(sv, "false")) iv = 0; - - if(iv == -1) - { - /*WARN("Unknown boolean value '%s' for %s.", - sv, queryctrl->name);*/ - return(-1); - } - - /*MSG("Setting %s to %s (%i).", queryctrl->name, sv, iv);*/ - - control.value = iv; - ioctl(s->fd, VIDIOC_S_CTRL, &control); - - break; - - case V4L2_CTRL_TYPE_MENU: - - /* Scan for a matching value. */ - querymenu.id = queryctrl->id; - - for(iv = queryctrl->minimum; iv <= queryctrl->maximum; iv++) - { - querymenu.index = iv; - - if(ioctl(s->fd, VIDIOC_QUERYMENU, &querymenu)) - { - /*ERROR("Error querying menu.");*/ - continue; - } - - if(!strncasecmp((char *) querymenu.name, sv, 32)) - break; - } - - if(iv > queryctrl->maximum) - { - /*MSG("Unknown value '%s' for %s.", sv, queryctrl->name);*/ - return(-1); - } - - /*MSG("Setting %s to %s (%i).", - queryctrl->name, querymenu.name, iv);*/ - - control.value = iv; - ioctl(s->fd, VIDIOC_S_CTRL, &control); - - break; - - case V4L2_CTRL_TYPE_BUTTON: - - /*MSG("Triggering %s control.", queryctrl->name); - ioctl(s->fd, VIDIOC_S_CTRL, &control);*/ - - break; - - default: - /*WARN("Not setting unknown control type %i (%s).", - queryctrl->name);*/ - break; - } - - return(0); -} - -int src_v4l2_set_controls(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - struct v4l2_queryctrl queryctrl; - int c; - - memset(&queryctrl, 0, sizeof(queryctrl)); - - if(src->list & SRC_LIST_CONTROLS) - { - /*HEAD("%-25s %-15s %s", "Available Controls", "Current Value", "Range"); - MSG("%-25s %-15s %s", "------------------", "-------------", "-----");*/ - - /* Display normal controls. */ - for(c = V4L2_CID_BASE; c < V4L2_CID_LASTP1; c++) - { - queryctrl.id = c; - - if(ioctl(s->fd, VIDIOC_QUERYCTRL, &queryctrl)) continue; - src_v4l2_show_control(src, &queryctrl); - } - - /* Display device-specific controls. */ - for(c = V4L2_CID_PRIVATE_BASE; ; c++) - { - queryctrl.id = c; - - if(ioctl(s->fd, VIDIOC_QUERYCTRL, &queryctrl)) break; - src_v4l2_show_control(src, &queryctrl); - } - } - - /* Scan normal controls. */ - for(c = V4L2_CID_BASE; c < V4L2_CID_LASTP1; c++) - { - queryctrl.id = c; - - if(ioctl(s->fd, VIDIOC_QUERYCTRL, &queryctrl)) continue; - src_v4l2_set_control(src, &queryctrl); - } - - /* Scan device-specific controls. */ - for(c = V4L2_CID_PRIVATE_BASE; ; c++) - { - queryctrl.id = c; - - if(ioctl(s->fd, VIDIOC_QUERYCTRL, &queryctrl)) break; - src_v4l2_set_control(src, &queryctrl); - } - - return(0); -} - -int src_v4l2_set_pix_format(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - struct v4l2_fmtdesc fmt; - int v4l2_pal; - - /* Dump a list of formats the device supports. */ - /*DEBUG("Device offers the following V4L2 pixel formats:");*/ - - v4l2_pal = 0; - memset(&fmt, 0, sizeof(fmt)); - fmt.index = v4l2_pal; - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - while(ioctl(s->fd, VIDIOC_ENUM_FMT, &fmt) != -1) - { - /*DEBUG("%i: [0x%08X] '%c%c%c%c' (%s)", v4l2_pal, - fmt.pixelformat, - fmt.pixelformat >> 0, fmt.pixelformat >> 8, - fmt.pixelformat >> 16, fmt.pixelformat >> 24, - fmt.description);*/ - - memset(&fmt, 0, sizeof(fmt)); - fmt.index = ++v4l2_pal; - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - - /* Step through each palette type. */ - v4l2_pal = 0; - - if(src->palette != -1) - { - while(v4l2_palette[v4l2_pal].v4l2) - { - if(v4l2_palette[v4l2_pal].src == src->palette) break; - v4l2_pal++; - } - - if(!v4l2_palette[v4l2_pal].v4l2) - { - /*ERROR("Unable to handle palette format %s.", - src_palette[src->palette]);*/ - - return(-1); - } - } - - while(v4l2_palette[v4l2_pal].v4l2) - { - /* Try the palette... */ - memset(&s->fmt, 0, sizeof(s->fmt)); - s->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - s->fmt.fmt.pix.width = src->width; - s->fmt.fmt.pix.height = src->height; - s->fmt.fmt.pix.pixelformat = v4l2_palette[v4l2_pal].v4l2; - s->fmt.fmt.pix.field = V4L2_FIELD_ANY; - - if(ioctl(s->fd, VIDIOC_TRY_FMT, &s->fmt) != -1 && - s->fmt.fmt.pix.pixelformat == v4l2_palette[v4l2_pal].v4l2) - { - src->palette = v4l2_palette[v4l2_pal].src; - - /*INFO("Using palette %s", src_palette[src->palette].name);*/ - - if(s->fmt.fmt.pix.width != src->width || - s->fmt.fmt.pix.height != src->height) - { - /*MSG("Adjusting resolution from %ix%i to %ix%i.", - src->width, src->height, - s->fmt.fmt.pix.width, - s->fmt.fmt.pix.height);*/ - src->width = s->fmt.fmt.pix.width; - src->height = s->fmt.fmt.pix.height; - } - - if(ioctl(s->fd, VIDIOC_S_FMT, &s->fmt) == -1) - { - /*ERROR("Error setting pixel format."); - ERROR("VIDIOC_S_FMT: %s", strerror(errno));*/ - return(-1); - } - - if(v4l2_palette[v4l2_pal].v4l2 == V4L2_PIX_FMT_MJPEG) - { - struct v4l2_jpegcompression jpegcomp; - - memset(&jpegcomp, 0, sizeof(jpegcomp)); - ioctl(s->fd, VIDIOC_G_JPEGCOMP, &jpegcomp); - jpegcomp.jpeg_markers |= V4L2_JPEG_MARKER_DHT; - ioctl(s->fd, VIDIOC_S_JPEGCOMP, &jpegcomp); - } - - return(0); - } - - if(src->palette != -1) break; - - v4l2_pal++; - } - - /*ERROR("Unable to find a compatible palette format.");*/ - - return(-1); -} - -int src_v4l2_set_fps(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - struct v4l2_streamparm setfps; - - memset(&setfps, 0, sizeof(setfps)); - - setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - setfps.parm.capture.timeperframe.numerator = 1; - setfps.parm.capture.timeperframe.denominator = src->fps; - if(ioctl(s->fd, VIDIOC_S_PARM, setfps) == -1) - { - /* Not fatal - just warn about it */ - /*WARN("Error setting frame rate:"); - WARN("VIDIOC_S_PARM: %s", strerror(errno));*/ - return(-1); - } - - return(0); -} - -int src_v4l2_free_mmap(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - int i; - - for(i = 0; i < s->req.count; i++) - munmap(s->buffer[i].start, s->buffer[i].length); - - return(0); -} - -int src_v4l2_set_mmap(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - enum v4l2_buf_type type; - uint32_t b; - - /* Does the device support streaming? */ - if(~s->cap.capabilities & V4L2_CAP_STREAMING) return(-1); - - memset(&s->req, 0, sizeof(s->req)); - - s->req.count = 4; - s->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - s->req.memory = V4L2_MEMORY_MMAP; - - if(ioctl(s->fd, VIDIOC_REQBUFS, &s->req) == -1) - { - /*ERROR("Error requesting buffers for memory map."); - ERROR("VIDIOC_REQBUFS: %s", strerror(errno));*/ - return(-1); - } - - /*DEBUG("mmap information:"); - DEBUG("frames=%d", s->req.count);*/ - - if(s->req.count < 2) - { - /*ERROR("Insufficient buffer memory.");*/ - return(-1); - } - - s->buffer = calloc(s->req.count, sizeof(v4l2_buffer_t)); - if(!s->buffer) - { - /*ERROR("Out of memory.");*/ - return(-1); - } - - for(b = 0; b < s->req.count; b++) - { - struct v4l2_buffer buf; - - memset(&buf, 0, sizeof(buf)); - - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = b; - - if(ioctl(s->fd, VIDIOC_QUERYBUF, &buf) == -1) - { - /*ERROR("Error querying buffer %i", b); - ERROR("VIDIOC_QUERYBUF: %s", strerror(errno));*/ - free(s->buffer); - return(-1); - } - - s->buffer[b].length = buf.length; - s->buffer[b].start = mmap(NULL, buf.length, - PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset); - - if(s->buffer[b].start == MAP_FAILED) - { - /*ERROR("Error mapping buffer %i", b); - ERROR("mmap: %s", strerror(errno));*/ - s->req.count = b; - src_v4l2_free_mmap(src); - free(s->buffer); - return(-1); - } - - /*DEBUG("%i length=%d", b, buf.length);*/ - } - - s->map = -1; - - for(b = 0; b < s->req.count; b++) - { - memset(&s->buf, 0, sizeof(s->buf)); - - s->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - s->buf.memory = V4L2_MEMORY_MMAP; - s->buf.index = b; - - if(ioctl(s->fd, VIDIOC_QBUF, &s->buf) == -1) - { - /*ERROR("VIDIOC_QBUF: %s", strerror(errno));*/ - src_v4l2_free_mmap(src); - free(s->buffer); - return(-1); - } - } - - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - if(ioctl(s->fd, VIDIOC_STREAMON, &type) == -1) - { - /*ERROR("Error starting stream."); - ERROR("VIDIOC_STREAMON: %s", strerror(errno));*/ - src_v4l2_free_mmap(src); - free(s->buffer); - return(-1); - } - - return(0); -} - -int src_v4l2_set_read(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - - if(~s->cap.capabilities & V4L2_CAP_READWRITE) return(-1); - - s->buffer = calloc(1, sizeof(v4l2_buffer_t)); - if(!s->buffer) - { - /*ERROR("Out of memory.");*/ - return(-1); - } - - s->buffer[0].length = s->fmt.fmt.pix.sizeimage; - s->buffer[0].start = malloc(s->buffer[0].length); - - if(!s->buffer[0].start) - { - /*ERROR("Out of memory.");*/ - - free(s->buffer); - s->buffer = NULL; - - return(-1); - } - - return(0); -} - -static const char *src_v4l2_query(src_t *src, uint *width, uint *height, char **pixelformatdescription) -{ - if(!src->source) - { - /*ERROR("No device name specified.");*/ - fprintf(stderr, "No device name specified."); - return NULL; - } - src_v4l2_t *s; - - /* Allocate memory for the state structure. */ - s = calloc(sizeof(src_v4l2_t), 1); - if(!s) - { - fprintf(stderr, "Out of memory."); - return NULL; - } - - src->state = (void *) s; - - /* Open the device. */ - s->fd = open(src->source, O_RDWR | O_NONBLOCK); - if(s->fd < 0) - { - fprintf(stderr, "Cannot open device."); - free(s); - return NULL; - } - - if(ioctl(s->fd, VIDIOC_QUERYCAP, &s->cap) < 0) { - src_v4l2_close(src); - fprintf(stderr, "Cannot get capabilities."); - return NULL; - } - char *res = strdup((char*) s->cap.card); - /*strcpy(res, (char*) s->cap.card);*/ - if(!s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { - *width = 0; - *height = 0; - } - else { - struct v4l2_format format; - memset(&format,0,sizeof(format)); - format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (ioctl(s->fd,VIDIOC_G_FMT,&format) < 0) { - fprintf(stderr, "Cannot get format."); - } - else { - *width = format.fmt.pix.width; - *height = format.fmt.pix.height; - } - struct v4l2_fmtdesc fmt; - memset(&fmt,0,sizeof(fmt)); - fmt.index = 0; - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - struct v4l2_frmsizeenum sizes; - memset(&sizes,0,sizeof(sizes)); - - struct v4l2_frmivalenum rates; - memset(&rates,0,sizeof(rates)); - char value[200]; - *pixelformatdescription = strdup((char *) "result:"); - - while (ioctl(s->fd, VIDIOC_ENUM_FMT, &fmt) != -1) - { - /*strcpy(*pixelformatdescription, (char *) fmt.description);*/ - //*pixelformatdescription = strdup((char*)fmt.description); - snprintf( value, sizeof(value), "%c%c%c%c:", fmt.pixelformat >> 0, fmt.pixelformat >> 8, fmt.pixelformat >> 16, fmt.pixelformat >> 24 ); - strcat(*pixelformatdescription, strdup((char *) value)); - fprintf(stderr, "detected format: %s: %c%c%c%c\n", fmt.description, fmt.pixelformat >> 0, fmt.pixelformat >> 8, - fmt.pixelformat >> 16, fmt.pixelformat >> 24); - - sizes.pixel_format = fmt.pixelformat; - sizes.index = 0; - // Query supported frame size - while (ioctl(s->fd, VIDIOC_ENUM_FRAMESIZES, &sizes) != -1) { - struct v4l2_frmsize_discrete image_size = sizes.un.discrete; - // Query supported frame rates - rates.index = 0; - rates.pixel_format = fmt.pixelformat; - rates.width = image_size.width; - rates.height = image_size.height; - snprintf( value, sizeof(value), "%dx%d,", image_size.width, image_size.height ); - strcat(*pixelformatdescription, strdup((char *) value)); - fprintf(stderr, "Size: %dx%d: ", image_size.width, image_size.height); - while (ioctl(s->fd, VIDIOC_ENUM_FRAMEINTERVALS, &rates) != -1) { - snprintf( value, sizeof(value), "%d/%d,", rates.un.discrete.numerator, rates.un.discrete.denominator ); - strcat(*pixelformatdescription, strdup((char *) value)); - fprintf(stderr, "%d/%d, ", rates.un.discrete.numerator, rates.un.discrete.denominator); - rates.index ++; - } - fprintf(stderr, "\n"); - sizes.index++; - } - - - /*[0x%08X] '%c%c%c%c' (%s)", v4l2_pal, - fmt.pixelformat, - fmt.pixelformat >> 0, fmt.pixelformat >> 8, - fmt.pixelformat >> 16, fmt.pixelformat >> 24*/ - fmt.index++; - } - /*else { - *pixelformatdescription = '\0'; - }*/ - } - src_v4l2_close(src); - return res; -} - -static int src_v4l2_open(src_t *src) -{ - src_v4l2_t *s; - - if(!src->source) - { - /*ERROR("No device name specified.");*/ - return(-2); - } - - /* Allocate memory for the state structure. */ - s = calloc(sizeof(src_v4l2_t), 1); - if(!s) - { - /*ERROR("Out of memory.");*/ - return(-2); - } - - src->state = (void *) s; - - /* Open the device. */ - s->fd = open(src->source, O_RDWR | O_NONBLOCK); - if(s->fd < 0) - { - /*ERROR("Error opening device: %s", src->source); - ERROR("open: %s", strerror(errno));*/ - free(s); - return(-2); - } - - /*MSG("%s opened.", src->source);*/ - - /* Get the device capabilities. */ - if(src_v4l2_get_capability(src)) - { - src_v4l2_close(src); - return(-2); - } - - /* Set the input. */ - if(src_v4l2_set_input(src)) - { - src_v4l2_close(src); - return(-1); - } - - /* Set picture options. */ - src_v4l2_set_controls(src); - - /* Set the pixel format. */ - if(src_v4l2_set_pix_format(src)) - { - src_v4l2_close(src); - return(-1); - } - - /* Set the frame-rate if > 0 */ - if(src->fps) src_v4l2_set_fps(src); - - /* Delay to let the image settle down. */ - if(src->delay) - { - /*MSG("Delaying %i seconds.", src->delay);*/ - usleep(src->delay * 1000 * 1000); - } - - /* Try to setup mmap. */ - if(!src->use_read && src_v4l2_set_mmap(src)) - { - /*WARN("Unable to use mmap. Using read instead.");*/ - src->use_read = -1; - } - - /* If unable to use mmap or user requested read(). */ - if(src->use_read) - { - if(src_v4l2_set_read(src)) - { - /*ERROR("Unable to use read.");*/ - src_v4l2_close(src); - return(-1); - } - } - - s->pframe = -1; - - return(0); -} - -static int src_v4l2_close(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - - if(s->buffer) - { - if(!s->map) free(s->buffer[0].start); - else src_v4l2_free_mmap(src); - free(s->buffer); - } - if(s->fd >= 0) close(s->fd); - free(s); - - return(0); -} - -static int src_v4l2_grab(src_t *src) -{ - src_v4l2_t *s = (src_v4l2_t *) src->state; - - if(src->timeout) - { - fd_set fds; - struct timeval tv; - int r; - - /* Is a frame ready? */ - FD_ZERO(&fds); - FD_SET(s->fd, &fds); - - tv.tv_sec = src->timeout; - tv.tv_usec = 0; - - r = select(s->fd + 1, &fds, NULL, NULL, &tv); - - if(r == -1) - { - /*ERROR("select: %s", strerror(errno));*/ - return(-1); - } - - if(!r) - { - /*ERROR("Timed out waiting for frame!");*/ - return(-1); - } - } - - if(s->map) - { - if(s->pframe >= 0) - { - if(ioctl(s->fd, VIDIOC_QBUF, &s->buf) == -1) - { - /*ERROR("VIDIOC_QBUF: %s", strerror(errno));*/ - return(-1); - } - } - - memset(&s->buf, 0, sizeof(s->buf)); - - s->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - s->buf.memory = V4L2_MEMORY_MMAP; - - if(ioctl(s->fd, VIDIOC_DQBUF, &s->buf) == -1) - { - /*ERROR("VIDIOC_DQBUF: %s", strerror(errno));*/ - return(-1); - } - - src->img = s->buffer[s->buf.index].start; - src->length = s->buffer[s->buf.index].length; - - s->pframe = s->buf.index; - } - else - { - ssize_t r; - - r = read(s->fd, s->buffer[0].start, s->buffer[0].length); - if(r <= 0) - { - /*ERROR("Unable to read a frame."); - ERROR("read: %s", strerror(errno));*/ - return(-1); - } - - src->img = s->buffer[0].start; - src->length = r; - } - - return(0); -} - -src_mod_t src_v4l2 = { - "v4l2", SRC_TYPE_DEVICE, - src_v4l2_open, - src_v4l2_close, - src_v4l2_grab, - src_v4l2_query -}; - -#else /* #ifdef HAVE_V4L2 */ - -src_mod_t src_v4l2 = { - "", SRC_TYPE_NONE, - NULL, - NULL, - NULL, - NULL -}; - -#endif /* #ifdef HAVE_V4L2 */ -