/* 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); }
/* 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; opb = _ogg_malloc(sizeof(oggpack_buffer)); oggpackB_writeinit(opb); 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); /* 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); _ogg_free(opb); op->b_o_s=0; op->e_o_s=0; op->packetno=0; op->granulepos=0; return (0); }