Find attached a fixed version of your program.
The main thing I think was how you were allocating the pFormatCtx.

--
Gonzalo Garramuño
[email protected]

extern "C" {
#include <libavutil/frame.h>
#include <libavutil/imgutils.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
}


#include <iostream>

using namespace std;


static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
{
    /* rescale output packet timestamp values from codec to stream timebase */
    av_packet_rescale_ts(pkt, *time_base, st->time_base);
    pkt->stream_index = st->index;


    /* Write the compressed frame to the media file. */
#ifdef DEBUG_PACKET
    log_packet(fmt_ctx, pkt);
#endif
    return av_interleaved_write_frame(fmt_ctx, pkt);
}
/*
 * Video encoding example
 */
char filename[] = "test.mp4";
int main(int argc, char** argv)
{
    AVCodec *codec = NULL;
    AVCodecContext *c= NULL;
    AVFormatContext *oc = NULL;
    AVStream * pVideoStream = NULL;
    AVFrame *picture = NULL;
    
    int i, x, y,            //
        ret,                 // Return value
        got_packet_ptr;     // Data encoded into packet

    printf("Video encoding\n");
    
    // Register all formats and codecs
    avcodec_register_all();
    av_register_all();

    // allocate context
    // oc = avformat_alloc_context();
    // memcpy(oc->filename,filename,
    //     min(strlen(filename), sizeof(oc->filename)));
    int err = avformat_alloc_output_context2( &oc, NULL, NULL, filename );
    if ( !oc || err < 0 )
    {
        cerr << "Could not allocate output context" << endl;
    }

    oc->flags |= AVFMT_FLAG_NOBUFFER|AVFMT_FLAG_FLUSH_PACKETS;
    oc->max_interleave_delta = 1;

    AVOutputFormat* fmt = oc->oformat;
    fmt->video_codec = AV_CODEC_ID_H264;
   
    // Find the codec.
    codec = avcodec_find_encoder(oc->oformat->video_codec);
    if (codec == NULL) {
        fprintf(stderr, "Codec not found\n");
        return -1;
    }
    
    // Add stream to oc
    pVideoStream = avformat_new_stream(oc, codec);
    if (!pVideoStream) 
    {
        printf("Cannot add new video stream\n");
        return -1;
    }
    
    int framerate = 10;
    pVideoStream->id = oc->nb_streams-1;
    pVideoStream->time_base.den = framerate;
    pVideoStream->time_base.num = 1;

    // Set context
    c = pVideoStream->codec;
    c->pix_fmt = AV_PIX_FMT_YUV420P;
    c->profile = FF_PROFILE_H264_BASELINE; 
    // Resolution must be a multiple of two.
    c->width  = 320;
    c->height = 240;
        
    c->bit_rate = 2000000;
    c->time_base.den = framerate;
    c->time_base.num = 1;
    c->gop_size = 12; // emit one intra frame every twelve frames at most
    
    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
        c->flags |= CODEC_FLAG_GLOBAL_HEADER;

    // Open the codec.    
    if (avcodec_open2(c, codec, NULL) < 0) 
    {
        printf("Cannot open video codec\n");
        return -1;
    }

    
    if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) 
    {
        printf("Cannot open file\n");
        return -1;
    }
    
    // Write file header.
    err = avformat_write_header(oc, NULL);
    if ( err < 0 )
    {
        cerr << "error writing header" << endl;
        return -1;
    }
    
    // Create frame
    picture= av_frame_alloc();
    if ( !picture )
    {
        cerr << "Could not allocate picture" << endl;
        return -1;
    }

    picture->format = c->pix_fmt;
    picture->width  = c->width;
    picture->height = c->height;

    int bufferImgSize = av_image_get_buffer_size(c->pix_fmt, c->width,
                                                 c->height,1);    
    av_image_alloc(picture->data, picture->linesize, c->width, c->height,                 c->pix_fmt, 32);

    AVPacket avpkt;

    /* encode 1 second of video */
    for(i=0;i<50;i++) 
    {
        /* prepare a dummy image */
        /* Y */
        for(y=0;y<c->height;y++)
        {
            for(x=0;x<c->width;x++) 
            {
                picture->data[0][y * picture->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++) 
            {
                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
            }
        }

        // Get timestamp
        // picture->pts = (float) i * (1000.0/(float)(c->time_base.den)) * 90;
        picture->pts = i;

        // Encode frame to packet
        av_init_packet(&avpkt);
        got_packet_ptr = 0;
        int error = avcodec_encode_video2(c, &avpkt, picture, &got_packet_ptr);
        if (!error && got_packet_ptr > 0) 
        {
            // Write packet with frame.
            ret = write_frame( oc, &c->time_base, pVideoStream,
                               &avpkt );       
        }    
        av_packet_unref(&avpkt); 
    }

    // Flush remaining encoded data
    while(1)
    {
        av_init_packet(&avpkt);
        got_packet_ptr = 0;
        // Encode frame to packet.
        int error = avcodec_encode_video2(c, &avpkt, NULL, &got_packet_ptr);
        if (!error && got_packet_ptr > 0) 
        {
            // Write packet with frame.
            ret = write_frame( oc, &c->time_base, pVideoStream,
                               &avpkt );
        } 
        else 
        {
            break;
        }
        av_packet_unref(&avpkt); 
    }
    av_write_trailer(oc);
    
    av_packet_unref(&avpkt);

    avcodec_close( pVideoStream->codec );

    av_frame_free(&picture);

    avio_close( oc->pb );

    avformat_free_context( oc );

    return 0;
}
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to