1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
/*********************编码器初始化阶段********************/
//初始化编码器,这里音频轨和视频轨都需要各自创建一个
codecCtx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(codecCtx, pFormatCtx->streams[stream_index]->codecpar);
...
//创建编码器
avcodec_find_decoder(codecCtx->codec_id);
avcodec_open2(codecCtx, codec, NULL);
/********************视频解码准备阶段********************/
...
//获得视频帧转换上下文,用于将视频数据解码还原成YUV格式
sws_getContext(is->video_ctx->width,
is->video_ctx->height,
is->video_ctx->pix_fmt,
is->video_ctx->width,
is->video_ctx->height,
AV_PIX_FMT_YUV420P,
SWS_BILINEAR, NULL, NULL, NULL);
//视频渲染设备初始化
win = SDL_CreateWindow("Media Player",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
is->video_ctx->width,
is->video_ctx->height
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(win, -1, 0);
texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_IYUV,
SDL_TEXTUREACCESS_STREAMING,
is->video_ctx->width,
is->video_ctx->height);
...
/********************音频编码准备阶段********************/
//为音频输出设备配置参数
wanted_spec.freq = codecCtx->sample_rate;//采样率
wanted_spec.format = AUDIO_S16SYS;//采样格式
wanted_spec.channels = 2;//通道数
wanted_spec.silence = 0;//表示静音的值。因为声音采样是有符号的,所以0当然就是这个值
wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;//采样数目
wanted_spec.callback = audio_callback;//音频数据索取回调
wanted_spec.userdata = is;//回调参数
SDL_OpenAudio(&wanted_spec, &spec);
//配置音频数据重采样上下文
struct SwrContext *audio_convert_ctx;
audio_convert_ctx = swr_alloc();
swr_alloc_set_opts(audio_convert_ctx, //重采样上下文
out_channel_layout, //输出的layout
AV_SAMPLE_FMT_S16, //输出的样本格式
out_sample_rate, //输出的样本率
in_channel_layout, //输入的layout
is->audio_ctx->sample_fmt, //输入的样本格式
is->audio_ctx->sample_rate,//输入的样本率
0,
NULL);
SDL_PauseAudio(0);
|