17#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
18#include <QtSystemDetection>
32#include "libavutil/cpu.h"
33#include "libmythmpeg2/attributes.h"
34#include "libmythmpeg2/mpeg2.h"
35#include "libmythmpeg2/mpeg2_internal.h"
44#include <netinet/in.h>
52 int level,
const char* fmt, va_list vl)
54 static QString s_fullLine(
"");
56 if (level > AV_LOG_INFO)
59 s_fullLine += QString::vasprintf(fmt, vl);
60 if (s_fullLine.endsWith(
"\n"))
63 LOG(VB_GENERAL, LOG_INFO, s_fullLine);
64 s_fullLine = QString(
"");
76 return QString(
"%1%2:%3:%4.%5")
77 .arg(is_neg ?
"-" :
"")
78 .arg((
uint)(
pts / 90000.) / 3600, 2, 10, QChar(
'0'))
79 .arg(((
uint)(
pts / 90000.) % 3600) / 60, 2, 10, QChar(
'0'))
80 .arg(((
uint)(
pts / 90000.) % 3600) % 60, 2, 10, QChar(
'0'))
81 .arg(((((
uint)(
pts / 90.) % 3600000) % 60000) % 1000), 3, 10, QChar(
'0'));
85 m_pkt(av_packet_alloc()),
86 m_mpeg2_seq(), m_mpeg2_gop(), m_mpeg2_pic()
88 av_new_packet(
m_pkt, size);
93 av_packet_free(&
m_pkt);
98 if (
m_pkt->size < size)
100 int oldSize =
m_pkt->size;
101 if ((av_grow_packet(
m_pkt, size -
m_pkt->size) < 0) ||
m_pkt->size < size)
103 LOG(VB_GENERAL, LOG_CRIT, QString(
"MPEG2frame::ensure_size(): "
104 "Failed to grow packet size "
105 "from %1 to %2, result was %3")
106 .arg(oldSize).arg(size)
115 av_packet_unref(
m_pkt);
116 av_packet_ref(
m_pkt, newpkt);
120 : m_keyList(std::move(keys)),
126 idx.newPTS = initPTS;
131 for (
const int key : std::as_const(
m_keyList))
137 QList<poq_idx_t>::iterator it;
138 int64_t value =
m_offset[idx].first().newPTS;
146 while (
m_offset[idx].count() > 1 && !done)
149 if (((
static_cast<int>((*it).type) == 0) &&
150 (pkt->pts >= (*it).pos_pts) ) ||
152 ((pkt->pos >= (*it).pos_pts) || (pkt->duration > (*it).framenum))))
155 value =
m_offset[idx].first().newPTS;
174 for (
const int key : std::as_const(
m_keyList))
184 idx.framenum = pkt->duration;
187 LOG(VB_FRAME, LOG_INFO, QString(
"Offset %1 -> %2 (%3) at %4")
190 PtsTime(delta), QString::number(pkt->pos)));
191 for (
const int key : std::as_const(
m_keyList))
196 m_orig[key].push_back(idx);
203 QList<poq_idx_t> *dltaList = &
m_orig[idx];
204 while (!dltaList->isEmpty() &&
205 (pkt->pos >= dltaList->first().pos_pts ||
206 pkt->duration > dltaList->first().framenum))
208 if (dltaList->first().newPTS >= 0)
209 ptsinc((uint64_t *)&origPTS, 300 * dltaList->first().newPTS);
211 ptsdec((uint64_t *)&origPTS, -300 * dltaList->first().newPTS);
212 delta += dltaList->first().newPTS;
213 dltaList->pop_front();
214 LOG(VB_PROCESS, LOG_INFO,
215 QString(
"Moving PTS offset of stream %1 by %2")
216 .arg(idx).arg(
PtsTime(delta)));
223 const char *fmt,
bool norp,
bool fixPTS,
int maxf,
224 bool showprog,
int otype,
void (*update_func)(
float),
226 : m_noRepeat(norp), m_fixPts(fixPTS), m_maxFrames(maxf),
227 m_infile(inf), m_format(fmt)
232 if (deleteMap && !deleteMap->isEmpty())
235 frm_dir_map_t::iterator it = deleteMap->begin();
236 for (; it != deleteMap->end(); ++it)
238 uint64_t mark = it.key();
291 const QFileInfo finfo(inf);
317 for (
auto *af : std::as_const(
m_aFrame))
319 while (!af->isEmpty())
333 {
return (ptr[0] == 0x00) && (ptr[1] == 0x00) && (ptr[2] == 0x01); };
335static void SETBITS(
unsigned char *ptr,
long value,
int num)
337 static int s_sbPos = 0;
338 static unsigned char *s_sbPtr =
nullptr;
346 if (s_sbPtr ==
nullptr)
349 int offset = s_sbPos >> 3;
350 int offset_r = s_sbPos & 0x07;
351 int offset_b = 32 - offset_r;
352 uint32_t mask = ~(((1 << num) - 1) << (offset_b - num));
353 uint32_t sb_long = ntohl(*((uint32_t *) (s_sbPtr + offset)));
354 value = value << (offset_b - num);
355 sb_long = (sb_long & mask) + value;
356 *((uint32_t *)(s_sbPtr + offset)) = htonl(sb_long);
366 *pts1 = (*pts1 + pts2) %
MAX_PTS;
371 int64_t diff = pts1 - pts2;
390 return (pts1 - pts2);
394 return (pts1 +
MAX_PTS - pts2);
398 return (pts1 - (pts2 +
MAX_PTS));
407 int64_t tmp = pts1 + pts2;
409 return (pts1 + pts2) %
MAX_PTS;
419 if ((uint64_t)(pts1 - pts2) >
MAX_PTS/2ULL)
424 else if (pts1 == pts2)
430 if ((uint64_t)(pts2 - pts1) >
MAX_PTS/2ULL)
440 for (
int i = 0; i < size; i++)
460 return (rx->WaitBuffers());
481 pthread_mutex_lock( &
m_mutex );
496 pthread_cond_signal(&
m_cond);
499 pthread_mutex_unlock(&
m_mutex);
505 static int errorcount = 0;
508 LOG(VB_GENERAL, LOG_ERR,
509 QString(
"thread finished with %1 write errors")
512 pthread_exit(&errorcount);
547 mx.
priv = (
void *)
this;
549 int fd_out = open(
m_outfile.toLocal8Bit().constData(),
554 pthread_cond_signal(&
m_cond);
556 pthread_mutex_unlock(&
m_mutex);
579#define INDEX_BUF (sizeof(index_unit) * 200)
586 if (
m_vFrame.first()->m_mpeg2_seq.height >= 720)
588 LOG(VB_GENERAL, LOG_NOTICE,
"MPEG2fixup::InitReplex(): High Definition input, increasing replex buffers");
599 LOG(VB_GENERAL, LOG_WARNING,
"MPEG2fixup::InitReplex(): Using '--ostream=dvd' with HD video is an invalid combination");
604 uint32_t memsize =
m_vFrame.first()->m_mpeg2_seq.width *
605 m_vFrame.first()->m_mpeg2_seq.height * 10;
617 uint index = it.key();
621 if (avctx ==
nullptr)
624 AVDictionaryEntry *metatag =
625 av_dict_get(
m_inputFC->streams[index]->metadata,
626 "language",
nullptr, 0);
627 char *lang = metatag ? metatag->value : (
char *)
"";
636 case AV_CODEC_ID_MP2:
637 case AV_CODEC_ID_MP3:
641 case AV_CODEC_ID_AC3:
651 26999999ULL) /
m_vFrame.first()->m_mpeg2_seq.frame_period;
658 QString msg = QString(
"Id:%1 %2 V:%3").arg(f->
m_pkt->stream_index)
666 msg += QString(
" %2")
669 LOG(VB_RPLXQUEUE, LOG_INFO, msg);
677 int id = f->
m_pkt->stream_index;
688 iu.gop =
static_cast<uint8_t
>(f->
m_isGop);
692 iu.dts = f->
m_pkt->dts * 300;
700 iu.framesize = f->
m_pkt->size;
705 LOG(VB_GENERAL, LOG_ERR,
"Ringbuffer pointers empty. No stream found");
710 iu.length = f->
m_pkt->size;
711 iu.pts = f->
m_pkt->pts * 300;
735 unsigned int inc_size = 10 * (
unsigned int)f->
m_pkt->size;
736 LOG(VB_GENERAL, LOG_NOTICE,
737 QString(
"Increasing ringbuffer size by %1 to avoid deadlock")
747 LOG(VB_GENERAL, LOG_ERR,
748 "Deadlock detected. One buffer is full when "
749 "the other is empty! Aborting");
762 LOG(VB_GENERAL, LOG_ERR,
763 QString(
"Ring buffer overflow %1").arg(rb->
size));
770 LOG(VB_GENERAL, LOG_ERR,
771 QString(
"Ring buffer overflow %1").arg(rbi->
size));
781 QByteArray ifarray = inputfile.toLocal8Bit();
782 const char *ifname = ifarray.constData();
784 const AVInputFormat *fmt =
nullptr;
787 fmt = av_find_input_format(
type);
790 LOG(VB_GENERAL, LOG_INFO, QString(
"Opening %1").arg(inputfile));
798 int ret = avformat_open_input(&
m_inputFC, ifname, fmt,
nullptr);
801 LOG(VB_GENERAL, LOG_ERR,
802 QString(
"Couldn't open input file, error #%1").arg(ret));
812 ret = avformat_find_stream_info(
m_inputFC,
nullptr);
815 LOG(VB_GENERAL, LOG_ERR,
816 QString(
"Couldn't get stream info, error #%1").arg(ret));
826 for (
unsigned int i = 0; i <
m_inputFC->nb_streams; i++)
828 switch (
m_inputFC->streams[i]->codecpar->codec_type)
830 case AVMEDIA_TYPE_VIDEO:
835 case AVMEDIA_TYPE_AUDIO:
837 m_inputFC->streams[i]->codecpar->ch_layout.nb_channels < 2 &&
838 m_inputFC->streams[i]->codecpar->sample_rate < 100000)
840 LOG(VB_GENERAL, LOG_ERR,
841 QString(
"Skipping audio stream: %1").arg(i));
844 if (
m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_AC3 ||
845 m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_MP3 ||
846 m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_MP2)
853 LOG(VB_GENERAL, LOG_ERR,
854 QString(
"Skipping unsupported audio stream: %1")
855 .arg(
m_inputFC->streams[i]->codecpar->codec_id));
859 LOG(VB_GENERAL, LOG_ERR,
860 QString(
"Skipping unsupported codec %1 on stream %2")
861 .arg(
m_inputFC->streams[i]->codecpar->codec_type).arg(i));
881 int oldPktSize = frame1->
m_pkt->size;
883 memmove(frame1->
m_pkt->data + head_size, frame1->
m_pkt->data, oldPktSize);
884 memcpy(frame1->
m_pkt->data, frame2->
m_pkt->data, head_size);
889 static int count = 0;
890 QString
filename = QString(
"hdr%1.yuv").arg(count++);
908 auto *
info = (mpeg2_info_t *)mpeg2_info(dec);
912 while (state != STATE_PICTURE)
914 state = mpeg2_parse(dec);
922 case STATE_SEQUENCE_MODIFIED:
923 case STATE_SEQUENCE_REPEATED:
925 sizeof(mpeg2_sequence_t));
938 sizeof(mpeg2_picture_t));
943 LOG(VB_GENERAL, LOG_WARNING,
944 "Warning: partial frame found!");
948 else if (state == STATE_BUFFER)
951 LOG(VB_GENERAL, LOG_ERR,
952 QString(
"Failed to decode frame. Position was: %1")
956 last_pos = (vf->
m_pkt->size - mpeg2_getpos(dec)) - 4;
961 while (state != STATE_BUFFER)
962 state = mpeg2_parse(dec);
963 if (
info->display_picture)
970 std::array<uint8_t,8> tmp {0x00, 0x00, 0x01, 0xb2, 0xff, 0xff, 0xff, 0xff};
971 mpeg2_buffer(dec, tmp.data(), tmp.data() + 8);
978 QString msg = QString(
"");
980 msg += QString(
"unused:%1 ") .arg(vf->
m_pkt->size - mpeg2_getpos(dec));
984 msg += QString(
"%1x%2 P:%3 ").arg(
info->sequence->width)
985 .arg(
info->sequence->height).arg(
info->sequence->frame_period);
989 QString gop = QString(
"%1:%2:%3:%4 ")
990 .arg(
info->gop->hours, 2, 10, QChar(
'0')).arg(
info->gop->minutes, 2, 10, QChar(
'0'))
991 .arg(
info->gop->seconds, 2, 10, QChar(
'0')).arg(
info->gop->pictures, 3, 10, QChar(
'0'));
994 if (
info->current_picture)
996 int ct =
info->current_picture->flags & PIC_MASK_CODING_TYPE;
997 char coding_type {
'X' };
998 if (ct == PIC_FLAG_CODING_TYPE_I)
1000 else if (ct == PIC_FLAG_CODING_TYPE_P)
1002 else if (ct == PIC_FLAG_CODING_TYPE_B)
1004 else if (ct == PIC_FLAG_CODING_TYPE_D)
1006 char top_bottom = (
info->current_picture->flags &
1007 PIC_FLAG_TOP_FIELD_FIRST) ?
'T' :
'B';
1008 char progressive = (
info->current_picture->flags &
1009 PIC_FLAG_PROGRESSIVE_FRAME) ?
'P' :
'_';
1010 msg += QString(
"#%1 fl:%2%3%4%5%6 ")
1011 .arg(
info->current_picture->temporal_reference)
1012 .arg(
info->current_picture->nb_fields)
1016 .arg(
info->current_picture->flags >> 4, 0, 16);
1018 msg += QString(
"pos: %1").arg(vf->
m_pkt->pos);
1019 LOG(VB_DECODE, LOG_INFO, msg);
1028 if (tmpFrame ==
nullptr)
1032 for (
const auto & vf : std::as_const(
m_vFrame))
1034 if (vf->m_isSequence)
1048 if (tmpFrame ==
nullptr)
1054 mpeg2dec_t *tmp_decoder = mpeg2_init();
1055 auto *
info = (mpeg2_info_t *)mpeg2_info(tmp_decoder);
1057 while (!
info->display_picture)
1068 mpeg2_close(tmp_decoder);
1073 int fh = open(
filename.toLocal8Bit().constData(),
1074 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1077 LOG(VB_GENERAL, LOG_ERR,
1078 QString(
"Couldn't open file %1: ").arg(
filename) +
ENO);
1083 auto close_fh = [](
const int *fh2) {
close(*fh2); };
1084 std::unique_ptr<int,
decltype(close_fh)>
cleanup { &fh, close_fh };
1086 ssize_t ret =
write(fh,
info->display_fbuf->buf[0],
1087 static_cast<size_t>(
info->sequence->width) *
1088 static_cast<size_t>(
info->sequence->height));
1091 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1095 ret =
write(fh,
info->display_fbuf->buf[1],
1096 static_cast<size_t>(
info->sequence->chroma_width) *
1097 static_cast<size_t>(
info->sequence->chroma_height));
1100 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1104 ret =
write(fh,
info->display_fbuf->buf[2],
1105 static_cast<size_t>(
info->sequence->chroma_width) *
1106 static_cast<size_t>(
info->sequence->chroma_height));
1109 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1117 int fh = open(
filename.toLocal8Bit().constData(),
1118 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1121 LOG(VB_GENERAL, LOG_ERR,
1122 QString(
"Couldn't open file %1: ").arg(
filename) +
ENO);
1126 int ret =
write(fh, data, size);
1128 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1").arg(
filename) +
1135 alignas(16) std::array<uint16_t,64> intra_matrix {};
1136 int64_t savedPts = pkt->pts;
1139 if (!
info->display_fbuf)
1142 int outbuf_size =
info->sequence->width *
info->sequence->height * 2;
1144 if (!fname.isEmpty())
1146 QString tmpstr = fname +
".yuv";
1164 if (pkt->size < outbuf_size)
1165 av_grow_packet(pkt, (outbuf_size - pkt->size));
1178 static constexpr std::array<uint8_t, 64> k_zigzag_scan = {
1179 0, 1, 8, 16, 9, 2, 3, 10,
1180 17, 24, 32, 25, 18, 11, 4, 5,
1181 12, 19, 26, 33, 40, 48, 41, 34,
1182 27, 20, 13, 6, 7, 14, 21, 28,
1183 35, 42, 49, 56, 57, 50, 43, 36,
1184 29, 22, 15, 23, 30, 37, 44, 51,
1185 58, 59, 52, 45, 38, 31, 39, 46,
1186 53, 60, 61, 54, 47, 55, 62, 63
1189 static std::array<uint16_t, 64> k_invZigzagDirect16 = {};
1190 for (
int i = 0; i < 64; i++)
1192 k_invZigzagDirect16[k_zigzag_scan[i]] = i;
1195 static constexpr std::array<uint16_t, 64> k_invZigzagDirect16 = {
1196 0, 1, 5, 6, 14, 15, 27, 28,
1197 2, 4, 7, 13, 16, 26, 29, 42,
1198 3, 8, 12, 17, 25, 30, 41, 43,
1199 9, 11, 18, 24, 31, 40, 44, 53,
1200 10, 19, 23, 32, 39, 45, 52, 54,
1201 20, 22, 33, 38, 46, 51, 55, 60,
1202 21, 34, 37, 47, 50, 56, 59, 61,
1203 35, 36, 48, 49, 57, 58, 62, 63,
1207 for (
int i = 0; i < 64; i++)
1209 intra_matrix[k_invZigzagDirect16[i]] =
m_imgDecoder->quantizer_matrix[0][i];
1212 if (
info->display_picture->nb_fields % 2)
1214 if ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0)
1216 m_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
1220 m_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
1225 if ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0)
1227 m_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
1231 m_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
1235 if ((
info->display_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME) != 0)
1237 m_picture->flags &= ~AV_FRAME_FLAG_INTERLACED;
1241 m_picture->flags |= AV_FRAME_FLAG_INTERLACED;
1244 const AVCodec *out_codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO);
1247 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find MPEG2 encoder");
1251 AVCodecContext *c = avcodec_alloc_context3(
nullptr);
1257 if ((
m_picture->flags & AV_FRAME_FLAG_INTERLACED) != 0)
1258 c->flags |= AV_CODEC_FLAG_INTERLACED_DCT;
1260 c->bit_rate =
info->sequence->byte_rate << 3;
1261 c->bit_rate_tolerance = c->bit_rate >> 2;
1262 c->width =
info->sequence->width;
1263 c->height =
info->sequence->height;
1264 av_reduce(&c->time_base.num, &c->time_base.den,
1265 info->sequence->frame_period, 27000000LL, 100000);
1266 c->pix_fmt = AV_PIX_FMT_YUV420P;
1267 c->max_b_frames = 0;
1268 c->has_b_frames = 0;
1274 c->rc_buffer_size = 0;
1278 if (intra_matrix[0] == 0x08)
1279 c->intra_matrix = intra_matrix.data();
1281 c->qmin = c->qmax = 2;
1288 m_picture->pict_type = AV_PICTURE_TYPE_NONE;
1291 if (avcodec_open2(c, out_codec,
nullptr) < 0)
1293 LOG(VB_GENERAL, LOG_ERR,
"could not open codec");
1298 int ret = avcodec_send_frame(c,
m_picture);
1300 bool flushed =
false;
1304 ret = avcodec_receive_packet(c, pkt);
1307 if (ret == AVERROR(EAGAIN))
1314 ret = avcodec_send_frame(c,
nullptr);
1318 if (ret < 0 || !got_packet)
1320 LOG(VB_GENERAL, LOG_ERR,
1321 QString(
"avcodec_encode_video2 failed (%1)").arg(ret));
1325 if (!fname.isEmpty())
1327 QString ename = fname +
".enc";
1330 QString yname = fname +
".enc.yuv";
1337 int newSize = pkt->size - delta;
1338 pkt->pts = savedPts;
1339 memmove(pkt->data, pkt->data + delta, newSize);
1340 av_shrink_packet(pkt, newSize);
1343 SetRepeat(pkt->data, pkt->size,
info->display_picture->nb_fields,
1344 ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0U));
1346 avcodec_free_context(&c);
1358 static int s_frameCount = 0;
1361 LOG(VB_GENERAL, LOG_ERR,
"No more queue slots!");
1406 pkt->pts = AV_NOPTS_VALUE;
1407 pkt->dts = AV_NOPTS_VALUE;
1408 int ret = av_read_frame(
m_inputFC, pkt);
1419 LOG(VB_GENERAL, LOG_ERR,
1420 "Found end of file without finding any frames");
1421 av_packet_unref(pkt);
1426 if (tmpFrame ==
nullptr)
1428 av_packet_unref(pkt);
1438 if (pkt->stream_index ==
m_vidId ||
1439 m_aFrame.contains(pkt->stream_index))
1442 av_packet_unref(pkt);
1448 float percent_done = 100.0F * pkt->pos /
m_fileSize;
1452 LOG(VB_GENERAL, LOG_INFO, QString(
"%1% complete")
1453 .arg(percent_done, 0,
'f', 1));
1461 LOG(VB_DECODE, LOG_INFO, QString(
"Stream: %1 PTS: %2 DTS: %3 pos: %4")
1462 .arg(pkt->stream_index)
1463 .arg((pkt->pts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->pts))
1464 .arg((pkt->dts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->dts))
1469 if (tmpFrame ==
nullptr)
1471 av_packet_unref(pkt);
1475 switch (
m_inputFC->streams[pkt->stream_index]->codecpar->codec_type)
1477 case AVMEDIA_TYPE_VIDEO:
1479 av_packet_unref(pkt);
1486 case AVMEDIA_TYPE_AUDIO:
1487 if (
m_aFrame.contains(pkt->stream_index))
1489 m_aFrame[pkt->stream_index]->append(tmpFrame);
1493 LOG(VB_GENERAL, LOG_DEBUG,
1494 QString(
"Invalid stream ID %1, ignoring").arg(pkt->stream_index));
1497 av_packet_unref(pkt);
1502 av_packet_unref(pkt);
1510 QMap <int, bool> found;
1511 AVPacket *pkt = av_packet_alloc();
1514 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1518 while (found.count() !=
m_aFrame.count())
1522 av_packet_free(&pkt);
1526 if (
m_vidId == pkt->stream_index)
1530 if (
m_vFrame.first()->m_isSequence)
1532 if (pkt->pos !=
m_vFrame.first()->m_pkt->pos)
1535 if (pkt->pts != AV_NOPTS_VALUE ||
1536 pkt->dts != AV_NOPTS_VALUE)
1538 if (pkt->pts == AV_NOPTS_VALUE)
1539 m_vFrame.first()->m_pkt->pts = pkt->dts;
1541 LOG(VB_PROCESS, LOG_INFO,
1542 "Found 1st valid video frame");
1547 LOG(VB_PROCESS, LOG_INFO,
"Dropping V packet");
1558 if (found.contains(it.key()))
1563 while (!af->isEmpty())
1565 int64_t delta =
diff2x33(af->first()->m_pkt->pts,
1567 if (delta < -180000 || delta > 180000)
1572 for (
auto *currFrame : std::as_const(
m_vFrame))
1574 if (currFrame->m_isSequence)
1576 int64_t dlta1 =
diff2x33(af->first()->m_pkt->pts,
1577 currFrame->m_pkt->pts);
1578 if (dlta1 >= -180000 && dlta1 <= 180000)
1580 foundframe = currFrame;
1587 while (foundframe &&
m_vFrame.first() != foundframe)
1593 if (delta < -180000 || delta > 180000)
1595 LOG(VB_PROCESS, LOG_INFO,
1596 QString(
"Dropping A packet from stream %1")
1598 LOG(VB_PROCESS, LOG_INFO, QString(
" A:%1 V:%2")
1599 .arg(
PtsTime(af->first()->m_pkt->pts),
1605 if (delta < 0 && af->count() > 1)
1607 if (
cmp2x33(af->at(1)->m_pkt->pts,
1610 LOG(VB_PROCESS, LOG_INFO,
1611 QString(
"Found useful audio frame from stream %1")
1613 found[it.key()] =
true;
1616 LOG(VB_PROCESS, LOG_INFO,
1617 QString(
"Dropping A packet from stream %1")
1624 LOG(VB_PROCESS, LOG_INFO,
1625 QString(
"Found useful audio frame from stream %1")
1627 found[it.key()] =
true;
1631 if (af->count() == 1)
1637 av_packet_free(&pkt);
1650 uint8_t *end = ptr + size;
1651 uint8_t setmask = 0x00;
1652 uint8_t clrmask = 0xff;
1665 if (
MATCH_HEADER(ptr) && ptr[3] == 0xB5 && (ptr[4] & 0xF0) == 0x80)
1680 for (
const auto & vf : std::as_const(
m_vFrame))
1693 for (
int pos = start_pos; pos < maxPos; pos++)
1734 bool skip_first =
false;
1749 int framePos =
m_vFrame.indexOf(spare);
1757 if (!skip_first && curPos >= framePos &&
info->display_picture &&
1758 (
int)
info->display_picture->temporal_reference >= frameNum)
1770 int tmpFrameNum = frameNum;
1772 if (tmpFrame ==
nullptr)
1778 while (!
info->display_picture ||
1779 (
int)
info->display_picture->temporal_reference < frameNum)
1792 if ((
int)
info->display_picture->temporal_reference > frameNum)
1798 LOG(VB_GENERAL, LOG_NOTICE,
1799 QString(
"Frame %1 > %2. Corruption likely at pos: %3")
1800 .arg(
info->display_picture->temporal_reference)
1801 .arg(frameNum).arg(spare->
m_pkt->pos));
1810 AVPacket *pkt = av_packet_alloc();
1813 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1817 static int ins_count = 0;
1825 av_packet_free(&pkt);
1830 for (
const auto & of : std::as_const(*orderedFrames))
1834 if (spare ==
nullptr)
1836 LOG(VB_GENERAL, LOG_WARNING,
1837 QString(
"ConvertToI skipping undecoded frame #%1").arg(i));
1845 av_packet_ref(pkt, spare->
m_pkt);
1852 fname = QString(
"cnv%1").arg(ins_count++);
1857 av_packet_free(&pkt);
1861 LOG(VB_GENERAL, LOG_INFO,
1862 QString(
"Converting frame #%1 from %2 to I %3")
1866 av_packet_unref(pkt);
1872 m_vFrame.move(headPos, headPos + orderedFrames->count() - 1);
1873 av_packet_free(&pkt);
1878 int64_t ptsIncrement, int64_t initPTS)
1884 AVPacket *pkt = av_packet_alloc();
1887 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1892 if (spare ==
nullptr)
1894 av_packet_free(&pkt);
1898 av_packet_ref(pkt, spare->
m_pkt);
1904 static int ins_count = 0;
1906 (QString(
"ins%1").arg(ins_count++)) : QString());
1911 av_packet_free(&pkt);
1915 LOG(VB_GENERAL, LOG_INFO,
1916 QString(
"Inserting %1 I-Frames after #%2 %3")
1917 .arg((
int)(deltaPTS / ptsIncrement))
1923 index =
m_vFrame.indexOf(spare) + 1;
1930 while (deltaPTS > 0)
1934 pkt->dts = pkt->pts;
1937 if (tmpFrame ==
nullptr)
1942 inc2x33(&pkt->pts, ptsIncrement);
1943 deltaPTS -= ptsIncrement;
1946 av_packet_free(&pkt);
1970 for (
const auto & range : std::as_const(rangelist))
1972 QStringList tmp = range.split(
" - ");
1976 std::array<bool,2> ok {
false,
false };
1978 long long start = tmp[0].toLongLong(ok.data());
1979 long long end = tmp[1].toLongLong(&ok[1]);
1997 if (!rangelist.isEmpty())
2003 if (!mapPtr->isEmpty())
2006 frm_dir_map_t::iterator it = mapPtr->begin();
2007 for (; it != mapPtr->end(); ++it)
2010 msg += QString(
"\n\t\t%1 - %2").arg(start).arg(it.key());
2015 msg += QString(
"\n\t\t%1 - end").arg(start);
2016 LOG(VB_PROCESS, LOG_INFO, msg);
2023 int maxPos = dtsOrder->count() - 1;
2030 for (pos++; pos < maxPos &&
GetFrameTypeT(dtsOrder->at(pos)) ==
'B'; pos++)
2031 Lreorder.append(dtsOrder->at(pos));
2033 Lreorder.append(frame);
2038 int64_t &PTSdiscrep,
int numframes,
bool fix)
const
2043 if (curFrame->
m_pkt->pts == AV_NOPTS_VALUE)
2045 LOG(VB_PROCESS, LOG_INFO,
2046 QString(
"Found frame %1 with missing PTS at %2")
2048 .arg(
PtsTime(origvPTS / 300)));
2050 curFrame->
m_pkt->pts = origvPTS / 300;
2052 PTSdiscrep = AV_NOPTS_VALUE;
2057 if (tmpPTS != PTSdiscrep)
2059 PTSdiscrep = tmpPTS;
2060 LOG(VB_PROCESS, LOG_INFO,
2061 QString(
"Found invalid PTS (off by %1) at %2")
2066 curFrame->
m_pkt->pts = origvPTS / 300;
2070 origvPTS = curFrame->
m_pkt->pts * 300;
2072 ptsinc((uint64_t *)&origvPTS,
2078 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
2079 LOG(VB_GENERAL, LOG_INFO, QString(
"List contains %1 items")
2080 .arg(list->count()));
2082 for (
auto *curFrame : std::as_const(*list))
2084 LOG(VB_GENERAL, LOG_INFO,
2085 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 pos: %6")
2089 .arg(
PtsTime(curFrame->m_pkt->pts),
2090 PtsTime(curFrame->m_pkt->dts),
2091 QString::number(curFrame->m_pkt->pos)));
2093 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
2100 int64_t lastPTS = 0;
2101 int64_t deltaPTS = 0;
2102 std::array<int64_t,N_AUDIO> origaPTS {};
2103 int64_t cutStartPTS = 0;
2104 int64_t cutEndPTS = 0;
2105 uint64_t frame_count = 0;
2106 int new_discard_state = 0;
2107 QMap<int, int> af_dlta_cnt;
2108 QMap<int, int> cutState;
2110 AVPacket *pkt = av_packet_alloc();
2111 AVPacket *lastRealvPkt = av_packet_alloc();
2112 if ((pkt ==
nullptr) || (lastRealvPkt ==
nullptr))
2114 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
2120 av_packet_free(&pkt);
2121 av_packet_free(&lastRealvPkt);
2125 if (
m_inputFC->streams[
m_vidId]->codecpar->codec_id != AV_CODEC_ID_MPEG2VIDEO)
2127 LOG(VB_GENERAL, LOG_ERR,
"Input video codec is not MPEG-2.");
2133 av_packet_free(&pkt);
2134 av_packet_free(&lastRealvPkt);
2140 int64_t initPTS =
m_vFrame.first()->m_pkt->pts;
2142 LOG(VB_GENERAL, LOG_INFO, QString(
"#%1 PTS:%2 Delta: 0.0ms queue: %3")
2149 deltaPTS =
diff2x33(
m_vFrame.first()->m_pkt->pts, af->first()->m_pkt->pts);
2150 LOG(VB_GENERAL, LOG_INFO,
2151 QString(
"#%1 PTS:%2 Delta: %3ms queue: %4")
2152 .arg(it.key()) .arg(
PtsTime(af->first()->m_pkt->pts))
2153 .arg(1000.0*deltaPTS / 90000.0).arg(af->count()));
2155 if (
cmp2x33(af->first()->m_pkt->pts, initPTS) < 0)
2156 initPTS = af->first()->m_pkt->pts;
2163 LOG(VB_PROCESS, LOG_INFO,
2164 QString(
"ptsIncrement: %1 Frame #: %2 PTS-adjust: %3")
2171 int64_t expectedvPTS = 300 * (
udiff2x33(
m_vFrame.first()->m_pkt->pts, initPTS) -
2177 cutStartPTS = origvPTS / 300;
2183 origaPTS[it.key()] = af->first()->m_pkt->pts * 300;
2185 af_dlta_cnt[it.key()] = 0;
2186 cutState[it.key()] =
static_cast<int>(
m_discard);
2200 av_packet_free(&pkt);
2201 av_packet_free(&lastRealvPkt);
2216 LOG(VB_GENERAL, LOG_WARNING,
2217 QString(
"Problem: Frame %1 (type %2) doesn't contain "
2224 LOG(VB_GENERAL, LOG_WARNING,
2225 QString(
"WARNING - Unsupported FPS change from %1 to %2")
2227 .arg(27000000.0 / seqFrame->
m_mpeg2_seq.frame_period,
2231 for (
int frame_pos = 0; frame_pos <
m_vFrame.count() - 1;)
2233 bool ptsorder_eq_dtsorder =
false;
2234 int64_t PTSdiscrep = 0;
2241 LOG(VB_GENERAL, LOG_ERR,
2242 QString(
"expectedPTS != expectedDTS + ptsIncrement"));
2243 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2244 .arg(
PtsTime(expectedvPTS / 300),
2247 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2251 av_packet_free(&pkt);
2252 av_packet_free(&lastRealvPkt);
2260 for (
auto *curFrame : std::as_const(Lreorder))
2274 int count = Lreorder.count();
2280 av_packet_free(&pkt);
2281 av_packet_free(&lastRealvPkt);
2288 int64_t tmp_origvPTS = origvPTS;
2292 (frame_pos + count + 1) <
m_vFrame.count())
2297 for (
auto *curFrame : std::as_const(tmpReorder))
2299 int64_t tmpPTSdiscrep = 0;
2301 tmpPTSdiscrep, numframes,
false);
2309 if (tmpPTSdiscrep != AV_NOPTS_VALUE &&
2310 tmpPTSdiscrep != PTSdiscrep)
2311 PTSdiscrep = tmpPTSdiscrep;
2313 count += tmpReorder.count();
2326 for (
int curIndex = 0; curIndex < Lreorder.count(); curIndex++)
2328 MPEG2frame *curFrame = Lreorder.at(curIndex);
2331 if (
m_saveMap.begin().key() <= frame_count)
2335 LOG(VB_GENERAL, LOG_INFO,
2336 QString(
"Saving frame #%1") .arg(frame_count));
2341 av_packet_free(&pkt);
2342 av_packet_free(&lastRealvPkt);
2346 WriteFrame(QString(
"save%1.yuv").arg(frame_count),
2353 new_discard_state =
m_delMap.begin().value();
2354 LOG(VB_GENERAL, LOG_INFO,
2355 QString(
"Del map found %1 at %2 (%3)")
2356 .arg(new_discard_state) .arg(frame_count)
2360 markedFrameP = curFrame;
2362 if (!new_discard_state)
2364 cutEndPTS = markedFrameP->
m_pkt->pts;
2366 diff2x33(cutEndPTS, expectedvPTS / 300),
2378 cutState[it3.key()] = 1;
2386 (!new_discard_state &&
2391 av_packet_free(&pkt);
2392 av_packet_free(&lastRealvPkt);
2395 ptsorder_eq_dtsorder =
true;
2397 else if (!new_discard_state &&
2400 m_vFrame.move(frame_pos, frame_pos + curIndex);
2401 ptsorder_eq_dtsorder =
true;
2405 markedFrame =
m_vFrame.at(frame_pos + curIndex);
2407 if (!new_discard_state)
2418 if (!Lreorder.isEmpty())
2420 av_packet_unref(lastRealvPkt);
2421 av_packet_ref(lastRealvPkt, Lreorder.last()->m_pkt);
2426 int64_t dtsExtra = 0;
2428 for (
auto *curFrame : std::as_const(Lreorder))
2432 if (curFrame != markedFrameP)
2435 markedFrameP =
nullptr;
2438 dec2x33(&curFrame->m_pkt->pts,
2440 deltaPTS =
diff2x33(curFrame->m_pkt->pts,
2441 expectedvPTS / 300);
2443 if (deltaPTS < -2 || deltaPTS > 2)
2445 LOG(VB_PROCESS, LOG_INFO,
2446 QString(
"PTS discrepancy: %1 != %2 on "
2448 .arg(curFrame->m_pkt->pts)
2449 .arg(expectedvPTS / 300)
2460 curFrame->m_pkt->pts = expectedvPTS / 300;
2464 LOG(VB_GENERAL, LOG_NOTICE,
2465 QString(
"Need to insert %1 frames > max "
2466 "allowed: %2. Assuming bad PTS")
2469 curFrame->m_pkt->pts = expectedvPTS / 300;
2473 lastPTS = expectedvPTS;
2477 if (curFrame == markedFrameP && new_discard_state)
2483 if (ptsorder_eq_dtsorder)
2496 m_vFrame.at(frame_pos)->m_pkt->pts = lastPTS / 300;
2502 av_packet_free(&pkt);
2503 av_packet_free(&lastRealvPkt);
2507 for (
int index = frame_pos + Lreorder.count();
2508 ret && index <
m_vFrame.count(); index++, --ret)
2510 lastPTS = expectedvPTS;
2513 Lreorder.append(
m_vFrame.at(index));
2520 for (
int i = 0; i < Lreorder.count(); i++, frame_pos++)
2525 if (curFrame != markedFrame)
2529 markedFrame =
nullptr;
2533 if (curFrame ==
nullptr)
2535 curFrame->
m_pkt->dts = (expectedDTS / 300);
2538 curFrame->
m_pkt->pts = (expectedDTS / 300);
2541 ((!ptsorder_eq_dtsorder && i == 0) ? 2 :
2543 LOG(VB_FRAME, LOG_INFO,
2544 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 "
2551 QString::number(curFrame->
m_pkt->pos)));
2554 av_packet_free(&pkt);
2555 av_packet_free(&lastRealvPkt);
2559 if (curFrame == markedFrame)
2561 markedFrame =
nullptr;
2566 expectedDTS += dtsExtra;
2570 frame_pos += Lreorder.count();
2574 PTSdiscrep), lastRealvPkt);
2578 cutEndPTS = lastRealvPkt->pts;
2591 bool backwardsPTS =
false;
2593 while (!af->isEmpty())
2602 if (CC->sample_rate == 0 || !CPC || CPC->duration == 0)
2617 90000LL * (int64_t)CPC->duration / CC->sample_rate;
2620 af->first()->m_pkt) < 0)
2622 backwardsPTS =
true;
2623 af_dlta_cnt[it.key()] = 0;
2626 int64_t tmpPTS =
diff2x33(af->first()->m_pkt->pts,
2627 origaPTS[it.key()] / 300);
2629 if (tmpPTS < -incPTS)
2632 LOG(VB_PROCESS, LOG_INFO,
2633 QString(
"Aud discard: PTS %1 < %2")
2634 .arg(
PtsTime(af->first()->m_pkt->pts))
2635 .arg(
PtsTime(origaPTS[it.key()] / 300)));
2638 af_dlta_cnt[it.key()] = 0;
2644 LOG(VB_PROCESS, LOG_INFO,
2645 QString(
"Found invalid audio PTS (off by %1) at %2")
2647 PtsTime(origaPTS[it.key()] / 300)));
2648 if (backwardsPTS && tmpPTS < 90000LL)
2651 LOG(VB_PROCESS, LOG_INFO,
2652 "Fixing missing audio frames");
2653 ptsinc((uint64_t *)&origaPTS[it.key()], 300 * tmpPTS);
2654 backwardsPTS =
false;
2656 else if (tmpPTS < 90000LL * 4)
2658 if (af_dlta_cnt[it.key()] >= 20)
2664 ptsinc((uint64_t *)&origaPTS[it.key()],
2666 af_dlta_cnt[it.key()] = 0;
2670 af_dlta_cnt[it.key()]++;
2673 af->first()->m_pkt->pts = origaPTS[it.key()] / 300;
2675 else if (tmpPTS > incPTS)
2678 backwardsPTS =
false;
2679 af_dlta_cnt[it.key()] = 0;
2683 backwardsPTS =
false;
2684 af_dlta_cnt[it.key()] = 0;
2687 int64_t nextPTS =
add2x33(af->first()->m_pkt->pts,
2688 90000LL * (int64_t)CPC->duration / CC->sample_rate);
2690 if ((cutState[it.key()] == 1 &&
2691 cmp2x33(nextPTS, cutStartPTS) > 0) ||
2692 (cutState[it.key()] == 2 &&
2693 cmp2x33(af->first()->m_pkt->pts, cutEndPTS) < 0))
2696 LOG(VB_PROCESS, LOG_INFO,
2697 QString(
"Aud in cutpoint: %1 > %2 && %3 < %4")
2699 .arg(
PtsTime(af->first()->m_pkt->pts))
2703 cutState[it.key()] = 2;
2704 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2708 int64_t deltaPTS2 = poq.
Get(it.key(), af->first()->m_pkt);
2710 if (
udiff2x33(nextPTS, deltaPTS2) * 300 > expectedDTS &&
2711 cutState[it.key()] != 1)
2714 LOG(VB_PROCESS, LOG_INFO, QString(
"Aud not ready: %1 > %2")
2716 .arg(
PtsTime(expectedDTS / 300)));
2721 if (cutState[it.key()] == 2)
2722 cutState[it.key()] = 0;
2724 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2726 dec2x33(&af->first()->m_pkt->pts, deltaPTS2);
2729 expectedPTS[it.key()] =
udiff2x33(nextPTS, initPTS);
2730 write_audio(lApkt_tail->m_pkt, initPTS);
2732 LOG(VB_FRAME, LOG_INFO, QString(
"AUD #%1: pts: %2 pos: %3")
2734 .arg(
PtsTime(af->first()->m_pkt->pts))
2735 .arg(af->first()->m_pkt->pos));
2738 av_packet_free(&pkt);
2739 av_packet_free(&lastRealvPkt);
2752 void *errors =
nullptr;
2754 if (*(
int *)errors) {
2755 LOG(VB_GENERAL, LOG_ERR,
2756 QString(
"joined thread failed with %1 write errors")
2757 .arg(*(
int *)errors));
2761 av_packet_free(&pkt);
2762 av_packet_free(&lastRealvPkt);
2773 fprintf(
stderr,
"%s usage:\n", s);
2774 fprintf(
stderr,
"\t--infile <file> -i <file> : Input mpg file\n");
2775 fprintf(
stderr,
"\t--outfile <file> -o <file> : Output mpg file\n");
2776 fprintf(
stderr,
"\t--dbg_lvl # -d # : Debug level\n");
2777 fprintf(
stderr,
"\t--maxframes # -m # : Max frames to insert at once (default=10)\n");
2778 fprintf(
stderr,
"\t--cutlist \"start - end\" -c : Apply a cutlist. Specify on e'-c' per cut\n");
2779 fprintf(
stderr,
"\t--no3to2 -t : Remove 3:2 pullup\n");
2780 fprintf(
stderr,
"\t--fixup -f : make PTS continuous\n");
2781 fprintf(
stderr,
"\t--ostream <dvd|ps> -e : Output stream type (defaults to ps)\n");
2782 fprintf(
stderr,
"\t--showprogress -p : show progress\n");
2783 fprintf(
stderr,
"\t--help -h : This screen\n");
2787int main(
int argc,
char **argv)
2789 QStringList cutlist;
2790 QStringList savelist;
2791 char *infile =
nullptr, *outfile =
nullptr, *format =
nullptr;
2792 int no_repeat = 0, fix_PTS = 0, max_frames = 20, otype =
REPLEX_MPEG2;
2793 bool showprogress = 0;
2794 const struct option long_options[] =
2796 {
"infile", required_argument,
nullptr,
'i'},
2797 {
"outfile", required_argument,
nullptr,
'o'},
2798 {
"format", required_argument,
nullptr,
'r'},
2799 {
"dbg_lvl", required_argument,
nullptr,
'd'},
2800 {
"cutlist", required_argument,
nullptr,
'c'},
2801 {
"saveframe", required_argument,
nullptr,
's'},
2802 {
"ostream", required_argument,
nullptr,
'e'},
2803 {
"no3to2", no_argument,
nullptr,
't'},
2804 {
"fixup", no_argument,
nullptr,
'f'},
2805 {
"showprogress", no_argument,
nullptr,
'p'},
2806 {
"help", no_argument ,
nullptr,
'h'},
2812 int option_index = 0;
2814 c = getopt_long (argc, argv,
"i:o:d:r:m:c:s:e:tfph",
2815 long_options, &option_index);
2836 if (strlen(optarg) == 3 && strncmp(optarg,
"dvd", 3) == 0)
2845 max_frames = atoi(optarg);
2849 cutlist.append(optarg);
2860 savelist.append(optarg);
2864 showprogress =
true;
2876 if (infile ==
nullptr || outfile ==
nullptr)
2879 MPEG2fixup m2f(infile, outfile,
nullptr, format,
2880 no_repeat, fix_PTS, max_frames,
2881 showprogress, otype);
2883 if (cutlist.count())
2885 if (savelist.count())
2895 LOG(VB_GENERAL, LOG_INFO,
"Generating Keyframe Index");
2906 LOG(VB_GENERAL, LOG_INFO,
"Seek tables are not required for MKV");
2910 AVPacket *pkt = av_packet_alloc();
2913 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
2917 uint64_t totalDuration = 0;
2918 while (av_read_frame(
m_inputFC, pkt) >= 0)
2920 if (pkt->stream_index ==
m_vidId)
2922 if (pkt->flags & AV_PKT_FLAG_KEY)
2924 posMap[count] = pkt->pos;
2925 durMap[count] = totalDuration;
2934 av_q2d(
m_inputFC->streams[pkt->stream_index]->time_base) *
2935 pkt->duration * 1000;
2938 av_packet_unref(pkt);
2942 av_packet_free(&pkt);
2946 LOG(VB_GENERAL, LOG_NOTICE,
"Transcode Completed");
bool InitAV(const QString &inputfile, const char *type, int64_t offset)
bool BuildFrame(AVPacket *pkt, const QString &fname)
MPEG2frame * DecodeToFrame(int frameNum, int skip_reset)
static int GetFrameNum(const MPEG2frame *frame)
void AddSequence(MPEG2frame *frame1, MPEG2frame *frame2)
QMap< int, int > m_audMap
void RenumberFrames(int start_pos, int delta)
static void SetRepeat(MPEG2frame *vf, int nb_fields, bool topff)
static void WriteYUV(const QString &filename, const mpeg2_info_t *info)
static int64_t diff2x33(int64_t pts1, int64_t pts2)
void WriteFrame(const QString &filename, MPEG2frame *f)
static int GetNbFields(const MPEG2frame *frame)
static FrameList ReorderDTStoPTS(FrameList *dtsOrder, int pos)
static char GetFrameTypeT(const MPEG2frame *frame)
uint64_t m_lastWrittenPos
void InitialPTSFixup(MPEG2frame *curFrame, int64_t &origvPTS, int64_t &PTSdiscrep, int numframes, bool fix) const
static int FindMPEG2Header(const uint8_t *buf, int size, uint8_t code)
static void WriteData(const QString &filename, uint8_t *data, int size)
static int GetFrameTypeN(const MPEG2frame *frame)
AVCodecParserContext * getCodecParserContext(uint id)
int InsertFrame(int frameNum, int64_t deltaPTS, int64_t ptsIncrement, int64_t initPTS)
AVCodecContext * getCodecContext(uint id)
static void inc2x33(int64_t *pts1, int64_t pts2)
int AddFrame(MPEG2frame *f)
static void * ReplexStart(void *data)
MPEG2frame * FindFrameNum(int frameNum)
static int64_t add2x33(int64_t pts1, int64_t pts2)
static int64_t udiff2x33(int64_t pts1, int64_t pts2)
mpeg2dec_t * m_headerDecoder
static int cmp2x33(int64_t pts1, int64_t pts2)
MPEG2frame * GetPoolFrame(AVPacket *pkt)
int ProcessVideo(MPEG2frame *vf, mpeg2dec_t *dec)
void(* m_updateStatus)(float percent_done)
static void ShowRangeMap(frm_dir_map_t *mapPtr, QString msg)
int BuildKeyframeIndex(const QString &file, frm_pos_map_t &posMap, frm_pos_map_t &durMap)
static void SetFrameNum(uint8_t *ptr, int num)
void FrameInfo(MPEG2frame *f)
static void dumpList(FrameList *list)
FrameQueue m_unreadFrames
int GetFrame(AVPacket *pkt)
int GetStreamType(int id) const
void AddRangeList(const QStringList &rangelist, int type)
mpeg2dec_t * m_imgDecoder
MPEG2fixup(const QString &inf, const QString &outf, frm_dir_map_t *deleteMap, const char *fmt, bool norp, bool fixPTS, int maxf, bool showprog, int otype, void(*update_func)(float)=nullptr, int(*check_func)()=nullptr)
static void dec2x33(int64_t *pts1, int64_t pts2)
int ConvertToI(FrameList *orderedFrames, int headPos)
AVFormatContext * m_inputFC
mpeg2_picture_t m_mpeg2_pic
void ensure_size(int size) const
void set_pkt(AVPacket *newpkt) const
mpeg2_sequence_t m_mpeg2_seq
ExtTypeIntArray m_exttypcnt
RingbufferArray m_indexExtrbuf
RingbufferArray m_extrbuf
AudioFrameArray m_extframe
ExtTypeIntArray m_exttype
static void ThreadCleanup(void)
This is to be called on exit in those few threads that haven't been ported to MThread.
static void ThreadSetup(const QString &name)
This is to be called on startup in those few threads that haven't been ported to MThread.
void SetNextPos(int64_t newPTS, AVPacket *pkt)
void SetNextPTS(int64_t newPTS, int64_t atPTS)
int64_t Get(int idx, AVPacket *pkt)
int64_t UpdateOrigPTS(int idx, int64_t &origPTS, AVPacket *pkt)
QMap< int, QList< poq_idx_t > > m_offset
PTSOffsetQueue(int vidid, QList< int > keys, int64_t initPTS)
QMap< int, QList< poq_idx_t > > m_orig
@ GENERIC_EXIT_DEADLOCK
Transcode deadlock detected.
@ GENERIC_EXIT_WRITE_FRAME_ERROR
Frame write error.
@ GENERIC_EXIT_NOT_OK
Exited with error.
static constexpr int MAX_FRAMES
static constexpr bool MATCH_HEADER(const uint8_t *ptr)
static int fill_buffers(void *r, int finish)
static QString PtsTime(int64_t pts)
static void my_av_print(void *ptr, int level, const char *fmt, va_list vl)
static void SETBITS(unsigned char *ptr, long value, int num)
QList< MPEG2frame * > FrameList
int write_out_packs(multiplex_t *mx, int video_ok, aok_arr &ext_ok)
void check_times(multiplex_t *mx, int *video_ok, aok_arr &ext_ok, int *start)
void setup_multiplex(multiplex_t *mx)
void init_multiplex(multiplex_t *mx, sequence_t *seq_head, audio_frame_t *extframe, int *exttype, const int *exttypcnt, uint64_t video_delay, uint64_t audio_delay, int fd, int(*fill_buffers)(void *p, int f), ringbuffer *vrbuffer, ringbuffer *index_vrbuffer, ringbuffer *extrbuffer, ringbuffer *index_extrbuffer, int otype)
int finish_mpg(multiplex_t *mx)
std::array< bool, N_AUDIO > aok_arr
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define ENO
This can be appended to the LOG args with "+".
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
def write(text, progress=True)
static void ptsdec(uint64_t *pts1, uint64_t pts2)
static void ptsinc(uint64_t *pts1, uint64_t pts2)
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.
static QString cleanup(const QString &str)
static void usage(char *progname)
int ring_reinit(ringbuffer *rbuf, int size)
int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
int ring_init(ringbuffer *rbuf, int size)
void ring_destroy(ringbuffer *)
static unsigned int ring_avail(ringbuffer *rbuf)
static unsigned int ring_free(ringbuffer *rbuf)