图片合成视频时需要将图片编码转换相应视频的编码
以下是将png转换为YUV420p的AVFrame
AVFrame* openImageToFrame(const char* imageFileName){ AVFormatContext *pFormatCtx= NULL; if(avformat_open_input(&(pFormatCtx), imageFileName, NULL, NULL)!=0){ printf("Can't open image file '%s'\n", imageFileName); return NULL; } if(avformat_find_stream_info(pFormatCtx, NULL ) < 0){ printf("Can't find stream\n"); return NULL; } av_dump_format(pFormatCtx, 0, imageFileName, false); AVCodecContext *pCodecCtx; int index = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); const AVCodec* dec = avcodec_find_decoder(pFormatCtx->streams[index]->codecpar->codec_id); pCodecCtx = avcodec_alloc_context3(dec); avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[index]->codecpar); // Find the decoder for the video stream const AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (!pCodec){ printf("Codec not found\n"); return NULL; } // Open codec if(avcodec_open2(pCodecCtx, pCodec, NULL)<0){ printf("Could not open codec\n"); return NULL; } // AVFrame *pFrame; pFrame = av_frame_alloc(); if (!pFrame){ printf("Can't allocate memory for AVFrame\n"); return NULL; } AVPacket packet; packet.data = NULL; packet.size = 0; while (av_read_frame(pFormatCtx, &packet) >= 0){ if(packet.stream_index != index){ continue; } int ret = avcodec_send_packet(pCodecCtx, &packet); if (ret >= 0){ ret = avcodec_receive_frame(pCodecCtx,pFrame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){ break; } } else{ break; } } AVFrame* dst = av_frame_alloc(); int width = pFrame->width; int height = pFrame->height; // 设置转帧格式 enum AVPixelFormat dst_pixfmt = AV_PIX_FMT_YUV420P; // 计算转帧需要的buff大小 int numBytes = av_image_get_buffer_size(dst_pixfmt,width,height,1); uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t)); av_image_fill_arrays(dst->data, dst->linesize,buffer,dst_pixfmt,width,height,1); struct SwsContext *convert_ctx=NULL; convert_ctx = sws_getContext(pFrame->width, pFrame->height, pCodecCtx->pix_fmt, width, height, dst_pixfmt, SWS_POINT, NULL, NULL, NULL); sws_scale(convert_ctx, pFrame->data, pFrame->linesize, 0, pFrame->height, dst->data, dst->linesize); sws_freeContext(convert_ctx); av_frame_free(&pFrame); avformat_close_input(&(pFormatCtx)); avcodec_free_context(&pCodecCtx); dst->format = (int)dst_pixfmt; dst->width = width; dst->height = height; dst->pts = 0; dst->pkt_dts = 0; return dst; }