1
0
mirror of https://github.com/rofafor/vdr-plugin-femon.git synced 2023-10-10 13:36:53 +02:00

Add preliminary H.265 support.

This commit is contained in:
Rolf Ahrenberg 2017-01-05 17:55:53 +02:00
parent cc586c3eb4
commit ba767e02bf
10 changed files with 203 additions and 3 deletions

View File

@ -61,7 +61,7 @@ all-redirect: all
### The object files (add further files here): ### The object files (add further files here):
OBJS = $(PLUGIN).o aac.o ac3.o config.o h264.o latm.o mpeg.o osd.o receiver.o setup.o symbol.o tools.o OBJS = $(PLUGIN).o aac.o ac3.o config.o h264.o h265.o latm.o mpeg.o osd.o receiver.o setup.o symbol.o tools.o
### The main target: ### The main target:

118
h265.c Normal file
View File

@ -0,0 +1,118 @@
/*
* h265.c: Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#include "log.h"
#include "tools.h"
#include "h265.h"
cFemonH265::cFemonH265(cFemonVideoIf *videoHandlerP)
: videoHandlerM(videoHandlerP),
widthM(0),
heightM(0),
aspectRatioM(VIDEO_ASPECT_RATIO_INVALID),
formatM(VIDEO_FORMAT_INVALID),
frameRateM(0),
bitRateM(0),
scanM(VIDEO_SCAN_INVALID)
{
reset();
}
cFemonH265::~cFemonH265()
{
}
bool cFemonH265::processVideo(const uint8_t *bufP, int lenP)
{
bool aud_found = false;
const uint8_t *buf = bufP;
const uint8_t *start = buf;
const uint8_t *end = start + lenP;
if (!videoHandlerM)
return false;
// skip PES header
if (!PesLongEnough(lenP))
return false;
buf += PesPayloadOffset(buf);
start = buf;
reset();
for (;;) {
int consumed = 0;
buf = nextStartCode(buf, end);
if (buf >= end)
break;
switch ((buf[3] >> 1) & 0x3F) {
case NAL_AUD:
if (!aud_found) {
aud_found = true;
debug2("%s Found NAL AUD at offset %d/%d", __PRETTY_FUNCTION__, int(buf - start), lenP);
}
break;
default:
break;
}
if (aud_found)
break;
buf += consumed + 4;
}
if (aud_found) {
videoHandlerM->SetVideoCodec(VIDEO_CODEC_H265);
//videoHandlerM->SetVideoFormat(formatM);
//videoHandlerM->SetVideoSize(widthM, heightM);
//videoHandlerM->SetVideoAspectRatio(aspectRatioM);
//videoHandlerM->SetVideoBitrate(bitRateM);
//videoHandlerM->SetVideoScan(scanM);
//videoHandlerM->SetVideoFramerate((scanM == VIDEO_SCAN_PROGRESSIVE) ? (frameRateM / 2) : frameRateM);
}
return aud_found;
}
void cFemonH265::reset()
{
}
const uint8_t *cFemonH265::nextStartCode(const uint8_t *startP, const uint8_t *endP)
{
for (endP -= 3; startP < endP; ++startP) {
if ((startP[0] == 0x00) && (startP[1] == 0x00) && (startP[2] == 0x01))
return startP;
}
return (endP + 3);
}
int cFemonH265::nalUnescape(uint8_t *dstP, const uint8_t *srcP, int lenP)
{
int s = 0, d = 0;
while (s < lenP) {
if (!srcP[s] && !srcP[s + 1]) {
// hit 00 00 xx
dstP[d] = dstP[d + 1] = 0;
s += 2;
d += 2;
if (srcP[s] == 3) {
s++; // 00 00 03 xx --> 00 00 xx
if (s >= lenP)
return d;
}
}
dstP[d++] = srcP[s++];
}
return d;
}

44
h265.h Normal file
View File

@ -0,0 +1,44 @@
/*
* h265.h: Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#ifndef __FEMON_H265_H
#define __FEMON_H265_H
#include "video.h"
class cFemonH265 {
private:
enum {
NAL_VPS = 32, // Video Parameter Set
NAL_SPS = 33, // Sequence Parameter Set
NAL_PPS = 34, // Picture Parameter Set
NAL_AUD = 35, // Access Unit Delimiter
NAL_EOS = 36, // End of Sequence
NAL_EOB = 37, // End of Bitstream
};
cFemonVideoIf *videoHandlerM;
uint32_t widthM;
uint32_t heightM;
eVideoAspectRatio aspectRatioM;
eVideoFormat formatM;
double frameRateM;
double bitRateM;
eVideoScan scanM;
void reset();
const uint8_t *nextStartCode(const uint8_t *start, const uint8_t *end);
int nalUnescape(uint8_t *dst, const uint8_t *src, int len);
public:
cFemonH265(cFemonVideoIf *videoHandlerP);
virtual ~cFemonH265();
bool processVideo(const uint8_t *bufP, int lenP);
};
#endif //__FEMON_H265_H

1
osd.c
View File

@ -341,6 +341,7 @@ void cFemonOsd::DrawStatusWindow(void)
switch (receiverM->VideoCodec()) { switch (receiverM->VideoCodec()) {
case VIDEO_CODEC_MPEG2: bm = &OSDSYMBOL(SYMBOL_MPEG2); break; case VIDEO_CODEC_MPEG2: bm = &OSDSYMBOL(SYMBOL_MPEG2); break;
case VIDEO_CODEC_H264: bm = &OSDSYMBOL(SYMBOL_H264); break; case VIDEO_CODEC_H264: bm = &OSDSYMBOL(SYMBOL_H264); break;
case VIDEO_CODEC_H265: bm = &OSDSYMBOL(SYMBOL_H265); break;
default: bm = NULL; break; default: bm = NULL; break;
} }
OSDDRAWSTATUSBM(OSDSPACING); OSDDRAWSTATUSBM(OSDSPACING);

View File

@ -19,6 +19,7 @@ cFemonReceiver::cFemonReceiver(const cChannel *channelP, int aTrackP, int dTrack
sleepM(), sleepM(),
activeM(false), activeM(false),
detectH264M(this), detectH264M(this),
detectH265M(this),
detectMpegM(this, this), detectMpegM(this, this),
detectAacM(this), detectAacM(this),
detectLatmM(this), detectLatmM(this),
@ -163,12 +164,18 @@ void cFemonReceiver::Action(void)
processed = true; processed = true;
if (TsPayloadStart(Data)) { if (TsPayloadStart(Data)) {
while (const uint8_t *p = videoAssemblerM.GetPes(len)) { while (const uint8_t *p = videoAssemblerM.GetPes(len)) {
if (videoTypeM == 0x1B) { // MPEG4 if (videoTypeM == 0x1B) {
if (detectH264M.processVideo(p, len)) { if (detectH264M.processVideo(p, len)) {
videoValidM = true; videoValidM = true;
break; break;
} }
} }
else if (videoTypeM == 0x24) {
if (detectH265M.processVideo(p, len)) {
videoValidM = true;
break;
}
}
else { else {
if (detectMpegM.processVideo(p, len)) { if (detectMpegM.processVideo(p, len)) {
videoValidM = true; videoValidM = true;

View File

@ -15,6 +15,7 @@
#include "ac3.h" #include "ac3.h"
#include "audio.h" #include "audio.h"
#include "h264.h" #include "h264.h"
#include "h265.h"
#include "latm.h" #include "latm.h"
#include "mpeg.h" #include "mpeg.h"
#include "tools.h" #include "tools.h"
@ -27,6 +28,7 @@ private:
bool activeM; bool activeM;
cFemonH264 detectH264M; cFemonH264 detectH264M;
cFemonH265 detectH265M;
cFemonMPEG detectMpegM; cFemonMPEG detectMpegM;
cFemonAAC detectAacM; cFemonAAC detectAacM;
cFemonLATM detectLatmM; cFemonLATM detectLatmM;

View File

@ -19,6 +19,7 @@
#include "symbols/dolbydigital51.xpm" #include "symbols/dolbydigital51.xpm"
#include "symbols/mpeg2.xpm" #include "symbols/mpeg2.xpm"
#include "symbols/h264.xpm" #include "symbols/h264.xpm"
#include "symbols/h265.xpm"
#include "symbols/ntsc.xpm" #include "symbols/ntsc.xpm"
#include "symbols/pal.xpm" #include "symbols/pal.xpm"
#include "symbols/encrypted.xpm" #include "symbols/encrypted.xpm"
@ -64,6 +65,7 @@ static cBitmap bmDolbyDigital20(dolbydigital20_xpm);
static cBitmap bmDolbyDigital51(dolbydigital51_xpm); static cBitmap bmDolbyDigital51(dolbydigital51_xpm);
static cBitmap bmMpeg2(mpeg2_xpm); static cBitmap bmMpeg2(mpeg2_xpm);
static cBitmap bmH264(h264_xpm); static cBitmap bmH264(h264_xpm);
static cBitmap bmH265(h265_xpm);
static cBitmap bmPal(pal_xpm); static cBitmap bmPal(pal_xpm);
static cBitmap bmNtsc(ntsc_xpm); static cBitmap bmNtsc(ntsc_xpm);
static cBitmap bmEncrypted(encrypted_xpm); static cBitmap bmEncrypted(encrypted_xpm);
@ -146,6 +148,7 @@ bool cFemonSymbolCache::Populate(void)
cacheM.Append(bmDolbyDigital51.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DD51 cacheM.Append(bmDolbyDigital51.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_DD51
cacheM.Append(bmMpeg2.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_MPEG2 cacheM.Append(bmMpeg2.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_MPEG2
cacheM.Append(bmH264.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_H264 cacheM.Append(bmH264.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_H264
cacheM.Append(bmH265.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_H265
cacheM.Append(bmPal.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_PAL cacheM.Append(bmPal.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_PAL
cacheM.Append(bmNtsc.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_NTSC cacheM.Append(bmNtsc.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_NTSC
cacheM.Append(bmEncrypted.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ENCRYPTED cacheM.Append(bmEncrypted.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ENCRYPTED

View File

@ -21,6 +21,7 @@ enum eSymbols {
SYMBOL_DD51, SYMBOL_DD51,
SYMBOL_MPEG2, SYMBOL_MPEG2,
SYMBOL_H264, SYMBOL_H264,
SYMBOL_H265,
SYMBOL_PAL, SYMBOL_PAL,
SYMBOL_NTSC, SYMBOL_NTSC,
SYMBOL_ENCRYPTED, SYMBOL_ENCRYPTED,

23
symbols/h265.xpm Normal file
View File

@ -0,0 +1,23 @@
/* XPM */
static const char *const h265_xpm[] = {
"40 18 2 1",
". c #FFFFFF",
"+ c #000000",
"++++++++++++++++++++++++++++++++++++++++",
"+......................................+",
"+..++...++.....+++++...+++++..+++++++..+",
"+..++...++....+++++++.+++++++.+++++++..+",
"+..++...++....++...++.++...++.++.......+",
"+..++...++.........++.++......++.......+",
"+..++...++.........++.++......++.......+",
"+..++...++........+++.++......++.......+",
"+..+++++++.......+++..++++++..++++++...+",
"+..+++++++......+++...+++++++.+++++++..+",
"+..++...++.....+++....++...++.....+++..+",
"+..++...++....+++.....++...++......++..+",
"+..++...++....++......++...++......++..+",
"+..++...++....++...++.++...++.++...++..+",
"+..++...++.++.+++++++.+++++++.++...++..+",
"+..++...++.++.+++++++..+++++...+++++...+",
"+......................................+",
"++++++++++++++++++++++++++++++++++++++++"};

View File

@ -12,7 +12,8 @@ enum eVideoCodec {
VIDEO_CODEC_INVALID = -1, VIDEO_CODEC_INVALID = -1,
VIDEO_CODEC_UNKNOWN, VIDEO_CODEC_UNKNOWN,
VIDEO_CODEC_MPEG2, VIDEO_CODEC_MPEG2,
VIDEO_CODEC_H264 VIDEO_CODEC_H264,
VIDEO_CODEC_H265
}; };
enum eVideoFormat { enum eVideoFormat {