模块:
libavcodec - 编码解码器
libavdevice - 输入输出设备的支持
libavfilter - 视音频滤镜支持
libavformat - 视音频等格式的解析
libavutil
- 工具库
libpostproc - 后期效果处理
libswscale -
图像颜色、尺寸转换
1. 主函数分析:
- int_tmain(int argc, _TCHAR* argv[])
- {
- int ret;
- AVPacketpacket;
- AVFrame *frame= NULL;
- enum AVMediaType type;
- unsigned intstream_index;
- unsigned int i;
- int got_frame;
- int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket*);
- if (argc != 3) {
- av_log(NULL, AV_LOG_ERROR, "Usage: %s<input file> <output file>\n", argv[0]);
- return 1;
- }
- av_register_all();
- avfilter_register_all();
- if ((ret = open_input_file(argv[1])) < 0)
- goto end;
- if ((ret = open_output_file(argv[2])) < 0)
- goto end;
- if ((ret = init_filters()) < 0)
- goto end;
- /* read all packets */
- while (1) {
- if ((ret= av_read_frame(ifmt_ctx, &packet)) < 0)
- break;
- stream_index = packet.stream_index;
- type =ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
- av_log(NULL, AV_LOG_DEBUG, "Demuxergave frame of stream_index %u\n",
- stream_index);
- if (filter_ctx[stream_index].filter_graph) {
- av_log(NULL, AV_LOG_DEBUG, "Going toreencode&filter the frame\n");
- frame =av_frame_alloc();
- if (!frame) {
- ret = AVERROR(ENOMEM);
- break;
- }
- packet.dts = av_rescale_q_rnd(packet.dts,
- ifmt_ctx->streams[stream_index]->time_base,
- ifmt_ctx->streams[stream_index]->codec->time_base,
- (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- packet.pts = av_rescale_q_rnd(packet.pts,
- ifmt_ctx->streams[stream_index]->time_base,
- ifmt_ctx->streams[stream_index]->codec->time_base,
- (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
- avcodec_decode_audio4;
- ret =dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
- &got_frame, &packet);
- if (ret < 0) {
- av_frame_free(&frame);
- av_log(NULL, AV_LOG_ERROR, "Decodingfailed\n");
- break;
- }
- if (got_frame) {
- frame->pts = av_frame_get_best_effort_timestamp(frame);
- ret= filter_encode_write_frame(frame, stream_index);
- av_frame_free(&frame);
- if (ret< 0)
- goto end;
- } else {
- av_frame_free(&frame);
- }
- } else {
- /* remux this frame without reencoding */
- packet.dts = av_rescale_q_rnd(packet.dts,
- ifmt_ctx->streams[stream_index]->time_base,
- ofmt_ctx->streams[stream_index]->time_base,
- (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- packet.pts = av_rescale_q_rnd(packet.pts,
- ifmt_ctx->streams[stream_index]->time_base,
- ofmt_ctx->streams[stream_index]->time_base,
- (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- ret =av_interleaved_write_frame(ofmt_ctx, &packet);
- if (ret < 0)
- goto end;
- }
- av_free_packet(&packet);
- }
- /* flush filters and encoders */
- for (i = 0; i < ifmt_ctx->nb_streams; i++) {
- /* flush filter */
- if (!filter_ctx[i].filter_graph)
- continue;
- ret =filter_encode_write_frame(NULL, i);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Flushingfilter failed\n");
- goto end;
- }
- /* flush encoder */
- ret = flush_encoder(i);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Flushingencoder failed\n");
- goto end;
- }
- }
- av_write_trailer(ofmt_ctx);
- end:
- av_free_packet(&packet);
- av_frame_free(&frame);
- for (i = 0; i < ifmt_ctx->nb_streams; i++) {
- avcodec_close(ifmt_ctx->streams[i]->codec);
- if (ofmt_ctx && ofmt_ctx->nb_streams >i && ofmt_ctx->streams[i] &&ofmt_ctx->streams[i]->codec)
- avcodec_close(ofmt_ctx->streams[i]->codec);
- if(filter_ctx && filter_ctx[i].filter_graph)
- avfilter_graph_free(&filter_ctx[i].filter_graph);
- }
- av_free(filter_ctx);
- avformat_close_input(&ifmt_ctx);
- if (ofmt_ctx &&!(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
- avio_close(ofmt_ctx->pb);
- avformat_free_context(ofmt_ctx);
- if (ret < 0)
- av_log(NULL, AV_LOG_ERROR, "Erroroccurred\n");
- return (ret? 1:0);
- }
1.1 int _tmain(int argc, _TCHAR* argv[])
用过C的人都知道每一个C的程序都会有一个main(),但有时看别人写的程序发现主函数不是int main(),而是int _tmain(),而且头文件也不是<iostream.h>而是<stdafx.h>,会困惑吧?首先,这个_tmain() 是为了支持unicode所使用的main一个别名而已,既然是别名,应该有宏定义过的,在哪里定义的呢?就在那个让你困惑 的<stdafx.h>里,有这么两行
#include <stdio.h>
#include <tchar.h>
我们可以在头文件<tchar.h>里找到_tmain的宏定义
#define _tmain main
所以,经过预编译以后, _tmain就变成main了
//_TCHAR类型是宽字符型字符串,和我们一般常用的字符串不同,它是32位或者更 高的操作系统中所使用的类型.
时间: 2024-08-03 15:44:42