सी \ सी ++ में ओग थियोरा के फ्रेम के रूप में बिटमैप्स कैसे लिखें?सी सी ++ में ओग थियोरा के फ्रेम के रूप में बिटमैप्स कैसे लिखें?
स्रोत के साथ कुछ उदाहरणों में जाली होगा!)
सी \ सी ++ में ओग थियोरा के फ्रेम के रूप में बिटमैप्स कैसे लिखें?सी सी ++ में ओग थियोरा के फ्रेम के रूप में बिटमैप्स कैसे लिखें?
स्रोत के साथ कुछ उदाहरणों में जाली होगा!)
यहाँ libtheora API और example code है।
यहां एक micro howto है जो दिखाता है कि थियोरा बाइनरी का उपयोग कैसे करें। चूंकि एन्कोडर वीडियो के लिए कच्चे, असम्पीडित 'yuv4mpeg' डेटा को पढ़ता है, तो आप वीडियो एप को एन्कोडर पर पाइप करके भी अपने ऐप से इसका उपयोग कर सकते हैं।
संपूर्ण समाधान यहां कोड नमूना के रूप में पोस्ट करने के लिए थोड़ा लंबा है, लेकिन यदि आप Xiph.org से libtheora डाउनलोड करते हैं, तो एक उदाहरण png2theora है। मेरे द्वारा उल्लेख किए जाने वाले सभी पुस्तकालय कार्यों को थियोरा और ओग के लिए Xiph.org पर प्रलेखन में पाया जा सकता है।
दोहराएं का उपयोग कर एक खाली th_comment संरचना Initialise :
th_encode_flushheader तक रिटर्न 0 (या एक त्रुटि कोड)
साथ ogg धारा के परिणामस्वरूप पैकेट भेजें अब, बार-बार फोन ogg_stream_pageout(), हर बार और उसके बाद पृष्ठ। किसी आउटपुट फ़ाइल में, जब तक यह 0 न हो जाए। अब ogg_stream_flush को कॉल करें और परिणामी पृष्ठ को फ़ाइल में लिखें।
अब आप एन्कोडर में फ्रेम लिख सकते हैं। यहाँ है कैसे मैंने किया:
int theora_write_frame(int outputFd, unsigned long w, unsigned long h, unsigned char *yuv_y, unsigned char *yuv_u, unsigned char *yuv_v, int last)
{
th_ycbcr_buffer ycbcr;
ogg_packet op;
ogg_page og;
unsigned long yuv_w;
unsigned long yuv_h;
/* Must hold: yuv_w >= w */
yuv_w = (w + 15) & ~15;
/* Must hold: yuv_h >= h */
yuv_h = (h + 15) & ~15;
//Fill out the ycbcr buffer
ycbcr[0].width = yuv_w;
ycbcr[0].height = yuv_h;
ycbcr[0].stride = yuv_w;
ycbcr[1].width = yuv_w;
ycbcr[1].stride = ycbcr[1].width;
ycbcr[1].height = yuv_h;
ycbcr[2].width = ycbcr[1].width;
ycbcr[2].stride = ycbcr[1].stride;
ycbcr[2].height = ycbcr[1].height;
if(encoderInfo->pixel_fmt == TH_PF_420)
{
//Chroma is decimated by 2 in both directions
ycbcr[1].width = yuv_w >> 1;
ycbcr[2].width = yuv_w >> 1;
ycbcr[1].height = yuv_h >> 1;
ycbcr[2].height = yuv_h >> 1;
}else if(encoderInfo->pixel_fmt == TH_PF_422)
{
ycbcr[1].width = yuv_w >> 1;
ycbcr[2].width = yuv_w >> 1;
}else if(encoderInfo->pixel_fmt != TH_PF_422)
{
//Then we have an unknown pixel format
//We don't know how long the arrays are!
fprintf(stderr, "[theora_write_frame] Unknown pixel format in writeFrame!\n");
return -1;
}
ycbcr[0].data = yuv_y;
ycbcr[1].data = yuv_u;
ycbcr[2].data = yuv_v;
/* 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(encoderContext, ycbcr)) {
fprintf(stderr, "[theora_write_frame] Error: could not encode frame\n");
return -1;
}
if(!th_encode_packetout(encoderContext, last, &op)) {
fprintf(stderr, "[theora_write_frame] Error: could not read packets\n");
return -1;
}
ogg_stream_packetin(&theoraStreamState, &op);
ssize_t bytesWritten = 0;
int pagesOut = 0;
while(ogg_stream_pageout(&theoraStreamState, &og)) {
pagesOut ++;
bytesWritten = write(outputFd, og.header, og.header_len);
if(bytesWritten != og.header_len)
{
fprintf(stderr, "[theora_write_frame] Error: Could not write to file\n");
return -1;
}
bytesWritten = write(outputFd, og.body, og.body_len);
if(bytesWritten != og.body_len)
{
bytesWritten = fprintf(stderr, "[theora_write_frame] Error: Could not write to file\n");
return -1;
}
}
return pagesOut;
}
कहाँ encoderInfo th_info एनकोडर (मेरे लिए डेटा अनुभाग में स्थिर) आरंभ करने के लिए इस्तेमाल संरचना है।
अपने अंतिम फ्रेम पर, th_encode_packetout() पर अंतिम फ्रेम सेट करने से यह सुनिश्चित हो जाएगा कि स्ट्रीम ठीक से समाप्त हो जाए।
एक बार ऐसा करने के बाद, बस साफ करना सुनिश्चित करें (मुख्य रूप से fds बंद करना)। th_info_clear() th_info संरचना को साफ़ कर देगा, और th_encode_free() आपके एन्कोडर संदर्भ को मुक्त कर देगा।
जाहिर है, आपको अपने बिटमैप को YUV विमानों में कनवर्ट करने से पहले आपको theora_write_frame() में स्थानांतरित करने की आवश्यकता होगी।
आशा है कि यह कुछ मदद की है। सौभाग्य!