Bonsoir à tous,

J'ai un petit problème avec la librairie ffmpeg.
J'ai fais un petit programme tout bête qui capture une image d'une webcam, le programme fonctionne impeccablement mais en voulant l'améliorer j'obtiens soit une erreur de segmentation soit la librairie ffmpeg ne trouve plus ma webcam "/dev/video0".

Cela se produit rien qu'en "décommentant" la ligne "char *dev" : le programme ne fonctionne plus et bogue dans la fonction av_open_input_file(..).

Quelque chose m'échappe, ça fait déjà pas mal de temps que je cherche l'erreur mais je ne la trouve pas.

Est-ce que quelqu'un à une idée?

Merci d'avance.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
 
#include <stdio.h>
#include <stdlib.h>
 
#define WIDTH 640
#define HEIGHT 480
#define FIRST_FRAME 10
 
void SaveFrame90(AVFrame *pFrame, int width, int height, int iFrame)
{
  FILE *pFile;
  char szFilename[32];
  int  x,y;
 
  // ouvrir le fichier
  sprintf(szFilename, "frames/frame%d.ppm", iFrame);
  pFile=fopen(szFilename, "wb");
  if(pFile==NULL)
    return;
 
  // ecrire l'entete
  fprintf(pFile, "P6\n%d %d\n255\n", height, width);
 
  // ecrire les donnees des pixels
	for (x=0; x<width; x++)
  	for(y=height-1; y>=0; y--)
 
    	fwrite(pFrame->data[0]+3*x+y*pFrame->linesize[0], 1, 3, pFile);
  // fermer le fichier
  fclose(pFile);
}
 
int main(int argc, char *argv[])
{
	int LAST_FRAME = FIRST_FRAME;
	/* variable pour la video */
  AVFormatContext *pFormatCtx = NULL;
  int             videoStream;
	unsigned int		i;
  AVCodecContext  *pCodecCtx;
  AVCodec         *pCodec;
  AVFrame         *pFrame; 
  AVFrame         *pFrameRGB;
  AVPacket        packet;
  int             frameFinished;
  int             numBytes;
  uint8_t         *buffer;
//	char					  *dev;
 
	/* spécial pour les periphériques v4l (video4linux) */
	AVFormatParameters formatParams;
	AVInputFormat *iformat = NULL;
 
	/* contexte de convertion */
	static struct SwsContext *img_convert_ctx = NULL;
	int quit = 0;
 
  /*if(argc > 1)
  {
		sscanf(argv[1],"%u",&LAST_FRAME);
		if (LAST_FRAME==0)
		{
			dev=strdup("/dev/video0");
		}
		else
		{
			dev=strdup("/dev/video1");
		}
		if (argc > 2)
		{
    	sscanf(argv[2],"%u",&LAST_FRAME);
			LAST_FRAME += FIRST_FRAME;
		}
		else
		{
			LAST_FRAME = FIRST_FRAME;
		}	
  }
	else
	{
		dev=strdup("/dev/video0");
	}*/
 
  /* initialiser la librairie */
  av_register_all();
	avdevice_register_all();
	avcodec_register_all();
 
	/* renseignement webcam */
	formatParams.channel = 0;
	formatParams.standard = NULL;
	formatParams.width = WIDTH;
	formatParams.height = HEIGHT;
 
	iformat = av_find_input_format("video4linux");
 
	/* ouvrir la video */
	if (av_open_input_file(&pFormatCtx, "/dev/video0", iformat, 0, &formatParams))
	{
		/* impossible d'ouvrir la video tentative avec v4l2 */
		iformat = av_find_input_format("video4linux2");
		if (av_open_input_file(&pFormatCtx, "/dev/video0", iformat, 0, &formatParams))
		{
			fprintf(stderr,"erreur impossible d'ouvrir la video\n");
			return EXIT_FAILURE;
		}
	}
 
  /* pour debuguer : on affiche le format de la video */
  dump_format(pFormatCtx, 0, "/dev/video0", 0);
 
  // trouver le debut de la video
  videoStream=-1;
  for(i=0; i<pFormatCtx->nb_streams; i++)
    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
		{
      videoStream=i;
      break;
    }
  if(videoStream==-1)
    return -1;
 
  // pointeur vers le codec de la video
  pCodecCtx=pFormatCtx->streams[videoStream]->codec;
 
  // decodeur pour le flux video
  pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  if(pCodec==NULL) 
	{
    fprintf(stderr, "Unsupported codec!\n");
    return -1;
  }
  // ouvrir le codec
  if(avcodec_open(pCodecCtx, pCodec)<0)
    return -1;
 
  // allouer de la memoire pour l'image
  pFrame=avcodec_alloc_frame();
 
  // allouer de la memoire pour l'image en RGB
  pFrameRGB=avcodec_alloc_frame();
  if(pFrameRGB==NULL)
    return -1;
 
  // alouer de la memoire pour le buffer video
  numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
			      pCodecCtx->height);
  buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
 
  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
		 pCodecCtx->width, pCodecCtx->height);
 
  i=0;
	/* lecture du flux video */
  while ((av_read_frame(pFormatCtx, &packet)>=0)&&(quit==0))
  {
    /* packet du flux video ? */
    if(packet.stream_index==videoStream) 
		{
      /* oui on decode */
			/* deprecated depend de la version de ffmpeg */
      /* avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, 
			   packet.data, packet.size); */
			avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
 
      /* la frame est complete ? */
      if(frameFinished)
			{
				/* img_convert n'existe plus */
				/*img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, 
						              (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, 
						              pCodecCtx->height);*/
				/* on converti en RGB */
				if (img_convert_ctx==NULL)
				{
					img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, 
			                    pCodecCtx->pix_fmt, 
			                    pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, 
			                    NULL, NULL, NULL);
					if (img_convert_ctx == NULL)
					{
						fprintf(stderr,"erreur contexte de convertion d'image\n");
						return EXIT_FAILURE;
					}
				}
				sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, 
					        pFrame->linesize, 0, 
					        pCodecCtx->height, 
					        (uint8_t* const*)pFrameRGB->data, pFrameRGB->linesize);
 
				/* on sauvegarde les images entre FIRST_FRAME et LAST_FRAME */
				i++;
				if ((i>=FIRST_FRAME)&&(i<=LAST_FRAME))
				{
					SaveFrame90(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i-FIRST_FRAME);
					printf("%3.1f%\n",100.0*(i-FIRST_FRAME)/(LAST_FRAME-FIRST_FRAME));
				}
				if (i==LAST_FRAME)
				{
					quit=1;
				}
			}
		}
    /* on libère la memoire du packet */
    av_free_packet(&packet);
  }
 
	/* liberer le contexte de conversion */
	sws_freeContext(img_convert_ctx);
 
  /* liberer le buffer et l'image */
  av_free(buffer);
  av_free(pFrameRGB);
  av_free(pFrame);
 
  /* fermer le codec */
  avcodec_close(pCodecCtx);
 
  /* fermer le fichier video */
  av_close_input_file(pFormatCtx); 
//	free(dev);
  return 0;
}