]> rtime.felk.cvut.cz Git - v4l-streaming.git/blob - grab_mpeg.c
Initial commit
[v4l-streaming.git] / grab_mpeg.c
1 /**
2  * \defgroup common
3  *  
4  * \brief Grab form camere, transfer to the MPEG and transmitt to the LAN
5  *
6  * This application handle USB camere.
7  *
8  * \note Note.
9  *
10  * \author (last to touch it) $Author: zial (Ales Zikmund)$
11  *
12  * \version $Revision: 1.0 $
13  *
14  * \date $Date: 2008/12/12 5:45:20 $
15  *
16  * Contact: zikmua1@fel.cvut.cz
17  *
18  * Created on: Wed Dec 13 18:39:37 2008
19  *
20  */
21
22 /**
23  *  \file  grab_mpeg.c
24  *
25  *  \brief This is the main file where  application run.
26  * 
27  */
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "camv4l.h"
33 #include <ffmpeg/avcodec.h>
34
35
36 ///Codec
37 AVCodec *codec;
38
39 ///Contex of codec
40 AVCodecContext *c;
41
42 int i;
43 int out_size;
44 int size;
45
46 ///File name
47 FILE *f;
48
49 ///Frame of picture
50 AVFrame *picture;
51
52 ///Output mpeg frame
53 uint8_t *outbuf;
54 //Size of output 
55 int outbuf_size;
56
57 ///Max count of frame
58 int max_frame;
59
60 ///V4L device
61 struct vdIn myvidIn;
62
63 /**
64  *  Function make frame from videodevice and send to.
65  */
66 void processvideo ();
67
68 /**
69  * Alloc and set codec
70  */
71 void video_encode_alloc(const char *filename,uint8_t* in_buffer);
72
73 /**
74  * Encode global buffer from picture .
75  */
76 void video_encode_mpeg();
77
78 /**
79  * Free memory
80  */
81 void video_encode_free();
82
83
84 /**
85  *  The main function
86  *       \param count   Count of byte
87  *       \param strings String after run sequnce of aplicationss
88  *       \return 1 if all good
89  */
90 int main(int argc, char *argv[])
91 {       
92         c= NULL;
93         int retval;
94
95         const char *videodev ="/dev/video0";
96         const char *filename = "pokus.mpg";
97
98         max_frame=300;
99
100
101         for (i = 1; i < argc; i++){
102       /* skip bad arguments */
103       if (argv[i] == NULL || *argv[i] == 0 || *argv[i] != '-'){
104                   continue;
105                 }
106       if (strcmp (argv[i], "-f") == 0){
107                         if (i + 1 >= argc){
108                                 printf ("No parameter specified with -f, aborting.\n");
109                 exit (1);
110                 }
111                         max_frame = atoi(argv[i + 1]);
112                 }
113                 if (strcmp (argv[i], "-d") == 0){
114                         if (i + 1 >= argc){
115                                 printf ("No parameter specified with -d, aborting.\n");
116                 exit (1);
117                 }
118                         videodev = strdup (argv[i + 1]);
119                 }
120         if (strcmp (argv[i], "-h") == 0) {
121                         printf ("usage: grab_mpeg [-h -f] \n");
122                         printf ("-h     print this help \n");
123                         printf ("-d     /dev/videoX       use videoX device\n");
124                         printf ("-f     count of frame \n");
125                         exit (0);
126                 }
127         }
128
129         printf("Video device %s frames %d\n",videodev,max_frame);
130         
131         int grabmethod = 1; //or 0
132
133         printf("Open %s\n",videodev);
134
135         /* make room for init data */
136         myvidIn.videodevice = NULL;
137         myvidIn.cameraname = NULL;
138         myvidIn.bridge = NULL;
139         myvidIn.videodevice = (char *) realloc (myvidIn.videodevice, 16);
140         myvidIn.cameraname = (char *) realloc (myvidIn.cameraname, 32);
141         myvidIn.bridge = (char *) realloc (myvidIn.bridge, 9);
142         myvidIn.grabMethod = grabmethod;        // 1 mmap 0 read
143         snprintf (myvidIn.videodevice, 12, "%s", videodev);
144         printf ("video device %s\n", myvidIn.videodevice);
145         retval=init_v4l (&myvidIn);
146         printf("Device was been initialized %d \n",retval);
147
148         video_encode_alloc(filename,myvidIn.pixTmp);
149         
150         processvideo();
151         
152         video_encode_free();
153
154         free (myvidIn.videodevice);
155         free (myvidIn.cameraname);
156         free (myvidIn.bridge);
157         close_v4l (&myvidIn);
158
159         printf("Close \n");
160
161         return 1;
162 }
163
164
165
166 void processvideo () 
167 {
168         int run = 1;
169         int cnt=0;
170
171         //set size of video
172         myvidIn.hdrwidth = 384;
173         myvidIn.hdrheight = 288;
174         myvidIn.formatIn = VIDEO_PALETTE_YUV420P;
175         /* input data maybe a jpeg one */
176         setPalette (&myvidIn);
177
178         while (run){    
179                 grab (&myvidIn);
180
181                 if(cnt>2)
182                         video_encode_mpeg();
183
184                 //sleep(1);
185       cnt++;
186                 if(cnt==max_frame){run=0;}
187                 printf("Frame %d\n",cnt);
188         }
189 }
190
191 void video_encode_alloc(const char *filename,uint8_t* in_buffer){
192         
193         /* must be called before using avcodec lib */
194    avcodec_init();
195  
196    /* register all the codecs */
197         avcodec_register_all();
198
199         //printf("Video encoding\n");
200         /* find the mpeg1 video encoder */
201         codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
202         if (!codec) {
203                 fprintf(stderr, "codec not found\n");
204                 exit(1);
205         }
206
207         c= avcodec_alloc_context();
208         picture= avcodec_alloc_frame();
209         /* put sample parameters */
210         c->bit_rate = 1000000;
211         /* resolution must be a multiple of two */
212         c->width = 384;
213         c->height = 288;
214         /* frames per second */
215         c->time_base= (AVRational){1,60};
216         c->gop_size = 10; /* emit one intra frame every ten frames */
217         c->max_b_frames=1;
218         c->pix_fmt = PIX_FMT_YUV420P;
219  
220         /* open codec */
221         if (avcodec_open(c, codec) < 0) {
222                 fprintf(stderr, "could not open codec\n");
223                 exit(1);
224         }
225
226         f = fopen(filename, "wb");
227         if (!f) {
228                 fprintf(stderr, "could not open %s\n", filename);
229                 exit(1);
230         }
231
232         /* alloc image and output buffer */
233         //buffer pro zakodovany obrazek mpegem
234         outbuf_size = 100000;
235         outbuf = malloc(outbuf_size);
236
237         size = c->width * c->height;
238
239         picture->data[0] = in_buffer;
240         picture->data[1] = picture->data[0] + size;
241         picture->data[2] = picture->data[1] + size / 4;
242         picture->linesize[0] = c->width;
243         picture->linesize[1] = c->width / 2;
244         picture->linesize[2] = c->width / 2;
245 }
246
247 void video_encode_mpeg(){
248         
249         /* encode the image */
250         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
251         //printf("encoding frame %3d (size=%5d)\n", i, out_size);
252         fwrite(outbuf, 1, out_size, f);
253 }
254
255
256 void video_encode_free(){
257
258         /* get the delayed frames */
259         for(; out_size; i++) {
260                 fflush(stdout);
261                 out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
262                 printf("write frame %3d (size=%5d)\n", i, out_size);
263                 fwrite(outbuf, 1, out_size, f);
264         }
265
266         /* add sequence end code to have a real mpeg file */
267         outbuf[0] = 0x00;
268         outbuf[1] = 0x00;
269         outbuf[2] = 0x01;
270         outbuf[3] = 0xb7;
271
272         fwrite(outbuf, 1, 4, f);
273
274         fclose(f);
275         //free(picture_buf);
276         free(outbuf);
277
278         avcodec_close(c);
279         av_free(c);
280         av_free(picture);
281         printf("\n");
282         printf("video codev was been freed\n");
283 }