You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	Parse NAL units in H264 parser.
Patch by Ivan Schreter, schreter gmx net Originally committed as revision 17488 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
				
					committed by
					
						 Carl Eugen Hoyos
						Carl Eugen Hoyos
					
				
			
			
				
	
			
			
			
						parent
						
							1790a5e908
						
					
				
				
					commit
					ff6474dd15
				
			| @@ -27,6 +27,8 @@ | |||||||
|  |  | ||||||
| #include "parser.h" | #include "parser.h" | ||||||
| #include "h264_parser.h" | #include "h264_parser.h" | ||||||
|  | #include "h264data.h" | ||||||
|  | #include "golomb.h" | ||||||
|  |  | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
|  |  | ||||||
| @@ -96,6 +98,73 @@ found: | |||||||
|     return i-(state&5); |     return i-(state&5); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * Parse NAL units of found picture and decode some basic information. | ||||||
|  |  * | ||||||
|  |  * @param s parser context. | ||||||
|  |  * @param avctx codec context. | ||||||
|  |  * @param buf buffer with field/frame data. | ||||||
|  |  * @param buf_size size of the buffer. | ||||||
|  |  */ | ||||||
|  | static inline int parse_nal_units(AVCodecParserContext *s, | ||||||
|  |                                   AVCodecContext *avctx, | ||||||
|  |                                   const uint8_t *buf, int buf_size) | ||||||
|  | { | ||||||
|  |     H264Context *h = s->priv_data; | ||||||
|  |     const uint8_t *buf_end = buf + buf_size; | ||||||
|  |     unsigned int slice_type; | ||||||
|  |     int state; | ||||||
|  |     const uint8_t *ptr; | ||||||
|  |  | ||||||
|  |     /* set some sane default values */ | ||||||
|  |     s->pict_type = FF_I_TYPE; | ||||||
|  |  | ||||||
|  |     h->s.avctx= avctx; | ||||||
|  |  | ||||||
|  |     for(;;) { | ||||||
|  |         int src_length, dst_length, consumed; | ||||||
|  |         buf = ff_find_start_code(buf, buf_end, &state); | ||||||
|  |         if(buf >= buf_end) | ||||||
|  |             break; | ||||||
|  |         --buf; | ||||||
|  |         src_length = buf_end - buf; | ||||||
|  |         switch (state & 0x1f) { | ||||||
|  |         case NAL_SLICE: | ||||||
|  |         case NAL_IDR_SLICE: | ||||||
|  |             // Do not walk the whole buffer just to decode slice header | ||||||
|  |             if (src_length > 20) | ||||||
|  |                 src_length = 20; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); | ||||||
|  |         if (ptr==NULL || dst_length < 0) | ||||||
|  |             break; | ||||||
|  |  | ||||||
|  |         init_get_bits(&h->s.gb, ptr, 8*dst_length); | ||||||
|  |         switch(h->nal_unit_type) { | ||||||
|  |         case NAL_SPS: | ||||||
|  |             ff_h264_decode_seq_parameter_set(h); | ||||||
|  |             break; | ||||||
|  |         case NAL_PPS: | ||||||
|  |             ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits); | ||||||
|  |             break; | ||||||
|  |         case NAL_SEI: | ||||||
|  |             ff_h264_decode_sei(h); | ||||||
|  |             break; | ||||||
|  |         case NAL_IDR_SLICE: | ||||||
|  |         case NAL_SLICE: | ||||||
|  |             get_ue_golomb(&h->s.gb);  // skip first_mb_in_slice | ||||||
|  |             slice_type = get_ue_golomb_31(&h->s.gb); | ||||||
|  |             s->pict_type = golomb_to_pict_type[slice_type % 5]; | ||||||
|  |             return 0; /* no need to evaluate the rest */ | ||||||
|  |         } | ||||||
|  |         buf += consumed; | ||||||
|  |     } | ||||||
|  |     /* didn't find a picture! */ | ||||||
|  |     av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n"); | ||||||
|  |     return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int h264_parse(AVCodecParserContext *s, | static int h264_parse(AVCodecParserContext *s, | ||||||
|                       AVCodecContext *avctx, |                       AVCodecContext *avctx, | ||||||
|                       const uint8_t **poutbuf, int *poutbuf_size, |                       const uint8_t **poutbuf, int *poutbuf_size, | ||||||
| @@ -120,6 +189,8 @@ static int h264_parse(AVCodecParserContext *s, | |||||||
|             assert(pc->last_index + next >= 0 ); |             assert(pc->last_index + next >= 0 ); | ||||||
|             ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state |             ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         parse_nal_units(s, avctx, buf, buf_size); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     *poutbuf = buf; |     *poutbuf = buf; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user