Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / cinelerra / vdevicev4l2jpeg.C
blob7b060c4e4895ed2af45aea65fd1dac46af15651f
1 // V4L2 is incompatible with large file support
2 #undef _FILE_OFFSET_BITS
3 #undef _LARGEFILE_SOURCE
4 #undef _LARGEFILE64_SOURCE
7 #include "assets.h"
8 #include "channel.h"
9 #include "chantables.h"
10 #include "clip.h"
11 #include "condition.h"
12 #include "file.h"
13 #include "libmjpeg.h"
14 #include "picture.h"
15 #include "preferences.h"
16 #include "quicktime.h"
17 #include "recordconfig.h"
18 #include "vdevicev4l2jpeg.h"
19 #include "vdevicev4l2.h"
20 #include "vframe.h"
21 #include "videodevice.h"
23 #ifdef HAVE_VIDEO4LINUX2
25 #include <fcntl.h>
26 #include <string.h>
27 #include <sys/ioctl.h>
28 #include <sys/mman.h>
29 #include <unistd.h>
38 VDeviceV4L2JPEG::VDeviceV4L2JPEG(VideoDevice *device)
39  : VDeviceBase(device)
41         initialize();
44 VDeviceV4L2JPEG::~VDeviceV4L2JPEG()
46         close_all();
49 int VDeviceV4L2JPEG::initialize()
51         thread = 0;
55 int VDeviceV4L2JPEG::open_input()
57         return VDeviceV4L2::get_sources(device,
58                 device->in_config->v4l2jpeg_in_device);
61 int VDeviceV4L2JPEG::close_all()
63         if(thread) delete thread;
64         thread = 0;
65         return 0;
68 int VDeviceV4L2JPEG::get_best_colormodel(Asset_GC asset)
70         return BC_COMPRESSED;
73 int VDeviceV4L2JPEG::read_buffer(VFrame *frame)
75         int result = 0;
77         if((device->channel_changed || device->picture_changed) && thread)
78         {
79                 delete thread;
80                 thread = 0;
81         }
83         if(!thread)
84         {
85                 device->channel_changed = 0;
86                 device->picture_changed = 0;
87                 thread = new VDeviceV4L2Thread(device, BC_COMPRESSED);
88                 thread->start();
89         }
92 // Get buffer from thread
93         int timed_out;
94         VFrame *buffer = thread->get_buffer(&timed_out);
98         if(buffer)
99         {
100                 frame->allocate_compressed_data(buffer->get_compressed_size());
101                 frame->set_compressed_size(buffer->get_compressed_size());
103 // Transfer fields to frame
104                 if(device->odd_field_first)
105                 {
106                         int field2_offset = mjpeg_get_field2((unsigned char*)buffer->get_data(), 
107                                 buffer->get_compressed_size());
108                         int field1_len = field2_offset;
109                         int field2_len = buffer->get_compressed_size() - 
110                                 field2_offset;
112                         memcpy(frame->get_data(), 
113                                 buffer->get_data() + field2_offset, 
114                                 field2_len);
115                         memcpy(frame->get_data() + field2_len, 
116                                 buffer->get_data(), 
117                                 field1_len);
118                 }
119                 else
120                 {
121                         bcopy(buffer->get_data(), 
122                                 frame->get_data(), 
123                                 buffer->get_compressed_size());
124                 }
126                 thread->put_buffer();
127         }
128         else
129         {
130 // Driver in 2.6.3 needs to be restarted when it loses sync.
131                 if(timed_out)
132                 {
133                         delete thread;
134                         thread = 0;
135                 }
136                 result = 1;
137         }
140         return result;
145 #endif
149 //      Local Variables:
150 //      mode: C++
151 //      c-file-style: "linux"
152 //      End: