root/trunk/bitstream_info.c

Revision 905, 23.3 kB (checked in by gbooker, 3 months ago)

If one has properly framed data, setting mFramesPerPacket breaks AC3 passthrough on the AppleTV (that is, the proper passthrough instead of the hack). The rest is warning fixes

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 }
Note: See TracBrowser for help on using the browser.