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