root/branches/perian-1.1/bitstream_info.c

Revision 947, 24.0 kB (checked in by gbooker, 1 week ago)

Work around rdar 4870661 (gdb "failed internal consistency check" when dead code stripping in use)

Line 
1 /*
2  *  bitstream_info.c
3  *  Perian
4  *
5  *  Created by Graham Booker on 1/6/07.
6  *  Copyright 2007 Graham Booker. All rights reserved.
7  *
8  */
9
10 #include "bitstream_info.h"
11
12 #include <AudioToolbox/AudioToolbox.h>
13 #include <QuickTime/QuickTime.h>
14
15 #import "ac3tab.h"
16 //ffmpeg's struct Picture conflicts with QuickDraw's
17 #define Picture MPEGPICTURE
18
19 #include "avcodec.h"
20
21 #include "bswap.h"
22 #include "mpegvideo.h"
23 #include "parser.h"
24 #include "golomb.h"
25
26 #include "CodecIDs.h"
27
28 int inline MININT(int a, int b)
29 {
30         return a < b ? a : b;
31 }
32
33 static const int nfchans_tbl[8] = { 2, 1, 2, 3, 3, 4, 4, 5 };
34 static const int ac3_layout_no_lfe[8] = {
35         kAudioChannelLayoutTag_Stereo,
36         kAudioChannelLayoutTag_Mono,
37         kAudioChannelLayoutTag_Stereo,
38         kAudioChannelLayoutTag_ITU_3_0,
39         kAudioChannelLayoutTag_ITU_2_1,
40         kAudioChannelLayoutTag_ITU_3_1,
41         kAudioChannelLayoutTag_ITU_2_2,
42         kAudioChannelLayoutTag_ITU_3_2};
43
44 static const int ac3_layout_lfe[8] = {
45         kAudioChannelLayoutTag_DVD_4,
46         kAudioChannelLayoutTag_Mono,  //No layout for this, hopefully we never have it
47         kAudioChannelLayoutTag_DVD_4,
48         kAudioChannelLayoutTag_DVD_10,
49         kAudioChannelLayoutTag_DVD_5,
50         kAudioChannelLayoutTag_DVD_11,
51         kAudioChannelLayoutTag_DVD_6,
52         kAudioChannelLayoutTag_ITU_3_2_1};
53
54 static const uint16_t ac3_freqs[3] = { 48000, 44100, 32000 };
55 static const uint16_t ac3_bitratetab[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640};
56 static const uint8_t ac3_halfrate[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
57
58 /* From: http://svn.mplayerhq.hu/ac3/ (LGPL)
59  * Synchronize to ac3 bitstream.
60  * This function searches for the syncword '0xb77'.
61  *
62  * @param buf Pointer to "probable" ac3 bitstream buffer
63  * @param buf_size Size of buffer
64  * @return Returns the position where syncword is found, -1 if no syncword is found
65  */
66 static int ac3_synchronize(uint8_t *buf, int buf_size)
67 {
68     int i;
69        
70     for (i = 0; i < buf_size - 1; i++)
71         if (buf[i] == 0x0b && buf[i + 1] == 0x77)
72             return i;
73        
74     return -1;
75 }
76
77 /* A lot of this was stolen from: http://svn.mplayerhq.hu/ac3/ (LGPL)
78  * Fill info from an ac3 stream
79  *
80  * @param asdb Pointer to the AudioStreamBasicDescription to fill
81  * @param acl Pointer to the AudioChannelLayout to fill
82  * @param buffer Pointer to the buffer data to scan
83  * @param buff_size Size of the buffer
84  * @return 1 if successfull, 0 otherwise
85  */
86
87 int parse_ac3_bitstream(AudioStreamBasicDescription *asbd, AudioChannelLayout *acl, uint8_t *buffer, int buff_size)
88 {
89         int offset = ac3_synchronize(buffer, buff_size);
90         if(offset == -1)
91                 return 0;
92        
93         if(buff_size < offset + 7)
94                 return 0;
95        
96         uint8_t fscod_and_frmsizecod = buffer[offset + 4];
97        
98         uint8_t fscod = fscod_and_frmsizecod >> 6;
99         uint8_t frmsizecod = fscod_and_frmsizecod & 0x3f;
100         if(frmsizecod >= 38)
101                 return 0;
102        
103         uint8_t bsid = buffer[offset + 5] >> 3;
104         if(bsid >= 0x12)
105                 return 0;
106        
107         uint8_t acmod = buffer[offset + 6] >> 5;
108         uint8_t shift = 4;
109         if(acmod & 0x01 && acmod != 0x01)
110                 shift -= 2;
111         if(acmod & 0x04)
112                 shift -= 2;
113         if(acmod == 0x02)
114                 shift -= 2;
115         uint8_t lfe = (buffer[offset + 6] >> shift) & 0x01;
116        
117         /* This is a valid frame!!! */
118         uint16_t bitrate = ac3_bitratetab[frmsizecod >> 1];
119         uint8_t half = ac3_halfrate[bsid];
120         int sample_rate = ac3_freqs[fscod] >> half;
121         int framesize = 0;
122         switch (fscod) {
123                 case 0:
124                         framesize = 4 * bitrate;
125                         break;
126                 case 1:
127                         framesize = (320 * bitrate / 147 + (frmsizecod & 1 ? 1 : 0)) * 2;
128                         break;
129                 case 2:
130                         framesize = 6 * bitrate;
131                         break;
132                 default:
133                         break;
134         }
135        
136         shift = 0;
137         if(bsid > 8)
138                 shift = bsid - 8;
139        
140         /* Setup the AudioStreamBasicDescription and AudioChannelLayout */
141         memset(asbd, 0, sizeof(AudioStreamBasicDescription));
142         asbd->mSampleRate = sample_rate >> shift;
143         if(offset == 0 && buff_size == framesize)
144                 asbd->mFormatID = kAudioFormatAC3;
145         else
146                 asbd->mFormatID = kAudioFormatAC3MS;
147         asbd->mChannelsPerFrame = nfchans_tbl[acmod] + lfe;
148        
149         memset(acl, 0, sizeof(AudioChannelLayout));
150         if(lfe)
151                 acl->mChannelLayoutTag = ac3_layout_lfe[acmod];
152         else
153                 acl->mChannelLayoutTag = ac3_layout_no_lfe[acmod];
154        
155         return 1;
156 }
157
158 static int parse_mpeg4_extra(FFusionParserContext *parser, const uint8_t *buf, int buf_size)
159 {
160         ParseContext1 *pc1 = (ParseContext1 *)parser->pc->priv_data;
161         pc1->pc.frame_start_found = 0;
162        
163         MpegEncContext *s = pc1->enc;
164         GetBitContext gb1, *gb = &gb1;
165        
166         s->avctx = parser->avctx;
167         s->current_picture_ptr = &s->current_picture;
168        
169         init_get_bits(gb, buf, 8 * buf_size);
170         ff_mpeg4_decode_picture_header(s, gb);
171         return 1;
172 }
173
174 /*
175  * Long story short, FFMpeg's parsers suck for our use.  This function parses an mpeg4 bitstream,
176  * and assumes that it is given at least a full frame of data.
177  * @param parser A FFusionParserContext structure containg all our info
178  * @param buf The buffer to parse
179  * @param buf_size Size of the input buffer
180  * @param out_buf_size The number of bytes present in the first frame of data
181  * @param type The frame Type: FF_*_TYPE
182  * @param pts The PTS of the frame
183  * @return 1 if a frame is found, 0 otherwise
184  */
185 static int parse_mpeg4_stream(FFusionParserContext *parser, const uint8_t *buf, int buf_size, int *out_buf_size, int *type, int *skippable)
186 {
187         ParseContext1 *pc1 = (ParseContext1 *)parser->pc->priv_data;
188         pc1->pc.frame_start_found = 0;
189        
190         int endOfFrame = ff_mpeg4_find_frame_end(&(pc1->pc), buf, buf_size);
191        
192         MpegEncContext *s = pc1->enc;
193         GetBitContext gb1, *gb = &gb1;
194        
195         s->avctx = parser->avctx;
196         s->current_picture_ptr = &s->current_picture;
197        
198         init_get_bits(gb, buf, 8 * buf_size);
199         if(ff_mpeg4_decode_picture_header(s, gb) != 0)
200                 return 0;
201        
202         *type = s->pict_type;
203         *skippable = (*type == FF_B_TYPE);
204 #if 0 /*this was an attempt to figure out the PTS information and detect an out of order P frame before we hit its B frame */
205         int64_t *lastPtsPtr = (int64_t *)parser->internalContext;
206         int64_t lastPts = *lastPtsPtr;
207         int64_t currentPts = s->current_picture.pts;
208        
209         switch(s->pict_type)
210         {
211                 case FF_I_TYPE:
212                         *lastPtsPtr = currentPts;
213                         *precedesAPastFrame = 0;
214                         break;
215                 case FF_P_TYPE:
216                         if(currentPts > lastPts + 1)
217                                 *precedesAPastFrame = 1;
218                         else
219                                 *precedesAPastFrame = 0;
220                         *lastPtsPtr = currentPts;
221                         break;
222                 case FF_B_TYPE:
223                         *precedesAPastFrame = 0;
224                         break;
225                 default:
226                         break;
227         }
228 #endif
229        
230         if(endOfFrame == END_NOT_FOUND)
231                 *out_buf_size = buf_size;
232         else
233                 *out_buf_size = endOfFrame;
234         return 1;
235 }
236
237 extern AVCodecParser mpeg4video_parser;
238
239 FFusionParser ffusionMpeg4VideoParser = {
240         &mpeg4video_parser,
241         sizeof(uint64_t),
242         NULL,
243         parse_mpeg4_extra,
244         parse_mpeg4_stream,
245 };
246
247 typedef struct H264ParserContext_s
248 {
249         int is_avc;
250         int nal_length_size;
251         int prevPts;
252        
253         int poc_type;
254         int log2_max_frame_num;
255         int frame_mbs_only_flag;
256         int pic_order_present_flag;
257
258         int log2_max_poc_lsb;
259         int poc_msb;
260         int prev_poc_lsb;
261
262         int delta_pic_order_always_zero_flag;
263         int offset_for_non_ref_pic;
264         int num_ref_frames_in_pic_order_cnt_cycle;
265         int sum_of_offset_for_ref_frames;
266        
267         int chroma_format_idc;
268 }H264ParserContext;
269
270 static int decode_nal(const uint8_t *buf, int buf_size, uint8_t *out_buf, int *out_buf_size, int *type, int *nal_ref_idc)
271 {
272         int i;
273         int outIndex = 0;
274         int numNulls = 0;
275        
276         for(i=1; i<buf_size; i++)
277         {
278                 if(buf[i] == 0)
279                         numNulls++;
280                 else if(numNulls == 2)
281                 {
282                         numNulls = 0;
283                         if(buf[i] < 3)
284                         {
285                                 /* end of nal */
286                                 outIndex -= 2;
287                                 break;
288                         }
289                         else if(buf[i] == 3)
290                                 /* This is just a simple escape of 0x00 00 03 */
291                                 continue;
292                 }
293                 out_buf[outIndex] = buf[i];
294                 outIndex++;
295         }
296        
297         if(outIndex <= 0)
298                 return 0;
299        
300         *type = buf[0] & 0x1f;
301         *nal_ref_idc = (buf[0] >> 5) & 0x03;
302         *out_buf_size = outIndex;
303         return 1;
304 }
305
306 static void skip_scaling_list(GetBitContext *gb, int size){
307         int i, next = 8, last = 8;
308        
309     if(get_bits1(gb)) /* matrix not written, we use the predicted one */
310                 for(i=0;i<size;i++){
311                         if(next)
312                                 next = (last + get_se_golomb(gb)) & 0xff;
313                         if(!i && !next){ /* matrix not written, we use the preset one */
314                                 break;
315                         }
316                         last = next ? next : last;
317                 }
318 }
319
320 static void skip_scaling_matrices(GetBitContext *gb){
321     if(get_bits1(gb)){
322         skip_scaling_list(gb, 16); // Intra, Y
323         skip_scaling_list(gb, 16); // Intra, Cr
324         skip_scaling_list(gb, 16); // Intra, Cb
325         skip_scaling_list(gb, 16); // Inter, Y
326         skip_scaling_list(gb, 16); // Inter, Cr
327         skip_scaling_list(gb, 16); // Inter, Cb
328                 skip_scaling_list(gb, 64);  // Intra, Y
329                 skip_scaling_list(gb, 64);  // Inter, Y
330         }
331 }
332
333 static void decode_sps(H264ParserContext *context, const uint8_t *buf, int buf_size)
334 {
335         GetBitContext getbit, *gb = &getbit;
336         int profile_idc;
337        
338         init_get_bits(gb, buf, 8 * buf_size);
339     profile_idc= get_bits(gb, 8);
340     get_bits1(gb);              //constraint_set0_flag
341     get_bits1(gb);              //constraint_set1_flag
342     get_bits1(gb);              //constraint_set2_flag
343     get_bits1(gb);              //constraint_set3_flag
344     get_bits(gb, 4);    //reserved
345         get_bits(gb, 8);        //level_idc
346         get_ue_golomb(gb);      //seq_parameter_set_id
347         if(profile_idc >= 100)
348         {
349                 context->chroma_format_idc = get_ue_golomb(gb);
350                 //high profile
351                 if(context->chroma_format_idc == 3)     //chroma_format_idc
352                         get_bits1(gb);                  //residual_color_transfrom_flag
353                 get_ue_golomb(gb);                      //bit_depth_luma_minus8
354                 get_ue_golomb(gb);                      //bit_depth_chroma_minus8
355                 get_bits1(gb);                          //transform_bypass
356                 skip_scaling_matrices(gb);
357         }
358         context->log2_max_frame_num = get_ue_golomb(gb) + 4;
359         context->poc_type = get_ue_golomb(gb);
360         if(context->poc_type == 0)
361                 context->log2_max_poc_lsb = get_ue_golomb(gb) + 4;
362         else if(context->poc_type == 1)
363         {
364                 int i;
365                
366                 context->delta_pic_order_always_zero_flag = get_bits1(gb);
367                 context->offset_for_non_ref_pic = get_se_golomb(gb);
368                 get_se_golomb(gb);      //offset_for_top_to_bottom_field
369                 context->num_ref_frames_in_pic_order_cnt_cycle = get_ue_golomb(gb);
370                 context->sum_of_offset_for_ref_frames = 0;
371                 for(i=0; i<context->num_ref_frames_in_pic_order_cnt_cycle; i++)
372                         context->sum_of_offset_for_ref_frames += get_se_golomb(gb); //offset_for_ref_frame[i]
373         }
374         get_ue_golomb(gb);      //num_ref_frames
375         get_bits1(gb);          //gaps_in_frame_num_value_allowed_flag
376         get_ue_golomb(gb);      //pic_width_in_mbs_minus1
377         get_ue_golomb(gb);      //pic_height_in_map_units_minus1
378         context->frame_mbs_only_flag = get_bits1(gb);
379 }
380
381 static void decode_pps(H264ParserContext *context, const uint8_t *buf, int buf_size)
382 {
383         GetBitContext getbit, *gb = &getbit;
384        
385         init_get_bits(gb, buf, 8 * buf_size);
386         get_ue_golomb(gb); //pic_parameter_set_id
387         get_ue_golomb(gb); //seq_parameter_set_id
388         get_bits1(gb); //entropy_coding_mode_flag
389         context->pic_order_present_flag = get_bits1(gb);
390 }
391
392 static int inline decode_slice_header(H264ParserContext *context, const uint8_t *buf, int buf_size, int nal_ref_idc, int nal_type, int just_type, int *type, int *pts)
393 {
394         GetBitContext getbit, *gb = &getbit;
395         int slice_type;
396         int field_pic_flag = 0;
397         int bottom_field_flag = 0;
398         int frame_number;
399 //      static const uint8_t slice_type_map[5] = {FF_P_TYPE, FF_B_TYPE, FF_I_TYPE, FF_SP_TYPE, FF_SI_TYPE};
400         static const uint8_t slice_type_map[5] = {FF_P_TYPE, FF_P_TYPE, FF_I_TYPE, FF_SP_TYPE, FF_SI_TYPE};
401        
402         init_get_bits(gb, buf, 8 * buf_size);
403        
404         get_ue_golomb(gb);      //first_mb_in_slice
405         slice_type = get_ue_golomb(gb);
406         if(slice_type > 9)
407                 return 0;
408        
409         if(slice_type > 4)
410                 slice_type -= 5;
411        
412         *type = slice_type_map[slice_type];
413         if(just_type)
414                 return 1;
415        
416         get_ue_golomb(gb); //pic_parameter_set_id
417         frame_number = get_bits(gb, context->log2_max_frame_num);
418         if(!context->frame_mbs_only_flag)
419         {
420                 field_pic_flag = get_bits1(gb);
421                 if(field_pic_flag)
422                 {
423                         bottom_field_flag = get_bits1(gb);
424                 }
425         }
426         if(nal_type == 5)
427                 get_ue_golomb(gb);  //idr_pic_id
428         if(context->poc_type == 0)
429         {
430                 int pts_lsb = get_bits(gb, context->log2_max_poc_lsb);
431                 int delta_pic_order_cnt_bottom = 0;
432                 int maxPicOrderCntLsb = 1 << context->log2_max_poc_lsb;
433                 int pic_order_msb;
434                
435                 if(context->pic_order_present_flag && !field_pic_flag)
436                         delta_pic_order_cnt_bottom = get_se_golomb(gb);
437                 if((pts_lsb < context->prev_poc_lsb) && (context->prev_poc_lsb - pts_lsb) >= maxPicOrderCntLsb)
438                         pic_order_msb = context->poc_msb + maxPicOrderCntLsb;
439                 else if((pts_lsb > context->prev_poc_lsb) && (pts_lsb - context->prev_poc_lsb) > maxPicOrderCntLsb)
440                         pic_order_msb = context->poc_msb - maxPicOrderCntLsb;
441                 else
442                         pic_order_msb = context->poc_msb;
443                
444                 context->poc_msb = pic_order_msb;
445                
446                 *pts = pic_order_msb + pts_lsb;
447                 if(delta_pic_order_cnt_bottom < 0)
448                         *pts += delta_pic_order_cnt_bottom;
449                        
450         }
451         else if(context->poc_type == 1 && !context->delta_pic_order_always_zero_flag)
452         {
453                 int delta_pic_order_cnt[2] = {0, 0};
454                 delta_pic_order_cnt[0] = get_se_golomb(gb);
455                 if(context->pic_order_present_flag && !field_pic_flag)
456                         delta_pic_order_cnt[1] = get_se_golomb(gb);
457                
458                 int frame_num_offset = 0;  //I think this is wrong, but the pts code isn't used anywhere, so no harm yet and this removes a warning.
459                
460                 int abs_frame_num = 0;
461                 int num_ref_frames_in_pic_order_cnt_cycle = context->num_ref_frames_in_pic_order_cnt_cycle;
462                 if(num_ref_frames_in_pic_order_cnt_cycle != 0)
463                         abs_frame_num = frame_num_offset + frame_number;
464                
465                 if(nal_ref_idc == 0 && abs_frame_num > 0)
466                         abs_frame_num--;
467                
468                 int expected_delta_per_poc_cycle = context->sum_of_offset_for_ref_frames;
469                 int expectedpoc = 0;
470                 if(abs_frame_num > 0)
471                 {
472                         int poc_cycle_cnt = (abs_frame_num - 1) / num_ref_frames_in_pic_order_cnt_cycle;
473                        
474                         expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle + context->sum_of_offset_for_ref_frames;
475                 }
476                
477                 if(nal_ref_idc == 0)
478                         expectedpoc = expectedpoc + context->offset_for_non_ref_pic;
479                 *pts = expectedpoc + delta_pic_order_cnt[0];
480         }
481        
482         return 1;
483 }
484
485 #define NAL_PEEK_SIZE 32
486
487 static int inline decode_nals(H264ParserContext *context, const uint8_t *buf, int buf_size, int *type, int *skippable)
488 {
489         int nalsize = 0;
490         int buf_index = 0;
491         int ret = 0;
492         int pts_decoded = 0;
493         int lowestType = 20;
494        
495         *skippable = 1;
496        
497 #if 0 /*this was an attempt to figure out the PTS information and detect an out of order P frame before we hit its B frame */
498         if(context->poc_type == 2)
499         {
500                 //decode and display order are the same
501                 pts_decoded = 1;
502                 *precedesAPastFrame = 0;
503         }
504 #endif
505        
506         for(;;)
507         {
508                 if(context->is_avc)
509                 {
510                         if(buf_index >= buf_size)
511                                 break;
512                         nalsize = 0;
513                         switch (context->nal_length_size) {
514                                 case 1:
515                                         nalsize = buf[buf_index];
516                                         buf_index++;
517                                         break;
518                                 case 2:
519                                         nalsize = (buf[buf_index] << 8) | buf[buf_index+1];
520                                         buf_index += 2;
521                                         break;
522                                 case 3:
523                                         nalsize = (buf[buf_index] << 16) | (buf[buf_index+1] << 8) | buf[buf_index + 2];
524                                         buf_index += 3;
525                                         break;
526                                 case 4:
527                                         nalsize = (buf[buf_index] << 24) | (buf[buf_index+1] << 16) | (buf[buf_index + 2] << 8) | buf[buf_index + 3];
528                                         buf_index += 4;
529                                         break;
530                                 default:
531                                         break;
532                         }
533                         if(nalsize <= 1 || nalsize > buf_size)
534                         {
535                                 if(nalsize == 1)
536                                 {
537                                         buf_index++;
538                                         continue;
539                                 }
540                                 else
541                                         break;
542                         }
543                 }
544                 else
545                 {
546                         int num_nuls = 0;
547                         int start_offset = 0;
548                         //do start code prefix search
549                         for(; buf_index < buf_size; buf_index++)
550                         {
551                                 if(buf[buf_index] == 0)
552                                         num_nuls++;
553                                 else
554                                 {
555                                         if(num_nuls >= 2 && buf[buf_index] == 1)
556                                                 break;
557                                         num_nuls = 0;
558                                 }
559                         }
560                         start_offset = buf_index + 1;
561                         //do start code prefix search
562                         for(buf_index++; buf_index < buf_size; buf_index++)
563                         {
564                                 if(buf[buf_index] == 0)
565                                 {
566                                         if(num_nuls == 2)
567                                                 break;
568                                         num_nuls++;
569                                 }
570                                 else
571                                 {
572                                         if(num_nuls == 2 && buf[buf_index] == 1)
573                                                 break;
574                                         num_nuls = 0;
575                                 }
576                         }
577                         if(start_offset >= buf_size)
578                                 //no more
579                                 break;
580                         nalsize = buf_index - start_offset;
581                         if(buf_index < buf_size)
582                                 //Take off the next NAL's startcode
583                                 nalsize -= 2;
584                         //skip the start code
585                         buf_index = start_offset;
586                 }
587
588                 uint8_t partOfNal[NAL_PEEK_SIZE];
589                 int decodedNalSize, nalType;
590                 int nal_ref_idc;
591                 int slice_type = 0;
592                
593                 if(decode_nal(buf + buf_index, MININT(nalsize, NAL_PEEK_SIZE), partOfNal, &decodedNalSize, &nalType, &nal_ref_idc))
594                 {
595                         int pts = 0;
596                         if(nalType == 1 || nalType == 2)
597                         {
598                                 if(decode_slice_header(context, partOfNal, decodedNalSize, nal_ref_idc, nalType, pts_decoded, &slice_type, &pts))
599                                 {
600                                         ret = 1;
601                                         if(slice_type < lowestType)
602                                                 lowestType = slice_type;
603                                         if(nal_ref_idc)
604                                                 *skippable = 0;
605                                         if(pts_decoded == 0)
606                                         {
607                                                 pts_decoded = 1;
608                                                 if(pts > context->prevPts)
609                                                 {
610                                                         if(pts < context->prevPts)
611                                                                 lowestType = FF_B_TYPE;
612                                                         context->prevPts = pts;
613                                                 }
614                                         }
615                                 }
616                                
617                                 // Parser users assume I-frames are IDR-frames
618                                 // but in H.264 they don't have to be.
619                                 // Mark these as P-frames if they effectively are.
620                                 if (lowestType == FF_I_TYPE) lowestType = FF_P_TYPE;
621                         }
622                         else if(nalType == 5)
623                         {
624                                 ret = 1;
625 #if 0 /*this was an attempt to figure out the PTS information and detect an out of order P frame before we hit its B frame */
626                                 context->prev_poc_lsb = 0;
627                                 context->poc_msb = 0;
628                                 context->prevPts = 0;
629                                 *precedesAPastFrame = 0;
630 #endif
631                                 *skippable = 0;
632                                 lowestType = FF_I_TYPE;
633                         }
634                 }
635                 buf_index += nalsize;
636         }
637         if(lowestType != 20)
638                 *type = lowestType;
639        
640         return ret;
641 }
642
643 /*
644  * This function parses an h.264 bitstream, and assumes that it is given at least a full frame of data.
645  * @param parser A FFusionParserContext structure containg all our info
646  * @param buf The buffer to parse
647  * @param buf_size Size of the input buffer
648  * @param out_buf_size The number of bytes present in the first frame of data
649  * @param type The frame Type: FF_*_TYPE
650  * @param pts The PTS of the frame
651  * @return 1 if a frame is found, 0 otherwise
652  */
653 static int parse_h264_stream(FFusionParserContext *parser, const uint8_t *buf, int buf_size, int *out_buf_size, int *type, int *skippable)
654 {
655         int endOfFrame;
656         int size = 0;
657         const uint8_t *parseBuf = buf;
658         int parseSize;
659
660         /*
661          * Somehow figure out of frame type
662          * For our use, a frame with any B slices is a B frame, and then a frame with any P slices is a P frame.
663          * An I frame has only I slices.
664          * I expect this involves a NAL decoder, and then look at the slice types.
665          * Nal is a f(1) always set to 0, u(2) of nal_ref_idc, and then u(5) of nal_unit_type.
666          * Nal types 1, 2 start a non-I frame, and type 5 starts an I frame.  Each start with a slice header.
667          * Slice header has a ue(v) for first_mb_in_slice and then a ue(v) for the slice_type
668          * Slice types 0, 5 are P, 1, 6 are B, 2, 7 are I
669          */
670        
671         do
672         {
673                 parseBuf = parseBuf + size;
674                 parseSize = buf_size - size;
675                 endOfFrame = (parser->parserStructure->avparse->split)(parser->avctx, parseBuf, parseSize);
676                 if(endOfFrame == 0)
677                         size = buf_size;
678                 else
679                 {
680                         size += endOfFrame;
681                         parseSize = endOfFrame;
682                 }
683         }while(decode_nals(parser->internalContext, parseBuf, parseSize, type, skippable) == 0 && size < buf_size);
684                
685         *out_buf_size = size;
686         return 1;
687 }
688
689 static int init_h264_parser(FFusionParserContext *parser)
690 {
691         H264ParserContext *context = parser->internalContext;
692        
693         context->nal_length_size = 2;
694         context->is_avc = 0;
695         return 1;
696 }
697
698 static int parse_extra_data_h264(FFusionParserContext *parser, const uint8_t *buf, int buf_size)
699 {
700         H264ParserContext *context = parser->internalContext;
701         const uint8_t *cur = buf;
702         int count, i, type, ref;
703        
704         context->is_avc = 1;
705         count = *(cur+5) & 0x1f;
706         cur += 6;
707         for (i=0; i<count; i++)
708         {
709                 int size = AV_RB16(cur);
710                 int out_size = 0;
711                 uint8_t *decoded = malloc(size);
712                 if(decode_nal(cur + 2, size, decoded, &out_size, &type, &ref))
713                         decode_sps(context, decoded, out_size);
714                 cur += size + 2;
715                 free(decoded);
716         }
717         count = *(cur++);
718         for (i=0; i<count; i++)
719         {
720                 int size = AV_RB16(cur);
721                 int out_size = 0;
722                 uint8_t *decoded = malloc(size);
723                 if(decode_nal(cur + 2, size, decoded, &out_size, &type, &ref))
724                         decode_pps(context, decoded, out_size);
725                 cur += size + 2;
726                 free(decoded);
727         }
728        
729         context->nal_length_size = ((*(buf+4)) & 0x03) + 1;
730        
731         return 1;
732 }
733
734 extern AVCodecParser h264_parser;
735
736 FFusionParser ffusionH264Parser = {
737         &h264_parser,
738         sizeof(H264ParserContext),
739         init_h264_parser,
740         parse_extra_data_h264,
741         parse_h264_stream,
742 };
743
744 FFusionParser *ffusionFirstParser = NULL;
745
746 void registerFFusionParsers(FFusionParser *parser)
747 {
748     parser->next = ffusionFirstParser;
749     ffusionFirstParser = parser;
750 }
751
752 void initFFusionParsers()
753 {
754         static Boolean inited = FALSE;
755         if(inited == FALSE)
756         {
757                 inited = TRUE;
758                 registerFFusionParsers(&ffusionMpeg4VideoParser);
759                 registerFFusionParsers(&ffusionH264Parser);
760         }
761 }
762
763 void freeFFusionParser(FFusionParserContext *parser)
764 {
765         if(parser->pc)
766         {
767                 if(parser->pc->priv_data)
768                         av_free(parser->pc->priv_data);
769                 av_free(parser->pc);
770         }
771         if(parser->avctx)
772                 av_free(parser->avctx);
773         if(parser->internalContext)
774                 av_free(parser->internalContext);
775         free(parser);
776 }
777
778 FFusionParserContext *ffusionParserInit(int codec_id)
779 {
780     AVCodecParserContext *s;
781     AVCodecParser *parser;
782         FFusionParser *ffParser;
783     int ret;
784         struct AVCodecContext *ctx = avcodec_alloc_context();
785        
786     if(codec_id == CODEC_ID_NONE)
787         return NULL;
788        
789         if (!ffusionFirstParser) initFFusionParsers();
790        
791     for(ffParser = ffusionFirstParser; ffParser != NULL; ffParser = ffParser->next) {
792                 parser = ffParser->avparse;
793         if (parser->codec_ids[0] == codec_id ||
794             parser->codec_ids[1] == codec_id ||
795             parser->codec_ids[2] == codec_id ||
796             parser->codec_ids[3] == codec_id ||
797             parser->codec_ids[4] == codec_id)
798             goto found;
799     }
800     return NULL;
801 found:
802         s = av_mallocz(sizeof(AVCodecParserContext));
803     if (!s)
804         return NULL;
805     s->parser = parser;
806     s->priv_data = av_mallocz(parser->priv_data_size);
807     if (!s->priv_data) {
808         av_free(s);
809         return NULL;
810     }
811     if (parser->parser_init) {
812         ret = parser->parser_init(s);
813         if (ret != 0) {
814             av_free(s->priv_data);
815             av_free(s);
816             return NULL;
817         }
818     }
819     s->fetch_timestamp=1;
820         s->flags |= PARSER_FLAG_COMPLETE_FRAMES;
821        
822         FFusionParserContext *parserContext = malloc(sizeof(FFusionParserContext));
823         parserContext->avctx = ctx;
824         parserContext->pc = s;
825         parserContext->parserStructure = ffParser;
826         if(ffParser->internalContextSize)
827                 parserContext->internalContext = av_mallocz(ffParser->internalContextSize);
828         else
829                 parserContext->internalContext = NULL;
830         if(ffParser->init)
831                 (ffParser->init)(parserContext);
832     return parserContext;
833 }
834
835 /*
836  * @param parser FFusionParserContext pointer
837  * @param buf The buffer to parse
838  * @param buf_size Size of the input buffer
839  * @return 1 if successful, 0 otherwise
840  */
841  int ffusionParseExtraData(FFusionParserContext *parser, const uint8_t *buf, int buf_size)
842 {
843          if(parser->parserStructure->extra_data)
844                  return (parser->parserStructure->extra_data)(parser, buf, buf_size);
845          return 1;       
846 }
847
848 /*
849  * @param parser FFusionParserContext pointer
850  * @param buf The buffer to parse
851  * @param buf_size Size of the input buffer
852  * @param out_buf_size The number of bytes present in the first frame of data
853  * @param type The frame Type: FF_*_TYPE
854  * @param pts The PTS of the frame
855  * @return 1 if a frame is found, 0 otherwise
856  */
857 int ffusionParse(FFusionParserContext *parser, const uint8_t *buf, int buf_size, int *out_buf_size, int *type, int *skippable)
858 {
859         if(parser->parserStructure->parser_parse)
860                 return (parser->parserStructure->parser_parse)(parser, buf, buf_size, out_buf_size, type, skippable);
861         return 0;
862 }
863
864 int ffusionIsParsedVideoDecodable(FFusionParserContext *parser)
865 {
866         if (!parser) return 1;
867        
868         if (parser->parserStructure == &ffusionH264Parser) {
869                 H264ParserContext *h264parser = parser->internalContext;
870                
871                 // don't try to decode interlaced or 4:2:2 H.264
872                 return (h264parser->frame_mbs_only_flag == 1) && (h264parser->chroma_format_idc <= 1);
873         }
874        
875         return 1;
876 }
877
878 #ifdef DEBUG_BUILD
879 //FFMPEG doesn't configure properly (their fault), so define their idoticly undefined symbols.
880 int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2], int ref_mv_scale, int size, int h){return 0;}
881 int ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index,int ref_index, int size, int h, int add_rate){return 0;}
882 int ff_init_me(MpegEncContext *s){return 0;}
883 int ff_rate_control_init(struct MpegEncContext *s){return 0;}
884 float ff_rate_estimate_qscale(struct MpegEncContext *s, int dry_run){return 0;}
885 void ff_write_pass1_stats(struct MpegEncContext *s){}
886 void h263_encode_init(MpegEncContext *s){}
887 #endif
Note: See TracBrowser for help on using the browser.