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):
|
||||
|
||||
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:
|
||||
|
||||
|
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()) {
|
||||
case VIDEO_CODEC_MPEG2: bm = &OSDSYMBOL(SYMBOL_MPEG2); break;
|
||||
case VIDEO_CODEC_H264: bm = &OSDSYMBOL(SYMBOL_H264); break;
|
||||
case VIDEO_CODEC_H265: bm = &OSDSYMBOL(SYMBOL_H265); break;
|
||||
default: bm = NULL; break;
|
||||
}
|
||||
OSDDRAWSTATUSBM(OSDSPACING);
|
||||
|
@ -19,6 +19,7 @@ cFemonReceiver::cFemonReceiver(const cChannel *channelP, int aTrackP, int dTrack
|
||||
sleepM(),
|
||||
activeM(false),
|
||||
detectH264M(this),
|
||||
detectH265M(this),
|
||||
detectMpegM(this, this),
|
||||
detectAacM(this),
|
||||
detectLatmM(this),
|
||||
@ -163,12 +164,18 @@ void cFemonReceiver::Action(void)
|
||||
processed = true;
|
||||
if (TsPayloadStart(Data)) {
|
||||
while (const uint8_t *p = videoAssemblerM.GetPes(len)) {
|
||||
if (videoTypeM == 0x1B) { // MPEG4
|
||||
if (videoTypeM == 0x1B) {
|
||||
if (detectH264M.processVideo(p, len)) {
|
||||
videoValidM = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (videoTypeM == 0x24) {
|
||||
if (detectH265M.processVideo(p, len)) {
|
||||
videoValidM = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (detectMpegM.processVideo(p, len)) {
|
||||
videoValidM = true;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "ac3.h"
|
||||
#include "audio.h"
|
||||
#include "h264.h"
|
||||
#include "h265.h"
|
||||
#include "latm.h"
|
||||
#include "mpeg.h"
|
||||
#include "tools.h"
|
||||
@ -27,6 +28,7 @@ private:
|
||||
bool activeM;
|
||||
|
||||
cFemonH264 detectH264M;
|
||||
cFemonH265 detectH265M;
|
||||
cFemonMPEG detectMpegM;
|
||||
cFemonAAC detectAacM;
|
||||
cFemonLATM detectLatmM;
|
||||
|
3
symbol.c
3
symbol.c
@ -19,6 +19,7 @@
|
||||
#include "symbols/dolbydigital51.xpm"
|
||||
#include "symbols/mpeg2.xpm"
|
||||
#include "symbols/h264.xpm"
|
||||
#include "symbols/h265.xpm"
|
||||
#include "symbols/ntsc.xpm"
|
||||
#include "symbols/pal.xpm"
|
||||
#include "symbols/encrypted.xpm"
|
||||
@ -64,6 +65,7 @@ static cBitmap bmDolbyDigital20(dolbydigital20_xpm);
|
||||
static cBitmap bmDolbyDigital51(dolbydigital51_xpm);
|
||||
static cBitmap bmMpeg2(mpeg2_xpm);
|
||||
static cBitmap bmH264(h264_xpm);
|
||||
static cBitmap bmH265(h265_xpm);
|
||||
static cBitmap bmPal(pal_xpm);
|
||||
static cBitmap bmNtsc(ntsc_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(bmMpeg2.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_MPEG2
|
||||
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(bmNtsc.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_NTSC
|
||||
cacheM.Append(bmEncrypted.Scaled(yFactorM, yFactorM, antiAliasM)); // SYMBOL_ENCRYPTED
|
||||
|
1
symbol.h
1
symbol.h
@ -21,6 +21,7 @@ enum eSymbols {
|
||||
SYMBOL_DD51,
|
||||
SYMBOL_MPEG2,
|
||||
SYMBOL_H264,
|
||||
SYMBOL_H265,
|
||||
SYMBOL_PAL,
|
||||
SYMBOL_NTSC,
|
||||
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