<html>
<head>
<meta content="text/html; charset=KOI8-R" http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">06.06.2013 7:53, áÎÄÒÅÊ ÐÉÛÅÔ:<br>
</div>
<blockquote cite="mid:51B007C9.7060009@gosniias.ru" type="cite">05.06.2013
14:39, Andrey Utkin ÐÉÛÅÔ:
<br>
<blockquote type="cite">2013/6/5 áÎÄÒÅÊ
<a class="moz-txt-link-rfc2396E" href="mailto:ashvyrkin@gosniias.ru"><ashvyrkin@gosniias.ru></a>:
<br>
<blockquote type="cite">I use to compile the 32-bit version of
ffmpeg visual studio 2012. I used the
<br>
latter for now build from 5/29/13.
<br>
This is my test code that reproduces the problem:
<br>
<br>
avcodec_register_all();
<br>
<br>
šššš int width = 764, height = 480;
<br>
šššš int got_output;
<br>
šššš AVFrame *frame;
<br>
šššš AVPacket pkt;
<br>
šššš AVCodec *codec;
<br>
šššš AVCodecContext *c = NULL;
<br>
<br>
šššš while(1)
<br>
šššš {
<br>
šššššššš frame = avcodec_alloc_frame();
<br>
šššššššš if (!frame) {
<br>
šššššššššššš fprintf(stderr, "Could not allocate video
frame\n");
<br>
šššššššššššš return -1;
<br>
šššššššš }
<br>
šššššššš frame->format = AV_PIX_FMT_YUV420P;
<br>
šššššššš frame->widthš = width;
<br>
šššššššš frame->height = height;
<br>
<br>
šššššššš /* the image can be allocated by any means and
av_image_alloc() is
<br>
ššššššššš * just the most convenient way if av_malloc() is to
be used */
<br>
šššššššš int ret = av_image_alloc(frame->data,
frame->linesize, width,
<br>
height,
<br>
ššššššššššššššššššššššššššššš AV_PIX_FMT_YUV420P, 1);
<br>
šššššššš if (ret < 0) {
<br>
šššššššššššš fprintf(stderr, "Could not allocate raw picture
buffer\n");
<br>
šššššššššššš av_freep(&frame->data[0]);
<br>
šššššššššššš avcodec_free_frame(&frame);
<br>
šššššššššššš return -1;
<br>
šššššššš }
<br>
<br>
šššššššš /* find the mpeg4 video encoder */
<br>
šššššššš codec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
<br>
šššššššš if (!codec) {
<br>
šššššššššššš fprintf(stderr, "Codec not found\n");
<br>
šššššššššššš return -1;
<br>
šššššššš }
<br>
<br>
šššššššš c = avcodec_alloc_context3(codec);
<br>
šššššššš if (!c) {
<br>
šššššššššššš fprintf(stderr, "Could not allocate video codec
context\n");
<br>
šššššššššššš return -1;
<br>
šššššššš }
<br>
<br>
šššššššš /* put sample parameters */
<br>
šššššššš c->profile = FF_PROFILE_MPEG4_SIMPLE;
<br>
šššššššš /* resolution must be a multiple of two */
<br>
šššššššš c->width = width;
<br>
šššššššš c->height = height;
<br>
šššššššš /* frames per second */
<br>
šššššššš c->time_base.den = 25;
<br>
šššššššš c->time_base.num = 1;
<br>
šššššššš c->gop_size = 25; /* emit one intra frame every 25
frames */
<br>
šššššššš c->pix_fmt = AV_PIX_FMT_YUV420P;
<br>
šššššššš c->qmax = 4;
<br>
šššššššš c->qmin = 4;
<br>
<br>
šššššššš /* open it */
<br>
šššššššš if (avcodec_open2(c, codec, NULL) < 0) {
<br>
šššššššššššš fprintf(stderr, "Could not open codec\n");
<br>
šššššššššššš avcodec_close(c);
<br>
</blockquote>
You shouldn't avcodec_close() here. I think this can cause a
problem.
<br>
<br>
<blockquote type="cite">šššššššššššš av_free(c);
<br>
šššššššššššš return -1;
<br>
šššššššš }
<br>
<br>
šššššššš for(int k = 0; k < 30; k++)
<br>
šššššššš {
<br>
šššššššššššš av_init_packet(&pkt);
<br>
šššššššššššš pkt.data = NULL;ššš // packet data will be
allocated by the
<br>
encoder
<br>
šššššššššššš pkt.size = 0;
<br>
<br>
šššššššššššš frame->pts = c->frame_number;
<br>
<br>
šššššššššššš /* encode the image */
<br>
šššššššššššš if (avcodec_encode_video2(c, &pkt, frame,
&got_output) < 0) {
<br>
šššššššššššššššš fprintf(stderr, "Error encoding frame\n");
<br>
šššššššššššššššš return -1;
<br>
šššššššššššš }
<br>
<br>
šššššššššššš if (got_output) {
<br>
šššššššššššššššš av_free_packet(&pkt);
<br>
šššššššššššš }
<br>
šššššššš }
<br>
<br>
šššššššš if(c)
<br>
šššššššš {
<br>
šššššššššššš avcodec_close(c);
<br>
šššššššššššš av_free(c);
<br>
</blockquote>
Can't say for sure, but av_free() seems redundant.
<br>
<br>
<blockquote type="cite">šššššššš }
<br>
šššššššš if(frame)
<br>
šššššššš {
<br>
šššššššššššš av_freep(&frame->data[0]);
<br>
šššššššššššš avcodec_free_frame(&frame);
<br>
</blockquote>
Maybe there also something is redundant.
<br>
<br>
<blockquote type="cite">šššššššš }
<br>
šššš }
<br>
<br>
When you call function avcodec_close () throws an exception.
Such an error
<br>
is detected on the MPEG4 codec with a frame width in the range
754-767 at an
<br>
altitude of 480. Perhaps at other resolutions, too. Help solve
the problem.
<br>
...sorry for bad english
<br>
</blockquote>
You have more than one call to avcodec_close(), do you know,
which one
<br>
is executed?
<br>
<br>
Your code snippet should be easily compiled on linux, there you
can
<br>
use valgrind memcheck tool, which makes debugging easy.
<br>
Also i suggest you to re-read avcodec.h and avformat.h for
<br>
explanations on how to release context objects correclty, some
places
<br>
in your code are suspicious for me.
<br>
<br>
--
<br>
Andrey Utkin
<br>
_______________________________________________
<br>
Libav-user mailing list
<br>
<a class="moz-txt-link-abbreviated" href="mailto:Libav-user@ffmpeg.org">Libav-user@ffmpeg.org</a>
<br>
<a class="moz-txt-link-freetext" href="http://ffmpeg.org/mailman/listinfo/libav-user">http://ffmpeg.org/mailman/listinfo/libav-user</a>
<br>
</blockquote>
Ok, for now I'm using video_encode_example from
decoding_encoding.c example:
<br>
<br>
AVCodec *codec;
<br>
ššš AVCodecContext *c = NULL;
<br>
ššš int i, ret, x, y, got_output;
<br>
ššš AVFrame *frame;
<br>
ššš AVPacket pkt;
<br>
<br>
ššš /* register all the codecs */
<br>
ššš avcodec_register_all();
<br>
<br>
ššš /* find the mpeg1 video encoder */
<br>
ššš codec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
<br>
ššš if (!codec) {
<br>
ššššššš fprintf(stderr, "Codec not found\n");
<br>
ššššššš exit(1);
<br>
ššš }
<br>
<br>
ššš c = avcodec_alloc_context3(codec);
<br>
ššš if (!c) {
<br>
ššššššš fprintf(stderr, "Could not allocate video codec
context\n");
<br>
ššššššš exit(1);
<br>
ššš }
<br>
<br>
ššš /* put sample parameters */
<br>
ššš c->bit_rate = 400000;
<br>
ššš /* resolution must be a multiple of two */
<br>
ššš c->width = 764;
<br>
ššš c->height = 480;
<br>
ššš /* frames per second */
<br>
ššš c->time_base.den = 25;
<br>
ššš c->time_base.num = 1;
<br>
ššš c->gop_size = 10; /* emit one intra frame every ten frames
*/
<br>
ššš c->max_b_frames = 1;
<br>
ššš c->pix_fmt = AV_PIX_FMT_YUV420P;
<br>
<br>
ššš /* open it */
<br>
ššš if (avcodec_open2(c, codec, NULL) < 0) {
<br>
ššššššš fprintf(stderr, "Could not open codec\n");
<br>
ššššššš exit(1);
<br>
ššš }
<br>
<br>
ššš frame = avcodec_alloc_frame();
<br>
ššš if (!frame) {
<br>
ššššššš fprintf(stderr, "Could not allocate video frame\n");
<br>
ššššššš exit(1);
<br>
ššš }
<br>
ššš frame->format = c->pix_fmt;
<br>
ššš frame->widthš = c->width;
<br>
ššš frame->height = c->height;
<br>
<br>
ššš /* the image can be allocated by any means and
av_image_alloc() is
<br>
šššš * just the most convenient way if av_malloc() is to be used
*/
<br>
ššš ret = av_image_alloc(frame->data, frame->linesize,
c->width, c->height,
<br>
šššššššššššššššššššššššš c->pix_fmt, 32);
<br>
ššš if (ret < 0) {
<br>
ššššššš fprintf(stderr, "Could not allocate raw picture
buffer\n");
<br>
ššššššš exit(1);
<br>
ššš }
<br>
<br>
ššš /* encode 1 second of video */
<br>
ššš for(i=0;i<25;i++) {
<br>
ššššššš av_init_packet(&pkt);
<br>
ššššššš pkt.data = NULL;ššš // packet data will be allocated by
the encoder
<br>
ššššššš pkt.size = 0;
<br>
<br>
ššššššš fflush(stdout);
<br>
ššššššš /* prepare a dummy image */
<br>
ššššššš /* Y */
<br>
ššššššš for(y=0;y<c->height;y++) {
<br>
ššššššššššš for(x=0;x<c->width;x++) {
<br>
ššššššššššššššš frame->data[0][y * frame->linesize[0] + x] =
x + y + i * 3;
<br>
ššššššššššš }
<br>
ššššššš }
<br>
<br>
ššššššš /* Cb and Cr */
<br>
ššššššš for(y=0;y<c->height/2;y++) {
<br>
ššššššššššš for(x=0;x<c->width/2;x++) {
<br>
ššššššššššššššš frame->data[1][y * frame->linesize[1] + x] =
128 + y + i * 2;
<br>
ššššššššššššššš frame->data[2][y * frame->linesize[2] + x] =
64 + x + i * 5;
<br>
ššššššššššš }
<br>
ššššššš }
<br>
<br>
ššššššš frame->pts = i;
<br>
<br>
ššššššš /* encode the image */
<br>
ššššššš ret = avcodec_encode_video2(c, &pkt, frame,
&got_output);
<br>
ššššššš if (ret < 0) {
<br>
ššššššššššš fprintf(stderr, "Error encoding frame\n");
<br>
ššššššššššš exit(1);
<br>
ššššššš }
<br>
<br>
ššššššš if (got_output) {
<br>
ššššššššššš av_free_packet(&pkt);
<br>
ššššššš }
<br>
ššš }
<br>
<br>
ššš avcodec_close(c);
<br>
ššš av_free(c);
<br>
ššš av_freep(&frame->data[0]);
<br>
ššš avcodec_free_frame(&frame);
<br>
<br>
The problem is that the context is not released correctly when the
resolution is 764x480 and some other resolutions. If you use a
different codec instead of MPEG4, such as H264, no error occurs if
any resolution. I use the assembly under windows and unfortunately
I do not have the possibility to compile the example under Linux
to pinpoint the cause of the fall.
<br>
</blockquote>
<b><big><big><big><big><big><span style="color: rgb(51, 51, 51);
font-family: 'Lucida Grande', 'Trebuchet MS', Verdana,
Helvetica, Arial, sans-serif; font-size: 13px;
font-style: normal; font-variant: normal; font-weight:
normal; letter-spacing: normal; line-height:
18.1875px; orphans: auto; text-align: start;
text-indent: 0px; text-transform: none; white-space:
normal; widows: auto; word-spacing: 0px;
-webkit-text-stroke-width: 0px; background-color:
rgb(236, 243, 247); display: inline !important; float:
none;">In the latest build of 14.06.13 the problem is
solved.</span></big></big></big></big></big></b>
</body>
</html>