[Libav-user] Encoding and writing to a file with libavformat and libavcodec
Shawn Van Every
savanevery at gmail.com
Sat Dec 29 10:16:23 CET 2012
Hi all,
Just getting started with the libraries and in need of a bit of help.
I have been building up a sample based off of the decoding_encoding example
along with some sample code using AVFormat.
Right now, I am running into issues which I am having a hard time finding
the cause of. Here is the error along with the backtrace:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000090
0x00000001000870b5 in ff_mov_write_packet ()
(gdb) bt
#0 0x00000001000870b5 in ff_mov_write_packet ()
#1 0x00007fff8e58cb28 in szone_malloc_should_clear ()
#2 0x00007fff8e57f71a in malloc_zone_memalign ()
#3 0x00007fff8e57ff4e in posix_memalign ()
#4 0x000000010000f9b5 in av_strdup ()
Full source is below.
Thanks for any help.
Best,
shawn
--
#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 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);
}
avOutputFormat->video_codec = codec_id;
/// 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);
}
//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);
}
// 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) {
/* 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);
}
av_free_packet(&pkt);
} else {
printf("got_output false: %d", i);
}
}
/* 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/b89f6bee/attachment.html>
More information about the Libav-user
mailing list