You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	change of aac_ac3_parser, so it is able to send complete portion of data to decoder
Originally committed as revision 12758 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		| @@ -29,35 +29,32 @@ int ff_aac_ac3_parse(AVCodecParserContext *s1, | |||||||
|                      const uint8_t *buf, int buf_size) |                      const uint8_t *buf, int buf_size) | ||||||
| { | { | ||||||
|     AACAC3ParseContext *s = s1->priv_data; |     AACAC3ParseContext *s = s1->priv_data; | ||||||
|     AACAC3FrameFlag frame_flag; |     ParseContext *pc = &s->pc; | ||||||
|     const uint8_t *buf_ptr; |     int len, i; | ||||||
|     int len; |  | ||||||
|  |  | ||||||
|     *poutbuf = NULL; |     while(s->remaining_size <= buf_size){ | ||||||
|     *poutbuf_size = 0; |         if(s->remaining_size && !s->need_next_header){ | ||||||
|  |             i= s->remaining_size; | ||||||
|  |             s->remaining_size = 0; | ||||||
|  |             goto output_frame; | ||||||
|  |         }else{ //we need a header first | ||||||
|  |             len=0; | ||||||
|  |             for(i=s->remaining_size; i<buf_size; i++){ | ||||||
|  |                 s->state = (s->state<<8) + buf[i]; | ||||||
|  |                 if((len=s->sync(s->state, s, &s->need_next_header, &s->new_frame_start))) | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |             i-= s->header_size; | ||||||
|  |             if(len>0){ | ||||||
|  |                 s->remaining_size = len + i; | ||||||
|  |  | ||||||
|     buf_ptr = buf; |                 if(pc->index+i > 0 && s->new_frame_start){ | ||||||
|     while (buf_size > 0) { |                     s->remaining_size -= i; // remaining_size=len | ||||||
|         int size_needed= s->frame_size ? s->frame_size : s->header_size; | output_frame: | ||||||
|         len = s->inbuf_ptr - s->inbuf; |                     ff_combine_frame(pc, i, &buf, &buf_size); | ||||||
|  |                     *poutbuf = buf; | ||||||
|  |                     *poutbuf_size = buf_size; | ||||||
|  |  | ||||||
|         if(len<size_needed){ |  | ||||||
|             len = FFMIN(size_needed - len, buf_size); |  | ||||||
|             memcpy(s->inbuf_ptr, buf_ptr, len); |  | ||||||
|             buf_ptr      += len; |  | ||||||
|             s->inbuf_ptr += len; |  | ||||||
|             buf_size     -= len; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (s->frame_size == 0) { |  | ||||||
|             if ((s->inbuf_ptr - s->inbuf) == s->header_size) { |  | ||||||
|                 len = s->sync(s, &frame_flag); |  | ||||||
|                 if (len == 0) { |  | ||||||
|                     /* no sync found : move by one byte (inefficient, but simple!) */ |  | ||||||
|                     memmove(s->inbuf, s->inbuf + 1, s->header_size - 1); |  | ||||||
|                     s->inbuf_ptr--; |  | ||||||
|                 } else { |  | ||||||
|                     s->frame_size = len; |  | ||||||
|                     /* update codec info */ |                     /* update codec info */ | ||||||
|                     avctx->sample_rate = s->sample_rate; |                     avctx->sample_rate = s->sample_rate; | ||||||
|                     /* allow downmixing to stereo (or mono for AC3) */ |                     /* allow downmixing to stereo (or mono for AC3) */ | ||||||
| @@ -72,17 +69,18 @@ int ff_aac_ac3_parse(AVCodecParserContext *s1, | |||||||
|                     } |                     } | ||||||
|                     avctx->bit_rate = s->bit_rate; |                     avctx->bit_rate = s->bit_rate; | ||||||
|                     avctx->frame_size = s->samples; |                     avctx->frame_size = s->samples; | ||||||
|  |  | ||||||
|  |                     return i; | ||||||
|                 } |                 } | ||||||
|             } |             }else{ | ||||||
|         } else { |  | ||||||
|             if(s->inbuf_ptr - s->inbuf == s->frame_size){ |  | ||||||
|                 *poutbuf = s->inbuf; |  | ||||||
|                 *poutbuf_size = s->frame_size; |  | ||||||
|                 s->inbuf_ptr = s->inbuf; |  | ||||||
|                 s->frame_size = 0; |  | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return buf_ptr - buf; |  | ||||||
|  |     ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size); | ||||||
|  |     s->remaining_size -= FFMIN(s->remaining_size, buf_size); | ||||||
|  |     *poutbuf = NULL; | ||||||
|  |     *poutbuf_size = 0; | ||||||
|  |     return buf_size; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -26,23 +26,23 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include "avcodec.h" | #include "avcodec.h" | ||||||
|  |  | ||||||
| typedef enum{ |  | ||||||
|     FRAME_COMPLETE,    ///< Complete frame, ends previous frame |  | ||||||
|     FRAME_START,       ///< Frame start, ends previous frame |  | ||||||
|     FRAME_CONTINUATION ///< Part of the previous frame |  | ||||||
| }AACAC3FrameFlag; |  | ||||||
|  |  | ||||||
| typedef struct AACAC3ParseContext { | typedef struct AACAC3ParseContext { | ||||||
|     uint8_t *inbuf_ptr; |  | ||||||
|     int frame_size; |     int frame_size; | ||||||
|     int header_size; |     int header_size; | ||||||
|     int (*sync)(struct AACAC3ParseContext *hdr_info, AACAC3FrameFlag *flag); |     int (*sync)(uint64_t state, struct AACAC3ParseContext *hdr_info, | ||||||
|     uint8_t inbuf[8192]; /* input buffer */ |             int *need_next_header, int *new_frame_start); | ||||||
|  |  | ||||||
|     int channels; |     int channels; | ||||||
|     int sample_rate; |     int sample_rate; | ||||||
|     int bit_rate; |     int bit_rate; | ||||||
|     int samples; |     int samples; | ||||||
|  |  | ||||||
|  |     ParseContext pc; | ||||||
|  |     int remaining_size; | ||||||
|  |     uint64_t state; | ||||||
|  |  | ||||||
|  |     int need_next_header; | ||||||
|  |     int new_frame_start; | ||||||
| } AACAC3ParseContext; | } AACAC3ParseContext; | ||||||
|  |  | ||||||
| int ff_aac_ac3_parse(AVCodecParserContext *s1, | int ff_aac_ac3_parse(AVCodecParserContext *s1, | ||||||
|   | |||||||
| @@ -27,12 +27,14 @@ | |||||||
|  |  | ||||||
| #define AAC_HEADER_SIZE 7 | #define AAC_HEADER_SIZE 7 | ||||||
|  |  | ||||||
| static int aac_sync(AACAC3ParseContext *hdr_info, AACAC3FrameFlag *flag) | static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info, | ||||||
|  |         int *need_next_header, int *new_frame_start) | ||||||
| { | { | ||||||
|     GetBitContext bits; |     GetBitContext bits; | ||||||
|     int size, rdb, ch, sr; |     int size, rdb, ch, sr; | ||||||
|  |     uint64_t tmp = be2me_64(state); | ||||||
|  |  | ||||||
|     init_get_bits(&bits, hdr_info->inbuf, AAC_HEADER_SIZE * 8); |     init_get_bits(&bits, (uint8_t *)&tmp, AAC_HEADER_SIZE * 8); | ||||||
|  |  | ||||||
|     if(get_bits(&bits, 12) != 0xfff) |     if(get_bits(&bits, 12) != 0xfff) | ||||||
|         return 0; |         return 0; | ||||||
| @@ -65,15 +67,15 @@ static int aac_sync(AACAC3ParseContext *hdr_info, AACAC3FrameFlag *flag) | |||||||
|     hdr_info->sample_rate = ff_mpeg4audio_sample_rates[sr]; |     hdr_info->sample_rate = ff_mpeg4audio_sample_rates[sr]; | ||||||
|     hdr_info->samples = (rdb + 1) * 1024; |     hdr_info->samples = (rdb + 1) * 1024; | ||||||
|     hdr_info->bit_rate = size * 8 * hdr_info->sample_rate / hdr_info->samples; |     hdr_info->bit_rate = size * 8 * hdr_info->sample_rate / hdr_info->samples; | ||||||
|     *flag = FRAME_COMPLETE; |  | ||||||
|  |  | ||||||
|  |     *need_next_header=0; | ||||||
|  |     *new_frame_start=1; | ||||||
|     return size; |     return size; | ||||||
| } | } | ||||||
|  |  | ||||||
| static av_cold int aac_parse_init(AVCodecParserContext *s1) | static av_cold int aac_parse_init(AVCodecParserContext *s1) | ||||||
| { | { | ||||||
|     AACAC3ParseContext *s = s1->priv_data; |     AACAC3ParseContext *s = s1->priv_data; | ||||||
|     s->inbuf_ptr = s->inbuf; |  | ||||||
|     s->header_size = AAC_HEADER_SIZE; |     s->header_size = AAC_HEADER_SIZE; | ||||||
|     s->sync = aac_sync; |     s->sync = aac_sync; | ||||||
|     return 0; |     return 0; | ||||||
|   | |||||||
| @@ -123,12 +123,14 @@ int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int ac3_sync(AACAC3ParseContext *hdr_info, AACAC3FrameFlag *flag) | static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, | ||||||
|  |         int *need_next_header, int *new_frame_start) | ||||||
| { | { | ||||||
|     int err; |     int err; | ||||||
|  |     uint64_t tmp = be2me_64(state); | ||||||
|     AC3HeaderInfo hdr; |     AC3HeaderInfo hdr; | ||||||
|  |  | ||||||
|     err = ff_ac3_parse_header(hdr_info->inbuf, &hdr); |     err = ff_ac3_parse_header((uint8_t *)&tmp, &hdr); | ||||||
|  |  | ||||||
|     if(err < 0) |     if(err < 0) | ||||||
|         return 0; |         return 0; | ||||||
| @@ -138,24 +140,14 @@ static int ac3_sync(AACAC3ParseContext *hdr_info, AACAC3FrameFlag *flag) | |||||||
|     hdr_info->channels = hdr.channels; |     hdr_info->channels = hdr.channels; | ||||||
|     hdr_info->samples = AC3_FRAME_SIZE; |     hdr_info->samples = AC3_FRAME_SIZE; | ||||||
|  |  | ||||||
|     switch(hdr.frame_type){ |     *need_next_header = (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT); | ||||||
|         case EAC3_FRAME_TYPE_INDEPENDENT: |     *new_frame_start = (hdr.frame_type != EAC3_FRAME_TYPE_DEPENDENT); | ||||||
|             *flag = FRAME_START; |  | ||||||
|             break; |  | ||||||
|         case EAC3_FRAME_TYPE_DEPENDENT: |  | ||||||
|             *flag = FRAME_CONTINUATION; |  | ||||||
|             break; |  | ||||||
|         case EAC3_FRAME_TYPE_AC3_CONVERT: |  | ||||||
|             *flag = FRAME_COMPLETE; |  | ||||||
|             break; |  | ||||||
|     } |  | ||||||
|     return hdr.frame_size; |     return hdr.frame_size; | ||||||
| } | } | ||||||
|  |  | ||||||
| static av_cold int ac3_parse_init(AVCodecParserContext *s1) | static av_cold int ac3_parse_init(AVCodecParserContext *s1) | ||||||
| { | { | ||||||
|     AACAC3ParseContext *s = s1->priv_data; |     AACAC3ParseContext *s = s1->priv_data; | ||||||
|     s->inbuf_ptr = s->inbuf; |  | ||||||
|     s->header_size = AC3_HEADER_SIZE; |     s->header_size = AC3_HEADER_SIZE; | ||||||
|     s->sync = ac3_sync; |     s->sync = ac3_sync; | ||||||
|     return 0; |     return 0; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user