[Libav-user] Encoding and writing to a file with libavformat and libavcodec

Shawn Van Every savanevery at gmail.com
Sat Dec 29 20:29:44 CET 2012


On Sat, Dec 29, 2012 at 10:50 AM, Shawn Van Every <savanevery at gmail.com>wrote:

>
> Program received signal EXC_BAD_ACCESS, Could not access memory.
> Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000090
> 0x0000000100090095 in mov_write_header (s=0x7fff5fbff410) at movenc.c:3499
> 3499    if (!s->pb->seekable &&
>
>  It looks like I either haven't instantiated AVFormatContext (s in
> movenc.c:3499) or AVIOContext (s->pb in movenc.c 3499) correctly.
>  Unfortunately, I haven't seen AVIOContext used in any of the examples.
>
> Thanks
>

Ahh..  I missed actually opening the output file.  Doing the following
fixes that error:

    /* open the output file, if needed */
    if (!(avOutputFormat->flags & AVFMT_NOFILE)) {
        if (avio_open(&avFormatContext->pb, outputfile, AVIO_FLAG_WRITE) <
0) {
            fprintf(stderr, "Could not open '%s'\n", outputfile);
            return 1;
        }
    }

Now I have this:

mine(1228,0x7fff70ca4180) malloc: *** error for object 0x10180f800: pointer
being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

Program received signal SIGABRT, Aborted.
0x00007fff83cab212 in __pthread_kill ()
(gdb) bt
#0  0x00007fff83cab212 in __pthread_kill ()
#1  0x00007fff8332bb34 in pthread_kill ()
#2  0x00007fff8336fdfa in abort ()
#3  0x00007fff83343989 in free ()
#4  0x000000010000f6dc in av_freep (arg=0x101111628) at mem.c:185
#5  0x00007fff855ba7e1 in start ()

Here is the updated full code if anyone feels like having a look:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/avutil.h>

#undef exit

#define STREAM_DURATION   5.0 /* 5 seconds stream duration */
#define STREAM_FRAME_RATE 25 /* 25 images/s */
#define STREAM_NB_FRAMES  ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
#define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */

static int sws_flags = SWS_BICUBIC;

