[FFmpeg-devel] [PATCH] lavu: Add DRM hwcontext

Jorge Ramirez jorge.ramirez-ortiz at linaro.org
Fri Sep 1 20:48:20 EEST 2017


On 09/01/2017 05:44 PM, LongChair . wrote:
> +static int drm_map_frame(AVHWFramesContext *hwfc,
> +                         AVFrame *dst, const AVFrame *src, int flags)
> +{
> +    const AVDRMFrameDescriptor*desc = (AVDRMFrameDescriptor*)src->data[0];
> +    DRMMapping *map;
> +    int err, i, p, plane;
> +    int mmap_prot;
> +    void *addr;
> +
> +    map = av_mallocz(sizeof(*map));
> +    if (!map)
> +        return AVERROR(ENOMEM);
> +
> +    mmap_prot = 0;
> +    if (flags & AV_HWFRAME_MAP_READ)
> +        mmap_prot |= PROT_READ;
> +    if (flags & AV_HWFRAME_MAP_WRITE)
> +        mmap_prot |= PROT_WRITE;
> +
> +    av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES);
> +    for (i = 0; i < desc->nb_objects; i++) {
> +        addr = mmap(NULL, desc->objects[i].size, mmap_prot, MAP_SHARED,
> +                    desc->objects[i].fd, 0);
> +        if (addr == MAP_FAILED) {
> +            err = AVERROR(errno);
> +            av_log(hwfc, AV_LOG_ERROR, "Failed to map DRM object %d to "
> +                   "memory: %d.\n", desc->objects[i].fd, errno);
> +            goto fail;
> +        }
> +
> +        map->address[i] = addr;
> +        map->length[i]  = desc->objects[i].size;
> +    }
> +    map->nb_regions = i;
> +
> +    plane = 0;
> +    for (i = 0; i < desc->nb_layers; i++) {
> +        const AVDRMLayerDescriptor *layer = &desc->layers[i];
> +        for (p = 0; p < layer->nb_planes; p++) {
> +            dst->data[plane] =
> +                (uint8_t*)map->address[layer->planes[p].object_index] +
> +                                       layer->planes[p].offset;
> +            dst->linesize[plane] =     layer->planes[p].pitch;
> +            ++plane;
> +        }
> +    }
> +    av_assert0(plane <= AV_DRM_MAX_PLANES);
> +
> +    dst->width  = src->width;
> +    dst->height = src->height;
> +
> +    err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src,
> +                                &drm_unmap_frame, map);
> +    if (err < 0)
shouldn't we unmap and free the map as well?
> +        return err;
> +
> +    return 0;
> +
> +fail:
> +    for (i = 0; i < desc->nb_objects; i++) {
> +        if (map->address[i])
> +            munmap(map->address[i], map->length[i]);
> +    }
> +    av_free(map);
> +    return err;
> +}



More information about the ffmpeg-devel mailing list