用libav / ffmpeg替换Bento4

时间:2018-07-22 22:12:28

标签: ffmpeg libav

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

{{1}}

出于几个原因,我们宁愿用libav / ffmpeg替换Bento4(主要是因为我们已经在项目中并且想要减少依赖性)

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

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

1 个答案:

答案 0 :(得分:0)

事实证明非常简单:

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);

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