我有带有VP8编码数据的RTP数据包。我想将它写入mkv文件或webm文件。我尝试了一下,但我还没有成功。我的代码如下
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <libavutil/avassert.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
bool mfmedia_init_ffmpeg();
void mfmedia_ffprint(void *handle, int cnt, const char *format, va_list valist);
int main()
{
mfmedia_init_ffmpeg();
return 0;
}
bool mfmedia_init_ffmpeg()
{
bool ret = false;
AVCodecContext* context;
AVCodec* codec;
AVFormatContext* format;
AVStream* stream;
unsigned fps = 24;
unsigned width = 768;
unsigned height = 608;
av_register_all();
int err = 0;
char errorLog[128] = { 0 };
av_log_set_level(AV_LOG_TRACE);
av_log_set_callback(mfmedia_ffprint);
err = avformat_alloc_output_context2(&format, NULL, NULL, "o.webm");
if (err < 0)
{
printf("Cannot allocate output context: %s\n", av_make_error_string(errorLog, 128, err));
goto last;
}
codec = avcodec_find_encoder(AV_CODEC_ID_VP8);
if (!codec)
{
printf("Cannot find an encoder\n");
goto last;
}
context = avcodec_alloc_context3(codec);
if (!context)
{
printf("Cannot allocate a codec context\n");
goto last;
}
context->pix_fmt = AV_PIX_FMT_YUV420P;
context->width = width;
context->height = height;
context->time_base = (AVRational){1, fps};
err = avcodec_open2(context, codec, NULL);
if(err < 0)
{
printf("Cannot open codec: %s\n", av_make_error_string(errorLog, 128, err));
goto last;
}
stream = avformat_new_stream(format, codec);
if (!stream)
{
printf("Cannot create a new stream\n");
goto last;
}
//av_dump_format(format, 0, "o.webm", 1);
err = avio_open(&format->pb, "o.webm", AVIO_FLAG_WRITE);
if(err < 0)
{
printf("Cannot open output: %s\n", av_make_error_string(errorLog, 128, err));
goto last;
}
err = avformat_write_header(format, NULL);
if(err < 0)
{
printf("Cannot write header to stream: %s\n", av_make_error_string(errorLog, 128, err));
goto last;
}
ret = true;
last:
return ret;
}
void mfmedia_ffprint(void *handle, int cnt, const char *format, va_list valist)
{
char *log_buf = (char *)malloc(38192);
int length;
if(log_buf)
{
time_t rawtime;
time ( &rawtime );
length = vsprintf(log_buf ,format, valist);
length += sprintf((log_buf + length), " : %s ", ctime (&rawtime));
*(log_buf + length) = 0x0;
printf("%s", log_buf);
fflush(stdout);
free(log_buf);
}
}
当我调用avformat_write_header时失败。
从跟踪日志(到结尾),我看到了
设置默认白名单'文件,加密'
:1月19日星期五16:58:57 2018年
不推荐使用AVStream.codec将编解码器参数传递给多路复用器,而是使用AVStream.codecpar。
:1月19日星期五16:58:57 2018年
尺寸未设定
:1月19日星期五16:58:57 2018年
无法将标题写入流:无效的参数
请告诉我为什么avformat_write_header失败。
答案 0 :(得分:1)
这应该可行,请在//av_dump_format(format, 0, "o.webm", 1);
/* copy the stream parameters to the muxer */
err = avcodec_parameters_from_context(stream->codecpar, context);
if (err < 0) {
fprintf(stderr, "Could not copy the stream parameters\n");
exit(1);
}