History

lavfi: implement ff_inlink_make_frame_writable().

Unlike av_frame_is_writable(), it uses the link's alloc callback, making direct rendering possible. The code comes from ff_filter_frame_framed(), moved with mostly trivial changes.

Nicolas George committed 9 years ago

Commit 28c62df1 parent 918891e2 files · +60 −41Browse files

Unified · Split

2 files
  1. libavfilter/avfilter.c +53 −41
  2. libavfilter/filters.h +7 −0
libavfilter/avfilter.c+53−41
@@ -1107,49 +1107,12 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) · 1106 unmodified lines
11071107 if (!(filter_frame = dst->filter_frame))
11081108 filter_frame = default_filter_frame;
11091109
1110− /* copy the frame if needed */
1111− if (dst->needs_writable && !av_frame_is_writable(frame)) {
1112− av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
1113−
1114− switch (link->type) {
1115− case AVMEDIA_TYPE_VIDEO:
1116− out = ff_get_video_buffer(link, link->w, link->h);
1117− break;
1118− case AVMEDIA_TYPE_AUDIO:
1119− out = ff_get_audio_buffer(link, frame->nb_samples);
1120− break;
1121− default:
1122− ret = AVERROR(EINVAL);
1123− goto fail;
1124− }
1125− if (!out) {
1126− ret = AVERROR(ENOMEM);
1127− goto fail;
1128− }
1129−
1130− ret = av_frame_copy_props(out, frame);
1110+ if (dst->needs_writable) {
1111+ ret = ff_inlink_make_frame_writable(link, &frame);
11311112 if (ret < 0)
11321113 goto fail;
1133−
1134− switch (link->type) {
1135− case AVMEDIA_TYPE_VIDEO:
1136− av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize,
1137− frame->format, frame->width, frame->height);
1138− break;
1139− case AVMEDIA_TYPE_AUDIO:
1140− av_samples_copy(out->extended_data, frame->extended_data,
1141− 0, 0, frame->nb_samples,
1142− av_frame_get_channels(frame),
1143− frame->format);
1144− break;
1145− default:
1146− ret = AVERROR(EINVAL);
1147− goto fail;
1148− }
1149−
1150− av_frame_free(&frame);
1151− } else
1152− out = frame;
1114+ }
1115+ out = frame; /* TODO rename */
11531116
11541117 while(cmd && cmd->time <= out->pts * av_q2d(link->time_base)){
11551118 av_log(link->dst, AV_LOG_DEBUG,
@@ -1559,6 +1522,55 @@ int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts · 403 unmodified lines
15591522 return 1;
15601523 }
15611524
1525+int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
1526+{
1527+ AVFrame *frame = *rframe;
1528+ AVFrame *out;
1529+ int ret;
1530+
1531+ if (av_frame_is_writable(frame))
1532+ return 0;
1533+ av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
1534+
1535+ switch (link->type) {
1536+ case AVMEDIA_TYPE_VIDEO:
1537+ out = ff_get_video_buffer(link, link->w, link->h);
1538+ break;
1539+ case AVMEDIA_TYPE_AUDIO:
1540+ out = ff_get_audio_buffer(link, frame->nb_samples);
1541+ break;
1542+ default:
1543+ return AVERROR(EINVAL);
1544+ }
1545+ if (!out)
1546+ return AVERROR(ENOMEM);
1547+
1548+ ret = av_frame_copy_props(out, frame);
1549+ if (ret < 0) {
1550+ av_frame_free(&out);
1551+ return ret;
1552+ }
1553+
1554+ switch (link->type) {
1555+ case AVMEDIA_TYPE_VIDEO:
1556+ av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize,
1557+ frame->format, frame->width, frame->height);
1558+ break;
1559+ case AVMEDIA_TYPE_AUDIO:
1560+ av_samples_copy(out->extended_data, frame->extended_data,
1561+ 0, 0, frame->nb_samples,
1562+ av_frame_get_channels(frame),
1563+ frame->format);
1564+ break;
1565+ default:
1566+ av_assert0(!"reached");
1567+ }
1568+
1569+ av_frame_free(&frame);
1570+ *rframe = out;
1571+ return 0;
1572+}
1573+
15621574 const AVClass *avfilter_get_class(void)
15631575 {
15641576 return &avfilter_class;
libavfilter/filters.h+7−0
@@ -39,6 +39,13 @@ · 38 unmodified lines
3939 */
4040 void ff_filter_set_ready(AVFilterContext *filter, unsigned priority);
4141
42+/**
43+ * Make sure a frame is writable.
44+ * This is similar to av_frame_make_writable() except it uses the link's
45+ * buffer allocation callback, and therefore allows direct rendering.
46+ */
47+int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe);
48+
4249 /**
4350 * Test and acknowledge the change of status on the link.
4451 *

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t