摘要: FFMPEG日志说明
日志示例:
[root@andrew ffmpeg-3.2]# ./ffmpeg -i rtmp://180.97.184.107:1936/live?vhost=cc.com/stream_1 -c copy -y -f flv test_out1.flv -v 56 -t 10
ffmpeg version 3.2-static Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-16)
configuration: --enable-gpl --enable-nonfree --disable-shared --enable-postproc --enable-bzlib --enable-zlib --enable-parsers --enable-libx264 --enable-libx265 --enable-libmp3lame --enable-libfdk-aac --enable-pthreads --extra-ldflags=-static --disable-ffserver --enable-ffplay --enable-asm --enable-yasm --enable-optimizations --pkg-config-flags=--static --extra-cflags=--static --extra-version=static --enable-libspeex --extra-ldflags=-L/usr/local/lib --extra-cflags=-I/usr/local/include --extra-libs=-lrtmp
libavutil 55. 34.100 / 55. 34.100
libavcodec 57. 64.100 / 57. 64.100
libavformat 57. 56.100 / 57. 56.100
libavdevice 57. 1.100 / 57. 1.100
libavfilter 6. 65.100 / 6. 65.100
libswscale 4. 2.100 / 4. 2.100
libswresample 2. 3.100 / 2. 3.100
libpostproc 54. 1.100 / 54. 1.100
Splitting the commandline.
Reading option '-i' ... matched as input file with argument 'rtmp://180.97.184.107:1936/live?vhost=cc.com/stream_1'.
Reading option '-c' ... matched as option 'c' (codec name) with argument 'copy'.
Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'flv'.
Reading option 'test_out1.flv' ... matched as output file.
Reading option '-v' ... matched as option 'v' (set logging level) with argument '56'.
Reading option '-t' ... matched as option 't' (record or transcode "duration" seconds of audio/video) with argument '10'.
Trailing options were found on the commandline.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option y (overwrite output files) with argument 1.
Applying option v (set logging level) with argument 56.
Successfully parsed a group of options.
Parsing a group of options: input file rtmp://180.97.184.107:1936/live?vhost=cc.com/stream_1.
Successfully parsed a group of options.
Opening an input file: rtmp://180.97.184.107:1936/live?vhost=cc.com/stream_1.
[rtmp @ 0x3a615e0] No default whitelist set
[tcp @ 0x3a61ac0] No default whitelist set
[rtmp @ 0x3a615e0] Handshaking...
[rtmp @ 0x3a615e0] Type answer 3
[rtmp @ 0x3a615e0] Server version 13.14.10.13
[rtmp @ 0x3a615e0] Proto = rtmp, path = /live?vhost=cc.com/stream_1, app = live?vhost=cc.com, fname = stream_1
[rtmp @ 0x3a615e0] Server bandwidth = 5000000
[rtmp @ 0x3a615e0] Client bandwidth = 5000000
[rtmp @ 0x3a615e0] New incoming chunk size = 4096
[rtmp @ 0x3a615e0] Creating stream...
[rtmp @ 0x3a615e0] Sending play command for 'stream_1'
Probing flv score:100 size:2048
Probing mp3 score:1 size:2048
[flv @ 0x3a60c80] Format flv probed with size=2048 and score=100
[flv @ 0x3a60c80] Before avformat_find_stream_info() pos: 13 bytes read:33294 seeks:0 nb_streams:0
[flv @ 0x3a60c80] type:18, size:405, last:-1, dts:0 pos:21
[flv @ 0x3a60c80] type:8, size:7, last:-1, dts:1614036 pos:441
[flv @ 0x3a60c80] audio stream discovered after head already parsed
[flv @ 0x3a60c80] 1 AF 0
[flv @ 0x3a60c80] type:9, size:56, last:-1, dts:1614046 pos:463
[flv @ 0x3a60c80] video stream discovered after head already parsed
[flv @ 0x3a60c80] 0 17 0
[flv @ 0x3a60c80] type:9, size:52148, last:-1, dts:1614088 pos:534
[flv @ 0x3a60c80] 0 17 0
[NULL @ 0x3a74ee0] nal_unit_type: 7, nal_ref_idc: 3
[NULL @ 0x3a74ee0] nal_unit_type: 8, nal_ref_idc: 3
[h264 @ 0x3a74ee0] nal_unit_type: 7, nal_ref_idc: 3
[h264 @ 0x3a74ee0] nal_unit_type: 8, nal_ref_idc: 3
[h264 @ 0x3a74ee0] nal_unit_type: 5, nal_ref_idc: 3
[h264 @ 0x3a74ee0] Reinit context to 1920x1088, pix_fmt: yuv420p
[h264 @ 0x3a74ee0] no picture
日志函数av_log()
void av_log(void* avcl, int level, const char *fmt, ...)
{
AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
va_list vl;
va_start(vl, fmt);
if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
avc->log_level_offset_offset && level >= AV_LOG_FATAL)
level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
av_vlog(avcl, level, fmt, vl);
va_end(vl);
}
av_log()第一个参数为NULL
例如:
av_log(NULL, AV_LOG_DEBUG, "Splitting the commandline.\n");
直接输出日志内容
av_log()第一个参数有明确的类型
例如:
av_log(uc, AV_LOG_DEBUG, "No default whitelist set\n");
其中URLContext *uc。
根据av_log定义,输出class_name的内容。
其中libavformat/rtmpproto.c,对于rtmp协议,item_name()函数回调av_default_item_name函数(),而class_name为rtmp
const char *av_default_item_name(void *ptr)
{
return (*(AVClass **) ptr)->class_name;
}
#define RTMP_PROTOCOL(flavor) \
static const AVClass flavor##_class = { \
.class_name = #flavor, \
.item_name = av_default_item_name, \
.option = rtmp_options, \
.version = LIBAVUTIL_VERSION_INT, \
}; \
\
const URLProtocol ff_##flavor##_protocol = { \
.name = #flavor, \
.url_open = rtmp_open, \
.url_read = rtmp_read, \
.url_read_seek = rtmp_seek, \
.url_read_pause = rtmp_pause, \
.url_write = rtmp_write, \
.url_close = rtmp_close, \
.priv_data_size = sizeof(RTMPContext), \
.flags = URL_PROTOCOL_FLAG_NETWORK, \
.priv_data_class= &flavor##_class, \
};
RTMP_PROTOCOL(rtmp)
RTMP_PROTOCOL(rtmpe)
RTMP_PROTOCOL(rtmps)
RTMP_PROTOCOL(rtmpt)
RTMP_PROTOCOL(rtmpte)
RTMP_PROTOCOL(rtmpts)
其中libavformat/tcp.c,对于tcp协议,item_name()函数回调av_default_item_name函数(),而class_name为tcp
const char *av_default_item_name(void *ptr)
{
return (*(AVClass **) ptr)->class_name;
}
static const AVClass tcp_class = {
.class_name = "tcp",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
const URLProtocol ff_tcp_protocol = {
.name = "tcp",
.url_open = tcp_open,
.url_accept = tcp_accept,
.url_read = tcp_read,
.url_write = tcp_write,
.url_close = tcp_close,
.url_get_file_handle = tcp_get_file_handle,
.url_shutdown = tcp_shutdown,
.priv_data_size = sizeof(TCPContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
.priv_data_class = &tcp_class,
};
av_log()第一个参数使用默认类型
例如:
av_log(logctx, AV_LOG_DEBUG,
"Format %s probed with size=%d and score=%d\n",
(*fmt)->name, probe_size, score);
static const char* format_to_name(void* ptr)
{
AVFormatContext* fc = (AVFormatContext*) ptr;
if(fc->iformat) return fc->iformat->name;
else if(fc->oformat) return fc->oformat->name;
else return "NULL";
}
static const AVClass av_format_context_class = {
.class_name = "AVFormatContext",
.item_name = format_to_name,
.option = avformat_options,
.version = LIBAVUTIL_VERSION_INT,
.child_next = format_child_next,
.child_class_next = format_child_class_next,
.category = AV_CLASS_CATEGORY_MUXER,
.get_category = get_category,
};
static void avformat_get_context_defaults(AVFormatContext *s)
{
memset(s, 0, sizeof(AVFormatContext));
s->av_class = &av_format_context_class;
s->io_open = io_open_default;
s->io_close = io_close_default;
av_opt_set_defaults(s);
}
static const AVClass flv_class = {
.class_name = "flvdec",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_flv_demuxer = {
.name = "flv",
.long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
.priv_data_size = sizeof(FLVContext),
.read_probe = flv_probe,
.read_header = flv_read_header,
.read_packet = flv_read_packet,
.read_seek = flv_read_seek,
.read_close = flv_read_close,
.extensions = "flv",
.priv_class = &flv_class,
};
其中函数item_name()回调函数format_to_name(),所以打印出:[flv @ 0x3a60c80] Format flv probed with size=2048 and score=100
© 著作权归作者所有