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;
} |
Partager