<div id="content_views" class="markdown_views prism-atom-one-dark">
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<h2><a name="t0"></a><a id="_FFmpegDemo_0"></a>一、 FFmpeg解复用(解封装)Demo</h2>
#include <stdio.h>
#include <libavformat/avformat.h>
int main(int argc, char **argv)
{
//打开网络流。这里如果只需要读取本地媒体文件,不需要用到网络功能,可以不用加上这一句
// avformat_network_init();
const char *default_filename = "believe.mp4";
char *in_filename = NULL;
if(argv[1] == NULL)
{
in_filename = default_filename;
}
else
{
in_filename = argv[1];
}
printf("in_filename = %s\n", in_filename);
//AVFormatContext是描述一个媒体文件或媒体流的构成和基本信息的结构体
AVFormatContext *ifmt_ctx = NULL; // 输入文件的demux
int videoindex = -1; // 视频索引
int audioindex = -1; // 音频索引
// 打开文件,主要是探测协议类型,如果是网络文件则创建网络链接
int ret = avformat_open_input(&ifmt_ctx, in_filename, NULL, NULL);
if (ret < 0) //如果打开媒体文件失败,打印失败原因
{
char buf[1024] = { 0 };
av_strerror(ret, buf, sizeof(buf) - 1);
printf("open %s failed:%s\n", in_filename, buf);
goto failed;
}
ret = avformat_find_stream_info(ifmt_ctx, NULL);
if (ret < 0) //如果打开媒体文件失败,打印失败原因
{
char buf[1024] = { 0 };
av_strerror(ret, buf, sizeof(buf) - 1);
printf("avformat_find_stream_info %s failed:%s\n", in_filename, buf);
goto failed;
}
//打开媒体文件成功
printf_s("\n==== av_dump_format in_filename:%s ===\n", in_filename);
av_dump_format(ifmt_ctx, 0, in_filename, 0);
printf_s("\n==== av_dump_format finish =======\n\n");
// url: 调用avformat_open_input读取到的媒体文件的路径/名字
printf("media name:%s\n", ifmt_ctx->url);
// nb_streams: nb_streams媒体流数量
printf("stream number:%d\n", ifmt_ctx->nb_streams);
// bit_rate: 媒体文件的码率,单位为bps
printf("media average ratio:%lldkbps\n",(int64_t)(ifmt_ctx->bit_rate/1024));
// 时间
int total_seconds, hour, minute, second;
// duration: 媒体文件时长,单位微妙
total_seconds = (ifmt_ctx->duration) / AV_TIME_BASE; // 1000us = 1ms, 1000ms = 1秒
hour = total_seconds / 3600;
minute = (total_seconds % 3600) / 60;
second = (total_seconds % 60);
//通过上述运算,可以得到媒体文件的总时长
printf("total duration: %02d:%02d:%02d\n", hour, minute, second);
printf("\n");
/*
* 老版本通过遍历的方式读取媒体文件视频和音频的信息
* 新版本的FFmpeg新增加了函数av_find_best_stream,也可以取得同样的效果
*/
for (uint32_t i = 0; i < ifmt_ctx->nb_streams; i++)
{
AVStream *in_stream = ifmt_ctx->streams[i];// 音频流、视频流、字幕流
//如果是音频流,则打印音频的信息
if (AVMEDIA_TYPE_AUDIO == in_stream->codecpar->codec_type)
{
printf("----- Audio info:\n");
// index: 每个流成分在ffmpeg解复用分析后都有唯一的index作为标识
printf("index:%d\n", in_stream->index);
// sample_rate: 音频编解码器的采样率,单位为Hz
printf("samplerate:%dHz\n", in_stream->codecpar->sample_rate);
// codecpar->format: 音频采样格式
if (AV_SAMPLE_FMT_FLTP == in_stream->codecpar->format)
{
printf("sampleformat:AV_SAMPLE_FMT_FLTP\n");
}
else if (AV_SAMPLE_FMT_S16P == in_stream->codecpar->format)
{
printf("sampleformat:AV_SAMPLE_FMT_S16P\n");
}
// channels: 音频信道数目
printf("channel number:%d\n", in_stream->codecpar->channels);
// codec_id: 音频压缩编码格式
if (AV_CODEC_ID_AAC == in_stream->codecpar->codec_id)
{
printf("audio codec:AAC\n");
}
else if (AV_CODEC_ID_MP3 == in_stream->codecpar->codec_id)
{
printf("audio codec:MP3\n");
}
else
{
printf("audio codec_id:%d\n", in_stream->codecpar->codec_id);
}
// 音频总时长,单位为秒。注意如果把单位放大为毫秒或者微妙,音频总时长跟视频总时长不一定相等的
if(in_stream->duration != AV_NOPTS_VALUE)
{
int duration_audio = (in_stream->duration) * av_q2d(in_stream->time_base);
//将音频总时长转换为时分秒的格式打印到控制台上
printf("audio duration: %02d:%02d:%02d\n",
duration_audio / 3600, (duration_audio % 3600) / 60, (duration_audio % 60));
}
else
{
printf("audio duration unknown");
}
printf("\n");
audioindex = i; // 获取音频的索引
}
else if (AVMEDIA_TYPE_VIDEO == in_stream->codecpar->codec_type) //如果是视频流,则打印视频的信息
{
printf("----- Video info:\n");
printf("index:%d\n", in_stream->index);
// avg_frame_rate: 视频帧率,单位为fps,表示每秒出现多少帧
printf("fps:%lffps\n", av_q2d(in_stream->avg_frame_rate));
if (AV_CODEC_ID_MPEG4 == in_stream->codecpar->codec_id) //视频压缩编码格式
{
printf("video codec:MPEG4\n");
}
else if (AV_CODEC_ID_H264 == in_stream->codecpar->codec_id) //视频压缩编码格式
{
printf("video codec:H264\n");
}
else
{
printf("video codec_id:%d\n", in_stream->codecpar->codec_id);
}
// 视频帧宽度和帧高度
printf("width:%d height:%d\n", in_stream->codecpar->width,
in_stream->codecpar->height);
//视频总时长,单位为秒。注意如果把单位放大为毫秒或者微妙,音频总时长跟视频总时长不一定相等的
if(in_stream->duration != AV_NOPTS_VALUE)
{
int duration_video = (in_stream->duration) * av_q2d(in_stream->time_base);
printf("video duration: %02d:%02d:%02d\n",
duration_video / 3600,
(duration_video % 3600) / 60,
(duration_video % 60)); //将视频总时长转换为时分秒的格式打印到控制台上
}
else
{
printf("video duration unknown");
}
printf("\n");
videoindex = i;
}
}
AVPacket *pkt = av_packet_alloc();
int pkt_count = 0;
int print_max_count = 10;
printf("\n-----av_read_frame start\n");
while (1)
{
ret = av_read_frame(ifmt_ctx, pkt);
if (ret < 0)
{
printf("av_read_frame end\n");
break;
}
if(pkt_count++ < print_max_count)
{
if (pkt->stream_index == audioindex)
{
printf("audio pts: %lld\n", pkt->pts);
printf("audio dts: %lld\n", pkt->dts);
printf("audio size: %d\n", pkt->size);
printf("audio pos: %lld\n", pkt->pos);
printf("audio duration: %lf\n\n",
pkt->duration * av_q2d(ifmt_ctx->streams[audioindex]->time_base));
}
else if (pkt->stream_index == videoindex)
{
printf("video pts: %lld\n", pkt->pts);
printf("video dts: %lld\n", pkt->dts);
printf("video size: %d\n", pkt->size);
printf("video pos: %lld\n", pkt->pos);
printf("video duration: %lf\n\n",
pkt->duration * av_q2d(ifmt_ctx->streams[videoindex]->time_base));
}
else
{
printf("unknown stream_index:\n", pkt->stream_index);
}
}
av_packet_unref(pkt);
}
if(pkt)
av_packet_free(&pkt);
failed:
if(ifmt_ctx)
avformat_close_input(&ifmt_ctx);
getchar(); //加上这一句,防止程序打印完信息马上退出
return 0;
}
- 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
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
二、读取媒体文件,将aac帧提取出到本地。
#include <stdio.h>
#include <libavutil/log.h>
#include <libavformat/avio.h>
#include <libavformat/avformat.h>
#define ADTS_HEADER_LEN 7;
const int sampling_frequencies[] = {
96000, // 0x0
88200, // 0x1
64000, // 0x2
48000, // 0x3
44100, // 0x4
32000, // 0x5
24000, // 0x6
22050, // 0x7
16000, // 0x8
12000, // 0x9
11025, // 0xa
8000 // 0xb
// 0xc d e f是保留的
};
int adts_header(char * const p_adts_header, const int data_length,
const int profile, const int samplerate,
const int channels)
{
<span class="token keyword">int</span> sampling_frequency_index <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// 默认使用48000hz</span>
<span class="token keyword">int</span> adtsLen <span class="token operator">=</span> data_length <span class="token operator">+</span> <span class="token number">7</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> frequencies_size <span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>sampling_frequencies<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>sampling_frequencies<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">for</span><span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> frequencies_size<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span><span class="token punctuation">(</span>sampling_frequencies<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> samplerate<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
sampling_frequency_index <span class="token operator">=</span> i<span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>i <span class="token operator">>=</span> frequencies_size<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"unsupport samplerate:%d\n"</span><span class="token punctuation">,</span> samplerate<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0xff</span><span class="token punctuation">;</span> <span class="token comment">//syncword:0xfff 高8bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0xf0</span><span class="token punctuation">;</span> <span class="token comment">//syncword:0xfff 低4bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator"><<</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//MPEG Version:0 for MPEG-4,1 for MPEG-2 1bit</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator"><<</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//Layer:0 2bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">//protection absent:1 1bit</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span>profile<span class="token punctuation">)</span><span class="token operator"><<</span><span class="token number">6</span><span class="token punctuation">;</span> <span class="token comment">//profile:profile 2bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span>sampling_frequency_index <span class="token operator">&</span> <span class="token number">0x0f</span><span class="token punctuation">)</span><span class="token operator"><<</span><span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">//sampling frequency index:sampling_frequency_index 4bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator"><<</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//private bit:0 1bit</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span>channels <span class="token operator">&</span> <span class="token number">0x04</span><span class="token punctuation">)</span><span class="token operator">>></span><span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">//channel configuration:channels 高1bit</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span>channels <span class="token operator">&</span> <span class="token number">0x03</span><span class="token punctuation">)</span><span class="token operator"><<</span><span class="token number">6</span><span class="token punctuation">;</span> <span class="token comment">//channel configuration:channels 低2bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator"><<</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//original:0 1bit</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator"><<</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//home:0 1bit</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator"><<</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//copyright id bit:0 1bit</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator"><<</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//copyright id start:0 1bit</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>adtsLen <span class="token operator">&</span> <span class="token number">0x1800</span><span class="token punctuation">)</span> <span class="token operator">>></span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//frame length:value 高2bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">uint8_t</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span>adtsLen <span class="token operator">&</span> <span class="token number">0x7f8</span><span class="token punctuation">)</span> <span class="token operator">>></span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//frame length:value 中间8bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">uint8_t</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span>adtsLen <span class="token operator">&</span> <span class="token number">0x7</span><span class="token punctuation">)</span> <span class="token operator"><<</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//frame length:value 低3bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span> <span class="token operator">|=</span> <span class="token number">0x1f</span><span class="token punctuation">;</span> <span class="token comment">//buffer fullness:0x7ff 高5bits</span>
p_adts_header<span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0xfc</span><span class="token punctuation">;</span> <span class="token comment">//11111100 //buffer fullness:0x7ff 低6bits</span>
<span class="token comment">// number_of_raw_data_blocks_in_frame:</span>
<span class="token comment">// 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧。</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
}
int main(int argc, char *argv[])
{
int ret = -1;
char errors[1024];
<span class="token keyword">char</span> <span class="token operator">*</span>in_filename <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token keyword">char</span> <span class="token operator">*</span>aac_filename <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
FILE <span class="token operator">*</span>aac_fd <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> audio_index <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> len <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
AVFormatContext <span class="token operator">*</span>ifmt_ctx <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
AVPacket pkt<span class="token punctuation">;</span>
<span class="token comment">// 设置打印级别</span>
<span class="token function">av_log_set_level</span><span class="token punctuation">(</span>AV_LOG_DEBUG<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>argc <span class="token operator"><</span> <span class="token number">3</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">av_log</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> AV_LOG_DEBUG<span class="token punctuation">,</span> <span class="token string">"the count of parameters should be more than three!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
in_filename <span class="token operator">=</span> argv<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 输入文件</span>
aac_filename <span class="token operator">=</span> argv<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 输出文件</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>in_filename <span class="token operator">==</span> <span class="token constant">NULL</span> <span class="token operator">||</span> aac_filename <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">av_log</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> AV_LOG_DEBUG<span class="token punctuation">,</span> <span class="token string">"src or dts file is null, plz check them!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
aac_fd <span class="token operator">=</span> <span class="token function">fopen</span><span class="token punctuation">(</span>aac_filename<span class="token punctuation">,</span> <span class="token string">"wb"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>aac_fd<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">av_log</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> AV_LOG_DEBUG<span class="token punctuation">,</span> <span class="token string">"Could not open destination file %s\n"</span><span class="token punctuation">,</span> aac_filename<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 打开输入文件</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">(</span>ret <span class="token operator">=</span> <span class="token function">avformat_open_input</span><span class="token punctuation">(</span><span class="token operator">&</span>ifmt_ctx<span class="token punctuation">,</span> in_filename<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">av_strerror</span><span class="token punctuation">(</span>ret<span class="token punctuation">,</span> errors<span class="token punctuation">,</span> <span class="token number">1024</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">av_log</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> AV_LOG_DEBUG<span class="token punctuation">,</span> <span class="token string">"Could not open source file: %s, %d(%s)\n"</span><span class="token punctuation">,</span>
in_filename<span class="token punctuation">,</span>
ret<span class="token punctuation">,</span>
errors<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 获取解码器信息</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">(</span>ret <span class="token operator">=</span> <span class="token function">avformat_find_stream_info</span><span class="token punctuation">(</span>ifmt_ctx<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">av_strerror</span><span class="token punctuation">(</span>ret<span class="token punctuation">,</span> errors<span class="token punctuation">,</span> <span class="token number">1024</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">av_log</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> AV_LOG_DEBUG<span class="token punctuation">,</span> <span class="token string">"failed to find stream information: %s, %d(%s)\n"</span><span class="token punctuation">,</span>
in_filename<span class="token punctuation">,</span>
ret<span class="token punctuation">,</span>
errors<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// dump媒体信息</span>
<span class="token function">av_dump_format</span><span class="token punctuation">(</span>ifmt_ctx<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> in_filename<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 初始化packet</span>
<span class="token function">av_init_packet</span><span class="token punctuation">(</span><span class="token operator">&</span>pkt<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 查找audio对应的steam index</span>
audio_index <span class="token operator">=</span> <span class="token function">av_find_best_stream</span><span class="token punctuation">(</span>ifmt_ctx<span class="token punctuation">,</span> AVMEDIA_TYPE_AUDIO<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>audio_index <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">av_log</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> AV_LOG_DEBUG<span class="token punctuation">,</span> <span class="token string">"Could not find %s stream in input file %s\n"</span><span class="token punctuation">,</span>
<span class="token function">av_get_media_type_string</span><span class="token punctuation">(</span>AVMEDIA_TYPE_AUDIO<span class="token punctuation">)</span><span class="token punctuation">,</span>
in_filename<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token function">AVERROR</span><span class="token punctuation">(</span>EINVAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 打印AAC级别</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"audio profile:%d, FF_PROFILE_AAC_LOW:%d\n"</span><span class="token punctuation">,</span>
ifmt_ctx<span class="token operator">-></span>streams<span class="token punctuation">[</span>audio_index<span class="token punctuation">]</span><span class="token operator">-></span>codecpar<span class="token operator">-></span>profile<span class="token punctuation">,</span>
FF_PROFILE_AAC_LOW<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>ifmt_ctx<span class="token operator">-></span>streams<span class="token punctuation">[</span>audio_index<span class="token punctuation">]</span><span class="token operator">-></span>codecpar<span class="token operator">-></span>codec_id <span class="token operator">!=</span> AV_CODEC_ID_AAC<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"the media file no contain AAC stream, it's codec_id is %d\n"</span><span class="token punctuation">,</span>
ifmt_ctx<span class="token operator">-></span>streams<span class="token punctuation">[</span>audio_index<span class="token punctuation">]</span><span class="token operator">-></span>codecpar<span class="token operator">-></span>codec_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">goto</span> failed<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 读取媒体文件,并把aac数据帧写入到本地文件</span>
<span class="token keyword">while</span><span class="token punctuation">(</span><span class="token function">av_read_frame</span><span class="token punctuation">(</span>ifmt_ctx<span class="token punctuation">,</span> <span class="token operator">&</span>pkt<span class="token punctuation">)</span> <span class="token operator">>=</span><span class="token number">0</span> <span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span><span class="token punctuation">(</span>pkt<span class="token punctuation">.</span>stream_index <span class="token operator">==</span> audio_index<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token keyword">char</span> adts_header_buf<span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">adts_header</span><span class="token punctuation">(</span>adts_header_buf<span class="token punctuation">,</span> pkt<span class="token punctuation">.</span>size<span class="token punctuation">,</span>
ifmt_ctx<span class="token operator">-></span>streams<span class="token punctuation">[</span>audio_index<span class="token punctuation">]</span><span class="token operator">-></span>codecpar<span class="token operator">-></span>profile<span class="token punctuation">,</span>
ifmt_ctx<span class="token operator">-></span>streams<span class="token punctuation">[</span>audio_index<span class="token punctuation">]</span><span class="token operator">-></span>codecpar<span class="token operator">-></span>sample_rate<span class="token punctuation">,</span>
ifmt_ctx<span class="token operator">-></span>streams<span class="token punctuation">[</span>audio_index<span class="token punctuation">]</span><span class="token operator">-></span>codecpar<span class="token operator">-></span>channels<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">fwrite</span><span class="token punctuation">(</span>adts_header_buf<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> aac_fd<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 写adts header , ts流不适用,ts流分离出来的packet带了adts header</span>
len <span class="token operator">=</span> <span class="token function">fwrite</span><span class="token punctuation">(</span> pkt<span class="token punctuation">.</span>data<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> pkt<span class="token punctuation">.</span>size<span class="token punctuation">,</span> aac_fd<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 写adts data</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>len <span class="token operator">!=</span> pkt<span class="token punctuation">.</span>size<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">av_log</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> AV_LOG_DEBUG<span class="token punctuation">,</span> <span class="token string">"warning, length of writed data isn't equal pkt.size(%d, %d)\n"</span><span class="token punctuation">,</span>
len<span class="token punctuation">,</span>
pkt<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token function">av_packet_unref</span><span class="token punctuation">(</span><span class="token operator">&</span>pkt<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
failed:
// 关闭输入文件
if(ifmt_ctx)
{
avformat_close_input(&ifmt_ctx);
}
if(aac_fd)
{
fclose(aac_fd);
}
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
}
- 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
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
三、从媒体文件中提取出h264视频帧到本地
#include <stdio.h>
#include <libavutil/log.h>
#include <libavformat/avio.h>
#include <libavformat/avformat.h>
static char err_buf[128] = {0};
static char* av_get_err(int errnum)
{
av_strerror(errnum, err_buf, 128);
return err_buf;
}
/*
AvCodecContext->extradata[]中为nalu长度
- codec_extradata:
- 1, 64, 0, 1f, ff, e1, [0, 18], 67, 64, 0, 1f, ac, c8, 60, 78, 1b, 7e,
- 78, 40, 0, 0, fa, 40, 0, 3a, 98, 3, c6, c, 66, 80,
- 1, [0, 5],68, e9, 78, bc, b0, 0,
*/
//ffmpeg -i 2018.mp4 -codec copy -bsf:h264_mp4toannexb -f h264 tmp.h264
//ffmpeg 从mp4上提取H264的nalu h
int main(int argc, char argv)
{
AVFormatContext ifmt_ctx = NULL;
int videoindex = -1;
AVPacket pkt = NULL;
int ret = -1;
int file_end = 0; // 文件是否读取结束
<span class="token keyword">if</span><span class="token punctuation">(</span>argc <span class="token operator"><</span> <span class="token number">3</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"usage inputfile outfile\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
FILE <span class="token operator">*</span>outfp<span class="token operator">=</span><span class="token function">fopen</span><span class="token punctuation">(</span>argv<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token string">"wb"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"in:%s out:%s\n"</span><span class="token punctuation">,</span> argv<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> argv<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 分配解复用器的内存,使用avformat_close_input释放</span>
ifmt_ctx <span class="token operator">=</span> <span class="token function">avformat_alloc_context</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>ifmt_ctx<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[error] Could not allocate context.\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 根据url打开码流,并选择匹配的解复用器</span>
ret <span class="token operator">=</span> <span class="token function">avformat_open_input</span><span class="token punctuation">(</span><span class="token operator">&</span>ifmt_ctx<span class="token punctuation">,</span>argv<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>ret <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[error]avformat_open_input: %s\n"</span><span class="token punctuation">,</span> <span class="token function">av_get_err</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 读取媒体文件的部分数据包以获取码流信息</span>
ret <span class="token operator">=</span> <span class="token function">avformat_find_stream_info</span><span class="token punctuation">(</span>ifmt_ctx<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[error]avformat_find_stream_info: %s\n"</span><span class="token punctuation">,</span> <span class="token function">av_get_err</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">avformat_close_input</span><span class="token punctuation">(</span><span class="token operator">&</span>ifmt_ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 查找出哪个码流是video/audio/subtitles</span>
videoindex <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token comment">// 推荐的方式</span>
videoindex <span class="token operator">=</span> <span class="token function">av_find_best_stream</span><span class="token punctuation">(</span>ifmt_ctx<span class="token punctuation">,</span> AVMEDIA_TYPE_VIDEO<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>videoindex <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Didn't find a video stream.\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">avformat_close_input</span><span class="token punctuation">(</span><span class="token operator">&</span>ifmt_ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 分配数据包</span>
pkt <span class="token operator">=</span> <span class="token function">av_packet_alloc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">av_init_packet</span><span class="token punctuation">(</span>pkt<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 1 获取相应的比特流过滤器</span>
<span class="token comment">//FLV/MP4/MKV等结构中,h264需要h264_mp4toannexb处理。添加SPS/PPS等信息。</span>
<span class="token comment">// FLV封装时,可以把多个NALU放在一个VIDEO TAG中,结构为4B NALU长度+NALU1+4B NALU长度+NALU2+...,</span>
<span class="token comment">// 需要做的处理把4B长度换成00000001或者000001</span>
<span class="token keyword">const</span> AVBitStreamFilter <span class="token operator">*</span>bsfilter <span class="token operator">=</span> <span class="token function">av_bsf_get_by_name</span><span class="token punctuation">(</span><span class="token string">"h264_mp4toannexb"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
AVBSFContext <span class="token operator">*</span>bsf_ctx <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token comment">// 2 初始化过滤器上下文</span>
<span class="token function">av_bsf_alloc</span><span class="token punctuation">(</span>bsfilter<span class="token punctuation">,</span> <span class="token operator">&</span>bsf_ctx<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//AVBSFContext;</span>
<span class="token comment">// 3 添加解码器属性</span>
<span class="token function">avcodec_parameters_copy</span><span class="token punctuation">(</span>bsf_ctx<span class="token operator">-></span>par_in<span class="token punctuation">,</span> ifmt_ctx<span class="token operator">-></span>streams<span class="token punctuation">[</span>videoindex<span class="token punctuation">]</span><span class="token operator">-></span>codecpar<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">av_bsf_init</span><span class="token punctuation">(</span>bsf_ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
file_end <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">==</span> file_end<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">(</span>ret <span class="token operator">=</span> <span class="token function">av_read_frame</span><span class="token punctuation">(</span>ifmt_ctx<span class="token punctuation">,</span> pkt<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token comment">// 没有更多包可读</span>
file_end <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"read file end: ret:%d\n"</span><span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&&</span> pkt<span class="token operator">-></span>stream_index <span class="token operator">==</span> videoindex<span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
#if 0
int input_size = pkt->size;
int out_pkt_count = 0;
if (av_bsf_send_packet(bsf_ctx, pkt) != 0) // bitstreamfilter内部去维护内存空间
{
av_packet_unref(pkt); // 你不用了就把资源释放掉
continue; // 继续送
}
av_packet_unref(pkt); // 释放资源
while(av_bsf_receive_packet(bsf_ctx, pkt) 0)
{
out_pkt_count++;
// printf(“fwrite size:%d\n”, pkt->size);
size_t size = fwrite(pkt->data, 1, pkt->size, outfp);
if(size != pkt->size)
{
printf(“fwrite failed-> write:%u, pkt_size:%u\n”, size, pkt->size);
}
av_packet_unref(pkt);
}
if(out_pkt_count >= 2)
{
printf(“cur pkt(size:%d) only get 1 out pkt, it get %d pkts\n”,
input_size, out_pkt_count);
}
#else // TS流可以直接写入
size_t size = fwrite(pkt->data, 1, pkt->size, outfp);
if(size != pkt->size)
{
printf(“fwrite failed-> write:%u, pkt_size:%u\n”, size, pkt->size);
}
av_packet_unref(pkt);
#endif
}
else
{
if(ret 0)
av_packet_unref(pkt); // 释放内存
}
}
if(outfp)
fclose(outfp);
if(bsf_ctx)
av_bsf_free(&bsf_ctx);
if(pkt)
av_packet_free(&pkt);
if(ifmt_ctx)
avformat_close_input(&ifmt_ctx);
printf(“finish\n”);
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
}
- 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
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
四、flv解封装
(1)FlvMetaData.cpp
#include "FlvMetaData.h"
FlvMetaData::FlvMetaData(uint8_t *meta, unsigned int length) {
m_meta <span class="token operator">=</span> meta<span class="token punctuation">;</span>
m_length <span class="token operator">=</span> length<span class="token punctuation">;</span>
m_duration <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_width <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_height <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_framerate <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_videodatarate <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_audiodatarate <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_videocodecid <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_audiosamplerate <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_audiosamplesize <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
m_stereo <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token function">parseMeta</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
FlvMetaData::FlvMetaData(const FlvMetaData& r) {
m_length <span class="token operator">=</span> r<span class="token punctuation">.</span>m_length<span class="token punctuation">;</span>
m_meta <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token keyword">uint8_t</span><span class="token punctuation">[</span>m_length<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">memcpy</span><span class="token punctuation">(</span>m_meta<span class="token punctuation">,</span> r<span class="token punctuation">.</span>m_meta<span class="token punctuation">,</span> m_length<span class="token punctuation">)</span><span class="token punctuation">;</span>
m_duration <span class="token operator">=</span> r<span class="token punctuation">.</span>m_duration<span class="token punctuation">;</span>
m_width <span class="token operator">=</span> r<span class="token punctuation">.</span>m_width<span class="token punctuation">;</span>
m_height <span class="token operator">=</span> r<span class="token punctuation">.</span>m_height<span class="token punctuation">;</span>
m_framerate <span class="token operator">=</span> r<span class="token punctuation">.</span>m_framerate<span class="token punctuation">;</span>
m_videodatarate <span class="token operator">=</span> r<span class="token punctuation">.</span>m_videodatarate<span class="token punctuation">;</span>
m_audiodatarate <span class="token operator">=</span> r<span class="token punctuation">.</span>m_audiodatarate<span class="token punctuation">;</span>
m_videocodecid <span class="token operator">=</span> r<span class="token punctuation">.</span>m_videocodecid<span class="token punctuation">;</span>
m_audiosamplerate <span class="token operator">=</span> r<span class="token punctuation">.</span>m_audiosamplerate<span class="token punctuation">;</span>
m_audiosamplesize <span class="token operator">=</span> r<span class="token punctuation">.</span>m_audiosamplesize<span class="token punctuation">;</span>
m_stereo <span class="token operator">=</span> r<span class="token punctuation">.</span>m_stereo<span class="token punctuation">;</span>
}
FlvMetaData& FlvMetaData::operator=(const FlvMetaData& r) {
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">==</span> <span class="token operator">&</span>r<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">return</span> <span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>m_meta <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">delete</span> m_meta<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
m_length <span class="token operator">=</span> r<span class="token punctuation">.</span>m_length<span class="token punctuation">;</span>
m_meta <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token keyword">uint8_t</span><span class="token punctuation">[</span>m_length<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">memcpy</span><span class="token punctuation">(</span>m_meta<span class="token punctuation">,</span> r<span class="token punctuation">.</span>m_meta<span class="token punctuation">,</span> m_length<span class="token punctuation">)</span><span class="token punctuation">;</span>
m_duration <span class="token operator">=</span> r<span class="token punctuation">.</span>m_duration<span class="token punctuation">;</span>
m_width <span class="token operator">=</span> r<span class="token punctuation">.</span>m_width<span class="token punctuation">;</span>
m_height <span class="token operator">=</span> r<span class="token punctuation">.</span>m_height<span class="token punctuation">;</span>
m_framerate <span class="token operator">=</span> r<span class="token punctuation">.</span>m_framerate<span class="token punctuation">;</span>
m_videodatarate <span class="token operator">=</span> r<span class="token punctuation">.</span>m_videodatarate<span class="token punctuation">;</span>
m_audiodatarate <span class="token operator">=</span> r<span class="token punctuation">.</span>m_audiodatarate<span class="token punctuation">;</span>
m_videocodecid <span class="token operator">=</span> r<span class="token punctuation">.</span>m_videocodecid<span class="token punctuation">;</span>
m_audiosamplerate <span class="token operator">=</span> r<span class="token punctuation">.</span>m_audiosamplerate<span class="token punctuation">;</span>
m_audiosamplesize <span class="token operator">=</span> r<span class="token punctuation">.</span>m_audiosamplesize<span class="token punctuation">;</span>
m_stereo <span class="token operator">=</span> r<span class="token punctuation">.</span>m_stereo<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">;</span>
}
FlvMetaData::~FlvMetaData() {
<span class="token keyword">if</span><span class="token punctuation">(</span>m_meta <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">delete</span> m_meta<span class="token punctuation">;</span>
m_meta <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
void FlvMetaData::parseMeta() {
<span class="token keyword">unsigned</span> <span class="token keyword">int</span> arrayLen <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">unsigned</span> <span class="token keyword">int</span> offset <span class="token operator">=</span> TAG_HEAD_LEN <span class="token operator">+</span> <span class="token number">13</span><span class="token punctuation">;</span>
<span class="token keyword">unsigned</span> <span class="token keyword">int</span> nameLen <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> numValue <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">bool</span> boolValue <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x08</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
arrayLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
arrayLen <span class="token operator">=</span> arrayLen <span class="token operator"><<</span> <span class="token number">8</span><span class="token punctuation">;</span>
arrayLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
arrayLen <span class="token operator">=</span> arrayLen <span class="token operator"><<</span> <span class="token number">8</span><span class="token punctuation">;</span>
arrayLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
arrayLen <span class="token operator">=</span> arrayLen <span class="token operator"><<</span> <span class="token number">8</span><span class="token punctuation">;</span>
arrayLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">//cerr << "ArrayLen = " << arrayLen << endl;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">//TODO:</span>
cerr <span class="token operator"><<</span> <span class="token string">"metadata format error!!!"</span> <span class="token operator"><<</span> endl<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> arrayLen<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
numValue <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
boolValue <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
nameLen <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
nameLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
nameLen <span class="token operator">=</span> nameLen <span class="token operator"><<</span> <span class="token number">8</span><span class="token punctuation">;</span>
nameLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">//cerr << "name length=" << nameLen << " ";</span>
<span class="token keyword">char</span> name<span class="token punctuation">[</span>nameLen <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
#if DEBUG
printf(“\norign \n”);
for(unsigned int i = 0; i < nameLen + 3; i++) {
printf(“%x “, m_meta[offset + i]);
}
printf(”\n”);
#endif
<span class="token function">memset</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">memcpy</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token operator">&</span>m_meta<span class="token punctuation">[</span>offset<span class="token punctuation">]</span><span class="token punctuation">,</span> nameLen<span class="token punctuation">)</span><span class="token punctuation">;</span>
name<span class="token punctuation">[</span>nameLen <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token char">'\0'</span><span class="token punctuation">;</span>
offset <span class="token operator">+=</span> nameLen<span class="token punctuation">;</span>
<span class="token comment">//cerr << "name=" << name << " ";</span>
#if DEBUG
printf(“memcpy\n”);
for(unsigned int i = 0; i < nameLen; i++) {
printf(“%x “, name[i]);
}
printf(”\n”);
#endif
switch(m_meta[offset++]) {
case 0x0: //Number type
numValue <span class="token operator">=</span> <span class="token function">hexStr2double</span><span class="token punctuation">(</span><span class="token operator">&</span>m_meta<span class="token punctuation">[</span>offset<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
offset <span class="token operator">+=</span> <span class="token number">8</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token number">0x1</span><span class="token operator">:</span> <span class="token comment">//Boolean type</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>offset<span class="token operator">++</span> <span class="token operator">!=</span> <span class="token number">0x00</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
boolValue <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token number">0x2</span><span class="token operator">:</span> <span class="token comment">//String type</span>
nameLen <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
nameLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
nameLen <span class="token operator">=</span> nameLen <span class="token operator"><<</span> <span class="token number">8</span><span class="token punctuation">;</span>
nameLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
offset <span class="token operator">+=</span> nameLen<span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token number">0x12</span><span class="token operator">:</span> <span class="token comment">//Long string type</span>
nameLen <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
nameLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
nameLen <span class="token operator">=</span> nameLen <span class="token operator"><<</span> <span class="token number">8</span><span class="token punctuation">;</span>
nameLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
nameLen <span class="token operator">=</span> nameLen <span class="token operator"><<</span> <span class="token number">8</span><span class="token punctuation">;</span>
nameLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
nameLen <span class="token operator">=</span> nameLen <span class="token operator"><<</span> <span class="token number">8</span><span class="token punctuation">;</span>
nameLen <span class="token operator">|=</span> m_meta<span class="token punctuation">[</span>offset<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
offset <span class="token operator">+=</span> nameLen<span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token comment">//FIXME:</span>
<span class="token keyword">default</span><span class="token operator">:</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"duration"</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_duration <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"width"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_width <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"height"</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_height <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"framerate"</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_framerate <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"videodatarate"</span><span class="token punctuation">,</span> <span class="token number">13</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_videodatarate <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"audiodatarate"</span><span class="token punctuation">,</span> <span class="token number">13</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_audiodatarate <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"videocodecid"</span><span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_videocodecid <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"audiosamplerate"</span><span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_audiosamplerate <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"audiosamplesize"</span><span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_audiosamplesize <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"audiocodecid"</span><span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_audiocodecid <span class="token operator">=</span> numValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">"stereo"</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
m_stereo <span class="token operator">=</span> boolValue<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
}
double FlvMetaData::hexStr2double(const uint8_t* hex, const unsigned int length) {
<span class="token keyword">double</span> ret <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">char</span> hexstr<span class="token punctuation">[</span>length <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">memset</span><span class="token punctuation">(</span>hexstr<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>hexstr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token function">sprintf</span><span class="token punctuation">(</span>hexstr <span class="token operator">+</span> i <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"%02x"</span><span class="token punctuation">,</span> hex<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">sscanf</span><span class="token punctuation">(</span>hexstr<span class="token punctuation">,</span> <span class="token string">"%llx"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">long</span> <span class="token keyword">long</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> ret<span class="token punctuation">;</span>
}
double FlvMetaData::getDuration() {
return m_duration;
}
double FlvMetaData::getWidth() {
return m_width;
}
double FlvMetaData::getHeight() {
return m_height;
}
double FlvMetaData::getFramerate() {
return m_framerate;
}
double FlvMetaData::getVideoDatarate() {
return m_videodatarate;
}
double FlvMetaData::getAudioDatarate() {
return m_audiodatarate;
}
double FlvMetaData::getVideoCodecId() {
return m_videocodecid;
}
double FlvMetaData::getAudioSamplerate() {
return m_audiosamplerate;
}
double FlvMetaData::getAudioSamplesize() {
return m_audiosamplesize;
}
double FlvMetaData::getAudioCodecId() {
return m_audiocodecid;
}
bool FlvMetaData::getStereo() {
return m_stereo;
}
- 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
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
(2) FlvMetaData.h
#ifndef FLVMETADATA_H
#define FLVMETADATA_H
#include <cstdint>
class FlvMetaData
{
public:
FlvMetaData(uint8_t *meta, uint32_t length);
~FlvMetaData();
<span class="token function">FlvMetaData</span><span class="token punctuation">(</span><span class="token keyword">const</span> FlvMetaData<span class="token operator">&</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
FlvMetaData<span class="token operator">&</span> <span class="token keyword">operator</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">const</span> FlvMetaData<span class="token operator">&</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getDuration</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getWidth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getFramerate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getVideoDatarate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getAudioDatarate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getVideoCodecId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getAudioCodecId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getAudioSamplerate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">double</span> <span class="token function">getAudioSamplesize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">bool</span> <span class="token function">getStereo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
private:
//convert HEX to double
double hexStr2double(const uint8_t* hex, const uint32_t length);
void parseMeta();
private:
uint8_t *m_meta;
uint32_t m_length;
<span class="token keyword">double</span> m_duration<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_width<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_height<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_framerate<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_videodatarate<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_audiodatarate<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_videocodecid<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_audiocodecid<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_audiosamplerate<span class="token punctuation">;</span>
<span class="token keyword">double</span> m_audiosamplesize<span class="token punctuation">;</span>
<span class="token keyword">bool</span> m_stereo<span class="token punctuation">;</span>
};
#endif // FLVMETADATA_H
- 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
(3)FlvPrase.cpp
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <iostream>
#include <fstream>
#include “FlvParser.h”
using namespace std;
#define CheckBuffer(x) { if ((nBufSize-nOffset)<(x)) { nUsedLen = nOffset; return 0;} }
int CFlvParser::CAudioTag::_aacProfile;
int CFlvParser::CAudioTag::_sampleRateIndex;
int CFlvParser::CAudioTag::_channelConfig;
static const uint32_t nH264StartCode = 0x01000000;
CFlvParser::CFlvParser()
{
_pFlvHeader = NULL;
_vjj = new CVideojj();
}
CFlvParser::~CFlvParser()
{
for (int i = 0; i < _vpTag.size(); i++)
{
DestroyTag(_vpTag[i]);
delete _vpTag[i];
}
if (_vjj != NULL)
delete _vjj;
}
int CFlvParser::Parse(uint8_t *pBuf, int nBufSize, int &nUsedLen)
{
int nOffset = 0;
<span class="token keyword">if</span> <span class="token punctuation">(</span>_pFlvHeader <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">CheckBuffer</span><span class="token punctuation">(</span><span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
_pFlvHeader <span class="token operator">=</span> <span class="token function">CreateFlvHeader</span><span class="token punctuation">(</span>pBuf<span class="token operator">+</span>nOffset<span class="token punctuation">)</span><span class="token punctuation">;</span>
nOffset <span class="token operator">+=</span> _pFlvHeader<span class="token operator">-></span>nHeadSize<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token function">CheckBuffer</span><span class="token punctuation">(</span><span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// nPrevSize(4字节) + Tag header(11字节)</span>
<span class="token keyword">int</span> nPrevSize <span class="token operator">=</span> <span class="token function">ShowU32</span><span class="token punctuation">(</span>pBuf <span class="token operator">+</span> nOffset<span class="token punctuation">)</span><span class="token punctuation">;</span>
nOffset <span class="token operator">+=</span> <span class="token number">4</span><span class="token punctuation">;</span>
Tag <span class="token operator">*</span>pTag <span class="token operator">=</span> <span class="token function">CreateTag</span><span class="token punctuation">(</span>pBuf <span class="token operator">+</span> nOffset<span class="token punctuation">,</span> nBufSize<span class="token operator">-</span>nOffset<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>pTag <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
nOffset <span class="token operator">-=</span> <span class="token number">4</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
nOffset <span class="token operator">+=</span> <span class="token punctuation">(</span><span class="token number">11</span> <span class="token operator">+</span> pTag<span class="token operator">-></span>_header<span class="token punctuation">.</span>nDataSize<span class="token punctuation">)</span><span class="token punctuation">;</span>
_vpTag<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>pTag<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
nUsedLen <span class="token operator">=</span> nOffset<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
}
int CFlvParser::PrintInfo()
{
Stat();
cout <span class="token operator"><<</span> <span class="token string">"vnum: "</span> <span class="token operator"><<</span> _sStat<span class="token punctuation">.</span>nVideoNum <span class="token operator"><<</span> <span class="token string">" , anum: "</span> <span class="token operator"><<</span> _sStat<span class="token punctuation">.</span>nAudioNum <span class="token operator"><<</span> <span class="token string">" , mnum: "</span> <span class="token operator"><<</span> _sStat<span class="token punctuation">.</span>nMetaNum <span class="token operator"><<</span> endl<span class="token punctuation">;</span>
cout <span class="token operator"><<</span> <span class="token string">"maxTimeStamp: "</span> <span class="token operator"><<</span> _sStat<span class="token punctuation">.</span>nMaxTimeStamp <span class="token operator"><<</span> <span class="token string">" ,nLengthSize: "</span> <span class="token operator"><<</span> _sStat<span class="token punctuation">.</span>nLengthSize <span class="token operator"><<</span> endl<span class="token punctuation">;</span>
cout <span class="token operator"><<</span> <span class="token string">"Vjj SEI num: "</span> <span class="token operator"><<</span> _vjj<span class="token operator">-></span>_vVjjSEI<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><<</span> endl<span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> _vjj<span class="token operator">-></span>_vVjjSEI<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
cout <span class="token operator"><<</span> <span class="token string">"SEI time : "</span> <span class="token operator"><<</span> _vjj<span class="token operator">-></span>_vVjjSEI<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>nTimeStamp <span class="token operator"><<</span> endl<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
}
int CFlvParser::DumpH264(const std::string &path)
{
fstream f;
f.open(path.c_str(), ios_base::out|ios_base::binary);
vector<span class="token operator"><</span>Tag <span class="token operator">*</span><span class="token operator">></span><span class="token double-colon punctuation">::</span>iterator it_tag<span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>it_tag <span class="token operator">=</span> _vpTag<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> it_tag <span class="token operator">!=</span> _vpTag<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> it_tag<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nType <span class="token operator">!=</span> <span class="token number">0x09</span><span class="token punctuation">)</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pMedia<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_nMediaLen<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
f<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
}
int CFlvParser::DumpAAC(const std::string &path)
{
fstream f;
f.open(path.c_str(), ios_base::out | ios_base::binary);
vector<span class="token operator"><</span>Tag <span class="token operator">*</span><span class="token operator">></span><span class="token double-colon punctuation">::</span>iterator it_tag<span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>it_tag <span class="token operator">=</span> _vpTag<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> it_tag <span class="token operator">!=</span> _vpTag<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> it_tag<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nType <span class="token operator">!=</span> <span class="token number">0x08</span><span class="token punctuation">)</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span>
CAudioTag <span class="token operator">*</span>pAudioTag <span class="token operator">=</span> <span class="token punctuation">(</span>CAudioTag <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>pAudioTag<span class="token operator">-></span>_nSoundFormat <span class="token operator">!=</span> <span class="token number">10</span><span class="token punctuation">)</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>pAudioTag<span class="token operator">-></span>_nMediaLen<span class="token operator">!=</span><span class="token number">0</span><span class="token punctuation">)</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pMedia<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_nMediaLen<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
f<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
}
int CFlvParser::DumpFlv(const std::string &path)
{
fstream f;
f.open(path.c_str(), ios_base::out | ios_base::binary);
<span class="token comment">// write flv-header</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span>_pFlvHeader<span class="token operator">-></span>pFlvHeader<span class="token punctuation">,</span> _pFlvHeader<span class="token operator">-></span>nHeadSize<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">uint32_t</span> nLastTagSize <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token comment">// write flv-tag</span>
vector<span class="token operator"><</span>Tag <span class="token operator">*</span><span class="token operator">></span><span class="token double-colon punctuation">::</span>iterator it_tag<span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>it_tag <span class="token operator">=</span> _vpTag<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> it_tag <span class="token operator"><</span> _vpTag<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> it_tag<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token punctuation">{<!-- --></span>
<span class="token keyword">uint32_t</span> nn <span class="token operator">=</span> <span class="token function">WriteU32</span><span class="token punctuation">(</span>nLastTagSize<span class="token punctuation">)</span><span class="token punctuation">;</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>nn<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//check duplicate start code</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nType <span class="token operator">==</span> <span class="token number">0x09</span> <span class="token operator">&&</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0x01</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">bool</span> duplicate <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token keyword">uint8_t</span> <span class="token operator">*</span>pStartCode <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span> <span class="token operator">+</span> _nNalUnitLength<span class="token punctuation">;</span>
<span class="token comment">//printf("tagsize=%d\n",(*it_tag)->_header.nDataSize);</span>
<span class="token keyword">unsigned</span> nalu_len <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">uint8_t</span> <span class="token operator">*</span>p_nalu_len<span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">uint8_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>nalu_len<span class="token punctuation">;</span>
<span class="token keyword">switch</span> <span class="token punctuation">(</span>_nNalUnitLength<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">case</span> <span class="token number">4</span><span class="token operator">:</span>
nalu_len <span class="token operator">=</span> <span class="token function">ShowU32</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token number">3</span><span class="token operator">:</span>
nalu_len <span class="token operator">=</span> <span class="token function">ShowU24</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token number">2</span><span class="token operator">:</span>
nalu_len <span class="token operator">=</span> <span class="token function">ShowU16</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">default</span><span class="token operator">:</span>
nalu_len <span class="token operator">=</span> <span class="token function">ShowU8</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/*
printf("nalu_len=%u\n",nalu_len);
printf("%x,%x,%x,%x,%x,%x,%x,%x,%x\n",(*it_tag)->_pTagData[5],(*it_tag)->_pTagData[6],
(*it_tag)->_pTagData[7],(*it_tag)->_pTagData[8],(*it_tag)->_pTagData[9],
(*it_tag)->_pTagData[10],(*it_tag)->_pTagData[11],(*it_tag)->_pTagData[12],
(*it_tag)->_pTagData[13]);
*/</span>
<span class="token keyword">uint8_t</span> <span class="token operator">*</span>pStartCodeRecord <span class="token operator">=</span> pStartCode<span class="token punctuation">;</span>
<span class="token keyword">int</span> i<span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nDataSize <span class="token operator">-</span> <span class="token number">5</span> <span class="token operator">-</span> _nNalUnitLength <span class="token operator">-</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>pStartCode<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x00</span> <span class="token operator">&&</span> pStartCode<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x00</span> <span class="token operator">&&</span> pStartCode<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x00</span> <span class="token operator">&&</span>
pStartCode<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x01</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>pStartCode<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x67</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">//printf("duplicate sps found!\n");</span>
i <span class="token operator">+=</span> <span class="token number">4</span><span class="token punctuation">;</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>pStartCode<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x68</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">//printf("duplicate pps found!\n");</span>
i <span class="token operator">+=</span> <span class="token number">4</span><span class="token punctuation">;</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>pStartCode<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x06</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">//printf("duplicate sei found!\n");</span>
i <span class="token operator">+=</span> <span class="token number">4</span><span class="token punctuation">;</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
i <span class="token operator">+=</span> <span class="token number">4</span><span class="token punctuation">;</span>
<span class="token comment">//printf("offset=%d\n",i);</span>
duplicate <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>duplicate<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
nalu_len <span class="token operator">-=</span> i<span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nDataSize <span class="token operator">-=</span> i<span class="token punctuation">;</span>
<span class="token keyword">uint8_t</span> <span class="token operator">*</span>p <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">uint8_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nDataSize<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagHeader<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> p<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagHeader<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagHeader<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> p<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">//printf("after,tagsize=%d\n",(int)ShowU24((*it_tag)->_pTagHeader + 1));</span>
<span class="token comment">//printf("%x,%x,%x\n",(*it_tag)->_pTagHeader[1],(*it_tag)->_pTagHeader[2],(*it_tag)->_pTagHeader[3]);</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagHeader<span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">switch</span> <span class="token punctuation">(</span>_nNalUnitLength<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token keyword">case</span> <span class="token number">4</span><span class="token operator">:</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">7</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token number">3</span><span class="token operator">:</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">7</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token number">2</span><span class="token operator">:</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">default</span><span class="token operator">:</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">=</span> p_nalu_len<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//printf("after,nalu_len=%d\n",(int)ShowU32((*it_tag)->_pTagData + 5));</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData<span class="token punctuation">,</span> pStartCode <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/*
printf("%x,%x,%x,%x,%x,%x,%x,%x,%x\n",(*it_tag)->_pTagData[0],(*it_tag)->_pTagData[1],(*it_tag)->_pTagData[2],
(*it_tag)->_pTagData[3],(*it_tag)->_pTagData[4],(*it_tag)->_pTagData[5],(*it_tag)->_pTagData[6],
(*it_tag)->_pTagData[7],(*it_tag)->_pTagData[8]);
*/</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span>pStartCode <span class="token operator">+</span> i<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nDataSize <span class="token operator">-</span> <span class="token punctuation">(</span>pStartCode <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/*
printf("write size:%d\n", (pStartCode - (*it_tag)->_pTagData) +
((*it_tag)->_header.nDataSize - (pStartCode - (*it_tag)->_pTagData)));
*/</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagHeader<span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nDataSize<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagHeader<span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_pTagData<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nDataSize<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
nLastTagSize <span class="token operator">=</span> <span class="token number">11</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token operator">*</span>it_tag<span class="token punctuation">)</span><span class="token operator">-></span>_header<span class="token punctuation">.</span>nDataSize<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">uint32_t</span> nn <span class="token operator">=</span> <span class="token function">WriteU32</span><span class="token punctuation">(</span>nLastTagSize<span class="token punctuation">)</span><span class="token punctuation">;</span>
f<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>nn<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
f<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
}
int CFlvParser::Stat()
{
for (int i = 0; i < _vpTag.size(); i++)
{
switch (_vpTag[i]->_header.nType)
{
case 0x08:
_sStat.nAudioNum++;
break;
case 0x09:
StatVideo(_vpTag[i]);
break;
case 0x12:
_sStat.nMetaNum++;
break;
default:
;
}
}
<span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
}
int CFlvParser::StatVideo(Tag *pTag)
{
_sStat.nVideoNum++;
_sStat.nMaxTimeStamp = pTag->_header.nTimeStamp;
<span class="token keyword">if</span> <span class="token punctuation">(</span>pTag<span class="token operator">-></span>_pTagData<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">0x17</span> <span class="token operator">&&</span> pTag<span class="token operator">-></span>_pTagDat