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");
595 LOG(VB_GENERAL, LOG_WARNING,
"MPEG2fixup::InitReplex(): Using '--ostream=dvd' with HD video is an invalid combination");
600 uint32_t memsize =
m_vFrame.first()->m_mpeg2_seq.width *
601 m_vFrame.first()->m_mpeg2_seq.height * 10;
613 uint index = it.key();
617 if (avctx ==
nullptr)
620 AVDictionaryEntry *metatag =
621 av_dict_get(
m_inputFC->streams[index]->metadata,
622 "language",
nullptr, 0);
623 char *lang = metatag ? metatag->value : (
char *)
"";
632 case AV_CODEC_ID_MP2:
633 case AV_CODEC_ID_MP3:
637 case AV_CODEC_ID_AC3:
647 26999999ULL) /
m_vFrame.first()->m_mpeg2_seq.frame_period;
654 QString msg = QString(
"Id:%1 %2 V:%3").arg(f->
m_pkt->stream_index)
662 msg += QString(
" %2")
665 LOG(VB_RPLXQUEUE, LOG_INFO, msg);
673 int id = f->
m_pkt->stream_index;
684 iu.gop =
static_cast<uint8_t
>(f->
m_isGop);
688 iu.dts = f->
m_pkt->dts * 300;
696 iu.framesize = f->
m_pkt->size;
701 LOG(VB_GENERAL, LOG_ERR,
"Ringbuffer pointers empty. No stream found");
706 iu.length = f->
m_pkt->size;
707 iu.pts = f->
m_pkt->pts * 300;
731 unsigned int inc_size = 10 * (
unsigned int)f->
m_pkt->size;
732 LOG(VB_GENERAL, LOG_NOTICE,
733 QString(
"Increasing ringbuffer size by %1 to avoid deadlock")
743 LOG(VB_GENERAL, LOG_ERR,
744 "Deadlock detected. One buffer is full when "
745 "the other is empty! Aborting");
758 LOG(VB_GENERAL, LOG_ERR,
759 QString(
"Ring buffer overflow %1").arg(rb->
size));
766 LOG(VB_GENERAL, LOG_ERR,
767 QString(
"Ring buffer overflow %1").arg(rbi->
size));
777 QByteArray ifarray = inputfile.toLocal8Bit();
778 const char *ifname = ifarray.constData();
780 const AVInputFormat *fmt =
nullptr;
783 fmt = av_find_input_format(
type);
786 LOG(VB_GENERAL, LOG_INFO, QString(
"Opening %1").arg(inputfile));
794 int ret = avformat_open_input(&
m_inputFC, ifname, fmt,
nullptr);
797 LOG(VB_GENERAL, LOG_ERR,
798 QString(
"Couldn't open input file, error #%1").arg(ret));
808 ret = avformat_find_stream_info(
m_inputFC,
nullptr);
811 LOG(VB_GENERAL, LOG_ERR,
812 QString(
"Couldn't get stream info, error #%1").arg(ret));
822 for (
unsigned int i = 0; i <
m_inputFC->nb_streams; i++)
824 switch (
m_inputFC->streams[i]->codecpar->codec_type)
826 case AVMEDIA_TYPE_VIDEO:
831 case AVMEDIA_TYPE_AUDIO:
833 m_inputFC->streams[i]->codecpar->ch_layout.nb_channels < 2 &&
834 m_inputFC->streams[i]->codecpar->sample_rate < 100000)
836 LOG(VB_GENERAL, LOG_ERR,
837 QString(
"Skipping audio stream: %1").arg(i));
840 if (
m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_AC3 ||
841 m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_MP3 ||
842 m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_MP2)
849 LOG(VB_GENERAL, LOG_ERR,
850 QString(
"Skipping unsupported audio stream: %1")
851 .arg(
m_inputFC->streams[i]->codecpar->codec_id));
855 LOG(VB_GENERAL, LOG_ERR,
856 QString(
"Skipping unsupported codec %1 on stream %2")
857 .arg(
m_inputFC->streams[i]->codecpar->codec_type).arg(i));
877 int oldPktSize = frame1->
m_pkt->size;
879 memmove(frame1->
m_pkt->data + head_size, frame1->
m_pkt->data, oldPktSize);
880 memcpy(frame1->
m_pkt->data, frame2->
m_pkt->data, head_size);
885 static int count = 0;
886 QString
filename = QString(
"hdr%1.yuv").arg(count++);
904 auto *
info = (mpeg2_info_t *)mpeg2_info(dec);
908 while (state != STATE_PICTURE)
910 state = mpeg2_parse(dec);
918 case STATE_SEQUENCE_MODIFIED:
919 case STATE_SEQUENCE_REPEATED:
921 sizeof(mpeg2_sequence_t));
934 sizeof(mpeg2_picture_t));
939 LOG(VB_GENERAL, LOG_WARNING,
940 "Warning: partial frame found!");
944 else if (state == STATE_BUFFER)
947 LOG(VB_GENERAL, LOG_ERR,
948 QString(
"Failed to decode frame. Position was: %1")
952 last_pos = (vf->
m_pkt->size - mpeg2_getpos(dec)) - 4;
957 while (state != STATE_BUFFER)
958 state = mpeg2_parse(dec);
959 if (
info->display_picture)
966 std::array<uint8_t,8> tmp {0x00, 0x00, 0x01, 0xb2, 0xff, 0xff, 0xff, 0xff};
967 mpeg2_buffer(dec, tmp.data(), tmp.data() + 8);
974 QString msg = QString(
"");
976 msg += QString(
"unused:%1 ") .arg(vf->
m_pkt->size - mpeg2_getpos(dec));
980 msg += QString(
"%1x%2 P:%3 ").arg(
info->sequence->width)
981 .arg(
info->sequence->height).arg(
info->sequence->frame_period);
985 QString gop = QString(
"%1:%2:%3:%4 ")
986 .arg(
info->gop->hours, 2, 10, QChar(
'0')).arg(
info->gop->minutes, 2, 10, QChar(
'0'))
987 .arg(
info->gop->seconds, 2, 10, QChar(
'0')).arg(
info->gop->pictures, 3, 10, QChar(
'0'));
990 if (
info->current_picture)
992 int ct =
info->current_picture->flags & PIC_MASK_CODING_TYPE;
993 char coding_type {
'X' };
994 if (ct == PIC_FLAG_CODING_TYPE_I)
996 else if (ct == PIC_FLAG_CODING_TYPE_P)
998 else if (ct == PIC_FLAG_CODING_TYPE_B)
1000 else if (ct == PIC_FLAG_CODING_TYPE_D)
1002 char top_bottom = (
info->current_picture->flags &
1003 PIC_FLAG_TOP_FIELD_FIRST) ?
'T' :
'B';
1004 char progressive = (
info->current_picture->flags &
1005 PIC_FLAG_PROGRESSIVE_FRAME) ?
'P' :
'_';
1006 msg += QString(
"#%1 fl:%2%3%4%5%6 ")
1007 .arg(
info->current_picture->temporal_reference)
1008 .arg(
info->current_picture->nb_fields)
1012 .arg(
info->current_picture->flags >> 4, 0, 16);
1014 msg += QString(
"pos: %1").arg(vf->
m_pkt->pos);
1015 LOG(VB_DECODE, LOG_INFO, msg);
1024 if (tmpFrame ==
nullptr)
1028 for (
const auto & vf : std::as_const(
m_vFrame))
1030 if (vf->m_isSequence)
1044 if (tmpFrame ==
nullptr)
1050 mpeg2dec_t *tmp_decoder = mpeg2_init();
1051 auto *
info = (mpeg2_info_t *)mpeg2_info(tmp_decoder);
1053 while (!
info->display_picture)
1064 mpeg2_close(tmp_decoder);
1069 int fh = open(
filename.toLocal8Bit().constData(),
1070 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1073 LOG(VB_GENERAL, LOG_ERR,
1074 QString(
"Couldn't open file %1: ").arg(
filename) +
ENO);
1079 auto close_fh = [](
const int *fh2) {
close(*fh2); };
1080 std::unique_ptr<int,
decltype(close_fh)>
cleanup { &fh, close_fh };
1082 ssize_t ret =
write(fh,
info->display_fbuf->buf[0],
1083 static_cast<size_t>(
info->sequence->width) *
1084 static_cast<size_t>(
info->sequence->height));
1087 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1091 ret =
write(fh,
info->display_fbuf->buf[1],
1092 static_cast<size_t>(
info->sequence->chroma_width) *
1093 static_cast<size_t>(
info->sequence->chroma_height));
1096 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1100 ret =
write(fh,
info->display_fbuf->buf[2],
1101 static_cast<size_t>(
info->sequence->chroma_width) *
1102 static_cast<size_t>(
info->sequence->chroma_height));
1105 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1113 int fh = open(
filename.toLocal8Bit().constData(),
1114 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1117 LOG(VB_GENERAL, LOG_ERR,
1118 QString(
"Couldn't open file %1: ").arg(
filename) +
ENO);
1122 int ret =
write(fh, data, size);
1124 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1").arg(
filename) +
1131 alignas(16) std::array<uint16_t,64> intra_matrix {};
1132 int64_t savedPts = pkt->pts;
1135 if (!
info->display_fbuf)
1138 int outbuf_size =
info->sequence->width *
info->sequence->height * 2;
1140 if (!fname.isEmpty())
1142 QString tmpstr = fname +
".yuv";
1160 if (pkt->size < outbuf_size)
1161 av_grow_packet(pkt, (outbuf_size - pkt->size));
1174 static constexpr std::array<uint8_t, 64> k_zigzag_scan = {
1175 0, 1, 8, 16, 9, 2, 3, 10,
1176 17, 24, 32, 25, 18, 11, 4, 5,
1177 12, 19, 26, 33, 40, 48, 41, 34,
1178 27, 20, 13, 6, 7, 14, 21, 28,
1179 35, 42, 49, 56, 57, 50, 43, 36,
1180 29, 22, 15, 23, 30, 37, 44, 51,
1181 58, 59, 52, 45, 38, 31, 39, 46,
1182 53, 60, 61, 54, 47, 55, 62, 63
1185 static std::array<uint16_t, 64> k_invZigzagDirect16 = {};
1186 for (
int i = 0; i < 64; i++)
1188 k_invZigzagDirect16[k_zigzag_scan[i]] = i;
1191 static constexpr std::array<uint16_t, 64> k_invZigzagDirect16 = {
1192 0, 1, 5, 6, 14, 15, 27, 28,
1193 2, 4, 7, 13, 16, 26, 29, 42,
1194 3, 8, 12, 17, 25, 30, 41, 43,
1195 9, 11, 18, 24, 31, 40, 44, 53,
1196 10, 19, 23, 32, 39, 45, 52, 54,
1197 20, 22, 33, 38, 46, 51, 55, 60,
1198 21, 34, 37, 47, 50, 56, 59, 61,
1199 35, 36, 48, 49, 57, 58, 62, 63,
1203 for (
int i = 0; i < 64; i++)
1205 intra_matrix[k_invZigzagDirect16[i]] =
m_imgDecoder->quantizer_matrix[0][i];
1208 if (
info->display_picture->nb_fields % 2)
1210 if ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0)
1212 m_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
1216 m_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
1221 if ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0)
1223 m_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
1227 m_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
1231 if ((
info->display_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME) != 0)
1233 m_picture->flags &= ~AV_FRAME_FLAG_INTERLACED;
1237 m_picture->flags |= AV_FRAME_FLAG_INTERLACED;
1240 const AVCodec *out_codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO);
1243 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find MPEG2 encoder");
1247 AVCodecContext *c = avcodec_alloc_context3(
nullptr);
1253 if ((
m_picture->flags & AV_FRAME_FLAG_INTERLACED) != 0)
1254 c->flags |= AV_CODEC_FLAG_INTERLACED_DCT;
1256 c->bit_rate =
info->sequence->byte_rate << 3;
1257 c->bit_rate_tolerance = c->bit_rate >> 2;
1258 c->width =
info->sequence->width;
1259 c->height =
info->sequence->height;
1260 av_reduce(&c->time_base.num, &c->time_base.den,
1261 info->sequence->frame_period, 27000000LL, 100000);
1262 c->pix_fmt = AV_PIX_FMT_YUV420P;
1263 c->max_b_frames = 0;
1264 c->has_b_frames = 0;
1270 c->rc_buffer_size = 0;
1274 if (intra_matrix[0] == 0x08)
1275 c->intra_matrix = intra_matrix.data();
1277 c->qmin = c->qmax = 2;
1284 m_picture->pict_type = AV_PICTURE_TYPE_NONE;
1287 if (avcodec_open2(c, out_codec,
nullptr) < 0)
1289 LOG(VB_GENERAL, LOG_ERR,
"could not open codec");
1294 int ret = avcodec_send_frame(c,
m_picture);
1296 bool flushed =
false;
1300 ret = avcodec_receive_packet(c, pkt);
1303 if (ret == AVERROR(EAGAIN))
1310 ret = avcodec_send_frame(c,
nullptr);
1314 if (ret < 0 || !got_packet)
1316 LOG(VB_GENERAL, LOG_ERR,
1317 QString(
"avcodec_encode_video2 failed (%1)").arg(ret));
1321 if (!fname.isEmpty())
1323 QString ename = fname +
".enc";
1326 QString yname = fname +
".enc.yuv";
1333 int newSize = pkt->size - delta;
1334 pkt->pts = savedPts;
1335 memmove(pkt->data, pkt->data + delta, newSize);
1336 av_shrink_packet(pkt, newSize);
1339 SetRepeat(pkt->data, pkt->size,
info->display_picture->nb_fields,
1340 ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0U));
1342 avcodec_free_context(&c);
1354 static int s_frameCount = 0;
1357 LOG(VB_GENERAL, LOG_ERR,
"No more queue slots!");
1402 pkt->pts = AV_NOPTS_VALUE;
1403 pkt->dts = AV_NOPTS_VALUE;
1404 int ret = av_read_frame(
m_inputFC, pkt);
1415 LOG(VB_GENERAL, LOG_ERR,
1416 "Found end of file without finding any frames");
1417 av_packet_unref(pkt);
1422 if (tmpFrame ==
nullptr)
1424 av_packet_unref(pkt);
1434 if (pkt->stream_index ==
m_vidId ||
1435 m_aFrame.contains(pkt->stream_index))
1438 av_packet_unref(pkt);
1444 float percent_done = 100.0F * pkt->pos /
m_fileSize;
1448 LOG(VB_GENERAL, LOG_INFO, QString(
"%1% complete")
1449 .arg(percent_done, 0,
'f', 1));
1457 LOG(VB_DECODE, LOG_INFO, QString(
"Stream: %1 PTS: %2 DTS: %3 pos: %4")
1458 .arg(pkt->stream_index)
1459 .arg((pkt->pts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->pts))
1460 .arg((pkt->dts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->dts))
1465 if (tmpFrame ==
nullptr)
1467 av_packet_unref(pkt);
1471 switch (
m_inputFC->streams[pkt->stream_index]->codecpar->codec_type)
1473 case AVMEDIA_TYPE_VIDEO:
1475 av_packet_unref(pkt);
1482 case AVMEDIA_TYPE_AUDIO:
1483 if (
m_aFrame.contains(pkt->stream_index))
1485 m_aFrame[pkt->stream_index]->append(tmpFrame);
1489 LOG(VB_GENERAL, LOG_DEBUG,
1490 QString(
"Invalid stream ID %1, ignoring").arg(pkt->stream_index));
1493 av_packet_unref(pkt);
1498 av_packet_unref(pkt);
1506 QMap <int, bool> found;
1507 AVPacket *pkt = av_packet_alloc();
1510 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1514 while (found.count() !=
m_aFrame.count())
1518 av_packet_free(&pkt);
1522 if (
m_vidId == pkt->stream_index)
1526 if (
m_vFrame.first()->m_isSequence)
1528 if (pkt->pos !=
m_vFrame.first()->m_pkt->pos)
1531 if (pkt->pts != AV_NOPTS_VALUE ||
1532 pkt->dts != AV_NOPTS_VALUE)
1534 if (pkt->pts == AV_NOPTS_VALUE)
1535 m_vFrame.first()->m_pkt->pts = pkt->dts;
1537 LOG(VB_PROCESS, LOG_INFO,
1538 "Found 1st valid video frame");
1543 LOG(VB_PROCESS, LOG_INFO,
"Dropping V packet");
1554 if (found.contains(it.key()))
1559 while (!af->isEmpty())
1561 int64_t delta =
diff2x33(af->first()->m_pkt->pts,
1563 if (delta < -180000 || delta > 180000)
1568 for (
auto *currFrame : std::as_const(
m_vFrame))
1570 if (currFrame->m_isSequence)
1572 int64_t dlta1 =
diff2x33(af->first()->m_pkt->pts,
1573 currFrame->m_pkt->pts);
1574 if (dlta1 >= -180000 && dlta1 <= 180000)
1576 foundframe = currFrame;
1583 while (foundframe &&
m_vFrame.first() != foundframe)
1589 if (delta < -180000 || delta > 180000)
1591 LOG(VB_PROCESS, LOG_INFO,
1592 QString(
"Dropping A packet from stream %1")
1594 LOG(VB_PROCESS, LOG_INFO, QString(
" A:%1 V:%2")
1595 .arg(
PtsTime(af->first()->m_pkt->pts),
1601 if (delta < 0 && af->count() > 1)
1603 if (
cmp2x33(af->at(1)->m_pkt->pts,
1606 LOG(VB_PROCESS, LOG_INFO,
1607 QString(
"Found useful audio frame from stream %1")
1609 found[it.key()] =
true;
1612 LOG(VB_PROCESS, LOG_INFO,
1613 QString(
"Dropping A packet from stream %1")
1620 LOG(VB_PROCESS, LOG_INFO,
1621 QString(
"Found useful audio frame from stream %1")
1623 found[it.key()] =
true;
1627 if (af->count() == 1)
1633 av_packet_free(&pkt);
1646 uint8_t *end = ptr + size;
1647 uint8_t setmask = 0x00;
1648 uint8_t clrmask = 0xff;
1661 if (
MATCH_HEADER(ptr) && ptr[3] == 0xB5 && (ptr[4] & 0xF0) == 0x80)
1676 for (
const auto & vf : std::as_const(
m_vFrame))
1689 for (
int pos = start_pos; pos < maxPos; pos++)
1730 bool skip_first =
false;
1745 int framePos =
m_vFrame.indexOf(spare);
1753 if (!skip_first && curPos >= framePos &&
info->display_picture &&
1754 (
int)
info->display_picture->temporal_reference >= frameNum)
1766 int tmpFrameNum = frameNum;
1768 if (tmpFrame ==
nullptr)
1774 while (!
info->display_picture ||
1775 (
int)
info->display_picture->temporal_reference < frameNum)
1788 if ((
int)
info->display_picture->temporal_reference > frameNum)
1794 LOG(VB_GENERAL, LOG_NOTICE,
1795 QString(
"Frame %1 > %2. Corruption likely at pos: %3")
1796 .arg(
info->display_picture->temporal_reference)
1797 .arg(frameNum).arg(spare->
m_pkt->pos));
1806 AVPacket *pkt = av_packet_alloc();
1809 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1813 static int ins_count = 0;
1821 av_packet_free(&pkt);
1826 for (
const auto & of : std::as_const(*orderedFrames))
1830 if (spare ==
nullptr)
1832 LOG(VB_GENERAL, LOG_WARNING,
1833 QString(
"ConvertToI skipping undecoded frame #%1").arg(i));
1841 av_packet_ref(pkt, spare->
m_pkt);
1848 fname = QString(
"cnv%1").arg(ins_count++);
1853 av_packet_free(&pkt);
1857 LOG(VB_GENERAL, LOG_INFO,
1858 QString(
"Converting frame #%1 from %2 to I %3")
1862 av_packet_unref(pkt);
1868 m_vFrame.move(headPos, headPos + orderedFrames->count() - 1);
1869 av_packet_free(&pkt);
1874 int64_t ptsIncrement, int64_t initPTS)
1880 AVPacket *pkt = av_packet_alloc();
1883 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1888 if (spare ==
nullptr)
1890 av_packet_free(&pkt);
1894 av_packet_ref(pkt, spare->
m_pkt);
1900 static int ins_count = 0;
1902 (QString(
"ins%1").arg(ins_count++)) : QString());
1907 av_packet_free(&pkt);
1911 LOG(VB_GENERAL, LOG_INFO,
1912 QString(
"Inserting %1 I-Frames after #%2 %3")
1913 .arg((
int)(deltaPTS / ptsIncrement))
1919 index =
m_vFrame.indexOf(spare) + 1;
1926 while (deltaPTS > 0)
1930 pkt->dts = pkt->pts;
1933 if (tmpFrame ==
nullptr)
1938 inc2x33(&pkt->pts, ptsIncrement);
1939 deltaPTS -= ptsIncrement;
1942 av_packet_free(&pkt);
1966 for (
const auto & range : std::as_const(rangelist))
1968 QStringList tmp = range.split(
" - ");
1972 std::array<bool,2> ok {
false,
false };
1974 long long start = tmp[0].toLongLong(ok.data());
1975 long long end = tmp[1].toLongLong(&ok[1]);
1993 if (!rangelist.isEmpty())
1999 if (!mapPtr->isEmpty())
2002 frm_dir_map_t::iterator it = mapPtr->begin();
2003 for (; it != mapPtr->end(); ++it)
2006 msg += QString(
"\n\t\t%1 - %2").arg(start).arg(it.key());
2011 msg += QString(
"\n\t\t%1 - end").arg(start);
2012 LOG(VB_PROCESS, LOG_INFO, msg);
2019 int maxPos = dtsOrder->count() - 1;
2026 for (pos++; pos < maxPos &&
GetFrameTypeT(dtsOrder->at(pos)) ==
'B'; pos++)
2027 Lreorder.append(dtsOrder->at(pos));
2029 Lreorder.append(frame);
2034 int64_t &PTSdiscrep,
int numframes,
bool fix)
const
2039 if (curFrame->
m_pkt->pts == AV_NOPTS_VALUE)
2041 LOG(VB_PROCESS, LOG_INFO,
2042 QString(
"Found frame %1 with missing PTS at %2")
2044 .arg(
PtsTime(origvPTS / 300)));
2046 curFrame->
m_pkt->pts = origvPTS / 300;
2048 PTSdiscrep = AV_NOPTS_VALUE;
2053 if (tmpPTS != PTSdiscrep)
2055 PTSdiscrep = tmpPTS;
2056 LOG(VB_PROCESS, LOG_INFO,
2057 QString(
"Found invalid PTS (off by %1) at %2")
2062 curFrame->
m_pkt->pts = origvPTS / 300;
2066 origvPTS = curFrame->
m_pkt->pts * 300;
2068 ptsinc((uint64_t *)&origvPTS,
2074 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
2075 LOG(VB_GENERAL, LOG_INFO, QString(
"List contains %1 items")
2076 .arg(list->count()));
2078 for (
auto *curFrame : std::as_const(*list))
2080 LOG(VB_GENERAL, LOG_INFO,
2081 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 pos: %6")
2085 .arg(
PtsTime(curFrame->m_pkt->pts),
2086 PtsTime(curFrame->m_pkt->dts),
2087 QString::number(curFrame->m_pkt->pos)));
2089 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
2096 int64_t lastPTS = 0;
2097 int64_t deltaPTS = 0;
2098 std::array<int64_t,N_AUDIO> origaPTS {};
2099 int64_t cutStartPTS = 0;
2100 int64_t cutEndPTS = 0;
2101 uint64_t frame_count = 0;
2102 int new_discard_state = 0;
2103 QMap<int, int> af_dlta_cnt;
2104 QMap<int, int> cutState;
2106 AVPacket *pkt = av_packet_alloc();
2107 AVPacket *lastRealvPkt = av_packet_alloc();
2108 if ((pkt ==
nullptr) || (lastRealvPkt ==
nullptr))
2110 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
2116 av_packet_free(&pkt);
2117 av_packet_free(&lastRealvPkt);
2121 if (
m_inputFC->streams[
m_vidId]->codecpar->codec_id != AV_CODEC_ID_MPEG2VIDEO)
2123 LOG(VB_GENERAL, LOG_ERR,
"Input video codec is not MPEG-2.");
2129 av_packet_free(&pkt);
2130 av_packet_free(&lastRealvPkt);
2136 int64_t initPTS =
m_vFrame.first()->m_pkt->pts;
2138 LOG(VB_GENERAL, LOG_INFO, QString(
"#%1 PTS:%2 Delta: 0.0ms queue: %3")
2145 deltaPTS =
diff2x33(
m_vFrame.first()->m_pkt->pts, af->first()->m_pkt->pts);
2146 LOG(VB_GENERAL, LOG_INFO,
2147 QString(
"#%1 PTS:%2 Delta: %3ms queue: %4")
2148 .arg(it.key()) .arg(
PtsTime(af->first()->m_pkt->pts))
2149 .arg(1000.0*deltaPTS / 90000.0).arg(af->count()));
2151 if (
cmp2x33(af->first()->m_pkt->pts, initPTS) < 0)
2152 initPTS = af->first()->m_pkt->pts;
2159 LOG(VB_PROCESS, LOG_INFO,
2160 QString(
"ptsIncrement: %1 Frame #: %2 PTS-adjust: %3")
2167 int64_t expectedvPTS = 300 * (
udiff2x33(
m_vFrame.first()->m_pkt->pts, initPTS) -
2173 cutStartPTS = origvPTS / 300;
2179 origaPTS[it.key()] = af->first()->m_pkt->pts * 300;
2181 af_dlta_cnt[it.key()] = 0;
2182 cutState[it.key()] =
static_cast<int>(
m_discard);
2196 av_packet_free(&pkt);
2197 av_packet_free(&lastRealvPkt);
2212 LOG(VB_GENERAL, LOG_WARNING,
2213 QString(
"Problem: Frame %1 (type %2) doesn't contain "
2220 LOG(VB_GENERAL, LOG_WARNING,
2221 QString(
"WARNING - Unsupported FPS change from %1 to %2")
2223 .arg(27000000.0 / seqFrame->
m_mpeg2_seq.frame_period,
2227 for (
int frame_pos = 0; frame_pos <
m_vFrame.count() - 1;)
2229 bool ptsorder_eq_dtsorder =
false;
2230 int64_t PTSdiscrep = 0;
2237 LOG(VB_GENERAL, LOG_ERR,
2238 QString(
"expectedPTS != expectedDTS + ptsIncrement"));
2239 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2240 .arg(
PtsTime(expectedvPTS / 300),
2243 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2247 av_packet_free(&pkt);
2248 av_packet_free(&lastRealvPkt);
2256 for (
auto *curFrame : std::as_const(Lreorder))
2270 int count = Lreorder.count();
2276 av_packet_free(&pkt);
2277 av_packet_free(&lastRealvPkt);
2284 int64_t tmp_origvPTS = origvPTS;
2288 (frame_pos + count + 1) <
m_vFrame.count())
2293 for (
auto *curFrame : std::as_const(tmpReorder))
2295 int64_t tmpPTSdiscrep = 0;
2297 tmpPTSdiscrep, numframes,
false);
2305 if (tmpPTSdiscrep != AV_NOPTS_VALUE &&
2306 tmpPTSdiscrep != PTSdiscrep)
2307 PTSdiscrep = tmpPTSdiscrep;
2309 count += tmpReorder.count();
2322 for (
int curIndex = 0; curIndex < Lreorder.count(); curIndex++)
2324 MPEG2frame *curFrame = Lreorder.at(curIndex);
2327 if (
m_saveMap.begin().key() <= frame_count)
2331 LOG(VB_GENERAL, LOG_INFO,
2332 QString(
"Saving frame #%1") .arg(frame_count));
2337 av_packet_free(&pkt);
2338 av_packet_free(&lastRealvPkt);
2342 WriteFrame(QString(
"save%1.yuv").arg(frame_count),
2349 new_discard_state =
m_delMap.begin().value();
2350 LOG(VB_GENERAL, LOG_INFO,
2351 QString(
"Del map found %1 at %2 (%3)")
2352 .arg(new_discard_state) .arg(frame_count)
2356 markedFrameP = curFrame;
2358 if (!new_discard_state)
2360 cutEndPTS = markedFrameP->
m_pkt->pts;
2362 diff2x33(cutEndPTS, expectedvPTS / 300),
2374 cutState[it3.key()] = 1;
2382 (!new_discard_state &&
2387 av_packet_free(&pkt);
2388 av_packet_free(&lastRealvPkt);
2391 ptsorder_eq_dtsorder =
true;
2393 else if (!new_discard_state &&
2396 m_vFrame.move(frame_pos, frame_pos + curIndex);
2397 ptsorder_eq_dtsorder =
true;
2401 markedFrame =
m_vFrame.at(frame_pos + curIndex);
2403 if (!new_discard_state)
2414 if (!Lreorder.isEmpty())
2416 av_packet_unref(lastRealvPkt);
2417 av_packet_ref(lastRealvPkt, Lreorder.last()->m_pkt);
2422 int64_t dtsExtra = 0;
2424 for (
auto *curFrame : std::as_const(Lreorder))
2428 if (curFrame != markedFrameP)
2431 markedFrameP =
nullptr;
2434 dec2x33(&curFrame->m_pkt->pts,
2436 deltaPTS =
diff2x33(curFrame->m_pkt->pts,
2437 expectedvPTS / 300);
2439 if (deltaPTS < -2 || deltaPTS > 2)
2441 LOG(VB_PROCESS, LOG_INFO,
2442 QString(
"PTS discrepancy: %1 != %2 on "
2444 .arg(curFrame->m_pkt->pts)
2445 .arg(expectedvPTS / 300)
2456 curFrame->m_pkt->pts = expectedvPTS / 300;
2460 LOG(VB_GENERAL, LOG_NOTICE,
2461 QString(
"Need to insert %1 frames > max "
2462 "allowed: %2. Assuming bad PTS")
2465 curFrame->m_pkt->pts = expectedvPTS / 300;
2469 lastPTS = expectedvPTS;
2473 if (curFrame == markedFrameP && new_discard_state)
2479 if (ptsorder_eq_dtsorder)
2492 m_vFrame.at(frame_pos)->m_pkt->pts = lastPTS / 300;
2498 av_packet_free(&pkt);
2499 av_packet_free(&lastRealvPkt);
2503 for (
int index = frame_pos + Lreorder.count();
2504 ret && index <
m_vFrame.count(); index++, --ret)
2506 lastPTS = expectedvPTS;
2509 Lreorder.append(
m_vFrame.at(index));
2516 for (
int i = 0; i < Lreorder.count(); i++, frame_pos++)
2521 if (curFrame != markedFrame)
2525 markedFrame =
nullptr;
2529 if (curFrame ==
nullptr)
2531 curFrame->
m_pkt->dts = (expectedDTS / 300);
2534 curFrame->
m_pkt->pts = (expectedDTS / 300);
2537 ((!ptsorder_eq_dtsorder && i == 0) ? 2 :
2539 LOG(VB_FRAME, LOG_INFO,
2540 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 "
2547 QString::number(curFrame->
m_pkt->pos)));
2550 av_packet_free(&pkt);
2551 av_packet_free(&lastRealvPkt);
2555 if (curFrame == markedFrame)
2557 markedFrame =
nullptr;
2562 expectedDTS += dtsExtra;
2566 frame_pos += Lreorder.count();
2570 PTSdiscrep), lastRealvPkt);
2574 cutEndPTS = lastRealvPkt->pts;
2587 bool backwardsPTS =
false;
2589 while (!af->isEmpty())
2598 if (CC->sample_rate == 0 || !CPC || CPC->duration == 0)
2613 90000LL * (int64_t)CPC->duration / CC->sample_rate;
2616 af->first()->m_pkt) < 0)
2618 backwardsPTS =
true;
2619 af_dlta_cnt[it.key()] = 0;
2622 int64_t tmpPTS =
diff2x33(af->first()->m_pkt->pts,
2623 origaPTS[it.key()] / 300);
2625 if (tmpPTS < -incPTS)
2628 LOG(VB_PROCESS, LOG_INFO,
2629 QString(
"Aud discard: PTS %1 < %2")
2630 .arg(
PtsTime(af->first()->m_pkt->pts))
2631 .arg(
PtsTime(origaPTS[it.key()] / 300)));
2634 af_dlta_cnt[it.key()] = 0;
2640 LOG(VB_PROCESS, LOG_INFO,
2641 QString(
"Found invalid audio PTS (off by %1) at %2")
2643 PtsTime(origaPTS[it.key()] / 300)));
2644 if (backwardsPTS && tmpPTS < 90000LL)
2647 LOG(VB_PROCESS, LOG_INFO,
2648 "Fixing missing audio frames");
2649 ptsinc((uint64_t *)&origaPTS[it.key()], 300 * tmpPTS);
2650 backwardsPTS =
false;
2652 else if (tmpPTS < 90000LL * 4)
2654 if (af_dlta_cnt[it.key()] >= 20)
2660 ptsinc((uint64_t *)&origaPTS[it.key()],
2662 af_dlta_cnt[it.key()] = 0;
2666 af_dlta_cnt[it.key()]++;
2669 af->first()->m_pkt->pts = origaPTS[it.key()] / 300;
2671 else if (tmpPTS > incPTS)
2674 backwardsPTS =
false;
2675 af_dlta_cnt[it.key()] = 0;
2679 backwardsPTS =
false;
2680 af_dlta_cnt[it.key()] = 0;
2683 int64_t nextPTS =
add2x33(af->first()->m_pkt->pts,
2684 90000LL * (int64_t)CPC->duration / CC->sample_rate);
2686 if ((cutState[it.key()] == 1 &&
2687 cmp2x33(nextPTS, cutStartPTS) > 0) ||
2688 (cutState[it.key()] == 2 &&
2689 cmp2x33(af->first()->m_pkt->pts, cutEndPTS) < 0))
2692 LOG(VB_PROCESS, LOG_INFO,
2693 QString(
"Aud in cutpoint: %1 > %2 && %3 < %4")
2695 .arg(
PtsTime(af->first()->m_pkt->pts))
2699 cutState[it.key()] = 2;
2700 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2704 int64_t deltaPTS2 = poq.
Get(it.key(), af->first()->m_pkt);
2706 if (
udiff2x33(nextPTS, deltaPTS2) * 300 > expectedDTS &&
2707 cutState[it.key()] != 1)
2710 LOG(VB_PROCESS, LOG_INFO, QString(
"Aud not ready: %1 > %2")
2712 .arg(
PtsTime(expectedDTS / 300)));
2717 if (cutState[it.key()] == 2)
2718 cutState[it.key()] = 0;
2720 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2722 dec2x33(&af->first()->m_pkt->pts, deltaPTS2);
2725 expectedPTS[it.key()] =
udiff2x33(nextPTS, initPTS);
2726 write_audio(lApkt_tail->m_pkt, initPTS);
2728 LOG(VB_FRAME, LOG_INFO, QString(
"AUD #%1: pts: %2 pos: %3")
2730 .arg(
PtsTime(af->first()->m_pkt->pts))
2731 .arg(af->first()->m_pkt->pos));
2734 av_packet_free(&pkt);
2735 av_packet_free(&lastRealvPkt);
2748 void *errors =
nullptr;
2750 if (*(
int *)errors) {
2751 LOG(VB_GENERAL, LOG_ERR,
2752 QString(
"joined thread failed with %1 write errors")
2753 .arg(*(
int *)errors));
2757 av_packet_free(&pkt);
2758 av_packet_free(&lastRealvPkt);
2769 fprintf(
stderr,
"%s usage:\n", s);
2770 fprintf(
stderr,
"\t--infile <file> -i <file> : Input mpg file\n");
2771 fprintf(
stderr,
"\t--outfile <file> -o <file> : Output mpg file\n");
2772 fprintf(
stderr,
"\t--dbg_lvl # -d # : Debug level\n");
2773 fprintf(
stderr,
"\t--maxframes # -m # : Max frames to insert at once (default=10)\n");
2774 fprintf(
stderr,
"\t--cutlist \"start - end\" -c : Apply a cutlist. Specify on e'-c' per cut\n");
2775 fprintf(
stderr,
"\t--no3to2 -t : Remove 3:2 pullup\n");
2776 fprintf(
stderr,
"\t--fixup -f : make PTS continuous\n");
2777 fprintf(
stderr,
"\t--ostream <dvd|ps> -e : Output stream type (defaults to ps)\n");
2778 fprintf(
stderr,
"\t--showprogress -p : show progress\n");
2779 fprintf(
stderr,
"\t--help -h : This screen\n");
2783int main(
int argc,
char **argv)
2785 QStringList cutlist;
2786 QStringList savelist;
2787 char *infile =
nullptr, *outfile =
nullptr, *format =
nullptr;
2788 int no_repeat = 0, fix_PTS = 0, max_frames = 20, otype =
REPLEX_MPEG2;
2789 bool showprogress = 0;
2790 const struct option long_options[] =
2792 {
"infile", required_argument,
nullptr,
'i'},
2793 {
"outfile", required_argument,
nullptr,
'o'},
2794 {
"format", required_argument,
nullptr,
'r'},
2795 {
"dbg_lvl", required_argument,
nullptr,
'd'},
2796 {
"cutlist", required_argument,
nullptr,
'c'},
2797 {
"saveframe", required_argument,
nullptr,
's'},
2798 {
"ostream", required_argument,
nullptr,
'e'},
2799 {
"no3to2", no_argument,
nullptr,
't'},
2800 {
"fixup", no_argument,
nullptr,
'f'},
2801 {
"showprogress", no_argument,
nullptr,
'p'},
2802 {
"help", no_argument ,
nullptr,
'h'},
2808 int option_index = 0;
2810 c = getopt_long (argc, argv,
"i:o:d:r:m:c:s:e:tfph",
2811 long_options, &option_index);
2832 if (strlen(optarg) == 3 && strncmp(optarg,
"dvd", 3) == 0)
2841 max_frames = atoi(optarg);
2845 cutlist.append(optarg);
2856 savelist.append(optarg);
2860 showprogress =
true;
2872 if (infile ==
nullptr || outfile ==
nullptr)
2875 MPEG2fixup m2f(infile, outfile,
nullptr, format,
2876 no_repeat, fix_PTS, max_frames,
2877 showprogress, otype);
2879 if (cutlist.count())
2881 if (savelist.count())
2891 LOG(VB_GENERAL, LOG_INFO,
"Generating Keyframe Index");
2902 LOG(VB_GENERAL, LOG_INFO,
"Seek tables are not required for MKV");
2906 AVPacket *pkt = av_packet_alloc();
2909 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
2913 uint64_t totalDuration = 0;
2914 while (av_read_frame(
m_inputFC, pkt) >= 0)
2916 if (pkt->stream_index ==
m_vidId)
2918 if (pkt->flags & AV_PKT_FLAG_KEY)
2920 posMap[count] = pkt->pos;
2921 durMap[count] = totalDuration;
2930 av_q2d(
m_inputFC->streams[pkt->stream_index]->time_base) *
2931 pkt->duration * 1000;
2934 av_packet_unref(pkt);
2938 av_packet_free(&pkt);
2942 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)