22#include "libmythbase/mythconfig.h"
30#include "libavutil/cpu.h"
31#include "libmythmpeg2/attributes.h"
32#include "libmythmpeg2/mpeg2.h"
33#include "libmythmpeg2/mpeg2_internal.h"
42#include <netinet/in.h>
50 int level,
const char* fmt, va_list vl)
52 static QString s_fullLine(
"");
54 if (level > AV_LOG_INFO)
57 s_fullLine += QString::vasprintf(fmt, vl);
58 if (s_fullLine.endsWith(
"\n"))
61 LOG(VB_GENERAL, LOG_INFO, s_fullLine);
62 s_fullLine = QString(
"");
74 return QString(
"%1%2:%3:%4.%5")
75 .arg(is_neg ?
"-" :
"")
76 .arg((
uint)(
pts / 90000.) / 3600, 2, 10, QChar(
'0'))
77 .arg(((
uint)(
pts / 90000.) % 3600) / 60, 2, 10, QChar(
'0'))
78 .arg(((
uint)(
pts / 90000.) % 3600) % 60, 2, 10, QChar(
'0'))
79 .arg(((((
uint)(
pts / 90.) % 3600000) % 60000) % 1000), 3, 10, QChar(
'0'));
83 m_pkt(av_packet_alloc()),
84 m_mpeg2_seq(), m_mpeg2_gop(), m_mpeg2_pic()
86 av_new_packet(
m_pkt, size);
91 av_packet_free(&
m_pkt);
96 if (
m_pkt->size < size)
98 int oldSize =
m_pkt->size;
99 if ((av_grow_packet(
m_pkt, size -
m_pkt->size) < 0) ||
m_pkt->size < size)
101 LOG(VB_GENERAL, LOG_CRIT, QString(
"MPEG2frame::ensure_size(): "
102 "Failed to grow packet size "
103 "from %1 to %2, result was %3")
104 .arg(oldSize).arg(size)
113 av_packet_unref(
m_pkt);
114 av_packet_ref(
m_pkt, newpkt);
118 : m_keyList(
std::move(keys)),
124 idx.newPTS = initPTS;
129 for (
const int key : std::as_const(
m_keyList))
135 QList<poq_idx_t>::iterator it;
136 int64_t value =
m_offset[idx].first().newPTS;
144 while (
m_offset[idx].count() > 1 && !done)
147 if (((
static_cast<int>((*it).type) == 0) &&
148 (pkt->pts >= (*it).pos_pts) ) ||
150 ((pkt->pos >= (*it).pos_pts) || (pkt->duration > (*it).framenum))))
153 value =
m_offset[idx].first().newPTS;
172 for (
const int key : std::as_const(
m_keyList))
182 idx.framenum = pkt->duration;
185 LOG(VB_FRAME, LOG_INFO, QString(
"Offset %1 -> %2 (%3) at %4")
188 PtsTime(delta), QString::number(pkt->pos)));
189 for (
const int key : std::as_const(
m_keyList))
194 m_orig[key].push_back(idx);
201 QList<poq_idx_t> *dltaList = &
m_orig[idx];
202 while (!dltaList->isEmpty() &&
203 (pkt->pos >= dltaList->first().pos_pts ||
204 pkt->duration > dltaList->first().framenum))
206 if (dltaList->first().newPTS >= 0)
207 ptsinc((uint64_t *)&origPTS, 300 * dltaList->first().newPTS);
209 ptsdec((uint64_t *)&origPTS, -300 * dltaList->first().newPTS);
210 delta += dltaList->first().newPTS;
211 dltaList->pop_front();
212 LOG(VB_PROCESS, LOG_INFO,
213 QString(
"Moving PTS offset of stream %1 by %2")
214 .arg(idx).arg(
PtsTime(delta)));
221 const char *fmt,
bool norp,
bool fixPTS,
int maxf,
222 bool showprog,
int otype,
void (*update_func)(
float),
224 : m_noRepeat(norp), m_fixPts(fixPTS), m_maxFrames(maxf),
225 m_infile(inf), m_format(fmt)
230 if (deleteMap && !deleteMap->isEmpty())
233 frm_dir_map_t::iterator it = deleteMap->begin();
234 for (; it != deleteMap->end(); ++it)
236 uint64_t mark = it.key();
289 const QFileInfo finfo(inf);
315 for (
auto *af : std::as_const(
m_aFrame))
317 while (!af->isEmpty())
331 {
return (ptr[0] == 0x00) && (ptr[1] == 0x00) && (ptr[2] == 0x01); };
333static void SETBITS(
unsigned char *ptr,
long value,
int num)
335 static int s_sbPos = 0;
336 static unsigned char *s_sbPtr =
nullptr;
344 if (s_sbPtr ==
nullptr)
347 int offset = s_sbPos >> 3;
348 int offset_r = s_sbPos & 0x07;
349 int offset_b = 32 - offset_r;
350 uint32_t mask = ~(((1 << num) - 1) << (offset_b - num));
351 uint32_t sb_long = ntohl(*((uint32_t *) (s_sbPtr + offset)));
352 value = value << (offset_b - num);
353 sb_long = (sb_long & mask) + value;
354 *((uint32_t *)(s_sbPtr + offset)) = htonl(sb_long);
364 *pts1 = (*pts1 + pts2) %
MAX_PTS;
369 int64_t diff = pts1 - pts2;
388 return (pts1 - pts2);
392 return (pts1 +
MAX_PTS - pts2);
396 return (pts1 - (pts2 +
MAX_PTS));
405 int64_t
tmp = pts1 + pts2;
407 return (pts1 + pts2) %
MAX_PTS;
417 if ((uint64_t)(pts1 - pts2) >
MAX_PTS/2ULL)
422 else if (pts1 == pts2)
428 if ((uint64_t)(pts2 - pts1) >
MAX_PTS/2ULL)
438 for (
int i = 0; i < size; i++)
458 return (rx->WaitBuffers());
479 pthread_mutex_lock( &
m_mutex );
494 pthread_cond_signal(&
m_cond);
497 pthread_mutex_unlock(&
m_mutex);
503 static int errorcount = 0;
506 LOG(VB_GENERAL, LOG_ERR,
507 QString(
"thread finished with %1 write errors")
510 pthread_exit(&errorcount);
545 mx.
priv = (
void *)
this;
547 int fd_out = open(
m_outfile.toLocal8Bit().constData(),
552 pthread_cond_signal(&
m_cond);
554 pthread_mutex_unlock(&
m_mutex);
577#define INDEX_BUF (sizeof(index_unit) * 200)
584 if (
m_vFrame.first()->m_mpeg2_seq.height >= 720)
586 LOG(VB_GENERAL, LOG_NOTICE,
"MPEG2fixup::InitReplex(): High Definition input, increasing replex buffers");
593 LOG(VB_GENERAL, LOG_WARNING,
"MPEG2fixup::InitReplex(): Using '--ostream=dvd' with HD video is an invalid combination");
598 uint32_t memsize =
m_vFrame.first()->m_mpeg2_seq.width *
599 m_vFrame.first()->m_mpeg2_seq.height * 10;
611 uint index = it.key();
615 if (avctx ==
nullptr)
618 AVDictionaryEntry *metatag =
619 av_dict_get(
m_inputFC->streams[index]->metadata,
620 "language",
nullptr, 0);
621 char *lang = metatag ? metatag->value : (
char *)
"";
630 case AV_CODEC_ID_MP2:
631 case AV_CODEC_ID_MP3:
635 case AV_CODEC_ID_AC3:
645 26999999ULL) /
m_vFrame.first()->m_mpeg2_seq.frame_period;
652 QString msg = QString(
"Id:%1 %2 V:%3").arg(f->
m_pkt->stream_index)
660 msg += QString(
" %2")
663 LOG(VB_RPLXQUEUE, LOG_INFO, msg);
671 int id = f->
m_pkt->stream_index;
682 iu.gop =
static_cast<uint8_t
>(f->
m_isGop);
686 iu.dts = f->
m_pkt->dts * 300;
694 iu.framesize = f->
m_pkt->size;
699 LOG(VB_GENERAL, LOG_ERR,
"Ringbuffer pointers empty. No stream found");
704 iu.length = f->
m_pkt->size;
705 iu.pts = f->
m_pkt->pts * 300;
729 unsigned int inc_size = 10 * (
unsigned int)f->
m_pkt->size;
730 LOG(VB_GENERAL, LOG_NOTICE,
731 QString(
"Increasing ringbuffer size by %1 to avoid deadlock")
741 LOG(VB_GENERAL, LOG_ERR,
742 "Deadlock detected. One buffer is full when "
743 "the other is empty! Aborting");
756 LOG(VB_GENERAL, LOG_ERR,
757 QString(
"Ring buffer overflow %1").arg(rb->
size));
764 LOG(VB_GENERAL, LOG_ERR,
765 QString(
"Ring buffer overflow %1").arg(rbi->
size));
775 QByteArray ifarray = inputfile.toLocal8Bit();
776 const char *ifname = ifarray.constData();
778 const AVInputFormat *fmt =
nullptr;
781 fmt = av_find_input_format(
type);
784 LOG(VB_GENERAL, LOG_INFO, QString(
"Opening %1").arg(inputfile));
792 int ret = avformat_open_input(&
m_inputFC, ifname, fmt,
nullptr);
795 LOG(VB_GENERAL, LOG_ERR,
796 QString(
"Couldn't open input file, error #%1").arg(ret));
803 fmt = av_find_input_format(
"mpegts-ffmpeg");
806 LOG(VB_PLAYBACK, LOG_INFO,
"Using FFmpeg MPEG-TS demuxer (forced)");
808 ret = avformat_open_input(&
m_inputFC, ifname, fmt,
nullptr);
811 LOG(VB_GENERAL, LOG_ERR,
812 QString(
"Couldn't open input file, error #%1").arg(ret));
824 ret = avformat_find_stream_info(
m_inputFC,
nullptr);
827 LOG(VB_GENERAL, LOG_ERR,
828 QString(
"Couldn't get stream info, error #%1").arg(ret));
838 for (
unsigned int i = 0; i <
m_inputFC->nb_streams; i++)
840 switch (
m_inputFC->streams[i]->codecpar->codec_type)
842 case AVMEDIA_TYPE_VIDEO:
847 case AVMEDIA_TYPE_AUDIO:
849 m_inputFC->streams[i]->codecpar->ch_layout.nb_channels < 2 &&
850 m_inputFC->streams[i]->codecpar->sample_rate < 100000)
852 LOG(VB_GENERAL, LOG_ERR,
853 QString(
"Skipping audio stream: %1").arg(i));
856 if (
m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_AC3 ||
857 m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_MP3 ||
858 m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_MP2)
865 LOG(VB_GENERAL, LOG_ERR,
866 QString(
"Skipping unsupported audio stream: %1")
867 .arg(
m_inputFC->streams[i]->codecpar->codec_id));
871 LOG(VB_GENERAL, LOG_ERR,
872 QString(
"Skipping unsupported codec %1 on stream %2")
873 .arg(
m_inputFC->streams[i]->codecpar->codec_type).arg(i));
893 int oldPktSize = frame1->
m_pkt->size;
895 memmove(frame1->
m_pkt->data + head_size, frame1->
m_pkt->data, oldPktSize);
896 memcpy(frame1->
m_pkt->data, frame2->
m_pkt->data, head_size);
901 static int count = 0;
902 QString
filename = QString(
"hdr%1.yuv").arg(count++);
920 auto *
info = (mpeg2_info_t *)mpeg2_info(dec);
924 while (state != STATE_PICTURE)
926 state = mpeg2_parse(dec);
934 case STATE_SEQUENCE_MODIFIED:
935 case STATE_SEQUENCE_REPEATED:
937 sizeof(mpeg2_sequence_t));
950 sizeof(mpeg2_picture_t));
955 LOG(VB_GENERAL, LOG_WARNING,
956 "Warning: partial frame found!");
960 else if (state == STATE_BUFFER)
963 LOG(VB_GENERAL, LOG_ERR,
964 QString(
"Failed to decode frame. Position was: %1")
968 last_pos = (vf->
m_pkt->size - mpeg2_getpos(dec)) - 4;
973 while (state != STATE_BUFFER)
974 state = mpeg2_parse(dec);
975 if (
info->display_picture)
982 std::array<uint8_t,8>
tmp {0x00, 0x00, 0x01, 0xb2, 0xff, 0xff, 0xff, 0xff};
983 mpeg2_buffer(dec,
tmp.data(),
tmp.data() + 8);
990 QString msg = QString(
"");
992 msg += QString(
"unused:%1 ") .arg(vf->
m_pkt->size - mpeg2_getpos(dec));
996 msg += QString(
"%1x%2 P:%3 ").arg(
info->sequence->width)
997 .arg(
info->sequence->height).arg(
info->sequence->frame_period);
1001 QString gop = QString(
"%1:%2:%3:%4 ")
1002 .arg(
info->gop->hours, 2, 10, QChar(
'0')).arg(
info->gop->minutes, 2, 10, QChar(
'0'))
1003 .arg(
info->gop->seconds, 2, 10, QChar(
'0')).arg(
info->gop->pictures, 3, 10, QChar(
'0'));
1006 if (
info->current_picture)
1008 int ct =
info->current_picture->flags & PIC_MASK_CODING_TYPE;
1009 char coding_type {
'X' };
1010 if (ct == PIC_FLAG_CODING_TYPE_I)
1012 else if (ct == PIC_FLAG_CODING_TYPE_P)
1014 else if (ct == PIC_FLAG_CODING_TYPE_B)
1016 else if (ct == PIC_FLAG_CODING_TYPE_D)
1018 char top_bottom = (
info->current_picture->flags &
1019 PIC_FLAG_TOP_FIELD_FIRST) ?
'T' :
'B';
1020 char progressive = (
info->current_picture->flags &
1021 PIC_FLAG_PROGRESSIVE_FRAME) ?
'P' :
'_';
1022 msg += QString(
"#%1 fl:%2%3%4%5%6 ")
1023 .arg(
info->current_picture->temporal_reference)
1024 .arg(
info->current_picture->nb_fields)
1028 .arg(
info->current_picture->flags >> 4, 0, 16);
1030 msg += QString(
"pos: %1").arg(vf->
m_pkt->pos);
1031 LOG(VB_DECODE, LOG_INFO, msg);
1040 if (tmpFrame ==
nullptr)
1044 for (
const auto & vf : std::as_const(
m_vFrame))
1046 if (vf->m_isSequence)
1060 if (tmpFrame ==
nullptr)
1066 mpeg2dec_t *tmp_decoder = mpeg2_init();
1067 auto *
info = (mpeg2_info_t *)mpeg2_info(tmp_decoder);
1069 while (!
info->display_picture)
1080 mpeg2_close(tmp_decoder);
1085 int fh = open(
filename.toLocal8Bit().constData(),
1086 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1089 LOG(VB_GENERAL, LOG_ERR,
1090 QString(
"Couldn't open file %1: ").arg(
filename) +
ENO);
1095 auto close_fh = [](
const int *fh2) {
close(*fh2); };
1096 std::unique_ptr<int,
decltype(close_fh)>
cleanup { &fh, close_fh };
1098 ssize_t ret =
write(fh,
info->display_fbuf->buf[0],
1099 static_cast<size_t>(
info->sequence->width) *
1100 static_cast<size_t>(
info->sequence->height));
1103 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1107 ret =
write(fh,
info->display_fbuf->buf[1],
1108 static_cast<size_t>(
info->sequence->chroma_width) *
1109 static_cast<size_t>(
info->sequence->chroma_height));
1112 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1116 ret =
write(fh,
info->display_fbuf->buf[2],
1117 static_cast<size_t>(
info->sequence->chroma_width) *
1118 static_cast<size_t>(
info->sequence->chroma_height));
1121 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1129 int fh = open(
filename.toLocal8Bit().constData(),
1130 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1133 LOG(VB_GENERAL, LOG_ERR,
1134 QString(
"Couldn't open file %1: ").arg(
filename) +
ENO);
1138 int ret =
write(fh, data, size);
1140 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1").arg(
filename) +
1147 alignas(16) std::array<uint16_t,64> intra_matrix {};
1148 int64_t savedPts = pkt->pts;
1151 if (!
info->display_fbuf)
1154 int outbuf_size =
info->sequence->width *
info->sequence->height * 2;
1156 if (!fname.isEmpty())
1158 QString tmpstr = fname +
".yuv";
1176 if (pkt->size < outbuf_size)
1177 av_grow_packet(pkt, (outbuf_size - pkt->size));
1190 static constexpr std::array<uint8_t, 64> k_zigzag_scan = {
1191 0, 1, 8, 16, 9, 2, 3, 10,
1192 17, 24, 32, 25, 18, 11, 4, 5,
1193 12, 19, 26, 33, 40, 48, 41, 34,
1194 27, 20, 13, 6, 7, 14, 21, 28,
1195 35, 42, 49, 56, 57, 50, 43, 36,
1196 29, 22, 15, 23, 30, 37, 44, 51,
1197 58, 59, 52, 45, 38, 31, 39, 46,
1198 53, 60, 61, 54, 47, 55, 62, 63
1201 static std::array<uint16_t, 64> k_invZigzagDirect16 = {};
1202 for (
int i = 0; i < 64; i++)
1204 k_invZigzagDirect16[k_zigzag_scan[i]] = i;
1207 static constexpr std::array<uint16_t, 64> k_invZigzagDirect16 = {
1208 0, 1, 5, 6, 14, 15, 27, 28,
1209 2, 4, 7, 13, 16, 26, 29, 42,
1210 3, 8, 12, 17, 25, 30, 41, 43,
1211 9, 11, 18, 24, 31, 40, 44, 53,
1212 10, 19, 23, 32, 39, 45, 52, 54,
1213 20, 22, 33, 38, 46, 51, 55, 60,
1214 21, 34, 37, 47, 50, 56, 59, 61,
1215 35, 36, 48, 49, 57, 58, 62, 63,
1219 for (
int i = 0; i < 64; i++)
1221 intra_matrix[k_invZigzagDirect16[i]] =
m_imgDecoder->quantizer_matrix[0][i];
1224 if (
info->display_picture->nb_fields % 2)
1226 if ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0)
1228 m_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
1232 m_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
1237 if ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0)
1239 m_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
1243 m_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
1247 if ((
info->display_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME) != 0)
1249 m_picture->flags &= ~AV_FRAME_FLAG_INTERLACED;
1253 m_picture->flags |= AV_FRAME_FLAG_INTERLACED;
1256 const AVCodec *out_codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO);
1259 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find MPEG2 encoder");
1263 AVCodecContext *c = avcodec_alloc_context3(
nullptr);
1269 if ((
m_picture->flags & AV_FRAME_FLAG_INTERLACED) != 0)
1270 c->flags |= AV_CODEC_FLAG_INTERLACED_DCT;
1272 c->bit_rate =
info->sequence->byte_rate << 3;
1273 c->bit_rate_tolerance = c->bit_rate >> 2;
1274 c->width =
info->sequence->width;
1275 c->height =
info->sequence->height;
1276 av_reduce(&c->time_base.num, &c->time_base.den,
1277 info->sequence->frame_period, 27000000LL, 100000);
1278 c->pix_fmt = AV_PIX_FMT_YUV420P;
1279 c->max_b_frames = 0;
1280 c->has_b_frames = 0;
1286 c->rc_buffer_size = 0;
1290 if (intra_matrix[0] == 0x08)
1291 c->intra_matrix = intra_matrix.data();
1293 c->qmin = c->qmax = 2;
1300 m_picture->pict_type = AV_PICTURE_TYPE_NONE;
1303 if (avcodec_open2(c, out_codec,
nullptr) < 0)
1305 LOG(VB_GENERAL, LOG_ERR,
"could not open codec");
1310 int ret = avcodec_send_frame(c,
m_picture);
1312 bool flushed =
false;
1316 ret = avcodec_receive_packet(c, pkt);
1319 if (ret == AVERROR(EAGAIN))
1326 ret = avcodec_send_frame(c,
nullptr);
1330 if (ret < 0 || !got_packet)
1332 LOG(VB_GENERAL, LOG_ERR,
1333 QString(
"avcodec_encode_video2 failed (%1)").arg(ret));
1337 if (!fname.isEmpty())
1339 QString ename = fname +
".enc";
1342 QString yname = fname +
".enc.yuv";
1349 int newSize = pkt->size - delta;
1350 pkt->pts = savedPts;
1351 memmove(pkt->data, pkt->data + delta, newSize);
1352 av_shrink_packet(pkt, newSize);
1355 SetRepeat(pkt->data, pkt->size,
info->display_picture->nb_fields,
1356 ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0U));
1358 avcodec_free_context(&c);
1370 static int s_frameCount = 0;
1373 LOG(VB_GENERAL, LOG_ERR,
"No more queue slots!");
1418 pkt->pts = AV_NOPTS_VALUE;
1419 pkt->dts = AV_NOPTS_VALUE;
1420 int ret = av_read_frame(
m_inputFC, pkt);
1431 LOG(VB_GENERAL, LOG_ERR,
1432 "Found end of file without finding any frames");
1433 av_packet_unref(pkt);
1438 if (tmpFrame ==
nullptr)
1440 av_packet_unref(pkt);
1450 if (pkt->stream_index ==
m_vidId ||
1451 m_aFrame.contains(pkt->stream_index))
1454 av_packet_unref(pkt);
1460 float percent_done = 100.0F * pkt->pos /
m_fileSize;
1464 LOG(VB_GENERAL, LOG_INFO, QString(
"%1% complete")
1465 .arg(percent_done, 0,
'f', 1));
1473 LOG(VB_DECODE, LOG_INFO, QString(
"Stream: %1 PTS: %2 DTS: %3 pos: %4")
1474 .arg(pkt->stream_index)
1475 .arg((pkt->pts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->pts))
1476 .arg((pkt->dts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->dts))
1481 if (tmpFrame ==
nullptr)
1483 av_packet_unref(pkt);
1487 switch (
m_inputFC->streams[pkt->stream_index]->codecpar->codec_type)
1489 case AVMEDIA_TYPE_VIDEO:
1491 av_packet_unref(pkt);
1498 case AVMEDIA_TYPE_AUDIO:
1499 if (
m_aFrame.contains(pkt->stream_index))
1501 m_aFrame[pkt->stream_index]->append(tmpFrame);
1505 LOG(VB_GENERAL, LOG_DEBUG,
1506 QString(
"Invalid stream ID %1, ignoring").arg(pkt->stream_index));
1509 av_packet_unref(pkt);
1514 av_packet_unref(pkt);
1522 QMap <int, bool> found;
1523 AVPacket *pkt = av_packet_alloc();
1526 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1534 av_packet_free(&pkt);
1538 if (
m_vidId == pkt->stream_index)
1542 if (
m_vFrame.first()->m_isSequence)
1544 if (pkt->pos !=
m_vFrame.first()->m_pkt->pos)
1547 if (pkt->pts != AV_NOPTS_VALUE ||
1548 pkt->dts != AV_NOPTS_VALUE)
1550 if (pkt->pts == AV_NOPTS_VALUE)
1551 m_vFrame.first()->m_pkt->pts = pkt->dts;
1553 LOG(VB_PROCESS, LOG_INFO,
1554 "Found 1st valid video frame");
1559 LOG(VB_PROCESS, LOG_INFO,
"Dropping V packet");
1570 if (found.contains(it.key()))
1575 while (!af->isEmpty())
1577 int64_t delta =
diff2x33(af->first()->m_pkt->pts,
1579 if (delta < -180000 || delta > 180000)
1584 for (
auto *currFrame : std::as_const(
m_vFrame))
1586 if (currFrame->m_isSequence)
1588 int64_t dlta1 =
diff2x33(af->first()->m_pkt->pts,
1589 currFrame->m_pkt->pts);
1590 if (dlta1 >= -180000 && dlta1 <= 180000)
1592 foundframe = currFrame;
1599 while (foundframe &&
m_vFrame.first() != foundframe)
1605 if (delta < -180000 || delta > 180000)
1607 LOG(VB_PROCESS, LOG_INFO,
1608 QString(
"Dropping A packet from stream %1")
1610 LOG(VB_PROCESS, LOG_INFO, QString(
" A:%1 V:%2")
1611 .arg(
PtsTime(af->first()->m_pkt->pts),
1617 if (delta < 0 && af->count() > 1)
1619 if (
cmp2x33(af->at(1)->m_pkt->pts,
1622 LOG(VB_PROCESS, LOG_INFO,
1623 QString(
"Found useful audio frame from stream %1")
1625 found[it.key()] =
true;
1628 LOG(VB_PROCESS, LOG_INFO,
1629 QString(
"Dropping A packet from stream %1")
1636 LOG(VB_PROCESS, LOG_INFO,
1637 QString(
"Found useful audio frame from stream %1")
1639 found[it.key()] =
true;
1643 if (af->count() == 1)
1647 }
while (found.count() !=
m_aFrame.count());
1649 av_packet_free(&pkt);
1662 uint8_t *end = ptr + size;
1663 uint8_t setmask = 0x00;
1664 uint8_t clrmask = 0xff;
1677 if (
MATCH_HEADER(ptr) && ptr[3] == 0xB5 && (ptr[4] & 0xF0) == 0x80)
1692 for (
const auto & vf : std::as_const(
m_vFrame))
1705 for (
int pos = start_pos; pos < maxPos; pos++)
1746 bool skip_first =
false;
1761 int framePos =
m_vFrame.indexOf(spare);
1769 if (!skip_first && curPos >= framePos &&
info->display_picture &&
1770 (
int)
info->display_picture->temporal_reference >= frameNum)
1782 int tmpFrameNum = frameNum;
1784 if (tmpFrame ==
nullptr)
1790 while (!
info->display_picture ||
1791 (
int)
info->display_picture->temporal_reference < frameNum)
1804 if ((
int)
info->display_picture->temporal_reference > frameNum)
1810 LOG(VB_GENERAL, LOG_NOTICE,
1811 QString(
"Frame %1 > %2. Corruption likely at pos: %3")
1812 .arg(
info->display_picture->temporal_reference)
1813 .arg(frameNum).arg(spare->
m_pkt->pos));
1822 AVPacket *pkt = av_packet_alloc();
1825 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1829 static int ins_count = 0;
1837 av_packet_free(&pkt);
1842 for (
const auto & of : std::as_const(*orderedFrames))
1846 if (spare ==
nullptr)
1848 LOG(VB_GENERAL, LOG_WARNING,
1849 QString(
"ConvertToI skipping undecoded frame #%1").arg(i));
1857 av_packet_ref(pkt, spare->
m_pkt);
1864 fname = QString(
"cnv%1").arg(ins_count++);
1869 av_packet_free(&pkt);
1873 LOG(VB_GENERAL, LOG_INFO,
1874 QString(
"Converting frame #%1 from %2 to I %3")
1878 av_packet_unref(pkt);
1884 m_vFrame.move(headPos, headPos + orderedFrames->count() - 1);
1885 av_packet_free(&pkt);
1890 int64_t ptsIncrement, int64_t initPTS)
1896 AVPacket *pkt = av_packet_alloc();
1899 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1904 if (spare ==
nullptr)
1906 av_packet_free(&pkt);
1910 av_packet_ref(pkt, spare->
m_pkt);
1916 static int ins_count = 0;
1918 (QString(
"ins%1").arg(ins_count++)) : QString());
1923 av_packet_free(&pkt);
1927 LOG(VB_GENERAL, LOG_INFO,
1928 QString(
"Inserting %1 I-Frames after #%2 %3")
1929 .arg((
int)(deltaPTS / ptsIncrement))
1935 index =
m_vFrame.indexOf(spare) + 1;
1942 while (deltaPTS > 0)
1946 pkt->dts = pkt->pts;
1949 if (tmpFrame ==
nullptr)
1954 inc2x33(&pkt->pts, ptsIncrement);
1955 deltaPTS -= ptsIncrement;
1958 av_packet_free(&pkt);
1982 for (
const auto & range : std::as_const(rangelist))
1984 QStringList
tmp = range.split(
" - ");
1988 std::array<bool,2> ok {
false,
false };
1990 long long start =
tmp[0].toLongLong(ok.data());
1991 long long end =
tmp[1].toLongLong(&ok[1]);
2009 if (!rangelist.isEmpty())
2015 if (!mapPtr->isEmpty())
2018 frm_dir_map_t::iterator it = mapPtr->begin();
2019 for (; it != mapPtr->end(); ++it)
2022 msg += QString(
"\n\t\t%1 - %2").arg(start).arg(it.key());
2027 msg += QString(
"\n\t\t%1 - end").arg(start);
2028 LOG(VB_PROCESS, LOG_INFO, msg);
2035 int maxPos = dtsOrder->count() - 1;
2042 for (pos++; pos < maxPos &&
GetFrameTypeT(dtsOrder->at(pos)) ==
'B'; pos++)
2043 Lreorder.append(dtsOrder->at(pos));
2045 Lreorder.append(frame);
2050 int64_t &PTSdiscrep,
int numframes,
bool fix)
const
2055 if (curFrame->
m_pkt->pts == AV_NOPTS_VALUE)
2057 LOG(VB_PROCESS, LOG_INFO,
2058 QString(
"Found frame %1 with missing PTS at %2")
2060 .arg(
PtsTime(origvPTS / 300)));
2062 curFrame->
m_pkt->pts = origvPTS / 300;
2064 PTSdiscrep = AV_NOPTS_VALUE;
2069 if (tmpPTS != PTSdiscrep)
2071 PTSdiscrep = tmpPTS;
2072 LOG(VB_PROCESS, LOG_INFO,
2073 QString(
"Found invalid PTS (off by %1) at %2")
2078 curFrame->
m_pkt->pts = origvPTS / 300;
2082 origvPTS = curFrame->
m_pkt->pts * 300;
2084 ptsinc((uint64_t *)&origvPTS,
2090 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
2091 LOG(VB_GENERAL, LOG_INFO, QString(
"List contains %1 items")
2092 .arg(list->count()));
2094 for (
auto *curFrame : std::as_const(*list))
2096 LOG(VB_GENERAL, LOG_INFO,
2097 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 pos: %6")
2101 .arg(
PtsTime(curFrame->m_pkt->pts),
2102 PtsTime(curFrame->m_pkt->dts),
2103 QString::number(curFrame->m_pkt->pos)));
2105 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
2112 int64_t lastPTS = 0;
2113 int64_t deltaPTS = 0;
2114 std::array<int64_t,N_AUDIO> origaPTS {};
2115 int64_t cutStartPTS = 0;
2116 int64_t cutEndPTS = 0;
2117 uint64_t frame_count = 0;
2118 int new_discard_state = 0;
2119 QMap<int, int> af_dlta_cnt;
2120 QMap<int, int> cutState;
2122 AVPacket *pkt = av_packet_alloc();
2123 AVPacket *lastRealvPkt = av_packet_alloc();
2124 if ((pkt ==
nullptr) || (lastRealvPkt ==
nullptr))
2126 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
2132 av_packet_free(&pkt);
2133 av_packet_free(&lastRealvPkt);
2139 av_packet_free(&pkt);
2140 av_packet_free(&lastRealvPkt);
2146 int64_t initPTS =
m_vFrame.first()->m_pkt->pts;
2148 LOG(VB_GENERAL, LOG_INFO, QString(
"#%1 PTS:%2 Delta: 0.0ms queue: %3")
2155 deltaPTS =
diff2x33(
m_vFrame.first()->m_pkt->pts, af->first()->m_pkt->pts);
2156 LOG(VB_GENERAL, LOG_INFO,
2157 QString(
"#%1 PTS:%2 Delta: %3ms queue: %4")
2158 .arg(it.key()) .arg(
PtsTime(af->first()->m_pkt->pts))
2159 .arg(1000.0*deltaPTS / 90000.0).arg(af->count()));
2161 if (
cmp2x33(af->first()->m_pkt->pts, initPTS) < 0)
2162 initPTS = af->first()->m_pkt->pts;
2169 LOG(VB_PROCESS, LOG_INFO,
2170 QString(
"ptsIncrement: %1 Frame #: %2 PTS-adjust: %3")
2177 int64_t expectedvPTS = 300 * (
udiff2x33(
m_vFrame.first()->m_pkt->pts, initPTS) -
2183 cutStartPTS = origvPTS / 300;
2189 origaPTS[it.key()] = af->first()->m_pkt->pts * 300;
2191 af_dlta_cnt[it.key()] = 0;
2192 cutState[it.key()] =
static_cast<int>(
m_discard);
2206 av_packet_free(&pkt);
2207 av_packet_free(&lastRealvPkt);
2222 LOG(VB_GENERAL, LOG_WARNING,
2223 QString(
"Problem: Frame %1 (type %2) doesn't contain "
2230 LOG(VB_GENERAL, LOG_WARNING,
2231 QString(
"WARNING - Unsupported FPS change from %1 to %2")
2233 .arg(27000000.0 / seqFrame->
m_mpeg2_seq.frame_period,
2237 for (
int frame_pos = 0; frame_pos <
m_vFrame.count() - 1;)
2239 bool ptsorder_eq_dtsorder =
false;
2240 int64_t PTSdiscrep = 0;
2247 LOG(VB_GENERAL, LOG_ERR,
2248 QString(
"expectedPTS != expectedDTS + ptsIncrement"));
2249 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2250 .arg(
PtsTime(expectedvPTS / 300),
2253 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2257 av_packet_free(&pkt);
2258 av_packet_free(&lastRealvPkt);
2266 for (
auto *curFrame : std::as_const(Lreorder))
2280 int count = Lreorder.count();
2286 av_packet_free(&pkt);
2287 av_packet_free(&lastRealvPkt);
2294 int64_t tmp_origvPTS = origvPTS;
2298 (frame_pos + count + 1) <
m_vFrame.count())
2303 for (
auto *curFrame : std::as_const(tmpReorder))
2305 int64_t tmpPTSdiscrep = 0;
2307 tmpPTSdiscrep, numframes,
false);
2315 if (tmpPTSdiscrep != AV_NOPTS_VALUE &&
2316 tmpPTSdiscrep != PTSdiscrep)
2317 PTSdiscrep = tmpPTSdiscrep;
2319 count += tmpReorder.count();
2332 for (
int curIndex = 0; curIndex < Lreorder.count(); curIndex++)
2334 MPEG2frame *curFrame = Lreorder.at(curIndex);
2337 if (
m_saveMap.begin().key() <= frame_count)
2341 LOG(VB_GENERAL, LOG_INFO,
2342 QString(
"Saving frame #%1") .arg(frame_count));
2347 av_packet_free(&pkt);
2348 av_packet_free(&lastRealvPkt);
2352 WriteFrame(QString(
"save%1.yuv").arg(frame_count),
2359 new_discard_state =
m_delMap.begin().value();
2360 LOG(VB_GENERAL, LOG_INFO,
2361 QString(
"Del map found %1 at %2 (%3)")
2362 .arg(new_discard_state) .arg(frame_count)
2366 markedFrameP = curFrame;
2368 if (!new_discard_state)
2370 cutEndPTS = markedFrameP->
m_pkt->pts;
2372 diff2x33(cutEndPTS, expectedvPTS / 300),
2384 cutState[it3.key()] = 1;
2392 (!new_discard_state &&
2397 av_packet_free(&pkt);
2398 av_packet_free(&lastRealvPkt);
2401 ptsorder_eq_dtsorder =
true;
2403 else if (!new_discard_state &&
2406 m_vFrame.move(frame_pos, frame_pos + curIndex);
2407 ptsorder_eq_dtsorder =
true;
2411 markedFrame =
m_vFrame.at(frame_pos + curIndex);
2413 if (!new_discard_state)
2424 if (!Lreorder.isEmpty())
2426 av_packet_unref(lastRealvPkt);
2427 av_packet_ref(lastRealvPkt, Lreorder.last()->m_pkt);
2432 int64_t dtsExtra = 0;
2434 for (
auto *curFrame : std::as_const(Lreorder))
2438 if (curFrame != markedFrameP)
2441 markedFrameP =
nullptr;
2444 dec2x33(&curFrame->m_pkt->pts,
2446 deltaPTS =
diff2x33(curFrame->m_pkt->pts,
2447 expectedvPTS / 300);
2449 if (deltaPTS < -2 || deltaPTS > 2)
2451 LOG(VB_PROCESS, LOG_INFO,
2452 QString(
"PTS discrepancy: %1 != %2 on "
2454 .arg(curFrame->m_pkt->pts)
2455 .arg(expectedvPTS / 300)
2466 curFrame->m_pkt->pts = expectedvPTS / 300;
2470 LOG(VB_GENERAL, LOG_NOTICE,
2471 QString(
"Need to insert %1 frames > max "
2472 "allowed: %2. Assuming bad PTS")
2475 curFrame->m_pkt->pts = expectedvPTS / 300;
2479 lastPTS = expectedvPTS;
2483 if (curFrame == markedFrameP && new_discard_state)
2489 if (ptsorder_eq_dtsorder)
2502 m_vFrame.at(frame_pos)->m_pkt->pts = lastPTS / 300;
2508 av_packet_free(&pkt);
2509 av_packet_free(&lastRealvPkt);
2513 for (
int index = frame_pos + Lreorder.count();
2514 ret && index <
m_vFrame.count(); index++, --ret)
2516 lastPTS = expectedvPTS;
2519 Lreorder.append(
m_vFrame.at(index));
2526 for (
int i = 0; i < Lreorder.count(); i++, frame_pos++)
2531 if (curFrame != markedFrame)
2535 markedFrame =
nullptr;
2539 if (curFrame ==
nullptr)
2541 curFrame->
m_pkt->dts = (expectedDTS / 300);
2544 curFrame->
m_pkt->pts = (expectedDTS / 300);
2547 ((!ptsorder_eq_dtsorder && i == 0) ? 2 :
2549 LOG(VB_FRAME, LOG_INFO,
2550 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 "
2557 QString::number(curFrame->
m_pkt->pos)));
2560 av_packet_free(&pkt);
2561 av_packet_free(&lastRealvPkt);
2565 if (curFrame == markedFrame)
2567 markedFrame =
nullptr;
2572 expectedDTS += dtsExtra;
2576 frame_pos += Lreorder.count();
2580 PTSdiscrep), lastRealvPkt);
2584 cutEndPTS = lastRealvPkt->pts;
2597 bool backwardsPTS =
false;
2599 while (!af->isEmpty())
2608 if (CC->sample_rate == 0 || !CPC || CPC->duration == 0)
2623 90000LL * (int64_t)CPC->duration / CC->sample_rate;
2626 af->first()->m_pkt) < 0)
2628 backwardsPTS =
true;
2629 af_dlta_cnt[it.key()] = 0;
2632 int64_t tmpPTS =
diff2x33(af->first()->m_pkt->pts,
2633 origaPTS[it.key()] / 300);
2635 if (tmpPTS < -incPTS)
2638 LOG(VB_PROCESS, LOG_INFO,
2639 QString(
"Aud discard: PTS %1 < %2")
2640 .arg(
PtsTime(af->first()->m_pkt->pts))
2641 .arg(
PtsTime(origaPTS[it.key()] / 300)));
2644 af_dlta_cnt[it.key()] = 0;
2650 LOG(VB_PROCESS, LOG_INFO,
2651 QString(
"Found invalid audio PTS (off by %1) at %2")
2653 PtsTime(origaPTS[it.key()] / 300)));
2654 if (backwardsPTS && tmpPTS < 90000LL)
2657 LOG(VB_PROCESS, LOG_INFO,
2658 "Fixing missing audio frames");
2659 ptsinc((uint64_t *)&origaPTS[it.key()], 300 * tmpPTS);
2660 backwardsPTS =
false;
2662 else if (tmpPTS < 90000LL * 4)
2664 if (af_dlta_cnt[it.key()] >= 20)
2670 ptsinc((uint64_t *)&origaPTS[it.key()],
2672 af_dlta_cnt[it.key()] = 0;
2676 af_dlta_cnt[it.key()]++;
2679 af->first()->m_pkt->pts = origaPTS[it.key()] / 300;
2681 else if (tmpPTS > incPTS)
2684 backwardsPTS =
false;
2685 af_dlta_cnt[it.key()] = 0;
2689 backwardsPTS =
false;
2690 af_dlta_cnt[it.key()] = 0;
2693 int64_t nextPTS =
add2x33(af->first()->m_pkt->pts,
2694 90000LL * (int64_t)CPC->duration / CC->sample_rate);
2696 if ((cutState[it.key()] == 1 &&
2697 cmp2x33(nextPTS, cutStartPTS) > 0) ||
2698 (cutState[it.key()] == 2 &&
2699 cmp2x33(af->first()->m_pkt->pts, cutEndPTS) < 0))
2702 LOG(VB_PROCESS, LOG_INFO,
2703 QString(
"Aud in cutpoint: %1 > %2 && %3 < %4")
2705 .arg(
PtsTime(af->first()->m_pkt->pts))
2709 cutState[it.key()] = 2;
2710 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2714 int64_t deltaPTS2 = poq.
Get(it.key(), af->first()->m_pkt);
2716 if (
udiff2x33(nextPTS, deltaPTS2) * 300 > expectedDTS &&
2717 cutState[it.key()] != 1)
2720 LOG(VB_PROCESS, LOG_INFO, QString(
"Aud not ready: %1 > %2")
2722 .arg(
PtsTime(expectedDTS / 300)));
2727 if (cutState[it.key()] == 2)
2728 cutState[it.key()] = 0;
2730 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2732 dec2x33(&af->first()->m_pkt->pts, deltaPTS2);
2735 expectedPTS[it.key()] =
udiff2x33(nextPTS, initPTS);
2736 write_audio(lApkt_tail->m_pkt, initPTS);
2738 LOG(VB_FRAME, LOG_INFO, QString(
"AUD #%1: pts: %2 pos: %3")
2740 .arg(
PtsTime(af->first()->m_pkt->pts))
2741 .arg(af->first()->m_pkt->pos));
2744 av_packet_free(&pkt);
2745 av_packet_free(&lastRealvPkt);
2758 void *errors =
nullptr;
2760 if (*(
int *)errors) {
2761 LOG(VB_GENERAL, LOG_ERR,
2762 QString(
"joined thread failed with %1 write errors")
2763 .arg(*(
int *)errors));
2767 av_packet_free(&pkt);
2768 av_packet_free(&lastRealvPkt);
2779 fprintf(
stderr,
"%s usage:\n", s);
2780 fprintf(
stderr,
"\t--infile <file> -i <file> : Input mpg file\n");
2781 fprintf(
stderr,
"\t--outfile <file> -o <file> : Output mpg file\n");
2782 fprintf(
stderr,
"\t--dbg_lvl # -d # : Debug level\n");
2783 fprintf(
stderr,
"\t--maxframes # -m # : Max frames to insert at once (default=10)\n");
2784 fprintf(
stderr,
"\t--cutlist \"start - end\" -c : Apply a cutlist. Specify on e'-c' per cut\n");
2785 fprintf(
stderr,
"\t--no3to2 -t : Remove 3:2 pullup\n");
2786 fprintf(
stderr,
"\t--fixup -f : make PTS continuous\n");
2787 fprintf(
stderr,
"\t--ostream <dvd|ps> -e : Output stream type (defaults to ps)\n");
2788 fprintf(
stderr,
"\t--showprogress -p : show progress\n");
2789 fprintf(
stderr,
"\t--help -h : This screen\n");
2793int main(
int argc,
char **argv)
2795 QStringList cutlist;
2796 QStringList savelist;
2797 char *infile =
nullptr, *outfile =
nullptr, *format =
nullptr;
2798 int no_repeat = 0, fix_PTS = 0, max_frames = 20, otype =
REPLEX_MPEG2;
2799 bool showprogress = 0;
2800 const struct option long_options[] =
2802 {
"infile", required_argument,
nullptr,
'i'},
2803 {
"outfile", required_argument,
nullptr,
'o'},
2804 {
"format", required_argument,
nullptr,
'r'},
2805 {
"dbg_lvl", required_argument,
nullptr,
'd'},
2806 {
"cutlist", required_argument,
nullptr,
'c'},
2807 {
"saveframe", required_argument,
nullptr,
's'},
2808 {
"ostream", required_argument,
nullptr,
'e'},
2809 {
"no3to2", no_argument,
nullptr,
't'},
2810 {
"fixup", no_argument,
nullptr,
'f'},
2811 {
"showprogress", no_argument,
nullptr,
'p'},
2812 {
"help", no_argument ,
nullptr,
'h'},
2818 int option_index = 0;
2820 c = getopt_long (argc, argv,
"i:o:d:r:m:c:s:e:tfph",
2821 long_options, &option_index);
2842 if (strlen(optarg) == 3 && strncmp(optarg,
"dvd", 3) == 0)
2851 max_frames = atoi(optarg);
2855 cutlist.append(optarg);
2866 savelist.append(optarg);
2870 showprogress =
true;
2882 if (infile ==
nullptr || outfile ==
nullptr)
2885 MPEG2fixup m2f(infile, outfile,
nullptr, format,
2886 no_repeat, fix_PTS, max_frames,
2887 showprogress, otype);
2889 if (cutlist.count())
2891 if (savelist.count())
2901 LOG(VB_GENERAL, LOG_INFO,
"Generating Keyframe Index");
2912 LOG(VB_GENERAL, LOG_INFO,
"Seek tables are not required for MKV");
2916 AVPacket *pkt = av_packet_alloc();
2919 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
2923 uint64_t totalDuration = 0;
2924 while (av_read_frame(
m_inputFC, pkt) >= 0)
2926 if (pkt->stream_index ==
m_vidId)
2928 if (pkt->flags & AV_PKT_FLAG_KEY)
2930 posMap[count] = pkt->pos;
2931 durMap[count] = totalDuration;
2940 av_q2d(
m_inputFC->streams[pkt->stream_index]->time_base) *
2941 pkt->duration * 1000;
2944 av_packet_unref(pkt);
2948 av_packet_free(&pkt);
2952 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.
bool GetBoolSetting(const QString &key, bool defaultval=false)
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
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
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)
void ring_destroy(ringbuffer *rbuf)
int ring_reinit(ringbuffer *rbuf, int size)
int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
int ring_init(ringbuffer *rbuf, int size)
static unsigned int ring_avail(ringbuffer *rbuf)
static unsigned int ring_free(ringbuffer *rbuf)