Reading output of a USB webcam in Linux - c

I was experimenting with a little bit with fread and fwrite in C. So i wrote this little program in C to get data from a webcam and dump it into a file. The following is the source:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 307200 // number of pixels (640x480 for my webcam)
int main() {
FILE *camera, *grab;
camera=fopen("/dev/video0", "rb");
grab=fopen("grab.raw", "wb");
float data[SIZE];
fread(data, sizeof(data[0]), SIZE, camera);
fwrite(data, sizeof(data[0]), SIZE, grab);
fclose(camera);
fclose(grab);
return 0;
}
The program works when compiled (gcc -o snap camera.c). What took me by surprise was that the output file was not a raw data dump but a JPEG file. Output of the file command on linux on the programs output file showed it was a JPEG image data: JFIF Standard 1.01. The file was viewable on an image viewer, although a little saturated.
How or why does this happen? I did not use any JPEG encoding libraries in the source or the program. Does the camera output JPEG natively? The webcam is a Sony Playstation 2 EyeToy which was manufactured by Logitech. The system is Debian Linux.

The Sony EyeToy has an OV7648 sensor with the quite popular OV519 bridge. The OV519 outputs frames in JPEG format - and if I remember correctly from my own cameras that's the only format that it supports.
Cameras like this require either application support, or a special driver that will decompress the frames before delivery to userspace. Apparently in your case the driver delivers the JPEG frames in their original form, which is why you are getting JPEG data in the output.
BTW, you should really have a look at the Video4Linux2 API for the proper way to access video devices on Linux - a simple open()/read()/close() is generally not enough...

Related

How to execute a ffmpeg code on a GPU without using the command line?

We have written a short code in C code to read a video file, using common libraries as libavcodec, libavformat, etc.
The code is running smoothly but only using the CPU resources. We'd need to run the code on the GPU (Nvidia GeForce 940MX and 1080Ti). Is there a way to force the code to be run on the GPU?
While using the command line (e.g., ffmpeg -hwaccel cuvid -i vid.mp4 out.avi) things are fine, we are not able to have it working on the GPU from the source code.
We are working with Ubuntu 18.04, and ffmpeg correctly compiled with CUDA 9.2
There are pretty good examples for using libav (ffmpeg) for encoding and decoding video at https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples.
For what you need is demuxing_decoding.c example and change the lines 166 which is:
/* find decoder for the stream */
dec = avcodec_find_decoder(st->codecpar->codec_id);
with
/* find decoder for the stream */
if (st->codecpar->codec_id == AV_CODEC_ID_H264)
{
dec = avcodec_find_decoder_by_name("h264_cuvid");
}
else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC)
{
dec = avcodec_find_decoder_by_name("hevc_cuvid");
}
else
{
dec = avcodec_find_decoder(st->codecpar->codec_id);
}
add/change lines for other formats. And make sure your FFmpeg compiled with --enable-cuda --enable-cuvid
In my tests I got error comes from line 85: because nvdec (hevc_cuvid) uses p010 internal format for 10bit (input is yuv420p10). Which means decoded frame will be either NV12 pixel format or P010 depending on bit depth. I hope you are familiar with pixel formats.
Hope that helps.

Portaudio: open file instead of using the microphone

I am using PortAudio, and this is how I'm opening a stream for reading right now.
Pa_OpenDefaultStream(&stream, 1, 0, paFloat32, SAMPLE_RATE, SAMPLES, PaCallback, NULL);
As far as I know, this uses the microphone as input. How can I instead use a file as input? The Pa_OpenStream function strangely doesn't seem to let me enter a filename?
PortAudio is for device I/O only, such as speakers, microphones, line inputs and similar devices. To do file I/O you need another library designed for that. For example, libsoundfile, libsox or libaudiofile.

Playing a wav file using pulseaudio APIs?

