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:
parent
cc586c3eb4
commit
ba767e02bf
2
Makefile
2
Makefile
@ -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
118
h265.c
Normal 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
44
h265.h
Normal 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
1
osd.c
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
3
symbol.c
3
symbol.c
@ -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
|
||||||
|
1
symbol.h
1
symbol.h
@ -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
23
symbols/h265.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static const char *const h265_xpm[] = {
|
||||||
|
"40 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"++++++++++++++++++++++++++++++++++++++++",
|
||||||
|
"+......................................+",
|
||||||
|
"+..++...++.....+++++...+++++..+++++++..+",
|
||||||
|
"+..++...++....+++++++.+++++++.+++++++..+",
|
||||||
|
"+..++...++....++...++.++...++.++.......+",
|
||||||
|
"+..++...++.........++.++......++.......+",
|
||||||
|
"+..++...++.........++.++......++.......+",
|
||||||
|
"+..++...++........+++.++......++.......+",
|
||||||
|
"+..+++++++.......+++..++++++..++++++...+",
|
||||||
|
"+..+++++++......+++...+++++++.+++++++..+",
|
||||||
|
"+..++...++.....+++....++...++.....+++..+",
|
||||||
|
"+..++...++....+++.....++...++......++..+",
|
||||||
|
"+..++...++....++......++...++......++..+",
|
||||||
|
"+..++...++....++...++.++...++.++...++..+",
|
||||||
|
"+..++...++.++.+++++++.+++++++.++...++..+",
|
||||||
|
"+..++...++.++.+++++++..+++++...+++++...+",
|
||||||
|
"+......................................+",
|
||||||
|
"++++++++++++++++++++++++++++++++++++++++"};
|
Loading…
Reference in New Issue
Block a user