int theora_decode_init(theora_state *th, theora_info *c){ PB_INSTANCE *pbi; codec_setup_info *ci; ci=(codec_setup_info *)c->codec_setup; th->internal_decode=pbi=_ogg_calloc(1,sizeof(*pbi)); InitPBInstance(pbi); memcpy(&pbi->info,c,sizeof(*c)); pbi->info.codec_setup=NULL; th->i=&pbi->info; th->granulepos=-1; InitFrameDetails(pbi); pbi->keyframe_granule_shift=_ilog(c->keyframe_frequency_force-1); pbi->LastFrameQualityValue = 0; pbi->DecoderErrorCode = 0; /* Clear down the YUVtoRGB conversion skipped list. */ memset(pbi->skipped_display_fragments, 0, pbi->UnitFragments ); /* Initialise version specific quantiser and in-loop filter values */ CopyQTables(pbi, ci); CopyFilterTables(pbi, ci); /* Huffman setup */ InitHuffmanTrees(pbi, ci); return(0); }
static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; vorbis_info_floor0 *info=look->vi; int j,k; int ampraw=oggpack_read(&vb->opb,info->ampbits); if(ampraw>0){ /* also handles the -1 out of data case */ long maxval=(1<<info->ampbits)-1; float amp=(float)ampraw/maxval*info->ampdB; int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */ codec_setup_info *ci=vb->vd->vi->codec_setup; codebook *b=ci->fullbooks+info->books[booknum]; float last=0.f; /* the additional b->dim is a guard against any possible stack smash; b->dim is provably more than we can overflow the vector */ float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1)); for(j=0;j<look->m;j+=b->dim) if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop; for(j=0;j<look->m;){ for(k=0;k<b->dim;k++,j++)lsp[j]+=last; last=lsp[j-1]; } lsp[look->m]=amp; return(lsp); } } eop: return(NULL); }
static gboolean theora_enc_set_format (GstVideoEncoder * benc, GstVideoCodecState * state) { GstTheoraEnc *enc = GST_THEORA_ENC (benc); GstVideoInfo *info = &state->info; enc->width = GST_VIDEO_INFO_WIDTH (info); enc->height = GST_VIDEO_INFO_HEIGHT (info); th_info_clear (&enc->info); th_info_init (&enc->info); /* Theora has a divisible-by-sixteen restriction for the encoded video size but * we can define a picture area using pic_width/pic_height */ enc->info.frame_width = GST_ROUND_UP_16 (enc->width); enc->info.frame_height = GST_ROUND_UP_16 (enc->height); enc->info.pic_width = enc->width; enc->info.pic_height = enc->height; switch (GST_VIDEO_INFO_FORMAT (info)) { case GST_VIDEO_FORMAT_I420: enc->info.pixel_fmt = TH_PF_420; break; case GST_VIDEO_FORMAT_Y42B: enc->info.pixel_fmt = TH_PF_422; break; case GST_VIDEO_FORMAT_Y444: enc->info.pixel_fmt = TH_PF_444; break; default: g_assert_not_reached (); } enc->info.fps_numerator = enc->fps_n = GST_VIDEO_INFO_FPS_N (info); enc->info.fps_denominator = enc->fps_d = GST_VIDEO_INFO_FPS_D (info); enc->info.aspect_numerator = GST_VIDEO_INFO_PAR_N (info); enc->info.aspect_denominator = GST_VIDEO_INFO_PAR_D (info); enc->info.colorspace = TH_CS_UNSPECIFIED; /* Save input state */ if (enc->input_state) gst_video_codec_state_unref (enc->input_state); enc->input_state = gst_video_codec_state_ref (state); /* as done in theora */ enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1); GST_DEBUG_OBJECT (enc, "keyframe_frequency_force is %d, granule shift is %d", enc->keyframe_force, enc->info.keyframe_granule_shift); theora_enc_reset (enc); enc->initialised = TRUE; return TRUE; }
/* choose the smallest supported node size that fits our decode table. Legal bytewidths are 1/1 1/2 2/2 2/4 4/4 */ static int _determine_node_bytes(long used, int leafwidth){ /* special case small books to size 4 to avoid multiple special cases in repack */ if(used<2) return 4; if(leafwidth==3)leafwidth=4; if(_ilog(3*used-6)+1 <= leafwidth*4) return leafwidth/2?leafwidth/2:1; return leafwidth; }
int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){ long i,j; int ordered=0; /* first the basic parameters */ oggpack_write(opb,0x564342,24); oggpack_write(opb,c->dim,16); oggpack_write(opb,c->entries,24); /* pack the codewords. There are two packings; length ordered and length random. Decide between the two now. */ for(i=1;i<c->entries;i++) if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break; if(i==c->entries)ordered=1; if(ordered){ /* length ordered. We only need to say how many codewords of each length. The actual codewords are generated deterministically */ long count=0; oggpack_write(opb,1,1); /* ordered */ oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */ for(i=1;i<c->entries;i++){ long this=c->lengthlist[i]; long last=c->lengthlist[i-1]; if(this>last){ for(j=last;j<this;j++){ oggpack_write(opb,i-count,_ilog(c->entries-count)); count=i; } } } oggpack_write(opb,i-count,_ilog(c->entries-count)); }else{
void vqext_quantize(vqgen *v,quant_meta *q){ int j,k; long dim=v->elements; long n=v->entries; float max=-1; float *test=alloca(sizeof(float)*dim); int moved=0; /* allow movement only to unoccupied coordinates on the coarse grid */ for(j=0;j<n;j++){ for(k=0;k<dim;k++){ float val=_now(v,j)[k]; float norm=rint(fabs(val)/scalequant); if(norm>max)max=norm; test[k]=norm; } /* allow move only if unoccupied */ if(quant_save){ for(k=0;k<n;k++) if(j!=k && memcmp(test,quant_save+dim*k,dim*sizeof(float))==0) break; if(k==n){ if(memcmp(test,quant_save+dim*j,dim*sizeof(float))) moved++; memcpy(quant_save+dim*j,test,sizeof(float)*dim); } }else{ memcpy(_now(v,j),test,sizeof(float)*dim); } } /* unlike the other trainers, we fill in our quantization information (as we know granularity beforehand and don't need to maximize it) */ q->min=_float32_pack(0.f); q->delta=_float32_pack(scalequant); q->quant=_ilog(max); if(quant_save){ memcpy(_now(v,0),quant_save,sizeof(float)*dim*n); fprintf(stderr,"cells shifted this iteration: %d\n",moved); } }
static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i,unsigned int channel) { vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; vorbis_info_floor0 *info=look->vif0; oggpack_buffer *vbopb=&vb->opb; int j,k; int ampraw=oggpack_read32(vbopb,info->ampbits); if(ampraw>0){ long maxval=(1<<info->ampbits)-1; ogg_double_t amp=(ogg_double_t)ampraw/maxval*info->ampdB; int booknum=oggpack_read32(vbopb,_ilog(info->numbooks)); if((booknum>=0) && (booknum<info->numbooks)){ codec_setup_info *ci=vb->vd->vi->codec_setup; codebook *b=ci->fullbooks+info->books[booknum]; int bookdim=b->dim; ogg_double_t *lsp=look->lsp_data[channel]; if(vorbis_book_decodev_set(b,lsp,vbopb,bookdim)<0) goto eop; for(j=bookdim;j<look->m;){ ogg_double_t last; if(vorbis_book_decodev_set(b,lsp+j,vbopb,bookdim)<0) goto eop; last=lsp[j-1]; for(k=0;k<bookdim;k++,j++) lsp[j]+=last; } lsp[look->m]=amp; return(lsp); } } eop: return(NULL); }
static void gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class) { enc->sinkpad = gst_pad_new_from_static_template (&theora_enc_sink_factory, "sink"); gst_pad_set_chain_function (enc->sinkpad, theora_enc_chain); gst_pad_set_event_function (enc->sinkpad, theora_enc_sink_event); gst_pad_set_setcaps_function (enc->sinkpad, theora_enc_sink_setcaps); gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad); enc->srcpad = gst_pad_new_from_static_template (&theora_enc_src_factory, "src"); gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad); gst_segment_init (&enc->segment, GST_FORMAT_UNDEFINED); enc->center = THEORA_DEF_CENTER; enc->border = THEORA_DEF_BORDER; enc->video_bitrate = THEORA_DEF_BITRATE; enc->video_quality = THEORA_DEF_QUALITY; enc->quick = THEORA_DEF_QUICK; enc->keyframe_auto = THEORA_DEF_KEYFRAME_AUTO; enc->keyframe_freq = THEORA_DEF_KEYFRAME_FREQ; enc->keyframe_force = THEORA_DEF_KEYFRAME_FREQ_FORCE; enc->keyframe_threshold = THEORA_DEF_KEYFRAME_THRESHOLD; enc->keyframe_mindistance = THEORA_DEF_KEYFRAME_MINDISTANCE; enc->noise_sensitivity = THEORA_DEF_NOISE_SENSITIVITY; enc->sharpness = THEORA_DEF_SHARPNESS; enc->granule_shift = _ilog (enc->info.keyframe_frequency_force - 1); GST_DEBUG_OBJECT (enc, "keyframe_frequency_force is %d, granule shift is %d", enc->info.keyframe_frequency_force, enc->granule_shift); enc->expected_ts = GST_CLOCK_TIME_NONE; }
static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps) { GstStructure *structure = gst_caps_get_structure (caps, 0); GstTheoraEnc *enc = GST_THEORA_ENC (gst_pad_get_parent (pad)); const GValue *par; gint fps_n, fps_d; gst_structure_get_int (structure, "width", &enc->width); gst_structure_get_int (structure, "height", &enc->height); gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d); par = gst_structure_get_value (structure, "pixel-aspect-ratio"); theora_info_clear (&enc->info); theora_info_init (&enc->info); /* Theora has a divisible-by-sixteen restriction for the encoded video size but * we can define a visible area using the frame_width/frame_height */ enc->info_width = enc->info.width = (enc->width + 15) & ~15; enc->info_height = enc->info.height = (enc->height + 15) & ~15; enc->info.frame_width = enc->width; enc->info.frame_height = enc->height; /* center image if needed */ if (enc->center) { /* make sure offset is even, for easier decoding */ enc->offset_x = GST_ROUND_UP_2 ((enc->info_width - enc->width) / 2); enc->offset_y = GST_ROUND_UP_2 ((enc->info_height - enc->height) / 2); } else { enc->offset_x = 0; enc->offset_y = 0; } enc->info.offset_x = enc->offset_x; enc->info.offset_y = enc->offset_y; enc->info.fps_numerator = enc->fps_n = fps_n; enc->info.fps_denominator = enc->fps_d = fps_d; if (par) { enc->info.aspect_numerator = gst_value_get_fraction_numerator (par); enc->info.aspect_denominator = gst_value_get_fraction_denominator (par); } else { /* setting them to 0 indicates that the decoder can chose a good aspect * ratio, defaulting to 1/1 */ enc->info.aspect_numerator = 0; enc->info.aspect_denominator = 0; } enc->info.colorspace = OC_CS_UNSPECIFIED; enc->info.target_bitrate = enc->video_bitrate; enc->info.quality = enc->video_quality; enc->info.dropframes_p = 0; enc->info.quick_p = (enc->quick ? 1 : 0); enc->info.keyframe_auto_p = (enc->keyframe_auto ? 1 : 0); enc->info.keyframe_frequency = enc->keyframe_freq; enc->info.keyframe_frequency_force = enc->keyframe_force; enc->info.keyframe_data_target_bitrate = enc->video_bitrate * 1.5; enc->info.keyframe_auto_threshold = enc->keyframe_threshold; enc->info.keyframe_mindistance = enc->keyframe_mindistance; enc->info.noise_sensitivity = enc->noise_sensitivity; enc->info.sharpness = enc->sharpness; /* as done in theora */ enc->granule_shift = _ilog (enc->info.keyframe_frequency_force - 1); GST_DEBUG_OBJECT (enc, "keyframe_frequency_force is %d, granule shift is %d", enc->info.keyframe_frequency_force, enc->granule_shift); theora_enc_reset (enc); enc->initialised = TRUE; gst_object_unref (enc); return TRUE; }
/* unpacks a codebook from the packet buffer into the codebook struct, readies the codebook auxiliary structures for decode *************/ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){ long i,j; memset(s,0,sizeof(*s)); /* make sure alignment is correct */ if(oggpack_read(opb,24)!=0x564342)goto _eofout; /* first the basic parameters */ s->dim=oggpack_read(opb,16); s->entries=oggpack_read(opb,24); if(s->entries==-1)goto _eofout; /* codeword ordering.... length ordered or unordered? */ switch((int)oggpack_read(opb,1)){ case 0: /* unordered */ s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); /* allocated but unused entries? */ if(oggpack_read(opb,1)){ /* yes, unused entries */ for(i=0;i<s->entries;i++){ if(oggpack_read(opb,1)){ long num=oggpack_read(opb,5); if(num==-1)goto _eofout; s->lengthlist[i]=num+1; }else s->lengthlist[i]=0; } }else{ /* all entries used; no tagging */ for(i=0;i<s->entries;i++){ long num=oggpack_read(opb,5); if(num==-1)goto _eofout; s->lengthlist[i]=num+1; } } break; case 1: /* ordered */ { long length=oggpack_read(opb,5)+1; s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); for(i=0;i<s->entries;){ long num=oggpack_read(opb,_ilog(s->entries-i)); if(num==-1)goto _eofout; for(j=0;j<num && i<s->entries;j++,i++) s->lengthlist[i]=length; length++; } } break; default: /* EOF */ return(-1); } /* Do we have a mapping to unpack? */ switch((s->maptype=oggpack_read(opb,4))){ case 0: /* no mapping */ break; case 1: case 2: /* implicitly populated value mapping */ /* explicitly populated value mapping */ s->q_min=oggpack_read(opb,32); s->q_delta=oggpack_read(opb,32); s->q_quant=oggpack_read(opb,4)+1; s->q_sequencep=oggpack_read(opb,1); { int quantvals=0; switch(s->maptype){ case 1: quantvals=_book_maptype1_quantvals(s); break; case 2: quantvals=s->entries*s->dim; break; } /* quantized values */ s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals); for(i=0;i<quantvals;i++) s->quantlist[i]=oggpack_read(opb,s->q_quant); if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; } break; default: goto _errout; } /* all set */ return(0); _errout: _eofout: vorbis_staticbook_clear(s); return(-1); }
int theora_encode_init(theora_state *th, theora_info *c){ int i; CP_INSTANCE *cpi; memset(th, 0, sizeof(*th)); /*Currently only the 4:2:0 format is supported.*/ if(c->pixelformat!=OC_PF_420)return OC_IMPL; th->internal_encode=cpi=_ogg_calloc(1,sizeof(*cpi)); dsp_static_init (&cpi->dsp); memcpy (&cpi->pb.dsp, &cpi->dsp, sizeof(DspFunctions)); c->version_major=VERSION_MAJOR; c->version_minor=VERSION_MINOR; c->version_subminor=VERSION_SUB; InitTmpBuffers(&cpi->pb); InitPPInstance(&cpi->pp, &cpi->dsp); /* Initialise Configuration structure to legal values */ if(c->quality>63)c->quality=63; if(c->quality<0)c->quality=32; if(c->target_bitrate<0)c->target_bitrate=0; /* we clamp target_bitrate to 24 bits after setting up the encoder */ cpi->Configuration.BaseQ = c->quality; cpi->Configuration.FirstFrameQ = c->quality; cpi->Configuration.MaxQ = c->quality; cpi->Configuration.ActiveMaxQ = c->quality; cpi->MVChangeFactor = 14; cpi->FourMvChangeFactor = 8; cpi->MinImprovementForNewMV = 25; cpi->ExhaustiveSearchThresh = 2500; cpi->MinImprovementForFourMV = 100; cpi->FourMVThreshold = 10000; cpi->BitRateCapFactor = 1.50; cpi->InterTripOutThresh = 5000; cpi->MVEnabled = 1; cpi->InterCodeCount = 127; cpi->BpbCorrectionFactor = 1.0; cpi->GoldenFrameEnabled = 1; cpi->InterPrediction = 1; cpi->MotionCompensation = 1; cpi->ThreshMapThreshold = 5; cpi->MaxConsDroppedFrames = 1; /* Set encoder flags. */ /* if not AutoKeyframing cpi->ForceKeyFrameEvery = is frequency */ if(!c->keyframe_auto_p) c->keyframe_frequency_force = c->keyframe_frequency; /* Set the frame rate variables. */ if ( c->fps_numerator < 1 ) c->fps_numerator = 1; if ( c->fps_denominator < 1 ) c->fps_denominator = 1; /* don't go too nuts on keyframe spacing; impose a high limit to make certain the granulepos encoding strategy works */ if(c->keyframe_frequency_force>32768)c->keyframe_frequency_force=32768; if(c->keyframe_mindistance>32768)c->keyframe_mindistance=32768; if(c->keyframe_mindistance>c->keyframe_frequency_force) c->keyframe_mindistance=c->keyframe_frequency_force; cpi->pb.keyframe_granule_shift=_ilog(c->keyframe_frequency_force-1); /* clamp the target_bitrate to a maximum of 24 bits so we get a more meaningful value when we write this out in the header. */ if(c->target_bitrate>(1<<24)-1)c->target_bitrate=(1<<24)-1; /* copy in config */ memcpy(&cpi->pb.info,c,sizeof(*c)); th->i=&cpi->pb.info; th->granulepos=-1; /* Set up default values for QTargetModifier[Q_TABLE_SIZE] table */ for ( i = 0; i < Q_TABLE_SIZE; i++ ) cpi->QTargetModifier[i] = 1.0; /* Set up an encode buffer */ #ifndef LIBOGG2 cpi->oggbuffer = _ogg_malloc(sizeof(oggpack_buffer)); oggpackB_writeinit(cpi->oggbuffer); #else cpi->oggbuffer = _ogg_malloc(oggpack_buffersize()); cpi->oggbufferstate = ogg_buffer_create(); oggpackB_writeinit(cpi->oggbuffer, cpi->oggbufferstate); #endif /* Set data rate related variables. */ cpi->Configuration.TargetBandwidth = (c->target_bitrate) / 8; cpi->Configuration.OutputFrameRate = (double)( c->fps_numerator / c->fps_denominator ); cpi->frame_target_rate = cpi->Configuration.TargetBandwidth / cpi->Configuration.OutputFrameRate; /* Set key frame data rate target; this is nominal keyframe size */ cpi->Configuration.KeyFrameDataTarget = (c->keyframe_data_target_bitrate * c->fps_denominator / c->fps_numerator ) / 8; /* Note the height and width in the pre-processor control structure. */ cpi->ScanConfig.VideoFrameHeight = cpi->pb.info.height; cpi->ScanConfig.VideoFrameWidth = cpi->pb.info.width; InitFrameDetails(&cpi->pb); InitFilterTables(&cpi->pb); EInitFragmentInfo(cpi); EInitFrameInfo(cpi); /* Set up pre-processor config pointers. */ cpi->ScanConfig.Yuv0ptr = cpi->yuv0ptr; cpi->ScanConfig.Yuv1ptr = cpi->yuv1ptr; cpi->ScanConfig.SrfWorkSpcPtr = cpi->ConvDestBuffer; cpi->ScanConfig.disp_fragments = cpi->pb.display_fragments; cpi->ScanConfig.RegionIndex = cpi->pb.pixel_index_table; /* Initialise the pre-processor module. */ ScanYUVInit(&cpi->pp, &(cpi->ScanConfig)); /* Initialise Motion compensation */ InitMotionCompensation(cpi); /* Initialise the compression process. */ /* We always start at frame 1 */ cpi->CurrentFrame = 1; /* Reset the rate targeting correction factor. */ cpi->BpbCorrectionFactor = 1.0; cpi->TotalByteCount = 0; cpi->TotalMotionScore = 0; /* Up regulation variables. */ cpi->FinalPassLastPos = 0; /* Used to regulate a final unrestricted pass. */ cpi->LastEndSB = 0; /* Where we were in the loop last time. */ cpi->ResidueLastEndSB = 0; /* Where we were in the residue update loop last time. */ InitHuffmanSet(&cpi->pb); /* This makes sure encoder version specific tables are initialised */ InitQTables(&cpi->pb); /* Indicate that the next frame to be compressed is the first in the current clip. */ cpi->ThisIsFirstFrame = 1; cpi->readyflag = 1; return 0; }
int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){ long i,j; int ordered=0; /* first the basic parameters */ oggpack_write(opb,0x564342,24); oggpack_write(opb,c->dim,16); oggpack_write(opb,c->entries,24); /* pack the codewords. There are two packings; length ordered and length random. Decide between the two now. */ for(i=1;i<c->entries;i++) if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break; if(i==c->entries)ordered=1; if(ordered){ /* length ordered. We only need to say how many codewords of each length. The actual codewords are generated deterministically */ long count=0; oggpack_write(opb,1,1); /* ordered */ oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */ for(i=1;i<c->entries;i++){ long thisx=c->lengthlist[i]; long last=c->lengthlist[i-1]; if(thisx>last){ for(j=last;j<thisx;j++){ oggpack_write(opb,i-count,_ilog(c->entries-count)); count=i; } } } oggpack_write(opb,i-count,_ilog(c->entries-count)); }else{ /* length random. Again, we don't code the codeword itself, just the length. This time, though, we have to encode each length */ oggpack_write(opb,0,1); /* unordered */ /* algortihmic mapping has use for 'unused entries', which we tag here. The algorithmic mapping happens as usual, but the unused entry has no codeword. */ for(i=0;i<c->entries;i++) if(c->lengthlist[i]==0)break; if(i==c->entries){ oggpack_write(opb,0,1); /* no unused entries */ for(i=0;i<c->entries;i++) oggpack_write(opb,c->lengthlist[i]-1,5); }else{ oggpack_write(opb,1,1); /* we have unused entries; thus we tag */ for(i=0;i<c->entries;i++){ if(c->lengthlist[i]==0){ oggpack_write(opb,0,1); }else{ oggpack_write(opb,1,1); oggpack_write(opb,c->lengthlist[i]-1,5); } } } } /* is the entry number the desired return value, or do we have a mapping? If we have a mapping, what type? */ oggpack_write(opb,c->maptype,4); switch(c->maptype){ case 0: /* no mapping */ break; case 1:case 2: /* implicitly populated value mapping */ /* explicitly populated value mapping */ if(!c->quantlist){ /* no quantlist? error */ return(-1); } /* values that define the dequantization */ oggpack_write(opb,c->q_min,32); oggpack_write(opb,c->q_delta,32); oggpack_write(opb,c->q_quant-1,4); oggpack_write(opb,c->q_sequencep,1); { int quantvals; switch(c->maptype){ case 1: /* a single column of (c->entries/c->dim) quantized values for building a full value list algorithmically (square lattice) */ quantvals=_book_maptype1_quantvals(c); break; case 2: /* every value (c->entries*c->dim total) specified explicitly */ quantvals=c->entries*c->dim; break; default: /* NOT_REACHABLE */ quantvals=-1; } /* quantized values */ for(i=0;i<quantvals;i++) oggpack_write(opb,labs(c->quantlist[i]),c->q_quant); } break; default: /* error case; we don't have any other map types now */ return(-1); } return(0); }
static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps) { GstStructure *structure = gst_caps_get_structure (caps, 0); GstTheoraEnc *enc = GST_THEORA_ENC (gst_pad_get_parent (pad)); guint32 fourcc; const GValue *par; gint fps_n, fps_d; gst_structure_get_fourcc (structure, "format", &fourcc); gst_structure_get_int (structure, "width", &enc->width); gst_structure_get_int (structure, "height", &enc->height); gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d); par = gst_structure_get_value (structure, "pixel-aspect-ratio"); th_info_clear (&enc->info); th_info_init (&enc->info); /* Theora has a divisible-by-sixteen restriction for the encoded video size but * we can define a picture area using pic_width/pic_height */ enc->info.frame_width = GST_ROUND_UP_16 (enc->width); enc->info.frame_height = GST_ROUND_UP_16 (enc->height); enc->info.pic_width = enc->width; enc->info.pic_height = enc->height; switch (fourcc) { case GST_MAKE_FOURCC ('I', '4', '2', '0'): enc->info.pixel_fmt = TH_PF_420; break; case GST_MAKE_FOURCC ('Y', '4', '2', 'B'): enc->info.pixel_fmt = TH_PF_422; break; case GST_MAKE_FOURCC ('Y', '4', '4', '4'): enc->info.pixel_fmt = TH_PF_444; break; default: g_assert_not_reached (); } enc->info.fps_numerator = enc->fps_n = fps_n; enc->info.fps_denominator = enc->fps_d = fps_d; if (par) { enc->info.aspect_numerator = gst_value_get_fraction_numerator (par); enc->info.aspect_denominator = gst_value_get_fraction_denominator (par); } else { /* setting them to 0 indicates that the decoder can chose a good aspect * ratio, defaulting to 1/1 */ enc->info.aspect_numerator = 0; enc->info.aspect_denominator = 0; } enc->info.colorspace = TH_CS_UNSPECIFIED; /* as done in theora */ enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1); GST_DEBUG_OBJECT (enc, "keyframe_frequency_force is %d, granule shift is %d", enc->keyframe_force, enc->info.keyframe_granule_shift); theora_enc_reset (enc); enc->initialised = TRUE; gst_object_unref (enc); return TRUE; }