av_write_frame(outputFormatCtx, &pkt);
这是我到目前为止的努力,在从返回的编码器缓冲区解析SP和pps之后。(在memcping到sps和pps之前,我删除了前导的0x0000001 nal分隔符)。
if ((sps) && (pps)) {
//length of extradata is 6 bytes + 2 bytes for spslen + sps + 1 byte number of pps + 2 bytes for ppslen + pps
uint32_t extradata_len = 8 + spslen + 1 + 2 + ppslen;
outputStream->codecpar->extradata = (uint8_t*)av_mallocz(extradata_len);
outputStream->codecpar->extradata_size = extradata_len;
//start writing avcc extradata
outputStream->codecpar->extradata[0] = 0x01; //version
outputStream->codecpar->extradata[1] = sps[1]; //profile
outputStream->codecpar->extradata[2] = sps[2]; //comatibility
outputStream->codecpar->extradata[3] = sps[3]; //level
outputStream->codecpar->extradata[4] = 0xFC | 3; // reserved (6 bits), NALU length size - 1 (2 bits) which is 3
outputStream->codecpar->extradata[5] = 0xE0 | 1; // reserved (3 bits), num of SPS (5 bits) which is 1 sps
//write sps length
memcpy(&outputStream->codecpar->extradata[6],&spslen,2);
//Check to see if written correctly
uint16_t *cspslen=(uint16_t *)&outputStream->codecpar->extradata[6];
fprintf(stderr,"SPS length Wrote %d and read %d \n",spslen,*cspslen);
//Write the actual sps
int i = 0;
for (i=0; i<spslen; i++) {
outputStream->codecpar->extradata[8 + i] = sps[i];
}
for (size_t i = 0; i != outputStream->codecpar->extradata_size; ++i)
fprintf(stderr, "\\%02x", (unsigned char)outputStream->codecpar->extradata[i]);
fprintf(stderr,"\n");
//Number of pps
outputStream->codecpar->extradata[8 + spslen] = 0x01;
//Size of pps
memcpy(&outputStream->codecpar->extradata[8+spslen+1],&ppslen,2);
for (size_t i = 0; i != outputStream->codecpar->extradata_size; ++i)
fprintf(stderr, "\\%02x", (unsigned char)outputStream->codecpar->extradata[i]);
fprintf(stderr,"\n");
//Check to see if written correctly
uint16_t *cppslen=(uint16_t *)&outputStream->codecpar->extradata[+8+spslen+1];
fprintf(stderr,"PPS length Wrote %d and read %d \n",ppslen,*cppslen);
//Write actual PPS
for (i=0; i<ppslen; i++) {
outputStream->codecpar->extradata[8 + spslen + 1 + 2 + i] = pps[i];
}
//Output the extradata to check
for (size_t i = 0; i != outputStream->codecpar->extradata_size; ++i)
fprintf(stderr, "\\%02x", (unsigned char)outputStream->codecpar->extradata[i]);
fprintf(stderr,"\n");
//Access the outputFormatCtx internal AVCodecContext and copy the codecpar to it
AVCodecContext *avctx= outputFormatCtx->streams[0]->codec;
fprintf(stderr,"Extradata size output stream sps pps %d\n",outputStream->codecpar->extradata_size);
if(avcodec_parameters_to_context(avctx, outputStream->codecpar) < 0 ){
fprintf(stderr,"Error avcodec_parameters_to_context");
}
//Check to see if extradata was actually transferred to OutputformatCtx internal AVCodecContext
fprintf(stderr,"Extradata size after sps pps %d\n",avctx->extradata_size);
//Write the MP4 header
if(avformat_write_header(outputFormatCtx , NULL) < 0){
fprintf(stderr,"Error avformat_write_header");
ret = 1;
} else {
extradata_written=true;
fprintf(stderr,"EXTRADATA written\n");
}
}
生成的视频文件将不播放。该extradata实际上存储在MP4文件的尾部部分,而不是AVC1的MP4头中的位置。因此它是由libavcodec编写的,但很可能是由avformat_write_trailer编写的。
我将在这里发布PPS和SPS信息以及最终的extradata字节字符串,以防在形成extradata时出错。
下面是硬件编码器的缓冲区,其前缀为nal分隔符的sps和pps
\00\00\00\01\27\64\00\28\AC\2B\40\A0\CD\00\F1\22\6A\00\00\00\01\28\EE\04\F2\C0
以下是13字节SPS:
27640028ac2b40a0cd00f1226a
下面是5字节PPS:
28ee04f2c0
下面是最后一个extradata字节字符串,它是29个字节长。我希望我写的PPS和SPS大小正确。
\01\64\00\28\FF\E1\0D\00\27\64\00\28\AC\2B\40\A0\CD\00\F1\22\6A\01\05\00\28\EE\04\F2\C0
我对编码器的后继帧进行了相同的转换,从NAL分隔符0x0000001转换为4字节NAL大小,并将它们按顺序保存到文件中,然后编写拖车。
知道错在哪里吗?我怎样才能写的引渡到它的适当位置在MP4头?
谢谢,克里斯
我发现了问题所在。raspberry pi是小endpoint,所以我假设我必须用小endpoint写sps长度和pps长度以及每个NALU大小。它们需要用大端语来写。在我做了更改之后,mp4info和mplayer中显示的avcc atom现在可以回放视频了。不必访问outputformatctx内部avcodeccontext并修改它。
这篇文章很有帮助:
H.264流的序列/图像参数集的可能位置
我们有一个Android应用程序,把视频编码成H264。在所有以前试用过的Android设备上,这个编码为基线配置文件,这是我需要的。 联想Yoga10的编解码器是omx.mtk.video.encoder.avc。这将视频编码为高轮廓,这给接收设备带来了问题。
The Python Imaging Library uses a plug-in model which allows you to add your own decoders to the library, without any changes to the library itself. Such plug-ins usually have names like XxxImagePlugi
我正在尝试用Android6.0的MediaCodec将h264编码成实时低延迟的流。有大约6帧的延迟从编码器,我想知道如何减少 零件代码为: 编码器以320×480 60 fps的速度由屏幕表面馈入,通过dequeueOutputBuffer()输出流数据。大约有6个帧的数据没有被dequeueOutputBuffer()及时返回到编码器。换句话说,当馈送第n帧时,编码器输出第(N-6)帧的数据
这是本问题的后续问题。 这是我的代码: 我的问题-我的实现对于呈现由解码的H264流是否可以?或者我需要做EGL设置或其他什么? 提前道谢!
以下是我的问题: 什么是? 格式是不明确的,因为它可以是属于家族的任何格式,例如、、和,对吗? 如果我想把这些数据从Image的三个平面写到MediaCodec中,我需要转换成什么样的格式?YUV420、NV21、NV12、……? 格式也不明确,因为它可以是属于家族的任何格式,对吗?如果我将MediaCodec对象的选项设置为,那么是什么格式(YUV420P,yuv420sp...)是否应该向Me
问题内容: 我有一些要发送到我的应用程序中的芹菜任务的对象。这些对象显然无法使用默认json库进行json序列化。有没有一种方法可以使celery使用自定义JSON / 对这些对象进行序列化/反序列化? 问题答案: 这里有些晚,但是您应该能够通过在kombu序列化程序注册表中注册自定义编码器和解码器,如docs中所示: http [//docs.celeryproject.org/en/lates