@@ -48,6 +48,7 @@ struct avc_ctx *init_avc(void)
4848 ctx -> cc_databufsize = 1024 ;
4949 ctx -> cc_buffer_saved = CCX_TRUE ; // Was the CC buffer saved after it was last updated?
5050
51+ ctx -> is_hevc = 0 ;
5152 ctx -> got_seq_para = 0 ;
5253 ctx -> nal_ref_idc = 0 ;
5354 ctx -> seq_parameter_set_id = 0 ;
@@ -87,62 +88,108 @@ struct avc_ctx *init_avc(void)
8788 return ctx ;
8889}
8990
91+ // HEVC NAL unit types for SEI messages
92+ #define HEVC_NAL_PREFIX_SEI 39
93+ #define HEVC_NAL_SUFFIX_SEI 40
94+ #define HEVC_NAL_VPS 32
95+ #define HEVC_NAL_SPS 33
96+ #define HEVC_NAL_PPS 34
97+
9098void do_NAL (struct encoder_ctx * enc_ctx , struct lib_cc_decode * dec_ctx , unsigned char * NAL_start , LLONG NAL_length , struct cc_subtitle * sub )
9199{
92100 unsigned char * NAL_stop ;
93- enum ccx_avc_nal_types nal_unit_type = * NAL_start & 0x1F ;
101+ int nal_unit_type ;
102+ int nal_header_size ;
103+ unsigned char * payload_start ;
104+
105+ // Determine if this is HEVC or H.264 based on NAL header
106+ // H.264 NAL header: 1 byte, type in bits [4:0]
107+ // HEVC NAL header: 2 bytes, type in bits [6:1] of first byte
108+ if (dec_ctx -> avc_ctx -> is_hevc )
109+ {
110+ // HEVC: NAL type is in bits [6:1] of byte 0
111+ nal_unit_type = (NAL_start [0 ] >> 1 ) & 0x3F ;
112+ nal_header_size = 2 ;
113+ }
114+ else
115+ {
116+ // H.264: NAL type is in bits [4:0] of byte 0
117+ nal_unit_type = NAL_start [0 ] & 0x1F ;
118+ nal_header_size = 1 ;
119+ }
94120
95121 NAL_stop = NAL_length + NAL_start ;
96- NAL_stop = remove_03emu (NAL_start + 1 , NAL_stop ); // Add +1 to NAL_stop for TS, without it for MP4. Still don't know why
122+ NAL_stop = remove_03emu (NAL_start + nal_header_size , NAL_stop );
123+ payload_start = NAL_start + nal_header_size ;
97124
98- dvprint ("BEGIN NAL unit type: %d length %d ref_idc: %d - Buffered captions before: %d\n" ,
99- nal_unit_type , NAL_stop - NAL_start - 1 , dec_ctx -> avc_ctx -> nal_ref_idc , !dec_ctx -> avc_ctx -> cc_buffer_saved );
125+ dvprint ("BEGIN NAL unit type: %d length %d ref_idc: %d - Buffered captions before: %d (HEVC: %d)\n" ,
126+ nal_unit_type , NAL_stop - NAL_start - nal_header_size , dec_ctx -> avc_ctx -> nal_ref_idc ,
127+ !dec_ctx -> avc_ctx -> cc_buffer_saved , dec_ctx -> avc_ctx -> is_hevc );
100128
101129 if (NAL_stop == NULL ) // remove_03emu failed.
102130 {
103131 mprint ("\rNotice: NAL of type %u had to be skipped because remove_03emu failed.\n" , nal_unit_type );
104132 return ;
105133 }
106134
107- if (nal_unit_type == CCX_NAL_TYPE_ACCESS_UNIT_DELIMITER_9 )
108- {
109- // Found Access Unit Delimiter
110- }
111- else if (nal_unit_type == CCX_NAL_TYPE_SEQUENCE_PARAMETER_SET_7 )
112- {
113- // Found sequence parameter set
114- // We need this to parse NAL type 1 (CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1)
115- dec_ctx -> avc_ctx -> num_nal_unit_type_7 ++ ;
116- seq_parameter_set_rbsp (dec_ctx -> avc_ctx , NAL_start + 1 , NAL_stop );
117- dec_ctx -> avc_ctx -> got_seq_para = 1 ;
118- }
119- else if (dec_ctx -> avc_ctx -> got_seq_para && (nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1 ||
120- nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_IDR_PICTURE )) // Only if nal_unit_type=1
135+ if (dec_ctx -> avc_ctx -> is_hevc )
121136 {
122- // Found coded slice of a non-IDR picture
123- // We only need the slice header data, no need to implement
124- // slice_layer_without_partitioning_rbsp( );
125- slice_header (enc_ctx , dec_ctx , NAL_start + 1 , NAL_stop , nal_unit_type , sub );
126- }
127- else if (dec_ctx -> avc_ctx -> got_seq_para && nal_unit_type == CCX_NAL_TYPE_SEI )
128- {
129- // Found SEI (used for subtitles)
130- // set_fts(ctx->timing); // FIXME - check this!!!
131- sei_rbsp (dec_ctx -> avc_ctx , NAL_start + 1 , NAL_stop );
137+ // HEVC NAL unit processing
138+ if (nal_unit_type == HEVC_NAL_VPS || nal_unit_type == HEVC_NAL_SPS || nal_unit_type == HEVC_NAL_PPS )
139+ {
140+ // Found HEVC parameter set - mark as having sequence params
141+ // We don't parse HEVC SPS fully, but we need to enable SEI processing
142+ dec_ctx -> avc_ctx -> got_seq_para = 1 ;
143+ }
144+ else if (nal_unit_type == HEVC_NAL_PREFIX_SEI || nal_unit_type == HEVC_NAL_SUFFIX_SEI )
145+ {
146+ // Found HEVC SEI (used for subtitles)
147+ // SEI payload format is similar to H.264
148+ sei_rbsp (dec_ctx -> avc_ctx , payload_start , NAL_stop );
149+ }
132150 }
133- else if ( dec_ctx -> avc_ctx -> got_seq_para && nal_unit_type == CCX_NAL_TYPE_PICTURE_PARAMETER_SET )
151+ else
134152 {
135- // Found Picture parameter set
153+ // H.264 NAL unit processing (original code)
154+ if (nal_unit_type == CCX_NAL_TYPE_ACCESS_UNIT_DELIMITER_9 )
155+ {
156+ // Found Access Unit Delimiter
157+ }
158+ else if (nal_unit_type == CCX_NAL_TYPE_SEQUENCE_PARAMETER_SET_7 )
159+ {
160+ // Found sequence parameter set
161+ // We need this to parse NAL type 1 (CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1)
162+ dec_ctx -> avc_ctx -> num_nal_unit_type_7 ++ ;
163+ seq_parameter_set_rbsp (dec_ctx -> avc_ctx , payload_start , NAL_stop );
164+ dec_ctx -> avc_ctx -> got_seq_para = 1 ;
165+ }
166+ else if (dec_ctx -> avc_ctx -> got_seq_para && (nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1 ||
167+ nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_IDR_PICTURE ))
168+ {
169+ // Found coded slice of a non-IDR picture
170+ // We only need the slice header data
171+ slice_header (enc_ctx , dec_ctx , payload_start , NAL_stop , nal_unit_type , sub );
172+ }
173+ else if (dec_ctx -> avc_ctx -> got_seq_para && nal_unit_type == CCX_NAL_TYPE_SEI )
174+ {
175+ // Found SEI (used for subtitles)
176+ sei_rbsp (dec_ctx -> avc_ctx , payload_start , NAL_stop );
177+ }
178+ else if (dec_ctx -> avc_ctx -> got_seq_para && nal_unit_type == CCX_NAL_TYPE_PICTURE_PARAMETER_SET )
179+ {
180+ // Found Picture parameter set
181+ }
136182 }
183+
137184 if (temp_debug )
138185 {
139- int len = NAL_stop - ( NAL_start + 1 ) ;
186+ int len = NAL_stop - payload_start ;
140187 dbg_print (CCX_DMT_VIDES , "\n After decoding, the actual thing was (length =%d)\n" , len );
141- dump (CCX_DMT_VIDES , NAL_start + 1 , len > 160 ? 160 : len , 0 , 0 );
188+ dump (CCX_DMT_VIDES , payload_start , len > 160 ? 160 : len , 0 , 0 );
142189 }
143190
144191 dvprint ("END NAL unit type: %d length %d ref_idc: %d - Buffered captions after: %d\n" ,
145- nal_unit_type , NAL_stop - NAL_start - 1 , dec_ctx -> avc_ctx -> nal_ref_idc , !dec_ctx -> avc_ctx -> cc_buffer_saved );
192+ nal_unit_type , NAL_stop - NAL_start - nal_header_size , dec_ctx -> avc_ctx -> nal_ref_idc , !dec_ctx -> avc_ctx -> cc_buffer_saved );
146193}
147194
148195// Process inbuf bytes in buffer holding and AVC (H.264) video stream.
0 commit comments