17#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
18#include <QtSystemDetection>
26#include "libmythbase/mythconfig.h"
34#include "libavutil/cpu.h"
35#include "libmythmpeg2/attributes.h"
36#include "libmythmpeg2/mpeg2.h"
37#include "libmythmpeg2/mpeg2_internal.h"
46#include <netinet/in.h>
54 int level,
const char* fmt, va_list vl)
56 static QString s_fullLine(
"");
58 if (level > AV_LOG_INFO)
61 s_fullLine += QString::vasprintf(fmt, vl);
62 if (s_fullLine.endsWith(
"\n"))
65 LOG(VB_GENERAL, LOG_INFO, s_fullLine);
66 s_fullLine = QString(
"");
78 return QString(
"%1%2:%3:%4.%5")
79 .arg(is_neg ?
"-" :
"")
80 .arg((
uint)(
pts / 90000.) / 3600, 2, 10, QChar(
'0'))
81 .arg(((
uint)(
pts / 90000.) % 3600) / 60, 2, 10, QChar(
'0'))
82 .arg(((
uint)(
pts / 90000.) % 3600) % 60, 2, 10, QChar(
'0'))
83 .arg(((((
uint)(
pts / 90.) % 3600000) % 60000) % 1000), 3, 10, QChar(
'0'));
87 m_pkt(av_packet_alloc()),
88 m_mpeg2_seq(), m_mpeg2_gop(), m_mpeg2_pic()
90 av_new_packet(
m_pkt, size);
95 av_packet_free(&
m_pkt);
100 if (
m_pkt->size < size)
102 int oldSize =
m_pkt->size;
103 if ((av_grow_packet(
m_pkt, size -
m_pkt->size) < 0) ||
m_pkt->size < size)
105 LOG(VB_GENERAL, LOG_CRIT, QString(
"MPEG2frame::ensure_size(): "
106 "Failed to grow packet size "
107 "from %1 to %2, result was %3")
108 .arg(oldSize).arg(size)
117 av_packet_unref(
m_pkt);
118 av_packet_ref(
m_pkt, newpkt);
122 : m_keyList(
std::move(keys)),
128 idx.newPTS = initPTS;
133 for (
const int key : std::as_const(
m_keyList))
139 QList<poq_idx_t>::iterator it;
140 int64_t value =
m_offset[idx].first().newPTS;
148 while (
m_offset[idx].count() > 1 && !done)
151 if (((
static_cast<int>((*it).type) == 0) &&
152 (pkt->pts >= (*it).pos_pts) ) ||
154 ((pkt->pos >= (*it).pos_pts) || (pkt->duration > (*it).framenum))))
157 value =
m_offset[idx].first().newPTS;
176 for (
const int key : std::as_const(
m_keyList))
186 idx.framenum = pkt->duration;
189 LOG(VB_FRAME, LOG_INFO, QString(
"Offset %1 -> %2 (%3) at %4")
192 PtsTime(delta), QString::number(pkt->pos)));
193 for (
const int key : std::as_const(
m_keyList))
198 m_orig[key].push_back(idx);
205 QList<poq_idx_t> *dltaList = &
m_orig[idx];
206 while (!dltaList->isEmpty() &&
207 (pkt->pos >= dltaList->first().pos_pts ||
208 pkt->duration > dltaList->first().framenum))
210 if (dltaList->first().newPTS >= 0)
211 ptsinc((uint64_t *)&origPTS, 300 * dltaList->first().newPTS);
213 ptsdec((uint64_t *)&origPTS, -300 * dltaList->first().newPTS);
214 delta += dltaList->first().newPTS;
215 dltaList->pop_front();
216 LOG(VB_PROCESS, LOG_INFO,
217 QString(
"Moving PTS offset of stream %1 by %2")
218 .arg(idx).arg(
PtsTime(delta)));
225 const char *fmt,
bool norp,
bool fixPTS,
int maxf,
226 bool showprog,
int otype,
void (*update_func)(
float),
228 : m_noRepeat(norp), m_fixPts(fixPTS), m_maxFrames(maxf),
229 m_infile(inf), m_format(fmt)
234 if (deleteMap && !deleteMap->isEmpty())
237 frm_dir_map_t::iterator it = deleteMap->begin();
238 for (; it != deleteMap->end(); ++it)
240 uint64_t mark = it.key();
293 const QFileInfo finfo(inf);
319 for (
auto *af : std::as_const(
m_aFrame))
321 while (!af->isEmpty())
335 {
return (ptr[0] == 0x00) && (ptr[1] == 0x00) && (ptr[2] == 0x01); };
337static void SETBITS(
unsigned char *ptr,
long value,
int num)
339 static int s_sbPos = 0;
340 static unsigned char *s_sbPtr =
nullptr;
348 if (s_sbPtr ==
nullptr)
351 int offset = s_sbPos >> 3;
352 int offset_r = s_sbPos & 0x07;
353 int offset_b = 32 - offset_r;
354 uint32_t mask = ~(((1 << num) - 1) << (offset_b - num));
355 uint32_t sb_long = ntohl(*((uint32_t *) (s_sbPtr + offset)));
356 value = value << (offset_b - num);
357 sb_long = (sb_long & mask) + value;
358 *((uint32_t *)(s_sbPtr + offset)) = htonl(sb_long);
368 *pts1 = (*pts1 + pts2) %
MAX_PTS;
373 int64_t diff = pts1 - pts2;
392 return (pts1 - pts2);
396 return (pts1 +
MAX_PTS - pts2);
400 return (pts1 - (pts2 +
MAX_PTS));
409 int64_t
tmp = pts1 + pts2;
411 return (pts1 + pts2) %
MAX_PTS;
421 if ((uint64_t)(pts1 - pts2) >
MAX_PTS/2ULL)
426 else if (pts1 == pts2)
432 if ((uint64_t)(pts2 - pts1) >
MAX_PTS/2ULL)
442 for (
int i = 0; i < size; i++)
462 return (rx->WaitBuffers());
483 pthread_mutex_lock( &
m_mutex );
498 pthread_cond_signal(&
m_cond);
501 pthread_mutex_unlock(&
m_mutex);
507 static int errorcount = 0;
510 LOG(VB_GENERAL, LOG_ERR,
511 QString(
"thread finished with %1 write errors")
514 pthread_exit(&errorcount);
549 mx.
priv = (
void *)
this;
551 int fd_out = open(
m_outfile.toLocal8Bit().constData(),
556 pthread_cond_signal(&
m_cond);
558 pthread_mutex_unlock(&
m_mutex);
581#define INDEX_BUF (sizeof(index_unit) * 200)
588 if (
m_vFrame.first()->m_mpeg2_seq.height >= 720)
590 LOG(VB_GENERAL, LOG_NOTICE,
"MPEG2fixup::InitReplex(): High Definition input, increasing replex buffers");
597 LOG(VB_GENERAL, LOG_WARNING,
"MPEG2fixup::InitReplex(): Using '--ostream=dvd' with HD video is an invalid combination");
602 uint32_t memsize =
m_vFrame.first()->m_mpeg2_seq.width *
603 m_vFrame.first()->m_mpeg2_seq.height * 10;
615 uint index = it.key();
619 if (avctx ==
nullptr)
622 AVDictionaryEntry *metatag =
623 av_dict_get(
m_inputFC->streams[index]->metadata,
624 "language",
nullptr, 0);
625 char *lang = metatag ? metatag->value : (
char *)
"";
634 case AV_CODEC_ID_MP2:
635 case AV_CODEC_ID_MP3:
639 case AV_CODEC_ID_AC3:
649 26999999ULL) /
m_vFrame.first()->m_mpeg2_seq.frame_period;
656 QString msg = QString(
"Id:%1 %2 V:%3").arg(f->
m_pkt->stream_index)
664 msg += QString(
" %2")
667 LOG(VB_RPLXQUEUE, LOG_INFO, msg);
675 int id = f->
m_pkt->stream_index;
686 iu.gop =
static_cast<uint8_t
>(f->
m_isGop);
690 iu.dts = f->
m_pkt->dts * 300;
698 iu.framesize = f->
m_pkt->size;
703 LOG(VB_GENERAL, LOG_ERR,
"Ringbuffer pointers empty. No stream found");
708 iu.length = f->
m_pkt->size;
709 iu.pts = f->
m_pkt->pts * 300;
733 unsigned int inc_size = 10 * (
unsigned int)f->
m_pkt->size;
734 LOG(VB_GENERAL, LOG_NOTICE,
735 QString(
"Increasing ringbuffer size by %1 to avoid deadlock")
745 LOG(VB_GENERAL, LOG_ERR,
746 "Deadlock detected. One buffer is full when "
747 "the other is empty! Aborting");
760 LOG(VB_GENERAL, LOG_ERR,
761 QString(
"Ring buffer overflow %1").arg(rb->
size));
768 LOG(VB_GENERAL, LOG_ERR,
769 QString(
"Ring buffer overflow %1").arg(rbi->
size));
779 QByteArray ifarray = inputfile.toLocal8Bit();
780 const char *ifname = ifarray.constData();
782 const AVInputFormat *fmt =
nullptr;
785 fmt = av_find_input_format(
type);
788 LOG(VB_GENERAL, LOG_INFO, QString(
"Opening %1").arg(inputfile));
796 int ret = avformat_open_input(&
m_inputFC, ifname, fmt,
nullptr);
799 LOG(VB_GENERAL, LOG_ERR,
800 QString(
"Couldn't open input file, error #%1").arg(ret));
807 fmt = av_find_input_format(
"mpegts-ffmpeg");
810 LOG(VB_PLAYBACK, LOG_INFO,
"Using FFmpeg MPEG-TS demuxer (forced)");
812 ret = avformat_open_input(&
m_inputFC, ifname, fmt,
nullptr);
815 LOG(VB_GENERAL, LOG_ERR,
816 QString(
"Couldn't open input file, error #%1").arg(ret));
828 ret = avformat_find_stream_info(
m_inputFC,
nullptr);
831 LOG(VB_GENERAL, LOG_ERR,
832 QString(
"Couldn't get stream info, error #%1").arg(ret));
842 for (
unsigned int i = 0; i <
m_inputFC->nb_streams; i++)
844 switch (
m_inputFC->streams[i]->codecpar->codec_type)
846 case AVMEDIA_TYPE_VIDEO:
851 case AVMEDIA_TYPE_AUDIO:
853 m_inputFC->streams[i]->codecpar->ch_layout.nb_channels < 2 &&
854 m_inputFC->streams[i]->codecpar->sample_rate < 100000)
856 LOG(VB_GENERAL, LOG_ERR,
857 QString(
"Skipping audio stream: %1").arg(i));
860 if (
m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_AC3 ||
861 m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_MP3 ||
862 m_inputFC->streams[i]->codecpar->codec_id == AV_CODEC_ID_MP2)
869 LOG(VB_GENERAL, LOG_ERR,
870 QString(
"Skipping unsupported audio stream: %1")
871 .arg(
m_inputFC->streams[i]->codecpar->codec_id));
875 LOG(VB_GENERAL, LOG_ERR,
876 QString(
"Skipping unsupported codec %1 on stream %2")
877 .arg(
m_inputFC->streams[i]->codecpar->codec_type).arg(i));
897 int oldPktSize = frame1->
m_pkt->size;
899 memmove(frame1->
m_pkt->data + head_size, frame1->
m_pkt->data, oldPktSize);
900 memcpy(frame1->
m_pkt->data, frame2->
m_pkt->data, head_size);
905 static int count = 0;
906 QString
filename = QString(
"hdr%1.yuv").arg(count++);
924 auto *
info = (mpeg2_info_t *)mpeg2_info(dec);
928 while (state != STATE_PICTURE)
930 state = mpeg2_parse(dec);
938 case STATE_SEQUENCE_MODIFIED:
939 case STATE_SEQUENCE_REPEATED:
941 sizeof(mpeg2_sequence_t));
954 sizeof(mpeg2_picture_t));
959 LOG(VB_GENERAL, LOG_WARNING,
960 "Warning: partial frame found!");
964 else if (state == STATE_BUFFER)
967 LOG(VB_GENERAL, LOG_ERR,
968 QString(
"Failed to decode frame. Position was: %1")
972 last_pos = (vf->
m_pkt->size - mpeg2_getpos(dec)) - 4;
977 while (state != STATE_BUFFER)
978 state = mpeg2_parse(dec);
979 if (
info->display_picture)
986 std::array<uint8_t,8>
tmp {0x00, 0x00, 0x01, 0xb2, 0xff, 0xff, 0xff, 0xff};
987 mpeg2_buffer(dec,
tmp.data(),
tmp.data() + 8);
994 QString msg = QString(
"");
996 msg += QString(
"unused:%1 ") .arg(vf->
m_pkt->size - mpeg2_getpos(dec));
1000 msg += QString(
"%1x%2 P:%3 ").arg(
info->sequence->width)
1001 .arg(
info->sequence->height).arg(
info->sequence->frame_period);
1005 QString gop = QString(
"%1:%2:%3:%4 ")
1006 .arg(
info->gop->hours, 2, 10, QChar(
'0')).arg(
info->gop->minutes, 2, 10, QChar(
'0'))
1007 .arg(
info->gop->seconds, 2, 10, QChar(
'0')).arg(
info->gop->pictures, 3, 10, QChar(
'0'));
1010 if (
info->current_picture)
1012 int ct =
info->current_picture->flags & PIC_MASK_CODING_TYPE;
1013 char coding_type {
'X' };
1014 if (ct == PIC_FLAG_CODING_TYPE_I)
1016 else if (ct == PIC_FLAG_CODING_TYPE_P)
1018 else if (ct == PIC_FLAG_CODING_TYPE_B)
1020 else if (ct == PIC_FLAG_CODING_TYPE_D)
1022 char top_bottom = (
info->current_picture->flags &
1023 PIC_FLAG_TOP_FIELD_FIRST) ?
'T' :
'B';
1024 char progressive = (
info->current_picture->flags &
1025 PIC_FLAG_PROGRESSIVE_FRAME) ?
'P' :
'_';
1026 msg += QString(
"#%1 fl:%2%3%4%5%6 ")
1027 .arg(
info->current_picture->temporal_reference)
1028 .arg(
info->current_picture->nb_fields)
1032 .arg(
info->current_picture->flags >> 4, 0, 16);
1034 msg += QString(
"pos: %1").arg(vf->
m_pkt->pos);
1035 LOG(VB_DECODE, LOG_INFO, msg);
1044 if (tmpFrame ==
nullptr)
1048 for (
const auto & vf : std::as_const(
m_vFrame))
1050 if (vf->m_isSequence)
1064 if (tmpFrame ==
nullptr)
1070 mpeg2dec_t *tmp_decoder = mpeg2_init();
1071 auto *
info = (mpeg2_info_t *)mpeg2_info(tmp_decoder);
1073 while (!
info->display_picture)
1084 mpeg2_close(tmp_decoder);
1089 int fh = open(
filename.toLocal8Bit().constData(),
1090 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1093 LOG(VB_GENERAL, LOG_ERR,
1094 QString(
"Couldn't open file %1: ").arg(
filename) +
ENO);
1099 auto close_fh = [](
const int *fh2) {
close(*fh2); };
1100 std::unique_ptr<int,
decltype(close_fh)>
cleanup { &fh, close_fh };
1102 ssize_t ret =
write(fh,
info->display_fbuf->buf[0],
1103 static_cast<size_t>(
info->sequence->width) *
1104 static_cast<size_t>(
info->sequence->height));
1107 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1111 ret =
write(fh,
info->display_fbuf->buf[1],
1112 static_cast<size_t>(
info->sequence->chroma_width) *
1113 static_cast<size_t>(
info->sequence->chroma_height));
1116 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1120 ret =
write(fh,
info->display_fbuf->buf[2],
1121 static_cast<size_t>(
info->sequence->chroma_width) *
1122 static_cast<size_t>(
info->sequence->chroma_height));
1125 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(
filename) +
1133 int fh = open(
filename.toLocal8Bit().constData(),
1134 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1137 LOG(VB_GENERAL, LOG_ERR,
1138 QString(
"Couldn't open file %1: ").arg(
filename) +
ENO);
1142 int ret =
write(fh, data, size);
1144 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1").arg(
filename) +
1151 alignas(16) std::array<uint16_t,64> intra_matrix {};
1152 int64_t savedPts = pkt->pts;
1155 if (!
info->display_fbuf)
1158 int outbuf_size =
info->sequence->width *
info->sequence->height * 2;
1160 if (!fname.isEmpty())
1162 QString tmpstr = fname +
".yuv";
1180 if (pkt->size < outbuf_size)
1181 av_grow_packet(pkt, (outbuf_size - pkt->size));
1194 static constexpr std::array<uint8_t, 64> k_zigzag_scan = {
1195 0, 1, 8, 16, 9, 2, 3, 10,
1196 17, 24, 32, 25, 18, 11, 4, 5,
1197 12, 19, 26, 33, 40, 48, 41, 34,
1198 27, 20, 13, 6, 7, 14, 21, 28,
1199 35, 42, 49, 56, 57, 50, 43, 36,
1200 29, 22, 15, 23, 30, 37, 44, 51,
1201 58, 59, 52, 45, 38, 31, 39, 46,
1202 53, 60, 61, 54, 47, 55, 62, 63
1205 static std::array<uint16_t, 64> k_invZigzagDirect16 = {};
1206 for (
int i = 0; i < 64; i++)
1208 k_invZigzagDirect16[k_zigzag_scan[i]] = i;
1211 static constexpr std::array<uint16_t, 64> k_invZigzagDirect16 = {
1212 0, 1, 5, 6, 14, 15, 27, 28,
1213 2, 4, 7, 13, 16, 26, 29, 42,
1214 3, 8, 12, 17, 25, 30, 41, 43,
1215 9, 11, 18, 24, 31, 40, 44, 53,
1216 10, 19, 23, 32, 39, 45, 52, 54,
1217 20, 22, 33, 38, 46, 51, 55, 60,
1218 21, 34, 37, 47, 50, 56, 59, 61,
1219 35, 36, 48, 49, 57, 58, 62, 63,
1223 for (
int i = 0; i < 64; i++)
1225 intra_matrix[k_invZigzagDirect16[i]] =
m_imgDecoder->quantizer_matrix[0][i];
1228 if (
info->display_picture->nb_fields % 2)
1230 if ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0)
1232 m_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
1236 m_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
1241 if ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0)
1243 m_picture->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
1247 m_picture->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
1251 if ((
info->display_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME) != 0)
1253 m_picture->flags &= ~AV_FRAME_FLAG_INTERLACED;
1257 m_picture->flags |= AV_FRAME_FLAG_INTERLACED;
1260 const AVCodec *out_codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO);
1263 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find MPEG2 encoder");
1267 AVCodecContext *c = avcodec_alloc_context3(
nullptr);
1273 if ((
m_picture->flags & AV_FRAME_FLAG_INTERLACED) != 0)
1274 c->flags |= AV_CODEC_FLAG_INTERLACED_DCT;
1276 c->bit_rate =
info->sequence->byte_rate << 3;
1277 c->bit_rate_tolerance = c->bit_rate >> 2;
1278 c->width =
info->sequence->width;
1279 c->height =
info->sequence->height;
1280 av_reduce(&c->time_base.num, &c->time_base.den,
1281 info->sequence->frame_period, 27000000LL, 100000);
1282 c->pix_fmt = AV_PIX_FMT_YUV420P;
1283 c->max_b_frames = 0;
1284 c->has_b_frames = 0;
1290 c->rc_buffer_size = 0;
1294 if (intra_matrix[0] == 0x08)
1295 c->intra_matrix = intra_matrix.data();
1297 c->qmin = c->qmax = 2;
1304 m_picture->pict_type = AV_PICTURE_TYPE_NONE;
1307 if (avcodec_open2(c, out_codec,
nullptr) < 0)
1309 LOG(VB_GENERAL, LOG_ERR,
"could not open codec");
1314 int ret = avcodec_send_frame(c,
m_picture);
1316 bool flushed =
false;
1320 ret = avcodec_receive_packet(c, pkt);
1323 if (ret == AVERROR(EAGAIN))
1330 ret = avcodec_send_frame(c,
nullptr);
1334 if (ret < 0 || !got_packet)
1336 LOG(VB_GENERAL, LOG_ERR,
1337 QString(
"avcodec_encode_video2 failed (%1)").arg(ret));
1341 if (!fname.isEmpty())
1343 QString ename = fname +
".enc";
1346 QString yname = fname +
".enc.yuv";
1353 int newSize = pkt->size - delta;
1354 pkt->pts = savedPts;
1355 memmove(pkt->data, pkt->data + delta, newSize);
1356 av_shrink_packet(pkt, newSize);
1359 SetRepeat(pkt->data, pkt->size,
info->display_picture->nb_fields,
1360 ((
info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST) != 0U));
1362 avcodec_free_context(&c);
1374 static int s_frameCount = 0;
1377 LOG(VB_GENERAL, LOG_ERR,
"No more queue slots!");
1422 pkt->pts = AV_NOPTS_VALUE;
1423 pkt->dts = AV_NOPTS_VALUE;
1424 int ret = av_read_frame(
m_inputFC, pkt);
1435 LOG(VB_GENERAL, LOG_ERR,
1436 "Found end of file without finding any frames");
1437 av_packet_unref(pkt);
1442 if (tmpFrame ==
nullptr)
1444 av_packet_unref(pkt);
1454 if (pkt->stream_index ==
m_vidId ||
1455 m_aFrame.contains(pkt->stream_index))
1458 av_packet_unref(pkt);
1464 float percent_done = 100.0F * pkt->pos /
m_fileSize;
1468 LOG(VB_GENERAL, LOG_INFO, QString(
"%1% complete")
1469 .arg(percent_done, 0,
'f', 1));
1477 LOG(VB_DECODE, LOG_INFO, QString(
"Stream: %1 PTS: %2 DTS: %3 pos: %4")
1478 .arg(pkt->stream_index)
1479 .arg((pkt->pts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->pts))
1480 .arg((pkt->dts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->dts))
1485 if (tmpFrame ==
nullptr)
1487 av_packet_unref(pkt);
1491 switch (
m_inputFC->streams[pkt->stream_index]->codecpar->codec_type)
1493 case AVMEDIA_TYPE_VIDEO:
1495 av_packet_unref(pkt);
1502 case AVMEDIA_TYPE_AUDIO:
1503 if (
m_aFrame.contains(pkt->stream_index))
1505 m_aFrame[pkt->stream_index]->append(tmpFrame);
1509 LOG(VB_GENERAL, LOG_DEBUG,
1510 QString(
"Invalid stream ID %1, ignoring").arg(pkt->stream_index));
1513 av_packet_unref(pkt);
1518 av_packet_unref(pkt);
1526 QMap <int, bool> found;
1527 AVPacket *pkt = av_packet_alloc();
1530 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1538 av_packet_free(&pkt);
1542 if (
m_vidId == pkt->stream_index)
1546 if (
m_vFrame.first()->m_isSequence)
1548 if (pkt->pos !=
m_vFrame.first()->m_pkt->pos)
1551 if (pkt->pts != AV_NOPTS_VALUE ||
1552 pkt->dts != AV_NOPTS_VALUE)
1554 if (pkt->pts == AV_NOPTS_VALUE)
1555 m_vFrame.first()->m_pkt->pts = pkt->dts;
1557 LOG(VB_PROCESS, LOG_INFO,
1558 "Found 1st valid video frame");
1563 LOG(VB_PROCESS, LOG_INFO,
"Dropping V packet");
1574 if (found.contains(it.key()))
1579 while (!af->isEmpty())
1581 int64_t delta =
diff2x33(af->first()->m_pkt->pts,
1583 if (delta < -180000 || delta > 180000)
1588 for (
auto *currFrame : std::as_const(
m_vFrame))
1590 if (currFrame->m_isSequence)
1592 int64_t dlta1 =
diff2x33(af->first()->m_pkt->pts,
1593 currFrame->m_pkt->pts);
1594 if (dlta1 >= -180000 && dlta1 <= 180000)
1596 foundframe = currFrame;
1603 while (foundframe &&
m_vFrame.first() != foundframe)
1609 if (delta < -180000 || delta > 180000)
1611 LOG(VB_PROCESS, LOG_INFO,
1612 QString(
"Dropping A packet from stream %1")
1614 LOG(VB_PROCESS, LOG_INFO, QString(
" A:%1 V:%2")
1615 .arg(
PtsTime(af->first()->m_pkt->pts),
1621 if (delta < 0 && af->count() > 1)
1623 if (
cmp2x33(af->at(1)->m_pkt->pts,
1626 LOG(VB_PROCESS, LOG_INFO,
1627 QString(
"Found useful audio frame from stream %1")
1629 found[it.key()] =
true;
1632 LOG(VB_PROCESS, LOG_INFO,
1633 QString(
"Dropping A packet from stream %1")
1640 LOG(VB_PROCESS, LOG_INFO,
1641 QString(
"Found useful audio frame from stream %1")
1643 found[it.key()] =
true;
1647 if (af->count() == 1)
1651 }
while (found.count() !=
m_aFrame.count());
1653 av_packet_free(&pkt);
1666 uint8_t *end = ptr + size;
1667 uint8_t setmask = 0x00;
1668 uint8_t clrmask = 0xff;
1681 if (
MATCH_HEADER(ptr) && ptr[3] == 0xB5 && (ptr[4] & 0xF0) == 0x80)
1696 for (
const auto & vf : std::as_const(
m_vFrame))
1709 for (
int pos = start_pos; pos < maxPos; pos++)
1750 bool skip_first =
false;
1765 int framePos =
m_vFrame.indexOf(spare);
1773 if (!skip_first && curPos >= framePos &&
info->display_picture &&
1774 (
int)
info->display_picture->temporal_reference >= frameNum)
1786 int tmpFrameNum = frameNum;
1788 if (tmpFrame ==
nullptr)
1794 while (!
info->display_picture ||
1795 (
int)
info->display_picture->temporal_reference < frameNum)
1808 if ((
int)
info->display_picture->temporal_reference > frameNum)
1814 LOG(VB_GENERAL, LOG_NOTICE,
1815 QString(
"Frame %1 > %2. Corruption likely at pos: %3")
1816 .arg(
info->display_picture->temporal_reference)
1817 .arg(frameNum).arg(spare->
m_pkt->pos));
1826 AVPacket *pkt = av_packet_alloc();
1829 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1833 static int ins_count = 0;
1841 av_packet_free(&pkt);
1846 for (
const auto & of : std::as_const(*orderedFrames))
1850 if (spare ==
nullptr)
1852 LOG(VB_GENERAL, LOG_WARNING,
1853 QString(
"ConvertToI skipping undecoded frame #%1").arg(i));
1861 av_packet_ref(pkt, spare->
m_pkt);
1868 fname = QString(
"cnv%1").arg(ins_count++);
1873 av_packet_free(&pkt);
1877 LOG(VB_GENERAL, LOG_INFO,
1878 QString(
"Converting frame #%1 from %2 to I %3")
1882 av_packet_unref(pkt);
1888 m_vFrame.move(headPos, headPos + orderedFrames->count() - 1);
1889 av_packet_free(&pkt);
1894 int64_t ptsIncrement, int64_t initPTS)
1900 AVPacket *pkt = av_packet_alloc();
1903 LOG(VB_PROCESS, LOG_ERR,
"packet allocation failed");
1908 if (spare ==
nullptr)
1910 av_packet_free(&pkt);
1914 av_packet_ref(pkt, spare->
m_pkt);
1920 static int ins_count = 0;
1922 (QString(
"ins%1").arg(ins_count++)) : QString());
1927 av_packet_free(&pkt);
1931 LOG(VB_GENERAL, LOG_INFO,
1932 QString(
"Inserting %1 I-Frames after #%2 %3")
1933 .arg((
int)(deltaPTS / ptsIncrement))
1939 index =
m_vFrame.indexOf(spare) + 1;
1946 while (deltaPTS > 0)
1950 pkt->dts = pkt->pts;
1953 if (tmpFrame ==
nullptr)
1958 inc2x33(&pkt->pts, ptsIncrement);
1959 deltaPTS -= ptsIncrement;
1962 av_packet_free(&pkt);
1986 for (
const auto & range : std::as_const(rangelist))
1988 QStringList
tmp = range.split(
" - ");
1992 std::array<bool,2> ok {
false,
false };
1994 long long start =
tmp[0].toLongLong(ok.data());
1995 long long end =
tmp[1].toLongLong(&ok[1]);
2013 if (!rangelist.isEmpty())
2019 if (!mapPtr->isEmpty())
2022 frm_dir_map_t::iterator it = mapPtr->begin();
2023 for (; it != mapPtr->end(); ++it)
2026 msg += QString(
"\n\t\t%1 - %2").arg(start).arg(it.key());
2031 msg += QString(
"\n\t\t%1 - end").arg(start);
2032 LOG(VB_PROCESS, LOG_INFO, msg);
2039 int maxPos = dtsOrder->count() - 1;
2046 for (pos++; pos < maxPos &&
GetFrameTypeT(dtsOrder->at(pos)) ==
'B'; pos++)
2047 Lreorder.append(dtsOrder->at(pos));
2049 Lreorder.append(frame);
2054 int64_t &PTSdiscrep,
int numframes,
bool fix)
const
2059 if (curFrame->
m_pkt->pts == AV_NOPTS_VALUE)
2061 LOG(VB_PROCESS, LOG_INFO,
2062 QString(
"Found frame %1 with missing PTS at %2")
2064 .arg(
PtsTime(origvPTS / 300)));
2066 curFrame->
m_pkt->pts = origvPTS / 300;
2068 PTSdiscrep = AV_NOPTS_VALUE;
2073 if (tmpPTS != PTSdiscrep)
2075 PTSdiscrep = tmpPTS;
2076 LOG(VB_PROCESS, LOG_INFO,
2077 QString(
"Found invalid PTS (off by %1) at %2")
2082 curFrame->
m_pkt->pts = origvPTS / 300;
2086 origvPTS = curFrame->
m_pkt->pts * 300;
2088 ptsinc((uint64_t *)&origvPTS,
2094 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
2095 LOG(VB_GENERAL, LOG_INFO, QString(
"List contains %1 items")
2096 .arg(list->count()));
2098 for (
auto *curFrame : std::as_const(*list))
2100 LOG(VB_GENERAL, LOG_INFO,
2101 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 pos: %6")
2105 .arg(
PtsTime(curFrame->m_pkt->pts),
2106 PtsTime(curFrame->m_pkt->dts),
2107 QString::number(curFrame->m_pkt->pos)));
2109 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
2116 int64_t lastPTS = 0;
2117 int64_t deltaPTS = 0;
2118 std::array<int64_t,N_AUDIO> origaPTS {};
2119 int64_t cutStartPTS = 0;
2120 int64_t cutEndPTS = 0;
2121 uint64_t frame_count = 0;
2122 int new_discard_state = 0;
2123 QMap<int, int> af_dlta_cnt;
2124 QMap<int, int> cutState;
2126 AVPacket *pkt = av_packet_alloc();
2127 AVPacket *lastRealvPkt = av_packet_alloc();
2128 if ((pkt ==
nullptr) || (lastRealvPkt ==
nullptr))
2130 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
2136 av_packet_free(&pkt);
2137 av_packet_free(&lastRealvPkt);
2143 av_packet_free(&pkt);
2144 av_packet_free(&lastRealvPkt);
2150 int64_t initPTS =
m_vFrame.first()->m_pkt->pts;
2152 LOG(VB_GENERAL, LOG_INFO, QString(
"#%1 PTS:%2 Delta: 0.0ms queue: %3")
2159 deltaPTS =
diff2x33(
m_vFrame.first()->m_pkt->pts, af->first()->m_pkt->pts);
2160 LOG(VB_GENERAL, LOG_INFO,
2161 QString(
"#%1 PTS:%2 Delta: %3ms queue: %4")
2162 .arg(it.key()) .arg(
PtsTime(af->first()->m_pkt->pts))
2163 .arg(1000.0*deltaPTS / 90000.0).arg(af->count()));
2165 if (
cmp2x33(af->first()->m_pkt->pts, initPTS) < 0)
2166 initPTS = af->first()->m_pkt->pts;
2173 LOG(VB_PROCESS, LOG_INFO,
2174 QString(
"ptsIncrement: %1 Frame #: %2 PTS-adjust: %3")
2181 int64_t expectedvPTS = 300 * (
udiff2x33(
m_vFrame.first()->m_pkt->pts, initPTS) -
2187 cutStartPTS = origvPTS / 300;
2193 origaPTS[it.key()] = af->first()->m_pkt->pts * 300;
2195 af_dlta_cnt[it.key()] = 0;
2196 cutState[it.key()] =
static_cast<int>(
m_discard);
2210 av_packet_free(&pkt);
2211 av_packet_free(&lastRealvPkt);
2226 LOG(VB_GENERAL, LOG_WARNING,
2227 QString(
"Problem: Frame %1 (type %2) doesn't contain "
2234 LOG(VB_GENERAL, LOG_WARNING,
2235 QString(
"WARNING - Unsupported FPS change from %1 to %2")
2237 .arg(27000000.0 / seqFrame->
m_mpeg2_seq.frame_period,
2241 for (
int frame_pos = 0; frame_pos <
m_vFrame.count() - 1;)
2243 bool ptsorder_eq_dtsorder =
false;
2244 int64_t PTSdiscrep = 0;
2251 LOG(VB_GENERAL, LOG_ERR,
2252 QString(
"expectedPTS != expectedDTS + ptsIncrement"));
2253 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2254 .arg(
PtsTime(expectedvPTS / 300),
2257 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2261 av_packet_free(&pkt);
2262 av_packet_free(&lastRealvPkt);
2270 for (
auto *curFrame : std::as_const(Lreorder))
2284 int count = Lreorder.count();
2290 av_packet_free(&pkt);
2291 av_packet_free(&lastRealvPkt);
2298 int64_t tmp_origvPTS = origvPTS;
2302 (frame_pos + count + 1) <
m_vFrame.count())
2307 for (
auto *curFrame : std::as_const(tmpReorder))
2309 int64_t tmpPTSdiscrep = 0;
2311 tmpPTSdiscrep, numframes,
false);
2319 if (tmpPTSdiscrep != AV_NOPTS_VALUE &&
2320 tmpPTSdiscrep != PTSdiscrep)
2321 PTSdiscrep = tmpPTSdiscrep;
2323 count += tmpReorder.count();
2336 for (
int curIndex = 0; curIndex < Lreorder.count(); curIndex++)
2338 MPEG2frame *curFrame = Lreorder.at(curIndex);
2341 if (
m_saveMap.begin().key() <= frame_count)
2345 LOG(VB_GENERAL, LOG_INFO,
2346 QString(
"Saving frame #%1") .arg(frame_count));
2351 av_packet_free(&pkt);
2352 av_packet_free(&lastRealvPkt);
2356 WriteFrame(QString(
"save%1.yuv").arg(frame_count),
2363 new_discard_state =
m_delMap.begin().value();
2364 LOG(VB_GENERAL, LOG_INFO,
2365 QString(
"Del map found %1 at %2 (%3)")
2366 .arg(new_discard_state) .arg(frame_count)
2370 markedFrameP = curFrame;
2372 if (!new_discard_state)
2374 cutEndPTS = markedFrameP->
m_pkt->pts;
2376 diff2x33(cutEndPTS, expectedvPTS / 300),
2388 cutState[it3.key()] = 1;
2396 (!new_discard_state &&
2401 av_packet_free(&pkt);
2402 av_packet_free(&lastRealvPkt);
2405 ptsorder_eq_dtsorder =
true;
2407 else if (!new_discard_state &&
2410 m_vFrame.move(frame_pos, frame_pos + curIndex);
2411 ptsorder_eq_dtsorder =
true;
2415 markedFrame =
m_vFrame.at(frame_pos + curIndex);
2417 if (!new_discard_state)
2428 if (!Lreorder.isEmpty())
2430 av_packet_unref(lastRealvPkt);
2431 av_packet_ref(lastRealvPkt, Lreorder.last()->m_pkt);
2436 int64_t dtsExtra = 0;
2438 for (
auto *curFrame : std::as_const(Lreorder))
2442 if (curFrame != markedFrameP)
2445 markedFrameP =
nullptr;
2448 dec2x33(&curFrame->m_pkt->pts,
2450 deltaPTS =
diff2x33(curFrame->m_pkt->pts,
2451 expectedvPTS / 300);
2453 if (deltaPTS < -2 || deltaPTS > 2)
2455 LOG(VB_PROCESS, LOG_INFO,
2456 QString(
"PTS discrepancy: %1 != %2 on "
2458 .arg(curFrame->m_pkt->pts)
2459 .arg(expectedvPTS / 300)
2470 curFrame->m_pkt->pts = expectedvPTS / 300;
2474 LOG(VB_GENERAL, LOG_NOTICE,
2475 QString(
"Need to insert %1 frames > max "
2476 "allowed: %2. Assuming bad PTS")
2479 curFrame->m_pkt->pts = expectedvPTS / 300;
2483 lastPTS = expectedvPTS;
2487 if (curFrame == markedFrameP && new_discard_state)
2493 if (ptsorder_eq_dtsorder)
2506 m_vFrame.at(frame_pos)->m_pkt->pts = lastPTS / 300;
2512 av_packet_free(&pkt);
2513 av_packet_free(&lastRealvPkt);
2517 for (
int index = frame_pos + Lreorder.count();
2518 ret && index <
m_vFrame.count(); index++, --ret)
2520 lastPTS = expectedvPTS;
2523 Lreorder.append(
m_vFrame.at(index));
2530 for (
int i = 0; i < Lreorder.count(); i++, frame_pos++)
2535 if (curFrame != markedFrame)
2539 markedFrame =
nullptr;
2543 if (curFrame ==
nullptr)
2545 curFrame->
m_pkt->dts = (expectedDTS / 300);
2548 curFrame->
m_pkt->pts = (expectedDTS / 300);
2551 ((!ptsorder_eq_dtsorder && i == 0) ? 2 :
2553 LOG(VB_FRAME, LOG_INFO,
2554 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 "
2561 QString::number(curFrame->
m_pkt->pos)));
2564 av_packet_free(&pkt);
2565 av_packet_free(&lastRealvPkt);
2569 if (curFrame == markedFrame)
2571 markedFrame =
nullptr;
2576 expectedDTS += dtsExtra;
2580 frame_pos += Lreorder.count();
2584 PTSdiscrep), lastRealvPkt);
2588 cutEndPTS = lastRealvPkt->pts;
2601 bool backwardsPTS =
false;
2603 while (!af->isEmpty())
2612 if (CC->sample_rate == 0 || !CPC || CPC->duration == 0)
2627 90000LL * (int64_t)CPC->duration / CC->sample_rate;
2630 af->first()->m_pkt) < 0)
2632 backwardsPTS =
true;
2633 af_dlta_cnt[it.key()] = 0;
2636 int64_t tmpPTS =
diff2x33(af->first()->m_pkt->pts,
2637 origaPTS[it.key()] / 300);
2639 if (tmpPTS < -incPTS)
2642 LOG(VB_PROCESS, LOG_INFO,
2643 QString(
"Aud discard: PTS %1 < %2")
2644 .arg(
PtsTime(af->first()->m_pkt->pts))
2645 .arg(
PtsTime(origaPTS[it.key()] / 300)));
2648 af_dlta_cnt[it.key()] = 0;
2654 LOG(VB_PROCESS, LOG_INFO,
2655 QString(
"Found invalid audio PTS (off by %1) at %2")
2657 PtsTime(origaPTS[it.key()] / 300)));
2658 if (backwardsPTS && tmpPTS < 90000LL)
2661 LOG(VB_PROCESS, LOG_INFO,
2662 "Fixing missing audio frames");
2663 ptsinc((uint64_t *)&origaPTS[it.key()], 300 * tmpPTS);
2664 backwardsPTS =
false;
2666 else if (tmpPTS < 90000LL * 4)
2668 if (af_dlta_cnt[it.key()] >= 20)
2674 ptsinc((uint64_t *)&origaPTS[it.key()],
2676 af_dlta_cnt[it.key()] = 0;
2680 af_dlta_cnt[it.key()]++;
2683 af->first()->m_pkt->pts = origaPTS[it.key()] / 300;
2685 else if (tmpPTS > incPTS)
2688 backwardsPTS =
false;
2689 af_dlta_cnt[it.key()] = 0;
2693 backwardsPTS =
false;
2694 af_dlta_cnt[it.key()] = 0;
2697 int64_t nextPTS =
add2x33(af->first()->m_pkt->pts,
2698 90000LL * (int64_t)CPC->duration / CC->sample_rate);
2700 if ((cutState[it.key()] == 1 &&
2701 cmp2x33(nextPTS, cutStartPTS) > 0) ||
2702 (cutState[it.key()] == 2 &&
2703 cmp2x33(af->first()->m_pkt->pts, cutEndPTS) < 0))
2706 LOG(VB_PROCESS, LOG_INFO,
2707 QString(
"Aud in cutpoint: %1 > %2 && %3 < %4")
2709 .arg(
PtsTime(af->first()->m_pkt->pts))
2713 cutState[it.key()] = 2;
2714 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2718 int64_t deltaPTS2 = poq.
Get(it.key(), af->first()->m_pkt);
2720 if (
udiff2x33(nextPTS, deltaPTS2) * 300 > expectedDTS &&
2721 cutState[it.key()] != 1)
2724 LOG(VB_PROCESS, LOG_INFO, QString(
"Aud not ready: %1 > %2")
2726 .arg(
PtsTime(expectedDTS / 300)));
2731 if (cutState[it.key()] == 2)
2732 cutState[it.key()] = 0;
2734 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2736 dec2x33(&af->first()->m_pkt->pts, deltaPTS2);
2739 expectedPTS[it.key()] =
udiff2x33(nextPTS, initPTS);
2740 write_audio(lApkt_tail->m_pkt, initPTS);
2742 LOG(VB_FRAME, LOG_INFO, QString(
"AUD #%1: pts: %2 pos: %3")
2744 .arg(
PtsTime(af->first()->m_pkt->pts))
2745 .arg(af->first()->m_pkt->pos));
2748 av_packet_free(&pkt);
2749 av_packet_free(&lastRealvPkt);
2762 void *errors =
nullptr;
2764 if (*(
int *)errors) {
2765 LOG(VB_GENERAL, LOG_ERR,
2766 QString(
"joined thread failed with %1 write errors")
2767 .arg(*(
int *)errors));
2771 av_packet_free(&pkt);
2772 av_packet_free(&lastRealvPkt);
2783 fprintf(
stderr,
"%s usage:\n", s);
2784 fprintf(
stderr,
"\t--infile <file> -i <file> : Input mpg file\n");
2785 fprintf(
stderr,
"\t--outfile <file> -o <file> : Output mpg file\n");
2786 fprintf(
stderr,
"\t--dbg_lvl # -d # : Debug level\n");
2787 fprintf(
stderr,
"\t--maxframes # -m # : Max frames to insert at once (default=10)\n");
2788 fprintf(
stderr,
"\t--cutlist \"start - end\" -c : Apply a cutlist. Specify on e'-c' per cut\n");
2789 fprintf(
stderr,
"\t--no3to2 -t : Remove 3:2 pullup\n");
2790 fprintf(
stderr,
"\t--fixup -f : make PTS continuous\n");
2791 fprintf(
stderr,
"\t--ostream <dvd|ps> -e : Output stream type (defaults to ps)\n");
2792 fprintf(
stderr,
"\t--showprogress -p : show progress\n");
2793 fprintf(
stderr,
"\t--help -h : This screen\n");
2797int main(
int argc,
char **argv)
2799 QStringList cutlist;
2800 QStringList savelist;
2801 char *infile =
nullptr, *outfile =
nullptr, *format =
nullptr;
2802 int no_repeat = 0, fix_PTS = 0, max_frames = 20, otype =
REPLEX_MPEG2;
2803 bool showprogress = 0;
2804 const struct option long_options[] =
2806 {
"infile", required_argument,
nullptr,
'i'},
2807 {
"outfile", required_argument,
nullptr,
'o'},
2808 {
"format", required_argument,
nullptr,
'r'},
2809 {
"dbg_lvl", required_argument,
nullptr,
'd'},
2810 {
"cutlist", required_argument,
nullptr,
'c'},
2811 {
"saveframe", required_argument,
nullptr,
's'},
2812 {
"ostream", required_argument,
nullptr,
'e'},
2813 {
"no3to2", no_argument,
nullptr,
't'},
2814 {
"fixup", no_argument,
nullptr,
'f'},
2815 {
"showprogress", no_argument,
nullptr,
'p'},
2816 {
"help", no_argument ,
nullptr,
'h'},
2822 int option_index = 0;
2824 c = getopt_long (argc, argv,
"i:o:d:r:m:c:s:e:tfph",
2825 long_options, &option_index);
2846 if (strlen(optarg) == 3 && strncmp(optarg,
"dvd", 3) == 0)
2855 max_frames = atoi(optarg);
2859 cutlist.append(optarg);
2870 savelist.append(optarg);
2874 showprogress =
true;
2886 if (infile ==
nullptr || outfile ==
nullptr)
2889 MPEG2fixup m2f(infile, outfile,
nullptr, format,
2890 no_repeat, fix_PTS, max_frames,
2891 showprogress, otype);
2893 if (cutlist.count())
2895 if (savelist.count())
2905 LOG(VB_GENERAL, LOG_INFO,
"Generating Keyframe Index");
2916 LOG(VB_GENERAL, LOG_INFO,
"Seek tables are not required for MKV");
2920 AVPacket *pkt = av_packet_alloc();
2923 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
2927 uint64_t totalDuration = 0;
2928 while (av_read_frame(
m_inputFC, pkt) >= 0)
2930 if (pkt->stream_index ==
m_vidId)
2932 if (pkt->flags & AV_PKT_FLAG_KEY)
2934 posMap[count] = pkt->pos;
2935 durMap[count] = totalDuration;
2944 av_q2d(
m_inputFC->streams[pkt->stream_index]->time_base) *
2945 pkt->duration * 1000;
2948 av_packet_unref(pkt);
2952 av_packet_free(&pkt);
2956 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)