Need entire solution for very simple encoder. Encoder must write to external file only 1 frame Theora/OGG, and viewed by VLC acording to How to write bitmaps as frames to Ogg Theora in C\C++?
i create, follow Thalex manual this code (before i create bitmap of course):
/*
####################################################################################
##
## fill ycbcr with bitmap
##
####################################################################################
*/
ycbcr[0].width = 640;
ycbcr[0].height = 480;
ycbcr[0].stride = 640;
ycbcr[0].data = (unsigned char*)Y_luma;
ycbcr[1].width = 320;
ycbcr[1].height = 240;
ycbcr[1].stride = 320;
ycbcr[1].data = (unsigned char*)Cb_chroma;
ycbcr[2].width = 320;
ycbcr[2].height = 240;
ycbcr[2].stride = 320;
ycbcr[2].data = (unsigned char*)Cr_chroma;
/*
####################################################################################
##
## Call th_info_init() to initialise a th_info structure, then set up you output
## parameters by assigning the appropriate members in that
##
####################################################################################
*/
th_info_init(&ti);
ti.frame_width = 640;
ti.frame_height = 480;
ti.pic_width = 640;
ti.pic_height = 480;
ti.pic_x = 0;
ti.pic_y = 0;
ti.fps_numerator = 1;
ti.fps_denominator = 1;
ti.aspect_numerator = 1;
ti.aspect_denominator = 1;
ti.colorspace = TH_CS_UNSPECIFIED;
ti.target_bitrate = 500;
ti.quality = 50;
ti.keyframe_granule_shift = 0;
ti.pixel_fmt = TH_PF_420;
/*
####################################################################################
#开发者_运维百科#
## Use that structure in a call to th_encode_alloc() to get an encoder context
##
####################################################################################
*/
td = th_encode_alloc(&ti);
if(td==NULL)
{
printf("-E- negative return code initializing encoder!");
th_info_clear(&ti);
return false;
}
/*
####################################################################################
##
## Initialise a blank th_comment structure using th_comment_init
##
####################################################################################
*/
th_comment_init(&tc);
/*
####################################################################################
##
## Initialise an ogg stream, with ogg_stream_init()
##
####################################################################################
*/
ogg_stream_init(&to,rand());
if (th_encode_flushheader(td,&tc,&op)<=0)
{
printf("-E- Internal Theora Library Error!");
return false;
}
/*
####################################################################################
##
## Call th_encode_flushheader with the the encoder context, the blank comment
## structure and an ogg_packet.
##
####################################################################################
*/
if (th_encode_flushheader(td,&tc,&op)<=0)
{
printf("-E- Internal Theora Library Error!");
return false;
}
/* Theora is a one-frame-in,one-frame-out system; submit a frame
for compression and pull out the packet */
if(th_encode_ycbcr_in(td, ycbcr)) {
fprintf(stderr, "-E- Error: could not encode frame\n");
return -1;
}
if(!th_encode_packetout(td, 1, &op)) {
fprintf(stderr, "-E- [theora_write_frame] Error: could not read packets\n");
return -1;
}
/*
####################################################################################
##
## Send the resulting packet to the ogg stream with ogg_stream_packetin()
##
####################################################################################
*/
ogg_page og;
ogg_stream_packetin(&to,&op);
if (ogg_stream_pageout(&to,&og)!=1)
{
printf("-E- Internal Ogg library Error!");
return false;
}
/*
####################################################################################
##
## Until th_encode_flushheader returns 0 (or an error code)
## Now, repeatedly call ogg_stream_pageout(), every time writing the page.header and then page.body
## to an output file, until it returns 0.
## Now call ogg_stream_flush and write the resulting page to the file.
####################################################################################
*/
//int ret;
for(;;)
{
ret=th_encode_flushheader(td,&tc,&op);
if(ret<0)
{
printf("-E- Internal Theora library error.");
if (td!=NULL)
{
th_encode_free(td);
td=NULL;
}
th_comment_clear(&tc);
th_info_clear(&ti);
return false;
}
else if(!ret)
{ fwrite (og.header, 1 , sizeof(og.header) , fout );
fwrite (og.body, 1 , sizeof(og.body) , fout );
break;
}
ogg_stream_packetin(&to,&op);
}
int result;
for(;;){
int result = ogg_stream_flush(&to,&og);
if(result<0){
printf("-E- Internal Ogg library error.");
return false;
}
if(result==0)break;
fwrite(og.body,1,sizeof(og.body),fout);
}
But the resulting ogg file is only 12 bytes long. What is wrong in my steps?
fwrite(og.body,1,sizeof(og.body),fout);
This is incorrect. sizeof(og.body)
is a compile-time constant measuring the size of the member body
in struct ogg_page
, which is a pointer (so usually 4 or 8 bytes).
Try replacing that with:
fwrite(og.body, og.body_len, 1, fout);
精彩评论