~thopiekar/+junk/vlc-2.0.8-github_community

« back to all changes in this revision

Viewing changes to modules/codec/rawvideo.c

  • Committer: Thomas-Karl Pietrowski
  • Date: 2014-02-25 08:48:22 UTC
  • Revision ID: thopiekar@googlemail.com-20140225084822-52495jnrzv3qlei6
vlc to build against libva-emgd-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 * rawvideo.c: Pseudo video decoder/packetizer for raw video data
 
3
 *****************************************************************************
 
4
 * Copyright (C) 2001, 2002 the VideoLAN team
 
5
 * $Id: aa68f35d26d544db938187f36fe8cc78e20d0e05 $
 
6
 *
 
7
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 2 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 
22
 *****************************************************************************/
 
23
 
 
24
/*****************************************************************************
 
25
 * Preamble
 
26
 *****************************************************************************/
 
27
#ifdef HAVE_CONFIG_H
 
28
# include "config.h"
 
29
#endif
 
30
 
 
31
#include <vlc_common.h>
 
32
#include <vlc_plugin.h>
 
33
#include <vlc_codec.h>
 
34
 
 
35
/*****************************************************************************
 
36
 * decoder_sys_t : raw video decoder descriptor
 
37
 *****************************************************************************/
 
38
struct decoder_sys_t
 
39
{
 
40
    /* Module mode */
 
41
    bool b_packetizer;
 
42
 
 
43
    /*
 
44
     * Input properties
 
45
     */
 
46
    size_t i_raw_size;
 
47
    bool b_invert;
 
48
    plane_t planes[PICTURE_PLANE_MAX];
 
49
 
 
50
    /*
 
51
     * Common properties
 
52
     */
 
53
    date_t pts;
 
54
};
 
55
 
 
56
/****************************************************************************
 
57
 * Local prototypes
 
58
 ****************************************************************************/
 
59
static int  OpenDecoder   ( vlc_object_t * );
 
60
static int  OpenPacketizer( vlc_object_t * );
 
61
static void CloseDecoder  ( vlc_object_t * );
 
62
 
 
63
static void *DecodeBlock  ( decoder_t *, block_t ** );
 
64
 
 
65
static picture_t *DecodeFrame( decoder_t *, block_t * );
 
66
static block_t   *SendFrame  ( decoder_t *, block_t * );
 
67
 
 
68
/*****************************************************************************
 
69
 * Module descriptor
 
70
 *****************************************************************************/
 
71
vlc_module_begin ()
 
72
    set_description( N_("Pseudo raw video decoder") )
 
73
    set_capability( "decoder", 50 )
 
74
    set_category( CAT_INPUT )
 
75
    set_subcategory( SUBCAT_INPUT_VCODEC )
 
76
    set_callbacks( OpenDecoder, CloseDecoder )
 
77
 
 
78
    add_submodule ()
 
79
    set_description( N_("Pseudo raw video packetizer") )
 
80
    set_capability( "packetizer", 100 )
 
81
    set_callbacks( OpenPacketizer, CloseDecoder )
 
82
vlc_module_end ()
 
83
 
 
84
/*****************************************************************************
 
85
 * OpenDecoder: probe the decoder and return score
 
86
 *****************************************************************************/
 
87
static int OpenDecoder( vlc_object_t *p_this )
 
