Merge commit 'abb5e37f64c48bba8bd0fde2bada0f7544defa24'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 10 Jan 2014 02:46:28 +0000 (03:46 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 10 Jan 2014 02:46:28 +0000 (03:46 +0100)
* commit 'abb5e37f64c48bba8bd0fde2bada0f7544defa24':
  avfilter: fix leaks on error in ff_filter_frame

Conflicts:
libavfilter/avfilter.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavfilter/avfilter.c

@@@ -1050,106 -782,14 +1057,111 @@@ static int ff_filter_frame_framed(AVFil
      } else
          out = frame;
  
 -    return filter_frame(link, out);
 +    while(cmd && cmd->time <= out->pts * av_q2d(link->time_base)){
 +        av_log(link->dst, AV_LOG_DEBUG,
 +               "Processing command time:%f command:%s arg:%s\n",
 +               cmd->time, cmd->command, cmd->arg);
 +        avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
 +        ff_command_queue_pop(link->dst);
 +        cmd= link->dst->command_queue;
 +    }
 +
 +    pts = out->pts;
 +    if (dstctx->enable_str) {
 +        int64_t pos = av_frame_get_pkt_pos(out);
 +        dstctx->var_values[VAR_N] = link->frame_count;
 +        dstctx->var_values[VAR_T] = pts == AV_NOPTS_VALUE ? NAN : pts * av_q2d(link->time_base);
 +        dstctx->var_values[VAR_POS] = pos == -1 ? NAN : pos;
 +
 +        dstctx->is_disabled = fabs(av_expr_eval(dstctx->enable, dstctx->var_values, NULL)) < 0.5;
 +        if (dstctx->is_disabled &&
 +            (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC))
 +            filter_frame = default_filter_frame;
 +    }
 +    ret = filter_frame(link, out);
 +    link->frame_count++;
 +    link->frame_requested = 0;
 +    ff_update_link_current_pts(link, pts);
 +    return ret;
+ fail:
+     av_frame_free(&out);
+     av_frame_free(&frame);
+     return ret;
  }
  
 +static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFrame *frame)
 +{
 +    int insamples = frame->nb_samples, inpos = 0, nb_samples;
 +    AVFrame *pbuf = link->partial_buf;
 +    int nb_channels = av_frame_get_channels(frame);
 +    int ret = 0;
 +
 +    link->flags |= FF_LINK_FLAG_REQUEST_LOOP;
 +    /* Handle framing (min_samples, max_samples) */
 +    while (insamples) {
 +        if (!pbuf) {
 +            AVRational samples_tb = { 1, link->sample_rate };
 +            pbuf = ff_get_audio_buffer(link, link->partial_buf_size);
 +            if (!pbuf) {
 +                av_log(link->dst, AV_LOG_WARNING,
 +                       "Samples dropped due to memory allocation failure.\n");
 +                return 0;
 +            }
 +            av_frame_copy_props(pbuf, frame);
 +            pbuf->pts = frame->pts;
 +            if (pbuf->pts != AV_NOPTS_VALUE)
 +                pbuf->pts += av_rescale_q(inpos, samples_tb, link->time_base);
 +            pbuf->nb_samples = 0;
 +        }
 +        nb_samples = FFMIN(insamples,
 +                           link->partial_buf_size - pbuf->nb_samples);
 +        av_samples_copy(pbuf->extended_data, frame->extended_data,
 +                        pbuf->nb_samples, inpos,
 +                        nb_samples, nb_channels, link->format);
 +        inpos                   += nb_samples;
 +        insamples               -= nb_samples;
 +        pbuf->nb_samples += nb_samples;
 +        if (pbuf->nb_samples >= link->min_samples) {
 +            ret = ff_filter_frame_framed(link, pbuf);
 +            pbuf = NULL;
 +        }
 +    }
 +    av_frame_free(&frame);
 +    link->partial_buf = pbuf;
 +    return ret;
 +}
 +
 +int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
 +{
 +    FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1);
 +
 +    /* Consistency checks */
 +    if (link->type == AVMEDIA_TYPE_VIDEO) {
 +        if (strcmp(link->dst->filter->name, "scale")) {
 +            av_assert1(frame->format                 == link->format);
 +            av_assert1(frame->width               == link->w);
 +            av_assert1(frame->height               == link->h);
 +        }
 +    } else {
 +        av_assert1(frame->format                == link->format);
 +        av_assert1(av_frame_get_channels(frame) == link->channels);
 +        av_assert1(frame->channel_layout        == link->channel_layout);
 +        av_assert1(frame->sample_rate           == link->sample_rate);
 +    }
 +
 +    /* Go directly to actual filtering if possible */
 +    if (link->type == AVMEDIA_TYPE_AUDIO &&
 +        link->min_samples &&
 +        (link->partial_buf ||
 +         frame->nb_samples < link->min_samples ||
 +         frame->nb_samples > link->max_samples)) {
 +        return ff_filter_frame_needs_framing(link, frame);
 +    } else {
 +        return ff_filter_frame_framed(link, frame);
 +    }
 +}
 +
  const AVClass *avfilter_get_class(void)
  {
      return &avfilter_class;