Mercurial > libavcodec.hg
comparison h264.c @ 5079:4ff805f87391 libavcodec
allocate PPS and SPS dynamically
patch by Andreas ªÓman andreas ta olebyn tod nu
reference thread:
subject: [FFmpeg-devel] [PATCH] h264: allocate PPS and SPS dynamically
date: 05/28/2007 03:00 PM
author | benoit |
---|---|
date | Tue, 29 May 2007 14:35:29 +0000 |
parents | 27afc3835257 |
children | ce36118abbbb |
comparison
equal
deleted
inserted
replaced
5078:4f36b52179d1 | 5079:4ff805f87391 |
---|---|
2764 h->pred16x16[TOP_DC_PRED8x8 ]= ff_pred16x16_top_dc_c; | 2764 h->pred16x16[TOP_DC_PRED8x8 ]= ff_pred16x16_top_dc_c; |
2765 h->pred16x16[DC_128_PRED8x8 ]= ff_pred16x16_128_dc_c; | 2765 h->pred16x16[DC_128_PRED8x8 ]= ff_pred16x16_128_dc_c; |
2766 } | 2766 } |
2767 | 2767 |
2768 static void free_tables(H264Context *h){ | 2768 static void free_tables(H264Context *h){ |
2769 int i; | |
2769 av_freep(&h->intra4x4_pred_mode); | 2770 av_freep(&h->intra4x4_pred_mode); |
2770 av_freep(&h->chroma_pred_mode_table); | 2771 av_freep(&h->chroma_pred_mode_table); |
2771 av_freep(&h->cbp_table); | 2772 av_freep(&h->cbp_table); |
2772 av_freep(&h->mvd_table[0]); | 2773 av_freep(&h->mvd_table[0]); |
2773 av_freep(&h->mvd_table[1]); | 2774 av_freep(&h->mvd_table[1]); |
2780 | 2781 |
2781 av_freep(&h->mb2b_xy); | 2782 av_freep(&h->mb2b_xy); |
2782 av_freep(&h->mb2b8_xy); | 2783 av_freep(&h->mb2b8_xy); |
2783 | 2784 |
2784 av_freep(&h->s.obmc_scratchpad); | 2785 av_freep(&h->s.obmc_scratchpad); |
2786 | |
2787 for(i = 0; i < MAX_SPS_COUNT; i++) | |
2788 av_freep(h->sps_buffers + i); | |
2789 | |
2790 for(i = 0; i < MAX_PPS_COUNT; i++) | |
2791 av_freep(h->pps_buffers + i); | |
2785 } | 2792 } |
2786 | 2793 |
2787 static void init_dequant8_coeff_table(H264Context *h){ | 2794 static void init_dequant8_coeff_table(H264Context *h){ |
2788 int i,q,x; | 2795 int i,q,x; |
2789 const int transpose = (h->s.dsp.h264_idct8_add != ff_h264_idct8_add_c); //FIXME ugly | 2796 const int transpose = (h->s.dsp.h264_idct8_add != ff_h264_idct8_add_c); //FIXME ugly |
4192 pps_id= get_ue_golomb(&s->gb); | 4199 pps_id= get_ue_golomb(&s->gb); |
4193 if(pps_id>=MAX_PPS_COUNT){ | 4200 if(pps_id>=MAX_PPS_COUNT){ |
4194 av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); | 4201 av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); |
4195 return -1; | 4202 return -1; |
4196 } | 4203 } |
4197 h->pps= h->pps_buffer[pps_id]; | 4204 if(!h->pps_buffers[pps_id]) { |
4198 if(h->pps.slice_group_count == 0){ | |
4199 av_log(h->s.avctx, AV_LOG_ERROR, "non existing PPS referenced\n"); | 4205 av_log(h->s.avctx, AV_LOG_ERROR, "non existing PPS referenced\n"); |
4200 return -1; | 4206 return -1; |
4201 } | 4207 } |
4202 | 4208 h->pps= *h->pps_buffers[pps_id]; |
4203 h->sps= h->sps_buffer[ h->pps.sps_id ]; | 4209 |
4204 if(h->sps.log2_max_frame_num == 0){ | 4210 if(!h->sps_buffers[h->pps.sps_id]) { |
4205 av_log(h->s.avctx, AV_LOG_ERROR, "non existing SPS referenced\n"); | 4211 av_log(h->s.avctx, AV_LOG_ERROR, "non existing SPS referenced\n"); |
4206 return -1; | 4212 return -1; |
4207 } | 4213 } |
4214 h->sps = *h->sps_buffers[h->pps.sps_id]; | |
4208 | 4215 |
4209 if(h->dequant_coeff_pps != pps_id){ | 4216 if(h->dequant_coeff_pps != pps_id){ |
4210 h->dequant_coeff_pps = pps_id; | 4217 h->dequant_coeff_pps = pps_id; |
4211 init_dequant_tables(h); | 4218 init_dequant_tables(h); |
4212 } | 4219 } |
7397 memcpy(scaling_matrix4, sps->scaling_matrix4, 6*16*sizeof(uint8_t)); | 7404 memcpy(scaling_matrix4, sps->scaling_matrix4, 6*16*sizeof(uint8_t)); |
7398 memcpy(scaling_matrix8, sps->scaling_matrix8, 2*64*sizeof(uint8_t)); | 7405 memcpy(scaling_matrix8, sps->scaling_matrix8, 2*64*sizeof(uint8_t)); |
7399 } | 7406 } |
7400 } | 7407 } |
7401 | 7408 |
7409 /** | |
7410 * Returns and optionally allocates SPS / PPS structures in the supplied array 'vec' | |
7411 */ | |
7412 static void * | |
7413 alloc_parameter_set(H264Context *h, void **vec, const unsigned int id, const unsigned int max, | |
7414 const size_t size, const char *name) | |
7415 { | |
7416 if(id>=max) { | |
7417 av_log(h->s.avctx, AV_LOG_ERROR, "%s_id (%d) out of range\n", name, id); | |
7418 return NULL; | |
7419 } | |
7420 | |
7421 if(!vec[id]) { | |
7422 vec[id] = av_mallocz(size); | |
7423 if(vec[id] == NULL) | |
7424 av_log(h->s.avctx, AV_LOG_ERROR, "cannot allocate memory for %s\n", name); | |
7425 } | |
7426 return vec[id]; | |
7427 } | |
7428 | |
7402 static inline int decode_seq_parameter_set(H264Context *h){ | 7429 static inline int decode_seq_parameter_set(H264Context *h){ |
7403 MpegEncContext * const s = &h->s; | 7430 MpegEncContext * const s = &h->s; |
7404 int profile_idc, level_idc; | 7431 int profile_idc, level_idc; |
7405 unsigned int sps_id, tmp, mb_width, mb_height; | 7432 unsigned int sps_id, tmp, mb_width, mb_height; |
7406 int i; | 7433 int i; |
7413 get_bits1(&s->gb); //constraint_set3_flag | 7440 get_bits1(&s->gb); //constraint_set3_flag |
7414 get_bits(&s->gb, 4); // reserved | 7441 get_bits(&s->gb, 4); // reserved |
7415 level_idc= get_bits(&s->gb, 8); | 7442 level_idc= get_bits(&s->gb, 8); |
7416 sps_id= get_ue_golomb(&s->gb); | 7443 sps_id= get_ue_golomb(&s->gb); |
7417 | 7444 |
7418 if (sps_id >= MAX_SPS_COUNT){ | 7445 sps = alloc_parameter_set(h, (void **)h->sps_buffers, sps_id, MAX_SPS_COUNT, sizeof(SPS), "sps"); |
7419 // ok it has gone out of hand, someone is sending us bad stuff. | 7446 if(sps == NULL) |
7420 av_log(h->s.avctx, AV_LOG_ERROR, "illegal sps_id (%d)\n", sps_id); | |
7421 return -1; | 7447 return -1; |
7422 } | 7448 |
7423 | |
7424 sps= &h->sps_buffer[ sps_id ]; | |
7425 sps->profile_idc= profile_idc; | 7449 sps->profile_idc= profile_idc; |
7426 sps->level_idc= level_idc; | 7450 sps->level_idc= level_idc; |
7427 | 7451 |
7428 if(sps->profile_idc >= 100){ //high profile | 7452 if(sps->profile_idc >= 100){ //high profile |
7429 if(get_ue_golomb(&s->gb) == 3) //chroma_format_idc | 7453 if(get_ue_golomb(&s->gb) == 3) //chroma_format_idc |
7529 static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ | 7553 static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ |
7530 MpegEncContext * const s = &h->s; | 7554 MpegEncContext * const s = &h->s; |
7531 unsigned int tmp, pps_id= get_ue_golomb(&s->gb); | 7555 unsigned int tmp, pps_id= get_ue_golomb(&s->gb); |
7532 PPS *pps; | 7556 PPS *pps; |
7533 | 7557 |
7534 if(pps_id>=MAX_PPS_COUNT){ | 7558 pps = alloc_parameter_set(h, (void **)h->pps_buffers, pps_id, MAX_PPS_COUNT, sizeof(PPS), "pps"); |
7535 av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); | 7559 if(pps == NULL) |
7536 return -1; | 7560 return -1; |
7537 } | |
7538 pps = &h->pps_buffer[pps_id]; | |
7539 | 7561 |
7540 tmp= get_ue_golomb(&s->gb); | 7562 tmp= get_ue_golomb(&s->gb); |
7541 if(tmp>=MAX_SPS_COUNT){ | 7563 if(tmp>=MAX_SPS_COUNT || h->sps_buffers[tmp] == NULL){ |
7542 av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n"); | 7564 av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n"); |
7543 return -1; | 7565 return -1; |
7544 } | 7566 } |
7545 pps->sps_id= tmp; | 7567 pps->sps_id= tmp; |
7546 | 7568 |
7606 memset(pps->scaling_matrix4, 16, 6*16*sizeof(uint8_t)); | 7628 memset(pps->scaling_matrix4, 16, 6*16*sizeof(uint8_t)); |
7607 memset(pps->scaling_matrix8, 16, 2*64*sizeof(uint8_t)); | 7629 memset(pps->scaling_matrix8, 16, 2*64*sizeof(uint8_t)); |
7608 | 7630 |
7609 if(get_bits_count(&s->gb) < bit_length){ | 7631 if(get_bits_count(&s->gb) < bit_length){ |
7610 pps->transform_8x8_mode= get_bits1(&s->gb); | 7632 pps->transform_8x8_mode= get_bits1(&s->gb); |
7611 decode_scaling_matrices(h, &h->sps_buffer[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); | 7633 decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); |
7612 get_se_golomb(&s->gb); //second_chroma_qp_index_offset | 7634 get_se_golomb(&s->gb); //second_chroma_qp_index_offset |
7613 } | 7635 } |
7614 | 7636 |
7615 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ | 7637 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ |
7616 av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s %s\n", | 7638 av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s %s\n", |