88
{
 
89
    decoder_t *p_dec = (decoder_t*)p_this;
 
90
    decoder_sys_t *p_sys;
 
91
 
 
92
    switch( p_dec->fmt_in.i_codec )
 
93
    {
 
94
        /* Planar YUV */
 
95
        case VLC_CODEC_I444:
 
96
        case VLC_CODEC_J444:
 
97
        case VLC_CODEC_I422:
 
98
        case VLC_CODEC_J422:
 
99
        case VLC_CODEC_I420:
 
100
        case VLC_CODEC_J420:
 
101
        case VLC_CODEC_YV12:
 
102
        case VLC_CODEC_YV9:
 
103
        case VLC_CODEC_I411:
 
104
        case VLC_CODEC_I410:
 
105
        case VLC_CODEC_GREY:
 
106
        case VLC_CODEC_YUVP:
 
107
        case VLC_CODEC_NV12:
 
108
        case VLC_CODEC_NV21:
 
109
 
 
110
        /* Packed YUV */
 
111
        case VLC_CODEC_YUYV:
 
112
        case VLC_CODEC_YVYU:
 
113
        case VLC_CODEC_UYVY:
 
114
        case VLC_CODEC_VYUY:
 
115
 
 
116
        /* RGB */
 
117
        case VLC_CODEC_RGB32:
 
118
        case VLC_CODEC_RGB24:
 
119
        case VLC_CODEC_RGB16:
 
120
        case VLC_CODEC_RGB15:
 
121
        case VLC_CODEC_RGB8:
 
122
        case VLC_CODEC_RGBP:
 
123
            break;
 
124
 
 
125
        default:
 
126
            return VLC_EGENERIC;
 
127
    }
 
128
 
 
129
    /* Allocate the memory needed to store the decoder's structure */
 
130
    if( ( p_dec->p_sys = p_sys =
 
131
          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
 
132
        return VLC_ENOMEM;
 
133
    /* Misc init */
 
134
    p_dec->p_sys->b_packetizer = false;
 
135
    p_sys->b_invert = 0;
 
136
 
 
137
    if( (int)p_dec->fmt_in.video.i_height < 0 )
 
138
    {
 
139
        /* Frames are coded from bottom to top */
 
140
        p_dec->fmt_in.video.i_height =
 
141
            (unsigned int)(-(int)p_dec->fmt_in.video.i_height);
 
142
        p_sys->b_invert = true;
 
143
    }
 
144
 
 
145
    if( p_dec->fmt_in.video.i_width <= 0 || p_dec->fmt_in.video.i_height <= 0 )
 
146
    {
 
147
        msg_Err( p_dec, "invalid display size %dx%d",
 
148
                 p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height );
 
149
        return VLC_EGENERIC;
 
150
    }
 
151
 
 
152
    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
 
153
 
 
154
    date_Init( &p_sys->pts, p_dec->fmt_out.video.i_frame_rate,
 
155
               p_dec->fmt_out.video.i_frame_rate_base );
 
156
    if( p_dec->fmt_out.video.i_frame_rate == 0 ||
 
157
        p_dec->fmt_out.video.i_frame_rate_base == 0)
 
158
    {
 
159
        msg_Warn( p_dec, "invalid frame rate %d/%d, using 25 fps instead",
 
160
                  p_dec->fmt_out.video.i_frame_rate,
 
161
                  p_dec->fmt_out.video.i_frame_rate_base);
 
162
        date_Init( &p_sys->pts, 25, 1 );
 
163
    }
 
164
 
 
165
    /* Find out p_vdec->i_raw_size */
 
166
    video_format_Setup( &p_dec->fmt_out.video, p_dec->fmt_in.i_codec,
 
167
                        p_dec->fmt_in.video.i_width,
 
168
                        p_dec->fmt_in.video.i_height,
 
169
                        p_dec->fmt_in.video.i_sar_num,
 
170
                        p_dec->fmt_in.video.i_sar_den );
 
171
    picture_t picture;
 
172
    picture_Setup( &picture, p_dec->fmt_out.i_codec,
 
173
                   p_dec->fmt_in.video.i_width,
 
174
                   p_dec->fmt_in.video.i_height, 0, 1 );
 
175
    p_sys->i_raw_size = 0;
 
176
    for( int i = 0; i < picture.i_planes; i++ )
 
177
    {
 
178
        p_sys->i_raw_size += picture.p[i].i_visible_pitch *
 
179
                             picture.p[i].i_visible_lines;
 
180
        p_sys->planes[i] = picture.p[i];
 
181
    }
 
182
 
 
183
    if( !p_dec->fmt_in.video.i_sar_num || !p_dec->fmt_in.video.i_sar_den )
 
184
    {
 
185
        p_dec->fmt_out.video.i_sar_num = 1;
 
186
        p_dec->fmt_out.video.i_sar_den = 1;
 
187
    }
 
188
 
 
189
    /* Set callbacks */
 
190
    p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
 
191
        DecodeBlock;
 
192
    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
 
193
        DecodeBlock;
 
194
 
 
195
    return VLC_SUCCESS;
 
196
}
 
197
 
 
198
static int OpenPacketizer( vlc_object_t *p_this )
 
199
{
 
200
    decoder_t *p_dec = (decoder_t*)p_this;
 
201
 
 
202
    int i_ret = OpenDecoder( p_this );
 
203
 
 
204
    if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = true;
 
205
 
 
206
    return i_ret;
 
207
}
 
208
 
 
209
/****************************************************************************
 
210
 * DecodeBlock: the whole thing
 
211
 ****************************************************************************
 
212
 * This function must be fed with complete frames.
 
213
 ****************************************************************************/
 
214
static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 
215
{
 
216
    decoder_sys_t *p_sys = p_dec->p_sys;
 
217
    block_t *p_block;
 
218
    void *p_buf;
 
219
 
 
220
    if( !pp_block || !*pp_block ) return NULL;
 
221
 
 
222
    p_block = *pp_block;
 
223
 
 
224
 
 
225
    if( p_block->i_pts <= VLC_TS_INVALID && p_block->i_dts <= VLC_TS_INVALID &&
 
226
        !date_Get( &p_sys->pts ) )
 
227
    {
 
228
        /* We've just started the stream, wait for the first PTS. */
 
229
        block_Release( p_block );
 
230
        return NULL;
 
231
    }
 
232
 
 
233
    /* Date management: If there is a pts avaliable, use that. */
 
234
    if( p_block->i_pts > VLC_TS_INVALID )
 
235
    {
 
236
        date_Set( &p_sys->pts, p_block->i_pts );
 
237
    }
 
238
    else if( p_block->i_dts > VLC_TS_INVALID )
 
239
    {
 
240
        /* NB, davidf doesn't quite agree with this in general, it is ok
 
241
         * for rawvideo since it is in order (ie pts=dts), however, it
 
242
         * may not be ok for an out-of-order codec, so don't copy this
 
243
         * without thinking */
 
244
        date_Set( &p_sys->pts, p_block->i_dts );
 
245
    }
 
246
 
 
247
    if( p_block->i_buffer < p_sys->i_raw_size )
 
248
    {
 
249
        msg_Warn( p_dec, "invalid frame size (%zu < %zu)",
 
250
                  p_block->i_buffer, p_sys->i_raw_size );
 
251
 
 
252
        block_Release( p_block );
 
253
        return NULL;
 
254
    }
 
255
 
 
256
    if( p_sys->b_packetizer )
 
257
    {
 
258
        p_buf = SendFrame( p_dec, p_block );
 
259
    }
 
260
    else
 
261
    {
 
262
        p_buf = DecodeFrame( p_dec, p_block );
 
263
    }
 
264
 
 
265
    /* Date management: 1 frame per packet */
 
266
    date_Increment( &p_sys->pts, 1 );
 
267
    *pp_block = NULL;
 
268
 
 
269
    return p_buf;
 
270
}
 
271
 
 
272
/*****************************************************************************
 
273
 * FillPicture:
 
274
 *****************************************************************************/
 
275
static void FillPicture( decoder_t *p_dec, block_t *p_block, picture_t *p_pic )
 
276
{
 
277
    int i_plane;
 
278
    decoder_sys_t *p_sys = p_dec->p_sys;
 
279
    uint8_t *p_src = p_block->p_buffer;
 
280
 
 
281
    for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
 
282
    {
 
283
        int i_pitch = p_pic->p[i_plane].i_pitch;
 
284
        int i_visible_pitch = p_sys->planes[i_plane].i_visible_pitch;
 
285
        int i_visible_lines = p_sys->planes[i_plane].i_visible_lines;
 
286
        uint8_t *p_dst = p_pic->p[i_plane].p_pixels;
 
287
        uint8_t *p_dst_end = p_dst+i_pitch*i_visible_lines;
 
288
 
 
289
        if( p_sys->b_invert )
 
290
            for( p_dst_end -= i_pitch; p_dst <= p_dst_end;
 
291
                 p_dst_end -= i_pitch, p_src += i_visible_pitch )
 
292
                vlc_memcpy( p_dst_end, p_src, i_visible_pitch );
 
293
        else
 
294
            for( ; p_dst < p_dst_end;
 
295
                 p_dst += i_pitch, p_src += i_visible_pitch )
 
296
                vlc_memcpy( p_dst, p_src, i_visible_pitch );
 
297
    }
 
298
}
 
299
 
 
300
/*****************************************************************************
 
301
 * DecodeFrame: decodes a video frame.
 
302
 *****************************************************************************/
 
303
static picture_t *DecodeFrame( decoder_t *p_dec, block_t *p_block )
 
304
{
 
305
    decoder_sys_t *p_sys = p_dec->p_sys;
 
306
    picture_t *p_pic;
 
307
 
 
308
    /* Get a new picture */
 
309
    p_pic = decoder_NewPicture( p_dec );
 
310
    if( !p_pic )
 
311
    {
 
312
        block_Release( p_block );
 
313
        return NULL;
 
314
    }
 
315
 
 
316
    FillPicture( p_dec, p_block, p_pic );
 
317
 
 
318
    p_pic->date = date_Get( &p_sys->pts );
 
319
    if( p_block->i_flags & BLOCK_FLAG_INTERLACED_MASK )
 
320
    {
 
321
        p_pic->b_progressive = false;
 
322
        p_pic->i_nb_fields = 2;
 
323
        if( p_block->i_flags & BLOCK_FLAG_TOP_FIELD_FIRST )
 
324
            p_pic->b_top_field_first = true;
 
325
        else
 
326
            p_pic->b_top_field_first = false;
 
327
    }
 
328
    else
 
329
        p_pic->b_progressive = true;
 
330
 
 
331
    block_Release( p_block );
 
332
    return p_pic;
 
333
}
 
334
 
 
335
/*****************************************************************************
 
336
 * SendFrame: send a video frame to the stream output.
 
337
 *****************************************************************************/
 
338
static block_t *SendFrame( decoder_t *p_dec, block_t *p_block )
 
339
{
 
340
    decoder_sys_t *p_sys = p_dec->p_sys;
 
341
 
 
342
    p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts );
 
343
 
 
344
    if( p_sys->b_invert )
 
345
    {
 
346
        picture_t pic;
 
347
        uint8_t *p_tmp, *p_pixels;
 
348
        int i, j;
 
349
 
 
350
        /* Fill in picture_t fields */
 
351
        picture_Setup( &pic, p_dec->fmt_out.i_codec,
 
352
                       p_dec->fmt_out.video.i_width,
 
353
                       p_dec->fmt_out.video.i_height, 0, 1 );
 
354
 
 
355
        if( !pic.i_planes )
 
356
        {
 
357
            msg_Err( p_dec, "unsupported chroma" );
 
358
            return p_block;
 
359
        }
 
360
 
 
361
        p_tmp = malloc( pic.p[0].i_pitch );
 
362
        if( !p_tmp )
 
363
            return p_block;
 
364
        p_pixels = p_block->p_buffer;
 
365
        for( i = 0; i < pic.i_planes; i++ )
 
366
        {
 
367
            int i_pitch = pic.p[i].i_pitch;
 
368
            uint8_t *p_top = p_pixels;
 
369
            uint8_t *p_bottom = p_pixels + i_pitch *
 
370
                (pic.p[i].i_visible_lines - 1);
 
371
 
 
372
            for( j = 0; j < pic.p[i].i_visible_lines / 2; j++ )
 
373
            {
 
374
                vlc_memcpy( p_tmp, p_bottom, pic.p[i].i_visible_pitch  );
 
375
                vlc_memcpy( p_bottom, p_top, pic.p[i].i_visible_pitch  );
 
376
                vlc_memcpy( p_top, p_tmp, pic.p[i].i_visible_pitch  );
 
377
                p_top += i_pitch;
 
378
                p_bottom -= i_pitch;
 
379
            }
 
380
 
 
381
            p_pixels += i_pitch * pic.p[i].i_lines;
 
382
        }
 
383
        free( p_tmp );
 
384
    }
 
385
 
 
386
    return p_block;
 
387
}
 
388
 
 
389
/*****************************************************************************
 
390
 * CloseDecoder: decoder destruction
 
391
 *****************************************************************************/
 
392
static void CloseDecoder( vlc_object_t *p_this )
 
393
{
 
394
    decoder_t *p_dec = (decoder_t*)p_this;
 
395
    free( p_dec->p_sys );
 
396
}