encinfo.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include "state.h"
  4. #include "enquant.h"
  5. #include "huffenc.h"
  6. /*Packs a series of octets from a given byte array into the pack buffer.
  7. _opb: The pack buffer to store the octets in.
  8. _buf: The byte array containing the bytes to pack.
  9. _len: The number of octets to pack.*/
  10. static void oc_pack_octets(oggpack_buffer *_opb,const char *_buf,int _len){
  11. int i;
  12. for(i=0;i<_len;i++)oggpackB_write(_opb,_buf[i],8);
  13. }
  14. int oc_state_flushheader(oc_theora_state *_state,int *_packet_state,
  15. oggpack_buffer *_opb,const th_quant_info *_qinfo,
  16. const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS],
  17. const char *_vendor,th_comment *_tc,ogg_packet *_op){
  18. unsigned char *packet;
  19. int b_o_s;
  20. if(_op==NULL)return TH_EFAULT;
  21. switch(*_packet_state){
  22. /*Codec info header.*/
  23. case OC_PACKET_INFO_HDR:{
  24. if(_state==NULL)return TH_EFAULT;
  25. oggpackB_reset(_opb);
  26. /*Mark this packet as the info header.*/
  27. oggpackB_write(_opb,0x80,8);
  28. /*Write the codec string.*/
  29. oc_pack_octets(_opb,"theora",6);
  30. /*Write the codec bitstream version.*/
  31. oggpackB_write(_opb,TH_VERSION_MAJOR,8);
  32. oggpackB_write(_opb,TH_VERSION_MINOR,8);
  33. oggpackB_write(_opb,TH_VERSION_SUB,8);
  34. /*Describe the encoded frame.*/
  35. oggpackB_write(_opb,_state->info.frame_width>>4,16);
  36. oggpackB_write(_opb,_state->info.frame_height>>4,16);
  37. oggpackB_write(_opb,_state->info.pic_width,24);
  38. oggpackB_write(_opb,_state->info.pic_height,24);
  39. oggpackB_write(_opb,_state->info.pic_x,8);
  40. oggpackB_write(_opb,_state->info.pic_y,8);
  41. oggpackB_write(_opb,_state->info.fps_numerator,32);
  42. oggpackB_write(_opb,_state->info.fps_denominator,32);
  43. oggpackB_write(_opb,_state->info.aspect_numerator,24);
  44. oggpackB_write(_opb,_state->info.aspect_denominator,24);
  45. oggpackB_write(_opb,_state->info.colorspace,8);
  46. oggpackB_write(_opb,_state->info.target_bitrate,24);
  47. oggpackB_write(_opb,_state->info.quality,6);
  48. oggpackB_write(_opb,_state->info.keyframe_granule_shift,5);
  49. oggpackB_write(_opb,_state->info.pixel_fmt,2);
  50. /*Spare configuration bits.*/
  51. oggpackB_write(_opb,0,3);
  52. b_o_s=1;
  53. }break;
  54. /*Comment header.*/
  55. case OC_PACKET_COMMENT_HDR:{
  56. int vendor_len;
  57. int i;
  58. if(_tc==NULL)return TH_EFAULT;
  59. vendor_len=strlen(_vendor);
  60. oggpackB_reset(_opb);
  61. /*Mark this packet as the comment header.*/
  62. oggpackB_write(_opb,0x81,8);
  63. /*Write the codec string.*/
  64. oc_pack_octets(_opb,"theora",6);
  65. /*Write the vendor string.*/
  66. oggpack_write(_opb,vendor_len,32);
  67. oc_pack_octets(_opb,_vendor,vendor_len);
  68. oggpack_write(_opb,_tc->comments,32);
  69. for(i=0;i<_tc->comments;i++){
  70. if(_tc->user_comments[i]!=NULL){
  71. oggpack_write(_opb,_tc->comment_lengths[i],32);
  72. oc_pack_octets(_opb,_tc->user_comments[i],_tc->comment_lengths[i]);
  73. }
  74. else oggpack_write(_opb,0,32);
  75. }
  76. b_o_s=0;
  77. }break;
  78. /*Codec setup header.*/
  79. case OC_PACKET_SETUP_HDR:{
  80. int ret;
  81. oggpackB_reset(_opb);
  82. /*Mark this packet as the setup header.*/
  83. oggpackB_write(_opb,0x82,8);
  84. /*Write the codec string.*/
  85. oc_pack_octets(_opb,"theora",6);
  86. /*Write the quantizer tables.*/
  87. oc_quant_params_pack(_opb,_qinfo);
  88. /*Write the huffman codes.*/
  89. ret=oc_huff_codes_pack(_opb,_codes);
  90. /*This should never happen, because we validate the tables when they
  91. are set.
  92. If you see, it's a good chance memory is being corrupted.*/
  93. if(ret<0)return ret;
  94. b_o_s=0;
  95. }break;
  96. /*No more headers to emit.*/
  97. default:return 0;
  98. }
  99. /*This is kind of fugly: we hand the user a buffer which they do not own.
  100. We will overwrite it when the next packet is output, so the user better be
  101. done with it by then.
  102. Vorbis is little better: it hands back buffers that it will free the next
  103. time the headers are requested, or when the encoder is cleared.
  104. Hopefully libogg2 will make this much cleaner.*/
  105. packet=oggpackB_get_buffer(_opb);
  106. /*If there's no packet, malloc failed while writing.*/
  107. if(packet==NULL)return TH_EFAULT;
  108. _op->packet=packet;
  109. _op->bytes=oggpackB_bytes(_opb);
  110. _op->b_o_s=b_o_s;
  111. _op->e_o_s=0;
  112. _op->granulepos=0;
  113. _op->packetno=*_packet_state+3;
  114. return ++(*_packet_state)+3;
  115. }