audiosignal.cpp
blackmagic/include/DeckLinkAPIDispatch.cpp
stopmotion/stopmotion.cpp
- stopmotion/capturehandler.cpp
- blackmagic/capture.cpp
blackmagic/devices.cpp
onmonitoritems/onmonitorrectitem.cpp
onmonitoritems/onmonitorcornersitem.cpp
+++ /dev/null
-/* -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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <QGLWidget>
-#include <QDebug>
-#include <QImage>
-#include <QMutex>
-#include <QPaintEvent>
-
-#include <QtOpenGL>
-
-#ifndef GL_TEXTURE_RECTANGLE_EXT
-#define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
-#endif
-
-#include <KDebug>
-#include <KLocale>
-
-#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<const char*>(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 <mode id> [OPTIONS]\n"
- "\n"
- " -m <mode id>:\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 <pixelformat>\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 <format> Print timecode\n"
- " rp188: RP 188\n"
- " vitc: VITC\n"
- " serial: Serial Timecode\n"
- " -f <filename> Filename raw video will be written to\n"
- " -a <filename> Filename raw audio will be written to\n"
- " -c <channels> Audio Channels (2, 8 or 16 - default is 2)\n"
- " -s <depth> Audio Sample Depth (16 or 32 - default is 16)\n"
- " -n <frames> 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;*/
-
-}
+++ /dev/null
-#ifndef __BMDCAPTURE_H__
-#define __BMDCAPTURE_H__
-
-#include "include/DeckLinkAPI.h"
-#include "../stopmotion/capturehandler.h"
-
-#include <QWidget>
-#include <QObject>
-#include <QLayout>
-#if defined(Q_WS_MAC) || defined(Q_OS_FREEBSD)
-#include <pthread.h>
-#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 <IDeckLinkVideoInputFrame*> 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
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;
}
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);
m_isCapturing(false),
m_didCapture(false),
m_isPlaying(false),
- m_blackmagicCapturing(false),
m_manager(manager),
m_captureDevice(NULL),
m_analyse(false)
#endif
control_frame_firewire->setLayout(layout);
-
- slotVideoDeviceChanged(device_selector->currentIndex());
m_displayProcess = new QProcess;
m_captureProcess = new QProcess;
setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
kDebug() << "/////// BUILDING MONITOR, ID: " << video_frame->winId();
+ slotVideoDeviceChanged(device_selector->currentIndex());
}
RecMonitor::~RecMonitor()
{
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);
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);
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);
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);
}
}
-void RecMonitor::slotGotBlackmagicFrameNumber(ulong ix)
-{
- m_dvinfo.setText(QString::number(ix));
-}
-
void RecMonitor::slotSetInfoMessage(const QString &message)
{
m_logger.insertItem(0, message);
}
-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;
}
}
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. */
void slotConfigure();
void slotReadDvgrabInfo();
void slotUpdateFreeSpace();
- void slotGotBlackmagicFrameNumber(ulong ix);
void slotSetInfoMessage(const QString &message);
void slotDroppedFrames(int dropped);
#define STOPMOTION_H
#include "ui_stopmotion_ui.h"
-#include "../blackmagic/capture.h"
#include <KUrl>
#include <QLabel>
+++ /dev/null
-/* fswebcam - Small and simple webcam for *nix */
-/*============================================================*/
-/* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
-/* */
-/* 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 <stdint.h>
-/*#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);
-}
-
+++ /dev/null
-/* fswebcam - Small and simple webcam for *nix */
-/*============================================================*/
-/* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
-/* */
-/* 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 <stdint.h>
-
-#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);
-}
-
+++ /dev/null
-/* fswebcam - Small and simple webcam for *nix */
-/*============================================================*/
-/* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
-/* */
-/* 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 <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-#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);
-}
-
-
-
+++ /dev/null
-/* fswebcam - Small and simple webcam for *nix */
-/*============================================================*/
-/* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
-/* */
-/* 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 <stdint.h>
-#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);
-}
-
+++ /dev/null
-/* 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 <string.h>
-#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);
-}
-
+++ /dev/null
-/* fswebcam - Small and simple webcam for *nix */
-/*============================================================*/
-/* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
-/* */
-/* 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 <stdint.h>
-
-#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);
-}
-
+++ /dev/null
-/* fswebcam - FireStorm.cx's webcam generator */
-/*============================================================*/
-/* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
-/* */
-/* 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 <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#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 */
-