mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-25 04:11:44 +00:00
extract: add support for extracting AV1 to IVF
Part of the implementation of #2261.
This commit is contained in:
parent
dca6f040a9
commit
3571f4ab4c
@ -184,7 +184,7 @@ xtr_base_c::create_extractor(const std::string &new_codec_id,
|
||||
result.reset(new xtr_mpeg1_2_video_c(new_codec_id, new_tid, tspec));
|
||||
else if (new_codec_id == MKV_V_THEORA)
|
||||
result.reset(new xtr_oggtheora_c(new_codec_id, new_tid, tspec));
|
||||
else if ((new_codec_id == MKV_V_VP8) || (new_codec_id == MKV_V_VP9))
|
||||
else if ((new_codec_id == MKV_V_VP8) || (new_codec_id == MKV_V_VP9) || (new_codec_id == MKV_V_AV1))
|
||||
result.reset(new xtr_ivf_c(new_codec_id, new_tid, tspec));
|
||||
|
||||
// Subtitle formats
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "common/common_pch.h"
|
||||
|
||||
#include "common/av1.h"
|
||||
#include "common/codec.h"
|
||||
#include "common/ebml.h"
|
||||
#include "common/endian.h"
|
||||
@ -21,9 +22,7 @@ xtr_ivf_c::xtr_ivf_c(const std::string &codec_id,
|
||||
int64_t tid,
|
||||
track_spec_t &tspec)
|
||||
: xtr_base_c(codec_id, tid, tspec)
|
||||
, m_frame_rate_num(0)
|
||||
, m_frame_rate_den(0)
|
||||
, m_frame_count(0)
|
||||
, m_is_av1{codec_id == MKV_V_AV1}
|
||||
{
|
||||
}
|
||||
|
||||
@ -52,7 +51,9 @@ xtr_ivf_c::create_file(xtr_base_c *master,
|
||||
"track %4% with the CodecID '%5%' is already being written to the same file.\n"))
|
||||
% m_tid % m_codec_id % m_file_name % master->m_tid % master->m_codec_id);
|
||||
|
||||
auto fourcc = m_codec_id == MKV_V_VP8 ? "VP80" : "VP90";
|
||||
auto fourcc = m_is_av1 ? "AV01"
|
||||
: m_codec_id == MKV_V_VP8 ? "VP80"
|
||||
: "VP90";
|
||||
|
||||
memcpy(m_file_header.file_magic, "DKIF", 4);
|
||||
memcpy(m_file_header.fourcc, fourcc, 4);
|
||||
@ -74,6 +75,8 @@ xtr_ivf_c::handle_frame(xtr_frame_t &f) {
|
||||
% f.timestamp % m_frame_rate_num % m_frame_rate_den % frame_number
|
||||
% (frame_number * 1000000000ull * m_frame_rate_den / m_frame_rate_num));
|
||||
|
||||
av1_prepend_temporal_delimiter_obu_if_needed(*f.frame);
|
||||
|
||||
ivf::frame_header_t frame_header;
|
||||
put_uint32_le(&frame_header.frame_size, f.frame->get_size());
|
||||
put_uint32_le(&frame_header.timestamp, frame_number);
|
||||
@ -91,3 +94,24 @@ xtr_ivf_c::finish_file() {
|
||||
m_out->setFilePointer(0);
|
||||
m_out->write(&m_file_header, sizeof(m_file_header));
|
||||
}
|
||||
|
||||
void
|
||||
xtr_ivf_c::av1_prepend_temporal_delimiter_obu_if_needed(memory_c &frame) {
|
||||
if (!m_is_av1 || !frame.get_size())
|
||||
return;
|
||||
|
||||
auto type = (frame.get_buffer()[0] & 0x74) >> 3;
|
||||
|
||||
if (type == mtx::av1::OBU_TEMPORAL_DELIMITER)
|
||||
return;
|
||||
|
||||
auto old_size = frame.get_size();
|
||||
|
||||
frame.resize(old_size + 2);
|
||||
|
||||
auto buffer = frame.get_buffer();
|
||||
|
||||
std::memmove(&buffer[2], &buffer[0], old_size);
|
||||
buffer[0] = 0x12; // type = OBU_TEMPORAL_DELIMITER, extension not present, OBU size field present
|
||||
buffer[1] = 0x00; // OBU size
|
||||
}
|
||||
|
@ -19,9 +19,10 @@
|
||||
|
||||
class xtr_ivf_c: public xtr_base_c {
|
||||
public:
|
||||
uint64_t m_frame_rate_num, m_frame_rate_den;
|
||||
uint32_t m_frame_count;
|
||||
uint64_t m_frame_rate_num{}, m_frame_rate_den{};
|
||||
uint32_t m_frame_count{};
|
||||
ivf::file_header_t m_file_header;
|
||||
bool m_is_av1{};
|
||||
|
||||
public:
|
||||
xtr_ivf_c(const std::string &codec_id, int64_t tid, track_spec_t &tspec);
|
||||
@ -33,4 +34,7 @@ public:
|
||||
virtual const char *get_container_name() {
|
||||
return "IVF";
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual void av1_prepend_temporal_delimiter_obu_if_needed(memory_c &frame);
|
||||
};
|
||||
|
@ -503,3 +503,4 @@ T_654text_subtitles_without_duration:ada9aaa1ae07ff6b20fb0618304d0820:passed:201
|
||||
T_655mpeg_ts_teletext_subs_long_gap_until_end_of_display:6027ec285e5c03ec7fa84afea1d57f56:passed:20181005-212927:0.513727609
|
||||
T_656mpeg_ts_bad_utf8_in_service_names2:544606778297772ea61146bdbd8f1186:passed:20181006-122753:0.020246407
|
||||
T_657av1_from_mp4:08895840fd959294a31f7cbba8b2d9dd:passed:20181007-220646:0.040201275
|
||||
T_658X_av1:9d2beba51aa2d3d61ddb2b82f2c94937+076ba34e5ca17057f32ad54ef12ef42c:passed:20181007-225807:0.019174721
|
||||
|
11
tests/test-658X_av1.rb
Executable file
11
tests/test-658X_av1.rb
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/ruby -w
|
||||
|
||||
# T_658X_av1
|
||||
describe "mkvextract / AV1 to IVF"
|
||||
|
||||
test "extraction to IVF" do
|
||||
extract "data/av1/av1.webm", 0 => "#{tmp}-1"
|
||||
merge "#{tmp}-1", :output => "#{tmp}-2"
|
||||
|
||||
(1..2).map { |idx| hash_file("#{tmp}-#{idx}") }.join('+')
|
||||
end
|
Loading…
Reference in New Issue
Block a user