]> git.sesse.net Git - vlc/blob - modules/codec/h264_nal.h
V4L2: make loudness, horizontal flip and vertical flip booleans
[vlc] / modules / codec / h264_nal.h
1 /*****************************************************************************
2  * Copyright © 2010-2011 VideoLAN
3  *
4  * Authors: Jean-Baptiste Kempf <jb@videolan.org>
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 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 /* Parse the SPS/PPS Metadata and convert it to annex b format */
22 static int convert_sps_pps( decoder_t *p_dec, const uint8_t *p_buf,
23                             uint32_t i_buf_size, uint8_t *p_out_buf,
24                             uint32_t i_out_buf_size, uint32_t *p_sps_pps_size,
25                             uint32_t *p_nal_size)
26 {
27     int i_profile;
28     uint32_t i_data_size = i_buf_size, i_nal_size, i_sps_pps_size = 0;
29     unsigned int i_loop_end;
30
31     /* */
32     if( i_data_size < 7 )
33     {
34         msg_Err( p_dec, "Input Metadata too small" );
35         return VLC_ENOMEM;
36     }
37
38     /* Read infos in first 6 bytes */
39     i_profile    = (p_buf[1] << 16) | (p_buf[2] << 8) | p_buf[3];
40     if (p_nal_size)
41         *p_nal_size  = (p_buf[4] & 0x03) + 1;
42     p_buf       += 5;
43     i_data_size -= 5;
44
45     for ( unsigned int j = 0; j < 2; j++ )
46     {
47         /* First time is SPS, Second is PPS */
48         if( i_data_size < 1 )
49         {
50             msg_Err( p_dec, "PPS too small after processing SPS/PPS %u",
51                     i_data_size );
52             return VLC_ENOMEM;
53         }
54         i_loop_end = p_buf[0] & (j == 0 ? 0x1f : 0xff);
55         p_buf++; i_data_size--;
56
57         for ( unsigned int i = 0; i < i_loop_end; i++)
58         {
59             if( i_data_size < 2 )
60             {
61                 msg_Err( p_dec, "SPS is too small %u", i_data_size );
62                 return VLC_ENOMEM;
63             }
64
65             i_nal_size = (p_buf[0] << 8) | p_buf[1];
66             p_buf += 2;
67             i_data_size -= 2;
68
69             if( i_data_size < i_nal_size )
70             {
71                 msg_Err( p_dec, "SPS size does not match NAL specified size %u",
72                         i_data_size );
73                 return VLC_ENOMEM;
74             }
75             if( i_sps_pps_size + 4 + i_nal_size > i_out_buf_size )
76             {
77                 msg_Err( p_dec, "Output SPS/PPS buffer too small" );
78                 return VLC_ENOMEM;
79             }
80
81             p_out_buf[i_sps_pps_size++] = 0;
82             p_out_buf[i_sps_pps_size++] = 0;
83             p_out_buf[i_sps_pps_size++] = 0;
84             p_out_buf[i_sps_pps_size++] = 1;
85
86             memcpy( p_out_buf + i_sps_pps_size, p_buf, i_nal_size );
87             i_sps_pps_size += i_nal_size;
88
89             p_buf += i_nal_size;
90             i_data_size -= i_nal_size;
91         }
92     }
93
94     *p_sps_pps_size = i_sps_pps_size;
95
96     return VLC_SUCCESS;
97 }
98