⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encoder_toplevel.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 3 页
字号:
  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 theora_encode_YUVin(theora_state *t,                         yuv_buffer *yuv){  ogg_int32_t i;  unsigned char *LocalDataPtr;  unsigned char *InputDataPtr;  CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);  if(!cpi->readyflag)return OC_EINVAL;  if(cpi->doneflag)return OC_EINVAL;  /* If frame size has changed, abort out for now */  if (yuv->y_height != (int)cpi->pb.info.height ||      yuv->y_width != (int)cpi->pb.info.width )    return(-1);  /* Copy over input YUV to internal YUV buffers. */  /* we invert the image for backward compatibility with VP3 */  /* First copy over the Y data */  LocalDataPtr = cpi->yuv1ptr + yuv->y_width*(yuv->y_height - 1);  InputDataPtr = yuv->y;  for ( i = 0; i < yuv->y_height; i++ ){    memcpy( LocalDataPtr, InputDataPtr, yuv->y_width );    LocalDataPtr -= yuv->y_width;    InputDataPtr += yuv->y_stride;  }  /* Now copy over the U data */  LocalDataPtr = &cpi->yuv1ptr[(yuv->y_height * yuv->y_width)];  LocalDataPtr += yuv->uv_width*(yuv->uv_height - 1);  InputDataPtr = yuv->u;  for ( i = 0; i < yuv->uv_height; i++ ){    memcpy( LocalDataPtr, InputDataPtr, yuv->uv_width );    LocalDataPtr -= yuv->uv_width;    InputDataPtr += yuv->uv_stride;  }  /* Now copy over the V data */  LocalDataPtr =    &cpi->yuv1ptr[((yuv->y_height*yuv->y_width)*5)/4];  LocalDataPtr += yuv->uv_width*(yuv->uv_height - 1);  InputDataPtr = yuv->v;  for ( i = 0; i < yuv->uv_height; i++ ){    memcpy( LocalDataPtr, InputDataPtr, yuv->uv_width );    LocalDataPtr -= yuv->uv_width;    InputDataPtr += yuv->uv_stride;  }  /* Special case for first frame */  if ( cpi->ThisIsFirstFrame ){    CompressFirstFrame(cpi);    cpi->ThisIsFirstFrame = 0;    cpi->ThisIsKeyFrame = 0;  } else {    /* don't allow generating invalid files that overflow the p-frame       shift, even if keyframe_auto_p is turned off */    if(cpi->LastKeyFrame >= (ogg_uint32_t)       cpi->pb.info.keyframe_frequency_force)      cpi->ThisIsKeyFrame = 1;        if ( cpi->ThisIsKeyFrame ) {      CompressKeyFrame(cpi);      cpi->ThisIsKeyFrame = 0;    } else  {      /* Compress the frame. */      CompressFrame( cpi );    }  }  /* Update stats variables. */  cpi->LastFrameSize = oggpackB_bytes(cpi->oggbuffer);  cpi->CurrentFrame++;  cpi->packetflag=1;  t->granulepos=    ((cpi->CurrentFrame-cpi->LastKeyFrame-1)<<cpi->pb.keyframe_granule_shift)+    cpi->LastKeyFrame-1;  return 0;}int theora_encode_packetout( theora_state *t, int last_p, ogg_packet *op){  CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);  long bytes=oggpackB_bytes(cpi->oggbuffer);  if(!bytes)return(0);  if(!cpi->packetflag)return(0);  if(cpi->doneflag)return(-1);#ifndef LIBOGG2  op->packet=oggpackB_get_buffer(cpi->oggbuffer);#else  op->packet=oggpackB_writebuffer(cpi->oggbuffer);#endif  op->bytes=bytes;  op->b_o_s=0;  op->e_o_s=last_p;  op->packetno=cpi->CurrentFrame;  op->granulepos=t->granulepos;  cpi->packetflag=0;  if(last_p)cpi->doneflag=1;  return 1;}static void _tp_writebuffer(oggpack_buffer *opb, const char *buf, const long len){  long i;  for (i = 0; i < len; i++)    oggpackB_write(opb, *buf++, 8);}static void _tp_writelsbint(oggpack_buffer *opb, long value){  oggpackB_write(opb, value&0xFF, 8);   oggpackB_write(opb, value>>8&0xFF, 8);  oggpackB_write(opb, value>>16&0xFF, 8);  oggpackB_write(opb, value>>24&0xFF, 8);}/* build the initial short header for stream recognition and format */int theora_encode_header(theora_state *t, ogg_packet *op){  CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);  int offset_y;#ifndef LIBOGG2  oggpackB_reset(cpi->oggbuffer);#else  oggpackB_writeinit(cpi->oggbuffer, cpi->oggbufferstate);#endif  oggpackB_write(cpi->oggbuffer,0x80,8);  _tp_writebuffer(cpi->oggbuffer, "theora", 6);  oggpackB_write(cpi->oggbuffer,VERSION_MAJOR,8);  oggpackB_write(cpi->oggbuffer,VERSION_MINOR,8);  oggpackB_write(cpi->oggbuffer,VERSION_SUB,8);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.width>>4,16);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.height>>4,16);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.frame_width,24);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.frame_height,24);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.offset_x,8);  /* Applications use offset_y to mean offset from the top of the image; the   * meaning in the bitstream is the opposite (from the bottom). Transform.   */  offset_y = cpi->pb.info.height - cpi->pb.info.frame_height -     cpi->pb.info.offset_y;  oggpackB_write(cpi->oggbuffer,offset_y,8);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.fps_numerator,32);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.fps_denominator,32);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.aspect_numerator,24);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.aspect_denominator,24);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.colorspace,8);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.target_bitrate,24);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.quality,6);  oggpackB_write(cpi->oggbuffer,cpi->pb.keyframe_granule_shift,5);  oggpackB_write(cpi->oggbuffer,cpi->pb.info.pixelformat,2);  oggpackB_write(cpi->oggbuffer,0,3); /* spare config bits */#ifndef LIBOGG2  op->packet=oggpackB_get_buffer(cpi->oggbuffer);#else  op->packet=oggpackB_writebuffer(cpi->oggbuffer);#endif  op->bytes=oggpackB_bytes(cpi->oggbuffer);  op->b_o_s=1;  op->e_o_s=0;  op->packetno=0;  op->granulepos=0;  cpi->packetflag=0;  return(0);}/* build the comment header packet from the passed metadata */int theora_encode_comment(theora_comment *tc, ogg_packet *op){  const char *vendor = theora_version_string();  const int vendor_length = strlen(vendor);  oggpack_buffer *opb;#ifndef LIBOGG2  opb = _ogg_malloc(sizeof(oggpack_buffer));  oggpackB_writeinit(opb);#else  opb = _ogg_malloc(oggpack_buffersize());  oggpackB_writeinit(opb, ogg_buffer_create());#endif   oggpackB_write(opb, 0x81, 8);  _tp_writebuffer(opb, "theora", 6);  _tp_writelsbint(opb, vendor_length);  _tp_writebuffer(opb, vendor, vendor_length);  _tp_writelsbint(opb, tc->comments);  if(tc->comments){    int i;    for(i=0;i<tc->comments;i++){      if(tc->user_comments[i]){        _tp_writelsbint(opb,tc->comment_lengths[i]);        _tp_writebuffer(opb,tc->user_comments[i],tc->comment_lengths[i]);      }else{        oggpackB_write(opb,0,32);      }    }  }  op->bytes=oggpack_bytes(opb);#ifndef LIBOGG2  /* So we're expecting the application will free this? */  op->packet=_ogg_malloc(oggpack_bytes(opb));  memcpy(op->packet, oggpack_get_buffer(opb), oggpack_bytes(opb));  oggpack_writeclear(opb);#else  op->packet = oggpack_writebuffer(opb);  /* When the application puts op->packet into a stream_state object,     it becomes the property of libogg2's internal memory management. */#endif  _ogg_free(opb);  op->b_o_s=0;  op->e_o_s=0;  op->packetno=0;  op->granulepos=0;  return (0);}/* build the final header packet with the tables required   for decode */int theora_encode_tables(theora_state *t, ogg_packet *op){  CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);#ifndef LIBOGG2  oggpackB_reset(cpi->oggbuffer);#else  oggpackB_writeinit(cpi->oggbuffer, cpi->oggbufferstate);#endif  oggpackB_write(cpi->oggbuffer,0x82,8);  _tp_writebuffer(cpi->oggbuffer,"theora",6);  WriteFilterTables(&cpi->pb,cpi->oggbuffer);  WriteQTables(&cpi->pb,cpi->oggbuffer);  WriteHuffmanTrees(cpi->pb.HuffRoot_VP3x,cpi->oggbuffer);#ifndef LIBOGG2  op->packet=oggpackB_get_buffer(cpi->oggbuffer);#else  op->packet=oggpackB_writebuffer(cpi->oggbuffer);#endif  op->bytes=oggpackB_bytes(cpi->oggbuffer);  op->b_o_s=0;  op->e_o_s=0;  op->packetno=0;  op->granulepos=0;  cpi->packetflag=0;  return(0);}void theora_encoder_clear (CP_INSTANCE * cpi){  if(cpi){        ClearHuffmanSet(&cpi->pb);    ClearFragmentInfo(&cpi->pb);    ClearFrameInfo(&cpi->pb);    EClearFragmentInfo(cpi);    EClearFrameInfo(cpi);    ClearTmpBuffers(&cpi->pb);    ClearPPInstance(&cpi->pp);        oggpackB_writeclear(cpi->oggbuffer);    _ogg_free(cpi->oggbuffer);    _ogg_free(cpi);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -