Hello, From one week I am trying to convert MP4 to JPEG going thru different
forums for examples, so far no success. Can you please share the link where you
have seen it working successfully or you had it working on your projects using
the libav shipped with FFMPEG 3.3.2 for windows shared/dev distribution. I am
stuck right now and thumbnail extraction is important for of our project. I
also tried the example that was part of the package, it generates pgm files,
but I cannot convert it to any other viewable image formats. Please help.
/* * Copyright (c) 2001 Fabrice Bellard * * Permission is hereby granted, free
of charge, to any person obtaining a copy * of this software and associated
documentation files (the "Software"), to deal * in the Software without
restriction, including without limitation the rights * to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell * copies of the Software,
and to permit persons to whom the Software is * furnished to do so, subject to
the following conditions: * * The above copyright notice and this permission
notice shall be included in * all copies or substantial portions of the
Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN * THE SOFTWARE. */
/** * @file * video decoding with libavcodec API example * * @example
decode_video.c */
#include <stdio.h>#include <stdlib.h>#include <string.h>
#include <libavcodec/avcodec.h>
#define INBUF_SIZE 4096
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
char *filename){ FILE *f; int i;
f = fopen(filename,"w"); fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize,
255); for (i = 0; i < ysize; i++) fwrite(buf + i * wrap, 1, xsize,
f); fclose(f);}
static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
AVFrame *frame, int *frame_count, AVPacket *pkt, int
last){ int len, got_frame; char buf[1024];
len = avcodec_decode_video2(avctx, frame, &got_frame, pkt); if (len < 0)
{ fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
return len; } if (got_frame) { printf("Saving %sframe %3d\n",
last ? "last " : "", *frame_count); fflush(stdout);
/* the picture is allocated by the decoder, no need to free it */
snprintf(buf, sizeof(buf), "%s-%d", outfilename, *frame_count);
pgm_save(frame->data[0], frame->linesize[0], frame->width,
frame->height, buf); (*frame_count)++; } if (pkt->data) {
pkt->size -= len; pkt->data += len; } return 0;}
int main(int argc, char **argv){ const char *filename, *outfilename;
const AVCodec *codec; AVCodecContext *c= NULL; int frame_count; FILE
*f; AVFrame *frame; uint8_t inbuf[INBUF_SIZE +
AV_INPUT_BUFFER_PADDING_SIZE]; AVPacket avpkt;
if (argc <= 2) { fprintf(stderr, "Usage: %s <input file> <output
file>\n", argv[0]); exit(0); } filename = argv[1];
outfilename = argv[2];
avcodec_register_all();
av_init_packet(&avpkt);
/* set end of buffer to 0 (this ensures that no overreading happens for
damaged MPEG streams) */ memset(inbuf + INBUF_SIZE, 0,
AV_INPUT_BUFFER_PADDING_SIZE);
/* find the MPEG-1 video decoder */ codec =
avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO); if (!codec) {
fprintf(stderr, "Codec not found\n"); exit(1); }
c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr,
"Could not allocate video codec context\n"); exit(1); }
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED) c->flags |=
AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
/* For some codecs, such as msmpeg4 and mpeg4, width and height MUST
be initialized there because this information is not available in the
bitstream. */
/* open it */ if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n"); exit(1); }
f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "Could not
open %s\n", filename); exit(1); }
frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Could
not allocate video frame\n"); exit(1); }
frame_count = 0; for (;;) { avpkt.size = fread(inbuf, 1,
INBUF_SIZE, f); if (avpkt.size == 0) break;
/* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
and this is the only method to use them because you cannot know the
compressed data size before analysing it.
BUT some other codecs (msmpeg4, mpeg4) are inherently frame
based, so you must call them with all the data for one frame
exactly. You must also initialize 'width' and 'height' before
initializing them. */
/* NOTE2: some codecs allow the raw parameters (frame size,
sample rate) to be changed at any frame. We handle this, so you
should also take care of it */
/* here, we use a stream based decoder (mpeg1video), so we
feed decoder and see if it could decode a frame */ avpkt.data = inbuf;
while (avpkt.size > 0) if (decode_write_frame(outfilename, c,
frame, &frame_count, &avpkt, 0) < 0) exit(1); }
/* Some codecs, such as MPEG, transmit the I- and P-frame with a
latency of one frame. You must do the following to have a chance to get
the last frame of the video. */ avpkt.data = NULL; avpkt.size = 0;
decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
fclose(f);
avcodec_free_context(&c); av_frame_free(&frame);
return 0;}
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user