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;
+}

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to