MythTV  master
nuppeldecoder.cpp
Go to the documentation of this file.
1 // C++ headers
2 #include <algorithm>
3 #include <cassert>
4 #include <cerrno>
5 #include <cstdio> // for SEEK_SET, SEEK_CUR
6 #include <cstring>
7 #include <sys/types.h>
8 #include <vector> // for vector
9 using namespace std;
10 
11 // Qt headers
12 #include <QMutex>
13 #include <QMap> // for QMap<>::iterator, QMap
14 
15 // MythTV headers
16 #include "mythconfig.h"
17 #include "nuppeldecoder.h"
18 #include "mythplayer.h"
19 #include "mythlogging.h"
20 #include "programinfo.h"
21 #include "mythavutil.h"
22 #include "fourcc.h"
23 #include "RTjpegN.h"
24 #include "audiooutput.h" // for RTjpeg, RTJ_YUV420
25 #include "audiooutputsettings.h" // for ::FORMAT_NONE, ::FORMAT_S16, etc
26 #include "audioplayer.h" // for AudioPlayer
27 #include "cc608reader.h" // for CC608Reader
28 
29 #include "lzo/lzo1x.h"
30 
31 extern "C" {
32 #if HAVE_BIGENDIAN
33 #include "bswap.h"
34 #endif
35 #include "libavutil/opt.h"
36 }
37 
38 #define LOC QString("NVD: ")
39 
41  const ProgramInfo &pginfo)
42  : DecoderBase(parent, pginfo)
43 {
44  // initialize structures
45  memset(&m_fileHeader, 0, sizeof(rtfileheader));
46  memset(&m_frameHeader, 0, sizeof(rtframeheader));
47  memset(&m_extraData, 0, sizeof(extendeddata));
48  m_planes[0] = m_planes[1] = m_planes[2] = nullptr;
49  m_audioSamples = (uint8_t *)av_mallocz(AudioOutput::kMaxSizeBuffer);
50 
51  // set parent class variables
53  m_lastKey = 0;
54  m_framesPlayed = 0;
55  m_getRawFrames = false;
56  m_getRawVideo = false;
57 
58  m_rtjd = new RTjpeg();
59  int format = RTJ_YUV420;
60  m_rtjd->SetFormat(&format);
61 
62  if (lzo_init() != LZO_E_OK)
63  {
64  LOG(VB_GENERAL, LOG_ERR, "NuppelDecoder: lzo_init() failed, aborting");
65  m_errored = true;
66  return;
67  }
68 }
69 
71 {
72  delete m_rtjd;
73  delete [] m_ffmpegExtraData;
74  if (m_buf)
75  av_freep(&m_buf);
76  if (m_buf2)
77  av_freep(&m_buf2);
78  if (m_strm)
79  av_freep(&m_strm);
80 
81  av_freep(&m_audioSamples);
82 
83  while (!m_storedData.empty())
84  {
85  delete m_storedData.front();
86  m_storedData.pop_front();
87  }
90 }
91 
93  int /*testbufsize*/)
94 {
95  return strncmp(testbuf, "NuppelVideo", 11) == 0 ||
96  strncmp(testbuf, "MythTVVideo", 11) == 0;
97 }
98 
100 {
101  MythCodecID value = kCodec_NONE;
102  if (m_mpaVidCodec)
103  {
104  if (QString(m_mpaVidCodec->name) == "mpeg4")
105  value = kCodec_NUV_MPEG4;
106  }
107  else if (m_usingExtraData && m_extraData.video_fourcc == FOURCC_DIVX)
108  value = kCodec_NUV_MPEG4;
109  else
110  value = kCodec_NUV_RTjpeg;
111  return (value);
112 }
113 
115 {
116  if (m_mpaVidCtx)
117  return ff_codec_id_string(m_mpaVidCtx->codec_id);
118  return QString();
119 }
120 
122 {
124  return false; // NOLINT(readability-simplify-boolean-expr)
125 
126 #if HAVE_BIGENDIAN
127  fh->width = bswap_32(fh->width);
128  fh->height = bswap_32(fh->height);
129  fh->desiredwidth = bswap_32(fh->desiredwidth);
130  fh->desiredheight = bswap_32(fh->desiredheight);
131  fh->aspect = bswap_dbl(fh->aspect);
132  fh->fps = bswap_dbl(fh->fps);
133  fh->videoblocks = bswap_32(fh->videoblocks);
134  fh->audioblocks = bswap_32(fh->audioblocks);
135  fh->textsblocks = bswap_32(fh->textsblocks);
136  fh->keyframedist = bswap_32(fh->keyframedist);
137 #endif
138 
139  return true;
140 }
141 
143 {
145  return false; // NOLINT(readability-simplify-boolean-expr)
146 
147 #if HAVE_BIGENDIAN
148  fh->timecode = bswap_32(fh->timecode);
149  fh->packetlength = bswap_32(fh->packetlength);
150 #endif
151 
152  return true;
153 }
154 
155 int NuppelDecoder::OpenFile(MythMediaBuffer *rbuffer, bool novideo,
156  char testbuf[kDecoderProbeBufferSize],
157  int /*testbufsize*/)
158 {
159  (void)testbuf;
160 
161  m_ringBuffer = rbuffer;
162  m_disableVideo = novideo;
163  m_tracks[kTrackTypeVideo].clear();
164  StreamInfo si(0, 0, 0, 0, 0);
165  m_tracks[kTrackTypeVideo].push_back(si);
167 
168  struct rtframeheader frameheader {};
169  long long startpos = 0;
170 
172  {
173  LOG(VB_GENERAL, LOG_ERR,
174  QString("Error reading file: %1").arg(m_ringBuffer->GetFilename()));
175  return -1;
176  }
177 
178  while ((QString(m_fileHeader.finfo) != "NuppelVideo") &&
179  (QString(m_fileHeader.finfo) != "MythTVVideo"))
180  {
181  m_ringBuffer->Seek(startpos, SEEK_SET);
182  char dummychar = 0;
183  m_ringBuffer->Read(&dummychar, 1);
184 
185  startpos = m_ringBuffer->GetReadPosition();
186 
188  {
189  LOG(VB_GENERAL, LOG_ERR, QString("Error reading file: %1")
191  return -1;
192  }
193 
194  if (startpos > 20000)
195  {
196  LOG(VB_GENERAL, LOG_ERR, QString("Bad file: '%1'")
198  return -1;
199  }
200  }
201 
202  if (m_fileHeader.aspect > .999 && m_fileHeader.aspect < 1.001)
203  m_fileHeader.aspect = 4.0 / 3;
204  m_currentAspect = m_fileHeader.aspect;
205 
206  GetPlayer()->SetKeyframeDistance(m_fileHeader.keyframedist);
208  m_fileHeader.fps, m_currentAspect, false, 16);
209 
210  m_videoWidth = m_fileHeader.width;
211  m_videoHeight = m_fileHeader.height;
213  m_keyframeDist = m_fileHeader.keyframedist;
215 
216  if (!ReadFrameheader(&frameheader))
217  {
218  LOG(VB_GENERAL, LOG_ERR, "File not big enough for a header");
219  return -1;
220  }
221  if (frameheader.frametype != 'D')
222  {
223  LOG(VB_GENERAL, LOG_ERR, "Illegal file format");
224  return -1;
225  }
226 
227  char *space = new char[m_videoSize];
228 
229  if (frameheader.comptype == 'F')
230  {
231  m_ffmpegExtraDataSize = frameheader.packetlength;
232  if (m_ffmpegExtraDataSize > 0)
233  {
235  if (frameheader.packetlength != m_ringBuffer->Read(m_ffmpegExtraData,
236  frameheader.packetlength))
237  {
238  LOG(VB_GENERAL, LOG_ERR,
239  "File not big enough for first frame data");
240  delete [] m_ffmpegExtraData;
241  m_ffmpegExtraData = nullptr;
242  delete [] space;
243  return -1;
244  }
245  }
246  }
247  else
248  {
249  if (frameheader.packetlength != m_ringBuffer->Read(space,
250  frameheader.packetlength))
251  {
252  LOG(VB_GENERAL, LOG_ERR,
253  "File not big enough for first frame data");
254  delete [] space;
255  return -1;
256  }
257  }
258 
259  if ((m_videoHeight & 1) == 1)
260  {
261  m_videoHeight--;
262  LOG(VB_GENERAL, LOG_ERR,
263  QString("Incompatible video height, reducing to %1")
264  .arg( m_videoHeight));
265  }
266 
267  startpos = m_ringBuffer->GetReadPosition();
268 
269  ReadFrameheader(&frameheader);
270 
271  if (frameheader.frametype == 'X')
272  {
273  if (frameheader.packetlength != EXTENDEDSIZE)
274  {
275  LOG(VB_GENERAL, LOG_ERR, "Corrupt file. Bad extended frame.");
276  }
277  else
278  {
279  m_ringBuffer->Read(&m_extraData, frameheader.packetlength);
280 #if HAVE_BIGENDIAN
281  struct extendeddata *ed = &m_extraData;
282  ed->version = bswap_32(ed->version);
283  ed->video_fourcc = bswap_32(ed->video_fourcc);
284  ed->audio_fourcc = bswap_32(ed->audio_fourcc);
285  ed->audio_sample_rate = bswap_32(ed->audio_sample_rate);
286  ed->audio_bits_per_sample = bswap_32(ed->audio_bits_per_sample);
287  ed->audio_channels = bswap_32(ed->audio_channels);
289  ed->audio_quality = bswap_32(ed->audio_quality);
290  ed->rtjpeg_quality = bswap_32(ed->rtjpeg_quality);
291  ed->rtjpeg_luma_filter = bswap_32(ed->rtjpeg_luma_filter);
292  ed->rtjpeg_chroma_filter = bswap_32(ed->rtjpeg_chroma_filter);
293  ed->lavc_bitrate = bswap_32(ed->lavc_bitrate);
294  ed->lavc_qmin = bswap_32(ed->lavc_qmin);
295  ed->lavc_qmax = bswap_32(ed->lavc_qmax);
296  ed->lavc_maxqdiff = bswap_32(ed->lavc_maxqdiff);
297  ed->seektable_offset = bswap_64(ed->seektable_offset);
298  ed->keyframeadjust_offset = bswap_64(ed->keyframeadjust_offset);
299 #endif
300  m_usingExtraData = true;
301  ReadFrameheader(&frameheader);
302  }
303  }
304 
305  if (m_usingExtraData && m_extraData.seektable_offset > 0)
306  {
307  long long currentpos = m_ringBuffer->GetReadPosition();
308  struct rtframeheader seek_frameheader {};
309 
310  int seekret = m_ringBuffer->Seek(m_extraData.seektable_offset, SEEK_SET);
311  if (seekret == -1)
312  {
313  LOG(VB_GENERAL, LOG_ERR,
314  QString("NuppelDecoder::OpenFile(): seek error (%1)")
315  .arg(strerror(errno)));
316  }
317 
318  ReadFrameheader(&seek_frameheader);
319 
320  if (seek_frameheader.frametype != 'Q')
321  {
322  LOG(VB_GENERAL, LOG_ERR,
323  QString("Invalid seektable (frametype %1)")
324  .arg((int)seek_frameheader.frametype));
325  }
326  else
327  {
328  if (seek_frameheader.packetlength > 0)
329  {
330  char *seekbuf = new char[seek_frameheader.packetlength];
331  m_ringBuffer->Read(seekbuf, seek_frameheader.packetlength);
332 
333  int numentries = seek_frameheader.packetlength /
334  sizeof(struct seektable_entry);
335  struct seektable_entry ste {0, 0};
336  int offset = 0;
337 
338  m_positionMapLock.lock();
339 
340  m_positionMap.clear();
341  m_positionMap.reserve(numentries);
342 
343  for (int z = 0; z < numentries; z++)
344  {
345  memcpy(&ste, seekbuf + offset,
346  sizeof(struct seektable_entry));
347 #if HAVE_BIGENDIAN
348  ste.file_offset = bswap_64(ste.file_offset);
349  ste.keyframe_number = bswap_32(ste.keyframe_number);
350 #endif
351  offset += sizeof(struct seektable_entry);
352 
355  ste.file_offset};
356  m_positionMap.push_back(e);
357  uint64_t frame_num = ste.keyframe_number * m_keyframeDist;
358  m_frameToDurMap[frame_num] =
359  frame_num * 1000 / m_videoFrameRate;
360  m_durToFrameMap[m_frameToDurMap[frame_num]] = frame_num;
361  }
362  m_hasFullPositionMap = true;
363  m_totalLength = (int)((ste.keyframe_number * m_keyframeDist * 1.0) /
366 
367  m_positionMapLock.unlock();
368 
370 
371  delete [] seekbuf;
372  }
373  else
374  LOG(VB_GENERAL, LOG_ERR, "0 length seek table");
375  }
376 
377  m_ringBuffer->Seek(currentpos, SEEK_SET);
378  }
379 
380  if (m_usingExtraData && m_extraData.keyframeadjust_offset > 0 &&
382  {
383  long long currentpos = m_ringBuffer->GetReadPosition();
384  struct rtframeheader kfa_frameheader {};
385 
386  int kfa_ret = m_ringBuffer->Seek(m_extraData.keyframeadjust_offset,
387  SEEK_SET);
388  if (kfa_ret == -1)
389  {
390  LOG(VB_GENERAL, LOG_ERR,
391  QString("NuppelDecoder::OpenFile(): keyframeadjust (%1)")
392  .arg(strerror(errno)));
393  }
394 
395  m_ringBuffer->Read(&kfa_frameheader, FRAMEHEADERSIZE);
396 
397  if (kfa_frameheader.frametype != 'K')
398  {
399  LOG(VB_GENERAL, LOG_ERR,
400  QString("Invalid key frame adjust table (frametype %1)")
401  .arg((int)kfa_frameheader.frametype));
402  }
403  else
404  {
405  if (kfa_frameheader.packetlength > 0)
406  {
407  char *kfa_buf = new char[kfa_frameheader.packetlength];
408  m_ringBuffer->Read(kfa_buf, kfa_frameheader.packetlength);
409 
410  int numentries = kfa_frameheader.packetlength /
411  sizeof(struct kfatable_entry);
412  struct kfatable_entry kfate {};
413  int offset = 0;
414  int adjust = 0;
415  QMap<long long, int> keyFrameAdjustMap;
416 
417  for (int z = 0; z < numentries; z++)
418  {
419  memcpy(&kfate, kfa_buf + offset,
420  sizeof(struct kfatable_entry));
421 #if HAVE_BIGENDIAN
422  kfate.adjust = bswap_32(kfate.adjust);
423  kfate.keyframe_number = bswap_32(kfate.keyframe_number);
424 #endif
425  offset += sizeof(struct kfatable_entry);
426 
427  keyFrameAdjustMap[kfate.keyframe_number] = kfate.adjust;
428  adjust += kfate.adjust;
429  }
431 
435 
436  adjust = 0;
437 
438  {
439  QMutexLocker locker(&m_positionMapLock);
440  for (auto & entry : m_positionMap)
441  {
442  long long adj = entry.adjFrame;
443 
444  if (keyFrameAdjustMap.contains(adj))
445  adjust += keyFrameAdjustMap[adj];
446 
447  entry.adjFrame -= adjust;
448  }
449  }
450 
451  delete [] kfa_buf;
452  }
453  else
454  LOG(VB_GENERAL, LOG_ERR, "0 length key frame adjust table");
455  }
456 
457  m_ringBuffer->Seek(currentpos, SEEK_SET);
458  }
459 
460  while (frameheader.frametype != 'A' && frameheader.frametype != 'V' &&
461  frameheader.frametype != 'S' && frameheader.frametype != 'T' &&
462  frameheader.frametype != 'R')
463  {
464  m_ringBuffer->Seek(startpos, SEEK_SET);
465 
466  char dummychar = 0;
467  m_ringBuffer->Read(&dummychar, 1);
468 
469  startpos = m_ringBuffer->GetReadPosition();
470 
471  if (!ReadFrameheader(&frameheader))
472  {
473  delete [] space;
474  return -1;
475  }
476 
477  if (startpos > 20000)
478  {
479  delete [] space;
480  return -1;
481  }
482  }
483 
484  bool foundit = false;
485 
486  m_effDsp = m_audioSamplerate * 100;
488 
489  if (m_usingExtraData)
490  {
491  m_effDsp = m_extraData.audio_sample_rate * 100;
493  m_audioSamplerate = m_extraData.audio_sample_rate;
494 #if HAVE_BIGENDIAN
495  // Why only if using extradata?
496  m_audioBitsPerSample = m_extraData.audio_bits_per_sample;
497 #endif
498  AudioFormat format = FORMAT_NONE;
499  switch (m_extraData.audio_bits_per_sample)
500  {
501  case 8: format = FORMAT_U8; break;
502  case 16: format = FORMAT_S16; break;
503  case 24: format = FORMAT_S24; break;
504  case 32: format = FORMAT_S32; break;
505  }
506 
507  m_audio->SetAudioParams(format, m_extraData.audio_channels,
508  m_extraData.audio_channels,
509  AV_CODEC_ID_NONE, m_extraData.audio_sample_rate,
510  false /* AC3/DTS pass through */);
511  m_audio->ReinitAudio();
512  foundit = true;
513  }
514 
515  while (!foundit)
516  {
517  if (frameheader.frametype == 'S')
518  {
519  if (frameheader.comptype == 'A')
520  {
521  m_effDsp = frameheader.timecode;
522  if (m_effDsp > 0)
523  {
525  foundit = true;
526  continue;
527  }
528  }
529  }
530  if (frameheader.frametype != 'R' && frameheader.packetlength != 0)
531  {
532  if (frameheader.packetlength != m_ringBuffer->Read(space,
533  frameheader.packetlength))
534  {
535  foundit = true;
536  continue;
537  }
538  }
539 
540  long long startpos2 = m_ringBuffer->GetReadPosition();
541 
542  foundit = !ReadFrameheader(&frameheader);
543 
544  bool framesearch = false;
545 
546  while (frameheader.frametype != 'A' && frameheader.frametype != 'V' &&
547  frameheader.frametype != 'S' && frameheader.frametype != 'T' &&
548  frameheader.frametype != 'R' && frameheader.frametype != 'X')
549  {
550  if (!framesearch)
551  LOG(VB_GENERAL, LOG_INFO, "Searching for frame header.");
552 
553  framesearch = true;
554 
555  m_ringBuffer->Seek(startpos2, SEEK_SET);
556 
557  char dummychar = 0;
558  m_ringBuffer->Read(&dummychar, 1);
559 
560  startpos2 = m_ringBuffer->GetReadPosition();
561 
562  foundit = !ReadFrameheader(&frameheader);
563  if (foundit)
564  break;
565  }
566  }
567 
568  delete [] space;
569 
570  m_setReadAhead = false;
571 
572  // mpeg4 encodes are small enough that this shouldn't matter
573  if (m_usingExtraData && m_extraData.video_fourcc == FOURCC_DIVX)
574  m_setReadAhead = true;
575 
576  m_bitrate = 0;
577  unsigned min_bitrate = 1000;
578  if (m_usingExtraData && m_extraData.video_fourcc == FOURCC_DIVX)
579  {
580  // Use video bitrate, ignore negligible audio bitrate
581  m_bitrate = m_extraData.lavc_bitrate / 1000;
582  }
583  m_bitrate = max(m_bitrate, min_bitrate); // set minimum 1 Mb/s to be safe
584  LOG(VB_PLAYBACK, LOG_INFO,
585  QString("Setting bitrate to %1 Kb/s").arg(m_bitrate));
586 
588 
589  m_videoSizeTotal = 0;
590  m_videoFramesRead = 0;
591 
592  m_ringBuffer->Seek(startpos, SEEK_SET);
593 
594  m_buf = (unsigned char*)av_malloc(m_videoSize);
595  m_strm = (unsigned char*)av_malloc(m_videoSize * 2);
596 
598  return 1;
599 
600  if (SyncPositionMap())
601  return 1;
602 
603  return 0;
604 }
605 
606 void release_nuppel_buffer(void *opaque, uint8_t *data)
607 {
608  auto *frame = (VideoFrame*)data;
609  auto *nd = (NuppelDecoder*)opaque;
610  if (nd && nd->GetPlayer())
611  nd->GetPlayer()->DeLimboFrame(frame);
612 }
613 
614 int get_nuppel_buffer(struct AVCodecContext *c, AVFrame *pic, int /*flags*/)
615 {
616  auto *nd = (NuppelDecoder *)(c->opaque);
617 
618  for (int i = 0; i < 3; i++)
619  {
620  pic->data[i] = nd->m_directFrame->buf + nd->m_directFrame->offsets[i];
621  pic->linesize[i] = nd->m_directFrame->pitches[i];
622  }
623 
624  pic->opaque = nd->m_directFrame;
625 
626  // Set release method
627  AVBufferRef *buffer =
628  av_buffer_create((uint8_t*)nd->m_directFrame, 0, release_nuppel_buffer, nd, 0);
629  pic->buf[0] = buffer;
630 
631  return 0;
632 }
633 
635 {
636  if (m_mpaVidCodec)
638 
639  if (m_usingExtraData)
640  {
641  switch(m_extraData.video_fourcc)
642  {
643  case FOURCC_DIVX: codec = AV_CODEC_ID_MPEG4; break;
644  case FOURCC_WMV1: codec = AV_CODEC_ID_WMV1; break;
645  case FOURCC_DIV3: codec = AV_CODEC_ID_MSMPEG4V3; break;
646  case FOURCC_MP42: codec = AV_CODEC_ID_MSMPEG4V2; break;
647  case FOURCC_MPG4: codec = AV_CODEC_ID_MSMPEG4V1; break;
648  case FOURCC_MJPG: codec = AV_CODEC_ID_MJPEG; break;
649  case FOURCC_H263: codec = AV_CODEC_ID_H263; break;
650  case FOURCC_H264: codec = AV_CODEC_ID_H264; break;
651  case FOURCC_I263: codec = AV_CODEC_ID_H263I; break;
652  case FOURCC_MPEG: codec = AV_CODEC_ID_MPEG1VIDEO; break;
653  case FOURCC_MPG2: codec = AV_CODEC_ID_MPEG2VIDEO; break;
654  case FOURCC_HFYU: codec = AV_CODEC_ID_HUFFYUV; break;
655  default: codec = -1;
656  }
657  }
658  m_mpaVidCodec = avcodec_find_decoder((enum AVCodecID)codec);
659 
660  if (!m_mpaVidCodec)
661  {
662  if (m_usingExtraData)
663  {
664  LOG(VB_GENERAL, LOG_ERR,
665  QString("couldn't find video codec (%1)")
666  .arg(m_extraData.video_fourcc));
667  }
668  else
669  {
670  LOG(VB_GENERAL, LOG_ERR, "couldn't find video codec");
671  }
672  return false;
673  }
674 
675  if (m_mpaVidCodec->capabilities & AV_CODEC_CAP_DR1 && codec != AV_CODEC_ID_MJPEG)
676  m_directRendering = true;
677 
678  if (m_mpaVidCtx)
679  avcodec_free_context(&m_mpaVidCtx);
680 
681  m_mpaVidCtx = avcodec_alloc_context3(nullptr);
682 
683  m_mpaVidCtx->codec_id = (enum AVCodecID)codec;
684  m_mpaVidCtx->codec_type = AVMEDIA_TYPE_VIDEO;
685  m_mpaVidCtx->width = m_videoWidth;
686  m_mpaVidCtx->height = m_videoHeight;
687  m_mpaVidCtx->err_recognition = AV_EF_CRCCHECK | AV_EF_BITSTREAM |
688  AV_EF_BUFFER;
689  m_mpaVidCtx->bits_per_coded_sample = 12;
690 
691  if (m_directRendering)
692  {
693  // m_mpaVidCtx->flags |= CODEC_FLAG_EMU_EDGE;
694  m_mpaVidCtx->draw_horiz_band = nullptr;
695  m_mpaVidCtx->get_buffer2 = get_nuppel_buffer;
696  m_mpaVidCtx->opaque = (void *)this;
697  }
698  if (m_ffmpegExtraDataSize > 0)
699  {
700  av_opt_set_int(m_mpaVidCtx, "extern_huff", 1, 0);
701  m_mpaVidCtx->extradata = m_ffmpegExtraData;
702  m_mpaVidCtx->extradata_size = m_ffmpegExtraDataSize;
703  }
704 
705  if (avcodec_open2(m_mpaVidCtx, m_mpaVidCodec, nullptr) < 0)
706  {
707  LOG(VB_GENERAL, LOG_ERR, LOC + "Couldn't find lavc video codec");
708  return false;
709  }
710 
711  return true;
712 }
713 
715 {
716  if (m_mpaVidCodec && m_mpaVidCtx)
717  avcodec_free_context(&m_mpaVidCtx);
718 }
719 
721 {
722  if (m_mpaAudCodec)
724 
725  if (m_usingExtraData)
726  {
727  switch(m_extraData.audio_fourcc)
728  {
729  case FOURCC_LAME: codec = AV_CODEC_ID_MP3; break;
730  case FOURCC_AC3 : codec = AV_CODEC_ID_AC3; break;
731  default: codec = -1;
732  }
733  }
734  m_mpaAudCodec = avcodec_find_decoder((enum AVCodecID)codec);
735 
736  if (!m_mpaAudCodec)
737  {
738  if (m_usingExtraData)
739  {
740  LOG(VB_GENERAL, LOG_ERR, QString("couldn't find audio codec (%1)")
741  .arg(m_extraData.audio_fourcc));
742  }
743  else
744  {
745  LOG(VB_GENERAL, LOG_ERR, "couldn't find audio codec");
746  }
747  return false;
748  }
749 
750  if (m_mpaAudCtx)
751  avcodec_free_context(&m_mpaAudCtx);
752 
753  m_mpaAudCtx = avcodec_alloc_context3(nullptr);
754 
755  m_mpaAudCtx->codec_id = (enum AVCodecID)codec;
756  m_mpaAudCtx->codec_type = AVMEDIA_TYPE_AUDIO;
757 
758  if (avcodec_open2(m_mpaAudCtx, m_mpaAudCodec, nullptr) < 0)
759  {
760  LOG(VB_GENERAL, LOG_ERR, LOC + "Couldn't find lavc audio codec");
761  return false;
762  }
763 
764  return true;
765 }
766 
768 {
769  if (m_mpaAudCodec && m_mpaAudCtx)
770  avcodec_free_context(&m_mpaAudCtx);
771 }
772 
773 static void CopyToVideo(unsigned char *buf, int video_width,
774  int video_height, VideoFrame *frame)
775 {
776  (void)video_width;
777  (void)video_height;
778  copybuffer(frame, buf, frame->width);
779 }
780 
781 bool NuppelDecoder::DecodeFrame(struct rtframeheader *frameheader,
782  unsigned char *lstrm, VideoFrame *frame)
783 {
784  lzo_uint out_len = 0;
785  int compoff = 0;
786 
787  m_directFrame = frame;
788 
789  if (!m_buf2)
790  {
791  m_buf2 = (unsigned char*)av_malloc(m_videoSize + 64);
792  m_planes[0] = m_buf;
794  m_planes[2] = m_planes[1] + (m_videoWidth * m_videoHeight) / 4;
795  }
796 
797  if (frameheader->comptype == 'N')
798  {
799  memset(frame->buf, 0, frame->pitches[0] * m_videoHeight);
800  memset(frame->buf + frame->offsets[1], 127,
801  frame->pitches[1] * frame->height / 2);
802  memset(frame->buf + frame->offsets[2], 127,
803  frame->pitches[2] * frame->height / 2);
804  return true;
805  }
806 
807  if (frameheader->comptype == 'L')
808  {
809  switch(m_lastCt)
810  {
811  case '0': case '3':
813  break;
814  case '1': case '2':
815  default:
817  break;
818  }
819  return true;
820  }
821 
822  compoff = 1;
823  if (frameheader->comptype == '2' || frameheader->comptype == '3')
824  compoff=0;
825 
826  m_lastCt = frameheader->comptype;
827 
828  if (!compoff)
829  {
830  int r = lzo1x_decompress(lstrm, frameheader->packetlength, m_buf2, &out_len,
831  nullptr);
832  if (r != LZO_E_OK)
833  {
834  LOG(VB_GENERAL, LOG_ERR, "minilzo: can't decompress illegal data");
835  }
836  }
837 
838  if (frameheader->comptype == '0')
839  {
840  CopyToVideo(lstrm, m_videoWidth, m_videoHeight, frame);
841  return true;
842  }
843 
844  if (frameheader->comptype == '3')
845  {
847  return true;
848  }
849 
850  if (frameheader->comptype == '2' || frameheader->comptype == '1')
851  {
852  if (compoff)
853  m_rtjd->Decompress((int8_t*)lstrm, m_planes);
854  else
855  m_rtjd->Decompress((int8_t*)m_buf2, m_planes);
856 
858  }
859  else
860  {
861  if (!m_mpaVidCodec)
862  InitAVCodecVideo(frameheader->comptype - '3');
863 
864  if (!m_mpaVidCtx)
865  {
866  LOG(VB_PLAYBACK, LOG_ERR, LOC + "NULL mpa_vidctx");
867  return false;
868  }
869 
870  MythAVFrame mpa_pic;
871  if (!mpa_pic)
872  return false;
873  AVPacket pkt;
874  av_init_packet(&pkt);
875  pkt.data = lstrm;
876  pkt.size = frameheader->packetlength;
877 
878  // if directrendering, writes into buf
879  bool gotpicture = false;
880  // SUGGESTION
881  // Now that avcodec_decode_video2 is deprecated and replaced
882  // by 2 calls (receive frame and send packet), this could be optimized
883  // into separate routines or separate threads.
884  // Also now that it always consumes a whole buffer some code
885  // in the caller may be able to be optimized.
886  int ret = avcodec_receive_frame(m_mpaVidCtx, mpa_pic);
887  if (ret == 0)
888  gotpicture = true;
889  if (ret == AVERROR(EAGAIN))
890  ret = 0;
891  if (ret == 0)
892  ret = avcodec_send_packet(m_mpaVidCtx, &pkt);
893  m_directFrame = nullptr;
894  // The code assumes that there is always space to add a new
895  // packet. This seems risky but has always worked.
896  // It should actually check if (ret == AVERROR(EAGAIN)) and then keep
897  // the packet around and try it again after processing the frame
898  // received here.
899  if (ret < 0)
900  {
901  std::string error;
902  LOG(VB_GENERAL, LOG_ERR, LOC +
903  QString("video decode error: %1 (%2)")
905  .arg(gotpicture));
906  }
907  if (!gotpicture)
908  return false;
909 
910 /* XXX: Broken
911  if (mpa_pic->qscale_table != nullptr && mpa_pic->qstride > 0)
912  {
913  int tablesize = mpa_pic->qstride * ((m_videoHeight + 15) / 16);
914 
915  if (frame->qstride != mpa_pic->qstride ||
916  frame->qscale_table == nullptr)
917  {
918  frame->qstride = mpa_pic->qstride;
919 
920  if (frame->qscale_table)
921  delete [] frame->qscale_table;
922 
923  frame->qscale_table = new unsigned char[tablesize];
924  }
925 
926  memcpy(frame->qscale_table, mpa_pic->qscale_table, tablesize);
927  }
928 */
929 
930  if (m_directRendering)
931  return true;
932 
933  AVFrame *tmp = mpa_pic;
934  m_copyFrame.Copy(frame, tmp, m_mpaVidCtx->pix_fmt);
935  }
936 
937  return true;
938 }
939 
941 {
942  switch (type)
943  {
944  case 'A': case 'V': case 'S': case 'T': case 'R': case 'X':
945  case 'M': case 'D': case 'Q': case 'K':
946  return true;
947  default:
948  return false;
949  }
950 
951  return false;
952 }
953 
954 void NuppelDecoder::StoreRawData(unsigned char *newstrm)
955 {
956  unsigned char *strmcpy = nullptr;
957  if (newstrm)
958  {
959  strmcpy = new unsigned char[m_frameHeader.packetlength];
960  memcpy(strmcpy, newstrm, m_frameHeader.packetlength);
961  }
962 
963  m_storedData.push_back(new RawDataList(m_frameHeader, strmcpy));
964 }
965 
966 // The return value is the number of bytes in storedData before the 'SV' frame
968 {
969  long sync_offset = 0;
970 
971  for (auto *data : m_storedData)
972  {
973  if (data->frameheader.frametype == 'S' &&
974  data->frameheader.comptype == 'V')
975  {
976  data->frameheader.timecode = framenum;
977  return sync_offset;
978  }
979  sync_offset += FRAMEHEADERSIZE;
980  if (data->packet)
981  sync_offset += data->frameheader.packetlength;
982  }
983  return 0;
984 }
985 
987  long timecodeOffset)
988 {
989  while (!m_storedData.empty())
990  {
991  RawDataList *data = m_storedData.front();
992 
993  if (data->frameheader.frametype != 'S')
994  data->frameheader.timecode -= timecodeOffset;
995 
996  if (storevid || data->frameheader.frametype != 'V')
997  {
998  rb->Write(&(data->frameheader), FRAMEHEADERSIZE);
999  if (data->packet)
1000  rb->Write(data->packet, data->frameheader.packetlength);
1001  }
1002  m_storedData.pop_front();
1003  delete data;
1004  }
1005 }
1006 
1008 {
1009  while (!m_storedData.empty())
1010  {
1011  RawDataList *data = m_storedData.front();
1012  m_storedData.pop_front();
1013  delete data;
1014  }
1015 }
1016 
1017 bool NuppelDecoder::GetFrame(DecodeType decodetype, bool& /*Retry*/)
1018 {
1019  bool gotvideo = false;
1020  int seeklen = 0;
1021  AVPacket pkt;
1022 
1023  m_decodedVideoFrame = nullptr;
1024 
1025  while (!gotvideo)
1026  {
1027  long long currentposition = m_ringBuffer->GetReadPosition();
1028  if (m_waitingForChange && currentposition + 4 >= m_readAdjust)
1029  {
1030  FileChanged();
1031  currentposition = m_ringBuffer->GetReadPosition();
1032  }
1033 
1035  {
1036  SetEof(true);
1037  return false;
1038  }
1039 
1040 
1041  if (!m_ringBuffer->LiveMode() &&
1042  ((m_frameHeader.frametype == 'Q') || (m_frameHeader.frametype == 'K')))
1043  {
1044  SetEof(true);
1045  return false;
1046  }
1047 
1048  bool framesearch = false;
1049 
1050  while (!isValidFrametype(m_frameHeader.frametype))
1051  {
1052  if (!framesearch)
1053  LOG(VB_GENERAL, LOG_INFO, "Searching for frame header.");
1054 
1055  framesearch = true;
1056 
1057  m_ringBuffer->Seek((long long)seeklen-FRAMEHEADERSIZE, SEEK_CUR);
1058 
1060  {
1061  SetEof(true);
1062  return false;
1063  }
1064  seeklen = 1;
1065  }
1066 
1067  if (m_frameHeader.frametype == 'M')
1068  {
1069  int sizetoskip = sizeof(rtfileheader) - sizeof(rtframeheader);
1070  char *dummy = new char[sizetoskip + 1];
1071 
1072  if (m_ringBuffer->Read(dummy, sizetoskip) != sizetoskip)
1073  {
1074  delete [] dummy;
1075  SetEof(true);
1076  return false;
1077  }
1078 
1079  delete [] dummy;
1080  continue;
1081  }
1082 
1083  if (m_frameHeader.frametype == 'R')
1084  {
1085  if (m_getRawFrames)
1086  StoreRawData(nullptr);
1087  continue; // the R-frame has no data packet
1088  }
1089 
1090  if (m_frameHeader.frametype == 'S')
1091  {
1092  if (m_frameHeader.comptype == 'A')
1093  {
1094  if (m_frameHeader.timecode > 2000000 &&
1095  m_frameHeader.timecode < 5500000)
1096  {
1097  m_effDsp = m_frameHeader.timecode;
1099  }
1100  }
1101  else if (m_frameHeader.comptype == 'V')
1102  {
1103  m_lastKey = m_frameHeader.timecode;
1104  m_framesPlayed = (m_frameHeader.timecode > 0 ?
1105  m_frameHeader.timecode - 1 : 0);
1106 
1107  if (!m_hasFullPositionMap)
1108  {
1109  long long last_index = 0;
1110  long long this_index = m_lastKey / m_keyframeDist;
1111 
1112  QMutexLocker locker(&m_positionMapLock);
1113  if (!m_positionMap.empty())
1114  last_index = m_positionMap.back().index;
1115 
1116  if (this_index > last_index)
1117  {
1118  PosMapEntry e = {this_index, m_lastKey, currentposition};
1119  m_positionMap.push_back(e);
1121  m_lastKey * 1000 / m_videoFrameRate;
1123  }
1124  }
1125  }
1126  if (m_getRawFrames)
1127  StoreRawData(nullptr);
1128  }
1129 
1130  if (m_frameHeader.packetlength > 0)
1131  {
1132  if (m_frameHeader.packetlength > 10485760) // arbitrary 10MB limit
1133  {
1134  LOG(VB_GENERAL, LOG_ERR, QString("Broken packet: %1 %2")
1135  .arg(m_frameHeader.frametype)
1136  .arg(m_frameHeader.packetlength));
1137  SetEof(true);
1138  return false;
1139  }
1140  if (m_ringBuffer->Read(m_strm, m_frameHeader.packetlength) !=
1141  m_frameHeader.packetlength)
1142  {
1143  SetEof(true);
1144  return false;
1145  }
1146  }
1147  else
1148  continue;
1149 
1150  if (m_frameHeader.frametype == 'V')
1151  {
1152  if (!(kDecodeVideo & decodetype))
1153  {
1154  m_framesPlayed++;
1155  gotvideo = true;
1156  continue;
1157  }
1158 
1160  if (!buf)
1161  continue;
1162 
1163  bool ret = DecodeFrame(&m_frameHeader, m_strm, buf);
1164  if (!ret)
1165  {
1166  GetPlayer()->DiscardVideoFrame(buf);
1167  continue;
1168  }
1169 
1170  buf->aspect = m_currentAspect;
1171  buf->frameNumber = m_framesPlayed;
1172  buf->frameCounter = m_frameCounter++;
1173  buf->dummy = false;
1174  GetPlayer()->ReleaseNextVideoFrame(buf, m_frameHeader.timecode);
1175 
1176  // We need to make the frame available ourselves
1177  // if we are not using ffmpeg/avlib.
1178  if (m_directFrame)
1179  GetPlayer()->DeLimboFrame(buf);
1180 
1181  m_decodedVideoFrame = buf;
1182  gotvideo = true;
1185  m_framesPlayed++;
1186 
1187  if (!m_setReadAhead)
1188  {
1189  m_videoSizeTotal += m_frameHeader.packetlength;
1191 
1192  if (m_videoFramesRead > 15)
1193  {
1195 
1196  float bps = (m_videoSizeTotal * 8.0F / 1024.0F *
1197  static_cast<float>(m_videoFrameRate));
1198  m_bitrate = (uint) (bps * 1.5F);
1199 
1201  m_setReadAhead = true;
1202  }
1203  }
1204  continue;
1205  }
1206 
1207  if (m_frameHeader.frametype=='A' && (kDecodeAudio & decodetype))
1208  {
1209  if ((m_frameHeader.comptype == '3') || (m_frameHeader.comptype == 'A'))
1210  {
1211  if (m_getRawFrames)
1213 
1214  if (!m_mpaAudCodec)
1215  {
1216  if (m_frameHeader.comptype == '3')
1217  InitAVCodecAudio(AV_CODEC_ID_MP3);
1218  else if (m_frameHeader.comptype == 'A')
1219  InitAVCodecAudio(AV_CODEC_ID_AC3);
1220  else
1221  {
1222  LOG(VB_GENERAL, LOG_ERR, LOC + QString("GetFrame: "
1223  "Unknown audio comptype of '%1', skipping")
1224  .arg(m_frameHeader.comptype));
1225  return false;
1226  }
1227  }
1228 
1229  av_init_packet(&pkt);
1230  pkt.data = m_strm;
1231  pkt.size = m_frameHeader.packetlength;
1232 
1233  while (pkt.size > 0 && m_audio->HasAudioOut())
1234  {
1235  int data_size = 0;
1236 
1238  data_size, &pkt);
1239  if (ret < 0)
1240  {
1241  LOG(VB_GENERAL, LOG_ERR, LOC + "Unknown audio decoding error");
1242  return false;
1243  }
1244 
1245  pkt.size -= ret;
1246  pkt.data += ret;
1247  if (data_size <= 0)
1248  continue;
1249 
1250  m_audio->AddAudioData((char *)m_audioSamples, data_size,
1251  m_frameHeader.timecode, 0);
1252  }
1253  }
1254  else
1255  {
1256  m_getRawFrames = false;
1257 #if HAVE_BIGENDIAN
1258  // Why endian correct the audio buffer here?
1259  // Don't big-endian clients have to do it in audiooutBlah.cpp?
1260  if (m_audioBitsPerSample == 16) {
1261  // swap bytes
1262  for (int i = 0; i < (m_frameHeader.packetlength & ~1); i+=2) {
1263  char tmp;
1264  tmp = m_strm[i+1];
1265  m_strm[i+1] = m_strm[i];
1266  m_strm[i] = tmp;
1267  }
1268  }
1269 #endif
1270  LOG(VB_PLAYBACK, LOG_DEBUG, QString("A audio timecode %1")
1271  .arg(m_frameHeader.timecode));
1272  m_audio->AddAudioData((char *)m_strm, m_frameHeader.packetlength,
1273  m_frameHeader.timecode, 0);
1274  }
1275  }
1276 
1277  if (m_frameHeader.frametype == 'T' && (kDecodeVideo & decodetype))
1278  {
1279  if (m_getRawFrames)
1281 
1283  m_frameHeader.timecode, m_frameHeader.comptype);
1284  }
1285 
1286  if (m_frameHeader.frametype == 'S' && m_frameHeader.comptype == 'M')
1287  {
1288  unsigned char *eop = m_strm + m_frameHeader.packetlength;
1289  unsigned char *cur = m_strm;
1290 
1291  struct rtfileheader tmphead {};
1292  struct rtfileheader *fh = &tmphead;
1293 
1294  memcpy(fh, cur, min((int)sizeof(*fh), m_frameHeader.packetlength));
1295 
1296  while (QString(fh->finfo) != "MythTVVideo" &&
1297  cur + m_frameHeader.packetlength <= eop)
1298  {
1299  cur++;
1300  memcpy(fh, cur, min((int)sizeof(*fh), m_frameHeader.packetlength));
1301  }
1302 
1303  if (QString(fh->finfo) == "MythTVVideo")
1304  {
1305 #if HAVE_BIGENDIAN
1306  fh->width = bswap_32(fh->width);
1307  fh->height = bswap_32(fh->height);
1308  fh->desiredwidth = bswap_32(fh->desiredwidth);
1309  fh->desiredheight = bswap_32(fh->desiredheight);
1310  fh->aspect = bswap_dbl(fh->aspect);
1311  fh->fps = bswap_dbl(fh->fps);
1312  fh->videoblocks = bswap_32(fh->videoblocks);
1313  fh->audioblocks = bswap_32(fh->audioblocks);
1314  fh->textsblocks = bswap_32(fh->textsblocks);
1315  fh->keyframedist = bswap_32(fh->keyframedist);
1316 #endif
1317 
1318  m_fileHeader = *fh;
1319 
1320  if (m_fileHeader.aspect > .999 && m_fileHeader.aspect < 1.001)
1321  m_fileHeader.aspect = 4.0 / 3;
1322  m_currentAspect = m_fileHeader.aspect;
1323 
1324  GetPlayer()->SetKeyframeDistance(m_fileHeader.keyframedist);
1326  m_fileHeader.fps, m_currentAspect, false, 2);
1327  }
1328  }
1329  }
1330 
1332 
1333  return true;
1334 }
1335 
1336 void NuppelDecoder::SeekReset(long long newKey, uint skipFrames,
1337  bool doFlush, bool discardFrames)
1338 {
1339  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1340  QString("SeekReset(%1, %2, %3 flush, %4 discard)")
1341  .arg(newKey).arg(skipFrames)
1342  .arg((doFlush) ? "do" : "don't")
1343  .arg((discardFrames) ? "do" : "don't"));
1344 
1345  DecoderBase::SeekReset(newKey, skipFrames, doFlush, discardFrames);
1346 
1347  if (m_mpaVidCodec && doFlush)
1348  avcodec_flush_buffers(m_mpaVidCtx);
1349 
1350  if (discardFrames)
1351  GetPlayer()->DiscardVideoFrames(doFlush, false);
1352 
1353  for (;(skipFrames > 0) && !m_atEof; skipFrames--)
1354  {
1355  bool retry = false;
1356  GetFrame(kDecodeAV, retry);
1357  if (m_decodedVideoFrame)
1359  }
1360 }
1361 
1362 /* vim: set expandtab tabstop=4 shiftwidth=4: */
FORMAT_U8
@ FORMAT_U8
Definition: audiooutputsettings.h:27
rtframeheader
Definition: format.h:31
FORMAT_NONE
@ FORMAT_NONE
Definition: audiooutputsettings.h:26
kDecodeAV
@ kDecodeAV
Definition: decoderbase.h:51
AudioOutput::kMaxSizeBuffer
static const int kMaxSizeBuffer
kMaxSizeBuffer is the maximum size of a buffer to be used with DecodeAudio
Definition: audiooutput.h:195
copybuffer
static void copybuffer(VideoFrame *dst, uint8_t *buffer, int pitch, VideoFrameType type=FMT_YV12)
Definition: mythframe.h:701
extendeddata::version
int version
Definition: format.h:94
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1417
NuppelDecoder::ClearStoredData
void ClearStoredData(void) override
Definition: nuppeldecoder.cpp:1007
NuppelDecoder::m_totalLength
int m_totalLength
Definition: nuppeldecoder.h:108
FOURCC_I263
#define FOURCC_I263
Definition: fourcc.h:97
MARK_KEYFRAME
@ MARK_KEYFRAME
Definition: programtypes.h:62
rtfileheader::fps
double fps
Definition: format.h:23
DecoderBase::m_readAdjust
long long m_readAdjust
Definition: decoderbase.h:345
NuppelDecoder::OpenFile
int OpenFile(MythMediaBuffer *rbuffer, bool novideo, char testbuf[kDecoderProbeBufferSize], int testbufsize=kDecoderProbeBufferSize) override
Definition: nuppeldecoder.cpp:155
kDecoderProbeBufferSize
const int kDecoderProbeBufferSize
Definition: decoderbase.h:22
FILEHEADERSIZE
#define FILEHEADERSIZE
Definition: format.h:136
NuppelDecoder::m_audioSamples
uint8_t * m_audioSamples
Definition: nuppeldecoder.h:120
AudioPlayer::SetEffDsp
void SetEffDsp(int dsprate)
Definition: audioplayer.cpp:266
NuppelDecoder::~NuppelDecoder
~NuppelDecoder() override
Definition: nuppeldecoder.cpp:70
error
static void error(const char *str,...)
Definition: vbi.cpp:42
DecoderBase::m_ringBuffer
MythMediaBuffer * m_ringBuffer
Definition: decoderbase.h:290
FORMAT_S16
@ FORMAT_S16
Definition: audiooutputsettings.h:28
NuppelDecoder::m_totalFrames
long long m_totalFrames
Definition: nuppeldecoder.h:109
rtfileheader::height
int height
Definition: format.h:17
VideoFrame::pitches
int pitches[3]
Y, U, & V pitches.
Definition: mythframe.h:161
DecoderBase::PosMapEntry
Definition: decoderbase.h:280
NuppelDecoder::m_planes
unsigned char * m_planes[3]
Definition: nuppeldecoder.h:129
AudioPlayer::ReinitAudio
QString ReinitAudio(void)
Definition: audioplayer.cpp:104
space
Definition: space.py:1
extendeddata::lavc_maxqdiff
int lavc_maxqdiff
Definition: format.h:113
NuppelDecoder::m_effDsp
int m_effDsp
Definition: nuppeldecoder.h:111
kCodec_NONE
@ kCodec_NONE
Definition: mythcodecid.h:14
NuppelDecoder::m_extraData
Definition: nuppeldecoder.h:103
MythMediaBuffer::Seek
long long Seek(long long Position, int Whence, bool HasLock=false)
Definition: mythmediabuffer.cpp:496
DecoderBase::m_hasKeyFrameAdjustTable
bool m_hasKeyFrameAdjustTable
Definition: decoderbase.h:336
seektable_entry::file_offset
long long file_offset
Definition: format.h:125
DecoderBase::m_atEof
EofState m_atEof
Definition: decoderbase.h:310
DecoderBase::m_bitrate
uint m_bitrate
Definition: decoderbase.h:295
NuppelDecoder::m_buf2
unsigned char * m_buf2
Definition: nuppeldecoder.h:128
DecoderBase::m_frameCounter
unsigned long long m_frameCounter
Definition: decoderbase.h:302
NuppelDecoder::WriteStoredData
void WriteStoredData(MythMediaBuffer *rb, bool storevid, long timecodeOffset) override
Definition: nuppeldecoder.cpp:986
MythAVFrame
MythAVFrame little utility class that act as a safe way to allocate an AVFrame which can then be allo...
Definition: mythavutil.h:44
rtfileheader::width
int width
Definition: format.h:16
arg
arg(title).arg(filename).arg(doDelete))
NuppelDecoder::InitAVCodecVideo
bool InitAVCodecVideo(int codec)
Definition: nuppeldecoder.cpp:634
extendeddata::audio_channels
int audio_channels
Definition: format.h:100
kfatable_entry::keyframe_number
int keyframe_number
Definition: format.h:132
NuppelDecoder::InitAVCodecAudio
bool InitAVCodecAudio(int codec)
Definition: nuppeldecoder.cpp:720
FOURCC_HFYU
#define FOURCC_HFYU
Definition: fourcc.h:96
MythMediaBuffer::Write
int Write(const void *Buffer, uint Count)
Writes buffer to ThreadedFileWriter::Write(const void*,uint)
Definition: mythmediabuffer.cpp:1633
DecoderBase::m_hasFullPositionMap
bool m_hasFullPositionMap
Definition: decoderbase.h:320
NuppelDecoder::m_disableVideo
bool m_disableVideo
Definition: nuppeldecoder.h:106
rtfileheader::textsblocks
int textsblocks
Definition: format.h:26
rtfileheader::desiredheight
int desiredheight
Definition: format.h:19
NuppelDecoder::m_directFrame
VideoFrame * m_directFrame
Definition: nuppeldecoder.h:113
rtframeheader::timecode
int timecode
Definition: format.h:81
MythMediaBuffer
Definition: mythmediabuffer.h:50
seektable_entry
Definition: format.h:124
VideoFrame::buf
unsigned char * buf
Definition: mythframe.h:140
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
cc608reader.h
NuppelDecoder::m_videoSize
int m_videoSize
Definition: nuppeldecoder.h:93
AudioPlayer::HasAudioOut
bool HasAudioOut(void) const
Definition: audioplayer.h:53
mythplayer.h
DecoderBase::m_positionMapType
MarkTypes m_positionMapType
Definition: decoderbase.h:323
MythPlayer
Definition: mythplayer.h:165
FOURCC_AC3
#define FOURCC_AC3
Definition: fourcc.h:84
VideoFrame
Definition: mythframe.h:138
NuppelDecoder::CloseAVCodecAudio
void CloseAVCodecAudio(void)
Definition: nuppeldecoder.cpp:767
kfatable_entry
Definition: format.h:130
DecoderBase::GetRawBitrate
uint GetRawBitrate(void) const
Returns the estimated bitrate if the video were played at normal speed.
Definition: decoderbase.h:200
MythMediaBuffer::UpdateRawBitrate
void UpdateRawBitrate(uint RawBitrate)
Set the raw bit rate, to allow RingBuffer adjust effective bitrate.
Definition: mythmediabuffer.cpp:301
DecoderBase::m_frameToDurMap
frm_pos_map_t m_frameToDurMap
Definition: decoderbase.h:327
extendeddata::audio_fourcc
int audio_fourcc
Definition: format.h:96
rtfileheader::desiredwidth
int desiredwidth
Definition: format.h:18
RawDataList
Definition: nuppeldecoder.h:23
CopyToVideo
static void CopyToVideo(unsigned char *buf, int video_width, int video_height, VideoFrame *frame)
Definition: nuppeldecoder.cpp:773
MythPlayer::ReleaseNextVideoFrame
virtual void ReleaseNextVideoFrame(VideoFrame *buffer, int64_t timecode, bool wrap=true)
Places frame on the queue of frames ready for display.
Definition: mythplayer.cpp:976
extendeddata::rtjpeg_chroma_filter
int rtjpeg_chroma_filter
Definition: format.h:108
MythPlayer::DiscardVideoFrames
void DiscardVideoFrames(bool KeyFrame, bool Flushed)
Places frames in the available frames queue.
Definition: mythplayer.cpp:1015
NuppelDecoder::m_ffmpegExtraData
uint8_t * m_ffmpegExtraData
Definition: nuppeldecoder.h:101
FOURCC_MJPG
#define FOURCC_MJPG
Definition: fourcc.h:98
tmp
static guint32 * tmp
Definition: goom_core.cpp:30
rtfileheader
Definition: format.h:13
kCodec_NUV_MPEG4
@ kCodec_NUV_MPEG4
Definition: mythcodecid.h:19
NuppelDecoder::m_directRendering
bool m_directRendering
Definition: nuppeldecoder.h:122
DecoderBase::m_errored
bool m_errored
Definition: decoderbase.h:341
FRAMEHEADERSIZE
#define FRAMEHEADERSIZE
Definition: format.h:135
MythCodecID
MythCodecID
Definition: mythcodecid.h:11
AVFrame
struct AVFrame AVFrame
Definition: BorderDetector.h:15
MythPlayer::DiscardVideoFrame
void DiscardVideoFrame(VideoFrame *buffer)
Places frame in the available frames queue.
Definition: mythplayer.cpp:996
MythPlayer::DeLimboFrame
void DeLimboFrame(VideoFrame *frame)
Definition: mythplayer.cpp:1052
MythMediaBuffer::GetFilename
QString GetFilename(void) const
Definition: mythmediabuffer.cpp:1748
FOURCC_H264
#define FOURCC_H264
Definition: fourcc.h:95
DecoderBase::m_selectedTrack
StreamInfo m_selectedTrack[kTrackTypeCount]
Definition: decoderbase.h:354
NuppelDecoder::SeekReset
void SeekReset(long long newKey=0, uint skipFrames=0, bool doFlush=false, bool discardFrames=false) override
Definition: nuppeldecoder.cpp:1336
programinfo.h
DecoderBase::m_keyframeDist
int m_keyframeDist
Definition: decoderbase.h:304
DecoderBase::m_getRawFrames
bool m_getRawFrames
Definition: decoderbase.h:338
mythlogging.h
AudioPlayer::DecodeAudio
int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, const AVPacket *pkt)
DecodeAudio Utility routine.
Definition: audioplayer.cpp:541
NuppelDecoder::m_lastCt
char m_lastCt
Definition: nuppeldecoder.h:124
VideoFrame::dummy
bool dummy
Definition: mythframe.h:159
release_nuppel_buffer
void release_nuppel_buffer(void *opaque, uint8_t *data)
Definition: nuppeldecoder.cpp:606
StreamInfo
Definition: decoderbase.h:74
NuppelDecoder::StoreRawData
void StoreRawData(unsigned char *strm)
Definition: nuppeldecoder.cpp:954
FOURCC_LAME
#define FOURCC_LAME
Definition: fourcc.h:82
AudioPlayer::SetAudioParams
void SetAudioParams(AudioFormat format, int orig_channels, int channels, AVCodecID codec, int samplerate, bool passthru, int codec_profile=-1)
Set audio output parameters.
Definition: audioplayer.cpp:250
NuppelDecoder::m_mpaAudCodec
AVCodec * m_mpaAudCodec
Definition: nuppeldecoder.h:118
NuppelDecoder::NuppelDecoder
NuppelDecoder(MythPlayer *parent, const ProgramInfo &pginfo)
Definition: nuppeldecoder.cpp:40
NuppelDecoder::GetVideoCodecID
MythCodecID GetVideoCodecID(void) const override
Definition: nuppeldecoder.cpp:99
FORMAT_S24
@ FORMAT_S24
Definition: audiooutputsettings.h:30
NuppelDecoder::m_decodedVideoFrame
VideoFrame * m_decodedVideoFrame
Definition: nuppeldecoder.h:114
rtfileheader::videoblocks
int videoblocks
Definition: format.h:24
extendeddata::audio_compression_ratio
int audio_compression_ratio
Definition: format.h:103
DecoderBase::m_audio
AudioPlayer * m_audio
Definition: decoderbase.h:289
NuppelDecoder::m_videoSizeTotal
int m_videoSizeTotal
Definition: nuppeldecoder.h:133
rtframeheader::comptype
char comptype
Definition: format.h:39
RTJ_YUV420
#define RTJ_YUV420
Definition: RTjpegN.h:60
DecodeType
DecodeType
Definition: decoderbase.h:47
MythPlayer::GetCC608Reader
virtual CC608Reader * GetCC608Reader(uint=0)
Definition: mythplayer.h:330
DecoderBase::m_positionMapLock
QMutex m_positionMapLock
Definition: decoderbase.h:325
NuppelDecoder::m_audioSamplerate
int m_audioSamplerate
Definition: nuppeldecoder.h:95
kCodec_NUV_RTjpeg
@ kCodec_NUV_RTjpeg
Definition: mythcodecid.h:18
VideoFrame::aspect
float aspect
Definition: mythframe.h:144
NuppelDecoder
Definition: nuppeldecoder.h:34
DecoderBase::SetEof
virtual void SetEof(bool eof)
Definition: decoderbase.h:133
FORMAT_S32
@ FORMAT_S32
Definition: audiooutputsettings.h:31
FOURCC_WMV1
#define FOURCC_WMV1
Definition: fourcc.h:104
CC608Reader::AddTextData
void AddTextData(unsigned char *buf, int len, int64_t timecode, char type) override
Definition: cc608reader.cpp:488
hardwareprofile.smolt.long
long
Definition: smolt.py:76
RawDataList::frameheader
struct rtframeheader frameheader
Definition: nuppeldecoder.h:29
DecoderBase::m_getRawVideo
bool m_getRawVideo
Definition: decoderbase.h:339
NuppelDecoder::isValidFrametype
static bool isValidFrametype(char type)
Definition: nuppeldecoder.cpp:940
NuppelDecoder::ReadFileheader
bool ReadFileheader(struct rtfileheader *fh)
Definition: nuppeldecoder.cpp:121
DecoderBase::m_durToFrameMap
frm_pos_map_t m_durToFrameMap
Definition: decoderbase.h:328
NuppelDecoder::UpdateStoredFrameNum
long UpdateStoredFrameNum(long framenumber) override
Definition: nuppeldecoder.cpp:967
rtfileheader::finfo
char finfo[12]
Definition: format.h:14
MythMediaBuffer::LiveMode
bool LiveMode(void) const
Returns true if this RingBuffer has been assigned a LiveTVChain.
Definition: mythmediabuffer.cpp:1807
NuppelDecoder::get_nuppel_buffer
friend int get_nuppel_buffer(struct AVCodecContext *c, AVFrame *pic, int flags)
Definition: nuppeldecoder.cpp:614
uint
unsigned int uint
Definition: compat.h:140
DecoderBase::FileChanged
void FileChanged(void)
Definition: decoderbase.cpp:880
NuppelDecoder::m_frameHeader
Definition: nuppeldecoder.h:87
extendeddata::video_fourcc
int video_fourcc
Definition: format.h:95
DecoderBase::m_waitingForChange
bool m_waitingForChange
Definition: decoderbase.h:343
AudioPlayer::AddAudioData
void AddAudioData(char *buffer, int len, int64_t timecode, int frames)
Definition: audioplayer.cpp:453
rtfileheader::audioblocks
int audioblocks
Definition: format.h:25
NuppelDecoder::DecodeFrame
bool DecodeFrame(struct rtframeheader *frameheader, unsigned char *lstrm, VideoFrame *frame)
Definition: nuppeldecoder.cpp:781
DecoderBase::m_currentAspect
float m_currentAspect
Definition: decoderbase.h:298
DecoderBase::SyncPositionMap
virtual bool SyncPositionMap(void)
Updates the position map used for skipping frames.
Definition: decoderbase.cpp:320
FOURCC_MPG4
#define FOURCC_MPG4
Definition: fourcc.h:102
extendeddata::audio_bits_per_sample
int audio_bits_per_sample
Definition: format.h:99
extendeddata::lavc_bitrate
int lavc_bitrate
Definition: format.h:110
NuppelDecoder::m_buf
unsigned char * m_buf
Definition: nuppeldecoder.h:127
MythMediaBuffer::Read
int Read(void *Buffer, int Count)
This is the public method for reading from a file, it calls the appropriate read method if the file i...
Definition: mythmediabuffer.cpp:1495
DecoderBase::m_tracks
vector< StreamInfo > m_tracks[kTrackTypeCount]
Definition: decoderbase.h:352
RawDataList::packet
unsigned char * packet
Definition: nuppeldecoder.h:30
RTjpeg
Definition: RTjpegN.h:65
nuppeldecoder.h
MythPlayer::SetFileLength
void SetFileLength(int total, int frames)
Definition: mythplayer.cpp:743
extendeddata::lavc_qmin
int lavc_qmin
Definition: format.h:111
NuppelDecoder::m_videoFrameRate
double m_videoFrameRate
Definition: nuppeldecoder.h:94
kDecodeVideo
@ kDecodeVideo
Definition: decoderbase.h:49
MythPlayer::SetKeyframeDistance
void SetKeyframeDistance(int keyframedistance)
Definition: mythplayer.cpp:521
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:68
VideoFrame::offsets
int offsets[3]
Y, U, & V offsets.
Definition: mythframe.h:162
NuppelDecoder::m_videoFramesRead
int m_videoFramesRead
Definition: nuppeldecoder.h:134
DecoderBase::m_framesPlayed
long long m_framesPlayed
Definition: decoderbase.h:300
FOURCC_MPG2
#define FOURCC_MPG2
Definition: fourcc.h:101
NuppelDecoder::m_mpaAudCtx
AVCodecContext * m_mpaAudCtx
Definition: nuppeldecoder.h:119
extendeddata::keyframeadjust_offset
long long keyframeadjust_offset
Definition: format.h:117
bswap_dbl
#define bswap_dbl(x)
Definition: bswap.h:6
RTjpeg::SetFormat
int SetFormat(const int *fmt)
Definition: RTjpegN.cpp:2684
NuppelDecoder::GetFrame
bool GetFrame(DecodeType, bool &) override
Demux, preprocess and possibly decode a frame of video/audio.
Definition: nuppeldecoder.cpp:1017
NuppelDecoder::GetRawEncodingType
QString GetRawEncodingType(void) override
Definition: nuppeldecoder.cpp:114
audiooutput.h
extendeddata::audio_sample_rate
int audio_sample_rate
Definition: format.h:98
bswap.h
mythavutil.h
NuppelDecoder::CloseAVCodecVideo
void CloseAVCodecVideo(void)
Definition: nuppeldecoder.cpp:714
rtframeheader::packetlength
int packetlength
Definition: format.h:83
MythMediaBuffer::GetReadPosition
virtual long long GetReadPosition(void) const =0
rtfileheader::aspect
double aspect
Definition: format.h:22
NuppelDecoder::m_videoHeight
int m_videoHeight
Definition: nuppeldecoder.h:92
extendeddata
Definition: format.h:93
FOURCC_MP42
#define FOURCC_MP42
Definition: fourcc.h:99
MythPlayer::GetNextVideoFrame
VideoFrame * GetNextVideoFrame(void)
Removes a frame from the available queue for decoding onto.
Definition: mythplayer.cpp:966
extendeddata::rtjpeg_quality
int rtjpeg_quality
Definition: format.h:106
extendeddata::audio_quality
int audio_quality
Definition: format.h:104
VideoFrame::height
int height
Definition: mythframe.h:143
VideoFrame::frameNumber
long long frameNumber
Definition: mythframe.h:148
MythPlayer::SetVideoParams
void SetVideoParams(int w, int h, double fps, float aspect, bool ForceUpdate, int ReferenceFrames, FrameScanType scan=kScan_Ignore, const QString &codecName=QString())
Definition: mythplayer.cpp:674
FOURCC_MPEG
#define FOURCC_MPEG
Definition: fourcc.h:100
NuppelDecoder::m_rtjd
RTjpeg * m_rtjd
Definition: nuppeldecoder.h:89
RTjpeg::Decompress
void Decompress(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:3307
NuppelDecoder::m_mpaVidCtx
AVCodecContext * m_mpaVidCtx
Definition: nuppeldecoder.h:117
NuppelDecoder::m_ffmpegExtraDataSize
int m_ffmpegExtraDataSize
Definition: nuppeldecoder.h:100
NuppelDecoder::m_strm
unsigned char * m_strm
Definition: nuppeldecoder.h:126
audioplayer.h
NuppelDecoder::m_storedData
list< RawDataList * > m_storedData
Definition: nuppeldecoder.h:131
extendeddata::rtjpeg_luma_filter
int rtjpeg_luma_filter
Definition: format.h:107
FOURCC_DIVX
#define FOURCC_DIVX
Definition: fourcc.h:92
NuppelDecoder::CanHandle
static bool CanHandle(char testbuf[kDecoderProbeBufferSize], int testbufsize=kDecoderProbeBufferSize)
Definition: nuppeldecoder.cpp:92
NuppelDecoder::m_setReadAhead
bool m_setReadAhead
Definition: nuppeldecoder.h:135
FOURCC_H263
#define FOURCC_H263
Definition: fourcc.h:94
av_malloc
void * av_malloc(unsigned int size)
DecoderBase::m_lastKey
long long m_lastKey
Definition: decoderbase.h:305
NuppelDecoder::m_usingExtraData
bool m_usingExtraData
Definition: nuppeldecoder.h:104
LOC
#define LOC
Definition: nuppeldecoder.cpp:38
kTrackTypeVideo
@ kTrackTypeVideo
Definition: decoderbase.h:29
MythAVCopy::Copy
int Copy(VideoFrame *dst, const VideoFrame *src)
Definition: mythavutil.cpp:331
RTjpegN.h
DecoderBase::m_positionMap
vector< PosMapEntry > m_positionMap
Definition: decoderbase.h:326
DecoderBase::m_framesRead
long long m_framesRead
Definition: decoderbase.h:301
VideoFrame::frameCounter
long long frameCounter
raw frame counter/ticker for discontinuity checks
Definition: mythframe.h:149
seektable_entry::keyframe_number
int keyframe_number
Definition: format.h:126
extendeddata::lavc_qmax
int lavc_qmax
Definition: format.h:112
DecoderBase::m_copyFrame
MythAVCopy m_copyFrame
Definition: decoderbase.h:307
NuppelDecoder::m_fileHeader
Definition: nuppeldecoder.h:86
AudioFormat
AudioFormat
Definition: audiooutputsettings.h:25
audiooutputsettings.h
DecoderBase::SeekReset
virtual void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames)
Definition: decoderbase.cpp:70
kfatable_entry::adjust
int adjust
Definition: format.h:131
kDecodeAudio
@ kDecodeAudio
Definition: decoderbase.h:50
NuppelDecoder::ReadFrameheader
bool ReadFrameheader(struct rtframeheader *fh)
Definition: nuppeldecoder.cpp:142
rtframeheader::frametype
char frametype
Definition: format.h:32
VideoFrame::width
int width
Definition: mythframe.h:142
rtfileheader::keyframedist
int keyframedist
Definition: format.h:27
av_make_error_stdstring
char * av_make_error_stdstring(std::string &errbuf, int errnum)
Definition: mythaverror.cpp:41
DecoderBase
Definition: decoderbase.h:120
FOURCC_DIV3
#define FOURCC_DIV3
Definition: fourcc.h:91
NuppelDecoder::m_mpaVidCodec
AVCodec * m_mpaVidCodec
Definition: nuppeldecoder.h:116
NuppelDecoder::m_videoWidth
int m_videoWidth
Definition: nuppeldecoder.h:91
get_nuppel_buffer
int get_nuppel_buffer(struct AVCodecContext *c, AVFrame *pic, int)
Definition: nuppeldecoder.cpp:614
DecoderBase::GetPlayer
MythPlayer * GetPlayer()
Definition: decoderbase.h:153
extendeddata::seektable_offset
long long seektable_offset
Definition: format.h:115
EXTENDEDSIZE
#define EXTENDEDSIZE
Definition: format.h:137
fourcc.h