ffmpeg代码实现自定义decoder
来源:互联网 发布:商丘学院网络教学平台 编辑:程序博客网 时间:2024/04/30 10:30
1、概述
本文主要讲述如何用ffmpeg代码实现自己的decoder。
2、代码
/* *本程序主要实现一个自己的decoder并加入到decoder链中去,供api调用*作者:缪国凯(MK) *821486004@qq.com *2015-6-4 */ #include "stdafx.h"#ifdef __cplusplusextern "C"{#endif#include <libavformat/avformat.h>#include <libavcodec/avcodec.h>#include <libavutil/pixdesc.h>##ifdef __cplusplus};#endif#pragma comment(lib, "avcodec.lib")#pragma comment(lib, "avformat.lib")#pragma comment(lib, "avutil.lib")//#pragma comment(lib, "avdevice.lib")//#pragma comment(lib, "avfilter.lib")//#pragma comment(lib, "postproc.lib")//#pragma comment(lib, "swresample.lib")//#pragma comment(lib, "swscale.lib")static av_cold int mk_init_decoder(AVCodecContext *avctx){return 0;}static int mk_decode(AVCodecContext *avctx, void *data, int *got_frame,AVPacket *avpkt){AVFrame *frame = (AVFrame*)data;AVPicture *picture = (AVPicture*)data;const uint8_t *buf = avpkt->data;int buf_size = avpkt->size;int size = avpicture_get_size(avctx->pix_fmt, avctx->width,avctx->height);frame->pict_type = AV_PICTURE_TYPE_I;frame->key_frame = 1;frame->buf[0] = av_buffer_alloc(size);memcpy(frame->buf[0]->data, buf, buf_size);int res = 0;if ((res = avpicture_fill(picture, frame->buf[0]->data, avctx->pix_fmt,avctx->width, avctx->height)) < 0) {av_buffer_unref(&frame->buf[0]);return res;}*got_frame = 1;return 0;}static av_cold int mk_close_decoder(AVCodecContext *avctx){return 0;}AVCodec ff_mkvideo_decoder = {/*.name = */"mkvideo",/*.long_name = */"mk video",/*.type = */AVMEDIA_TYPE_VIDEO,/*.id = */AV_CODEC_ID_MKVIDEO,/*.capabilities= */CODEC_CAP_PARAM_CHANGE,/*.supported_framerates = */NULL,/*.pix_fmts= */NULL,/*.supported_samplerates = */NULL,/*.sample_fmts= */NULL,/*.channel_layouts = */NULL,/*.max_lowres= */0,/*.priv_class= */NULL,/*.profiles= */NULL,/*.priv_data_size= */0,/*.next= */NULL,/*.init_thread_copy = */NULL,/*.update_thread_context = */NULL,/*.defaults= */NULL,/*.init_static_data = */NULL,/*.init = */mk_init_decoder,/*.encode_sub= */NULL,/*.encode2 = */NULL,/*.decode= */mk_decode,/*.close = */mk_close_decoder,};void help(){printf("**********************************************\n");printf("Usage:\n");printf(" MyMuxer [inputfile.mk] [outputfile] [size]\n");printf("\n");printf("Examples: \n");printf(" MyMuxer a.mk a.avi 1280x720\n");printf("**********************************************\n"); }int _tmain(int argc, _TCHAR* argv[]){if(argc < 4|| (!strcmp(argv[1],"--help"))){help();return 0;}av_register_all();avcodec_register(&ff_mkvideo_decoder);AVFormatContext *in_fxt = NULL, *out_fxt = NULL;AVStream *out_stream = NULL;int video_index = -1;AVDictionary *param = 0;av_dict_set(¶m, "video_size", argv[3], 0);if (avformat_open_input(&in_fxt, argv[1], NULL, ¶m) < 0){printf("can not open the input file context!\n");goto end;}if (avformat_find_stream_info(in_fxt, NULL) < 0){printf("can not find the stream info!\n");goto end;}if(avformat_alloc_output_context2(&out_fxt, NULL, NULL, argv[2]) < 0){printf("can not alloc output context!\n");goto end;}for (int i = 0; i < in_fxt->nb_streams; i++){if (in_fxt->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){//open decoderAVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_MKVIDEO);//由于ffmpeg源码里 还没把mk demuxer的codecid改过来,所以这里强制赋值,不然avcodec_open2打不开in_fxt->streams[i]->codec->codec_id = AV_CODEC_ID_MKVIDEO;if(0 > avcodec_open2(in_fxt->streams[i]->codec, codec, NULL)){printf("can not find or open decoder!\n");goto end;}video_index = i;//new streamout_stream = avformat_new_stream(out_fxt, NULL);if (!out_stream){printf("can not new stream for output!\n");goto end;}//set codec context paramout_stream->codec->codec = avcodec_find_encoder(out_fxt->oformat->video_codec);out_stream->codec->height = in_fxt->streams[i]->codec->height;out_stream->codec->width = in_fxt->streams[i]->codec->width;out_stream->codec->time_base = in_fxt->streams[i]->time_base;//out_stream->codec->time_base.den = 25;out_stream->codec->sample_aspect_ratio = in_fxt->streams[i]->codec->sample_aspect_ratio;out_stream->codec->pix_fmt = in_fxt->streams[i]->codec->pix_fmt;out_stream->avg_frame_rate.den = out_stream->codec->time_base.num;out_stream->avg_frame_rate.num = out_stream->codec->time_base.den;if (!out_stream->codec->codec){printf("can not find the encoder!\n");goto end;}if ((avcodec_open2(out_stream->codec, out_stream->codec->codec, NULL)) < 0){printf("can not open the encoder\n");goto end;}if (out_fxt->oformat->flags & AVFMT_GLOBALHEADER)out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;break;}}if (-1 == video_index){printf("found no video stream in input file!\n");goto end;}if (!(out_fxt->oformat->flags & AVFMT_NOFILE)){if(avio_open(&out_fxt->pb, argv[2], AVIO_FLAG_WRITE) < 0){printf("can not open output file handle!\n");goto end;}}if(avformat_write_header(out_fxt, NULL) < 0){printf("can not write the header of the output file!\n");goto end;}AVPacket pkt_in, pkt_out;av_init_packet(&pkt_in);av_init_packet(&pkt_out);int got_frame, got_picture;int i = 0, frame_index = 0;while(1){AVFrame *frame;frame = av_frame_alloc();got_frame = -1;got_picture = -1;if (av_read_frame(in_fxt, &pkt_in) < 0){break;}frame->buf;if (avcodec_decode_video2(in_fxt->streams[video_index]->codec, frame, &got_frame, &pkt_in) < 0){printf("can not decoder a frame");break;}av_free_packet(&pkt_in);if (got_frame){frame->pts = i++;pkt_out.data = NULL;//主要这里必须自己初始化,或者必须置为null,不然ff_alloc_packet2函数会报错pkt_out.size = 0;if (avcodec_encode_video2(out_stream->codec, &pkt_out, frame, &got_picture) < 0){printf("can not encode a frame!\n");break;}if (got_picture){printf("Succeed to encode frame: %5d\tsize:%5d\n",frame_index,pkt_out.size);pkt_out.stream_index = out_stream->index;frame_index++;av_write_frame(out_fxt, &pkt_out);av_free_packet(&pkt_out);}}av_frame_free(&frame);}av_write_trailer(out_fxt);//cleanavcodec_close(out_stream->codec);avcodec_close(out_fxt->streams[video_index]->codec);end:avformat_close_input(&in_fxt);if (out_fxt && !(out_fxt->oformat->flags & AVFMT_NOFILE)){avio_close(out_fxt->pb);}avformat_free_context(out_fxt);return 0;}
3、解释
原理和前面的自定义的muxer、demuxer、encoder一样,在这里就不多说了。
0 0
- ffmpeg代码实现自定义decoder
- ffmpeg代码实现自定义decoder
- 把自定义的decoder加入ffmpeg源码
- ffmpeg代码实现自定义encoder
- ffmpeg代码实现自定义encoder
- ffmpeg的decoder有哪些?
- ffmpeg h264 decoder for vc 下载
- 编译只包含h264 decoder的ffmpeg
- 编译只包含h264 decoder的ffmpeg
- 编译只包含h264 decoder的ffmpeg
- FFmpeg完美入门【8】-FFmpeg架构之Decoder/Encoder模块
- FFmpeg入门(2)-使用ffmpeg实现转码样例(代码实现)
- 使用ffmpeg实现转码样例(代码实现)
- 使用ffmpeg实现转码样例(代码实现)
- 使用ffmpeg实现转码样例(代码实现)
- Netty4 自定义Decoder,Encoder进行对象传递
- Netty protobuf使用,自定义Encoder 和DeCoder
- BaseAdapter自定义实现代码
- hbase建表时region预分区的方法
- GRE数学——单位转换问题
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- struts2入门实例
- JackSon学习笔记(一)
- ffmpeg代码实现自定义decoder
- 数值的整数次方
- iOS 堆和栈的区别
- 2015中国二三线城市互联网跨界经济报告
- 我的MYSQL学习心得(4) : 数据类型 上
- 求出最长连续序列,并打印出序列
- 使用AssetsLibrary.Framework创建多图片选择控制器(翻译)
- Android之 MTP框架和流程分析
- Android之android:launchMode