我们使用Bento4(一个设计精良的SDK)对.mov容器中的mp4文件进行解复用。解码由自己的编解码器完成,因此仅需要原始(帧内)样本。到目前为止,这很简单
{{1}}
出于几个原因,我们宁愿用libav / ffmpeg替换Bento4(主要是因为我们已经在项目中并且想要减少依赖性)
我们(最好用伪代码)如何用libav替换上面完成的Bento4任务?请记住,所使用的编解码器不在ffmpeg库中,因此我们无法使用标准ffmpeg解码示例。打开媒体文件完全失败。没有解码器,到目前为止,我们没有大小或任何其他信息。我们需要的是
答案 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);
现在,数据包中包含一个准备好用自己的解码器解包的帧。