Hello, I try to use FFMpeg, this wonderful library through C language. But I encounter a problem : I have 900 pictures to crop, but at the image number 305, my app crash with message "Failed to allocate packet of size 34296000". I stuck because I don't know where is located my memory leak (av_malloc return NULL and my application consume more than 1800 Mb of RAM) ... Softwares used to build my project : - Pelles C (32 bits) - Windows 7 (32 bits) - ffmpeg-20120919-git-cb3591e-win32-dev.7z and appropriate dlls version (from zeranoe distrib) A snippet from my application : #include <windows.h> #include <stdio.h> #include <conio.h> #include <dirent.h> #include <direct.h> #include <sys/stat.h> #include "libavcodec/avcodec.h" #include "libavutil/opt.h" #include "libavformat/avformat.h" #include "libavutil/imgutils.h" #include "libswscale/swscale.h" typedef struct { AVCodec *codec; AVCodecContext *context; int index; } DataThumb; static BOOL write_image(AVCodecContext *pCodecCtx, AVFrame *pFrame, char *outfile) { BOOL result = FALSE; AVCodecContext *pOCodecCtx = avcodec_alloc_context3(avcodec_find_encoder(pCodecCtx->codec_id)); // // Allocate the output codec context // if (pOCodecCtx != NULL) { // // Initialise format parameters // pOCodecCtx->bit_rate = pCodecCtx->bit_rate; pOCodecCtx->width = pFrame->width; pOCodecCtx->height = pFrame->height; pOCodecCtx->pix_fmt = pCodecCtx->pix_fmt; pOCodecCtx->codec_id = CODEC_ID_MJPEG; pOCodecCtx->time_base = (AVRational) {1, 1}; pOCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO; // // Allocate the JPEG encoder // AVCodec *pOCodec = avcodec_find_encoder(pOCodecCtx->codec_id); if (pOCodec != NULL) { // // Open the JPEG encoder // if (avcodec_open2(pOCodecCtx, pOCodec, NULL) >= 0) { // // Initialise the "VBR" settings // pOCodecCtx->qmin = pOCodecCtx->qmax = 4; pOCodecCtx->mb_lmin = pOCodecCtx->lmin = pOCodecCtx->qmin * FF_QP2LAMBDA; pOCodecCtx->mb_lmax = pOCodecCtx->lmax = pOCodecCtx->qmax * FF_QP2LAMBDA; pOCodecCtx->flags = CODEC_FLAG_QSCALE; pOCodecCtx->global_quality = pOCodecCtx->qmin * FF_QP2LAMBDA; // // Set the timestamp and quality parameters // pFrame->pts = 1; pFrame->quality = pOCodecCtx->global_quality; AVPacket packet; av_init_packet(&packet); packet.data = NULL; packet.size = 0; // // Write JPEG to file // FILE *file = fopen(outfile, "wb"); int got_output; if (avcodec_encode_video2(pOCodecCtx, &packet, pFrame, &got_output) < 0) { result = FALSE; } else if(got_output) { fwrite(packet.data, 1, packet.size, file); } fclose(file); av_free_packet(&packet); result = TRUE; } } avcodec_close(pOCodecCtx); }
return result; } static BOOL sample_crop(char *source, char *destination, FLOAT ratio) { BOOL result = FALSE; AVFormatContext *pFormatCtx = avformat_alloc_context(); if(avformat_open_input(&pFormatCtx, source, NULL, NULL) == 0) { av_dump_format(pFormatCtx, 0, source, 0); AVCodecContext *pCodecCtx = pFormatCtx->streams[0]->codec; pCodecCtx->pix_fmt = PIX_FMT_YUV444P; AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec != NULL) { if (avcodec_open2(pCodecCtx, pCodec, NULL) >= 0) { AVFrame *pFrame = avcodec_alloc_frame(); if(pFrame != NULL) { // Read frame AVPacket packet; int frameFinished; while (av_read_frame(pFormatCtx, &packet) >= 0) { if (packet.stream_index == 0) { if (avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet) > 0) { pFrame->quality = 4; av_free_packet(&packet); // Il nous faut déterminer le plus grand rectangle // tout en respectant un certain ratio int minimum = 0; int maximum = pFrame->width; do { int mid = minimum + (maximum + minimum) / 2; if(mid / ratio <= pFrame->height) { minimum = mid + 1; } else { maximum = mid - 1; } } while(maximum < minimum); // On a enfin les nouvelles dimensions : AVFrame *cropped = avcodec_alloc_frame(); cropped->width = maximum; cropped->height = roundf(maximum / ratio); const int left = (int) (pFrame->width-cropped->width) / 2; const int top = (int) (pFrame->height-cropped->height) / 2; avpicture_alloc((AVPicture *) cropped, pCodecCtx->pix_fmt, cropped->width, cropped->height); if(av_picture_crop((AVPicture *) cropped, (AVPicture *) pFrame, pCodecCtx->pix_fmt, top, left) >= 0) { // L'image est retaillé : on la sauvegarde dans le fichier de sortie if(write_image(pCodecCtx, cropped, destination) == TRUE) { result = TRUE; } } av_free(cropped); break; } } } av_free(pFrame); } } avcodec_close(pCodecCtx); } } avformat_close_input(&pFormatCtx); return result; } static DataThumb *sample_open(UINT width, UINT height, enum AVCodecID codec, UINT fps) { DataThumb *result = (DataThumb *)av_malloc(sizeof(DataThumb)); result->codec = avcodec_find_encoder(codec); if (result->codec != NULL) { result->index = 0; result->context = avcodec_alloc_context3(result->codec); result->context->width = width; result->context->height = height; result->context->time_base = (AVRational) {1, fps}; result->context->pix_fmt = PIX_FMT_YUV444P; result->context->bit_rate = 5 * 1000 * 1000; result->context->gop_size = fps / 12; result->context->max_b_frames = 1; if (result->codec->id == AV_CODEC_ID_H264) av_opt_set(result->context->priv_data, "preset", "veryslow", 0); if (avcodec_open2(result->context, result->codec, NULL) >= 0) { return result; } } av_free(result); return NULL; } static void sample_close(DataThumb *tla) { avcodec_close(tla->context); av_free(tla); } #define MAXPATH 10 * 1024 int main(int argc, char *argv[]) { if(argc < 3) { printf("\n\tusage : %s {input folder} {output folder}\n", argv[0]); } else { avcodec_register_all(); av_register_all(); DataThumb *tla = sample_open(1920, 1080, AV_CODEC_ID_H264, 25); _DIR *d = _opendir(argv[1]); if (d) { int index = 1; struct _dirent *dir; _mkdir(argv[2]); while ((dir = _readdir(d)) != NULL) { char inputfile[MAXPATH]; struct _stat statbuf; sprintf(inputfile, "%s\\%s", argv[1], dir->d_name); _stat(inputfile, &statbuf); if(!_S_ISDIR(statbuf.st_mode)) { char outputfile[MAXPATH]; sprintf(outputfile, "%s\\%04d.jpg", argv[2], index); sample_crop(inputfile, outputfile, 16. / 9); index++; } } _closedir(d); } sample_close(tla); } return 0; } Sincerly, Guillaume _______________________________________________ Libav-user mailing list Libav-user@ffmpeg.org http://ffmpeg.org/mailman/listinfo/libav-user