Я хочу преобразовать кадры видеофайла в формате MPG в изображения JPEG.
Ниже приведен код, который я пробовал
int save_frame_as_jpeg(AVCodecContext *pCodecCtx, AVFrame *pFrame, int FrameNo) {
//AVCodec *jpegCodec = avcodec_find_encoder(AV_CODEC_ID_JPEG2000);
AVCodec *jpegCodec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
if (!jpegCodec) {
return -1;
}
AVCodecContext *jpegContext = avcodec_alloc_context3(jpegCodec);
if (!jpegContext) {
return -1;
}
jpegContext->pix_fmt = pCodecCtx->pix_fmt;
jpegContext->height = pFrame->height;
jpegContext->width = pFrame->width;
jpegContext->time_base = pCodecCtx->time_base;
if (avcodec_open2(jpegContext, jpegCodec, NULL) < 0) {
return -1;
}
FILE *JPEGFile;
char JPEGFName[256];
//AVPacket packet = { .data = NULL,.size = 0 };
AVPacket packet;
av_init_packet(&packet);
int gotFrame;
if (( avcodec_send_packet(jpegContext, &packet)) < 0) {
return -1;
}
if (( avcodec_receive_frame(jpegContext, pFrame)) < 0) {
return -1;
}
sprintf(JPEGFName, "dvr-%06d.jpg", FrameNo);
JPEGFile = fopen(JPEGFName, "wb");
fwrite(packet.data, 1, packet.size, JPEGFile);
fclose(JPEGFile);
av_packet_unref(&packet);
avcodec_close(jpegContext);
return 0;
}
static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt)
{
char buf[1024];
int ret;
ret = avcodec_send_packet(dec_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error sending a packet for decoding\n");
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
exit(1);
}
printf("saving frame %3d\n", dec_ctx->frame_number);
fflush(stdout);
FILE *iFile = fopen(buf, "rb");
fseek(iFile, 0, SEEK_END);
size_t fileLen = ftell(iFile);
fseek(iFile, 0, SEEK_SET);
unsigned char* fileData = new unsigned char[fileLen];
fread(fileData, 1, fileLen, iFile);
fclose(iFile);
getchar();
}
}
int main()
{
av_register_all();
avcodec_register_all();
avdevice_register_all();
avfilter_register_all();
const char *filename = "video.mpg";
AVFormatContext *format_context = NULL;
int ret = -1;
ret = avformat_open_input(&format_context, filename, NULL, NULL);
if (ret < 0) {
printf("cannot open file. filename=%s, ret=%08x\n", filename, AVERROR(ret));
return -1;
}
ret = avformat_find_stream_info(format_context, NULL);
if (ret < 0) {
printf("avformat_find_stream_info error. ret=%08x\n", AVERROR(ret));
return -1;
}
AVStream *video_stream = NULL;
for (unsigned int i = 0; i < format_context->nb_streams; i++) {
if (format_context->streams[i]->codecpar->codec_type == AVMediaType::AVMEDIA_TYPE_VIDEO) {
// found Video stream
video_stream = format_context->streams[i];
break;
}
}
if (video_stream == NULL) {
printf("video_stream not found\n");
return -1;
}
AVCodec *video_codec = avcodec_find_decoder(video_stream->codecpar->codec_id);
if (video_codec == NULL) {
printf("avcodec_find_decoder codec not found. codec_id=%d\n", video_stream->codecpar->codec_id);
return -1;
}
AVCodecContext *video_codec_context = avcodec_alloc_context3(video_codec);
if (video_codec_context == NULL) {
printf("avcodec_alloc_context3 error.\n");
return -1;
}
ret = avcodec_open2(video_codec_context, video_codec, NULL);
if (ret < 0) {
printf("avcodec_open2 error. ret=%08x\n", AVERROR(ret));
return -1;
}
AVFrame *frame = av_frame_alloc();
AVPacket packet;
int frame_number = 0;
while (1) {
// read ES
if ((ret = av_read_frame(format_context, &packet)) < 0) {
printf("av_read_frame eof or error. ret=%08x\n", AVERROR(ret));
break; // eof or error
}
if (packet.stream_index == video_stream->index) {
// decode Video ES
if ((ret = avcodec_send_packet(video_codec_context, &packet)) < 0) {
printf("avcodec_send_packet error. ret=%08x\n", AVERROR(ret));
}
if ((ret = avcodec_receive_frame(video_codec_context, frame)) < 0) {
if (ret != AVERROR(EAGAIN)) {
printf("avcodec_receive_frame error. ret=%08x\n", AVERROR(ret));
break;
}
}
else {
if (packet.size)
decode(video_codec_context, frame, &packet);
printf("decode finished. frame_number=%d\n", ++frame_number);
save_frame_as_jpeg(video_codec_context, frame, frame_number);
getchar();
}
}
else {
// does not Video ES.
}
av_packet_unref(&packet);
}
getchar(); // wait user input
return 0;
}
Эта ошибка появилась
[mjpeg @ 000002889038fb80] Указанный формат пикселя yuv420p недопустим или не поддерживается
ошибка этой строки:
avcodec_open2(jpegContext, jpegCodec, NULL)
Я могу 'Не могу понять ошибку. Может ли кто-нибудь мне помочь?