if (!frame->linesize[0]) { for (int i = 1; i <= align; i += i) {
ret = av_image_fill_linesizes(frame->linesize, frame->format,
FFALIGN(frame->width, i)); if (ret < 0) return ret; if (!(frame->linesize[0] & (align-1))) break;
}
for (int i = 0; i < 4 && frame->linesize[i]; i++)
frame->linesize[i] = FFALIGN(frame->linesize[i], align);
}
for (int i = 0; i < 4; i++)
linesizes[i] = frame->linesize[i];
for (int i = 1; i < 4; i++) { if (frame->data[i])
frame->data[i] += i * plane_padding;
frame->data[i] = (uint8_t *)FFALIGN((uintptr_t)frame->data[i], align);
}
staticint get_audio_buffer(AVFrame *frame, int align)
{ int planar = av_sample_fmt_is_planar(frame->format); int channels, planes;
size_t size; int ret;
channels = frame->ch_layout.nb_channels;
planes = planar ? channels : 1; if (!frame->linesize[0]) {
ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
frame->nb_samples, frame->format,
align); if (ret < 0) return ret;
}
ret = frame_copy_props(dst, src, 0); if (ret < 0) goto fail;
ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout); if (ret < 0) goto fail;
/* duplicate the frame data if it's not refcounted */ if (!src->buf[0]) {
ret = av_frame_get_buffer(dst, 0); if (ret < 0) goto fail;
ret = av_frame_copy(dst, src); if (ret < 0) goto fail;
return0;
}
/* ref the buffers */ for (int i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) { if (!src->buf[i]) continue;
dst->buf[i] = av_buffer_ref(src->buf[i]); if (!dst->buf[i]) {
ret = AVERROR(ENOMEM); goto fail;
}
}
if (src->extended_buf) {
dst->extended_buf = av_calloc(src->nb_extended_buf, sizeof(*dst->extended_buf)); if (!dst->extended_buf) {
ret = AVERROR(ENOMEM); goto fail;
}
dst->nb_extended_buf = src->nb_extended_buf;
for (int i = 0; i < src->nb_extended_buf; i++) {
dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]); if (!dst->extended_buf[i]) {
ret = AVERROR(ENOMEM); goto fail;
}
}
}
if (src->hw_frames_ctx) {
dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); if (!dst->hw_frames_ctx) {
ret = AVERROR(ENOMEM); goto fail;
}
}
/* duplicate extended data */ if (src->extended_data != src->data) { int ch = dst->ch_layout.nb_channels;
if (ch <= 0 || ch > SIZE_MAX / sizeof(*dst->extended_data)) {
ret = AVERROR(EINVAL); goto fail;
}
dst->extended_data = av_memdup(src->extended_data, sizeof(*dst->extended_data) * ch); if (!dst->extended_data) {
ret = AVERROR(ENOMEM); goto fail;
}
} else
dst->extended_data = dst->data;
int av_frame_replace(AVFrame *dst, const AVFrame *src)
{ int ret = 0;
if (dst == src) return AVERROR(EINVAL);
if (!src->buf[0]) {
av_frame_unref(dst);
/* duplicate the frame data if it's not refcounted */ if ( src->data[0] || src->data[1]
|| src->data[2] || src->data[3]) return av_frame_ref(dst, src);
ret = frame_copy_props(dst, src, 0); if (ret < 0) goto fail;
}
ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout); if (ret < 0) goto fail;
av_frame_side_data_free(&dst->side_data, &dst->nb_side_data);
av_dict_free(&dst->metadata);
ret = frame_copy_props(dst, src, 0); if (ret < 0) goto fail;
/* replace the buffers */ for (int i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) {
ret = av_buffer_replace(&dst->buf[i], src->buf[i]); if (ret < 0) goto fail;
}
if (src->extended_buf) { if (dst->nb_extended_buf != src->nb_extended_buf) { int nb_extended_buf = FFMIN(dst->nb_extended_buf, src->nb_extended_buf); void *tmp;
for (int i = nb_extended_buf; i < dst->nb_extended_buf; i++)
av_buffer_unref(&dst->extended_buf[i]);
tmp = av_realloc_array(dst->extended_buf, src->nb_extended_buf, sizeof(*dst->extended_buf)); if (!tmp) {
ret = AVERROR(ENOMEM); goto fail;
}
dst->extended_buf = tmp;
dst->nb_extended_buf = src->nb_extended_buf;
for (int i = 0; i < src->nb_extended_buf; i++) {
ret = av_buffer_replace(&dst->extended_buf[i], src->extended_buf[i]); if (ret < 0) goto fail;
}
} elseif (dst->extended_buf) { for (int i = 0; i < dst->nb_extended_buf; i++)
av_buffer_unref(&dst->extended_buf[i]);
av_freep(&dst->extended_buf);
}
ret = av_buffer_replace(&dst->hw_frames_ctx, src->hw_frames_ctx); if (ret < 0) goto fail;
if (dst->extended_data != dst->data)
av_freep(&dst->extended_data);
if (src->extended_data != src->data) { int ch = dst->ch_layout.nb_channels;
if (ch <= 0 || ch > SIZE_MAX / sizeof(*dst->extended_data)) {
ret = AVERROR(EINVAL); goto fail;
}
dst->extended_data = av_memdup(src->extended_data, sizeof(*dst->extended_data) * ch); if (!dst->extended_data) {
ret = AVERROR(ENOMEM); goto fail;
}
} else
dst->extended_data = dst->data;
for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
av_buffer_unref(&frame->buf[i]); for (int i = 0; i < frame->nb_extended_buf; i++)
av_buffer_unref(&frame->extended_buf[i]);
av_freep(&frame->extended_buf);
av_dict_free(&frame->metadata);
int av_frame_is_writable(AVFrame *frame)
{ int ret = 1;
/* assume non-refcounted frames are not writable */ if (!frame->buf[0]) return0;
for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) if (frame->buf[i])
ret &= !!av_buffer_is_writable(frame->buf[i]); for (int i = 0; i < frame->nb_extended_buf; i++)
ret &= !!av_buffer_is_writable(frame->extended_buf[i]);
return ret;
}
int av_frame_make_writable(AVFrame *frame)
{
AVFrame tmp; int ret;
if (frame->hw_frames_ctx)
ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0); else
ret = av_frame_get_buffer(&tmp, 0); if (ret < 0) return ret;
ret = av_frame_copy(&tmp, frame); if (ret < 0) {
av_frame_unref(&tmp); return ret;
}
ret = av_frame_copy_props(&tmp, frame); if (ret < 0) {
av_frame_unref(&tmp); return ret;
}
av_frame_unref(frame);
*frame = tmp; if (tmp.data == tmp.extended_data)
frame->extended_data = frame->data;
desc = av_pix_fmt_desc_get(frame->format); if (!desc) return AVERROR_BUG;
/* Apply just the right/bottom cropping for hwaccel formats. Bitstream *formatscannotbeeasilyhandledhereeither(andcorrespondingdecoders *shouldnotexportanycroppinganyway),sodothesameforthoseaswell.
* */ if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL)) {
frame->width -= frame->crop_right;
frame->height -= frame->crop_bottom;
frame->crop_right = 0;
frame->crop_bottom = 0; return0;
}
/* calculate the offsets for each plane */
ret = calc_cropping_offsets(offsets, frame, desc); if (ret < 0) return ret;
/* adjust the offsets to avoid breaking alignment */ if (!(flags & AV_FRAME_CROP_UNALIGNED)) { int log2_crop_align = frame->crop_left ? ff_ctz(frame->crop_left) : INT_MAX; int min_log2_align = INT_MAX;
for (int i = 0; frame->data[i]; i++) { int log2_align = offsets[i] ? ff_ctz(offsets[i]) : INT_MAX;
min_log2_align = FFMIN(log2_align, min_log2_align);
}
/* we assume, and it should always be true, that the data alignment is
* related to the cropping alignment by a constant power-of-2 factor */ if (log2_crop_align < min_log2_align) return AVERROR_BUG;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.