我是FFmpeg的新手,正在努力解码可以作为uint8_t数组获得的H264数据包。
经过多次调查后,我认为它应该能够将数组放入如下所示的AVPacket中
AVPacket *avpkt = (AVPacket *)malloc(sizeof(AVPacket) * 1);
av_init_packet(avpkt);
avpkt->data = ct; // ct is the array
avpkt->length =....
并通过avcodec_decode_video2()进行解码。代码的一部分就像
...
codec = avcodec_find_decoder(CODEC_ID_H264);
gVideoCodecCtx = avcodec_alloc_context();
gFrame = avcodec_alloc_frame();
avcodec_decode_video2(gVideoCodecCtx, gFrame, &frameFinished, packet);
...
我想我正确设置了所有必需的属性,但这个函数只返回-1 :(
我刚发现-1来自
ret = avctx-> codec-> decode(avctx,picture,got_picture_ptr,avpkt);
avcodec_decode_video2(); 中的
实际上,我想知道的是我是否可以通过avcodec_decode_video2()解码H264数据包(没有RTP头)。
感谢您的帮助。
///////////已添加
好的,我还在努力寻找解决方案。我现在正在做的是下面的
**此RTP流中的H264流由FU-A
编码收到RTP数据包
查看RTP标头的第二个字节是否> 0表示它是第一个数据包(可能会被跟踪)
查看下一个RTP数据包是否具有>在它的第二个字节也是0,那么它意味着前一帧是一个完整的NAL,或者如果它是< 0,数据包应附加到前一个数据包。
删除数据包的所有RTP标头,使其只有FU指示符| FU标题| NAL
尝试使用avcodec_decode_video2()
但它只返回-1 .....我是否应该删除FU指示符和标题?
任何建议都将非常感激
提前感谢。
答案 0 :(得分:5)
实际上,我想知道的是我是否可以通过avcodec_decode_video2()解码H264数据包(没有RTP头)。
如果使用除单个NAL单元模式之外的分组模式,则可能需要在将NAL单元传递到解码器之前预处理RTP有效负载(重新组合分段NALU,分割聚合NALU)。流中允许的NAL单元类型(STAP,MTAP,FU)取决于分组化模式。有关打包模式的详细信息,请阅读RFC 6184。
其次,虽然我不熟悉FFMPEG,但它可能更像是一般的H.264解码问题:您必须始终使用H.264序列(SPS)和图片参数集(PPS)初始化解码器你将能够解码其他帧。你做到了吗?
答案 1 :(得分:1)
我不认为您可以在没有RTP标头的情况下解码H264数据包,因为RTP标头中嵌入了相当多的视频流信息。同时,我猜可能所有视频流信息都可以在RTP视频数据包中复制。所以它还取决于流的生成方式。
VIBGYOR
答案 2 :(得分:0)
这是我的工作代码
bool VideoDecoder::decode(const QByteArray &encoded)
{
AVPacket packet;
av_new_packet(&packet, encoded.size());
memcpy(packet.data, encoded.data(), encoded.size());
//TODO: use AVPacket directly instead of Packet?
//TODO: some decoders might in addition need other fields like flags&AV_PKT_FLAG_KEY
int ret = avcodec_decode_video2(d->codec_ctx, d->frame, &d->got_frame_ptr, &packet);
av_free_packet(&packet);
if ((ret < 0) || (!d->got_frame_ptr))
return false;
d->sws_ctx = sws_getCachedContext(d->sws_ctx
, d->codec_ctx->width, d->codec_ctx->height, d->codec_ctx->pix_fmt
, d->width, d->height, d->pix_fmt
, (d->width == d->codec_ctx->width && d->height == d->codec_ctx->height) ? SWS_POINT : SWS_BICUBIC
, NULL, NULL, NULL
);
int v_scale_result = sws_scale(
d->sws_ctx,
d->frame->data,
d->frame->linesize,
0,
d->codec_ctx->height,
d->picture.data,
d->picture.linesize
);
Q_UNUSED(v_scale_result);
if (d->frame->interlaced_frame)
avpicture_deinterlace(&d->picture, &d->picture, d->pix_fmt, d->width, d->height);
return true;
}