int main(int argc, char **argv)
{
    // Output file
    const char *outputfile;

    // Struct to hold the output format details, audio codec, video codec,
extension
    // http://ffmpeg.org/doxygen/trunk/structAVOutputFormat.html
    AVOutputFormat *avOutputFormat; // Was *fmt

    // http://ffmpeg.org/doxygen/trunk/structAVFormatContext.html
    AVFormatContext *avFormatContext; // was *oc

    // Individual AVStreams for audio and video
    // http://ffmpeg.org/doxygen/trunk/structAVStream.html
    AVStream *video_avstream; // was *video_st and *st

// Audio and Video Timestamps (presentation time stamp)
    double audio_pts, video_pts;

///////////////////

int codec_id = AV_CODEC_ID_H264;
    AVCodec *codec;
    AVCodecContext *c= NULL;
    int i, ret, x, y, got_output;
    int write_ret;
    //FILE *f;
    AVFrame *frame;
    AVPacket pkt;
    //uint8_t endcode[] = { 0, 0, 1, 0xb7 };

    printf("Encode video file\n");

    /* register all the codecs */
    //avcodec_register_all();

///////
// Intialize libavcodec - register all codecs and formats??????????
    av_register_all();

// Set inpput filename and output filename
    outputfile = "outtestmov.mp4";

    // auto detect the output format from the name. default is mpeg.
    avOutputFormat = av_guess_format(NULL, outputfile, NULL);
    if (!avOutputFormat) {
        printf("Could not deduce output format from file extension: using
MPEG.\n");
        avOutputFormat = av_guess_format("mpeg", NULL, NULL);
    }
    if (!avOutputFormat) {
        fprintf(stderr, "Could not find suitable output format\n");
        exit(1);
    }

    fprintf(stdout,"Format Name: %s\n",avOutputFormat->name);
    fprintf(stdout,"Format Video Codec: %d\n",avOutputFormat->video_codec);
    avOutputFormat->video_codec = codec_id;
    fprintf(stdout,"Format Video Codec: %d\n",avOutputFormat->video_codec);

    /// allocate the output media context, avFormatContext
    avFormatContext = avformat_alloc_context();
    if (!avFormatContext) {
        fprintf(stderr, "Memory error\n");
        exit(1);
    }
    // Set the output format of the newly allocated avFormatContext to our
avOutputFormat
    avFormatContext->oformat = avOutputFormat;

    // Set the output filename to the outputfile
    snprintf(avFormatContext->filename, sizeof(avFormatContext->filename),
"%s", outputfile);

    /* find the mpeg1 video encoder */
    //codec = avcodec_find_encoder(codec_id);
    codec = avcodec_find_encoder(avOutputFormat->video_codec);
    if (!codec) {
        fprintf(stderr, "Codec not found\n");
        exit(1);
    }

    // add the video stream using the default format codec and initialize
the codecs
    video_avstream = avformat_new_stream(avFormatContext, codec);
    if (!video_avstream) {
        fprintf(stderr, "Could not alloc stream\n");
        exit(1);
    }

    if (video_avstream->codec == NULL) {
    fprintf(stderr, "AVStream codec is NULL\n");
    exit(1);
    }

    //c = avcodec_alloc_context3(codec);
    c = video_avstream->codec;
    //c->codec_id = avOutputFormat->video_codec;
    if (!c) {
        fprintf(stderr, "Could not allocate video codec context\n");
        exit(1);
    }

    /* put sample parameters */
    c->bit_rate = 400000;
    /* resolution must be a multiple of two */
    c->width = 352;
    c->height = 288;
    /* frames per second */
    c->time_base= (AVRational){1,25};
    c->gop_size = 10; /* emit one intra frame every ten frames */
    c->max_b_frames=1;
    c->pix_fmt = AV_PIX_FMT_YUV420P;

    if(codec_id == AV_CODEC_ID_H264)
        av_opt_set(c->priv_data, "preset", "slow", 0);

    /* open it */
    if (avcodec_open2(c, codec, NULL) < 0) {
        fprintf(stderr, "Could not open codec\n");
        exit(1);
    }

/*
    f = fopen(filename, "wb");
    if (!f) {
        fprintf(stderr, "Could not open %s\n", filename);
        exit(1);
    }
*/
 //video_avstream->codec = c;

//////////////////////////////////
    frame = avcodec_alloc_frame();
    if (!frame) {
        fprintf(stderr, "Could not allocate video frame\n");
        exit(1);
    }
    frame->format = c->pix_fmt;
    frame->width  = c->width;
    frame->height = c->height;

    /* the image can be allocated by any means and av_image_alloc() is
     * just the most convenient way if av_malloc() is to be used */
    ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
                         c->pix_fmt, 32);
    if (ret < 0) {
        fprintf(stderr, "Could not allocate raw picture buffer\n");
        exit(1);
    }

    /* open the output file, if needed */
    if (!(avOutputFormat->flags & AVFMT_NOFILE)) {
        if (avio_open(&avFormatContext->pb, outputfile, AVIO_FLAG_WRITE) <
0) {
            fprintf(stderr, "Could not open '%s'\n", outputfile);
            return 1;
        }
    }

    // some formats want stream headers to be separate
    if(avFormatContext->oformat->flags & AVFMT_GLOBALHEADER)
        c->flags |= CODEC_FLAG_GLOBAL_HEADER;

avformat_write_header(avFormatContext, NULL);

    /* encode 1 second of video */
    for(i=0;i<25;i++) {
        av_init_packet(&pkt);
        pkt.data = NULL;    // packet data will be allocated by the encoder
        pkt.size = 0;

        fflush(stdout);
        /* prepare a dummy image */
        /* Y */
        for(y=0;y<c->height;y++) {
            for(x=0;x<c->width;x++) {
                frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
            }
        }

        /* Cb and Cr */
        for(y=0;y<c->height/2;y++) {
            for(x=0;x<c->width/2;x++) {
                frame->data[1][y * frame->linesize[1] + x] = 128 + y + i *
2;
                frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
            }
        }

frame->pts = i;

        /* encode the image */
        ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
        if (ret < 0) {
            fprintf(stderr, "Error encoding frame\n");
            exit(1);
        }

        if (got_output) {

        /*
            if (c->coded_frame->pts != AV_NOPTS_VALUE) {
                pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base,
video_avstream->time_base);
            } else {
            printf("pkt.pts AV_NOPTS_VALUE");
            }

            pkt.pts = i;


        printf("pkt.pts:%5d\n",pkt.pts);

            printf("Write frame %3d (size=%5d)\n", i, pkt.size);
            */

            /* write the compressed frame in the media file */
            write_ret = av_write_frame(avFormatContext, &pkt);
            if (write_ret < 0) {
            fprintf(stderr, "Error writing frame\n");
            exit(1);
            }

//            fwrite(pkt.data, 1, pkt.size, f);
            av_free_packet(&pkt);
        } else {
        printf("got_output false: %d", i);
        }
    }

    /* get the delayed frames */
/*
    for (got_output = 1; got_output; i++) {
        fflush(stdout);

ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
        if (ret < 0) {
            fprintf(stderr, "Error encoding frame\n");
            exit(1);
        }

        if (got_output) {
            printf("Write frame %3d (size=%5d)\n", i, pkt.size);
//            fwrite(pkt.data, 1, pkt.size, f);

            // write the compressed frame in the media file
// ret = av_interleaved_write_frame(avFormatContext, &pkt);

            av_free_packet(&pkt);
        }
    }
*/

    /* add sequence end code to have a real mpeg file */
    //fwrite(endcode, 1, sizeof(endcode), f);
    //fclose(f);

    /* write the trailer, if any.  the trailer must be written
     * before you close the CodecContexts open when you wrote the
     * header; otherwise write_trailer may try to use memory that
     * was freed on av_codec_close() */
    //av_write_trailer(avFormatContext);

    avcodec_close(c);
    av_free(c);
    av_freep(&frame->data[0]);
    avcodec_free_frame(&frame);


    /* free the streams */
    for(i = 0; i < avFormatContext->nb_streams; i++) {
        av_freep(&avFormatContext->streams[i]->codec);
        av_freep(&avFormatContext->streams[i]);
    }

    if (!(avOutputFormat->flags & AVFMT_NOFILE)) {
        /* close the output file */
        avio_close(avFormatContext->pb);
    }

    /* free the stream */
    av_free(avFormatContext);

    printf("\n");
    return 0;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20121229/960d455e/attachment.html>


More information about the Libav-user mailing list