正如标题所说,我被困如何将FFmpeg的AVPacket转移到CUVID的CUVIDSOURCEDATAPACKET ,我的主要代码如下:`
AVPacket* avpkt;
avpkt = (AVPacket*)av_malloc(sizeof(AVPacket));
CUVIDSOURCEDATAPACKET cupkt;
int iPkt = 0;
while (av_read_frame(pFormatCtx, avpkt) >= 0) {
if (avpkt->stream_index == videoindex) {
cuCtxPushCurrent(g_oContext);
if (avpkt && avpkt->size) {
cupkt.payload_size = (unsigned long)avpkt->size;
cupkt.payload = (const unsigned char*)avpkt->data;
if (avpkt->pts != AV_NOPTS_VALUE) {
cupkt.flags = CUVID_PKT_TIMESTAMP;
if (pCodecCtx->pkt_timebase.num && pCodecCtx->pkt_timebase.den) {
AVRational tb;
tb.num = 1;
tb.den = AV_TIME_BASE;
cupkt.timestamp = av_rescale_q(avpkt->pts, pCodecCtx->pkt_timebase, tb);
}
else
cupkt.timestamp = avpkt->pts;
}
}
else {
cupkt.flags = CUVID_PKT_ENDOFSTREAM;
}
oResult = cuvidParseVideoData(hParser_, &cupkt);
if ((cupkt.flags & CUVID_PKT_ENDOFSTREAM) || (oResult != CUDA_SUCCESS)) {
break;
}
iPkt++;
printf("Succeed to read avpkt %d !\n", iPkt);
checkCudaErrors(cuCtxPopCurrent(NULL));
}
av_free_packet(avpkt);
}
如您所见,代码
cupkt.payload_size = (unsigned long)avpkt->size;
cupkt.payload = (const unsigned char*)avpkt->data;
需要纠正。 我英语很差,我希望我能清楚地表达自己。
答案 0 :(得分:1)
今天我很高兴。在我问这个问题之后的一个晚上,我去看看FFmpeg的源代码,经过几个小时的努力,我发现我的代码和FFmpeg之间有一点区别。所以我会我自己回答这个问题。
AVBitStreamFilterContext* h264bsfc = NULL;
if (pCodecCtx->codec_id == AV_CODEC_ID_H264 || pCodecCtx->codec_id == AV_CODEC_ID_HEVC) {
if (pCodecCtx->codec_id == AV_CODEC_ID_H264)
h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
else
h264bsfc = av_bitstream_filter_init("hevc_mp4toannexb");
}
AVPacket *avpkt;
avpkt = (AVPacket *)av_malloc(sizeof(AVPacket));
CUVIDSOURCEDATAPACKET cupkt;
int iPkt = 0;
while (av_read_frame(pFormatCtx, avpkt) >= 0){
if (avpkt->stream_index == videoindex){
cuCtxPushCurrent(g_oContext);
if (avpkt && avpkt->size) {
if (h264bsfc)
{
av_bitstream_filter_filter(h264bsfc, pFormatCtx->streams[videoindex]->codec, NULL, &avpkt->data, &avpkt->size, avpkt->data, avpkt->size, 0);
}
cupkt.payload_size = (unsigned long)avpkt->size;
cupkt.payload = (const unsigned char*)avpkt->data;
if (avpkt->pts != AV_NOPTS_VALUE) {
cupkt.flags = CUVID_PKT_TIMESTAMP;
if (pCodecCtx->pkt_timebase.num && pCodecCtx->pkt_timebase.den){
AVRational tb;
tb.num = 1;
tb.den = AV_TIME_BASE;
cupkt.timestamp = av_rescale_q(avpkt->pts, pCodecCtx->pkt_timebase, tb);
}
else
cupkt.timestamp = avpkt->pts;
}
}
else {
cupkt.flags = CUVID_PKT_ENDOFSTREAM;
}
oResult = cuvidParseVideoData(hParser_, &cupkt);
if ((cupkt.flags & CUVID_PKT_ENDOFSTREAM) || (oResult != CUDA_SUCCESS)){
break;
}
iPkt++;
//printf("Succeed to read avpkt %d !\n", iPkt);
checkCudaErrors(cuCtxPopCurrent(NULL));
}
av_free_packet(avpkt);
}
if (h264bsfc)
{
av_bitstream_filter_close(h264bsfc);
}
主要区别如下:
AVBitStreamFilterContext* h264bsfc = NULL;
if (pCodecCtx->codec_id == AV_CODEC_ID_H264 || pCodecCtx->codec_id == AV_CODEC_ID_HEVC) {
if (pCodecCtx->codec_id == AV_CODEC_ID_H264)
h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
else
h264bsfc = av_bitstream_filter_init("hevc_mp4toannexb");
}
········
if (h264bsfc)
{
av_bitstream_filter_filter(h264bsfc, pFormatCtx->streams[videoindex]->codec, NULL, &avpkt->data, &avpkt->size, avpkt->data, avpkt->size, 0);
}
·········
if (h264bsfc)
{
av_bitstream_filter_close(h264bsfc);
}
这是因为我使用的文件是H264格式,必须用H264的NALU做一些事情(我不知道它是什么,我从其他人的问题得到它,我不知道很明显,也许问题不像我说的那样。。我添加的代码对我有用,我希望我的帮助可以帮助你。我记得,如果你对我说的话感到困惑,我的英语很差,只需转到代码。