31 #include <netinet/in.h>
38 #define ATTR_ALIGN(align) __attribute__ ((__aligned__ (align)))
47 buf = (
char *) malloc (size + 63 +
sizeof (
void **));
51 memset(buf, 0, size + 63 +
sizeof (
void **));
52 align_buf = buf + 63 +
sizeof (
void **);
53 align_buf -= (long)align_buf & 63;
54 *(((
void **)align_buf) - 1) = buf;
66 static QString full_line(
"");
69 if (level > AV_LOG_INFO)
71 vsprintf(str, fmt, vl);
73 full_line += QString(str);
74 if (full_line.endsWith(
"\n"))
76 full_line.truncate(full_line.length() - 1);
77 LOG(VB_GENERAL, LOG_INFO, full_line);
78 full_line = QString(
"");
91 return(msg.sprintf(
"%s%02d:%02d:%02d.%03d", (is_neg) ?
"-" :
"",
92 (
unsigned int)(pts / 90000.) / 3600,
93 ((
unsigned int)(pts / 90000.) % 3600) / 60,
94 ((
unsigned int)(pts / 90000.) % 3600) % 60,
95 (((
unsigned int)(pts / 90.) % 3600000) % 60000) % 1000));
100 QList<int>::iterator it;
112 offset[*it].push_back(idx);
117 QList<poq_idx_t>::iterator it;
118 int64_t value =
offset[idx].first().newPTS;
126 while (
offset[idx].count() > 1 && !done)
128 it = ++
offset[idx].begin();
129 if ((((*it).type == 0) && (pkt->pts >= (*it).pos_pts) ) ||
130 (((*it).type == 1) &&
131 ((pkt->pos >= (*it).pos_pts) || (pkt->duration > (*it).framenum))))
134 value =
offset[idx].first().newPTS;
144 QList<int>::iterator it;
153 offset[*it].push_back(idx);
158 QList<int>::iterator it;
166 LOG(VB_FRAME, LOG_INFO, QString(
"Offset %1 -> %2 (%3) at %4")
172 offset[*it].push_back(idx);
174 orig[*it].push_back(idx);
181 QList<poq_idx_t> *dltaList = &
orig[idx];
182 while (dltaList->count() &&
183 (pkt.pos >= dltaList->first().pos_pts ||
184 pkt.duration > dltaList->first().framenum))
186 if (dltaList->first().newPTS >= 0)
187 ptsinc((uint64_t *)&origPTS, 300 * dltaList->first().newPTS);
189 ptsdec((uint64_t *)&origPTS, -300 * dltaList->first().newPTS);
190 delta += dltaList->first().newPTS;
191 dltaList->pop_front();
192 LOG(VB_PROCESS, LOG_INFO,
193 QString(
"Moving PTS offset of stream %1 by %2")
194 .arg(idx).arg(
PtsTime(delta)));
201 const char *fmt,
int norp,
int fixPTS,
int maxf,
202 bool showprog,
int otype,
void (*update_func)(
float),
221 if (deleteMap && deleteMap->count())
243 pthread_mutex_init(&
rx.
mutex, NULL);
244 pthread_cond_init(&
rx.
cond, NULL);
250 pthread_mutex_unlock(&
rx.
mutex);
268 const QFileInfo finfo(inf);
279 avformat_close_input(&
inputFC);
285 tmpFrame =
vFrame.takeFirst();
295 for (FrameMap::Iterator it =
aFrame.begin(); it !=
aFrame.end(); it++)
300 tmpFrame = af->takeFirst();
311 #define MATCH_HEADER(ptr) (((ptr)[0] == 0x00) && ((ptr)[1] == 0x00) && ((ptr)[2] == 0x01))
316 static unsigned char *sb_ptr = 0;
317 uint32_t sb_long, mask;
318 int offset, offset_r, offset_b;
326 offset = sb_pos >> 3;
327 offset_r = sb_pos & 0x07;
328 offset_b = 32 - offset_r;
329 mask = ~(((1 << num) - 1) << (offset_b - num));
330 sb_long = ntohl(*((uint32_t *) (sb_ptr + offset)));
331 value = value << (offset_b - num);
332 sb_long = (sb_long & mask) + value;
333 *((uint32_t *)(sb_ptr + offset)) = htonl(sb_long);
343 *pts1 = (*pts1 + pts2) % MAX_PTS;
353 diff = MAX_PTS + diff;
355 return (diff % MAX_PTS);
368 return (pts1 - pts2);
372 return (pts1 + MAX_PTS - pts2);
376 return (pts1 - (pts2 + MAX_PTS));
385 int64_t
tmp = pts1 + pts2;
387 return (pts1 + pts2) % MAX_PTS;
388 return (tmp + MAX_PTS);
397 if ((uint64_t)(pts1 - pts2) > MAX_PTS/2)
402 else if (pts1 == pts2)
406 if ((uint64_t)(pts2 - pts1) > MAX_PTS/2)
418 for (i = 0; i <
size; i++)
420 if (MATCH_HEADER(buf + i) && buf[i + 3] == code)
443 ext_count(0), mplex(0)
473 pthread_mutex_lock( &
mutex );
488 pthread_cond_signal(&
cond);
491 pthread_mutex_unlock(&
mutex);
526 int video_delay = 0, audio_delay = 0;
529 memset(&mx, 0,
sizeof(mx));
530 memset(ext_ok, 0,
sizeof(ext_ok));
532 mx.
priv = (
void *)
this;
535 O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
538 pthread_mutex_lock(&
mutex);
539 pthread_cond_signal(&
cond);
541 pthread_mutex_unlock(&
mutex);
557 #define INDEX_BUF (sizeof(index_unit) * 200)
565 uint32_t memsize =
vFrame.first()->mpeg2_seq.width *
566 vFrame.first()->mpeg2_seq.height * 10;
572 int mp2_count = 0, ac3_count = 0;
573 for (FrameMap::Iterator it =
aFrame.begin(); it !=
aFrame.end(); it++)
576 AVDictionaryEntry *metatag =
577 av_dict_get(
inputFC->streams[it.key()]->metadata,
578 "language", NULL, 0);
579 char *lang = metatag ? metatag->value : (
char *)
"";
588 case AV_CODEC_ID_MP2:
589 case AV_CODEC_ID_MP3:
593 case AV_CODEC_ID_AC3:
603 26999999ULL) /
vFrame.first()->mpeg2_seq.frame_period;
610 QString msg = QString(
"Id:%1 %2 V:%3").arg(f->
pkt.stream_index)
618 msg += QString(
" %2")
621 LOG(VB_RPLXQUEUE, LOG_INFO, msg);
628 int id = f->
pkt.stream_index;
643 iu.
dts = f->
pkt.dts * 300;
656 LOG(VB_GENERAL, LOG_ERR,
"Ringbuffer pointers empty. No stream found");
662 iu.
pts = f->
pkt.pts * 300;
663 pthread_mutex_lock( &
rx.
mutex );
684 unsigned int inc_size = 10 * (
unsigned int)f->
pkt.size;
685 LOG(VB_GENERAL, LOG_NOTICE,
686 QString(
"Increasing ringbuffer size by %1 to avoid deadlock")
694 pthread_mutex_unlock( &
rx.
mutex );
696 LOG(VB_GENERAL, LOG_ERR,
697 "Deadlock detected. One buffer is full when "
698 "the other is empty! Aborting");
702 pthread_cond_signal(&
rx.
cond);
709 pthread_mutex_unlock( &
rx.
mutex );
710 LOG(VB_GENERAL, LOG_ERR,
711 QString(
"Ring buffer overflow %1").arg(rb->
size));
716 pthread_mutex_unlock( &
rx.
mutex );
717 LOG(VB_GENERAL, LOG_ERR,
718 QString(
"Ring buffer overflow %1").arg(rbi->size));
721 pthread_mutex_unlock(&
rx.
mutex);
729 QByteArray ifarray = inputfile.toLocal8Bit();
730 const char *ifname = ifarray.constData();
732 AVInputFormat *fmt = NULL;
735 fmt = av_find_input_format(type);
738 LOG(VB_GENERAL, LOG_INFO, QString(
"Opening %1").arg(inputfile));
742 ret = avformat_open_input(&
inputFC, ifname, fmt, NULL);
745 LOG(VB_GENERAL, LOG_ERR,
746 QString(
"Couldn't open input file, error #%1").arg(ret));
756 ret = avformat_find_stream_info(
inputFC, NULL);
759 LOG(VB_GENERAL, LOG_ERR,
760 QString(
"Couldn't get stream info, error #%1").arg(ret));
761 avformat_close_input(&
inputFC);
767 if (VERBOSE_LEVEL_CHECK(VB_GENERAL, LOG_INFO))
768 av_dump_format(
inputFC, 0, ifname, 0);
770 for (
unsigned int i = 0; i <
inputFC->nb_streams; i++)
772 switch (
inputFC->streams[i]->codec->codec_type)
774 case AVMEDIA_TYPE_VIDEO:
779 case AVMEDIA_TYPE_AUDIO:
780 if (
inputFC->streams[i]->codec->channels == 0)
782 LOG(VB_GENERAL, LOG_ERR,
783 QString(
"Skipping invalid audio stream: %1").arg(i));
786 if (
inputFC->streams[i]->codec->codec_id == AV_CODEC_ID_AC3 ||
787 inputFC->streams[i]->codec->codec_id == AV_CODEC_ID_MP3 ||
788 inputFC->streams[i]->codec->codec_id == AV_CODEC_ID_MP2)
794 LOG(VB_GENERAL, LOG_ERR,
795 QString(
"Skipping unsupported audio stream: %1")
796 .arg(
inputFC->streams[i]->codec->codec_id));
799 LOG(VB_GENERAL, LOG_ERR,
800 QString(
"Skipping unsupported codec %1 on stream %2")
801 .arg(
inputFC->streams[i]->codec->codec_type).arg(i));
819 int head_size = (frame2->
framePos - frame2->
pkt.data);
822 memmove(frame1->
pkt.data + head_size, frame1->
pkt.data, frame1->
pkt.size);
823 memcpy(frame1->
pkt.data, frame2->
pkt.data, head_size);
824 frame1->
pkt.size += head_size;
827 if (VERBOSE_LEVEL_CHECK(VB_PROCESS, LOG_ANY))
829 static int count = 0;
830 QString filename = QString(
"hdr%1.yuv").arg(count++);
884 LOG(VB_GENERAL, LOG_WARNING,
885 "Warning: partial frame found!");
892 LOG(VB_GENERAL, LOG_ERR,
893 QString(
"Failed to decode frame. Position was: %1")
911 uint8_t
tmp[8] = {0x00, 0x00, 0x01, 0xb2, 0xff, 0xff, 0xff, 0xff};
917 if (VERBOSE_LEVEL_CHECK(VB_DECODE, LOG_INFO))
919 QString msg = QString(
"");
931 gop.sprintf(
"%02d:%02d:%02d:%03d ",
938 char coding_type = (ct == PIC_FLAG_CODING_TYPE_I) ?
'I' :
939 ((ct == PIC_FLAG_CODING_TYPE_P) ?
'P' :
940 ((ct == PIC_FLAG_CODING_TYPE_B) ?
'B' :
941 ((ct == PIC_FLAG_CODING_TYPE_D) ?
'D' :
'X')));
943 PIC_FLAG_TOP_FIELD_FIRST) ?
'T' :
'B';
945 PIC_FLAG_PROGRESSIVE_FRAME) ?
'P' :
'_';
946 msg += QString(
"#%1 fl:%2%3%4%5%6 ")
954 msg += QString(
"pos: %1").arg(vf->
pkt.pos);
955 LOG(VB_DECODE, LOG_INFO, msg);
964 if (tmpFrame == NULL)
968 for (FrameList::Iterator it =
vFrame.begin(); it !=
vFrame.end(); it++)
970 if ((*it)->isSequence)
984 if (tmpFrame == NULL)
987 QString fname = filename +
".enc";
1009 int fh =
open(filename.toLocal8Bit().constData(),
1010 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1012 LOG(VB_GENERAL, LOG_ERR,
1013 QString(
"Couldn't open file %1: ").arg(filename) + ENO);
1021 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(filename) +
1029 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(filename) +
1037 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1: ").arg(filename) +
1047 int fh =
open(filename.toLocal8Bit().constData(),
1048 O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
1050 LOG(VB_GENERAL, LOG_ERR,
1051 QString(
"Couldn't open file %1: ").arg(filename) + ENO);
1055 int ret =
write(fh, data, size);
1057 LOG(VB_GENERAL, LOG_ERR, QString(
"write failed %1").arg(filename) +
1072 AVCodecContext *c = NULL;
1081 if (!fname.isEmpty())
1083 QString tmpstr = fname +
".yuv";
1087 picture = avcodec_alloc_frame();
1089 pkt->data = (uint8_t *)
av_malloc(outbuf_size);
1105 PIC_FLAG_TOP_FIELD_FIRST);
1108 PIC_FLAG_TOP_FIELD_FIRST);
1111 PIC_FLAG_PROGRESSIVE_FRAME);
1113 out_codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO);
1118 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find MPEG2 encoder");
1122 c = avcodec_alloc_context3(NULL);
1128 if (picture->interlaced_frame)
1129 c->flags |= CODEC_FLAG_INTERLACED_DCT;
1132 c->bit_rate_tolerance = c->bit_rate >> 2;
1135 av_reduce(&c->time_base.num, &c->time_base.den,
1137 c->pix_fmt = PIX_FMT_YUV420P;
1138 c->max_b_frames = 0;
1139 c->has_b_frames = 0;
1140 c->rc_buffer_aggressivity = 1;
1143 c->rc_buffer_size = 0;
1147 if (intra_matrix[0] == 0x08)
1148 c->intra_matrix = intra_matrix;
1150 c->qmin = c->qmax = 2;
1152 picture->pts = AV_NOPTS_VALUE;
1153 picture->key_frame = 1;
1154 picture->pict_type = AV_PICTURE_TYPE_NONE;
1156 picture->quality = 0;
1158 if (avcodec_open2(c, out_codec, NULL) < 0)
1161 LOG(VB_GENERAL, LOG_ERR,
"could not open codec");
1167 bool initial =
true;
1175 ret = avcodec_encode_video2(c, pkt, (initial ? picture : NULL),
1181 LOG(VB_GENERAL, LOG_ERR,
1182 QString(
"avcodec_encode_video2 failed (%1)").arg(ret));
1187 if (!fname.isEmpty())
1189 QString ename = fname +
".enc";
1192 QString yname = fname +
".enc.yuv";
1198 memmove(pkt->data, pkt->data + delta, pkt->size);
1209 #define MAX_FRAMES 20000
1213 static int frame_count = 0;
1217 if (frame_count >= MAX_FRAMES)
1219 LOG(VB_GENERAL, LOG_ERR,
"No more queue slots!");
1264 pkt->pts = AV_NOPTS_VALUE;
1265 pkt->dts = AV_NOPTS_VALUE;
1266 ret = av_read_frame(
inputFC, pkt);
1277 LOG(VB_GENERAL, LOG_ERR,
1278 "Found end of file without finding any frames");
1279 av_free_packet(pkt);
1284 if (tmpFrame == NULL)
1286 av_free_packet(pkt);
1296 if (pkt->stream_index ==
vid_id ||
1297 aFrame.contains(pkt->stream_index))
1300 av_free_packet(pkt);
1306 float percent_done = 100.0 * pkt->pos /
filesize;
1310 LOG(VB_GENERAL, LOG_INFO, QString(
"%1% complete")
1311 .arg(percent_done, 0,
'f', 1));
1313 return REENCODE_STOPPED;
1319 LOG(VB_DECODE, LOG_INFO, QString(
"Stream: %1 PTS: %2 DTS: %3 pos: %4")
1320 .arg(pkt->stream_index)
1321 .arg((pkt->pts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->pts))
1322 .arg((pkt->dts == AV_NOPTS_VALUE) ?
"NONE" :
PtsTime(pkt->dts))
1327 if (tmpFrame == NULL)
1329 av_free_packet(pkt);
1333 switch (
inputFC->streams[pkt->stream_index]->codec->codec_type)
1335 case AVMEDIA_TYPE_VIDEO:
1337 av_free_packet(pkt);
1344 case AVMEDIA_TYPE_AUDIO:
1345 aFrame[pkt->stream_index]->append(tmpFrame);
1346 av_free_packet(pkt);
1351 av_free_packet(pkt);
1360 QMap <int, bool> found;
1362 av_init_packet(&pkt);
1369 if (
vid_id == pkt.stream_index)
1371 while (!
vFrame.isEmpty())
1373 if (
vFrame.first()->isSequence)
1375 if (pkt.pos !=
vFrame.first()->pkt.pos)
1378 if (pkt.pts != AV_NOPTS_VALUE ||
1379 pkt.dts != AV_NOPTS_VALUE)
1381 if (pkt.pts == AV_NOPTS_VALUE)
1382 vFrame.first()->pkt.pts = pkt.dts;
1384 LOG(VB_PROCESS, LOG_INFO,
1385 "Found 1st valid video frame");
1390 LOG(VB_PROCESS, LOG_INFO,
"Dropping V packet");
1399 for (FrameMap::Iterator it =
aFrame.begin(); it !=
aFrame.end(); it++)
1401 if (found.contains(it.key()))
1406 while (!af->isEmpty())
1408 int64_t delta =
diff2x33(af->first()->pkt.pts,
1409 vFrame.first()->pkt.pts);
1410 if (delta < -180000 || delta > 180000)
1415 for (FrameList::Iterator it2 =
vFrame.begin();
1416 it2 !=
vFrame.end(); it2++)
1421 int64_t dlta1 =
diff2x33(af->first()->pkt.pts,
1422 currFrame->
pkt.pts);
1423 if (dlta1 >= -180000 && dlta1 <= 180000)
1425 foundframe = currFrame;
1432 while (foundframe &&
vFrame.first() != foundframe)
1438 if (delta < -180000 || delta > 180000)
1440 LOG(VB_PROCESS, LOG_INFO,
1441 QString(
"Dropping A packet from stream %1")
1443 LOG(VB_PROCESS, LOG_INFO, QString(
" A:%1 V:%2")
1444 .arg(
PtsTime(af->first()->pkt.pts))
1450 if (delta < 0 && af->count() > 1)
1452 if (
cmp2x33(af->at(1)->pkt.pts,
1453 vFrame.first()->pkt.pts) > 0)
1455 LOG(VB_PROCESS, LOG_INFO,
1456 QString(
"Found useful audio frame from stream %1")
1458 found[it.key()] = 1;
1463 LOG(VB_PROCESS, LOG_INFO,
1464 QString(
"Dropping A packet from stream %1")
1470 else if (delta >= 0)
1472 LOG(VB_PROCESS, LOG_INFO,
1473 QString(
"Found useful audio frame from stream %1")
1475 found[it.key()] = 1;
1479 if (af->count() == 1)
1483 }
while (found.count() !=
aFrame.count());
1497 uint8_t *end = ptr +
size;
1498 uint8_t setmask = 0x00;
1499 uint8_t clrmask = 0xff;
1512 if (MATCH_HEADER(ptr) && ptr[3] == 0xB5 && (ptr[4] & 0xF0) == 0x80)
1527 for (FrameList::Iterator it =
vFrame.begin(); it !=
vFrame.end(); it++)
1538 int maxPos =
vFrame.count() - 1;
1540 for (
int pos = start_pos; pos < maxPos; pos++)
1555 while (
vFrame.count() > 1)
1582 bool skip_first =
false;
1584 int maxPos =
vFrame.count() - 1;
1597 int framePos =
vFrame.indexOf(spare);
1618 int tmpFrameNum = frameNum;
1620 if (tmpFrame == NULL)
1646 LOG(VB_GENERAL, LOG_NOTICE,
1647 QString(
"Frame %1 > %2. Corruption likely at pos: %3")
1649 .arg(frameNum).arg(spare->
pkt.pos));
1660 static int ins_count = 0;
1668 for (FrameList::Iterator it = orderedFrames->begin();
1669 it != orderedFrames->end(); it++)
1674 LOG(VB_GENERAL, LOG_WARNING,
1675 QString(
"ConvertToI skipping undecoded frame #%1").arg(i));
1689 if (VERBOSE_LEVEL_CHECK(VB_PROCESS, LOG_ANY))
1690 fname = QString(
"cnv%1").arg(ins_count++);
1696 LOG(VB_GENERAL, LOG_INFO,
1697 QString(
"Converting frame #%1 from %2 to I %3")
1708 vFrame.move(headPos, headPos + orderedFrames->count() - 1);
1713 int64_t ptsIncrement, int64_t initPTS)
1720 static int ins_count = 0;
1732 fname = (VERBOSE_LEVEL_CHECK(VB_PROCESS, LOG_ANY) ?
1733 (QString(
"ins%1").arg(ins_count++)) : QString());
1739 LOG(VB_GENERAL, LOG_INFO,
1740 QString(
"Inserting %1 I-Frames after #%2 %3")
1741 .arg((
int)(deltaPTS / ptsIncrement))
1747 index =
vFrame.indexOf(spare) + 1;
1748 while (index <
vFrame.count() &&
1750 spare =
vFrame.at(index++);
1752 index =
vFrame.indexOf(spare);
1754 while (deltaPTS > 0)
1762 if (tmpFrame == NULL)
1764 vFrame.insert(index, tmpFrame);
1767 inc2x33(&pkt.pts, ptsIncrement);
1782 QStringList::iterator i;
1795 for (i = rangelist.begin(); i != rangelist.end(); ++i)
1797 QStringList
tmp = (*i).split(
" - ");
1801 bool ok[2] = {
false,
false };
1803 long long start = tmp[0].toLongLong(&ok[0]);
1804 long long end = tmp[1].toLongLong(&ok[1]);
1820 if (rangelist.count())
1826 if (mapPtr->count())
1829 frm_dir_map_t::iterator it = mapPtr->begin();
1830 for (; it != mapPtr->end(); ++it)
1832 msg += QString(
"\n\t\t%1 - %2").arg(start).arg(it.key());
1835 LOG(VB_PROCESS, LOG_INFO, msg);
1842 int maxPos = dtsOrder->count() - 1;
1849 for (pos++; pos < maxPos &&
GetFrameTypeT(dtsOrder->at(pos)) ==
'B'; pos++)
1850 Lreorder.append(dtsOrder->at(pos));
1852 Lreorder.append(frame);
1857 int64_t &PTSdiscrep,
int numframes,
bool fix)
1862 if (curFrame->
pkt.pts == AV_NOPTS_VALUE)
1864 LOG(VB_PROCESS, LOG_INFO,
1865 QString(
"Found frame %1 with missing PTS at %2")
1867 .arg(
PtsTime(origvPTS / 300)));
1869 curFrame->
pkt.pts = origvPTS / 300;
1871 PTSdiscrep = AV_NOPTS_VALUE;
1876 if (tmpPTS != PTSdiscrep)
1878 PTSdiscrep = tmpPTS;
1879 LOG(VB_PROCESS, LOG_INFO,
1880 QString(
"Found invalid PTS (off by %1) at %2")
1882 .arg(
PtsTime(origvPTS / 300)));
1885 curFrame->
pkt.pts = origvPTS / 300;
1889 origvPTS = curFrame->
pkt.pts * 300;
1891 ptsinc((uint64_t *)&origvPTS,
1897 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
1898 LOG(VB_GENERAL, LOG_INFO, QString(
"List contains %1 items")
1899 .arg(list->count()));
1901 for (FrameList::Iterator it = list->begin(); it != list->end(); it++)
1905 LOG(VB_GENERAL, LOG_INFO,
1906 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 pos: %6")
1912 .arg(curFrame->
pkt.pos));
1914 LOG(VB_GENERAL, LOG_INFO,
"=========================================");
1921 int64_t expectedvPTS;
1922 int64_t expectedDTS = 0, lastPTS = 0, initPTS = 0, deltaPTS = 0;
1923 int64_t origvPTS = 0, origaPTS[N_AUDIO];
1924 int64_t cutStartPTS = 0, cutEndPTS = 0;
1925 uint64_t frame_count = 0;
1926 int new_discard_state = 0;
1928 QMap<int, int> af_dlta_cnt, cutState;
1930 AVPacket pkt, lastRealvPkt;
1933 return GENERIC_EXIT_NOT_OK;
1936 return GENERIC_EXIT_NOT_OK;
1938 av_init_packet(&pkt);
1942 initPTS =
vFrame.first()->pkt.pts;
1944 LOG(VB_GENERAL, LOG_INFO, QString(
"#%1 PTS:%2 Delta: 0.0ms queue: %3")
1948 for (FrameMap::Iterator it =
aFrame.begin(); it !=
aFrame.end(); it++)
1951 deltaPTS =
diff2x33(
vFrame.first()->pkt.pts, af->first()->pkt.pts);
1952 LOG(VB_GENERAL, LOG_INFO,
1953 QString(
"#%1 PTS:%2 Delta: %3ms queue: %4")
1954 .arg(it.key()) .arg(
PtsTime(af->first()->pkt.pts))
1955 .arg(1000.0*deltaPTS / 90000.0).arg(af->count()));
1957 if (
cmp2x33(af->first()->pkt.pts, initPTS) < 0)
1958 initPTS = af->first()->pkt.pts;
1965 LOG(VB_PROCESS, LOG_INFO,
1966 QString(
"ptsIncrement: %1 Frame #: %2 PTS-adjust: %3")
1979 cutStartPTS = origvPTS / 300;
1982 for (FrameMap::Iterator it =
aFrame.begin(); it !=
aFrame.end(); it++)
1985 origaPTS[it.key()] = af->first()->pkt.pts * 300;
1987 af_dlta_cnt[it.key()] = 0;
1988 cutState[it.key()] = !!(
discard);
2013 LOG(VB_GENERAL, LOG_WARNING,
2014 QString(
"Problem: Frame %1 (type %2) doesn't contain "
2021 LOG(VB_GENERAL, LOG_WARNING,
2022 QString(
"WARNING - Unsupported FPS change from %1 to %2")
2023 .arg(90000.0 / ptsIncrement, 0,
'f', 2)
2028 for (
int frame_pos = 0; frame_pos <
vFrame.count() - 1;)
2030 bool ptsorder_eq_dtsorder =
false;
2031 int64_t dtsExtra = 0, PTSdiscrep = 0;
2033 MPEG2frame *markedFrame = NULL, *markedFrameP = NULL;
2035 if (expectedvPTS != expectedDTS + ptsIncrement * 300)
2037 LOG(VB_GENERAL, LOG_ERR,
2038 QString(
"expectedPTS != expectedDTS + ptsIncrement"));
2039 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2040 .arg(
PtsTime(expectedvPTS / 300))
2041 .arg(
PtsTime(expectedDTS / 300))
2043 LOG(VB_GENERAL, LOG_ERR, QString(
"%1 != %2 + %3")
2046 .arg(ptsIncrement));
2047 return GENERIC_EXIT_NOT_OK;
2054 for (FrameList::Iterator it2 = Lreorder.begin();
2055 it2 != Lreorder.end(); it2++)
2058 poq.UpdateOrigPTS(
vid_id, origvPTS, curFrame->
pkt);
2069 int pos =
vFrame.count();
2070 int count = Lreorder.count();
2077 int64_t tmp_origvPTS = origvPTS;
2081 (frame_pos + count + 1) <
vFrame.count())
2086 for (FrameList::Iterator it2 = tmpReorder.begin();
2087 it2 != tmpReorder.end(); it2++)
2090 int64_t tmpPTSdiscrep = 0;
2092 tmpPTSdiscrep, numframes,
false);
2100 if (tmpPTSdiscrep != AV_NOPTS_VALUE &&
2101 tmpPTSdiscrep != PTSdiscrep)
2102 PTSdiscrep = tmpPTSdiscrep;
2104 count += tmpReorder.count();
2109 while (
vFrame.count() > pos)
2117 for (
int curIndex = 0; curIndex < Lreorder.count(); curIndex++)
2119 MPEG2frame *curFrame = Lreorder.at(curIndex);
2122 if (
saveMap.begin().key() <= frame_count)
2126 LOG(VB_GENERAL, LOG_INFO,
2127 QString(
"Saving frame #%1") .arg(frame_count));
2132 return GENERIC_EXIT_WRITE_FRAME_ERROR;
2135 WriteFrame(QString(
"save%1.yuv").arg(frame_count),
2140 if (
delMap.count() &&
delMap.begin().key() <= frame_count)
2142 new_discard_state =
delMap.begin().value();
2143 LOG(VB_GENERAL, LOG_INFO,
2144 QString(
"Del map found %1 at %2 (%3)")
2145 .arg(new_discard_state) .arg(frame_count)
2146 .arg(
delMap.begin().key()));
2149 markedFrameP = curFrame;
2151 if (!new_discard_state)
2153 cutEndPTS = markedFrameP->
pkt.pts;
2155 diff2x33(cutEndPTS, expectedvPTS / 300),
2161 add2x33(markedFrameP->pkt.pts,
2164 for (FrameMap::Iterator it3 =
aFrame.begin();
2165 it3 !=
aFrame.end(); it3++)
2167 cutState[it3.key()] = 1;
2175 (!new_discard_state &&
2179 return GENERIC_EXIT_WRITE_FRAME_ERROR;
2180 ptsorder_eq_dtsorder =
true;
2182 else if (!new_discard_state &&
2185 vFrame.move(frame_pos, frame_pos + curIndex);
2186 ptsorder_eq_dtsorder =
true;
2190 markedFrame =
vFrame.at(frame_pos + curIndex);
2192 if (!new_discard_state)
2203 if (!Lreorder.isEmpty())
2204 lastRealvPkt = Lreorder.last()->pkt;
2209 for (FrameList::Iterator it2 = Lreorder.begin();
2210 it2 != Lreorder.end(); it2++)
2215 if (curFrame != markedFrameP)
2218 markedFrameP = NULL;
2224 expectedvPTS / 300);
2226 if (deltaPTS < -2 || deltaPTS > 2)
2228 LOG(VB_PROCESS, LOG_INFO,
2229 QString(
"PTS discrepancy: %1 != %2 on "
2231 .arg(curFrame->
pkt.pts)
2232 .arg(expectedvPTS / 300)
2243 curFrame->
pkt.pts = expectedvPTS / 300;
2247 LOG(VB_GENERAL, LOG_NOTICE,
2248 QString(
"Need to insert %1 frames > max "
2249 "allowed: %2. Assuming bad PTS")
2250 .arg((
int)(deltaPTS / ptsIncrement))
2252 curFrame->
pkt.pts = expectedvPTS / 300;
2256 lastPTS = expectedvPTS;
2257 expectedvPTS += 150 * ptsIncrement *
2260 if (curFrame == markedFrameP && new_discard_state)
2266 if (ptsorder_eq_dtsorder)
2269 dtsExtra = 150 * ptsIncrement *
2272 if (!markedFrame && deltaPTS > (4 * ptsIncrement / 5))
2279 vFrame.at(frame_pos)->pkt.pts = lastPTS / 300;
2281 deltaPTS, ptsIncrement, 0);
2284 return GENERIC_EXIT_WRITE_FRAME_ERROR;
2286 for (
int index = frame_pos + Lreorder.count();
2289 lastPTS = expectedvPTS;
2290 expectedvPTS += 150 * ptsIncrement *
2299 for (
int i = 0; i < Lreorder.count(); i++, frame_pos++)
2304 if (curFrame != markedFrame)
2311 curFrame->
pkt.dts = (expectedDTS / 300);
2314 curFrame->
pkt.pts = (expectedDTS / 300);
2316 expectedDTS += 150 * ptsIncrement *
2317 ((!ptsorder_eq_dtsorder && i == 0) ? 2 :
2319 LOG(VB_FRAME, LOG_INFO,
2320 QString(
"VID: %1 #:%2 nb: %3 pts: %4 dts: %5 "
2327 .arg(curFrame->
pkt.pos));
2329 return GENERIC_EXIT_DEADLOCK;
2331 if (curFrame == markedFrame)
2338 expectedDTS += dtsExtra;
2342 frame_pos += Lreorder.count();
2346 PTSdiscrep), lastRealvPkt);
2350 cutEndPTS = lastRealvPkt.pts;
2358 for (FrameMap::Iterator it =
aFrame.begin(); it !=
aFrame.end(); it++)
2363 bool backwardsPTS =
false;
2369 if (CC->sample_rate == 0 || !CPC || CPC->duration == 0)
2383 int64_t nextPTS, tmpPTS;
2385 90000LL * (int64_t)CPC->duration / CC->sample_rate;
2387 if (poq.UpdateOrigPTS(it.key(), origaPTS[it.key()],
2388 af->first()->pkt) < 0)
2390 backwardsPTS =
true;
2391 af_dlta_cnt[it.key()] = 0;
2394 tmpPTS =
diff2x33(af->first()->pkt.pts,
2395 origaPTS[it.key()] / 300);
2397 if (tmpPTS < -incPTS)
2400 LOG(VB_PROCESS, LOG_INFO,
2401 QString(
"Aud discard: PTS %1 < %2")
2402 .arg(
PtsTime(af->first()->pkt.pts))
2403 .arg(
PtsTime(origaPTS[it.key()] / 300)));
2406 af_dlta_cnt[it.key()] = 0;
2412 LOG(VB_PROCESS, LOG_INFO,
2413 QString(
"Found invalid audio PTS (off by %1) at %2")
2415 .arg(
PtsTime(origaPTS[it.key()] / 300)));
2416 if (backwardsPTS && tmpPTS < 90000LL)
2419 LOG(VB_PROCESS, LOG_INFO,
2420 "Fixing missing audio frames");
2421 ptsinc((uint64_t *)&origaPTS[it.key()], 300 * tmpPTS);
2422 backwardsPTS =
false;
2424 else if (tmpPTS < 90000LL * 4)
2426 if (af_dlta_cnt[it.key()] >= 20)
2432 ptsinc((uint64_t *)&origaPTS[it.key()],
2434 af_dlta_cnt[it.key()] = 0;
2437 af_dlta_cnt[it.key()]++;
2439 af->first()->pkt.pts = origaPTS[it.key()] / 300;
2441 else if (tmpPTS > incPTS)
2444 backwardsPTS =
false;
2445 af_dlta_cnt[it.key()] = 0;
2449 backwardsPTS =
false;
2450 af_dlta_cnt[it.key()] = 0;
2453 nextPTS =
add2x33(af->first()->pkt.pts,
2454 90000LL * (int64_t)CPC->duration / CC->sample_rate);
2456 if ((cutState[it.key()] == 1 &&
2457 cmp2x33(nextPTS, cutStartPTS) > 0) ||
2458 (cutState[it.key()] == 2 &&
2459 cmp2x33(af->first()->pkt.pts, cutEndPTS) < 0))
2462 LOG(VB_PROCESS, LOG_INFO,
2463 QString(
"Aud in cutpoint: %1 > %2 && %3 < %4")
2465 .arg(
PtsTime(af->first()->pkt.pts))
2469 cutState[it.key()] = 2;
2470 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2474 int64_t deltaPTS = poq.Get(it.key(), &af->first()->pkt);
2476 if (
udiff2x33(nextPTS, deltaPTS) * 300 > expectedDTS &&
2477 cutState[it.key()] != 1)
2480 LOG(VB_PROCESS, LOG_INFO, QString(
"Aud not ready: %1 > %2")
2482 .arg(
PtsTime(expectedDTS / 300)));
2487 if (cutState[it.key()] == 2)
2488 cutState[it.key()] = 0;
2490 ptsinc((uint64_t *)&origaPTS[it.key()], incPTS * 300);
2492 dec2x33(&af->first()->pkt.pts, deltaPTS);
2495 expectedPTS[it.key()] =
udiff2x33(nextPTS, initPTS);
2496 write_audio(lApkt_tail->pkt, initPTS);
2498 LOG(VB_FRAME, LOG_INFO, QString(
"AUD #%1: pts: %2 pos: %3")
2500 .arg(
PtsTime(af->first()->pkt.pts))
2501 .arg(af->first()->pkt.pos));
2503 return GENERIC_EXIT_DEADLOCK;
2510 pthread_mutex_lock( &
rx.
mutex );
2511 pthread_cond_signal(&
rx.
cond);
2512 pthread_mutex_unlock( &
rx.
mutex );
2513 pthread_join(
thread, NULL);
2515 avformat_close_input(&
inputFC);
2525 fprintf(stderr,
"%s usage:\n", s);
2526 fprintf(stderr,
"\t--infile <file> -i <file> : Input mpg file\n");
2527 fprintf(stderr,
"\t--outfile <file> -o <file> : Output mpg file\n");
2528 fprintf(stderr,
"\t--dbg_lvl # -d # : Debug level\n");
2529 fprintf(stderr,
"\t--maxframes # -m # : Max frames to insert at once (default=10)\n");
2530 fprintf(stderr,
"\t--cutlist \"start - end\" -c : Apply a cutlist. Specify on e'-c' per cut\n");
2531 fprintf(stderr,
"\t--no3to2 -t : Remove 3:2 pullup\n");
2532 fprintf(stderr,
"\t--fixup -f : make PTS continuous\n");
2533 fprintf(stderr,
"\t--ostream <dvd|ps> -e : Output stream type (defaults to ps)\n");
2534 fprintf(stderr,
"\t--showprogress -p : show progress\n");
2535 fprintf(stderr,
"\t--help -h : This screen\n");
2541 QStringList cutlist;
2542 QStringList savelist;
2543 char *infile = NULL, *outfile = NULL, *
format = NULL;
2544 int no_repeat = 0, fix_PTS = 0, max_frames = 20, otype = REPLEX_MPEG2;
2545 bool showprogress = 0;
2546 const struct option long_options[] =
2548 {
"infile", required_argument, NULL,
'i'},
2550 {
"outfile", required_argument, NULL,
'o'},
2551 {
"format", required_argument, NULL,
'r'},
2552 {
"dbg_lvl", required_argument, NULL,
'd'},
2553 {
"cutlist", required_argument, NULL,
'c'},
2554 {
"saveframe", required_argument, NULL,
's'},
2555 {
"ostream", required_argument, NULL,
'e'},
2556 {
"no3to2", no_argument, NULL,
't'},
2557 {
"fixup", no_argument, NULL,
'f'},
2558 {
"showprogress", no_argument, NULL,
'p'},
2559 {
"help", no_argument , NULL,
'h'},
2565 int option_index = 0;
2567 c = getopt_long (argc, argv,
"i:o:d:r:m:c:s:e:tfph",
2568 long_options, &option_index);
2589 if (strlen(optarg) == 3 && strncmp(optarg,
"dvd", 3) == 0)
2594 verboseMask = atoi(optarg);
2598 max_frames = atoi(optarg);
2602 cutlist.append(optarg);
2613 savelist.append(optarg);
2617 showprogress =
true;
2629 if (infile == NULL || outfile == NULL)
2632 MPEG2fixup m2f(infile, outfile, NULL, format,
2633 no_repeat, fix_PTS, max_frames,
2634 showprogress, otype);
2636 if (cutlist.count())
2638 if (savelist.count())
2648 LOG(VB_GENERAL, LOG_INFO,
"Generating Keyframe Index");
2654 if (!
InitAV(file, NULL, 0))
2655 return GENERIC_EXIT_NOT_OK;
2659 LOG(VB_GENERAL, LOG_INFO,
"Seek tables are not required for MKV");
2660 return GENERIC_EXIT_NOT_OK;
2663 av_init_packet(&pkt);
2665 uint64_t totalDuration = 0;
2666 while (av_read_frame(
inputFC, &pkt) >= 0)
2668 if (pkt.stream_index ==
vid_id)
2670 if (pkt.flags & AV_PKT_FLAG_KEY)
2672 posMap[count] = pkt.pos;
2673 durMap[count] = totalDuration;
2682 av_q2d(
inputFC->streams[pkt.stream_index]->time_base) *
2683 pkt.duration * 1000;
2686 av_free_packet(&pkt);
2690 avformat_close_input(&
inputFC);
2693 LOG(VB_GENERAL, LOG_NOTICE,
"Transcode Completed");