/** @internal @This checks if the pump may be allocated. * * @param upipe description structure of the pipe * @param flow_format amended flow format * @return an error code */ static int upipe_qt_html_check(struct upipe *upipe, struct uref *flow_format) { struct upipe_qt_html *upipe_qt_html = upipe_qt_html_from_upipe(upipe); if (flow_format != NULL) upipe_qt_html_store_flow_def(upipe, flow_format); upipe_qt_html_check_upump_mgr(upipe); if (upipe_qt_html->upump_mgr == NULL) return UBASE_ERR_NONE; if (upipe_qt_html->uref_mgr == NULL) { upipe_qt_html_require_uref_mgr(upipe); return UBASE_ERR_NONE; } if (upipe_qt_html->ubuf_mgr == NULL) { struct uref *flow_format = uref_pic_flow_alloc_def(upipe_qt_html->uref_mgr, 1); uref_pic_flow_set_macropixel(flow_format, 1); uref_pic_flow_add_plane(flow_format, 1, 1, 4, "b8g8r8a8"); uref_pic_flow_set_hsize(flow_format, upipe_qt_html->H); uref_pic_flow_set_vsize(flow_format, upipe_qt_html->V); if (unlikely(flow_format == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_qt_html_require_ubuf_mgr(upipe, flow_format); return UBASE_ERR_NONE; } if (upipe_qt_html->upump == NULL) { upipe_qt_html_wait_upumpstart(upipe, 0, start); } return UBASE_ERR_NONE; }
/** @internal @This outputs video frames * * @param upipe description structure of the pipe * @param frame AVFrame structure * @param upump upump structure */ static void upipe_avcdec_output_frame(struct upipe *upipe, AVFrame *frame, struct upump *upump) { struct ubuf *ubuf; struct upipe_avcdec *upipe_avcdec = upipe_avcdec_from_upipe(upipe); const struct upipe_av_plane *planes = upipe_avcdec->pixfmt->planes; struct uref *uref = uref_dup(frame->opaque); uint8_t *data, *src, hsub, vsub; const char *chroma = NULL; size_t sstride, dstride; int i, j; struct urational aspect; /* if uref has no attached ubuf (ie DR not supported) */ if (unlikely(!uref->ubuf)) { ubuf = ubuf_pic_alloc(upipe_avcdec->ubuf_mgr, frame->width, frame->height); if (!ubuf) { upipe_throw_aerror(upipe); return; } /* iterate through planes and copy data */ i = j = 0; for (i=0; i < 4 && (chroma = planes[i].chroma); i++) { ubuf_pic_plane_write(ubuf, chroma, 0, 0, -1, -1, &data); ubuf_pic_plane_size(ubuf, chroma, &dstride, &hsub, &vsub, NULL); src = frame->data[i]; sstride = frame->linesize[i]; for (j = 0; j < frame->height/vsub; j++) { memcpy(data, src, frame->width/hsub); data += dstride; src += sstride; } ubuf_pic_plane_unmap(ubuf, chroma, 0, 0, -1, -1); } uref_attach_ubuf(uref, ubuf); } /* set aspect-ratio */ aspect.den = 0; /* null denom is invalid */ if (upipe_avcdec->context->sample_aspect_ratio.den) { aspect.num = upipe_avcdec->context->sample_aspect_ratio.num; aspect.den = upipe_avcdec->context->sample_aspect_ratio.den; } else if (frame->sample_aspect_ratio.den) { aspect.num = frame->sample_aspect_ratio.num; aspect.den = frame->sample_aspect_ratio.den; } if (aspect.den) { urational_simplify(&aspect); uref_pic_set_aspect(uref, aspect); } if (!upipe_avcdec->output_flow) { struct uref *outflow = uref_pic_flow_alloc_def(upipe_avcdec->uref_mgr, 1); upipe_avcdec_store_flow_def(upipe, outflow); } /* index rap attribute */ upipe_avcdec_set_index_rap(upipe, uref); upipe_avcdec_output(upipe, uref, upump); }