用 libav / ffmpeg 替换 Bento4

海纳

我们使用 Bento4——一个设计精良的 SDK——在 .mov 容器中解复用 mp4 文件。解码由自己的编解码器完成,因此只需要原始(帧内)样本。到目前为止,这非常简单

AP4_Track *test_videoTrack = nullptr;
AP4_ByteStream *input = nullptr;
AP4_Result result = AP4_FileByteStream::Create(filename, AP4_FileByteStream::STREAM_MODE_READ, input);

AP4_File m_file (*input, true);

//
// Read movie tracks, and metadata, find the video track
size_t index = 0;
uint32_t m_width = 0, m_height = 0;
auto item = m_file.GetMovie()->GetTracks().FirstItem();
auto track = item->GetData();
if (track->GetType() == AP4_Track::TYPE_VIDEO) 
{
    m_width = (uint32_t)((double)test_videoTrack->GetWidth() / double(1 << 16));
    m_height = (uint32_t)((double)test_videoTrack->GetHeight() / double(1 << 16));

    std::string codec("unknown");
    auto sd = track->GetSampleDescription(0);
    AP4_String c;
    if (AP4_SUCCEEDED(sd->GetCodecString(c))) 
    {
        codec = c.GetChars();
    }

    // Find and instantiate the decoder
    AP4_Sample sample;
    AP4_DataBuffer sampleData;
    test_videoTrack->ReadSample(0, sample, sampleData);
}

出于多种原因,我们更愿意用 libav/ffmpeg 替换 Bento4(主要是因为我们已经在项目中并希望减少依赖项)

我们将如何(最好用伪代码)用 libav 替换上面完成的 Bento4 任务?请记住,使用的编解码器不在 ffmpeg 库中,因此我们不能使用标准的 ffmpeg 解码示例。打开媒体文件只是失败。没有解码器,到目前为止我们没有大小或任何其他信息。我们需要什么

  • 打开媒体文件
  • 获取包含的曲目(可能还有音频)
  • 获取轨道大小/长度信息
  • 按索引获取跟踪样本
海纳

结果证明这很容易:

AVFormatContext* inputFile = avformat_alloc_context();
avformat_open_input(&inputFile, filename, nullptr, nullptr);
avformat_find_stream_info(inputFile, nullptr);

//Get just two streams...First Video & First Audio
int videoStreamIndex = -1, audioStreamIndex = -1;
for (int i = 0; i < inputFile->nb_streams; i++)
{
    if (inputFile->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && videoStreamIndex == -1)
    {
            videoStreamIndex = i;
    }
    else if (inputFile->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audioStreamIndex == -1)
    {
        audioStreamIndex = i;
    }
}

现在测试正确的编解码器标签

// get codec id
char ct[64] = {0};
static const char* codec_id = "MPAK";
av_get_codec_tag_string( ct, sizeof(ct),inputFile->streams[videoStreamIndex]->codec->codec_tag);
assert(strncmp( ct , codec_id, strlen(codec_id)) == 0)

我不知道甚至在选择(或什至可用)编解码器之前就设置了大小。

// lookup size
Size2D mediasize(inputFile->streams[videoStreamIndex]->codec->width, inputFile->streams[videoStreamIndex]->codec->height);

按帧查找和解包(视频)是这样完成的:

AVStream* s = m_file->streams[videoStreamIndex];
int64_t seek_ts = (int64_t(frame_index) * s->r_frame_rate.den *  s->time_base.den) / (int64_t(s->r_frame_rate.num) * s->time_base.num);
av_seek_frame(m_hap_file, videoStreamIndex,  seek_ts, AVSEEK_FLAG_ANY);

AVPacket pkt;
av_read_frame(inputFile, &pkt);

现在数据包包含一个准备好用自己的解码器解包的帧。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

用libav混合流式分段mp4

来自分类Dev

FFmpeg / Libav音频解码示例

来自分类Dev

用 FFmpeg 替换视频中的音频部分

来自分类Dev

Set RTSP/UDP buffer size in FFmpeg/LibAV

来自分类Dev

使用FFMPEG LibAV重采样音频

来自分类Dev

如何使用ffmpeg用外部字幕替换集成字幕?

来自分类Dev

如何在CMake中检测ffmpeg vs libav?

来自分类Dev

在FFmpeg / LibAV中设置RTSP / UDP缓冲区大小

来自分类Dev

C ++ H264 ffmpeg / libav编码/解码(无损)问题

来自分类Dev

libav / ffmpeg输出优化,适用于小文件

来自分类Dev

添加avfilter后编译FFMPEG / libav代码时出错

来自分类Dev

保存原始YUV420P帧FFmpeg / Libav

来自分类Dev

libav / ffmpeg输出优化,适用于小文件

来自分类Dev

Linux用4个空格替换标签

来自分类Dev

用ffmpeg将视频的一部分替换为另一视频

来自分类Dev

如何在ffmpeg的extract_mvs.c上用“帧类型”替换“标志”

来自分类Dev

使用libav转换mp4-ts

来自分类Dev

使用libav转换mp4-ts

来自分类Dev

当安装了libav-tools但未运行ffmpeg时,如何运行ffmpeg?

来自分类Dev

转换mp3->具有静态图像的视频(ffmpeg / libav&BASH)

来自分类Dev

如何在Libav / ffmpeg中区分相同的摄像机?

来自分类Dev

FFMPEG / libav:UYVY422是如何在AVFrame结构中编写的?

来自分类Dev

为什么我选择Libav而不是FFmpeg,甚至还有区别?

来自分类Dev

是否可以在ubuntu 14.04上同时安装和运行libav和ffmpeg?

来自分类Dev

是否可以在ubuntu 14.04上同时安装和运行libav和ffmpeg?

来自分类Dev

用ffmpeg修剪的脚本

来自分类Dev

用ffmpeg寻找FLAC

来自分类Dev

用ffmpeg旋转图像

来自分类Dev

在Spring 4中用什么替换MethodInvokingTimerTaskFactoryBean?

Related 相关文章

热门标签

归档