2011-07-06 12 views
9

मैं libavcodecffmpeg :: avcodec_encode_video सेटिंग पीटीएस एच 264

ffmpeg::avcodec_encode_video(codec,output,size,avframe);

का उपयोग कर H264 के रूप में वीडियो को एन्कोड करने का प्रयास कर रहा हूं, एक त्रुटि देता है कि मेरे पास avframe-> pts मान सही ढंग से सेट नहीं है।
मैंने इसे 0,1, AV_NOPTS_VALUE और 90khz * framenumber पर सेट करने का प्रयास किया है, लेकिन फिर भी त्रुटि non-strictly-monotonic PTS

प्राप्त करें ffmpeg.c उदाहरण ffmpeg :: av_rescale_q() के साथ पैकेट.प्ट्स सेट करता है लेकिन इसे केवल बाद में बुलाया जाता है आपने फ्रेम को एन्कोड किया है!

जब MP4V कोडेक के साथ प्रयोग किया जाता है तो avcodec_encode_video() pts मान को सही ढंग से सेट करता है।

+2

"ppicture-> अंक = pCodecCtx-> frame_number," काम करता है –

उत्तर

0

मैं भी इस समस्या थी। जहाँ तक मुझे याद है कि, वे त्रुटि dts

की स्थापना

out_video_packet.dts = AV_NOPTS_VALUE; 

मुझे

0

मदद की एक सख्ती से monotonic समारोह में वृद्धि से संबंधित है एक समारोह जहां f (x) < च (y) अगर एक्स है < वाई। तो इसका मतलब है कि आप उसी पीटीएस के साथ 2 फ्रेम को एन्कोड नहीं कर सकते जैसा आप कर रहे थे ... उदाहरण के लिए काउंटर के साथ जांचें और इसे अब त्रुटि वापस नहीं करनी चाहिए।

6

मैं एक ही समस्या थी अंक की गणना के द्वारा इसे हल avcodec_encode_video बुला इस प्रकार से पहले,:, khz में बदला गया नमूना दर व्यक्त में हर्ट्ज दूर था:

//Calculate PTS: (1/FPS) * sample rate * frame number 
//sample rate 90KHz is for h.264 at 30 fps 
picture->pts = (1.0/30) * 90 * frame_count; 
out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture); 

समाधान this helpful blog post

(नोट से चोरी बहुत लंबा फ्रेम के बीच, यह मान के साथ खेलने के लिए आवश्यकता हो सकती है - एक वीडियो एन्कोडिंग यहां विशेषज्ञ नहीं, बस कुछ ऐसा है जो काम किया चाहता था और ऐसा किया)

1

मैं भी इस समस्या थी। मैं इस तरह से समस्या sloved:

इससे पहले कि आप आह्वान

ffmpeg::avcodec_encode_video(codec,output,size,avframe); 

आप सिर्फ इस तरह जो एक प्रारंभिक मान 0 और एक के बाद वेतन वृद्धि हर बार है avframe एक पूर्णांक मूल्य के अंक मान सेट,:

avframe->pts = nextPTS(); 

nextPTS के कार्यान्वयन() है:

int nextPTS() 
{ 
    static int static_pts = 0; 
    return static_pts ++; 
} 

टी देने के बाद वह एक मूल्य avframe के अंक, फिर इसे एन्कोड किया। अगर सफलतापूर्वक एन्कोडिंग। निम्नलिखित कोड जोड़ें:

if (packet.pts != AV_NOPTS_VALUE) 
     packet.pts = av_rescale_q(packet.pts, mOutputCodecCtxPtr->time_base, mOutputStreamPtr->time_base); 
    if (packet.dts != AV_NOPTS_VALUE) 
     packet.dts = av_rescale_q(packet.dts, mOutputCodecCtxPtr->time_base, mOutputStreamPtr->time_base); 

यह एन्कोडेड AVFrame के लिए सही डीटीएस मूल्य जोड़ देगा। कोड के बीच, एवीपैकेट प्रकार का पैक, mOutputCodeCtxPtr प्रकार के AVCodecContext * और mOutputStreamPtr प्रकार AVStream के प्रकार।

avcodec_encode_video रिटर्न 0 इंगित करता है वर्तमान फ्रेम बफ़र है, तो आप सब बफ़र फ्रेम फ्लश करने के बाद सभी फ्रेम इनकोडिंग किया गया है।कोड कुछ हद तक की तरह सभी बफ़र फ्रेम flushs:

int ret; 
while((ret = ffmpeg::avcodec_encode_video(codec,output,size,NULL)) >0) 
    ;// place your code here. 
एक नए संस्करण बंद ffmpeg सरल सेटिंग के साथ
+0

आपके अगले पीटीएस फ़ंक्शन ओवरफ़्लो के दौरान क्या होता है (यानी static_pts> INT_MAX)? – tmatth

+0

यदि static_pts अतिप्रवाह के खतरे में है, तो बस int से int64_t में अपना प्रकार बदल रहा है। – Alanmars

संबंधित मुद्दे