मुझे वर्तमान में एक mp4 कंटेनर में कच्चे H264 नाल पैकेट को समाहित करने का प्रयास करने में समस्याएं हैं। हालांकि उन्हें डिस्क पर लिखने के बजाय, मैं परिणाम स्मृति में संग्रहीत करना चाहता हूं। मैंने इस दृष्टिकोण का पालन किया Raw H264 frames in mpegts container using libavcodec लेकिन अभी तक सफल नहीं हुआ है।एफएफएमपीईजी I/O आउटपुट बफर
सबसे पहले, क्या यह स्मृति को लिखने का सही तरीका है? मेरे हेडर
struct IOOutput {
uint8_t* outBuffer;
int bytesSet;
};
जहां मैं बफर और बाइटसेट शुरू करता हूं, में एक छोटी सी संरचना है। मैं तो प्रारंभ मेरी AVIOContext चर
AVIOContext* pIOCtx = avio_alloc_context(pBuffer, iBufSize, 1, outptr, NULL, write_packet, NULL);
जहां outptr IOOutput उत्पादन के लिए एक शून्य सूचक है, और write_packet निम्नलिखित
int write_packet (void *opaque, uint8_t *buf, int buf_size) {
IOOutput* out = reinterpret_cast<IOOutput*>(opaque);
memcpy(out->outBuffer+out->bytesSet, buf, buf_size);
out->bytesSet+=buf_size;
return buf_size;
}
मैं तो मेरे AVFormatContext पर
fc->pb = pIOCtx;
fc->flags = AVFMT_FLAG_CUSTOM_IO;
सेट की तरह दिखता है * एफसी चर।
फिर, जब भी मैं एनएएल पैकेट मैं एक फ्रेम से है सांकेतिक शब्दों में बदलना है, मैं उन्हें AVFormatContext को av_interleaved_write_frame के माध्यम से लिख सकते हैं और उसके बाद के माध्यम से
void getBufferContent(char* buffer) {
memcpy(buffer, output.outBuffer, output.bytesSet);
output.bytesSet=0;
}
mp4 सामग्री प्राप्त है और इस तरह के दौरान चर bytesSet रीसेट, तो अगले लेखन ऑपरेशन बाइट बफर की शुरुआत में डाला जाएगा। क्या ऐसा करने के लिए इससे अच्छा तरीका है? क्या यह वास्तव में ऐसा करने का एक वैध तरीका है? क्या पैफ जोड़ने के लिए एफएफएमपीईजी कोई रीडिंग ऑपरेशन करता है अगर मैं केवल av_interleaved_write_frame और avformat_write_header को कॉल करता हूं?
अग्रिम में बहुत बहुत धन्यवाद! मैं की तरह
int frame_size = x264_encoder_encode(obj->mEncoder, &obj->nals, &obj->i_nals, obj->pic_in, obj->pic_out);
int total_size=0;
for(int i=0; i<obj->i_nals;i++)
{
if (!obj->fc) {
obj->create(obj->nals[i].p_payload, obj->nals[i].i_payload);
}
if (obj->fc) {
obj->write_frame(obj->nals[i].p_payload, obj->nals[i].i_payload);
}
}
// Here I get the output values
int currentBufferSize = obj->output.bytesSet;
char* mem = new char[currentBufferSize];
obj->getBufferContent(mem);
और बना सकते हैं और लिखने कार्यों इस
int create(void *p, int len) {
AVOutputFormat *of = av_guess_format("mp4", 0, 0);
fc = avformat_alloc_context();
// Add video stream
AVStream *pst = av_new_stream(fc, 0);
vi = pst->index;
void* outptr = (void*) &output;
// Create Buffer
pIOCtx = avio_alloc_context(pBuffer, iBufSize, 1, outptr, NULL, write_packet, NULL);
fc->oformat = of;
fc->pb = pIOCtx;
fc->flags = AVFMT_FLAG_CUSTOM_IO;
pcc = pst->codec;
AVCodec c= {0};
c.type= AVMEDIA_TYPE_VIDEO;
avcodec_get_context_defaults3(pcc, &c);
pcc->codec_type = AVMEDIA_TYPE_VIDEO;
pcc->codec_id = codec_id;
pcc->bit_rate = br;
pcc->width = w;
pcc->height = h;
pcc->time_base.num = 1;
pcc->time_base.den = fps;
}
void write_frame(const void* p, int len) {
AVStream *pst = fc->streams[ vi ];
// Init packet
AVPacket pkt;
av_init_packet(&pkt);
pkt.flags |= (0 >= getVopType(p, len)) ? AV_PKT_FLAG_KEY : 0;
pkt.stream_index = pst->index;
pkt.data = (uint8_t*)p;
pkt.size = len;
pkt.dts = AV_NOPTS_VALUE;
pkt.pts = AV_NOPTS_VALUE;
av_interleaved_write_frame(fc, &pkt);
}
आपको इस एफएफएमपीईजी पैच को देखने में रुचि हो सकती है: https://ffmpeg.org/pipermail/ffmpeg-devel/2014-November/164996.html हालांकि मुझे वास्तविक "डॉक्टर/उदाहरण/avio_writing.c "एफएफएमपीजी के गिट में ... – Gediminas