MPEG 4p10/MPEG-H: re-factor NALU↔RBSP functions to common file

This commit is contained in:
Moritz Bunkus 2015-12-28 14:44:15 +01:00
parent 39c878f59b
commit b3876a9f74
6 changed files with 120 additions and 130 deletions

View File

@ -22,6 +22,7 @@
#include "common/endian.h"
#include "common/hacks.h"
#include "common/mm_io.h"
#include "common/mpeg.h"
#include "common/hevc.h"
#include "common/strings/formatting.h"
@ -102,10 +103,9 @@ hevcc_c::parse_vps_list(bool ignore_errors) {
return true;
m_vps_info_list.clear();
for (auto &vps: m_vps_list) {
for (auto const &vps: m_vps_list) {
vps_info_t vps_info;
auto vps_as_rbsp = vps->clone();
nalu_to_rbsp(vps_as_rbsp);
auto vps_as_rbsp = mpeg::nalu_to_rbsp(vps);
if (ignore_errors) {
try {
@ -127,10 +127,9 @@ hevcc_c::parse_sps_list(bool ignore_errors) {
return true;
m_sps_info_list.clear();
for (auto &sps: m_sps_list) {
for (auto const &sps: m_sps_list) {
sps_info_t sps_info;
auto sps_as_rbsp = sps->clone();
nalu_to_rbsp(sps_as_rbsp);
auto sps_as_rbsp = mpeg::nalu_to_rbsp(sps);
if (ignore_errors) {
try {
@ -152,10 +151,9 @@ hevcc_c::parse_pps_list(bool ignore_errors) {
return true;
m_pps_info_list.clear();
for (auto &pps: m_pps_list) {
for (auto const &pps: m_pps_list) {
pps_info_t pps_info;
auto pps_as_rbsp = pps->clone();
nalu_to_rbsp(pps_as_rbsp);
auto pps_as_rbsp = mpeg::nalu_to_rbsp(pps);
if (ignore_errors) {
try {
@ -217,9 +215,7 @@ hevcc_c::parse_sei_list() {
mcptr_newsei->set_size(w.get_bit_position() / 8);
rbsp_to_nalu(mcptr_newsei);
m_sei_list.push_back(mcptr_newsei);
m_sei_list.push_back(mpeg::rbsp_to_nalu(mcptr_newsei));
return true;
}
@ -941,51 +937,6 @@ slice_info_t::dump()
% pps);
}
void
nalu_to_rbsp(memory_cptr &buffer) {
int pos, size = buffer->get_size();
mm_mem_io_c d(nullptr, size, 100);
unsigned char *b = buffer->get_buffer();
for (pos = 0; pos < size; ++pos) {
if ( ((pos + 2) < size)
&& (0 == b[pos])
&& (0 == b[pos + 1])
&& (3 == b[pos + 2])) {
d.write_uint8(0);
d.write_uint8(0);
pos += 2;
} else
d.write_uint8(b[pos]);
}
buffer = memory_cptr(new memory_c(d.get_and_lock_buffer(), d.getFilePointer(), true));
}
void
rbsp_to_nalu(memory_cptr &buffer) {
int pos, size = buffer->get_size();
mm_mem_io_c d(nullptr, size, 100);
unsigned char *b = buffer->get_buffer();
for (pos = 0; pos < size; ++pos) {
if ( ((pos + 2) < size)
&& (0 == b[pos])
&& (0 == b[pos + 1])
&& (3 >= b[pos + 2])) {
d.write_uint8(0);
d.write_uint8(0);
d.write_uint8(3);
++pos;
} else
d.write_uint8(b[pos]);
}
buffer = memory_cptr(new memory_c(d.get_and_lock_buffer(), d.getFilePointer(), true));
}
bool
parse_vps(memory_cptr &buffer,
vps_info_t &vps) {
@ -1421,7 +1372,7 @@ extract_par(memory_cptr const &buffer) {
for (auto &nalu : hevcc.m_sps_list) {
if (!ar_found) {
nalu_to_rbsp(nalu);
nalu = mpeg::nalu_to_rbsp(nalu);
try {
sps_info_t sps_info;
@ -1438,7 +1389,7 @@ extract_par(memory_cptr const &buffer) {
} catch (mtx::mm_io::end_of_file_x &) {
}
rbsp_to_nalu(nalu);
nalu = mpeg::rbsp_to_nalu(nalu);
}
new_hevcc.m_sps_list.push_back(nalu);
@ -1748,10 +1699,10 @@ void
es_parser_c::handle_vps_nalu(memory_cptr &nalu) {
vps_info_t vps_info;
nalu_to_rbsp(nalu);
nalu = mpeg::nalu_to_rbsp(nalu);
if (!parse_vps(nalu, vps_info))
return;
rbsp_to_nalu(nalu);
nalu = mpeg::rbsp_to_nalu(nalu);
size_t i;
for (i = 0; m_vps_info_list.size() > i; ++i)
@ -1806,10 +1757,10 @@ void
es_parser_c::handle_sps_nalu(memory_cptr &nalu) {
sps_info_t sps_info;
nalu_to_rbsp(nalu);
nalu = mpeg::nalu_to_rbsp(nalu);
if (!parse_sps(nalu, sps_info, m_vps_info_list, m_keep_ar_info))
return;
rbsp_to_nalu(nalu);
nalu = mpeg::rbsp_to_nalu(nalu);
size_t i;
for (i = 0; m_sps_info_list.size() > i; ++i)
@ -1878,10 +1829,10 @@ void
es_parser_c::handle_pps_nalu(memory_cptr &nalu) {
pps_info_t pps_info;
nalu_to_rbsp(nalu);
nalu = mpeg::nalu_to_rbsp(nalu);
if (!parse_pps(nalu, pps_info))
return;
rbsp_to_nalu(nalu);
nalu = mpeg::rbsp_to_nalu(nalu);
size_t i;
for (i = 0; m_pps_info_list.size() > i; ++i)
@ -1906,10 +1857,10 @@ es_parser_c::handle_pps_nalu(memory_cptr &nalu) {
void
es_parser_c::handle_sei_nalu(memory_cptr &nalu) {
nalu_to_rbsp(nalu);
nalu = mpeg::nalu_to_rbsp(nalu);
if (!parse_sei(nalu, m_user_data))
return;
rbsp_to_nalu(nalu);
return;
nalu = mpeg::rbsp_to_nalu(nalu);
m_extra_data.push_back(create_nalu_with_size(nalu));
}

View File

@ -336,9 +336,6 @@ struct par_extraction_t {
bool is_valid() const;
};
void nalu_to_rbsp(memory_cptr &buffer);
void rbsp_to_nalu(memory_cptr &buffer);
bool parse_vps(memory_cptr &buffer, vps_info_t &vps);
bool parse_sps(memory_cptr &buffer, sps_info_t &sps, std::vector<vps_info_t> &m_vps_info_list, bool keep_ar_info = false);
bool parse_pps(memory_cptr &buffer, pps_info_t &pps);

64
src/common/mpeg.cpp Normal file
View File

@ -0,0 +1,64 @@
/** MPEG helper functions
mkvmerge -- utility for splicing together matroska files
from component media subtypes
Distributed under the GPL v2
see the file COPYING for details
or visit http://www.gnu.org/copyleft/gpl.html
\author Written by Moritz Bunkus <moritz@bunkus.org>.
*/
#include "common/common_pch.h"
#include "common/mpeg.h"
namespace mpeg {
memory_cptr
nalu_to_rbsp(memory_cptr const &buffer) {
int pos, size = buffer->get_size();
mm_mem_io_c d(nullptr, size, 100);
unsigned char *b = buffer->get_buffer();
for (pos = 0; pos < size; ++pos) {
if ( ((pos + 2) < size)
&& (0 == b[pos])
&& (0 == b[pos + 1])
&& (3 == b[pos + 2])) {
d.write_uint8(0);
d.write_uint8(0);
pos += 2;
} else
d.write_uint8(b[pos]);
}
return memory_c::clone(d.get_and_lock_buffer(), d.getFilePointer());
}
memory_cptr
rbsp_to_nalu(memory_cptr const &buffer) {
int pos, size = buffer->get_size();
mm_mem_io_c d(nullptr, size, 100);
unsigned char *b = buffer->get_buffer();
for (pos = 0; pos < size; ++pos) {
if ( ((pos + 2) < size)
&& (0 == b[pos])
&& (0 == b[pos + 1])
&& (3 >= b[pos + 2])) {
d.write_uint8(0);
d.write_uint8(0);
d.write_uint8(3);
++pos;
} else
d.write_uint8(b[pos]);
}
return memory_c::clone(d.get_and_lock_buffer(), d.getFilePointer());
}
}

25
src/common/mpeg.h Normal file
View File

@ -0,0 +1,25 @@
/** MPEG helper functions
mkvmerge -- utility for splicing together matroska files
from component media subtypes
Distributed under the GPL v2
see the file COPYING for details
or visit http://www.gnu.org/copyleft/gpl.html
\author Written by Moritz Bunkus <moritz@bunkus.org>.
*/
#ifndef MTX_COMMON_MPEG_COMMON_H
#define MTX_COMMON_MPEG_COMMON_H
#include "common/common_pch.h"
namespace mpeg {
memory_cptr nalu_to_rbsp(memory_cptr const &buffer);
memory_cptr rbsp_to_nalu(memory_cptr const &buffer);
}
#endif // MTX_COMMON_MPEG_COMMON_H

View File

@ -23,6 +23,7 @@
#include "common/endian.h"
#include "common/hacks.h"
#include "common/mm_io.h"
#include "common/mpeg.h"
#include "common/mpeg4_p10.h"
#include "common/strings/formatting.h"
@ -69,7 +70,7 @@ avcc_c::parse_sps_list(bool ignore_errors) {
m_sps_info_list.clear();
for (auto &sps: m_sps_list) {
sps_info_t sps_info;
auto sps_as_rbsp = nalu_to_rbsp(sps);
auto sps_as_rbsp = mpeg::nalu_to_rbsp(sps);
if (ignore_errors) {
try {
@ -93,7 +94,7 @@ avcc_c::parse_pps_list(bool ignore_errors) {
m_pps_info_list.clear();
for (auto &pps: m_pps_list) {
pps_info_t pps_info;
auto pps_as_rbsp = nalu_to_rbsp(pps);
auto pps_as_rbsp = mpeg::nalu_to_rbsp(pps);
if (ignore_errors) {
try {
@ -420,51 +421,6 @@ mpeg4::p10::slice_info_t::dump()
% pps);
}
memory_cptr
mpeg4::p10::nalu_to_rbsp(memory_cptr const &buffer) {
int pos, size = buffer->get_size();
mm_mem_io_c d(nullptr, size, 100);
unsigned char *b = buffer->get_buffer();
for (pos = 0; pos < size; ++pos) {
if ( ((pos + 2) < size)
&& (0 == b[pos])
&& (0 == b[pos + 1])
&& (3 == b[pos + 2])) {
d.write_uint8(0);
d.write_uint8(0);
pos += 2;
} else
d.write_uint8(b[pos]);
}
return memory_c::clone(d.get_and_lock_buffer(), d.getFilePointer());
}
memory_cptr
mpeg4::p10::rbsp_to_nalu(memory_cptr const &buffer) {
int pos, size = buffer->get_size();
mm_mem_io_c d(nullptr, size, 100);
unsigned char *b = buffer->get_buffer();
for (pos = 0; pos < size; ++pos) {
if ( ((pos + 2) < size)
&& (0 == b[pos])
&& (0 == b[pos + 1])
&& (3 >= b[pos + 2])) {
d.write_uint8(0);
d.write_uint8(0);
d.write_uint8(3);
++pos;
} else
d.write_uint8(b[pos]);
}
return memory_c::clone(d.get_and_lock_buffer(), d.getFilePointer());
}
memory_cptr
mpeg4::p10::parse_sps(memory_cptr const &buffer,
sps_info_t &sps,
@ -785,7 +741,7 @@ mpeg4::p10::extract_par(memory_cptr const &buffer) {
if (!ar_found) {
try {
sps_info_t sps_info;
auto nalu_as_rbsp = mpeg4::p10::parse_sps(nalu_to_rbsp(nalu), sps_info);
auto nalu_as_rbsp = mpeg4::p10::parse_sps(mpeg::nalu_to_rbsp(nalu), sps_info);
if (nalu_as_rbsp) {
if (s_debug_ar)
@ -797,7 +753,7 @@ mpeg4::p10::extract_par(memory_cptr const &buffer) {
par_den = sps_info.par_den;
}
nalu = rbsp_to_nalu(nalu_as_rbsp);
nalu = mpeg::rbsp_to_nalu(nalu_as_rbsp);
}
} catch (mtx::mm_io::end_of_file_x &) {
}
@ -842,10 +798,10 @@ mpeg4::p10::fix_sps_fps(memory_cptr const &buffer,
if ((0 < length) && ((nalu->get_buffer()[0] & 0x1f) == NALU_TYPE_SEQ_PARAM)) {
sps_info_t sps_info;
auto parsed_nalu = parse_sps(nalu_to_rbsp(nalu), sps_info, true, true, duration);
auto parsed_nalu = parse_sps(mpeg::nalu_to_rbsp(nalu), sps_info, true, true, duration);
if (parsed_nalu)
nalu = rbsp_to_nalu(parsed_nalu);
nalu = mpeg::rbsp_to_nalu(parsed_nalu);
}
new_avcc.write_uint16_be(nalu->get_size());
@ -1183,7 +1139,7 @@ mpeg4::p10::avc_es_parser_c::handle_slice_nalu(memory_cptr const &nalu) {
}
slice_info_t si;
if (!parse_slice(nalu_to_rbsp(nalu), si))
if (!parse_slice(mpeg::nalu_to_rbsp(nalu), si))
return;
if (m_have_incomplete_frame && flush_decision(si, m_incomplete_frame.m_si))
@ -1241,11 +1197,11 @@ void
mpeg4::p10::avc_es_parser_c::handle_sps_nalu(memory_cptr const &nalu) {
sps_info_t sps_info;
auto parsed_nalu = parse_sps(nalu_to_rbsp(nalu), sps_info, m_keep_ar_info, m_fix_bitstream_frame_rate, duration_for(0, true));
auto parsed_nalu = parse_sps(mpeg::nalu_to_rbsp(nalu), sps_info, m_keep_ar_info, m_fix_bitstream_frame_rate, duration_for(0, true));
if (!parsed_nalu)
return;
parsed_nalu = rbsp_to_nalu(parsed_nalu);
parsed_nalu = mpeg::rbsp_to_nalu(parsed_nalu);
size_t i;
for (i = 0; m_sps_info_list.size() > i; ++i)
@ -1294,7 +1250,7 @@ void
mpeg4::p10::avc_es_parser_c::handle_pps_nalu(memory_cptr const &nalu) {
pps_info_t pps_info;
if (!parse_pps(nalu_to_rbsp(nalu), pps_info))
if (!parse_pps(mpeg::nalu_to_rbsp(nalu), pps_info))
return;
size_t i;
@ -1321,7 +1277,7 @@ mpeg4::p10::avc_es_parser_c::handle_pps_nalu(memory_cptr const &nalu) {
void
mpeg4::p10::avc_es_parser_c::handle_sei_nalu(memory_cptr const &nalu) {
try {
auto nalu_as_rbsp = nalu_to_rbsp(nalu);
auto nalu_as_rbsp = mpeg::nalu_to_rbsp(nalu);
bit_reader_c r(nalu_as_rbsp->get_buffer(), nalu_as_rbsp->get_size());

View File

@ -144,9 +144,6 @@ struct par_extraction_t {
bool is_valid() const;
};
memory_cptr nalu_to_rbsp(memory_cptr const &buffer);
memory_cptr rbsp_to_nalu(memory_cptr const &buffer);
memory_cptr parse_sps(memory_cptr const &buffer, sps_info_t &sps, bool keep_ar_info = false, bool fix_bitstream_frame_rate = false, int64_t duration = -1);
bool parse_pps(memory_cptr const &buffer, pps_info_t &pps);