[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