1 /*****************************************************************************
2 * repack.c: Codec specific formatting for AnnexB multiplexers
3 *****************************************************************************
4 * Copyright (C) 2021 VideoLabs, VLC authors and VideoLAN
6 * This program is free software; you can redistribute it and/or modify it
7 * 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.
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.
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 *****************************************************************************/
24 #include <vlc_common.h>
25 #include <vlc_block.h>
28 #include "../../packetizer/hevc_nal.h"
29 #include "../../packetizer/h264_nal.h"
30 #include "../../packetizer/hxxx_nal.h"
34 static void AnnexBInject(block_t
**pp_pes
,
35 const uint8_t *p_extra
, size_t i_extra
,
36 const uint8_t *p_au
, size_t i_au
)
41 *pp_pes
= block_Realloc(*pp_pes
,
47 memcpy(&(*pp_pes
)->p_buffer
[0], p_au
, i_au
);
49 memcpy(&(*pp_pes
)->p_buffer
[i_au
], p_extra
, i_extra
);
53 static void PES_RepackHEVC(block_t
**pp_pes
,
54 const uint8_t *p_extra
, size_t i_extra
)
57 size_t i_aucurrent
= 0;
58 const uint8_t audata
[] = { 0x00, 0x00, 0x00, 0x01, 0x46, 0x01 };
59 hxxx_iterator_ctx_t ctx
;
60 hxxx_iterator_init(&ctx
, (*pp_pes
)->p_buffer
, (*pp_pes
)->i_buffer
, 0);
61 const uint8_t *p_nal
; size_t i_nal
;
62 while(hxxx_annexb_iterate_next(&ctx
, &p_nal
, &i_nal
))
66 uint8_t type
= hevc_getNALType(p_nal
);
67 if(type
< HEVC_NAL_VPS
)
73 i_aucurrent
= 2 + (p_nal
- (*pp_pes
)->p_buffer
);
85 if(i_extra
&& i_aucurrent
) /* strip existing AU for now */
87 (*pp_pes
)->p_buffer
+= i_aucurrent
;
88 (*pp_pes
)->i_buffer
-= i_aucurrent
;
92 AnnexBInject(pp_pes
, p_extra
, i_extra
, audata
, i_au
);
95 static void PES_RepackH264(block_t
**pp_pes
,
96 const uint8_t *p_extra
, size_t i_extra
)
99 size_t i_aucurrent
= 0;
100 const uint8_t audata
[] = { 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0 };
101 hxxx_iterator_ctx_t ctx
;
102 hxxx_iterator_init(&ctx
, (*pp_pes
)->p_buffer
, (*pp_pes
)->i_buffer
, 0);
103 const uint8_t *p_nal
; size_t i_nal
;
104 while(hxxx_annexb_iterate_next(&ctx
, &p_nal
, &i_nal
))
108 uint8_t type
= p_nal
[0]&0x1f;
109 if(type
< H264_NAL_SEI
)
113 case H264_NAL_AU_DELIMITER
:
115 i_aucurrent
= 2 + (p_nal
- (*pp_pes
)->p_buffer
);
126 if(i_extra
&& i_aucurrent
) /* strip existing AU for now */
128 (*pp_pes
)->p_buffer
+= i_aucurrent
;
129 (*pp_pes
)->i_buffer
-= i_aucurrent
;
133 AnnexBInject(pp_pes
, p_extra
, i_extra
, audata
, i_au
);
136 static void PES_RepackMP4V(block_t
**pp_pes
,
137 const uint8_t *p_extra
, size_t i_extra
)
139 hxxx_iterator_ctx_t ctx
;
140 hxxx_iterator_init(&ctx
, (*pp_pes
)->p_buffer
, (*pp_pes
)->i_buffer
, 0);
141 const uint8_t *p_nal
; size_t i_nal
;
142 while(hxxx_annexb_iterate_next(&ctx
, &p_nal
, &i_nal
))
146 if(p_nal
[0] >= 0x30) /* > VOLS */
148 if(p_nal
[0] >= 0x20 && p_nal
[0] == p_extra
[3]) /* same VOL */
152 AnnexBInject(pp_pes
, p_extra
, i_extra
, NULL
, 0);
155 block_t
* PES_Repack(vlc_fourcc_t i_codec
,
156 const uint8_t *p_extra
, size_t i_extra
,
159 /* safety check for annexb extra */
161 (memcmp(p_extra
, annexb_startcode4
, 4) &&
162 memcmp(&p_extra
[1], annexb_startcode3
, 3)))
168 PES_RepackHEVC(pp_pes
, p_extra
, i_extra
);
171 PES_RepackH264(pp_pes
, p_extra
, i_extra
);
174 PES_RepackMP4V(pp_pes
, p_extra
, i_extra
);