]> git.sesse.net Git - vlc/blob - modules/codec/avcodec/hwdummy.c
ead7ccdaec0588a71acbb45f271c9f21caa098fc
[vlc] / modules / codec / avcodec / hwdummy.c
1 /*****************************************************************************
2  * hwdummy.c: dummy hardware decoding acceleration plugin for VLC/libav
3  *****************************************************************************
4  * Copyright (C) 2013 RĂ©mi Denis-Courmont
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <string.h>
26 #include <stdlib.h>
27 #include <assert.h>
28
29 #include <libavutil/mem.h>
30 #include <libavcodec/avcodec.h>
31 #include <libavcodec/vdpau.h>
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_fourcc.h>
35 #include <vlc_picture.h>
36 #include "../../codec/avcodec/va.h"
37
38 static int Open(vlc_va_t *, int, const es_format_t *);
39 static void Close(vlc_va_t *);
40
41 vlc_module_begin()
42     set_description(N_("Dummy video decoding accelerator"))
43     set_capability("hw decoder", 0)
44     set_category(CAT_INPUT)
45     set_subcategory(SUBCAT_INPUT_VCODEC)
46     set_callbacks(Open, Close)
47     add_shortcut("dummy")
48 vlc_module_end()
49
50 #define DECODER_MAGIC 0x12345678
51 #define SURFACE_MAGIC 0x87654321
52
53 struct vlc_va_sys_t
54 {
55     AVVDPAUContext context;
56 };
57
58 static int Lock(vlc_va_t *va, AVFrame *ff)
59 {
60     for (unsigned i = 0; i < AV_NUM_DATA_POINTERS; i++)
61     {
62         ff->data[i] = NULL;
63         ff->linesize[i] = 0;
64     }
65
66     ff->data[0] = (void *)(uintptr_t)SURFACE_MAGIC; /* must be non-NULL */
67     ff->data[3] = (void *)(uintptr_t)SURFACE_MAGIC;
68     ff->opaque = (void *)(uintptr_t)SURFACE_MAGIC;
69     return VLC_SUCCESS;
70 }
71
72 static void Unlock(void *opaque)
73 {
74     assert((uintptr_t)opaque == SURFACE_MAGIC);
75 }
76
77 static VdpStatus Render(VdpDecoder decoder, VdpVideoSurface target,
78                         VdpPictureInfo const *picture_info,
79                         uint32_t bitstream_buffer_count,
80                         VdpBitstreamBuffer const *bitstream_buffers)
81 {
82     (void) decoder; (void) target; (void) picture_info;
83     (void) bitstream_buffer_count; (void) bitstream_buffers;
84     assert(decoder == DECODER_MAGIC);
85     assert(target == SURFACE_MAGIC);
86     return VDP_STATUS_OK;
87 }
88
89 static int Copy(vlc_va_t *va, picture_t *pic, AVFrame *ff)
90 {
91     (void) va; (void) ff;
92
93     assert((uintptr_t)ff->data[3] == SURFACE_MAGIC);
94     assert((uintptr_t)ff->opaque == SURFACE_MAGIC);
95
96     /* Put some dummy picture content */
97     memset(pic->p[0].p_pixels, 0xF0,
98            pic->p[0].i_pitch * pic->p[0].i_visible_lines);
99     for (int i = 0; i < pic->p[1].i_visible_lines; i++)
100         memset(pic->p[1].p_pixels + (i * pic->p[1].i_pitch), i,
101                pic->p[1].i_visible_pitch);
102     for (int i = 0; i < pic->p[2].i_visible_lines; i++)
103         for (int j = 0; j < pic->p[2].i_visible_pitch; j++)
104             pic->p[2].p_pixels[(i * pic->p[2].i_pitch) + j] = j;
105     return VLC_SUCCESS;
106 }
107
108 static int Setup(vlc_va_t *va, void **ctxp, vlc_fourcc_t *chromap,
109                  int width, int height)
110 {
111     vlc_va_sys_t *sys = va->sys;
112
113     (void) width; (void) height;
114
115     *ctxp = &sys->context;
116     *chromap = VLC_CODEC_YV12;
117     return VLC_SUCCESS;
118 }
119
120 static int Open(vlc_va_t *va, int codec, const es_format_t *fmt)
121 {
122     union
123     {
124         char str[4];
125         vlc_fourcc_t fourcc;
126     } u = { .fourcc = fmt->i_codec };
127
128     vlc_va_sys_t *sys = calloc(1, sizeof (*sys));
129     if (unlikely(sys == NULL))
130        return VLC_ENOMEM;
131
132     msg_Dbg(va, "codec %d (%4.4s) profile %d level %d", codec, u.str,
133             fmt->i_profile, fmt->i_level);
134
135     sys->context.decoder = DECODER_MAGIC;
136     sys->context.render = Render;
137
138     va->sys = sys;
139     va->description = (char *)"Dummy video decoding accelerator";
140     va->pix_fmt = AV_PIX_FMT_VDPAU;
141     va->setup = Setup;
142     va->get = Lock;
143     va->release = Unlock;
144     va->extract = Copy;
145     return VLC_SUCCESS;
146 }
147
148 static void Close(vlc_va_t *va)
149 {
150     vlc_va_sys_t *sys = va->sys;
151
152     av_freep(&sys->context.bitstream_buffers);
153     free(sys);
154 }