For example, this is how to use pulseaudio: http://freedesktop.org/software/pulseaudio/doxygen/pacat-simple_8c-example.html
but I'm not clear on how I can simply play a wav file or an ogg file for that matter.
The example code will play raw PCM data from a file. The trick is getting the data from a wav file into this format. The Microsoft wav files look like this:
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
Wav files just store raw PCM data. You just have to strip the header off the wav file and dump the rest into a file (extension is irrelevant, but I like to use .raw). That is, you can write a program that either: copies everything past byte 44 into a new file, or just read everything after that directly into a buffer. Pass either format to the pulseaudio example and you should be good to go.
Things to look out for: the endianness of the file and your system; bitdepth; number of channels. These are in the wav header and you may have to read them and tell pa_simple before you play the data. Although, I'm not sure if pa_simple detects this information for you. I like to work with the asynchronous implementation and there I just input the format directly.
-E
linux-commands-examples - pacat
pacat --list-file-formats
aiff AIFF (Apple/SGI)
au AU (Sun/NeXT)
avr AVR (Audio Visual Research)
caf CAF (Apple Core Audio File)
flac FLAC (Free Lossless Audio Codec)
htk HTK (HMM Tool Kit)
iff IFF (Amiga IFF/SVX8/SV16)
mat MAT4 (GNU Octave 2.0 / Matlab 4.2)
mat MAT5 (GNU Octave 2.1 / Matlab 5.0)
mpc MPC (Akai MPC 2k)
oga OGG (OGG Container format)
paf PAF (Ensoniq PARIS)
pvf PVF (Portable Voice Format)
raw RAW (header-less)
rf64 RF64 (RIFF 64)
sd2 SD2 (Sound Designer II)
sds SDS (Midi Sample Dump Standard)
sf SF (Berkeley/IRCAM/CARL)
voc VOC (Creative Labs)
w64 W64 (SoundFoundry WAVE 64)
wav WAV (Microsoft)
wav WAV (NIST Sphere)
wav WAVEX (Microsoft)
wve WVE (Psion Series 3)
xi XI (FastTracker 2)

Blackfin. 2D DCT/IDCT (image compression) with BF537 EZ-KIT, HOW TO WRITE TO FILE (on disk) reconstructed image (Raw pixel data) from BF537 memory?

I tried this experiment with Digital Image Processing - 2D DCT/IDCT (image compression) with BF537 EZ-KIT implemented by AnalogDevices.
To mention a "resume":
I build the project;
Load an black&white image (*.bmp) from disk to Blackfin memory at 0x8000 with Image Viewer;
Run project;
Push a button (from SW 10 to 13) from the BlackFin board (BF537) and select a level of compression;
After calculating the quantization table and DCT->Quantization->Dequantization->Inverse DCT.. results a reconstructed image at some adress point in BF memory (0x80000);
With Image Viewer (from VisualDsp) i load that reconstructed grayscale image from BF memory and it's everything ok, and differences are visible;
Mention that when i load image into BF memory from disk with Image Viewer, or from BF memory with Image Viewer, source format is Raw Pixel Data.
BUT all I want to do in addition to this project and DON'T KNOW HOW is:
to take ( create / write ) [in C language] that reconstructed image from Blackfin memory into disk (writing a code, or something like that; NOT with Image Viewer feature - Save image as... ).
I tried to fwrite that reconstructed buffer located in memory at 0x80000 into a *.bmp file, but it seems that when i open it i receive errors like: "can't read file header; unknown file format, or file not found...";
//my code for saving/creating/writing
// that reconstructed image = Raw pixel data from Blackfin memory
unsigned char *jpeg_buff;
int jpeg_buff_size;
jpeg_buff=0x80000;
jpeg_buff_size = 308280; //jpeg_buff_size = 480*640*1;
FILE *jpegfp = fopen ("myimg_reconstr80000.bmp", "wb");
fwrite (jpeg_buff, 1, jpeg_buff_size, jpegfp);
fclose (jpegfp);
Please anyone knows how to create / write / save *.bmp image from that Raw Pixel Data located in Blackfin memory in C language?
Thanks in advance; any solutions, suggestions will be appreciated!
Below is the link with archive of the entire Visual Dsp project. (i'm using VisualDsp++ 5.0)
https://docs.google.com/open?id=0B4IUN70RC09nMjRjNzlhNTctMTI3OS00ZmI4LWI4NzAtNWRkM2MyMDgyMjZm
*excuse me for my english writing errors
Before all the pixel data, add information for the bitmap header.
http://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header
If you write this header data before your image data, it should be a valid bitmap file.

formats.h file containing WAV file format info

I am trying to make a prog which can record voice and store it in digital audio format on LINUX using ALSA. (currently using Ubuntu).
While looking for some help on net, I found this code from here
#include "formats.h"
...
...
WaveChunkHeader wch, ch = {WAV_FMT,16};
WaveHeader h;
WaveFmtBody f;
wch.type = WAV_DATA;
...
...
However, I don't have "formats.h" header file on my system. Any one know from where(which dev pkg) I can get this header file (containing audio file format related info)?
Thanks,
Vikram
it should be in the alsa-utils package, subdirectory aplay:
http://alsa-utils.sourcearchive.com/documentation/1.0.17/formats_8h-source.html

Resources