Я пытаюсь декодировать поток H264 с помощью FFMPeg.Неисправность декодирования H264 Кадры с FFMpeg
У меня есть сохраненное видео и побежал в FFMpeg с помощью команды:
ffmpeg -i 20161201-090322.264 -pixel_format yuv420p -filter:v fps=fps=600/60 $filename%03d.raw
И успешно получили кадры из видео. Затем я начал пытаться декодировать прямой поток (именно контент, который сохраняется в этих видео).
Я инициализация FFmpeg, как это:
cam->ffmpegCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
cam->ffmpgContext = avcodec_alloc_context3(cam->ffmpegCodec);
cam->ffmpgContext->width = cam->Width;
cam->ffmpgContext->height = cam->Height;
cam->ffmpgContext->pix_fmt = AV_PIX_FMT_YUV420P;
cam->ffmpegFrame = av_frame_alloc();
cam->ffmpegParser = av_parser_init(AV_CODEC_ID_H264);
if(!cam->ffmpegParser)
{
sprintf(msg, "Error, initializing parser");
libLogCtx(msg, MODULE_NAME, PLogFileRelease, true);
}
int res = avcodec_open2(cam->ffmpgContext, cam->ffmpegCodec, 0);
if(res != 0)
{
sprintf(msg, "Error, openning codec [%d]", res);
libLogCtx(msg, MODULE_NAME, PLogFileRelease, true);
}
В то время как это мои объявления внутри конструкция распредвала:
AVCodecContext *ffmpgContext;
AVCodec *ffmpegCodec;
AVFrame *ffmpegFrame;
AVCodecParserContext *ffmpegParser;
Когда я получаю содержание потока, я сделать следующие шаги:
/// Copy the received data to buffer
memcpy(cam->imageBuffer + cam->imageBufferSz, pBuffer, dwBufSize);
cam->imageBufferSz += dwBufSize;
/// If there's some data,
if(cam->imageBufferSz > 0)
{
/// Try to parse
uint8_t* data = NULL;
int size = 0;
int len = av_parser_parse2(cam->ffmpegParser, cam->ffmpgContext, &data, &size,
cam->imageBuffer, cam->imageBufferSz, 0, 0, AV_NOPTS_VALUE);
if(size > 0 && len >= 0)
{
/// Fill the packet and decode
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = cam->imageBuffer;
pkt.size = cam->imageBufferSz;
int frameFinished = 0;
int nres = avcodec_decode_video2(cam->ffmpgContext, cam->ffmpegFrame, &frameFinished, &pkt);
/// If decoding was successfully, Save only the Y to file (i'm just testing).
if(frameFinished)
{
char fnm[255];
sprintf(fnm, "C:\\Users\\Black_Spiders\\Desktop\\Rls\\test%d.raw", n);
n++;
FILE* f = (FILE*)fopen(fnm, "w");
for (int y = 0; y < cam->ffmpegFrame->height; y++)
{
fwrite(cam->ffmpegFrame->data[0] + y*cam->ffmpegFrame->linesize[0], 1, cam->ffmpegFrame->width, f);
}
fclose(f);
}
}
}
Несмотря на то, что мой код выглядит довольно хорошо (время, оставшееся некоторое время в Интернете), я ха Винг этот результат:
Может кто-нибудь дать мне какой-нибудь совет?
С наилучшими пожеланиями,
Я не знаю правильного использования API-анализатора парсера, но ваш кажется неправильным. Разве вы не должны каким-то образом использовать 'len' и' data' и 'size'? И должен быть цикл вокруг 'av_parser_parse2' вызова/потребления. –
@AndreyTurkin Это обратный вызов, вызываемый DVR, с которым я работаю. Вот почему av_parser_parse2 не находится в цикле (он вызывается каждый раз, когда у DVR есть данные). Что касается использования len, данных и размера, я не испытываю h264 и ffmpeg, и я попытался следовать этому руководству: [link] (http://roxlu.com/2014/039/decoding-h264-and- yuv420p-воспроизведение). Кстати, этот учебник использует этот метод, кажется, что цель состоит в том, чтобы проверить, достаточно ли данных для использования avcodec_decode_video2. Я пытался использовать 'len' как мой размер pkt, но все тот же результат. –