[Live-devel] WebCam as Frame Source
Ioannis Skazikis
iskaz at intracom.gr
Fri Sep 2 09:53:36 PDT 2005
Scott Hays wrote:
> Re-read the comments in DeviceSource.cpp. I don't know if it's the
> cause of all of your problems, but you're not supposed to allocate
> memory to fTo. Memory should already have been allocated and if the
> buffer isn't big enough, set fNumTruncatedBytes to let the class
> which owns the buffer know that the buffer should be bigger (and it
> will then expand the buffer). Also, in general, it's a bad idea to
> mix C and C++ memory allocation methods.
>
> Hope that helps,
> Scott
>
>
> On Sep 1, 2005, at 1:32 PM, Ioannis Skazikis wrote:
>
>> Hallo,
>>
>> I try to build an RTSP Live Video Stream server based on the live media
>> library.
>>
>> I have also read the live Media FAQ + Mailing List and tryed to follow
>> your answers to questions from the mailing list archive from others
>> having the same problem like me.
>>
>> The program is based on the testMPEG4VideoStreammer testprogramm found
>> in the liveMedia library.
>>
>> Based on the DeviseSource.cpp I wrote an DeviceSourceCammera
>> subclass of
>> the FramedSource" which opens a USB Camera, grubs an Image and decodes
>> it with help of the Revel Lib (XVID encoding Lib) to MPEG4.
>>
>> The functions which open the device and starts the Server look like
>> this:
>>
>> void init_play(){
>>
>> // Open the input source
>> DeviceParameters params;
>>
>> fileSource = DeviceSourceCammera::createNew(*env, params);
>> if (fileSource == NULL) {
>> *env << "Unable to open source\n";
>> exit(1);
>> }
>>
>> }
>>
>> void play() {
>>
>> FramedSource* videoES = fileSource;
>>
>> // Create a framer for the Video Elementary Stream:
>> videoSource = MPEG4VideoStreamFramer::createNew(*env, videoES);
>>
>> // Finally, start playing:
>> *env << "Beginning to read from file...\n";
>> videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
>> }
>>
>>
>>> From debuging outputs implemented in the DeviceSourceCammera.cpp by
>>>
>> running the programm I can see that it really opens the device, grab a
>> frame and encodes it (the procedure repeats it self), but if I start
>> the
>> mplayer, it connects to the servers reads the sdp , it writes as output
>> at the end "Found video stream: 0" ,but it does not starts to play the
>> stream. It stays there with out do nothing (like waiting frames, but
>> never receives them)
>>
>> Any Idea why (or what?) is happening?
>>
>> The DeviceSourceCammera.cpp is included in this e-mail.
>> lvsMain.cpp is the "Main" file with the server start up code (also
>> included in this e-mail)
>> DeviceUtil.hh is the Header file which includes the basic Function
>> of my
>> code for handling the WebCam device. (this works, I have encoded a
>> video file, before to play with the LiveMedia Lib.)
>>
>> The subclass Functions look like this. If you need more details please
>> ask me or have a look in the attached files...
>>
>> DeviceSourceCammera::DeviceSourceCammera(UsageEnvironment& env,
>> DeviceParameters params)
>> : DeviceSource(env, params){
>>
>> init(); // Open Device
>> }
>>
>> void DeviceSourceCammera::doGetNextFrame() {
>>
>> grab_image(); //Take a Frame from the Camera
>>
>> if (0 /* the source stops being readable */) {
>> handleClosure(this);
>> fprintf(stderr,"In Grab Image V4l, the source stops being readable
>> !!!!\n");
>> return;
>> }
>>
>> deliverFrame(); // call DeviceSourceCammera::deliverFrame()
>> Function.
>> }
>>
>> DeviceSourceCammera::deliverFrame() {
>>
>> //Encoding the grub frame from the Camera
>>
>> if (get_grab_size() > fMaxSize){
>> frameSize = fMaxSize;
>> }
>> else frameSize = get_grab_size();
>>
>> fTo = (unsigned char*)malloc(frameSize);
>>
>> memcpy(fTo, frame.pixels, frameSize); // frame.pixels is the buffer
>> where the grubed frame is now encoded, framesize the size of the
>> encoded
>> frame
>> }
>>
>> Thank you very much for your help and your time !!!!
>> Sorry about my bad english too.
>>
>> Ioannis.
>>
>>
>> #include "DeviceSourceCammera.hh"
>> #include "DeviceUtil.hh"
>> DeviceSourceCammera*
>> DeviceSourceCammera::createNew(UsageEnvironment& env,
>> DeviceParameters params) {
>> return new DeviceSourceCammera(env, params);
>> }
>>
>> DeviceSourceCammera::DeviceSourceCammera(UsageEnvironment& env,
>> DeviceParameters params)
>> : DeviceSource(env, params){
>> // Any initialization of the device would be done here
>>
>> init();
>>
>> }
>>
>> DeviceSourceCammera::~DeviceSourceCammera() {
>> //printf("DeviceSourceCammera Deconstructor...");
>> }
>>
>> void DeviceSourceCammera::doGetNextFrame() {
>>
>> // Arrange here for our "deliverFrame" member function to be called
>> // when the next frame of data becomes available from the device.
>> // This must be done in a non-blocking fashion - i.e., so that we
>> // return immediately from this function even if no data is
>> // currently available.
>> //
>> // If the device can be implemented as a readable socket, then one
>> easy
>> // way to do this is using a call to
>> // envir().taskScheduler().turnOnBackgroundReadHandling( ... )
>> // (See examples of this call in the "liveMedia" directory.)
>>
>> grab_image();
>> fprintf(stderr,"In Grab Image V4l...\n");
>>
>> // If, for some reason, the source device stops being readable
>> // (e.g., it gets closed), then you do the following:
>> if (0 /* the source stops being readable */) {
>> handleClosure(this);
>> fprintf(stderr,"In Grab Image V4l, the source stops being
>> readable !!!!\n");
>> return;
>> }
>> deliverFrame();
>> }
>>
>> void DeviceSourceCammera::deliverFrame() {
>> // This would be called when new frame data is available from the
>> device.
>> // This function should deliver the next frame of data from the
>> device,
>> // using the following parameters (class members):
>> // 'in' parameters (these should *not* be modified by this function):
>> // fTo: The frame data is copied to this address.
>> // (Note that the variable "fTo" is *not* modified. Instead,
>> // the frame data is copied to the address pointed to by
>> "fTo".)
>> // fMaxSize: This is the maximum number of bytes that can be
>> copied
>> // (If the actual frame is larger than this, then it should
>> // be truncated, and "fNumTruncatedBytes" set accordingly.)
>>
>> // 'out' parameters (these are modified by this function):
>> // fFrameSize: Should be set to the delivered frame size (<=
>> fMaxSize).
>> // fNumTruncatedBytes: Should be set iff the delivered frame
>> would have been
>> // bigger than "fMaxSize", in which case it's set to the
>> number of bytes
>> // that have been omitted.
>> // fPresentationTime: Should be set to the frame's
>> presentation time
>> // (seconds, microseconds).
>> // fDurationInMicroseconds: Should be set to the frame's
>> duration, if known.
>> if (!isCurrentlyAwaitingData()){
>> printf("isCurrentlyAwaitingData: Return; \n");
>> return; // we're not ready for the data yet
>> }
>> // Deliver the data here:
>>
>> //---------------------- Start Revel
>> --------------------------------------------
>> fprintf(stderr,"In DeviceSourceCammera deliver Frame\n");
>>
>> int width = 160;
>> int height = 120;
>> int numFrames = 128;
>> long frames;
>>
>> const char *filename = "test.m4v";
>> Revel_Error revError;
>> // Make sure the API version of Revel we're compiling against
>> matches the
>> // header files! This is terribly important!
>> if (REVEL_API_VERSION != Revel_GetApiVersion())
>> {
>> printf("ERROR: Revel version mismatch!\n");
>> printf("Headers: version %06x, API version %d\n",
>> REVEL_VERSION,
>> REVEL_API_VERSION);
>> printf("Library: version %06x, API version %d\n",
>> Revel_GetVersion(),
>> Revel_GetApiVersion());
>> exit(1);
>> }
>>
>> // Create an encoder
>> int encoderHandle;
>> revError = Revel_CreateEncoder(&encoderHandle);
>> if (revError != REVEL_ERR_NONE)
>> {
>> printf("Revel Error while creating encoder: %d\n",
>> revError);
>> exit(1);
>> }
>>
>> // Set up the encoding parameters. ALWAYS call
>> Revel_InitializeParams()
>> // before filling in your application's parameters, to ensure
>> that all
>> // fields (especially ones that you may not know about) are
>> initialized
>> // to safe values.
>> Revel_Params revParams;
>> Revel_InitializeParams(&revParams);
>> revParams.width = width;
>> revParams.height = height;
>> revParams.frameRate = 8.0f;
>> revParams.quality = 1.0f;
>> revParams.codec = REVEL_CD_XVID;
>>
>> // Initiate encoding
>> revError = Revel_EncodeStart(encoderHandle, filename, &revParams);
>> if (revError != REVEL_ERR_NONE)
>> {
>> printf("Revel Error while starting encoding: %d\n",
>> revError);
>> exit(1);
>> }
>>
>> // Draw and encode each frame.
>> Revel_VideoFrame frame;
>> frame.width = width;
>> frame.height = height;
>> frame.bytesPerPixel = 3;
>> frame.pixelFormat = REVEL_PF_BGR;
>> frame.pixels = new int[get_grab_size()*4];
>>
>> memset(frame.pixels, 0, get_grab_size());
>>
>> grab_image();
>> memcpy(frame.pixels, get_grab_data(), get_grab_size());
>>
>> int i=0;
>> int frameSize;
>>
>> //Copy raw Frame from the WebCam and encode it
>> grab_image();
>> memcpy(frame.pixels, get_grab_data(), get_grab_size());
>> frames++;
>>
>> revError = Revel_EncodeFrame(encoderHandle, &frame,
>> &frameSize);
>> if (revError != REVEL_ERR_NONE)
>> {
>> printf("Revel Error while writing frame: %d\n",
>> revError);
>> exit(1);
>> }
>>
>> //Set Device Source Params...
>> if (get_grab_size() > fMaxSize){
>> frameSize = fMaxSize;
>> }
>> else frameSize = get_grab_size();
>> fFrameSize = frameSize;
>>
>> //Copy to DeviceSource...
>> fTo = (unsigned char*)malloc(frameSize);
>> memcpy(fTo, frame.pixels, frameSize);
>>
>> printf("Frame %d : %d bytes\n", i+1, frameSize);
>>
>> // Final cleanup.
>> Revel_DestroyEncoder(encoderHandle);
>> delete [] (int*)frame.pixels;
>>
>> //-------------------------End Revel
>> -------------------------------------------
>>
>> // After delivering the data, switch to another task, and inform
>> // the reader that he has data:
>> nextTask()
>> = envir().taskScheduler().scheduleDelayedTask(0, (TaskFunc*)
>> afterGetting,this);
>>
>> }
>>
>> // "liveMedia"
>> // Copyright (c) 1996-2004 Live Networks, Inc. All rights reserved.
>> // A template for a MediaSource encapsulating an audio/video input
>> device
>> // C++ header
>>
>> #include <DeviceSource.hh>
>>
>>
>>
>> class DeviceSourceCammera: public DeviceSource {
>> public:
>> static DeviceSourceCammera* createNew(UsageEnvironment& env,
>> DeviceParameters params);
>>
>> protected:
>> DeviceSourceCammera(UsageEnvironment& env, DeviceParameters params);
>> // called only by createNew(), or by subclass constructors
>> virtual ~DeviceSourceCammera();
>>
>> private:
>> // redefined virtual functions:
>> virtual void doGetNextFrame();
>>
>> private:
>> void deliverFrame();
>>
>> private:
>> DeviceParameters fParams;
>> };
>>
>> #include <DeviceUtil.hh>
>> //V4l Glabal Var...
>> int grab_fd, grab_size;
>> static struct video_mmap grab_buf;
>> int yuv_width = 320;
>> int yuv_height = 240;
>> //int yuv_width = 160;
>> //int yuv_height = 120;
>> static unsigned char *grab_data = NULL;
>>
>> unsigned char *get_grab_data(){
>> return grab_data;
>> }
>>
>> int get_grab_size(){
>> return grab_size;
>> }
>>
>> //V4l Fct...
>> void deinit() {
>> munmap(grab_data, grab_size);
>> grab_data = NULL;
>> close(grab_fd);
>> }
>>
>> void init() {
>>
>> struct video_capability grab_cap;
>> struct video_channel grab_chan;
>> struct video_mbuf vid_mbuf;
>> struct video_picture pic;
>>
>> atexit(deinit);
>>
>> if ((grab_fd = open(VIDEO_DEVICE, O_RDWR)) == -1) {
>> fprintf(stderr, "Couldn't open /dev/videoXXX: %s\n", strerror
>> (errno));
>> exit(-1);
>> }
>>
>> if (ioctl(grab_fd, VIDIOCGCAP, &grab_cap) == -1) {
>> perror("ioctl VIDIOCGCAP");
>> exit(-1);
>> }
>> //------------- VIDEO CAPABILITIES ------------------
>> printf("------------------------------------\n");
>> printf("------------------------------------\n");
>> printf("name hola-> %s\n", grab_cap.name);
>> printf("type -> %d\n", grab_cap.type);
>> printf("channels -> %d\n", grab_cap.channels);
>> printf("audios -> %d\n", grab_cap.audios );
>> printf("maxwidth -> %d\n", grab_cap.maxwidth );
>> printf("maxheight -> %d\n", grab_cap.maxheight);
>> printf("minwidth -> %d\n", grab_cap.minwidth );
>> printf("minheight -> %d\n", grab_cap.minheight );
>> printf("------------------------------------\n");
>> //----------------------------------------------------
>>
>> grab_chan.channel = 1; //Or 0 ????
>> grab_chan.type = VIDEO_TYPE_CAMERA;
>>
>> if (ioctl(grab_fd, VIDIOCGCHAN, &grab_chan) == -1) {
>> perror("ioctl VIDOCGCHAN");
>> exit(-1);
>> }
>>
>> grab_chan.norm = 0; // grab_chan.norm = VIDEO_MODE_PAL;
>>
>> if (ioctl(grab_fd, VIDIOCSCHAN, &grab_chan) == -1) {
>> perror("ioctl VIDIOCSCHAN");
>> exit(-1);
>> }
>> //------------IMAGE PROPERTIES-------------------------
>> pic.depth = 24;
>> pic.palette = VIDEO_PALETTE_RGB24;
>> pic.brightness = 100;
>> pic.contrast = 30;
>> pic.whiteness = 0;
>> pic.colour = 0;
>> pic.hue = 0;
>>
>> printf("------------------------------------\n");
>> printf("brightness -> %d \n", pic.brightness/256 );
>> printf("hue -> %d\n", pic.hue/256);
>> printf("colour -> %d\n", pic.colour/256 );
>> printf("contrast -> %d \n", pic.contrast/256 );
>> printf("whiteness -> %d\n", pic.whiteness/256 );
>> printf("depth -> %d\n", pic.depth );
>> printf("palette -> %d \n", pic.palette );
>> printf("------------------------------------\n");
>>
>> ioctl(grab_fd, VIDIOCGPICT, &pic );
>> //-------------------------------------------------------
>>
>> grab_buf.format = VIDEO_PALETTE_RGB24; //Also
>> VIDEO_PALETTE_YUV420P or VIDEO_PALETTE_RAW or VIDEO_PALETTE_RGB24
>> grab_buf.frame = 0;
>> grab_buf.width = yuv_width;
>> grab_buf.height = yuv_height;
>>
>> ioctl(grab_fd, VIDIOCGMBUF, &vid_mbuf);
>>
>> grab_size = vid_mbuf.size;
>> grab_data = (unsigned char*)mmap(0, grab_size, PROT_READ |
>> PROT_WRITE, MAP_SHARED, grab_fd, 0);
>>
>> if ((grab_data == NULL) || (-1 == (int) grab_data)) {
>> fprintf(stderr, "Couldn't mmap\n");
>> exit(1);
>> }
>>
>> /* Useless? probably. */
>> setpriority(PRIO_PROCESS, 0, 20);
>> nice(20);
>> }
>>
>> void grab_image() {
>> int i = 0;
>> fd_set fds;
>>
>> FD_ZERO(&fds);
>> FD_SET(0, &fds);
>> FD_SET(grab_fd, &fds);
>>
>> /* Maybe a little nicer to the cpu ? */
>> select(grab_fd + 1, &fds, NULL, NULL, NULL);
>>
>> if (ioctl(grab_fd, VIDIOCMCAPTURE, &grab_buf) == -1) {
>> perror("ioctl VIDIOCMCAPTURE");
>> return;
>> }
>>
>> if (ioctl(grab_fd, VIDIOCSYNC, &i) == -1) {
>> perror("ioctrl VIDIOCSYNC");
>> return;
>> }
>> return;
>> }
>> //End V4l Fct...
>>
>> #include "revel.h"
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>> #include <errno.h>
>> #include <unistd.h>
>> #include <sys/ipc.h>
>> #include <sys/shm.h>
>> #include <sys/mman.h>
>> #include <sys/ioctl.h>
>> #include <sys/time.h>
>> #include <sys/resource.h>
>> #include <fcntl.h>
>> #include <linux/videodev.h>
>>
>> //#define GUID_I420_PLANAR 0x30323449
>> #define VIDEO_DEVICE "/dev/video1"
>>
>>
>> //End V4l Global Var...
>>
>> void deinit();
>> void init();
>> void grab_image();
>> int get_grab_size();
>> unsigned char *get_grab_data();
>>
>> /*Skazikis Ioannis
>> Live Video Streamming Programm
>> */
>> #include <liveMedia.hh>
>> #include <BasicUsageEnvironment.hh>
>> #include <GroupsockHelper.hh>
>> #include "DeviceSourceCammera.hh"
>> Boolean reuseFirstSource = true;
>>
>> UsageEnvironment* env;
>> char const* inputFileName = "test.m4v";
>> MPEG4VideoStreamFramer* videoSource;
>> RTPSink* videoSink;
>> DeviceSourceCammera* fileSource;
>>
>> void init_play();
>> void play(); // forward
>>
>> int main(int argc, char** argv) {
>> // Begin by setting up our usage environment:
>> TaskScheduler* scheduler = BasicTaskScheduler::createNew();
>> env = BasicUsageEnvironment::createNew(*scheduler);
>>
>> // Create 'groupsocks' for RTP and RTCP:
>> struct in_addr destinationAddress;
>> destinationAddress.s_addr = chooseRandomIPv4SSMAddress(*env);
>> // Note: This is a multicast address. If you wish instead to stream
>> // using unicast, then you should use the "testOnDemandRTSPServer"
>> // test program - not this test program - as a model.
>>
>> const unsigned short rtpPortNum = 18888;
>> const unsigned short rtcpPortNum = rtpPortNum+1;
>> const unsigned char ttl = 255;
>>
>> const Port rtpPort(rtpPortNum);
>> const Port rtcpPort(rtcpPortNum);
>>
>> Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);
>> rtpGroupsock.multicastSendOnly(); // we're a SSM source
>> Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);
>> rtcpGroupsock.multicastSendOnly(); // we're a SSM source
>>
>> // Create a 'MPEG-4 Video RTP' sink from the RTP 'groupsock':
>> videoSink = MPEG4ESVideoRTPSink::createNew(*env, &rtpGroupsock, 96);
>>
>> // Create (and start) a 'RTCP instance' for this RTP sink:
>> const unsigned estimatedSessionBandwidth = 500; // in kbps; for
>> RTCP b/w share
>> const unsigned maxCNAMElen = 100;
>> unsigned char CNAME[maxCNAMElen+1];
>> gethostname((char*)CNAME, maxCNAMElen);
>> CNAME[maxCNAMElen] = '\0'; // just in case
>> RTCPInstance* rtcp
>> = RTCPInstance::createNew(*env, &rtcpGroupsock,
>> estimatedSessionBandwidth, CNAME,
>> videoSink, NULL /* we're a server */,
>> True /* we're a SSM source */);
>> // Note: This starts RTCP running automatically
>>
>> RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554);
>> if (rtspServer == NULL) {
>> *env << "Failed to create RTSP server: " << env->getResultMsg()
>> << "\n";
>> exit(1);
>> }
>> ServerMediaSession* sms
>> = ServerMediaSession::createNew(*env, "testStream", inputFileName,
>> "Session streamed by \"testMPEG4VideoStreamer\"",
>> True /*SSM*/);
>> sms->addSubsession(PassiveServerMediaSubsession::createNew
>> (*videoSink, rtcp));
>> rtspServer->addServerMediaSession(sms);
>>
>> char* url = rtspServer->rtspURL(sms);
>> *env << "Play this stream using the URL \"" << url << "\"\n";
>> delete[] url;
>>
>> // Start the streaming:
>> *env << "Beginning streaming...\n";
>> init_play();
>> play();
>>
>> env->taskScheduler().doEventLoop(); // does not return
>>
>> return 0; // only to prevent compiler warning
>> }
>>
>> void afterPlaying(void* /*clientData*/) {
>> *env << "...done reading from file\n";
>>
>> Medium::close(videoSource);
>> // Note that this also closes the input file that this source read
>> from.
>>
>> // Start playing once again:
>> play();
>> }
>>
>> void init_play(){
>>
>> // Open the input source
>> DeviceParameters params;
>>
>> fileSource = DeviceSourceCammera::createNew(*env, params);
>> if (fileSource == NULL) {
>> *env << "Unable to open source\n";
>> exit(1);
>> }
>>
>> }
>>
>> void play() {
>>
>> FramedSource* videoES = fileSource;
>>
>> // Create a framer for the Video Elementary Stream:
>> videoSource = MPEG4VideoStreamFramer::createNew(*env, videoES);
>>
>> // Finally, start playing:
>> *env << "Beginning to read from file...\n";
>> videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
>> }
>>
>> /** \mainpage Revel (The Really Easy Video Encoding Library
>> * The Revel library provides the shortest path between your
>> application and
>> * high-quality video output.
>> *
>> * Using Revel generally involves the following sequence of function
>> calls:
>> * - Ensure binary compatibility by testing REVEL_API_VERSION against
>> * Revel_GetApiVersion().
>> * - Create an encoder with Revel_CreateEncoder().
>> * - Declare a Revel_Params object. initialize it to safe defaults with
>> * Revel_InitializeParams(), and then fill in the fields to fit your
>> * application's needs. Pass the object to Revel_EncodeStart() to
>> begin
>> * the encoding process.
>> * - Use Revel_EncodeFrame() to pass in individual video frames in
>> * the order you'd like them to appear. Optionally, you can
>> * use Revel_EncodeAudio() to provide an audio track for your movie.
>> * - Stop the encoding process with Revel_EncodeEnd(). This finalizes
>> * the output movie and makes it viewable. Don't skip this step!
>> * - Destory the encode object with Revel_DestoryEncoder().
>> */
>>
>> /** \example reveltest.cpp
>> * This file contains a complete demonstration of Revel in action.
>> * It generates a short movie of an animating checkerboard
>> * pattern, complete with audio.
>> */
>>
>> /*
>> Copyright (C) (2004) (Cort Stratton) <cort at cortstratton dot org>
>>
>> This program is free software; you can redistribute it and/or
>> modify it under the terms of the GNU General Public License
>> as published by the Free Software Foundation; either
>> version 2 of the License, or (at your option) any later
>> version.
>>
>> This program is distributed in the hope that it will be useful,
>> but WITHOUT ANY WARRANTY; without even the implied warranty of
>> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> GNU General Public License for more details.
>>
>> You should have received a copy of the GNU General Public License
>> along with this program; if not, write to the Free Software
>> Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>> */
>>
>> #ifndef REVEL_H
>> #define REVEL_H
>>
>> #ifdef __cplusplus
>> extern "C" {
>> #endif
>>
>> /* Version information. */
>> #define REVEL_VERSION 0x010100 /**< Updated for every release. */
>> #define REVEL_API_VERSION 2 /**< Updated only when the public API
>> changes. */
>>
>> /**
>> * Retrieves the run-time value of REVEL_VERSION.
>> * Use this function for run-time binary compatibility tests.
>> * @return The run-time value of REVEL_VERSION.
>> */
>> int Revel_GetVersion(void);
>>
>> /**
>> * Use this function to check for run-time binary compatibility.
>> * Specifically, if REVEL_API_VERSION != Revel_GetApiVersion(),
>> * then your library and header files are out of date, and
>> * Revel's behavior will be undefined!
>> * @return The run-time value of REVEL_API_VERSION.
>> */
>> int Revel_GetApiVersion(void);
>>
>> /**
>> * List of legal pixel formats for input video frames.
>> */
>> typedef enum
>> {
>> REVEL_PF_BGRA = 0, /**< 32-bit BGRA */
>> REVEL_PF_ABGR, /**< 32-bit ABGR */
>> REVEL_PF_RGBA, /**< 32-bit RGBA */
>> REVEL_PF_ARGB, /**< 32-bit ARGB */
>> REVEL_PF_BGR, /**< 24-bit BGR */
>> REVEL_PF_RGB555, /**< 16-bit RGB 5-5-5 packed */
>> REVEL_PF_RGB565, /**< 16-bit RGB 5-6-5 packed */
>>
>> REVEL_PF_COUNT /**< Number of pixel formats (this is NOT a
>> legal pixel format!) */
>> } Revel_PixelFormat;
>>
>>
>> /**
>> * List of supported video codecs.
>> */
>> typedef enum
>> {
>> REVEL_CD_XVID = 0, /**< XviD (http://www.xvid.org) */
>>
>> REVEL_CD_COUNT /**< Number of video codecs (this is NOT a
>> legal codec!) */
>> } Revel_VideoCodec;
>>
>> /**
>> * Partial list of supported audio sample formats.
>> * This enum only contains the most common sample formats.
>> * In actuality, any of the Microsoft WAVE_FORMAT_XXX values is
>> * legal. Please refer to the Windows mmreg.h file (available
>> * on the web at:
>> * http://graphics.cs.uni-sb.de/NMM/dist-0.6.0/Docs/Doxygen/html/
>> mmreg_8h.html)
>> * for a full list of supported sample formats and their associated
>> * numerical values.
>> */
>> typedef enum
>> {
>> REVEL_ASF_UNKNOWN = 0x0000, /**< Unknown format / no audio
>> present. */
>> REVEL_ASF_PCM = 0x0001, /**< PCM format (the most common
>> choice). */
>> REVEL_ASF_ADPCM = 0x0002, /**< ADPCM format. */
>> REVEL_ASF_ALAW = 0x0006, /**< A-law format. */
>> REVEL_ASF_MULAW = 0x0007, /**< mu-law format. */
>> } Revel_AudioSampleFormat;
>>
>>
>> /**
>> * List of error codes.
>> */
>> typedef enum
>> {
>> REVEL_ERR_NONE = 0, /**< No error (the operation
>> completed successfully). */
>> REVEL_ERR_UNKNOWN, /**< An unknown/unclassified error. */
>> REVEL_ERR_INVALID_HANDLE, /**< An invalid handle was passed to
>> the function. */
>> REVEL_ERR_PARAMS, /**< Invalid parameters passed to
>> the function. */
>> REVEL_ERR_FILE, /**< A file I/O error. */
>> REVEL_ERR_MEMORY, /**< A memory-related error. */
>> REVEL_ERR_BUSY, /**< Revel is busy with another
>> operation. */
>>
>> REVEL_ERR_COUNT /**< Number of error types (this is
>> nOT a legal error code!) */
>> } Revel_Error;
>>
>> /**
>> * General info about the video to encode.
>> */
>> typedef struct
>> {
>> unsigned int width, height; /**< width/height in pixels */
>> float frameRate; /**< frames per second. */
>> float quality; /**< ranges 0 to 1 */
>> Revel_VideoCodec codec; /**< This codec will be used to compress
>> the video frames. */
>>
>> /**
>> * If 1, the output movie will include an audio stream.
>> * Any other value means the movie will be silent.
>> */
>> int hasAudio;
>>
>> /* The following fields are ignored unless hasAudio is 1 */
>> int audioRate; /**< audio sample rate, e.g. 22050, 44100 */
>> int audioBits; /**< bits per audio sample, e.g. 8, 16 */
>> int audioChannels; /**< Number of channels in the audio stream
>> (1=mono, 2=stereo) */
>> int audioSampleFormat; /**< Format of the audio sample data. */
>> } Revel_Params;
>>
>>
>> /**
>> * Represents a frame of video. Use this to pass raw images
>> * into Revel to be encoded.
>> */
>> typedef struct
>> {
>> unsigned int width, height; /**< width/height in pixels. */
>> unsigned char bytesPerPixel; /**< color depth of pixels, in
>> bytes. */
>> Revel_PixelFormat pixelFormat; /**< color channel ordering for
>> these pixels. */
>> void *pixels; /**< Pointer to pixel data. */
>> } Revel_VideoFrame;
>>
>>
>> /**
>> * Create an encoder for your movie. Call me first!
>> * @param encoderHandle A handle to the new encoder will be stored
>> here.
>> * @return REVEL_ERR_NONE if success, an error code if not.
>> */
>> Revel_Error Revel_CreateEncoder(int *encoderHandle);
>>
>>
>> /**
>> * Initialize a Revel_Params structure to safe default values.
>> *
>> * It is very important that you call this function on your
>> * Revel_Params structure before filling it out yourself! Otherwise,
>> * if you upgrade to a new version of Revel in which new fields
>> * were added to Revel_Param, they would be left uninitialized in
>> * your application, and Terrible Things could happen.
>> *
>> * You should not rely on any of the specific default values used in
>> this
>> * function -- while they are guarenteed to be safe, they are NOT
>> guarenteed
>> * to be correct for your application.
>> *
>> * @param params This structure will be filled with safe default
>> values.
>> */
>> void Revel_InitializeParams(Revel_Params *params);
>>
>> /**
>> * Start encoding a new movie.
>> *
>> * @param encoderHandle Must be a valid encoder handle.
>> * @param filename The output movie will be written to this file.
>> * @param params Fill this structure with your movie settings before
>> calling.
>> * @return REVEL_ERR_NONE if success, an error code if not.
>> */
>> Revel_Error Revel_EncodeStart(int encoderHandle, const char* filename,
>> Revel_Params *params);
>>
>>
>> /**
>> * Encode a single frame and write it to the video stream.
>> *
>> * @param encoderHandle must be a valid encoder handle.
>> * @param frame The video frame to encode. It will not be written
>> to at all,
>> * so it is unnecessary to make a copy of your
>> framebuffer first.
>> * @param frameSize If non-NULL, the size of the encoded frame (in
>> bytes) will
>> * be stored here.
>> * @return REVEL_ERR_NONE if success, an error code if not.
>> */
>> Revel_Error Revel_EncodeFrame(int encoderHandle,
>> Revel_VideoFrame *frame, int
>> *frameSize = 0);
>>
>>
>> /**
>> * Encode a chunk of audio data to the movie.
>> *
>> * This function will have no effect if the hasAudio field of
>> Revel_Params
>> * passed to Revel_EncodeStart() was 0.
>> * Each new audio chunk will be appended to the end of the existing
>> audio
>> * data. See the Revel FAQ (http://www.dangerware.org/cgi-bin/
>> revelfaq.py)
>> * for important ramifications of this behavior!
>> *
>> * @param encoderHandle must be a valid encoder handle.
>> * @param sampleBuffer The array of audio samples. The sample data
>> must
>> * be of the same format specified in the
>> Revel_Params
>> * structure passed to Revel_EncodeStart().
>> * @param numBytes The size of the sampleBuffer array, in bytes.
>> * @param numTotalBytes If non-NULL, the total number of bytes of audio
>> * encoded so far will be stored here.
>> * @return REVEL_ERR_NONE if success, an error code if not.
>> */
>> Revel_Error Revel_EncodeAudio(int encoderHandle, void *sampleBuffer,
>> int numBytes, int *numTotalBytes = 0);
>>
>>
>> /**
>> * Finalize the new movie.
>> *
>> * This function MUST be called when you're finished encoding, or
>> the output
>> * movie will be corrupted and unviewable!
>> *
>> * @param encoderHandle must be a valid encoder handle.
>> * @param totalSize If non-NULL, the total size of the output movie
>> (in bytes)
>> * will be stored here.
>> * @return REVEL_ERR_NONE if success, an error code if not.
>> */
>> Revel_Error Revel_EncodeEnd(int encoderHandle, int *totalSize = 0);
>>
>>
>> /**
>> * Destroys an encoder through its handle, and frees the memory
>> associated
>> * with it.
>> *
>> * @param encoderHandle A handle to the encoder to destroy.
>> * @return REVEL_ERR_NONE if success, an error code if not.
>> */
>> Revel_Error Revel_DestroyEncoder(int encoderHandle);
>>
>> #ifdef __cplusplus
>> }
>> #endif
>> #endif
>>
>>
>> <mime-attachment.txt>
>>
>
> -----------------------------------------------------------
> Scott Hays
> R&D Engineer
> http://www.neon.com.tw/
> Neon Advanced Technology Co., Ltd.
>
>
>
> _______________________________________________
> live-devel mailing list
> live-devel at lists.live.com
> http://lists.live.com/mailman/listinfo/live-devel
>
It worked !!!
Thank you very much for your help !!!
Ioannis.
More information about the live-devel
mailing list