ffmpeg 解码 png apng 图片

来源:互联网 发布:java线程yield 编辑:程序博客网 时间:2024/06/05 04:41

ffmpeg 解码 png apng 图片

1,搭建环境
参考网上搭建 ubuntu 下 ffmpeg 环境

2. 定义解码结构体
typedef struct Decode_PNG_Key{ int video_stream_index; AVFormatContext *pFormatCtx; AVCodecContext *pCodecCtx;AVCodec *dec;int init_flag;int decode_flag;AVFrame *filt_frame;} Decode_Png_key;

3, 初始化编码器
int decode_png_init(Decode_Png_key *args, char *filename){int ret = 0;if (args == NULL || filename == NULL )return -1;if ((ret = avformat_open_input(&args->pFormatCtx, filename, NULL, NULL)) < 0){dm_printf("Cannot open input file");goto end;}if ((ret = avformat_find_stream_info(args->pFormatCtx, NULL)) < 0){dm_printf("Cannot find stream information\n");goto end;}for(int i = 0; i < args->pFormatCtx->nb_streams; i++){if(args->pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){args->video_stream_index = i;break;}}args->pCodecCtx = args->pFormatCtx->streams[args->video_stream_index]->codec;args->dec = avcodec_find_decoder(args->pCodecCtx->codec_id);if(args->dec == NULL){fprintf(stderr, "can not find decoder!\n");goto end;}av_opt_set_int(args->pCodecCtx, "refcounted_frames", 1, 0);/* init the video decoder */if ((ret = avcodec_open2(args->pCodecCtx, args->dec, NULL)) < 0){dm_printf("Cannot open video decoder\n");goto end;}args->filt_frame = av_frame_alloc();if (args->filt_frame == NULL)ret = -1;end:if (ret < 0){if (args->pCodecCtx){avcodec_close(args->pCodecCtx);args->pCodecCtx = NULL;}if (args->pFormatCtx){avformat_close_input(&args->pFormatCtx);args->pFormatCtx = NULL;}}elseargs->init_flag = 1;return ret;}



4. 编码一张图片
这个切记一定编码一次不一定成功,所以需要多加几次循环才能最终编码成功
int decode_png_next(Decode_Png_key *args, AVFrame *filt_frame){int ret = -1;int got_frame = 0;int decLen = 0;int error_count = 0;AVPacket  packet;memset(&packet, 0, sizeof(packet));if (args == NULL || filt_frame == NULL || args->pCodecCtx == NULL){dm_printf("args == NULL || filt_frame== NULL || args->pCodecCtx == NULL");return -1;}av_init_packet(&packet);packet.data = NULL;while(1){if ((ret = av_read_frame(args->pFormatCtx, &packet)) < 0){dm_printf("png_read_over");av_free_packet(&packet);break;}if (packet.stream_index == args->video_stream_index){got_frame = 0;while (packet.size > 0){decLen = avcodec_decode_video2(args->pCodecCtx, filt_frame, &got_frame, &packet);error_count++;if (error_count > 50){av_free_packet(&packet);ret = -1;break;}if (decLen < 0){decLen = packet.size;packet.data += decLen;packet.size -= decLen;}if (got_frame){dm_printf("[video_decode_example]picture->linesize[0]=%d, c->width=%d,c->height=%d,c->format=  %d\n",          filt_frame->linesize[0], filt_frame->width, filt_frame->height, filt_frame->format);packet.data += decLen;packet.size -= decLen;ret = 0;}}av_free_packet(&packet);if (got_frame)break;}else{/* discard non-wanted packets */av_free_packet(&packet);}}if (ret == 0)args->decode_flag = 1;elseargs->decode_flag = 0;return ret;}

5. 释放资源
 
int decode_png_release(Decode_Png_key *args){if (args == NULL)return -1;if (args->pCodecCtx){avcodec_close(args->pCodecCtx);args->pCodecCtx = NULL;}if (args->pFormatCtx){avformat_close_input(&args->pFormatCtx);args->pFormatCtx = NULL;}if (args->filt_frame != NULL)av_frame_free(&args->filt_frame );memset(args, 0, sizeof(Decode_Png_key));return 0;}


原创粉丝点击