/********************************************************************************* * recordMyDesktop * ********************************************************************************** * * * Copyright (C) 2006 John Varouhakis * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * * * * * * For further information contact me at biocrasher@gmail.com * **********************************************************************************/ #include void InitEncoder(ProgData *pdata,EncData *enc_data_t){ int y1,y2; (pdata)->enc_data=enc_data_t; srand(time(NULL)); y1=rand(); y2=rand(); y2+=(y1==y2); ogg_stream_init(&(enc_data_t)->m_ogg_ts,y1); if(!pdata->args.nosound) ogg_stream_init(&(enc_data_t)->m_ogg_vs,y2); (enc_data_t)->fp=fopen((pdata)->args.filename,"w"); theora_info_init(&(enc_data_t)->m_th_inf); (enc_data_t)->m_th_inf.frame_width=(pdata)->brwin.rgeom.width; (enc_data_t)->m_th_inf.frame_height=(pdata)->brwin.rgeom.height; (enc_data_t)->m_th_inf.width=(((enc_data_t)->m_th_inf.frame_width + 15) >>4)<<4; (enc_data_t)->m_th_inf.height=(((enc_data_t)->m_th_inf.frame_height + 15) >>4)<<4; (enc_data_t)->m_th_inf.offset_x=(((enc_data_t)->m_th_inf.width-(enc_data_t)->m_th_inf.frame_width)/2)&~1; (enc_data_t)->m_th_inf.offset_y=(((enc_data_t)->m_th_inf.height-(enc_data_t)->m_th_inf.frame_height)/2)&~1; (enc_data_t)->m_th_inf.fps_numerator=((pdata)->args.fps*100.0); (enc_data_t)->m_th_inf.fps_denominator=100; (enc_data_t)->m_th_inf.aspect_numerator=(pdata)->brwin.rgeom.width; (enc_data_t)->m_th_inf.aspect_denominator=(pdata)->brwin.rgeom.height; (enc_data_t)->m_th_inf.colorspace=OC_CS_UNSPECIFIED; (enc_data_t)->m_th_inf.pixelformat=OC_PF_420; (enc_data_t)->m_th_inf.target_bitrate=(pdata)->args.v_bitrate; (enc_data_t)->m_th_inf.quality=(pdata)->args.v_quality; (enc_data_t)->m_th_inf.dropframes_p=0; (enc_data_t)->m_th_inf.quick_p=1; (enc_data_t)->m_th_inf.keyframe_auto_p=1; (enc_data_t)->m_th_inf.keyframe_frequency=64; (enc_data_t)->m_th_inf.keyframe_frequency_force=64; (enc_data_t)->m_th_inf.keyframe_data_target_bitrate=(enc_data_t)->m_th_inf.quality*1.5; (enc_data_t)->m_th_inf.keyframe_auto_threshold=80; (enc_data_t)->m_th_inf.keyframe_mindistance=8; (enc_data_t)->m_th_inf.noise_sensitivity=1; theora_encode_init(&(enc_data_t)->m_th_st,&(enc_data_t)->m_th_inf); if(!pdata->args.nosound){ int ret; vorbis_info_init(&(enc_data_t)->m_vo_inf); ret = vorbis_encode_init_vbr(&(enc_data_t)->m_vo_inf,pdata->args.channels,pdata->args.frequency,(float)pdata->args.s_quality*0.1); if(ret){ fprintf(stderr,"Error while setting up vorbis stream quality!\n"); exit(1); } vorbis_comment_init(&(enc_data_t)->m_vo_cmmnt); vorbis_analysis_init(&(enc_data_t)->m_vo_dsp,&(enc_data_t)->m_vo_inf); vorbis_block_init(&(enc_data_t)->m_vo_dsp,&(enc_data_t)->m_vo_block); } theora_encode_header(&(enc_data_t)->m_th_st,&(enc_data_t)->m_ogg_pckt1); ogg_stream_packetin(&(enc_data_t)->m_ogg_ts,&(enc_data_t)->m_ogg_pckt1); if(ogg_stream_pageout(&(enc_data_t)->m_ogg_ts,&(enc_data_t)->m_ogg_pg)!=1){ fprintf(stderr,"Internal Ogg library error.\n"); exit(1); } fwrite((enc_data_t)->m_ogg_pg.header,1,(enc_data_t)->m_ogg_pg.header_len,(enc_data_t)->fp); fwrite((enc_data_t)->m_ogg_pg.body,1,(enc_data_t)->m_ogg_pg.body_len,(enc_data_t)->fp); theora_comment_init(&(enc_data_t)->m_th_cmmnt); theora_comment_add_tag(&(enc_data_t)->m_th_cmmnt,"recordMyDesktop",VERSION); theora_encode_comment(&(enc_data_t)->m_th_cmmnt,&(enc_data_t)->m_ogg_pckt1); ogg_stream_packetin(&(enc_data_t)->m_ogg_ts,&(enc_data_t)->m_ogg_pckt1); theora_encode_tables(&(enc_data_t)->m_th_st,&(enc_data_t)->m_ogg_pckt1); ogg_stream_packetin(&(enc_data_t)->m_ogg_ts,&(enc_data_t)->m_ogg_pckt1); if(!pdata->args.nosound){ ogg_packet header; ogg_packet header_comm; ogg_packet header_code; vorbis_analysis_headerout(&(enc_data_t)->m_vo_dsp,&(enc_data_t)->m_vo_cmmnt,&header,&header_comm,&header_code); ogg_stream_packetin(&(enc_data_t)->m_ogg_vs,&header); if(ogg_stream_pageout(&(enc_data_t)->m_ogg_vs,&(enc_data_t)->m_ogg_pg)!=1){ fprintf(stderr,"Internal Ogg library error.\n"); exit(1); } fwrite((enc_data_t)->m_ogg_pg.header,1,(enc_data_t)->m_ogg_pg.header_len,(enc_data_t)->fp); fwrite((enc_data_t)->m_ogg_pg.body,1,(enc_data_t)->m_ogg_pg.body_len,(enc_data_t)->fp); ogg_stream_packetin(&(enc_data_t)->m_ogg_vs,&header_comm); ogg_stream_packetin(&(enc_data_t)->m_ogg_vs,&header_code); } while(1){ int result = ogg_stream_flush(&(enc_data_t)->m_ogg_ts,&(enc_data_t)->m_ogg_pg); if(result<0){ fprintf(stderr,"Internal Ogg library error.\n"); exit(1); } if(result==0)break; fwrite((enc_data_t)->m_ogg_pg.header,1,(enc_data_t)->m_ogg_pg.header_len,(enc_data_t)->fp); fwrite((enc_data_t)->m_ogg_pg.body,1,(enc_data_t)->m_ogg_pg.body_len,(enc_data_t)->fp); } if(!pdata->args.nosound){ while(1){ int result=ogg_stream_flush(&(enc_data_t)->m_ogg_vs,&(enc_data_t)->m_ogg_pg); if(result<0){ fprintf(stderr,"Internal Ogg library error.\n"); exit(1); } if(result==0)break; fwrite((enc_data_t)->m_ogg_pg.header,1,(enc_data_t)->m_ogg_pg.header_len,(enc_data_t)->fp); fwrite((enc_data_t)->m_ogg_pg.body,1,(enc_data_t)->m_ogg_pg.body_len,(enc_data_t)->fp); } } (enc_data_t)->yuv.y=(unsigned char *)malloc((pdata)->image->height*((ProgData *)pdata)->image->width); (enc_data_t)->yuv.u=(unsigned char *)malloc((pdata)->image->height*((ProgData *)pdata)->image->width/4); (enc_data_t)->yuv.v=(unsigned char *)malloc((pdata)->image->height*((ProgData *)pdata)->image->width/4); (enc_data_t)->yuv.y_width=(enc_data_t)->m_th_inf.width; (enc_data_t)->yuv.y_height=(enc_data_t)->m_th_inf.height; (enc_data_t)->yuv.y_stride=(enc_data_t)->m_th_inf.width; (enc_data_t)->yuv.uv_width=(enc_data_t)->m_th_inf.width/2; (enc_data_t)->yuv.uv_height=(enc_data_t)->m_th_inf.height/2; (enc_data_t)->yuv.uv_stride=(enc_data_t)->m_th_inf.width/2; theora_info_clear(&(enc_data_t)->m_th_inf); }