编辑:在以前的版本中,我使用了一个非常古老的ffmpeg API.我现在使用最新的库.问题只是略有改变,从"主要"到"高".
我正在使用ffmpeg C API在C++中创建mp4视频.
我希望得到的视频属于"约束基线",这样生成的视频可以在尽可能多的平台上播放,特别是移动,但我每次都获得"高"配置文件,即使我对编解码器进行了硬编码个人资料为FF_PROFILE_H264_CONSTRAINED_BASELINE.因此,视频无法在我们所有的测试平台上播放.
这就是"ffprobe video.mp4 -show_streams"讲述我的视频流:
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
creation_time : 1970-01-01 00:00:00
encoder : Lavf53.5.0
Duration: 00:00:13.20, start: 0.000000, bitrate: 553 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 320x180,
424 kb/s, 15 fps, 15 tbr, 15 tbn, 30 tbc
Metadata:
creation_time : 1970-01-01 00:00:00
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, s16, 12
kb/s
Metadata:
creation_time : 1970-01-01 …Run Code Online (Sandbox Code Playgroud) 我正在写一个小工具,它将视频转换为原始的h264文件。这些文件应稍后通过SIP电话播放。我有以下代码:
eccx->pix_fmt = PIX_FMT_YUV420P;
eccx->width = VIDEO_FRAME_WIDTH;
eccx->height = VIDEO_FRAME_HEIGHT;
eccx->time_base.num = 1;
eccx->time_base.den = VIDEO_FRAMES_PER_SEC;
eccx->max_b_frames = 0;
eccx->rtp_payload_size = VIDEO_RTP_PAYLOAD_SIZE;
eccx->bit_rate = VIDEO_BIT_RATE;
eccx->rc_max_rate = VIDEO_BIT_RATE;
eccx->rc_buffer_size = VIDEO_BIT_RATE * 2;
eccx->flags |= CODEC_FLAG_QP_RD;
eccx->flags |= CODEC_FLAG_LOW_DELAY;
eccx->flags |= CODEC_FLAG_QSCALE;
eccx->flags |= CODEC_FLAG_EMU_EDGE;
eccx->mb_decision = FF_MB_DECISION_SIMPLE;
switch(video){
case H263:
break;
case H263P:
eccx->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
break;
case H264:
av_dict_set(&options, "vprofile", "baseline", 0);
eccx->flags2 = CODEC_FLAG2_FASTPSKIP;
eccx->profile = FF_PROFILE_H264_BASELINE;
eccx->level = 13;
break;
}
Run Code Online (Sandbox Code Playgroud)
执行此程序时,我从libx264得到以下输出:
[libx264 @ 0x10fad60] using …Run Code Online (Sandbox Code Playgroud) 众所周知,在Smooth Stream客户端清单文件中,视频标记中包含"CodecPrivateData"属性.在我初步调查之后,我发现这个字符串是使用SPS和PPS形成的,它们基本上是NAL单位.
我正在寻找一种从视频GOP中提取该信息的方法,以便我可以使用相同的方法创建清单文件并手动替换编解码器私有数据
基本上,我期待使用ffmpeg创建自定义应用程序以创建流畅的表示
我正在用C++编写一个应用程序,它使用libavcodec和libx264对视频进行编码.然而,编码数据最终比我预期的要大得多.我分析了结果并发现我的编码从未产生过B帧,只有I帧和P帧.
我创建了一个基于ffmpeg源代码和示例的独立实用程序来测试我的编码器设置.它读入H.264文件,重新编码解码的帧,并使用ITU H.264附录B格式将结果输出到文件.我还使用ffmpeg执行相同的操作,因此我可以与已知良好的实现进行比较.我的实用程序从不输出B帧,而ffmpeg则输出.
我已经试图弄清楚我的代码没有做什么ffmpeg.我首先尝试手动指定与B帧相关的编码器设置.这没有效果.
然后我尝试在gdb下运行ffmpeg和我的实用程序,并在打开编码器之前比较AVStream,AVCodecContext和X264Context的内容,并手动设置看起来不同的任何字段.即使设置相同,我仍然只生产I帧和P帧.
最后,我想也许问题出在我的时间戳处理上.我重新设计了我的测试实用程序,以模仿ffmpeg使用的管道,并像ffmpeg那样输出时间戳调试输出.即使我的时间戳与ffmpeg相同,我仍然没有得到B帧.
在这一点上,我不知道还有什么可以尝试.当我运行ffmpeg时,我使用下面的命令行运行它.请注意,除了"超高速"预设外,我几乎都使用默认值.
ffmpeg -v debug -i ~/annexb.264 -codec:v libx264 -preset superfast -g 30 -f h264 ./out.264
Run Code Online (Sandbox Code Playgroud)
下面列出了配置编码器的代码.它也指定了"超高速"预设.
static AVStream *add_video_stream(AVFormatContext *output_ctx, AVCodec **output_codec, enum AVCodecID codec_id)
{
*output_codec = avcodec_find_encoder(codec_id);
if (*output_codec == NULL) {
printf("Could not find encoder for '%s' (%d)\n", avcodec_get_name(codec_id), codec_id);
return NULL;
}
AVStream *output_stream = avformat_new_stream(output_ctx, *output_codec);
if (output_stream == NULL) {
printf("Could not create video stream.\n");
return NULL;
}
output_stream->id = output_ctx->nb_streams - 1;
AVCodecContext *codec_ctx = output_stream->codec;
avcodec_get_context_defaults3(codec_ctx, …Run Code Online (Sandbox Code Playgroud) 我正在使用zeranoe.com的开发版,其中包含OpenH264和libx264.如何在这两个解码器之间进行选择以比较解码速度?
avcodec_find_decoder(AVCodecID.AV_CODEC_ID_H264);
Run Code Online (Sandbox Code Playgroud)
只给我一个名字"h264",但它是哪个解码器?
并尝试强制特定解码器失败,如:
codec = avcodec_find_decoder _by_name("x264");
codec = avcodec_find_decoder _by_name("libx264");
Run Code Online (Sandbox Code Playgroud)
还有哪些其他选项可以提高avcodec_decode_video2对于高(4k及更高)RTSP视频流的解码速度?
我想制作一个 AVPacket 的副本,以便以后可以在我喜欢的时候对其进行解码。
AVPacket 来自音频流。
av_dup_packet 似乎不起作用。
AVPacket 复制构造函数不起作用。
创建我自己的复制构造函数会导致内存损坏。
我正在尝试使用 libavcodec/ffmpeg API 对 AAC-LC、AAC-HE-V1、AAC-HE-V2 中的音频进行编码。
但是当我使用以下配置和 API 调用时。它显示“无效的 AAC 配置文件”。
AVCodecContext *encoder_ctx;
encoder_ctx->codec_id = AV_CODEC_ID_AAC;
encoder_ctx->sample_fmt = AV_SAMPLE_FMT_S16;
encoder_ctx->profile = FF_PROFILE_AAC_HE;
encoder = avcodec_find_encoder(encoder_ctx->codec_id);
avcodec_open2(encoder_ctx, encoder, NULL);
Run Code Online (Sandbox Code Playgroud)
您能解释一下这有什么问题吗?
我正在尝试将帧数据从AVFrame结构复制到缓冲区。我知道如何使用YUV420P格式来做到这一点,因为 Y 数据存储在内部AVFrame frame->data[0],U 数据存储在内部AVFrame frame->data[1],V 数据存储在内部AVFrame frame->data[2],因此很容易memcpy()单独处理 Y、U 和 V 数据+它是平面格式,所以我能够做到这一点轻松:
for (y = 0; y < height; y++)
{
memcpy(buffer + y*frame->linesize[0], frame->data[0] + y*frame->linesize[0], width);
}
buffer += ySize;
for (y = 0; y < height / 2; y++)
{
memcpy(buffer + y*frame->linesize[1], frame->data[1] + y*frame->linesize[1], width / 2);
}
buffer += uSize;
for (y = 0; y < height / 2; y++)
{
memcpy(buffer …Run Code Online (Sandbox Code Playgroud) 我使用 ffmpeg 的 avcodec 从我的 C++ 应用程序中的音乐文件中检索原始音频样本。对于我测试的文件,这些文件样本的字节序似乎是小字节序,但我想知道对于我尝试解码的所有文件是否总是如此(即来自 ffmpeg 的实现或至少它的体系结构 -具体是因为我的计算机的体系结构使用小字节序)。如果没有,我认为这将取决于特定文件的编码格式。在这种情况下,我如何检查我正在解码的每个文件适用哪种字节序?我在文档中找不到任何相关信息。
根据此处的文档,Libav 提供了多线程解码的“基础设施”。但文档对于多线程解码的实现方式模糊且令人困惑。它是内部支持的并且只需要在结构中设置一个标志,还是用户必须使用所提供的函数提供自己的实现?我进行了很多搜索,但甚至找不到一个使用 libav 进行多线程视频解码的示例。