Note that there are some explanatory texts on larger screens.

plurals
  1. POFFmpeg: avcodec_encode_video() and JPEG images
    primarykey
    data
    text
    <p>I'm trying to encode a series of .jpg files into a video using the ffmpeg library, and I can't seem to get the frames to encode. (I have to use the ffmpeg library, and using ffmpeg from a command line is not an option in my case.)</p> <p>Except for the part where I'm trying to open JPG files as AVFrames, my code is more or less the same thing as found in api-example.c from the ffmpeg library. When I populate the frames as the example does, everything works as expected. In the code below, I fail to encode any frames. Obviously the trouble is related to how I'm opening the JPG files, but I can't figure out what.</p> <p>I'm opening the image like this:</p> <pre><code>AVFrame* open_image(const char* imageFileName, int width, int height, long * bufSize) { AVFormatContext *pFormatCtx; if(av_open_input_file(&amp;pFormatCtx, imageFileName, NULL, 0, NULL)!=0) { printf("Can't open image file '%s'\n", imageFileName); return NULL; } AVCodecContext *pCodecCtx; pCodecCtx = pFormatCtx-&gt;streams[0]-&gt;codec; pCodecCtx-&gt;width = width; pCodecCtx-&gt;height = height; pCodecCtx-&gt;pix_fmt = PIX_FMT_YUV420P; // Find the decoder for the video stream AVCodec *pCodec = avcodec_find_decoder(pCodecCtx-&gt;codec_id); if (!pCodec) { printf("Codec not found\n"); return NULL; } // Open codec if(avcodec_open(pCodecCtx, pCodec)&lt;0) { printf("Could not open codec\n"); return NULL; } AVFrame *pFrame = avcodec_alloc_frame(); if (!pFrame) { LOGV(TAG, "Can't allocate memory for AVFrame\n"); return NULL; } int frameFinished; int numBytes; // Determine required buffer size and allocate buffer numBytes = avpicture_get_size(PIX_FMT_YUVJ420P, pCodecCtx-&gt;width, pCodecCtx-&gt;height); // *** *bufSize = numBytes; // *** uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t)); avpicture_fill((AVPicture *) pFrame, buffer, PIX_FMT_YUVJ420P, pCodecCtx-&gt;width, pCodecCtx-&gt;height); // Read frame AVPacket packet; int framesNumber = 0; while (av_read_frame(pFormatCtx, &amp;packet) &gt;= 0) { if(packet.stream_index != 0) continue; int ret = avcodec_decode_video2(pCodecCtx, pFrame, &amp;frameFinished, &amp;packet); if (ret &gt; 0) { sprintf(buf, "Frame is decoded, size %d", ret); LOGV(TAG, buf); pFrame-&gt;quality = 4; return pFrame; } else { // printf("Error [%d] while decoding frame: %s\n", ret, strerror(AVERROR(ret))); sprintf(buf, "Error %d decoding frame: %s", ret, strerror(AVERROR(ret))); LOGV(TAG, buf); } } } </code></pre> <p>...and attempting to encode them like this:</p> <pre><code>DIR * dir = opendir(path); int i = 0; if (dir != NULL) { for(struct dirent *ent = readdir(dir); ent != NULL; ent = readdir(dir)) { fflush(stdout); printf("%s/%s", path, ent-&gt;d_name); LOGV(TAG, filename); // If not a jpg file, pass it over const char * ext = strrchr(filename, '.'); if((!ext) || (strcmp(ext, ".jpg"))) { continue; } /*** NOTE: Is this where I've gone wrong? Bufsize is set in open_image based on av_picture_size() */ long bufSize = 0L; AVFrame * frame = open_image(filename, width, height, &amp;bufSize); if(frame) { // This is what it needs to do, and it does not work. // Causes: // Wrong format? // Wrong buffer size? uint8_t * picBuf = (uint8_t *)malloc(bufSize); out_size = avcodec_encode_video(c, picBuf, bufSize, frame); printf("encoding frame %3d (size=%5d)\n", i++, out_size); /** On the first image, out_size is 0. On the next, it's -1, and fails. */ if(out_size &lt; 0) { printf("Error encoding frame"); return -6; } fwrite(picBuf, 1, bufSize, f); free(picBuf); av_free(frame); } else { printf("Couldn't open image"); return -5; } } closedir(dir); } else { printf("Couldn't open directory %s\n", path); return -4; } </code></pre> <p>Could someone point me in the right direction? </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload